1.所有接口需要根据agent_id绑定渠道
2.移除所有记录页面的更新按钮,只能查看数据 3.将所有软删除修改为硬删除
This commit is contained in:
@@ -427,6 +427,9 @@
|
|||||||
"rewardConfigRecord": "Dice Weight Test Records",
|
"rewardConfigRecord": "Dice Weight Test Records",
|
||||||
"playRecordTest": "Draw Records (Test Weight)",
|
"playRecordTest": "Draw Records (Test Weight)",
|
||||||
"config": "Game Config"
|
"config": "Game Config"
|
||||||
|
},
|
||||||
|
"game": {
|
||||||
|
"title": "Game Management"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"table": {
|
"table": {
|
||||||
|
|||||||
@@ -38,8 +38,31 @@
|
|||||||
"ruleGameNameRequired": "Chinese name is required",
|
"ruleGameNameRequired": "Chinese name is required",
|
||||||
"ruleGameTypeRequired": "Game type is required"
|
"ruleGameTypeRequired": "Game type is required"
|
||||||
},
|
},
|
||||||
"table": {
|
"search": {
|
||||||
|
"providerCode": "Provider Code",
|
||||||
|
"placeholderProviderCode": "Enter provider code",
|
||||||
|
"gameCode": "Game Code",
|
||||||
|
"placeholderGameCode": "Enter game code",
|
||||||
|
"gameType": "Game Type",
|
||||||
|
"placeholderGameType": "Enter game type",
|
||||||
|
"status": "Status",
|
||||||
|
"placeholderStatus": "Select status",
|
||||||
"statusEnabled": "Enabled",
|
"statusEnabled": "Enabled",
|
||||||
"statusDisabled": "Disabled"
|
"statusDisabled": "Disabled"
|
||||||
|
},
|
||||||
|
"table": {
|
||||||
|
"id": "ID",
|
||||||
|
"provider": "Provider",
|
||||||
|
"providerCode": "Provider Code",
|
||||||
|
"gameCode": "Game Code",
|
||||||
|
"gameKey": "Game Key",
|
||||||
|
"gameName": "Name (ZH)",
|
||||||
|
"gameNameEn": "Name (EN)",
|
||||||
|
"gameType": "Type",
|
||||||
|
"sort": "Sort",
|
||||||
|
"status": "Status",
|
||||||
|
"statusEnabled": "Enabled",
|
||||||
|
"statusDisabled": "Disabled",
|
||||||
|
"updateTime": "Update Time"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -423,6 +423,9 @@
|
|||||||
"rewardConfigRecord": "权重测试记录",
|
"rewardConfigRecord": "权重测试记录",
|
||||||
"playRecordTest": "抽奖记录(测试权重)",
|
"playRecordTest": "抽奖记录(测试权重)",
|
||||||
"config": "游戏配置"
|
"config": "游戏配置"
|
||||||
|
},
|
||||||
|
"game": {
|
||||||
|
"title": "游戏管理"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"table": {
|
"table": {
|
||||||
|
|||||||
@@ -38,8 +38,31 @@
|
|||||||
"ruleGameNameRequired": "请输入中文名称",
|
"ruleGameNameRequired": "请输入中文名称",
|
||||||
"ruleGameTypeRequired": "请输入游戏类型"
|
"ruleGameTypeRequired": "请输入游戏类型"
|
||||||
},
|
},
|
||||||
"table": {
|
"search": {
|
||||||
|
"providerCode": "供应商编码",
|
||||||
|
"placeholderProviderCode": "请输入供应商编码",
|
||||||
|
"gameCode": "游戏编号",
|
||||||
|
"placeholderGameCode": "请输入游戏编号",
|
||||||
|
"gameType": "游戏类型",
|
||||||
|
"placeholderGameType": "请输入游戏类型",
|
||||||
|
"status": "状态",
|
||||||
|
"placeholderStatus": "请选择状态",
|
||||||
"statusEnabled": "启用",
|
"statusEnabled": "启用",
|
||||||
"statusDisabled": "禁用"
|
"statusDisabled": "禁用"
|
||||||
|
},
|
||||||
|
"table": {
|
||||||
|
"id": "ID",
|
||||||
|
"provider": "供应商",
|
||||||
|
"providerCode": "供应商编码",
|
||||||
|
"gameCode": "游戏编号",
|
||||||
|
"gameKey": "游戏唯一值",
|
||||||
|
"gameName": "中文名",
|
||||||
|
"gameNameEn": "英文名",
|
||||||
|
"gameType": "类型",
|
||||||
|
"sort": "排序",
|
||||||
|
"status": "状态",
|
||||||
|
"statusEnabled": "启用",
|
||||||
|
"statusDisabled": "禁用",
|
||||||
|
"updateTime": "更新时间"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,12 +46,21 @@ export async function loadPageLocale(routePath: string): Promise<void> {
|
|||||||
const modules = locale === LanguageEnum.EN ? enModules : zhModules
|
const modules = locale === LanguageEnum.EN ? enModules : zhModules
|
||||||
|
|
||||||
const tryPaths: string[] = [path]
|
const tryPaths: string[] = [path]
|
||||||
// 兼容别名路由:例如 /user 实际页面为 /system/user
|
// 兼容别名路由:菜单 path 为短名但 locale 文件位于模块子目录
|
||||||
|
// 例如:/user -> system/user,/game -> dice/game
|
||||||
if (!path.includes('/')) {
|
if (!path.includes('/')) {
|
||||||
tryPaths.push(`system/${path}`)
|
tryPaths.push(`system/${path}`)
|
||||||
}
|
// 兜底:在任意一级子目录下查找同名文件
|
||||||
if (path === 'user') {
|
const suffix = `/${path}.json`
|
||||||
tryPaths.push('system/user')
|
const localePrefix = `./langs/${locale}/`
|
||||||
|
for (const key of Object.keys(modules)) {
|
||||||
|
if (key.startsWith(localePrefix) && key.endsWith(suffix)) {
|
||||||
|
const candidate = key.slice(localePrefix.length, -'.json'.length)
|
||||||
|
if (!tryPaths.includes(candidate)) {
|
||||||
|
tryPaths.push(candidate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let matchedPath: string | null = null
|
let matchedPath: string | null = null
|
||||||
|
|||||||
@@ -61,6 +61,10 @@ export const MAP_PATH_TO_MENU_I18N_KEY: Record<string, string> = {
|
|||||||
'/dice/play_record_test/index': 'menus.dice.playRecordTest',
|
'/dice/play_record_test/index': 'menus.dice.playRecordTest',
|
||||||
'/dice/config': 'menus.dice.config',
|
'/dice/config': 'menus.dice.config',
|
||||||
'/dice/config/index': 'menus.dice.config',
|
'/dice/config/index': 'menus.dice.config',
|
||||||
|
'game': 'menus.game.title',
|
||||||
|
'game/index': 'menus.game.title',
|
||||||
|
'/game': 'menus.game.title',
|
||||||
|
'/game/index': 'menus.game.title',
|
||||||
'/result/success': 'menus.result.success',
|
'/result/success': 'menus.result.success',
|
||||||
'/result/fail': 'menus.result.fail',
|
'/result/fail': 'menus.result.fail',
|
||||||
'/exception/403': 'menus.exception.forbidden',
|
'/exception/403': 'menus.exception.forbidden',
|
||||||
|
|||||||
@@ -39,18 +39,6 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新数据
|
|
||||||
* @param params 数据参数
|
|
||||||
* @returns 执行结果
|
|
||||||
*/
|
|
||||||
update(params: Record<string, any>) {
|
|
||||||
return request.put<any>({
|
|
||||||
url: '/core/dice/play_record/DicePlayRecord/update',
|
|
||||||
data: params
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除数据
|
* 删除数据
|
||||||
* @param id 数据ID
|
* @param id 数据ID
|
||||||
|
|||||||
@@ -39,18 +39,6 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新数据
|
|
||||||
* @param params 数据参数
|
|
||||||
* @returns 执行结果
|
|
||||||
*/
|
|
||||||
update(params: Record<string, any>) {
|
|
||||||
return request.put<any>({
|
|
||||||
url: '/core/dice/play_record_test/DicePlayRecordTest/update',
|
|
||||||
data: params
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除数据
|
* 删除数据
|
||||||
* @param id 数据ID
|
* @param id 数据ID
|
||||||
|
|||||||
@@ -39,18 +39,6 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新数据
|
|
||||||
* @param params 数据参数
|
|
||||||
* @returns 执行结果
|
|
||||||
*/
|
|
||||||
update(params: Record<string, any>) {
|
|
||||||
return request.put<any>({
|
|
||||||
url: '/core/dice/player_ticket_record/DicePlayerTicketRecord/update',
|
|
||||||
data: params
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除数据
|
* 删除数据
|
||||||
* @param id 数据ID
|
* @param id 数据ID
|
||||||
|
|||||||
@@ -39,18 +39,6 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新数据
|
|
||||||
* @param params 数据参数
|
|
||||||
* @returns 执行结果
|
|
||||||
*/
|
|
||||||
update(params: Record<string, any>) {
|
|
||||||
return request.put<any>({
|
|
||||||
url: '/core/dice/player_wallet_record/DicePlayerWalletRecord/update',
|
|
||||||
data: params
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除数据
|
* 删除数据
|
||||||
* @param id 数据ID
|
* @param id 数据ID
|
||||||
|
|||||||
@@ -39,18 +39,6 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新数据
|
|
||||||
* @param params 数据参数
|
|
||||||
* @returns 执行结果
|
|
||||||
*/
|
|
||||||
update(params: Record<string, any>) {
|
|
||||||
return request.put<any>({
|
|
||||||
url: '/core/dice/reward_config_record/DiceRewardConfigRecord/update',
|
|
||||||
data: params
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除数据
|
* 删除数据
|
||||||
* @param id 数据ID
|
* @param id 数据ID
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<template #icon>
|
<template #icon>
|
||||||
<ArtSvgIcon icon="ri:add-fill" />
|
<ArtSvgIcon icon="ri:add-fill" />
|
||||||
</template>
|
</template>
|
||||||
新增
|
{{ $t('table.actions.add') }}
|
||||||
</ElButton>
|
</ElButton>
|
||||||
<ElButton
|
<ElButton
|
||||||
v-permission="'dice:game:index:destroy'"
|
v-permission="'dice:game:index:destroy'"
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
<template #icon>
|
<template #icon>
|
||||||
<ArtSvgIcon icon="ri:delete-bin-5-line" />
|
<ArtSvgIcon icon="ri:delete-bin-5-line" />
|
||||||
</template>
|
</template>
|
||||||
删除
|
{{ $t('table.actions.delete') }}
|
||||||
</ElButton>
|
</ElButton>
|
||||||
</ElSpace>
|
</ElSpace>
|
||||||
</template>
|
</template>
|
||||||
@@ -108,20 +108,20 @@
|
|||||||
apiParams: { limit: 100 },
|
apiParams: { limit: 100 },
|
||||||
columnsFactory: () => [
|
columnsFactory: () => [
|
||||||
{ type: 'selection', align: 'center' },
|
{ type: 'selection', align: 'center' },
|
||||||
{ prop: 'id', label: 'ID', width: 80, align: 'center' },
|
{ prop: 'id', label: 'page.table.id', width: 80, align: 'center' },
|
||||||
{ prop: 'provider', label: '供应商', minWidth: 120, align: 'center' },
|
{ prop: 'provider', label: 'page.table.provider', minWidth: 120, align: 'center' },
|
||||||
{ prop: 'provider_code', label: '供应商编码', minWidth: 120, align: 'center' },
|
{ prop: 'provider_code', label: 'page.table.providerCode', minWidth: 120, align: 'center' },
|
||||||
{ prop: 'game_code', label: '游戏编号', minWidth: 120, align: 'center' },
|
{ prop: 'game_code', label: 'page.table.gameCode', minWidth: 120, align: 'center' },
|
||||||
{ prop: 'game_key', label: '游戏唯一值', minWidth: 120, align: 'center' },
|
{ prop: 'game_key', label: 'page.table.gameKey', minWidth: 120, align: 'center' },
|
||||||
{ prop: 'game_name', label: '中文名', minWidth: 120, align: 'center' },
|
{ prop: 'game_name', label: 'page.table.gameName', minWidth: 120, align: 'center' },
|
||||||
{ prop: 'game_name_en', label: '英文名', minWidth: 120, align: 'center' },
|
{ prop: 'game_name_en', label: 'page.table.gameNameEn', minWidth: 120, align: 'center' },
|
||||||
{ prop: 'game_type', label: '类型', minWidth: 90, align: 'center' },
|
{ prop: 'game_type', label: 'page.table.gameType', minWidth: 90, align: 'center' },
|
||||||
{ prop: 'sort', label: '排序', width: 80, align: 'center' },
|
{ prop: 'sort', label: 'page.table.sort', width: 80, align: 'center' },
|
||||||
{ prop: 'status', label: '状态', width: 90, align: 'center', useSlot: true },
|
{ prop: 'status', label: 'page.table.status', width: 90, align: 'center', useSlot: true },
|
||||||
{ prop: 'update_time', label: '更新时间', minWidth: 160, align: 'center' },
|
{ prop: 'update_time', label: 'page.table.updateTime', minWidth: 160, align: 'center' },
|
||||||
{
|
{
|
||||||
prop: 'operation',
|
prop: 'operation',
|
||||||
label: '操作',
|
label: 'table.actions.operation',
|
||||||
width: 110,
|
width: 110,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
fixed: 'right',
|
fixed: 'right',
|
||||||
|
|||||||
@@ -8,25 +8,41 @@
|
|||||||
@search="handleSearch"
|
@search="handleSearch"
|
||||||
>
|
>
|
||||||
<el-col v-bind="setSpan(6)">
|
<el-col v-bind="setSpan(6)">
|
||||||
<el-form-item label="供应商编码" prop="provider_code">
|
<el-form-item :label="$t('page.search.providerCode')" prop="provider_code">
|
||||||
<el-input v-model="formData.provider_code" placeholder="请输入供应商编码" clearable />
|
<el-input
|
||||||
|
v-model="formData.provider_code"
|
||||||
|
:placeholder="$t('page.search.placeholderProviderCode')"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col v-bind="setSpan(6)">
|
<el-col v-bind="setSpan(6)">
|
||||||
<el-form-item label="游戏编号" prop="game_code">
|
<el-form-item :label="$t('page.search.gameCode')" prop="game_code">
|
||||||
<el-input v-model="formData.game_code" placeholder="请输入游戏编号" clearable />
|
<el-input
|
||||||
|
v-model="formData.game_code"
|
||||||
|
:placeholder="$t('page.search.placeholderGameCode')"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col v-bind="setSpan(6)">
|
<el-col v-bind="setSpan(6)">
|
||||||
<el-form-item label="游戏类型" prop="game_type">
|
<el-form-item :label="$t('page.search.gameType')" prop="game_type">
|
||||||
<el-input v-model="formData.game_type" placeholder="请输入游戏类型" clearable />
|
<el-input
|
||||||
|
v-model="formData.game_type"
|
||||||
|
:placeholder="$t('page.search.placeholderGameType')"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col v-bind="setSpan(6)">
|
<el-col v-bind="setSpan(6)">
|
||||||
<el-form-item label="状态" prop="status">
|
<el-form-item :label="$t('page.search.status')" prop="status">
|
||||||
<el-select v-model="formData.status" placeholder="请选择状态" clearable>
|
<el-select
|
||||||
<el-option label="启用" :value="1" />
|
v-model="formData.status"
|
||||||
<el-option label="禁用" :value="0" />
|
:placeholder="$t('page.search.placeholderStatus')"
|
||||||
|
clearable
|
||||||
|
>
|
||||||
|
<el-option :label="$t('page.search.statusEnabled')" :value="1" />
|
||||||
|
<el-option :label="$t('page.search.statusDisabled')" :value="0" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog
|
<el-dialog
|
||||||
v-model="visible"
|
v-model="visible"
|
||||||
:title="dialogType === 'add' ? $t('page.form.dialogTitleAdd') : $t('page.form.dialogTitleEdit')"
|
:title="$t('page.form.dialogTitleEdit')"
|
||||||
width="600px"
|
width="600px"
|
||||||
align-center
|
align-center
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
@close="handleClose"
|
@close="handleClose"
|
||||||
>
|
>
|
||||||
<el-form ref="formRef" :model="formData" :rules="rules" label-width="120px">
|
<el-form ref="formRef" :model="formData" label-width="120px">
|
||||||
<el-form-item :label="$t('page.form.player')" prop="player_id">
|
<el-form-item :label="$t('page.form.player')" prop="player_id">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="formData.player_id"
|
v-model="formData.player_id"
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
clearable
|
clearable
|
||||||
filterable
|
filterable
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
:disabled="dialogType === 'edit'"
|
disabled
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in playerOptions"
|
v-for="item in playerOptions"
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
clearable
|
clearable
|
||||||
filterable
|
filterable
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
:disabled="dialogType === 'edit'"
|
disabled
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in lotteryConfigOptions"
|
v-for="item in lotteryConfigOptions"
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
:placeholder="$t('form.placeholderSelect')"
|
:placeholder="$t('form.placeholderSelect')"
|
||||||
clearable
|
clearable
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
:disabled="dialogType === 'edit'"
|
disabled
|
||||||
>
|
>
|
||||||
<el-option :label="$t('page.form.paid')" :value="0" />
|
<el-option :label="$t('page.form.paid')" :value="0" />
|
||||||
<el-option :label="$t('page.form.free')" :value="1" />
|
<el-option :label="$t('page.form.free')" :value="1" />
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
:placeholder="$t('form.placeholderSelect')"
|
:placeholder="$t('form.placeholderSelect')"
|
||||||
clearable
|
clearable
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
:disabled="dialogType === 'edit'"
|
disabled
|
||||||
>
|
>
|
||||||
<el-option :label="$t('page.form.noBigWin')" :value="0" />
|
<el-option :label="$t('page.form.noBigWin')" :value="0" />
|
||||||
<el-option :label="$t('page.form.bigWin')" :value="1" />
|
<el-option :label="$t('page.form.bigWin')" :value="1" />
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
:placeholder="$t('page.form.placeholderWinCoin')"
|
:placeholder="$t('page.form.placeholderWinCoin')"
|
||||||
:precision="0"
|
:precision="0"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
:disabled="dialogType === 'edit'"
|
disabled
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('page.form.superWinCoin')" prop="super_win_coin">
|
<el-form-item :label="$t('page.form.superWinCoin')" prop="super_win_coin">
|
||||||
@@ -82,7 +82,7 @@
|
|||||||
:precision="0"
|
:precision="0"
|
||||||
:min="0"
|
:min="0"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
:disabled="dialogType === 'edit'"
|
disabled
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('page.form.rewardWinCoin')" prop="reward_win_coin">
|
<el-form-item :label="$t('page.form.rewardWinCoin')" prop="reward_win_coin">
|
||||||
@@ -92,7 +92,7 @@
|
|||||||
:precision="0"
|
:precision="0"
|
||||||
:min="0"
|
:min="0"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
:disabled="dialogType === 'edit'"
|
disabled
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('page.form.direction')" prop="direction">
|
<el-form-item :label="$t('page.form.direction')" prop="direction">
|
||||||
@@ -101,7 +101,7 @@
|
|||||||
:placeholder="$t('page.form.placeholderDirection')"
|
:placeholder="$t('page.form.placeholderDirection')"
|
||||||
clearable
|
clearable
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
:disabled="dialogType === 'edit'"
|
disabled
|
||||||
>
|
>
|
||||||
<el-option :label="$t('page.form.clockwise')" :value="0" />
|
<el-option :label="$t('page.form.clockwise')" :value="0" />
|
||||||
<el-option :label="$t('page.form.anticlockwise')" :value="1" />
|
<el-option :label="$t('page.form.anticlockwise')" :value="1" />
|
||||||
@@ -113,7 +113,7 @@
|
|||||||
:placeholder="$t('page.form.placeholderStartIndex')"
|
:placeholder="$t('page.form.placeholderStartIndex')"
|
||||||
:min="0"
|
:min="0"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
:disabled="dialogType === 'edit'"
|
disabled
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('page.form.targetIndex')" prop="target_index">
|
<el-form-item :label="$t('page.form.targetIndex')" prop="target_index">
|
||||||
@@ -122,7 +122,7 @@
|
|||||||
:placeholder="$t('page.form.placeholderTargetIndex')"
|
:placeholder="$t('page.form.placeholderTargetIndex')"
|
||||||
:min="0"
|
:min="0"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
:disabled="dialogType === 'edit'"
|
disabled
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('page.form.rollArray')" prop="rollArrayItems">
|
<el-form-item :label="$t('page.form.rollArray')" prop="rollArrayItems">
|
||||||
@@ -137,7 +137,7 @@
|
|||||||
controls-position="right"
|
controls-position="right"
|
||||||
placeholder=""
|
placeholder=""
|
||||||
class="roll-array-input"
|
class="roll-array-input"
|
||||||
:disabled="dialogType === 'edit'"
|
disabled
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="roll-array-hint">{{ $t('page.form.rollArrayHint') }}</div>
|
<div class="roll-array-hint">{{ $t('page.form.rollArrayHint') }}</div>
|
||||||
@@ -150,7 +150,7 @@
|
|||||||
:max="30"
|
:max="30"
|
||||||
:precision="0"
|
:precision="0"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
:disabled="dialogType === 'edit'"
|
disabled
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('page.form.rewardTier')" prop="reward_tier">
|
<el-form-item :label="$t('page.form.rewardTier')" prop="reward_tier">
|
||||||
@@ -160,7 +160,7 @@
|
|||||||
clearable
|
clearable
|
||||||
filterable
|
filterable
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
:disabled="true"
|
disabled
|
||||||
>
|
>
|
||||||
<el-option label="T1" value="T1" />
|
<el-option label="T1" value="T1" />
|
||||||
<el-option label="T2" value="T2" />
|
<el-option label="T2" value="T2" />
|
||||||
@@ -172,20 +172,15 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button @click="handleClose">{{ dialogType === 'edit' ? $t('form.close') : $t('common.cancel') }}</el-button>
|
<el-button @click="handleClose">{{ $t('form.close') }}</el-button>
|
||||||
<el-button v-if="dialogType === 'add'" type="primary" @click="handleSubmit">{{ $t('table.form.submit') }}</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import api from '../../../api/play_record/index'
|
import api from '../../../api/play_record/index'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { getChannelDeptRequestParams } from '@/composables/useChannelDeptScope'
|
||||||
import { getChannelDeptRequestParams, withChannelDeptParams } from '@/composables/useChannelDeptScope'
|
import type { FormInstance } from 'element-plus'
|
||||||
import { ElMessage } from 'element-plus'
|
|
||||||
import type { FormInstance, FormRules } from 'element-plus'
|
|
||||||
|
|
||||||
const { t } = useI18n()
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
modelValue: boolean
|
modelValue: boolean
|
||||||
@@ -200,7 +195,7 @@
|
|||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
modelValue: false,
|
modelValue: false,
|
||||||
dialogType: 'add',
|
dialogType: 'edit',
|
||||||
data: undefined
|
data: undefined
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -213,32 +208,6 @@
|
|||||||
set: (value) => emit('update:modelValue', value)
|
set: (value) => emit('update:modelValue', value)
|
||||||
})
|
})
|
||||||
|
|
||||||
const rules = computed<FormRules>(() => ({
|
|
||||||
player_id: [{ required: true, message: t('page.form.rulePlayerRequired'), trigger: 'change' }],
|
|
||||||
lottery_config_id: [{ required: true, message: t('page.form.ruleLotteryConfigRequired'), trigger: 'change' }],
|
|
||||||
lottery_type: [{ required: true, message: t('page.form.ruleLotteryTypeRequired'), trigger: 'change' }],
|
|
||||||
is_win: [{ required: true, message: t('page.form.ruleIsWinRequired'), trigger: 'change' }],
|
|
||||||
win_coin: [{ required: true, message: t('page.form.ruleWinCoinRequired'), trigger: 'blur' }],
|
|
||||||
rollArrayItems: [
|
|
||||||
{
|
|
||||||
validator: (_rule: any, value: (number | null)[], callback: (e?: Error) => void) => {
|
|
||||||
if (!value || value.length !== 5) {
|
|
||||||
callback(new Error(t('page.form.ruleRollArrayLength')))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const ok = value.every((n) => n != null && n >= 1 && n <= 6)
|
|
||||||
if (!ok) {
|
|
||||||
callback(new Error(t('page.form.ruleRollArrayValues')))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
callback()
|
|
||||||
},
|
|
||||||
trigger: 'change'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
reward_tier: [{ required: true, message: t('page.form.ruleRewardTierRequired'), trigger: 'change' }]
|
|
||||||
}))
|
|
||||||
|
|
||||||
const playerOptions = ref<Array<{ id: number; username: string }>>([])
|
const playerOptions = ref<Array<{ id: number; username: string }>>([])
|
||||||
const lotteryConfigOptions = ref<Array<{ id: number; name: string }>>([])
|
const lotteryConfigOptions = ref<Array<{ id: number; name: string }>>([])
|
||||||
|
|
||||||
@@ -376,46 +345,6 @@
|
|||||||
visible.value = false
|
visible.value = false
|
||||||
formRef.value?.resetFields()
|
formRef.value?.resetFields()
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
|
||||||
if (!formRef.value) return
|
|
||||||
try {
|
|
||||||
await formRef.value.validate()
|
|
||||||
const payload = { ...formData } as Record<string, unknown>
|
|
||||||
// 将 5 个输入值拼成 [1,2,3,4,5] 格式,确保每项为 1~6 的整数
|
|
||||||
const items = formData.rollArrayItems
|
|
||||||
const rollArray = items.map((n) => {
|
|
||||||
const v = n != null ? Number(n) : 1
|
|
||||||
return Math.min(6, Math.max(1, Number.isNaN(v) ? 1 : Math.floor(v)))
|
|
||||||
})
|
|
||||||
payload.roll_array = rollArray
|
|
||||||
payload.roll_number = formData.roll_number ?? rollArray.reduce((s, n) => s + n, 0)
|
|
||||||
delete payload.rollArrayItems
|
|
||||||
if (props.dialogType === 'add') {
|
|
||||||
delete payload.id
|
|
||||||
await api.save(withChannelDeptParams(payload))
|
|
||||||
ElMessage.success(t('page.form.addSuccess'))
|
|
||||||
} else {
|
|
||||||
await api.update(withChannelDeptParams(payload))
|
|
||||||
ElMessage.success(t('page.form.editSuccess'))
|
|
||||||
}
|
|
||||||
emit('success')
|
|
||||||
handleClose()
|
|
||||||
} catch (error: any) {
|
|
||||||
let msg = t('page.form.validateFailed')
|
|
||||||
if (error?.message) {
|
|
||||||
msg = error.message
|
|
||||||
} else if (typeof error === 'string') {
|
|
||||||
msg = error
|
|
||||||
} else if (error && typeof error === 'object') {
|
|
||||||
const first = Object.values(error).find((v: any) => v?.[0]?.message)
|
|
||||||
if (first && Array.isArray(first)) {
|
|
||||||
msg = (first[0] as any).message || msg
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ElMessage.warning(msg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog
|
<el-dialog
|
||||||
v-model="visible"
|
v-model="visible"
|
||||||
:title="dialogType === 'add' ? $t('page.form.titleAdd') : $t('page.form.titleEdit')"
|
:title="$t('page.form.titleEdit')"
|
||||||
width="600px"
|
width="600px"
|
||||||
align-center
|
align-center
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
@close="handleClose"
|
@close="handleClose"
|
||||||
>
|
>
|
||||||
<el-form ref="formRef" :model="formData" :rules="rules" label-width="120px">
|
<el-form ref="formRef" :model="formData" label-width="120px">
|
||||||
<el-form-item :label="$t('page.form.labelLotteryConfigId')" prop="lottery_config_id">
|
<el-form-item :label="$t('page.form.labelLotteryConfigId')" prop="lottery_config_id">
|
||||||
<el-input v-model="formData.lottery_config_id" :placeholder="$t('page.form.placeholderLotteryConfigId')" />
|
<el-input v-model="formData.lottery_config_id" :placeholder="$t('page.form.placeholderLotteryConfigId')" disabled />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('page.form.drawType')" prop="lottery_type">
|
<el-form-item :label="$t('page.form.drawType')" prop="lottery_type">
|
||||||
<el-select
|
<el-select
|
||||||
@@ -17,13 +17,20 @@
|
|||||||
:placeholder="$t('form.placeholderSelect')"
|
:placeholder="$t('form.placeholderSelect')"
|
||||||
clearable
|
clearable
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
|
disabled
|
||||||
>
|
>
|
||||||
<el-option :label="$t('page.search.paid')" :value="0" />
|
<el-option :label="$t('page.search.paid')" :value="0" />
|
||||||
<el-option :label="$t('page.search.free')" :value="1" />
|
<el-option :label="$t('page.search.free')" :value="1" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('page.search.direction')" prop="direction">
|
<el-form-item :label="$t('page.search.direction')" prop="direction">
|
||||||
<el-select v-model="formData.direction" :placeholder="$t('form.placeholderSelect')" clearable style="width: 100%">
|
<el-select
|
||||||
|
v-model="formData.direction"
|
||||||
|
:placeholder="$t('form.placeholderSelect')"
|
||||||
|
clearable
|
||||||
|
style="width: 100%"
|
||||||
|
disabled
|
||||||
|
>
|
||||||
<el-option :label="$t('page.search.clockwise')" :value="0" />
|
<el-option :label="$t('page.search.clockwise')" :value="0" />
|
||||||
<el-option :label="$t('page.search.anticlockwise')" :value="1" />
|
<el-option :label="$t('page.search.anticlockwise')" :value="1" />
|
||||||
</el-select>
|
</el-select>
|
||||||
@@ -35,6 +42,7 @@
|
|||||||
:precision="0"
|
:precision="0"
|
||||||
controls-position="right"
|
controls-position="right"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
|
disabled
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('page.search.paidAmount')" prop="paid_amount">
|
<el-form-item :label="$t('page.search.paidAmount')" prop="paid_amount">
|
||||||
@@ -44,10 +52,11 @@
|
|||||||
:precision="0"
|
:precision="0"
|
||||||
controls-position="right"
|
controls-position="right"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
|
disabled
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('page.search.isBigWin')" prop="is_win">
|
<el-form-item :label="$t('page.search.isBigWin')" prop="is_win">
|
||||||
<el-select v-model="formData.is_win" :placeholder="$t('form.placeholderSelect')" clearable style="width: 100%">
|
<el-select v-model="formData.is_win" :placeholder="$t('form.placeholderSelect')" clearable style="width: 100%" disabled>
|
||||||
<el-option :label="$t('page.search.noBigWin')" :value="0" />
|
<el-option :label="$t('page.search.noBigWin')" :value="0" />
|
||||||
<el-option :label="$t('page.search.bigWin')" :value="1" />
|
<el-option :label="$t('page.search.bigWin')" :value="1" />
|
||||||
</el-select>
|
</el-select>
|
||||||
@@ -59,6 +68,7 @@
|
|||||||
:precision="0"
|
:precision="0"
|
||||||
controls-position="right"
|
controls-position="right"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
|
disabled
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('page.search.rewardTier')" prop="reward_tier">
|
<el-form-item :label="$t('page.search.rewardTier')" prop="reward_tier">
|
||||||
@@ -67,6 +77,7 @@
|
|||||||
:placeholder="$t('page.form.placeholderRewardTier')"
|
:placeholder="$t('page.form.placeholderRewardTier')"
|
||||||
clearable
|
clearable
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
|
disabled
|
||||||
>
|
>
|
||||||
<el-option label="T1" value="T1" />
|
<el-option label="T1" value="T1" />
|
||||||
<el-option label="T2" value="T2" />
|
<el-option label="T2" value="T2" />
|
||||||
@@ -77,19 +88,19 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('page.table.startIndex')" prop="start_index">
|
<el-form-item :label="$t('page.table.startIndex')" prop="start_index">
|
||||||
<el-input v-model="formData.start_index" :placeholder="$t('page.form.placeholderStartIndex')" />
|
<el-input v-model="formData.start_index" :placeholder="$t('page.form.placeholderStartIndex')" disabled />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('page.form.labelTargetIndex')" prop="target_index">
|
<el-form-item :label="$t('page.form.labelTargetIndex')" prop="target_index">
|
||||||
<el-input v-model="formData.target_index" :placeholder="$t('page.form.placeholderTargetIndex')" />
|
<el-input v-model="formData.target_index" :placeholder="$t('page.form.placeholderTargetIndex')" disabled />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('page.search.rollNumber')" prop="roll_number">
|
<el-form-item :label="$t('page.search.rollNumber')" prop="roll_number">
|
||||||
<el-input v-model="formData.roll_number" :placeholder="$t('page.form.placeholderRollNumber')" />
|
<el-input v-model="formData.roll_number" :placeholder="$t('page.form.placeholderRollNumber')" disabled />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('page.form.labelRollArray')" prop="roll_array">
|
<el-form-item :label="$t('page.form.labelRollArray')" prop="roll_array">
|
||||||
<el-input v-model="formData.roll_array" :placeholder="$t('page.form.placeholderRollArray')" />
|
<el-input v-model="formData.roll_array" :placeholder="$t('page.form.placeholderRollArray')" disabled />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('page.form.labelStatus')" prop="status">
|
<el-form-item :label="$t('page.form.labelStatus')" prop="status">
|
||||||
<sa-radio v-model="formData.status" dict="data_status" />
|
<sa-radio v-model="formData.status" dict="data_status" disabled />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('page.table.superWinCoin')" prop="super_win_coin">
|
<el-form-item :label="$t('page.table.superWinCoin')" prop="super_win_coin">
|
||||||
<el-input-number
|
<el-input-number
|
||||||
@@ -98,6 +109,7 @@
|
|||||||
:precision="0"
|
:precision="0"
|
||||||
controls-position="right"
|
controls-position="right"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
|
disabled
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('page.table.rewardWinCoin')" prop="reward_win_coin">
|
<el-form-item :label="$t('page.table.rewardWinCoin')" prop="reward_win_coin">
|
||||||
@@ -107,25 +119,21 @@
|
|||||||
:precision="0"
|
:precision="0"
|
||||||
controls-position="right"
|
controls-position="right"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
|
disabled
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('page.form.labelAdminId')" prop="admin_id">
|
<el-form-item :label="$t('page.form.labelAdminId')" prop="admin_id">
|
||||||
<el-input v-model="formData.admin_id" :placeholder="$t('page.form.placeholderAdminId')" />
|
<el-input v-model="formData.admin_id" :placeholder="$t('page.form.placeholderAdminId')" disabled />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button @click="handleClose">{{ $t('common.cancel') }}</el-button>
|
<el-button @click="handleClose">{{ $t('form.close') }}</el-button>
|
||||||
<el-button type="primary" @click="handleSubmit">{{ $t('table.form.submit') }}</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import api from '../../../api/play_record_test/index'
|
import type { FormInstance } from 'element-plus'
|
||||||
import { ElMessage } from 'element-plus'
|
|
||||||
import type { FormInstance, FormRules } from 'element-plus'
|
|
||||||
import { useI18n } from 'vue-i18n'
|
|
||||||
import { withChannelDeptParams } from '@/composables/useChannelDeptScope'
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
modelValue: boolean
|
modelValue: boolean
|
||||||
@@ -140,12 +148,11 @@
|
|||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
modelValue: false,
|
modelValue: false,
|
||||||
dialogType: 'add',
|
dialogType: 'edit',
|
||||||
data: undefined
|
data: undefined
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits<Emits>()
|
const emit = defineEmits<Emits>()
|
||||||
const { t } = useI18n()
|
|
||||||
|
|
||||||
const formRef = ref<FormInstance>()
|
const formRef = ref<FormInstance>()
|
||||||
|
|
||||||
@@ -157,18 +164,6 @@
|
|||||||
set: (value) => emit('update:modelValue', value)
|
set: (value) => emit('update:modelValue', value)
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
|
||||||
* 表单验证规则
|
|
||||||
*/
|
|
||||||
const rules = computed<FormRules>(() => ({
|
|
||||||
lottery_config_id: [{ required: true, message: t('page.form.ruleLotteryConfigIdRequired'), trigger: 'blur' }],
|
|
||||||
lottery_type: [{ required: true, message: t('page.form.ruleDrawTypeRequired'), trigger: 'blur' }],
|
|
||||||
is_win: [{ required: true, message: t('page.form.ruleIsBigWinRequired'), trigger: 'blur' }],
|
|
||||||
direction: [{ required: true, message: t('page.form.ruleDirectionRequired'), trigger: 'blur' }],
|
|
||||||
reward_tier: [{ required: true, message: t('page.form.ruleRewardTierRequired'), trigger: 'blur' }],
|
|
||||||
status: [{ required: true, message: t('page.form.ruleStatusRequired'), trigger: 'blur' }]
|
|
||||||
}))
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始数据
|
* 初始数据
|
||||||
*/
|
*/
|
||||||
@@ -198,7 +193,7 @@
|
|||||||
const formData = reactive({ ...initialFormData })
|
const formData = reactive({ ...initialFormData })
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 监听弹窗打开,初始化表单数据
|
* 监听弹窗打开,初始化表单数据(仅查看)
|
||||||
*/
|
*/
|
||||||
watch(
|
watch(
|
||||||
() => props.modelValue,
|
() => props.modelValue,
|
||||||
@@ -213,9 +208,7 @@
|
|||||||
* 初始化页面数据
|
* 初始化页面数据
|
||||||
*/
|
*/
|
||||||
const initPage = async () => {
|
const initPage = async () => {
|
||||||
// 先重置为初始值
|
|
||||||
Object.assign(formData, initialFormData)
|
Object.assign(formData, initialFormData)
|
||||||
// 如果有数据,则填充数据
|
|
||||||
if (props.data) {
|
if (props.data) {
|
||||||
await nextTick()
|
await nextTick()
|
||||||
initForm()
|
initForm()
|
||||||
@@ -223,7 +216,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化表单数据
|
* 回填表单数据
|
||||||
*/
|
*/
|
||||||
function normalizePlatformCoin(val: unknown): number {
|
function normalizePlatformCoin(val: unknown): number {
|
||||||
if (val === '' || val === null || val === undefined) return 0
|
if (val === '' || val === null || val === undefined) return 0
|
||||||
@@ -245,34 +238,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 关闭弹窗并重置表单
|
* 关闭弹窗
|
||||||
*/
|
*/
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
visible.value = false
|
visible.value = false
|
||||||
formRef.value?.resetFields()
|
formRef.value?.resetFields()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 提交表单
|
|
||||||
*/
|
|
||||||
const handleSubmit = async () => {
|
|
||||||
if (!formRef.value) return
|
|
||||||
try {
|
|
||||||
await formRef.value.validate()
|
|
||||||
const payload = { ...formData }
|
|
||||||
if (props.dialogType === 'add') {
|
|
||||||
await api.save(withChannelDeptParams(payload))
|
|
||||||
ElMessage.success(t('page.form.addSuccess'))
|
|
||||||
} else {
|
|
||||||
await api.update(withChannelDeptParams(payload))
|
|
||||||
ElMessage.success(t('page.form.editSuccess'))
|
|
||||||
}
|
|
||||||
emit('success')
|
|
||||||
handleClose()
|
|
||||||
} catch (error) {
|
|
||||||
console.log('表单验证失败:', error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog
|
<el-dialog
|
||||||
v-model="visible"
|
v-model="visible"
|
||||||
:title="dialogType === 'add' ? $t('page.form.dialogTitleAdd') : $t('page.form.dialogTitleEdit')"
|
:title="$t('page.form.dialogTitleEdit')"
|
||||||
width="600px"
|
width="600px"
|
||||||
align-center
|
align-center
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
@close="handleClose"
|
@close="handleClose"
|
||||||
>
|
>
|
||||||
<el-form ref="formRef" :model="formData" :rules="rules" label-width="120px">
|
<el-form ref="formRef" :model="formData" label-width="120px">
|
||||||
<el-form-item :label="$t('page.form.player')" prop="player_id">
|
<el-form-item :label="$t('page.form.player')" prop="player_id">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="formData.player_id"
|
v-model="formData.player_id"
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
clearable
|
clearable
|
||||||
filterable
|
filterable
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
:disabled="dialogType === 'edit'"
|
disabled
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in playerOptions"
|
v-for="item in playerOptions"
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
v-model="formData.use_coins"
|
v-model="formData.use_coins"
|
||||||
:placeholder="$t('page.form.placeholderUseCoins')"
|
:placeholder="$t('page.form.placeholderUseCoins')"
|
||||||
:min="0"
|
:min="0"
|
||||||
:disabled="dialogType === 'edit'"
|
disabled
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('page.form.paidDrawCount')" prop="paid_ticket_count">
|
<el-form-item :label="$t('page.form.paidDrawCount')" prop="paid_ticket_count">
|
||||||
@@ -38,8 +38,7 @@
|
|||||||
v-model="formData.paid_ticket_count"
|
v-model="formData.paid_ticket_count"
|
||||||
:placeholder="$t('page.form.placeholderPaidDrawCount')"
|
:placeholder="$t('page.form.placeholderPaidDrawCount')"
|
||||||
:min="0"
|
:min="0"
|
||||||
@change="onTicketCountChange"
|
disabled
|
||||||
:disabled="dialogType === 'edit'"
|
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('page.form.freeDrawCount')" prop="free_ticket_count">
|
<el-form-item :label="$t('page.form.freeDrawCount')" prop="free_ticket_count">
|
||||||
@@ -47,8 +46,7 @@
|
|||||||
v-model="formData.free_ticket_count"
|
v-model="formData.free_ticket_count"
|
||||||
:placeholder="$t('page.form.placeholderFreeDrawCount')"
|
:placeholder="$t('page.form.placeholderFreeDrawCount')"
|
||||||
:min="0"
|
:min="0"
|
||||||
@change="onTicketCountChange"
|
disabled
|
||||||
:disabled="dialogType === 'edit'"
|
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('page.form.totalDrawCount')" prop="total_ticket_count">
|
<el-form-item :label="$t('page.form.totalDrawCount')" prop="total_ticket_count">
|
||||||
@@ -68,25 +66,20 @@
|
|||||||
maxlength="500"
|
maxlength="500"
|
||||||
show-word-limit
|
show-word-limit
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
:disabled="dialogType === 'edit'"
|
disabled
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button @click="handleClose">{{ $t('common.cancel') }}</el-button>
|
<el-button @click="handleClose">{{ $t('form.close') }}</el-button>
|
||||||
<el-button type="primary" @click="handleSubmit">{{ $t('table.form.submit') }}</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import api from '../../../api/player_ticket_record/index'
|
import api from '../../../api/player_ticket_record/index'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { getChannelDeptRequestParams } from '@/composables/useChannelDeptScope'
|
||||||
import { getChannelDeptRequestParams, withChannelDeptParams } from '@/composables/useChannelDeptScope'
|
import type { FormInstance } from 'element-plus'
|
||||||
import { ElMessage } from 'element-plus'
|
|
||||||
import type { FormInstance, FormRules } from 'element-plus'
|
|
||||||
|
|
||||||
const { t } = useI18n()
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
modelValue: boolean
|
modelValue: boolean
|
||||||
@@ -101,7 +94,7 @@
|
|||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
modelValue: false,
|
modelValue: false,
|
||||||
dialogType: 'add',
|
dialogType: 'edit',
|
||||||
data: undefined
|
data: undefined
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -117,17 +110,6 @@
|
|||||||
set: (value) => emit('update:modelValue', value)
|
set: (value) => emit('update:modelValue', value)
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
|
||||||
* 表单验证规则
|
|
||||||
*/
|
|
||||||
const rules = reactive<FormRules>({
|
|
||||||
player_id: [{ required: true, message: t('page.form.rulePlayerRequired'), trigger: 'change' }],
|
|
||||||
use_coins: [{ required: true, message: t('page.form.ruleUseCoinsRequired'), trigger: 'blur' }],
|
|
||||||
paid_ticket_count: [{ required: true, message: t('page.form.rulePaidDrawRequired'), trigger: 'blur' }],
|
|
||||||
free_ticket_count: [{ required: true, message: t('page.form.ruleFreeDrawRequired'), trigger: 'blur' }],
|
|
||||||
remark: [{ required: true, message: t('page.form.ruleRemarkRequired'), trigger: 'blur' }]
|
|
||||||
})
|
|
||||||
|
|
||||||
/** 玩家下拉选项(id、username) */
|
/** 玩家下拉选项(id、username) */
|
||||||
const playerOptions = ref<Array<{ id: number; username: string }>>([])
|
const playerOptions = ref<Array<{ id: number; username: string }>>([])
|
||||||
|
|
||||||
@@ -138,10 +120,6 @@
|
|||||||
return paid + free
|
return paid + free
|
||||||
})
|
})
|
||||||
|
|
||||||
function onTicketCountChange() {
|
|
||||||
formData.total_ticket_count = totalTicketCountComputed.value
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始数据
|
* 初始数据
|
||||||
*/
|
*/
|
||||||
@@ -161,7 +139,7 @@
|
|||||||
const formData = reactive({ ...initialFormData })
|
const formData = reactive({ ...initialFormData })
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 监听弹窗打开,初始化表单并拉取玩家选项(与 player_wallet_record 一致)
|
* 监听弹窗打开,初始化表单并拉取玩家选项
|
||||||
*/
|
*/
|
||||||
watch(
|
watch(
|
||||||
() => props.modelValue,
|
() => props.modelValue,
|
||||||
@@ -182,7 +160,7 @@
|
|||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化页面数据(仅重置表单、回填编辑数据,不在此处请求玩家列表)
|
* 初始化页面数据
|
||||||
*/
|
*/
|
||||||
const initPage = async () => {
|
const initPage = async () => {
|
||||||
Object.assign(formData, { ...initialFormData })
|
Object.assign(formData, { ...initialFormData })
|
||||||
@@ -193,7 +171,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化表单数据
|
* 回填表单数据
|
||||||
*/
|
*/
|
||||||
const initForm = () => {
|
const initForm = () => {
|
||||||
if (!props.data) return
|
if (!props.data) return
|
||||||
@@ -215,34 +193,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 关闭弹窗并重置表单
|
* 关闭弹窗
|
||||||
*/
|
*/
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
visible.value = false
|
visible.value = false
|
||||||
formRef.value?.resetFields()
|
formRef.value?.resetFields()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 提交表单(total_ticket_count 由 paid_ticket_count + free_ticket_count 自动求和,提交前写入)
|
|
||||||
*/
|
|
||||||
const handleSubmit = async () => {
|
|
||||||
if (!formRef.value) return
|
|
||||||
try {
|
|
||||||
formData.total_ticket_count = totalTicketCountComputed.value
|
|
||||||
await formRef.value.validate()
|
|
||||||
if (props.dialogType === 'add') {
|
|
||||||
const rest = { ...formData } as Record<string, unknown>
|
|
||||||
delete rest.id
|
|
||||||
await api.save(withChannelDeptParams(rest))
|
|
||||||
ElMessage.success(t('page.form.addSuccess'))
|
|
||||||
} else {
|
|
||||||
await api.update(withChannelDeptParams(formData))
|
|
||||||
ElMessage.success(t('page.form.editSuccess'))
|
|
||||||
}
|
|
||||||
emit('success')
|
|
||||||
handleClose()
|
|
||||||
} catch (error) {
|
|
||||||
console.log('表单验证失败:', error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog
|
<el-dialog
|
||||||
v-model="visible"
|
v-model="visible"
|
||||||
:title="dialogType === 'add' ? $t('page.form.dialogTitleAdd') : $t('page.form.dialogTitleEdit')"
|
:title="$t('page.form.dialogTitleEdit')"
|
||||||
width="600px"
|
width="600px"
|
||||||
align-center
|
align-center
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
@close="handleClose"
|
@close="handleClose"
|
||||||
>
|
>
|
||||||
<el-form ref="formRef" :model="formData" :rules="rules" label-width="120px">
|
<el-form ref="formRef" :model="formData" label-width="120px">
|
||||||
<el-form-item :label="$t('page.form.user')" prop="player_id">
|
<el-form-item :label="$t('page.form.user')" prop="player_id">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="formData.player_id"
|
v-model="formData.player_id"
|
||||||
@@ -15,8 +15,7 @@
|
|||||||
clearable
|
clearable
|
||||||
filterable
|
filterable
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
:disabled="dialogType === 'edit'"
|
disabled
|
||||||
@change="onPlayerChange"
|
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in playerOptions"
|
v-for="item in playerOptions"
|
||||||
@@ -32,7 +31,7 @@
|
|||||||
:placeholder="$t('page.form.placeholderType')"
|
:placeholder="$t('page.form.placeholderType')"
|
||||||
clearable
|
clearable
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
:disabled="dialogType === 'edit'"
|
disabled
|
||||||
>
|
>
|
||||||
<el-option :label="$t('page.form.typeRecharge')" :value="0" />
|
<el-option :label="$t('page.form.typeRecharge')" :value="0" />
|
||||||
<el-option :label="$t('page.form.typeWithdraw')" :value="1" />
|
<el-option :label="$t('page.form.typeWithdraw')" :value="1" />
|
||||||
@@ -48,8 +47,7 @@
|
|||||||
:precision="2"
|
:precision="2"
|
||||||
:step="1"
|
:step="1"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
@change="onCoinChange"
|
disabled
|
||||||
:disabled="dialogType === 'edit'"
|
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('page.form.walletBefore')" prop="wallet_before">
|
<el-form-item :label="$t('page.form.walletBefore')" prop="wallet_before">
|
||||||
@@ -78,25 +76,20 @@
|
|||||||
:placeholder="$t('page.form.placeholderRemark')"
|
:placeholder="$t('page.form.placeholderRemark')"
|
||||||
maxlength="500"
|
maxlength="500"
|
||||||
show-word-limit
|
show-word-limit
|
||||||
:disabled="dialogType === 'edit'"
|
disabled
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button @click="handleClose">{{ $t('common.cancel') }}</el-button>
|
<el-button @click="handleClose">{{ $t('form.close') }}</el-button>
|
||||||
<el-button type="primary" @click="handleSubmit">{{ $t('table.form.submit') }}</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import api from '../../../api/player_wallet_record/index'
|
import api from '../../../api/player_wallet_record/index'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { getChannelDeptRequestParams } from '@/composables/useChannelDeptScope'
|
||||||
import { getChannelDeptRequestParams, withChannelDeptParams } from '@/composables/useChannelDeptScope'
|
import type { FormInstance } from 'element-plus'
|
||||||
import { ElMessage } from 'element-plus'
|
|
||||||
import type { FormInstance, FormRules } from 'element-plus'
|
|
||||||
|
|
||||||
const { t } = useI18n()
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
modelValue: boolean
|
modelValue: boolean
|
||||||
@@ -111,7 +104,7 @@
|
|||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
modelValue: false,
|
modelValue: false,
|
||||||
dialogType: 'add',
|
dialogType: 'edit',
|
||||||
data: undefined
|
data: undefined
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -127,12 +120,6 @@
|
|||||||
set: (value) => emit('update:modelValue', value)
|
set: (value) => emit('update:modelValue', value)
|
||||||
})
|
})
|
||||||
|
|
||||||
const rules = reactive<FormRules>({
|
|
||||||
player_id: [{ required: true, message: t('page.form.ruleUserRequired'), trigger: 'change' }],
|
|
||||||
coin: [{ required: true, message: t('page.form.ruleCoinRequired'), trigger: 'blur' }],
|
|
||||||
type: [{ required: true, message: t('page.form.ruleTypeRequired'), trigger: 'change' }]
|
|
||||||
})
|
|
||||||
|
|
||||||
const initialFormData: {
|
const initialFormData: {
|
||||||
id: number | null
|
id: number | null
|
||||||
player_id: number | null
|
player_id: number | null
|
||||||
@@ -153,36 +140,6 @@
|
|||||||
|
|
||||||
const formData = reactive({ ...initialFormData })
|
const formData = reactive({ ...initialFormData })
|
||||||
|
|
||||||
/** 选择用户后拉取当前平台币作为钱包操作前 */
|
|
||||||
async function onPlayerChange(playerId: number | null) {
|
|
||||||
if (playerId == null) {
|
|
||||||
formData.wallet_before = 0
|
|
||||||
calcWalletAfter()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const res = await api.getPlayerWalletBefore(playerId)
|
|
||||||
const before = res?.wallet_before ?? 0
|
|
||||||
formData.wallet_before = Number(before)
|
|
||||||
calcWalletAfter()
|
|
||||||
} catch {
|
|
||||||
formData.wallet_before = 0
|
|
||||||
calcWalletAfter()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 平台币变化时重算钱包操作后 */
|
|
||||||
function onCoinChange() {
|
|
||||||
calcWalletAfter()
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 钱包操作后 = 钱包操作前 + 平台币变化 */
|
|
||||||
function calcWalletAfter() {
|
|
||||||
const before = Number(formData.wallet_before) || 0
|
|
||||||
const coin = Number(formData.coin) || 0
|
|
||||||
formData.wallet_after = Number((before + coin).toFixed(2))
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.modelValue,
|
() => props.modelValue,
|
||||||
async (open) => {
|
async (open) => {
|
||||||
@@ -230,24 +187,4 @@
|
|||||||
visible.value = false
|
visible.value = false
|
||||||
formRef.value?.resetFields()
|
formRef.value?.resetFields()
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
|
||||||
if (!formRef.value) return
|
|
||||||
try {
|
|
||||||
await formRef.value.validate()
|
|
||||||
calcWalletAfter()
|
|
||||||
const payload = { ...formData }
|
|
||||||
if (props.dialogType === 'add') {
|
|
||||||
await api.save(withChannelDeptParams(payload))
|
|
||||||
ElMessage.success(t('page.form.addSuccess'))
|
|
||||||
} else {
|
|
||||||
await api.update(withChannelDeptParams(payload))
|
|
||||||
ElMessage.success(t('page.form.editSuccess'))
|
|
||||||
}
|
|
||||||
emit('success')
|
|
||||||
handleClose()
|
|
||||||
} catch (error) {
|
|
||||||
console.log('表单验证失败:', error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,36 +1,31 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog
|
<el-dialog
|
||||||
v-model="visible"
|
v-model="visible"
|
||||||
:title="dialogType === 'add' ? $t('page.form.titleAdd') : $t('page.form.titleEdit')"
|
:title="$t('page.form.titleEdit')"
|
||||||
width="600px"
|
width="600px"
|
||||||
align-center
|
align-center
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
@close="handleClose"
|
@close="handleClose"
|
||||||
>
|
>
|
||||||
<el-form ref="formRef" :model="formData" :rules="rules" label-width="120px">
|
<el-form ref="formRef" :model="formData" label-width="120px">
|
||||||
<el-form-item :label="$t('page.form.labelTestCount')" prop="test_count">
|
<el-form-item :label="$t('page.form.labelTestCount')" prop="test_count">
|
||||||
<el-input v-model="formData.test_count" :placeholder="$t('page.form.placeholderTestCount')" />
|
<el-input v-model="formData.test_count" :placeholder="$t('page.form.placeholderTestCount')" disabled />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('page.form.labelWeightSnapshot')" prop="weight_config_snapshot">
|
<el-form-item :label="$t('page.form.labelWeightSnapshot')" prop="weight_config_snapshot">
|
||||||
<el-input v-model="formData.weight_config_snapshot" :placeholder="$t('page.form.placeholderWeightSnapshot')" />
|
<el-input v-model="formData.weight_config_snapshot" :placeholder="$t('page.form.placeholderWeightSnapshot')" disabled />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('page.form.labelResultCounts')" prop="result_counts">
|
<el-form-item :label="$t('page.form.labelResultCounts')" prop="result_counts">
|
||||||
<el-input v-model="formData.result_counts" :placeholder="$t('page.form.placeholderResultCounts')" />
|
<el-input v-model="formData.result_counts" :placeholder="$t('page.form.placeholderResultCounts')" disabled />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button @click="handleClose">{{ $t('common.cancel') }}</el-button>
|
<el-button @click="handleClose">{{ $t('form.close') }}</el-button>
|
||||||
<el-button type="primary" @click="handleSubmit">{{ $t('table.form.submit') }}</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import api from '../../../api/reward_config_record/index'
|
import type { FormInstance } from 'element-plus'
|
||||||
import { ElMessage } from 'element-plus'
|
|
||||||
import type { FormInstance, FormRules } from 'element-plus'
|
|
||||||
import { useI18n } from 'vue-i18n'
|
|
||||||
import { withChannelDeptParams } from '@/composables/useChannelDeptScope'
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
modelValue: boolean
|
modelValue: boolean
|
||||||
@@ -45,12 +40,11 @@
|
|||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
modelValue: false,
|
modelValue: false,
|
||||||
dialogType: 'add',
|
dialogType: 'edit',
|
||||||
data: undefined
|
data: undefined
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits<Emits>()
|
const emit = defineEmits<Emits>()
|
||||||
const { t } = useI18n()
|
|
||||||
|
|
||||||
const formRef = ref<FormInstance>()
|
const formRef = ref<FormInstance>()
|
||||||
|
|
||||||
@@ -62,13 +56,6 @@
|
|||||||
set: (value) => emit('update:modelValue', value)
|
set: (value) => emit('update:modelValue', value)
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
|
||||||
* 表单验证规则
|
|
||||||
*/
|
|
||||||
const rules = computed<FormRules>(() => ({
|
|
||||||
test_count: [{ required: true, message: t('page.form.ruleTestCountRequired'), trigger: 'blur' }]
|
|
||||||
}))
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始数据
|
* 初始数据
|
||||||
*/
|
*/
|
||||||
@@ -76,7 +63,7 @@
|
|||||||
id: null,
|
id: null,
|
||||||
test_count: 100,
|
test_count: 100,
|
||||||
weight_config_snapshot: '',
|
weight_config_snapshot: '',
|
||||||
result_counts: '',
|
result_counts: ''
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -85,7 +72,7 @@
|
|||||||
const formData = reactive({ ...initialFormData })
|
const formData = reactive({ ...initialFormData })
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 监听弹窗打开,初始化表单数据
|
* 监听弹窗打开,初始化表单数据(仅查看)
|
||||||
*/
|
*/
|
||||||
watch(
|
watch(
|
||||||
() => props.modelValue,
|
() => props.modelValue,
|
||||||
@@ -100,9 +87,7 @@
|
|||||||
* 初始化页面数据
|
* 初始化页面数据
|
||||||
*/
|
*/
|
||||||
const initPage = async () => {
|
const initPage = async () => {
|
||||||
// 先重置为初始值
|
|
||||||
Object.assign(formData, initialFormData)
|
Object.assign(formData, initialFormData)
|
||||||
// 如果有数据,则填充数据
|
|
||||||
if (props.data) {
|
if (props.data) {
|
||||||
await nextTick()
|
await nextTick()
|
||||||
initForm()
|
initForm()
|
||||||
@@ -110,7 +95,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化表单数据
|
* 回填表单数据
|
||||||
*/
|
*/
|
||||||
const initForm = () => {
|
const initForm = () => {
|
||||||
if (props.data) {
|
if (props.data) {
|
||||||
@@ -123,31 +108,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 关闭弹窗并重置表单
|
* 关闭弹窗
|
||||||
*/
|
*/
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
visible.value = false
|
visible.value = false
|
||||||
formRef.value?.resetFields()
|
formRef.value?.resetFields()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 提交表单
|
|
||||||
*/
|
|
||||||
const handleSubmit = async () => {
|
|
||||||
if (!formRef.value) return
|
|
||||||
try {
|
|
||||||
await formRef.value.validate()
|
|
||||||
if (props.dialogType === 'add') {
|
|
||||||
await api.save(withChannelDeptParams(formData))
|
|
||||||
ElMessage.success(t('page.form.addSuccess'))
|
|
||||||
} else {
|
|
||||||
await api.update(withChannelDeptParams(formData))
|
|
||||||
ElMessage.success(t('page.form.editSuccess'))
|
|
||||||
}
|
|
||||||
emit('success')
|
|
||||||
handleClose()
|
|
||||||
} catch (error) {
|
|
||||||
console.log('表单验证失败:', error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ namespace app\api\controller\v1;
|
|||||||
use app\api\cache\AuthTokenCache;
|
use app\api\cache\AuthTokenCache;
|
||||||
use app\api\controller\BaseController;
|
use app\api\controller\BaseController;
|
||||||
use app\api\util\ReturnCode;
|
use app\api\util\ReturnCode;
|
||||||
|
use plugin\saiadmin\app\model\system\SystemUser;
|
||||||
use support\Request;
|
use support\Request;
|
||||||
use support\Response;
|
use support\Response;
|
||||||
use Tinywan\Jwt\JwtToken;
|
use Tinywan\Jwt\JwtToken;
|
||||||
@@ -54,6 +55,14 @@ class AuthTokenController extends BaseController
|
|||||||
return $this->fail('Signature verification failed', ReturnCode::FORBIDDEN);
|
return $this->fail('Signature verification failed', ReturnCode::FORBIDDEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$agent = SystemUser::where('agent_id', $agentId)->find();
|
||||||
|
if (!$agent || (int) ($agent->status ?? 0) !== 1) {
|
||||||
|
return $this->fail('Invalid agent_id', ReturnCode::FORBIDDEN);
|
||||||
|
}
|
||||||
|
if (empty($agent->dept_id) || (int) $agent->dept_id <= 0) {
|
||||||
|
return $this->fail('Agent channel is not configured', ReturnCode::FORBIDDEN);
|
||||||
|
}
|
||||||
|
|
||||||
$exp = (int) config('api.auth_token_exp', 86400);
|
$exp = (int) config('api.auth_token_exp', 86400);
|
||||||
$tokenResult = JwtToken::generateToken([
|
$tokenResult = JwtToken::generateToken([
|
||||||
'id' => 0,
|
'id' => 0,
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ use app\api\logic\UserLogic;
|
|||||||
use app\api\util\ReturnCode;
|
use app\api\util\ReturnCode;
|
||||||
use app\dice\model\game\DiceGame;
|
use app\dice\model\game\DiceGame;
|
||||||
use app\dice\model\player\DicePlayer;
|
use app\dice\model\player\DicePlayer;
|
||||||
use plugin\saiadmin\app\model\system\SystemUser;
|
|
||||||
use app\dice\model\play_record\DicePlayRecord;
|
use app\dice\model\play_record\DicePlayRecord;
|
||||||
use app\dice\model\player_wallet_record\DicePlayerWalletRecord;
|
use app\dice\model\player_wallet_record\DicePlayerWalletRecord;
|
||||||
use app\dice\model\player_ticket_record\DicePlayerTicketRecord;
|
use app\dice\model\player_ticket_record\DicePlayerTicketRecord;
|
||||||
@@ -60,7 +59,7 @@ class GameController extends BaseController
|
|||||||
public function getGameList(Request $request): Response
|
public function getGameList(Request $request): Response
|
||||||
{
|
{
|
||||||
$lang = $this->resolveLang($request->post('lang', 'zh'));
|
$lang = $this->resolveLang($request->post('lang', 'zh'));
|
||||||
$games = $this->buildPublicGameList($lang);
|
$games = $this->buildPublicGameList($lang, $this->agentDeptId($request));
|
||||||
return $this->success([
|
return $this->success([
|
||||||
'game_list' => $games,
|
'game_list' => $games,
|
||||||
]);
|
]);
|
||||||
@@ -73,7 +72,7 @@ class GameController extends BaseController
|
|||||||
public function getGameHall(Request $request): Response
|
public function getGameHall(Request $request): Response
|
||||||
{
|
{
|
||||||
$lang = $this->resolveLang($request->post('lang', 'zh'));
|
$lang = $this->resolveLang($request->post('lang', 'zh'));
|
||||||
$games = $this->buildPublicGameList($lang);
|
$games = $this->buildPublicGameList($lang, $this->agentDeptId($request));
|
||||||
$hallUrl = '';
|
$hallUrl = '';
|
||||||
if (!empty($games)) {
|
if (!empty($games)) {
|
||||||
$hallUrl = $games[0]['hall_url'] ?? '';
|
$hallUrl = $games[0]['hall_url'] ?? '';
|
||||||
@@ -106,23 +105,16 @@ class GameController extends BaseController
|
|||||||
$time = (string) time();
|
$time = (string) time();
|
||||||
}
|
}
|
||||||
|
|
||||||
$adminId = null;
|
$deptId = $this->agentDeptId($request);
|
||||||
$adminIdsInTopDept = null;
|
$adminId = $this->agentAdminId($request);
|
||||||
$agentId = trim((string) ($request->agent_id ?? ''));
|
$adminIdsInTopDept = UserLogic::getAdminIdsByAgentIdTopDept(trim((string) ($request->agent_id ?? '')));
|
||||||
if ($agentId !== '') {
|
|
||||||
$systemUser = SystemUser::where('agent_id', $agentId)->find();
|
|
||||||
if ($systemUser) {
|
|
||||||
$adminId = (int) $systemUser->id;
|
|
||||||
$adminIdsInTopDept = UserLogic::getAdminIdsByAgentIdTopDept($agentId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$lang = trim((string) ($request->post('lang', 'zh')));
|
$lang = trim((string) ($request->post('lang', 'zh')));
|
||||||
$lang = in_array($lang, ['en', 'zh'], true) ? $lang : 'zh';
|
$lang = in_array($lang, ['en', 'zh'], true) ? $lang : 'zh';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$logic = new UserLogic();
|
$logic = new UserLogic();
|
||||||
$result = $logic->loginByUsername($username, $password, $lang, 0.0, $time, $adminId, $adminIdsInTopDept);
|
$result = $logic->loginByUsername($username, $password, $lang, 0.0, $time, $adminId, $adminIdsInTopDept, $deptId);
|
||||||
} catch (\plugin\saiadmin\exception\ApiException $e) {
|
} catch (\plugin\saiadmin\exception\ApiException $e) {
|
||||||
return $this->fail($e->getMessage(), ReturnCode::PARAMS_ERROR);
|
return $this->fail($e->getMessage(), ReturnCode::PARAMS_ERROR);
|
||||||
}
|
}
|
||||||
@@ -145,24 +137,25 @@ class GameController extends BaseController
|
|||||||
{
|
{
|
||||||
$usernameRaw = $request->input('username', '');
|
$usernameRaw = $request->input('username', '');
|
||||||
$username = is_string($usernameRaw) ? trim($usernameRaw) : '';
|
$username = is_string($usernameRaw) ? trim($usernameRaw) : '';
|
||||||
|
$deptId = $this->agentDeptId($request);
|
||||||
|
|
||||||
if ($username === '') {
|
if ($username === '') {
|
||||||
return $this->fail('username is required', ReturnCode::PARAMS_ERROR);
|
return $this->fail('username is required', ReturnCode::PARAMS_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
$cached = UserCache::getPlayerInfoSnapshotByUsername($username);
|
$cached = UserCache::getPlayerInfoSnapshotByUsername($this->scopedUsername($deptId, $username));
|
||||||
if ($cached !== null) {
|
if ($cached !== null) {
|
||||||
return $this->success($cached);
|
return $this->success($cached);
|
||||||
}
|
}
|
||||||
|
|
||||||
$player = DicePlayer::field(self::PLAYER_INFO_DB_FIELDS)->where('username', $username)->find();
|
$player = DicePlayer::field(self::PLAYER_INFO_DB_FIELDS)->where('username', $username)->where('dept_id', $deptId)->find();
|
||||||
if (!$player) {
|
if (!$player) {
|
||||||
return $this->fail('User not found', ReturnCode::NOT_FOUND);
|
return $this->fail('User not found', ReturnCode::PARAMS_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
$hidden = ['password', 'lottery_config_id', 't1_weight', 't2_weight', 't3_weight', 't4_weight', 't5_weight', 'delete_time'];
|
$hidden = ['password', 'lottery_config_id', 't1_weight', 't2_weight', 't3_weight', 't4_weight', 't5_weight', 'delete_time'];
|
||||||
$info = $player->hidden($hidden)->toArray();
|
$info = $player->hidden($hidden)->toArray();
|
||||||
UserCache::setPlayerInfoSnapshotByUsername($username, $info);
|
UserCache::setPlayerInfoSnapshotByUsername($this->scopedUsername($deptId, $username), $info);
|
||||||
|
|
||||||
return $this->success($info);
|
return $this->success($info);
|
||||||
}
|
}
|
||||||
@@ -276,6 +269,7 @@ class GameController extends BaseController
|
|||||||
public function getPlayerGameRecord(Request $request): Response
|
public function getPlayerGameRecord(Request $request): Response
|
||||||
{
|
{
|
||||||
$username = trim((string) ($request->post('username', '')));
|
$username = trim((string) ($request->post('username', '')));
|
||||||
|
$deptId = $this->agentDeptId($request);
|
||||||
$startCreateTime = trim((string) ($request->post('start_create_time', '')));
|
$startCreateTime = trim((string) ($request->post('start_create_time', '')));
|
||||||
$endCreateTime = trim((string) ($request->post('end_create_time', '')));
|
$endCreateTime = trim((string) ($request->post('end_create_time', '')));
|
||||||
$window = $this->resolvePullRecordTimeWindow($startCreateTime, $endCreateTime);
|
$window = $this->resolvePullRecordTimeWindow($startCreateTime, $endCreateTime);
|
||||||
@@ -284,10 +278,10 @@ class GameController extends BaseController
|
|||||||
}
|
}
|
||||||
$limit = $this->resolvePullRecordLimit($request);
|
$limit = $this->resolvePullRecordLimit($request);
|
||||||
|
|
||||||
$query = DicePlayRecord::order('id', 'desc');
|
$query = DicePlayRecord::where('dept_id', $deptId)->order('id', 'desc');
|
||||||
|
|
||||||
if ($username !== '') {
|
if ($username !== '') {
|
||||||
$player = DicePlayer::where('username', $username)->find();
|
$player = $this->findPlayerByUsername($username, $deptId);
|
||||||
if (!$player) {
|
if (!$player) {
|
||||||
return $this->success([]);
|
return $this->success([]);
|
||||||
}
|
}
|
||||||
@@ -300,7 +294,7 @@ class GameController extends BaseController
|
|||||||
$list = $query->limit($limit)->select()->toArray();
|
$list = $query->limit($limit)->select()->toArray();
|
||||||
$playerIds = array_unique(array_column($list, 'player_id'));
|
$playerIds = array_unique(array_column($list, 'player_id'));
|
||||||
if (!empty($playerIds)) {
|
if (!empty($playerIds)) {
|
||||||
$players = DicePlayer::whereIn('id', $playerIds)->field('id,username,phone')->select()->toArray();
|
$players = DicePlayer::whereIn('id', $playerIds)->where('dept_id', $deptId)->field('id,username,phone')->select()->toArray();
|
||||||
$playerMap = [];
|
$playerMap = [];
|
||||||
foreach ($players as $p) {
|
foreach ($players as $p) {
|
||||||
$playerMap[(int) ($p['id'] ?? 0)] = $p;
|
$playerMap[(int) ($p['id'] ?? 0)] = $p;
|
||||||
@@ -321,6 +315,7 @@ class GameController extends BaseController
|
|||||||
public function getPlayerWalletRecord(Request $request): Response
|
public function getPlayerWalletRecord(Request $request): Response
|
||||||
{
|
{
|
||||||
$username = trim((string) ($request->post('username', '')));
|
$username = trim((string) ($request->post('username', '')));
|
||||||
|
$deptId = $this->agentDeptId($request);
|
||||||
$startCreateTime = trim((string) ($request->post('start_create_time', '')));
|
$startCreateTime = trim((string) ($request->post('start_create_time', '')));
|
||||||
$endCreateTime = trim((string) ($request->post('end_create_time', '')));
|
$endCreateTime = trim((string) ($request->post('end_create_time', '')));
|
||||||
$window = $this->resolvePullRecordTimeWindow($startCreateTime, $endCreateTime);
|
$window = $this->resolvePullRecordTimeWindow($startCreateTime, $endCreateTime);
|
||||||
@@ -329,10 +324,10 @@ class GameController extends BaseController
|
|||||||
}
|
}
|
||||||
$limit = $this->resolvePullRecordLimit($request);
|
$limit = $this->resolvePullRecordLimit($request);
|
||||||
|
|
||||||
$query = DicePlayerWalletRecord::order('id', 'desc');
|
$query = DicePlayerWalletRecord::where('dept_id', $deptId)->order('id', 'desc');
|
||||||
|
|
||||||
if ($username !== '') {
|
if ($username !== '') {
|
||||||
$player = DicePlayer::where('username', $username)->find();
|
$player = $this->findPlayerByUsername($username, $deptId);
|
||||||
if (!$player) {
|
if (!$player) {
|
||||||
return $this->success([]);
|
return $this->success([]);
|
||||||
}
|
}
|
||||||
@@ -357,6 +352,7 @@ class GameController extends BaseController
|
|||||||
public function getPlayerTicketRecord(Request $request): Response
|
public function getPlayerTicketRecord(Request $request): Response
|
||||||
{
|
{
|
||||||
$username = trim((string) ($request->post('username', '')));
|
$username = trim((string) ($request->post('username', '')));
|
||||||
|
$deptId = $this->agentDeptId($request);
|
||||||
$startCreateTime = trim((string) ($request->post('start_create_time', '')));
|
$startCreateTime = trim((string) ($request->post('start_create_time', '')));
|
||||||
$endCreateTime = trim((string) ($request->post('end_create_time', '')));
|
$endCreateTime = trim((string) ($request->post('end_create_time', '')));
|
||||||
$window = $this->resolvePullRecordTimeWindow($startCreateTime, $endCreateTime);
|
$window = $this->resolvePullRecordTimeWindow($startCreateTime, $endCreateTime);
|
||||||
@@ -365,10 +361,10 @@ class GameController extends BaseController
|
|||||||
}
|
}
|
||||||
$limit = $this->resolvePullRecordLimit($request);
|
$limit = $this->resolvePullRecordLimit($request);
|
||||||
|
|
||||||
$query = DicePlayerTicketRecord::order('id', 'desc');
|
$query = DicePlayerTicketRecord::where('dept_id', $deptId)->order('id', 'desc');
|
||||||
|
|
||||||
if ($username !== '') {
|
if ($username !== '') {
|
||||||
$player = DicePlayer::where('username', $username)->find();
|
$player = $this->findPlayerByUsername($username, $deptId);
|
||||||
if (!$player) {
|
if (!$player) {
|
||||||
return $this->success([]);
|
return $this->success([]);
|
||||||
}
|
}
|
||||||
@@ -394,6 +390,7 @@ class GameController extends BaseController
|
|||||||
public function setPlayerWallet(Request $request): Response
|
public function setPlayerWallet(Request $request): Response
|
||||||
{
|
{
|
||||||
$username = trim((string) ($request->post('username', '')));
|
$username = trim((string) ($request->post('username', '')));
|
||||||
|
$deptId = $this->agentDeptId($request);
|
||||||
$coin = $request->post('coin');
|
$coin = $request->post('coin');
|
||||||
|
|
||||||
if ($username === '') {
|
if ($username === '') {
|
||||||
@@ -408,9 +405,9 @@ class GameController extends BaseController
|
|||||||
return $this->fail('coin cannot be 0', ReturnCode::PARAMS_ERROR);
|
return $this->fail('coin cannot be 0', ReturnCode::PARAMS_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
$player = DicePlayer::where('username', $username)->find();
|
$player = $this->findPlayerByUsername($username, $deptId);
|
||||||
if (!$player) {
|
if (!$player) {
|
||||||
return $this->fail('User not found', ReturnCode::NOT_FOUND);
|
return $this->fail('User not found', ReturnCode::PARAMS_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
$walletBefore = (float) ($player->coin ?? 0);
|
$walletBefore = (float) ($player->coin ?? 0);
|
||||||
@@ -430,6 +427,7 @@ class GameController extends BaseController
|
|||||||
|
|
||||||
$adminId = ($player->admin_id ?? null) ? (int) $player->admin_id : null;
|
$adminId = ($player->admin_id ?? null) ? (int) $player->admin_id : null;
|
||||||
$record = DicePlayerWalletRecord::create([
|
$record = DicePlayerWalletRecord::create([
|
||||||
|
'dept_id' => $deptId,
|
||||||
'player_id' => (int) $player->id,
|
'player_id' => (int) $player->id,
|
||||||
'admin_id' => $adminId,
|
'admin_id' => $adminId,
|
||||||
'coin' => $coinVal,
|
'coin' => $coinVal,
|
||||||
@@ -452,6 +450,7 @@ class GameController extends BaseController
|
|||||||
UserCache::deleteUser($player->id);
|
UserCache::deleteUser($player->id);
|
||||||
if ($player->username !== '') {
|
if ($player->username !== '') {
|
||||||
UserCache::deletePlayerByUsername($player->username);
|
UserCache::deletePlayerByUsername($player->username);
|
||||||
|
UserCache::deletePlayerByUsername($this->scopedUsername($deptId, (string) $player->username));
|
||||||
}
|
}
|
||||||
|
|
||||||
$recordArr = $record->toArray();
|
$recordArr = $record->toArray();
|
||||||
@@ -471,13 +470,14 @@ class GameController extends BaseController
|
|||||||
return $langValue;
|
return $langValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildPublicGameList(string $lang): array
|
private function buildPublicGameList(string $lang, int $deptId): array
|
||||||
{
|
{
|
||||||
$rows = DiceGame::where('status', 1)
|
$rows = DiceGame::where('status', 1)
|
||||||
->orderBy('sort', 'asc')
|
->where('dept_id', $deptId)
|
||||||
->orderBy('id', 'asc')
|
->order('sort', 'asc')
|
||||||
->select(array_merge(self::GAME_PUBLIC_FIELDS, ['game_name', 'game_name_en']))
|
->order('id', 'asc')
|
||||||
->get()
|
->field(array_merge(self::GAME_PUBLIC_FIELDS, ['game_name', 'game_name_en']))
|
||||||
|
->select()
|
||||||
->toArray();
|
->toArray();
|
||||||
if (empty($rows)) {
|
if (empty($rows)) {
|
||||||
return [];
|
return [];
|
||||||
@@ -495,4 +495,26 @@ class GameController extends BaseController
|
|||||||
}
|
}
|
||||||
return $games;
|
return $games;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function agentDeptId(Request $request): int
|
||||||
|
{
|
||||||
|
return (int) ($request->agent_dept_id ?? 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function agentAdminId(Request $request): ?int
|
||||||
|
{
|
||||||
|
$adminId = (int) ($request->agent_admin_id ?? 0);
|
||||||
|
return $adminId > 0 ? $adminId : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function scopedUsername(int $deptId, string $username): string
|
||||||
|
{
|
||||||
|
return $deptId . ':' . $username;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function findPlayerByUsername(string $username, int $deptId): ?DicePlayer
|
||||||
|
{
|
||||||
|
$player = DicePlayer::where('username', $username)->where('dept_id', $deptId)->find();
|
||||||
|
return $player ?: null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ class UserLogic
|
|||||||
* @param int|null $adminId 创建新用户时关联的后台管理员ID(sa_system_user.id),可选
|
* @param int|null $adminId 创建新用户时关联的后台管理员ID(sa_system_user.id),可选
|
||||||
* @param int[]|null $adminIdsInTopDept 当前管理员顶级部门下的所有管理员ID,用于按部门范围查找玩家;为空时退化为仅按 username 查找
|
* @param int[]|null $adminIdsInTopDept 当前管理员顶级部门下的所有管理员ID,用于按部门范围查找玩家;为空时退化为仅按 username 查找
|
||||||
*/
|
*/
|
||||||
public function loginByUsername(string $username, string $password, string $lang, float $coin, string $time, ?int $adminId = null, ?array $adminIdsInTopDept = null): array
|
public function loginByUsername(string $username, string $password, string $lang, float $coin, string $time, ?int $adminId = null, ?array $adminIdsInTopDept = null, ?int $deptId = null): array
|
||||||
{
|
{
|
||||||
$username = trim($username);
|
$username = trim($username);
|
||||||
if ($username === '') {
|
if ($username === '') {
|
||||||
@@ -84,6 +84,9 @@ class UserLogic
|
|||||||
}
|
}
|
||||||
|
|
||||||
$query = DicePlayer::where('username', $username);
|
$query = DicePlayer::where('username', $username);
|
||||||
|
if ($deptId !== null && $deptId > 0) {
|
||||||
|
$query->where('dept_id', $deptId);
|
||||||
|
}
|
||||||
if ($adminIdsInTopDept !== null && !empty($adminIdsInTopDept)) {
|
if ($adminIdsInTopDept !== null && !empty($adminIdsInTopDept)) {
|
||||||
$query->whereIn('admin_id', $adminIdsInTopDept);
|
$query->whereIn('admin_id', $adminIdsInTopDept);
|
||||||
}
|
}
|
||||||
@@ -106,10 +109,13 @@ class UserLogic
|
|||||||
$player->password = $this->hashPassword($password);
|
$player->password = $this->hashPassword($password);
|
||||||
$player->status = self::STATUS_NORMAL;
|
$player->status = self::STATUS_NORMAL;
|
||||||
$player->coin = $coin;
|
$player->coin = $coin;
|
||||||
|
if ($deptId !== null && $deptId > 0) {
|
||||||
|
$player->dept_id = $deptId;
|
||||||
|
}
|
||||||
if ($adminId !== null && $adminId > 0) {
|
if ($adminId !== null && $adminId > 0) {
|
||||||
$player->admin_id = $adminId;
|
$player->admin_id = $adminId;
|
||||||
$adminUser = SystemUser::find($adminId);
|
$adminUser = SystemUser::find($adminId);
|
||||||
if ($adminUser && !empty($adminUser->dept_id)) {
|
if (($deptId === null || $deptId <= 0) && $adminUser && !empty($adminUser->dept_id)) {
|
||||||
$player->dept_id = $adminUser->dept_id;
|
$player->dept_id = $adminUser->dept_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,6 +131,7 @@ class UserLogic
|
|||||||
]);
|
]);
|
||||||
$token = $tokenResult['access_token'];
|
$token = $tokenResult['access_token'];
|
||||||
UserCache::setSessionByUsername($username, $token);
|
UserCache::setSessionByUsername($username, $token);
|
||||||
|
UserCache::setCurrentUserToken((int) $player->id, $token);
|
||||||
|
|
||||||
$userArr = $player->hidden(['password', 'lottery_config_id', 't1_weight', 't2_weight', 't3_weight', 't4_weight', 't5_weight'])->toArray();
|
$userArr = $player->hidden(['password', 'lottery_config_id', 't1_weight', 't2_weight', 't3_weight', 't4_weight', 't5_weight'])->toArray();
|
||||||
UserCache::setUser((int) $player->id, $userArr);
|
UserCache::setUser((int) $player->id, $userArr);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ namespace app\api\middleware;
|
|||||||
|
|
||||||
use app\api\cache\AuthTokenCache;
|
use app\api\cache\AuthTokenCache;
|
||||||
use app\api\util\ReturnCode;
|
use app\api\util\ReturnCode;
|
||||||
|
use plugin\saiadmin\app\model\system\SystemUser;
|
||||||
use plugin\saiadmin\exception\ApiException;
|
use plugin\saiadmin\exception\ApiException;
|
||||||
use Tinywan\Jwt\JwtToken;
|
use Tinywan\Jwt\JwtToken;
|
||||||
use Tinywan\Jwt\Exception\JwtTokenException;
|
use Tinywan\Jwt\Exception\JwtTokenException;
|
||||||
@@ -53,7 +54,17 @@ class AuthTokenMiddleware implements MiddlewareInterface
|
|||||||
throw new ApiException('auth-token invalid or expired', ReturnCode::TOKEN_INVALID);
|
throw new ApiException('auth-token invalid or expired', ReturnCode::TOKEN_INVALID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$agent = SystemUser::where('agent_id', $agentId)->find();
|
||||||
|
if (!$agent || (int) ($agent->status ?? 0) !== 1) {
|
||||||
|
throw new ApiException('Invalid agent_id', ReturnCode::FORBIDDEN);
|
||||||
|
}
|
||||||
|
if (empty($agent->dept_id) || (int) $agent->dept_id <= 0) {
|
||||||
|
throw new ApiException('Agent channel is not configured', ReturnCode::FORBIDDEN);
|
||||||
|
}
|
||||||
|
|
||||||
$request->agent_id = $agentId;
|
$request->agent_id = $agentId;
|
||||||
|
$request->agent_admin_id = (int) $agent->id;
|
||||||
|
$request->agent_dept_id = (int) $agent->dept_id;
|
||||||
return $handler($request);
|
return $handler($request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,10 +53,14 @@ class TokenMiddleware implements MiddlewareInterface
|
|||||||
if ($username === '') {
|
if ($username === '') {
|
||||||
throw new ApiException('Invalid or expired token', ReturnCode::TOKEN_INVALID);
|
throw new ApiException('Invalid or expired token', ReturnCode::TOKEN_INVALID);
|
||||||
}
|
}
|
||||||
|
$userId = (int) ($extend['id'] ?? 0);
|
||||||
|
if ($userId <= 0) {
|
||||||
|
throw new ApiException('Invalid or expired token', ReturnCode::TOKEN_INVALID);
|
||||||
|
}
|
||||||
|
|
||||||
$currentToken = UserCache::getSessionTokenByUsername($username);
|
$currentToken = UserCache::getCurrentUserToken($userId);
|
||||||
if ($currentToken === null || $currentToken === '') {
|
if ($currentToken === null || $currentToken === '') {
|
||||||
$player = DicePlayer::where('username', $username)->find();
|
$player = DicePlayer::find($userId);
|
||||||
if (!$player) {
|
if (!$player) {
|
||||||
throw new ApiException('Please register', ReturnCode::TOKEN_INVALID);
|
throw new ApiException('Please register', ReturnCode::TOKEN_INVALID);
|
||||||
}
|
}
|
||||||
@@ -68,17 +72,17 @@ class TokenMiddleware implements MiddlewareInterface
|
|||||||
|
|
||||||
// 优先从 Redis 缓存取玩家,避免每次请求都查库
|
// 优先从 Redis 缓存取玩家,避免每次请求都查库
|
||||||
$player = null;
|
$player = null;
|
||||||
$cached = UserCache::getPlayerByUsername($username);
|
$cached = UserCache::getUser($userId);
|
||||||
if ($cached !== null && isset($cached['id'])) {
|
if (!empty($cached) && isset($cached['id']) && (int) $cached['id'] === $userId) {
|
||||||
$player = (new DicePlayer())->data($cached, true);
|
$player = (new DicePlayer())->data($cached, true);
|
||||||
}
|
}
|
||||||
if ($player === null) {
|
if ($player === null) {
|
||||||
$player = DicePlayer::where('username', $username)->find();
|
$player = DicePlayer::find($userId);
|
||||||
if (!$player) {
|
if (!$player) {
|
||||||
UserCache::deleteSessionByUsername($username);
|
UserCache::deleteSessionByUsername($username);
|
||||||
throw new ApiException('Please login again', ReturnCode::TOKEN_INVALID);
|
throw new ApiException('Please login again', ReturnCode::TOKEN_INVALID);
|
||||||
}
|
}
|
||||||
UserCache::setPlayerByUsername($username, $player->hidden(['password'])->toArray());
|
UserCache::setUser($userId, $player->hidden(['password'])->toArray());
|
||||||
}
|
}
|
||||||
$request->player_id = (int) $player->id;
|
$request->player_id = (int) $player->id;
|
||||||
$request->player = $player;
|
$request->player = $player;
|
||||||
|
|||||||
@@ -144,31 +144,6 @@ class DicePlayRecordController extends BaseController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新数据
|
|
||||||
* @param Request $request
|
|
||||||
* @return Response
|
|
||||||
*/
|
|
||||||
#[Permission('玩家抽奖记录修改', 'dice:play_record:index:update')]
|
|
||||||
public function update(Request $request): Response
|
|
||||||
{
|
|
||||||
$data = $request->post();
|
|
||||||
$this->validate('update', $data);
|
|
||||||
$model = $this->logic->read($data['id'] ?? 0);
|
|
||||||
if ($model) {
|
|
||||||
$recordDeptId = is_array($model) ? ($model['dept_id'] ?? null) : ($model->dept_id ?? null);
|
|
||||||
if (! AdminScopeHelper::canAccessDept($this->adminInfo ?? null, $recordDeptId, $request->input('dept_id'))) {
|
|
||||||
return $this->fail('no permission to update this record');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$result = $this->logic->edit($data['id'], $data);
|
|
||||||
if ($result) {
|
|
||||||
return $this->success('update success');
|
|
||||||
} else {
|
|
||||||
return $this->fail('update failed');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除数据
|
* 删除数据
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
|
|||||||
@@ -103,31 +103,6 @@ class DicePlayRecordTestController extends BaseController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新数据
|
|
||||||
* @param Request $request
|
|
||||||
* @return Response
|
|
||||||
*/
|
|
||||||
#[Permission('玩家抽奖记录(测试数据)修改', 'dice:play_record_test:index:update')]
|
|
||||||
public function update(Request $request): Response
|
|
||||||
{
|
|
||||||
$data = $request->post();
|
|
||||||
$this->validate('update', $data);
|
|
||||||
$model = $this->logic->read($data['id'] ?? 0);
|
|
||||||
if ($model) {
|
|
||||||
$recordDeptId = is_array($model) ? ($model['dept_id'] ?? null) : ($model->dept_id ?? null);
|
|
||||||
if (! AdminScopeHelper::canAccessDept($this->adminInfo ?? null, $recordDeptId, $request->input('dept_id'))) {
|
|
||||||
return $this->fail('no permission to update this record');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$result = $this->logic->edit($data['id'], $data);
|
|
||||||
if ($result) {
|
|
||||||
return $this->success('update success');
|
|
||||||
} else {
|
|
||||||
return $this->fail('update failed');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除数据
|
* 删除数据
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
|
|||||||
@@ -117,31 +117,6 @@ class DicePlayerTicketRecordController extends BaseController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新数据
|
|
||||||
* @param Request $request
|
|
||||||
* @return Response
|
|
||||||
*/
|
|
||||||
#[Permission('抽奖券获取记录修改', 'dice:player_ticket_record:index:update')]
|
|
||||||
public function update(Request $request): Response
|
|
||||||
{
|
|
||||||
$data = $request->post();
|
|
||||||
$this->validate('update', $data);
|
|
||||||
$model = $this->logic->read($data['id'] ?? 0);
|
|
||||||
if ($model) {
|
|
||||||
$recordDeptId = is_array($model) ? ($model['dept_id'] ?? null) : ($model->dept_id ?? null);
|
|
||||||
if (! AdminScopeHelper::canAccessDept($this->adminInfo ?? null, $recordDeptId, $request->input('dept_id'))) {
|
|
||||||
return $this->fail('no permission to update this record');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$result = $this->logic->edit($data['id'], $data);
|
|
||||||
if ($result) {
|
|
||||||
return $this->success('update success');
|
|
||||||
} else {
|
|
||||||
return $this->fail('update failed');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除数据
|
* 删除数据
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
|
|||||||
@@ -200,28 +200,4 @@ class DicePlayerWalletRecordController extends BaseController
|
|||||||
return $this->fail('add failed');
|
return $this->fail('add failed');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新数据
|
|
||||||
* @param Request $request
|
|
||||||
* @return Response
|
|
||||||
*/
|
|
||||||
#[Permission('玩家钱包流水修改', 'dice:player_wallet_record:index:update')]
|
|
||||||
public function update(Request $request): Response
|
|
||||||
{
|
|
||||||
$data = $request->post();
|
|
||||||
$this->validate('update', $data);
|
|
||||||
$model = $this->logic->read($data['id'] ?? 0);
|
|
||||||
if ($model) {
|
|
||||||
$recordDeptId = is_array($model) ? ($model['dept_id'] ?? null) : ($model->dept_id ?? null);
|
|
||||||
if (! AdminScopeHelper::canAccessDept($this->adminInfo ?? null, $recordDeptId, $request->input('dept_id'))) {
|
|
||||||
return $this->fail('no permission to update this record');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$result = $this->logic->edit($data['id'], $data);
|
|
||||||
if ($result) {
|
|
||||||
return $this->success('update success');
|
|
||||||
} else {
|
|
||||||
return $this->fail('update failed');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,31 +107,6 @@ class DiceRewardConfigRecordController extends BaseController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新数据
|
|
||||||
* @param Request $request
|
|
||||||
* @return Response
|
|
||||||
*/
|
|
||||||
#[Permission('奖励配置权重测试记录修改', 'dice:reward_config_record:index:update')]
|
|
||||||
public function update(Request $request): Response
|
|
||||||
{
|
|
||||||
$data = $request->post();
|
|
||||||
$this->validate('update', $data);
|
|
||||||
$model = $this->logic->read($data['id'] ?? 0);
|
|
||||||
if ($model) {
|
|
||||||
$recordDeptId = is_array($model) ? ($model['dept_id'] ?? null) : ($model->dept_id ?? null);
|
|
||||||
if (! AdminScopeHelper::canAccessDept($this->adminInfo ?? null, $recordDeptId, $request->input('dept_id'))) {
|
|
||||||
return $this->fail('no permission to update this record');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$result = $this->logic->edit($data['id'], $data);
|
|
||||||
if ($result) {
|
|
||||||
return $this->success('update success');
|
|
||||||
} else {
|
|
||||||
return $this->fail('update failed');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除数据
|
* 删除数据
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
|
|||||||
@@ -7,6 +7,13 @@ use plugin\saiadmin\basic\think\BaseModel as SaiBaseModel;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 大富翁模块模型基类:删除均为硬删除(物理删除)
|
* 大富翁模块模型基类:删除均为硬删除(物理删除)
|
||||||
|
*
|
||||||
|
* 注意:
|
||||||
|
* - 不要在此重写实例方法 delete(),否则与 trait/父类的 delete() 相互覆盖,
|
||||||
|
* 在调用 $this->force()->delete() 时会无限递归(force() 返回 $this),
|
||||||
|
* 导致内存爆栈、HTTP 500。
|
||||||
|
* - 物理删除一律通过静态 destroy() 入口(强制 $force=true)完成;
|
||||||
|
* SoftDelete::destroy() 内部会按硬删除分支执行。
|
||||||
*/
|
*/
|
||||||
abstract class DiceModel extends SaiBaseModel
|
abstract class DiceModel extends SaiBaseModel
|
||||||
{
|
{
|
||||||
@@ -17,9 +24,4 @@ abstract class DiceModel extends SaiBaseModel
|
|||||||
{
|
{
|
||||||
return parent::destroy($data, true);
|
return parent::destroy($data, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function delete(): bool
|
|
||||||
{
|
|
||||||
return $this->force()->delete();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,10 +12,18 @@ use plugin\saiadmin\basic\contracts\ModelInterface;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* ThinkORM 模型基类
|
* ThinkORM 模型基类
|
||||||
|
*
|
||||||
|
* 全局策略:所有删除一律为硬删除(物理删除)。
|
||||||
|
* - 保留 SoftDelete trait 仅是为了兼容历史字段(如 delete_time)与查询作用域,
|
||||||
|
* 实际删除方法(delete/destroy)均通过 trait 别名重写为强制 force=true。
|
||||||
|
* - 项目中不使用 withTrashed/onlyTrashed/restore() 等软删除恢复接口。
|
||||||
*/
|
*/
|
||||||
class BaseModel extends Model implements ModelInterface
|
class BaseModel extends Model implements ModelInterface
|
||||||
{
|
{
|
||||||
use SoftDelete;
|
use SoftDelete {
|
||||||
|
delete as protected softDeleteCascadeOriginal;
|
||||||
|
destroy as protected softDeleteDestroyOriginal;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除时间字段
|
* 删除时间字段
|
||||||
@@ -99,6 +107,25 @@ class BaseModel extends Model implements ModelInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除记录(静态入口):一律强制硬删除(物理删除)。
|
||||||
|
* @param mixed $data 主键、闭包或条件
|
||||||
|
* @param bool $force 兼容签名,内部一律按 true 处理
|
||||||
|
*/
|
||||||
|
public static function destroy($data, bool $force = true): bool
|
||||||
|
{
|
||||||
|
return static::softDeleteDestroyOriginal($data, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除记录(实例方法):一律强制硬删除。
|
||||||
|
*/
|
||||||
|
public function delete(): bool
|
||||||
|
{
|
||||||
|
$this->force(true);
|
||||||
|
return $this->softDeleteCascadeOriginal();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增前事件:自动写入 create_time,有后台登录信息时写入 created_by
|
* 新增前事件:自动写入 create_time,有后台登录信息时写入 created_by
|
||||||
* @param Model $model
|
* @param Model $model
|
||||||
|
|||||||
Reference in New Issue
Block a user