[update]GameRtp页面接入后端
This commit is contained in:
94
web/src/api/backend/embed.ts
Normal file
94
web/src/api/backend/embed.ts
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
import createAxios from '/@/utils/axios'
|
||||||
|
|
||||||
|
export interface GameRtpParams {
|
||||||
|
provider: string
|
||||||
|
game_name: string
|
||||||
|
page: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export function gameRtp(params: GameRtpParams) {
|
||||||
|
return createAxios({
|
||||||
|
url: '/admin/embed.Embed/gameRtp',
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AddGamePayload {
|
||||||
|
provider_site: string
|
||||||
|
game_name: string
|
||||||
|
image_url: string
|
||||||
|
rtp: number
|
||||||
|
status: 0 | 1
|
||||||
|
}
|
||||||
|
|
||||||
|
export function addGame(data: AddGamePayload) {
|
||||||
|
return createAxios(
|
||||||
|
{
|
||||||
|
url: '/admin/embed.Embed/addGame',
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
showSuccessMessage: true,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EditGamePayload extends AddGamePayload {
|
||||||
|
id: number | string
|
||||||
|
}
|
||||||
|
|
||||||
|
export function editGame(data: EditGamePayload) {
|
||||||
|
return createAxios(
|
||||||
|
{
|
||||||
|
url: '/admin/embed.Embed/editGame',
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
showSuccessMessage: true,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function del(data: { ids: (number | string)[] }) {
|
||||||
|
return createAxios(
|
||||||
|
{
|
||||||
|
url: '/admin/embed.Embed/del',
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
showSuccessMessage: true,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SaveGameRtpPayload {
|
||||||
|
auto_game_rtp: 0 | 1
|
||||||
|
auto_rtp_amount: Record<string, string | number>
|
||||||
|
auto_frequency: number
|
||||||
|
provider_display: string
|
||||||
|
custom_config: string
|
||||||
|
header_image_url: string
|
||||||
|
text_color: string
|
||||||
|
button_text_color: string
|
||||||
|
base_color: string
|
||||||
|
button_bg_color: string
|
||||||
|
outline_color: string
|
||||||
|
progress_bar_bg_color: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export function saveGameRtp(data: SaveGameRtpPayload) {
|
||||||
|
return createAxios(
|
||||||
|
{
|
||||||
|
url: '/admin/embed.Embed/saveGameRtp',
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
showSuccessMessage: true,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -45,6 +45,7 @@ export default {
|
|||||||
nameRequired: 'Please enter the game name',
|
nameRequired: 'Please enter the game name',
|
||||||
urlRequired: 'Please enter the game image URL',
|
urlRequired: 'Please enter the game image URL',
|
||||||
saved: 'Settings saved',
|
saved: 'Settings saved',
|
||||||
|
invalidAutoAmount: 'Auto RTP Amount must be a valid JSON object',
|
||||||
copied: 'Embed code copied',
|
copied: 'Embed code copied',
|
||||||
copyFailed: 'Unable to copy the embed code',
|
copyFailed: 'Unable to copy the embed code',
|
||||||
operationSuccess: 'Operation completed',
|
operationSuccess: 'Operation completed',
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ export default {
|
|||||||
nameRequired: '请输入游戏名称',
|
nameRequired: '请输入游戏名称',
|
||||||
urlRequired: '请输入游戏图片 URL',
|
urlRequired: '请输入游戏图片 URL',
|
||||||
saved: '设置已保存',
|
saved: '设置已保存',
|
||||||
|
invalidAutoAmount: '自动 RTP 范围必须是有效的 JSON 对象',
|
||||||
copied: '嵌入代码已复制',
|
copied: '嵌入代码已复制',
|
||||||
copyFailed: '无法复制嵌入代码',
|
copyFailed: '无法复制嵌入代码',
|
||||||
operationSuccess: '操作成功',
|
operationSuccess: '操作成功',
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
<span>{{ settings[item.key] }}</span>
|
<span>{{ settings[item.key] }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-button type="primary" class="save-button" @click="saveSettings">
|
<el-button type="primary" class="save-button" :loading="savingSettings" @click="saveSettings">
|
||||||
{{ t('embed.gameRtp.save') }}
|
{{ t('embed.gameRtp.save') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -87,8 +87,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="table-wrap">
|
<div v-loading="loading" class="table-wrap">
|
||||||
<el-table :data="pagedRows" border stripe>
|
<el-table :data="rows" border stripe>
|
||||||
<el-table-column prop="id" :label="t('embed.gameRtp.gameId')" width="100" />
|
<el-table-column prop="id" :label="t('embed.gameRtp.gameId')" width="100" />
|
||||||
<el-table-column prop="provider" :label="t('embed.gameRtp.provider')" min-width="140" />
|
<el-table-column prop="provider" :label="t('embed.gameRtp.provider')" min-width="140" />
|
||||||
<el-table-column prop="name" :label="t('embed.gameRtp.gameName')" min-width="180" />
|
<el-table-column prop="name" :label="t('embed.gameRtp.gameName')" min-width="180" />
|
||||||
@@ -115,13 +115,13 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="table-footer">
|
<div class="table-footer">
|
||||||
<span>{{ t('embed.gameRtp.totalRecords', { total: filteredRows.length }) }}</span>
|
<span>{{ t('embed.gameRtp.totalRecords', { total }) }}</span>
|
||||||
<el-pagination
|
<el-pagination
|
||||||
v-model:current-page="currentPage"
|
v-model:current-page="currentPage"
|
||||||
background
|
background
|
||||||
layout="prev, pager, next"
|
layout="prev, pager, next"
|
||||||
:page-size="pageSize"
|
:page-count="lastPage"
|
||||||
:total="filteredRows.length"
|
@current-change="loadGameRtp"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@@ -153,13 +153,13 @@
|
|||||||
<el-form-item :label="t('embed.gameRtp.status')" prop="status">
|
<el-form-item :label="t('embed.gameRtp.status')" prop="status">
|
||||||
<el-select v-model="form.status">
|
<el-select v-model="form.status">
|
||||||
<el-option :label="t('embed.gameRtp.active')" :value="1" />
|
<el-option :label="t('embed.gameRtp.active')" :value="1" />
|
||||||
<el-option :label="t('embed.gameRtp.inactive')" :value="2" />
|
<el-option :label="t('embed.gameRtp.inactive')" :value="0" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button @click="dialogVisible = false">{{ t('embed.gameRtp.cancel') }}</el-button>
|
<el-button @click="dialogVisible = false">{{ t('embed.gameRtp.cancel') }}</el-button>
|
||||||
<el-button type="primary" @click="submitForm">{{ t('embed.gameRtp.confirm') }}</el-button>
|
<el-button type="primary" :loading="submitting" @click="submitForm">{{ t('embed.gameRtp.confirm') }}</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
@@ -168,8 +168,9 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { FormInstance, FormRules } from 'element-plus'
|
import type { FormInstance, FormRules } from 'element-plus'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import { computed, reactive, ref, watch } from 'vue'
|
import { computed, onMounted, reactive, ref } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import { addGame, del, editGame, gameRtp, saveGameRtp } from '/@/api/backend/embed'
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'embed/gameRtp',
|
name: 'embed/gameRtp',
|
||||||
@@ -180,10 +181,44 @@ interface GameRtpRow {
|
|||||||
provider: string
|
provider: string
|
||||||
name: string
|
name: string
|
||||||
imageUrl: string
|
imageUrl: string
|
||||||
rtp: number
|
rtp: number | null
|
||||||
status: number
|
status: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface GameRtpSourceRow {
|
||||||
|
id?: number | string
|
||||||
|
game_id?: number | string
|
||||||
|
provider?: string
|
||||||
|
game_provider?: string
|
||||||
|
provider_site?: string
|
||||||
|
type?: string
|
||||||
|
name?: string
|
||||||
|
game_name?: string
|
||||||
|
image_url?: string
|
||||||
|
game_image_url?: string
|
||||||
|
url?: string
|
||||||
|
rtp?: number | string
|
||||||
|
game_rtp?: number | string
|
||||||
|
status?: number | string
|
||||||
|
game_status?: number | string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface GameRtpSetting {
|
||||||
|
auto_game_rtp?: number | string
|
||||||
|
auto_rtp_amount?: string | Record<string, string | number> | null
|
||||||
|
auto_frequency?: number | string
|
||||||
|
provider_display?: string | null
|
||||||
|
custom_config?: string | null
|
||||||
|
header_image_url?: string | null
|
||||||
|
text_color?: string | null
|
||||||
|
button_text_color?: string | null
|
||||||
|
base_color?: string | null
|
||||||
|
button_bg_color?: string | null
|
||||||
|
outline_color?: string | null
|
||||||
|
progress_bar_bg_color?: string | null
|
||||||
|
update_time?: number | string | null
|
||||||
|
}
|
||||||
|
|
||||||
type ColorSettingKey = 'textColor' | 'baseColor' | 'outlineColor' | 'buttonTextColor' | 'buttonBgColor' | 'progressBgColor'
|
type ColorSettingKey = 'textColor' | 'baseColor' | 'outlineColor' | 'buttonTextColor' | 'buttonBgColor' | 'progressBgColor'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
@@ -229,9 +264,9 @@ const colorFields: { key: ColorSettingKey; label: string }[] = [
|
|||||||
{ key: 'progressBgColor', label: 'embed.gameRtp.progressBgColor' },
|
{ key: 'progressBgColor', label: 'embed.gameRtp.progressBgColor' },
|
||||||
]
|
]
|
||||||
|
|
||||||
const lastRefresh = ref('2026-06-11 18:23:54')
|
const lastRefresh = ref('')
|
||||||
const embedCode = ref(`<div style="position: relative;max-width: 1000px;margin: 0 auto;overflow: hidden;border: none;">
|
const embedCode = ref(`<div style="position: relative;max-width: 1000px;margin: 0 auto;overflow: hidden;border: none;">
|
||||||
<iframe id="gameRtpIframe" src="https://1xaud.em7bd7.co/embed/game-rtp/game-rtp.asp" style="width: 100%;overflow: hidden;border: none;"></iframe>
|
<iframe id="gameRtpIframe" src="http://192.168.0.46:8000/index.php/api/external/gameRtp" style="width: 100%;overflow: hidden;border: none;"></iframe>
|
||||||
<script>
|
<script>
|
||||||
(() => {
|
(() => {
|
||||||
const merchantId = (typeof _ !== "undefined" && typeof _.getVar === "function") ? (_.getVar("merchantId") ?? "") : "";
|
const merchantId = (typeof _ !== "undefined" && typeof _.getVar === "function") ? (_.getVar("merchantId") ?? "") : "";
|
||||||
@@ -264,61 +299,156 @@ const embedCode = ref(`<div style="position: relative;max-width: 1000px;margin:
|
|||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
})();
|
})();
|
||||||
<\/script>
|
/script>
|
||||||
</div>`)
|
</div>`)
|
||||||
|
|
||||||
const sourceRows: GameRtpRow[] = [
|
const rows = ref<GameRtpRow[]>([])
|
||||||
{ id: 15996, provider: 'SCRATCH', name: 'Spiritual Fortune', imageUrl: 'https://bonzagame.example/thumb_xl_spiritualfortune.png', rtp: 33, status: 1 },
|
|
||||||
{ id: 15995, provider: 'SCRATCH', name: 'Monster Mayhem', imageUrl: 'https://bonzagame.example/thumb_xl_monstermayhem.png', rtp: 70, status: 1 },
|
|
||||||
{ id: 15994, provider: 'SCRATCH', name: 'The Fiery Tales', imageUrl: 'https://bonzagame.example/thumb_xl_thefierytales.png', rtp: 76, status: 1 },
|
|
||||||
{ id: 15993, provider: 'SCRATCH', name: 'The Chronicles', imageUrl: 'https://bonzagame.example/thumb_xl_thechronicles.png', rtp: 52, status: 1 },
|
|
||||||
{ id: 15992, provider: 'SCRATCH', name: 'Spiritual King', imageUrl: 'https://bonzagame.example/thumb_xl_spiritualking.png', rtp: 31, status: 1 },
|
|
||||||
{ id: 15991, provider: 'SCRATCH', name: 'Enchanted Forest', imageUrl: 'https://bonzagame.example/thumb_xl_enchantedforest.png', rtp: 66, status: 1 },
|
|
||||||
{ id: 15990, provider: 'SCRATCH', name: 'Fortune Dino', imageUrl: 'https://bonzagame.example/thumb_xl_fortunedino.png', rtp: 69, status: 1 },
|
|
||||||
{ id: 15989, provider: 'SCRATCH', name: 'Gold Hunter', imageUrl: 'https://bonzagame.example/thumb_xl_goldhunter.png', rtp: 42, status: 1 },
|
|
||||||
{ id: 15988, provider: 'SCRATCH', name: 'Space Hunter', imageUrl: 'https://bonzagame.example/thumb_xl_spacehunter.png', rtp: 58, status: 1 },
|
|
||||||
{ id: 15987, provider: 'SCRATCH', name: 'Prosperity Play', imageUrl: 'https://bonzagame.example/thumb_xl_prosperityplay.png', rtp: 73, status: 1 },
|
|
||||||
{ id: 15986, provider: 'SCRATCH', name: 'Wonderful Alice', imageUrl: 'https://bonzagame.example/thumb_xl_wonderfulalice.png', rtp: 32, status: 1 },
|
|
||||||
{ id: 15985, provider: 'SCRATCH', name: 'Galactic Trooper', imageUrl: 'https://bonzagame.example/thumb_xl_galactictrooper.png', rtp: 59, status: 2 },
|
|
||||||
]
|
|
||||||
|
|
||||||
const rows = ref<GameRtpRow[]>(sourceRows)
|
|
||||||
const filters = reactive({ provider: '', name: '' })
|
const filters = reactive({ provider: '', name: '' })
|
||||||
const appliedFilters = reactive({ provider: '', name: '' })
|
const appliedFilters = reactive({ provider: '', name: '' })
|
||||||
const providers = computed(() => [...new Set(rows.value.map((row) => row.provider))].sort())
|
const providerOptions = ref<string[]>([])
|
||||||
const filteredRows = computed(() =>
|
const providers = computed(() => [...new Set([...providerOptions.value, ...rows.value.map((row) => row.provider)].filter(Boolean))].sort())
|
||||||
rows.value.filter(
|
|
||||||
(row) =>
|
|
||||||
(!appliedFilters.provider || row.provider === appliedFilters.provider) &&
|
|
||||||
(!appliedFilters.name || row.name.toLowerCase().includes(appliedFilters.name.toLowerCase()))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
const currentPage = ref(1)
|
const currentPage = ref(1)
|
||||||
const pageSize = 10
|
const lastPage = ref(1)
|
||||||
const pagedRows = computed(() => filteredRows.value.slice((currentPage.value - 1) * pageSize, currentPage.value * pageSize))
|
const pageSize = ref(50)
|
||||||
|
const total = ref(0)
|
||||||
|
const loading = ref(false)
|
||||||
|
|
||||||
watch(filteredRows, () => {
|
const toNumber = (value: unknown) => {
|
||||||
const lastPage = Math.max(1, Math.ceil(filteredRows.value.length / pageSize))
|
const number = Number(value)
|
||||||
if (currentPage.value > lastPage) currentPage.value = lastPage
|
return Number.isFinite(number) ? number : 0
|
||||||
})
|
|
||||||
|
|
||||||
const search = () => {
|
|
||||||
Object.assign(appliedFilters, filters)
|
|
||||||
currentPage.value = 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const clearSearch = () => {
|
const normalizeStatus = (value: unknown) => {
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
const normalized = value.trim().toUpperCase()
|
||||||
|
if (normalized === 'ACTIVE') return 1
|
||||||
|
if (normalized === 'INACTIVE') return 0
|
||||||
|
}
|
||||||
|
return toNumber(value) === 1 ? 1 : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatUpdateTime = (value: unknown) => {
|
||||||
|
if (!value) return ''
|
||||||
|
if (typeof value === 'string' && !/^\d+$/.test(value)) return value
|
||||||
|
const timestamp = toNumber(value)
|
||||||
|
if (!timestamp) return ''
|
||||||
|
return new Date(timestamp * (timestamp < 1e12 ? 1000 : 1)).toLocaleString()
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatJsonSetting = (value: string | Record<string, unknown> | null | undefined) => {
|
||||||
|
if (!value) return ''
|
||||||
|
return typeof value === 'string' ? value : JSON.stringify(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const applyRtpSetting = (setting?: GameRtpSetting) => {
|
||||||
|
if (!setting) return
|
||||||
|
settings.autoRtp = toNumber(setting.auto_game_rtp) === 1 ? 1 : 0
|
||||||
|
settings.autoAmount = formatJsonSetting(setting.auto_rtp_amount)
|
||||||
|
settings.frequency = String(setting.auto_frequency ?? '')
|
||||||
|
settings.providerDisplay = setting.provider_display ?? ''
|
||||||
|
settings.customConfig = setting.custom_config ?? ''
|
||||||
|
settings.headerImage = setting.header_image_url ?? ''
|
||||||
|
settings.textColor = setting.text_color ?? ''
|
||||||
|
settings.buttonTextColor = setting.button_text_color ?? ''
|
||||||
|
settings.baseColor = setting.base_color ?? ''
|
||||||
|
settings.buttonBgColor = setting.button_bg_color ?? ''
|
||||||
|
settings.outlineColor = setting.outline_color ?? ''
|
||||||
|
settings.progressBgColor = setting.progress_bar_bg_color ?? ''
|
||||||
|
lastRefresh.value = formatUpdateTime(setting.update_time)
|
||||||
|
}
|
||||||
|
|
||||||
|
const normalizeResponse = (responseData: any) => {
|
||||||
|
const source = responseData?.data ?? responseData ?? {}
|
||||||
|
const list = Array.isArray(source.list) ? source.list : []
|
||||||
|
|
||||||
|
const normalizedRows: GameRtpRow[] = list.map((row: GameRtpSourceRow) => ({
|
||||||
|
id: toNumber(row.id ?? row.game_id),
|
||||||
|
provider: String(row.provider_site ?? row.game_provider ?? row.provider ?? row.type ?? ''),
|
||||||
|
name: String(row.game_name ?? row.name ?? ''),
|
||||||
|
imageUrl: String(row.game_image_url ?? row.image_url ?? row.url ?? ''),
|
||||||
|
rtp: row.game_rtp == null && row.rtp == null ? null : toNumber(row.game_rtp ?? row.rtp),
|
||||||
|
status: normalizeStatus(row.game_status ?? row.status),
|
||||||
|
}))
|
||||||
|
|
||||||
|
if (currentPage.value === 1 && normalizedRows.length) pageSize.value = normalizedRows.length
|
||||||
|
const normalizedTotal = toNumber(source.total ?? normalizedRows.length)
|
||||||
|
|
||||||
|
return {
|
||||||
|
rows: normalizedRows,
|
||||||
|
total: normalizedTotal,
|
||||||
|
lastPage: Math.max(1, Math.ceil(normalizedTotal / pageSize.value)),
|
||||||
|
providers: Array.isArray(source.provider) ? source.provider.map(String) : [],
|
||||||
|
setting: source.rtp_setting as GameRtpSetting | undefined,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadGameRtp = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const response = await gameRtp({
|
||||||
|
provider: appliedFilters.provider,
|
||||||
|
game_name: appliedFilters.name,
|
||||||
|
page: currentPage.value,
|
||||||
|
})
|
||||||
|
const normalized = normalizeResponse(response.data)
|
||||||
|
rows.value = normalized.rows
|
||||||
|
total.value = normalized.total
|
||||||
|
lastPage.value = normalized.lastPage
|
||||||
|
providerOptions.value = normalized.providers
|
||||||
|
applyRtpSetting(normalized.setting)
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const search = async () => {
|
||||||
|
Object.assign(appliedFilters, filters)
|
||||||
|
currentPage.value = 1
|
||||||
|
await loadGameRtp()
|
||||||
|
}
|
||||||
|
|
||||||
|
const clearSearch = async () => {
|
||||||
Object.assign(filters, { provider: '', name: '' })
|
Object.assign(filters, { provider: '', name: '' })
|
||||||
search()
|
await search()
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadTemplate = () => {
|
const loadTemplate = () => {
|
||||||
settings.customConfig = configTemplate
|
settings.customConfig = configTemplate
|
||||||
}
|
}
|
||||||
|
|
||||||
const saveSettings = () => {
|
const savingSettings = ref(false)
|
||||||
lastRefresh.value = new Date().toLocaleString()
|
|
||||||
ElMessage.success(t('embed.gameRtp.saved'))
|
const saveSettings = async () => {
|
||||||
|
let autoRtpAmount: Record<string, string | number>
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(settings.autoAmount)
|
||||||
|
if (!parsed || Array.isArray(parsed) || typeof parsed !== 'object') throw new Error()
|
||||||
|
autoRtpAmount = parsed
|
||||||
|
} catch {
|
||||||
|
ElMessage.error(t('embed.gameRtp.invalidAutoAmount'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
savingSettings.value = true
|
||||||
|
try {
|
||||||
|
await saveGameRtp({
|
||||||
|
auto_game_rtp: settings.autoRtp as 0 | 1,
|
||||||
|
auto_rtp_amount: autoRtpAmount,
|
||||||
|
auto_frequency: toNumber(settings.frequency),
|
||||||
|
provider_display: settings.providerDisplay,
|
||||||
|
custom_config: settings.customConfig,
|
||||||
|
header_image_url: settings.headerImage,
|
||||||
|
text_color: settings.textColor,
|
||||||
|
button_text_color: settings.buttonTextColor,
|
||||||
|
base_color: settings.baseColor,
|
||||||
|
button_bg_color: settings.buttonBgColor,
|
||||||
|
outline_color: settings.outlineColor,
|
||||||
|
progress_bar_bg_color: settings.progressBgColor,
|
||||||
|
})
|
||||||
|
await loadGameRtp()
|
||||||
|
} finally {
|
||||||
|
savingSettings.value = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const copyEmbedCode = async () => {
|
const copyEmbedCode = async () => {
|
||||||
@@ -333,6 +463,7 @@ const copyEmbedCode = async () => {
|
|||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false)
|
||||||
const dialogMode = ref<'create' | 'edit'>('create')
|
const dialogMode = ref<'create' | 'edit'>('create')
|
||||||
const editingId = ref<number>()
|
const editingId = ref<number>()
|
||||||
|
const submitting = ref(false)
|
||||||
const formRef = ref<FormInstance>()
|
const formRef = ref<FormInstance>()
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
provider: '',
|
provider: '',
|
||||||
@@ -358,14 +489,39 @@ const submitForm = async () => {
|
|||||||
if (!(await formRef.value?.validate().catch(() => false))) return
|
if (!(await formRef.value?.validate().catch(() => false))) return
|
||||||
|
|
||||||
if (dialogMode.value === 'create') {
|
if (dialogMode.value === 'create') {
|
||||||
const nextId = Math.max(0, ...rows.value.map((row) => row.id)) + 1
|
submitting.value = true
|
||||||
rows.value.unshift({ id: nextId, ...form })
|
try {
|
||||||
} else {
|
await addGame({
|
||||||
const index = rows.value.findIndex((row) => row.id === editingId.value)
|
provider_site: form.provider,
|
||||||
if (index >= 0) rows.value[index] = { id: editingId.value!, ...form }
|
game_name: form.name,
|
||||||
}
|
image_url: form.imageUrl,
|
||||||
|
rtp: form.rtp,
|
||||||
|
status: form.status as 0 | 1,
|
||||||
|
})
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
ElMessage.success(t('embed.gameRtp.operationSuccess'))
|
currentPage.value = 1
|
||||||
|
await loadGameRtp()
|
||||||
|
} finally {
|
||||||
|
submitting.value = false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (editingId.value == null) return
|
||||||
|
submitting.value = true
|
||||||
|
try {
|
||||||
|
await editGame({
|
||||||
|
id: editingId.value,
|
||||||
|
provider_site: form.provider,
|
||||||
|
game_name: form.name,
|
||||||
|
image_url: form.imageUrl,
|
||||||
|
rtp: form.rtp,
|
||||||
|
status: form.status as 0 | 1,
|
||||||
|
})
|
||||||
|
dialogVisible.value = false
|
||||||
|
await loadGameRtp()
|
||||||
|
} finally {
|
||||||
|
submitting.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const removeRow = async (row: GameRtpRow) => {
|
const removeRow = async (row: GameRtpRow) => {
|
||||||
@@ -375,8 +531,9 @@ const removeRow = async (row: GameRtpRow) => {
|
|||||||
confirmButtonText: t('embed.gameRtp.confirm'),
|
confirmButtonText: t('embed.gameRtp.confirm'),
|
||||||
cancelButtonText: t('embed.gameRtp.cancel'),
|
cancelButtonText: t('embed.gameRtp.cancel'),
|
||||||
})
|
})
|
||||||
rows.value = rows.value.filter((item) => item.id !== row.id)
|
await del({ ids: [row.id] })
|
||||||
ElMessage.success(t('embed.gameRtp.deleted'))
|
if (rows.value.length === 1 && currentPage.value > 1) currentPage.value -= 1
|
||||||
|
await loadGameRtp()
|
||||||
} catch {
|
} catch {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -395,6 +552,8 @@ const importGames = async () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMounted(loadGameRtp)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
Reference in New Issue
Block a user