1.新增默认彩金池配置
2.优化关联彩金池配置的名称显示 3.优化一键测试权重 4.优化底注配置
This commit is contained in:
@@ -27,6 +27,8 @@
|
|||||||
"labelIsDefault": "Default Ante",
|
"labelIsDefault": "Default Ante",
|
||||||
"placeholderName": "Please enter name",
|
"placeholderName": "Please enter name",
|
||||||
"placeholderTitle": "Please enter title",
|
"placeholderTitle": "Please enter title",
|
||||||
|
"placeholderNameAuto": "Auto from multiplier, e.g. x5",
|
||||||
|
"placeholderTitleAuto": "Auto from multiplier, e.g. x5",
|
||||||
"ruleNameRequired": "Please enter name",
|
"ruleNameRequired": "Please enter name",
|
||||||
"ruleTitleRequired": "Please enter title",
|
"ruleTitleRequired": "Please enter title",
|
||||||
"ruleMultRequired": "Please enter ante multiplier",
|
"ruleMultRequired": "Please enter ante multiplier",
|
||||||
|
|||||||
@@ -5,11 +5,13 @@
|
|||||||
"dialogTitleEdit": "Edit Lottery Pool Config",
|
"dialogTitleEdit": "Edit Lottery Pool Config",
|
||||||
"placeholderName": "Please enter name",
|
"placeholderName": "Please enter name",
|
||||||
"placeholderRemark": "Please enter remark",
|
"placeholderRemark": "Please enter remark",
|
||||||
|
"placeholderPoolName": "Pool display name, e.g. Normal pool",
|
||||||
|
"placeholderConfigNote": "Optional notes about this pool",
|
||||||
"poolType": "Pool Type",
|
"poolType": "Pool Type",
|
||||||
"placeholderPoolType": "Please select pool type",
|
"placeholderPoolType": "Please select pool type",
|
||||||
"poolTypeNormal": "Normal",
|
"poolTypeNormal": "Normal",
|
||||||
"poolTypeFree": "Free",
|
"poolTypeFree": "Free",
|
||||||
"poolTypeKill": "Kill",
|
"poolTypeKill": "Force score kill",
|
||||||
"poolTypeT1": "T1 High",
|
"poolTypeT1": "T1 High",
|
||||||
"safetyLine": "Safety Line",
|
"safetyLine": "Safety Line",
|
||||||
"t1Weight": "T1 Pool Weight (%)",
|
"t1Weight": "T1 Pool Weight (%)",
|
||||||
@@ -59,11 +61,13 @@
|
|||||||
"placeholderPoolType": "Please select pool type",
|
"placeholderPoolType": "Please select pool type",
|
||||||
"poolTypeNormal": "Normal",
|
"poolTypeNormal": "Normal",
|
||||||
"poolTypeFree": "Free",
|
"poolTypeFree": "Free",
|
||||||
"poolTypeKill": "Force Kill",
|
"poolTypeKill": "Force Score Kill",
|
||||||
"poolTypeT1": "T1 High Rate"
|
"poolTypeT1": "T1 High Rate"
|
||||||
},
|
},
|
||||||
"table": {
|
"table": {
|
||||||
"name": "Name",
|
"name": "Code",
|
||||||
|
"poolName": "Pool Name",
|
||||||
|
"configNote": "Remark",
|
||||||
"poolType": "Pool Type",
|
"poolType": "Pool Type",
|
||||||
"safetyLine": "Safety Line",
|
"safetyLine": "Safety Line",
|
||||||
"safetyLineNotUsed": "Not used for kill",
|
"safetyLineNotUsed": "Not used for kill",
|
||||||
|
|||||||
@@ -22,6 +22,8 @@
|
|||||||
"placeholderLotteryPool": "Leave empty for custom weights below, or select pool",
|
"placeholderLotteryPool": "Leave empty for custom weights below, or select pool",
|
||||||
"currentConfig": "Current Config",
|
"currentConfig": "Current Config",
|
||||||
"configLabelName": "Name",
|
"configLabelName": "Name",
|
||||||
|
"configLabelPoolName": "Pool name",
|
||||||
|
"configLabelCode": "Code",
|
||||||
"configLabelType": "Type",
|
"configLabelType": "Type",
|
||||||
"configLabelWeights": "T1–T5 Weights",
|
"configLabelWeights": "T1–T5 Weights",
|
||||||
"configLabelRemark": "Remark",
|
"configLabelRemark": "Remark",
|
||||||
|
|||||||
@@ -73,8 +73,10 @@
|
|||||||
"labelLotteryTypeFree": "Free tier pool",
|
"labelLotteryTypeFree": "Free tier pool",
|
||||||
"labelAnte": "Ante",
|
"labelAnte": "Ante",
|
||||||
"placeholderAnte": "Select ante config",
|
"placeholderAnte": "Select ante config",
|
||||||
"placeholderPaidPool": "Leave empty for custom tier odds below (default: default)",
|
"anteRandomOption": "Random (pick from channel ante configs)",
|
||||||
"placeholderFreePool": "Leave empty for custom tier odds below (default: free pool)",
|
"placeholderPaidPool": "Leave empty to set T1–T5 weights manually",
|
||||||
|
"placeholderFreePool": "Leave empty to set T1–T5 weights manually",
|
||||||
|
"selectedPoolHint": "Selected pool: {name}",
|
||||||
"tierProbHint": "Custom tier odds (T1–T5), each 0–100%, sum of five must not exceed 100%",
|
"tierProbHint": "Custom tier odds (T1–T5), each 0–100%, sum of five must not exceed 100%",
|
||||||
"tierFieldLabel": "Tier {tier} (%)",
|
"tierFieldLabel": "Tier {tier} (%)",
|
||||||
"tierSumError": "Current sum of five tiers is {sum}%, cannot exceed 100%",
|
"tierSumError": "Current sum of five tiers is {sum}%, cannot exceed 100%",
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
"chainModeNo": "No",
|
"chainModeNo": "No",
|
||||||
"paidPlannedSpins": "Planned paid spins",
|
"paidPlannedSpins": "Planned paid spins",
|
||||||
"ante": "Ante",
|
"ante": "Ante",
|
||||||
|
"anteRandom": "Random",
|
||||||
|
"testSafetyLine": "Safety line",
|
||||||
"playAgainCount": "Play-again count",
|
"playAgainCount": "Play-again count",
|
||||||
"progressDraws": "{over} done",
|
"progressDraws": "{over} done",
|
||||||
"progressFailed": "{over} before fail",
|
"progressFailed": "{over} before fail",
|
||||||
@@ -51,11 +53,13 @@
|
|||||||
"testCountProgress": "In progress: {over} done",
|
"testCountProgress": "In progress: {over} done",
|
||||||
"testCountFailed": "{over} before failure",
|
"testCountFailed": "{over} before failure",
|
||||||
"chainModeLabel": "Chain play-again",
|
"chainModeLabel": "Chain play-again",
|
||||||
|
"killModeOff": "Kill mode off",
|
||||||
"paidPlannedSpins": "Planned paid spins",
|
"paidPlannedSpins": "Planned paid spins",
|
||||||
|
"testSafetyLine": "Test safety line",
|
||||||
"createTime": "Created at",
|
"createTime": "Created at",
|
||||||
"admin": "Operator",
|
"admin": "Operator",
|
||||||
"paidPoolId": "Paid lottery pool config ID",
|
"paidPoolId": "Paid lottery pool",
|
||||||
"freePoolId": "Free lottery pool config ID",
|
"freePoolId": "Free lottery pool",
|
||||||
"bigwinSnapshot": "BIGWIN weight snapshot",
|
"bigwinSnapshot": "BIGWIN weight snapshot",
|
||||||
"sectionPaidTier": "Paid draw tier odds (T1–T5, used in test)",
|
"sectionPaidTier": "Paid draw tier odds (T1–T5, used in test)",
|
||||||
"sectionFreeTier": "Free draw tier odds (T1–T5, used in test)",
|
"sectionFreeTier": "Free draw tier odds (T1–T5, used in test)",
|
||||||
|
|||||||
@@ -27,6 +27,8 @@
|
|||||||
"labelIsDefault": "默认底注",
|
"labelIsDefault": "默认底注",
|
||||||
"placeholderName": "请输入名称",
|
"placeholderName": "请输入名称",
|
||||||
"placeholderTitle": "请输入标题",
|
"placeholderTitle": "请输入标题",
|
||||||
|
"placeholderNameAuto": "随底注倍率自动生成,如 x5",
|
||||||
|
"placeholderTitleAuto": "随底注倍率自动生成,如 x5",
|
||||||
"ruleNameRequired": "请输入名称",
|
"ruleNameRequired": "请输入名称",
|
||||||
"ruleTitleRequired": "请输入标题",
|
"ruleTitleRequired": "请输入标题",
|
||||||
"ruleMultRequired": "请输入底注倍率",
|
"ruleMultRequired": "请输入底注倍率",
|
||||||
|
|||||||
@@ -5,11 +5,14 @@
|
|||||||
"dialogTitleEdit": "编辑色子奖池配置",
|
"dialogTitleEdit": "编辑色子奖池配置",
|
||||||
"placeholderName": "请输入名称",
|
"placeholderName": "请输入名称",
|
||||||
"placeholderRemark": "请输入备注",
|
"placeholderRemark": "请输入备注",
|
||||||
|
"placeholderPoolName": "请输入奖池名称,如:正常池",
|
||||||
|
"placeholderConfigNote": "选填,用于说明该奖池用途或规则",
|
||||||
"poolType": "奖池类型",
|
"poolType": "奖池类型",
|
||||||
|
"poolName": "奖池名称",
|
||||||
"placeholderPoolType": "请选择奖池类型",
|
"placeholderPoolType": "请选择奖池类型",
|
||||||
"poolTypeNormal": "正常",
|
"poolTypeNormal": "正常",
|
||||||
"poolTypeFree": "免费",
|
"poolTypeFree": "免费",
|
||||||
"poolTypeKill": "强制杀猪",
|
"poolTypeKill": "强制杀分",
|
||||||
"poolTypeT1": "T1高倍率",
|
"poolTypeT1": "T1高倍率",
|
||||||
"safetyLine": "安全线",
|
"safetyLine": "安全线",
|
||||||
"t1Weight": "T1池权重(%)",
|
"t1Weight": "T1池权重(%)",
|
||||||
@@ -29,7 +32,7 @@
|
|||||||
"tierRuleContent": "比较对象为 default 奖池的 profit_amount(非单个玩家盈利)。当 profit_amount 低于安全线或未开启杀分时,付费按玩家 T*_weight 抽档;当 profit_amount 高于或等于安全线且已开启杀分时,付费按 killScore 奖池抽档。免费抽奖始终按本渠道 name=free 奖池权重(无 free 时回退 default),与安全线无关。",
|
"tierRuleContent": "比较对象为 default 奖池的 profit_amount(非单个玩家盈利)。当 profit_amount 低于安全线或未开启杀分时,付费按玩家 T*_weight 抽档;当 profit_amount 高于或等于安全线且已开启杀分时,付费按 killScore 奖池抽档。免费抽奖始终按本渠道 name=free 奖池权重(无 free 时回退 default),与安全线无关。",
|
||||||
"enableKillScore": "开启杀分",
|
"enableKillScore": "开启杀分",
|
||||||
"killScoreWeights": "杀分权重(killScore)",
|
"killScoreWeights": "杀分权重(killScore)",
|
||||||
"killWeightNote": "杀分权重请在列表中编辑 name=killScore(强制杀猪)记录;本弹窗仅配置 default 奖池的安全线与杀分开关。",
|
"killWeightNote": "杀分权重请在列表中编辑 name=killScore(强制杀分)记录;本弹窗仅配置 default 奖池的安全线与杀分开关。",
|
||||||
"btnResetProfit": "重置彩金池累计盈利",
|
"btnResetProfit": "重置彩金池累计盈利",
|
||||||
"btnSaveSafetyLine": "保存安全线与杀分开关",
|
"btnSaveSafetyLine": "保存安全线与杀分开关",
|
||||||
"safetyLineDefaultOnlyHint": "仅 name=default(正常)奖池的安全线参与杀分判定;其它奖池类型请勿在此配置安全线。",
|
"safetyLineDefaultOnlyHint": "仅 name=default(正常)奖池的安全线参与杀分判定;其它奖池类型请勿在此配置安全线。",
|
||||||
@@ -55,15 +58,18 @@
|
|||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"poolType": "奖池类型",
|
"poolType": "奖池类型",
|
||||||
|
"poolName": "奖池名称",
|
||||||
"placeholderName": "请输入名称",
|
"placeholderName": "请输入名称",
|
||||||
"placeholderPoolType": "请选择奖池类型",
|
"placeholderPoolType": "请选择奖池类型",
|
||||||
"poolTypeNormal": "正常",
|
"poolTypeNormal": "正常",
|
||||||
"poolTypeFree": "免费",
|
"poolTypeFree": "免费",
|
||||||
"poolTypeKill": "强制杀猪",
|
"poolTypeKill": "强制杀分",
|
||||||
"poolTypeT1": "T1高倍率"
|
"poolTypeT1": "T1高倍率"
|
||||||
},
|
},
|
||||||
"table": {
|
"table": {
|
||||||
"name": "名称",
|
"name": "内部标识",
|
||||||
|
"poolName": "奖池名称",
|
||||||
|
"configNote": "备注",
|
||||||
"poolType": "奖池类型",
|
"poolType": "奖池类型",
|
||||||
"safetyLine": "安全线",
|
"safetyLine": "安全线",
|
||||||
"safetyLineNotUsed": "不参与杀分判定",
|
"safetyLineNotUsed": "不参与杀分判定",
|
||||||
|
|||||||
@@ -22,6 +22,8 @@
|
|||||||
"placeholderLotteryPool": "留空则使用下方自定义权重,或选择彩金池",
|
"placeholderLotteryPool": "留空则使用下方自定义权重,或选择彩金池",
|
||||||
"currentConfig": "当前配置",
|
"currentConfig": "当前配置",
|
||||||
"configLabelName": "名称",
|
"configLabelName": "名称",
|
||||||
|
"configLabelPoolName": "奖池名称",
|
||||||
|
"configLabelCode": "内部标识",
|
||||||
"configLabelType": "类型",
|
"configLabelType": "类型",
|
||||||
"configLabelWeights": "T1~T5 权重",
|
"configLabelWeights": "T1~T5 权重",
|
||||||
"configLabelRemark": "备注",
|
"configLabelRemark": "备注",
|
||||||
|
|||||||
@@ -73,8 +73,10 @@
|
|||||||
"labelLotteryTypeFree": "免费档位奖池",
|
"labelLotteryTypeFree": "免费档位奖池",
|
||||||
"labelAnte": "底注",
|
"labelAnte": "底注",
|
||||||
"placeholderAnte": "请选择底注配置",
|
"placeholderAnte": "请选择底注配置",
|
||||||
"placeholderPaidPool": "不选则下方自定义档位概率(默认 default)",
|
"anteRandomOption": "随机(从当前渠道底注配置中抽取)",
|
||||||
"placeholderFreePool": "不选则下方自定义档位概率(默认 free 免费奖池)",
|
"placeholderPaidPool": "不选则下方手动设定 T1–T5 档位权重",
|
||||||
|
"placeholderFreePool": "不选则下方手动设定 T1–T5 档位权重",
|
||||||
|
"selectedPoolHint": "已选奖池:{name}",
|
||||||
"tierProbHint": "自定义档位概率(T1~T5),每档 0-100%,五档之和不能超过 100%",
|
"tierProbHint": "自定义档位概率(T1~T5),每档 0-100%,五档之和不能超过 100%",
|
||||||
"tierFieldLabel": "档位 {tier}(%)",
|
"tierFieldLabel": "档位 {tier}(%)",
|
||||||
"tierSumError": "当前五档之和为 {sum}%,不能超过 100%",
|
"tierSumError": "当前五档之和为 {sum}%,不能超过 100%",
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
"chainModeNo": "否",
|
"chainModeNo": "否",
|
||||||
"paidPlannedSpins": "计划付费次数",
|
"paidPlannedSpins": "计划付费次数",
|
||||||
"ante": "底注",
|
"ante": "底注",
|
||||||
|
"anteRandom": "随机",
|
||||||
|
"testSafetyLine": "安全线",
|
||||||
"playAgainCount": "再来一次次数",
|
"playAgainCount": "再来一次次数",
|
||||||
"progressDraws": "已完成 {over} 次",
|
"progressDraws": "已完成 {over} 次",
|
||||||
"progressFailed": "失败前 {over} 次",
|
"progressFailed": "失败前 {over} 次",
|
||||||
@@ -51,11 +53,13 @@
|
|||||||
"testCountProgress": "进行中:已完成 {over} 次",
|
"testCountProgress": "进行中:已完成 {over} 次",
|
||||||
"testCountFailed": "失败前 {over} 次",
|
"testCountFailed": "失败前 {over} 次",
|
||||||
"chainModeLabel": "链式再来一次",
|
"chainModeLabel": "链式再来一次",
|
||||||
|
"killModeOff": "未开启杀分",
|
||||||
"paidPlannedSpins": "计划付费次数",
|
"paidPlannedSpins": "计划付费次数",
|
||||||
|
"testSafetyLine": "测试安全线",
|
||||||
"createTime": "创建时间",
|
"createTime": "创建时间",
|
||||||
"admin": "执行管理员",
|
"admin": "执行管理员",
|
||||||
"paidPoolId": "付费奖池配置ID",
|
"paidPoolId": "付费彩金池",
|
||||||
"freePoolId": "免费奖池配置ID",
|
"freePoolId": "免费彩金池",
|
||||||
"bigwinSnapshot": "BIGWIN 权重快照",
|
"bigwinSnapshot": "BIGWIN 权重快照",
|
||||||
"sectionPaidTier": "付费抽奖档位概率(T1-T5,测试时使用)",
|
"sectionPaidTier": "付费抽奖档位概率(T1-T5,测试时使用)",
|
||||||
"sectionFreeTier": "免费抽奖档位概率(T1-T5,测试时使用)",
|
"sectionFreeTier": "免费抽奖档位概率(T1-T5,测试时使用)",
|
||||||
|
|||||||
@@ -9,13 +9,19 @@
|
|||||||
>
|
>
|
||||||
<el-form ref="formRef" :model="formData" :rules="rules" label-width="120px">
|
<el-form ref="formRef" :model="formData" :rules="rules" label-width="120px">
|
||||||
<el-form-item :label="$t('page.form.labelName')" prop="name">
|
<el-form-item :label="$t('page.form.labelName')" prop="name">
|
||||||
<el-input v-model="formData.name" :placeholder="$t('page.form.placeholderName')" />
|
<el-input v-model="formData.name" disabled :placeholder="$t('page.form.placeholderNameAuto')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('page.form.labelTitle')" prop="title">
|
<el-form-item :label="$t('page.form.labelTitle')" prop="title">
|
||||||
<el-input v-model="formData.title" :placeholder="$t('page.form.placeholderTitle')" />
|
<el-input v-model="formData.title" disabled :placeholder="$t('page.form.placeholderTitleAuto')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('page.form.labelMult')" prop="mult">
|
<el-form-item :label="$t('page.form.labelMult')" prop="mult">
|
||||||
<el-input-number v-model="formData.mult" :min="1" :step="1" style="width: 100%" />
|
<el-input-number
|
||||||
|
v-model="formData.mult"
|
||||||
|
:min="1"
|
||||||
|
:step="1"
|
||||||
|
style="width: 100%"
|
||||||
|
@update:model-value="syncNameTitleFromMult"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('page.form.labelIsDefault')" prop="is_default">
|
<el-form-item :label="$t('page.form.labelIsDefault')" prop="is_default">
|
||||||
<el-radio-group v-model="formData.is_default">
|
<el-radio-group v-model="formData.is_default">
|
||||||
@@ -87,6 +93,13 @@
|
|||||||
|
|
||||||
const formData = reactive({ ...initialFormData })
|
const formData = reactive({ ...initialFormData })
|
||||||
|
|
||||||
|
function syncNameTitleFromMult() {
|
||||||
|
const mult = Number(formData.mult) || 1
|
||||||
|
const label = `x${mult}`
|
||||||
|
formData.name = label
|
||||||
|
formData.title = label
|
||||||
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.modelValue,
|
() => props.modelValue,
|
||||||
async (newVal) => {
|
async (newVal) => {
|
||||||
@@ -99,6 +112,7 @@
|
|||||||
if (typeof props.data.title === 'string') formData.title = props.data.title
|
if (typeof props.data.title === 'string') formData.title = props.data.title
|
||||||
formData.mult = Number(props.data.mult ?? 1) || 1
|
formData.mult = Number(props.data.mult ?? 1) || 1
|
||||||
formData.is_default = Number(props.data.is_default ?? 0) === 1 ? 1 : 0
|
formData.is_default = Number(props.data.is_default ?? 0) === 1 ? 1 : 0
|
||||||
|
syncNameTitleFromMult()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,16 @@
|
|||||||
import request from '@/utils/http'
|
import request from '@/utils/http'
|
||||||
|
import {
|
||||||
|
normalizeLotteryPoolOption,
|
||||||
|
type LotteryPoolOption
|
||||||
|
} from '@/views/plugin/dice/utils/lotteryPoolDisplay'
|
||||||
|
|
||||||
|
export type LotteryPoolConfigOption = LotteryPoolOption & {
|
||||||
|
t1_weight: number
|
||||||
|
t2_weight: number
|
||||||
|
t3_weight: number
|
||||||
|
t4_weight: number
|
||||||
|
t5_weight: number
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 色子奖池配置 API 接口
|
* 色子奖池配置 API 接口
|
||||||
@@ -20,32 +32,24 @@ export default {
|
|||||||
* 获取 DiceLotteryPoolConfig 列表数据,含 id、name、t1_weight~t5_weight,用于一键测试权重档位类型下拉
|
* 获取 DiceLotteryPoolConfig 列表数据,含 id、name、t1_weight~t5_weight,用于一键测试权重档位类型下拉
|
||||||
* name 映射:default=原 type=0,killScore=原 type=1,up=原 type=2
|
* name 映射:default=原 type=0,killScore=原 type=1,up=原 type=2
|
||||||
*/
|
*/
|
||||||
async getOptions(params?: Record<string, unknown>): Promise<
|
async getOptions(params?: Record<string, unknown>): Promise<LotteryPoolConfigOption[]> {
|
||||||
Array<{
|
|
||||||
id: number
|
|
||||||
name: string
|
|
||||||
t1_weight: number
|
|
||||||
t2_weight: number
|
|
||||||
t3_weight: number
|
|
||||||
t4_weight: number
|
|
||||||
t5_weight: number
|
|
||||||
}>
|
|
||||||
> {
|
|
||||||
const res = await request.get<any>({
|
const res = await request.get<any>({
|
||||||
url: '/core/dice/lottery_pool_config/DiceLotteryPoolConfig/getOptions',
|
url: '/core/dice/lottery_pool_config/DiceLotteryPoolConfig/getOptions',
|
||||||
params
|
params
|
||||||
})
|
})
|
||||||
const rows = Array.isArray(res) ? res : (Array.isArray((res as any)?.data) ? (res as any).data : [])
|
const rows = Array.isArray(res) ? res : (Array.isArray((res as any)?.data) ? (res as any).data : [])
|
||||||
if (!Array.isArray(rows)) return []
|
if (!Array.isArray(rows)) return []
|
||||||
return rows.map((r: any) => ({
|
return rows.map((r: Record<string, unknown>) => {
|
||||||
id: Number(r.id),
|
const base = normalizeLotteryPoolOption(r)
|
||||||
name: String(r.name ?? r.id ?? ''),
|
return {
|
||||||
|
...base,
|
||||||
t1_weight: Number(r.t1_weight ?? 0),
|
t1_weight: Number(r.t1_weight ?? 0),
|
||||||
t2_weight: Number(r.t2_weight ?? 0),
|
t2_weight: Number(r.t2_weight ?? 0),
|
||||||
t3_weight: Number(r.t3_weight ?? 0),
|
t3_weight: Number(r.t3_weight ?? 0),
|
||||||
t4_weight: Number(r.t4_weight ?? 0),
|
t4_weight: Number(r.t4_weight ?? 0),
|
||||||
t5_weight: Number(r.t5_weight ?? 0)
|
t5_weight: Number(r.t5_weight ?? 0)
|
||||||
}))
|
}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import request from '@/utils/http'
|
import request from '@/utils/http'
|
||||||
|
import { normalizeLotteryPoolOption, type LotteryPoolOption } from '@/views/plugin/dice/utils/lotteryPoolDisplay'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 玩家抽奖记录 API接口
|
* 玩家抽奖记录 API接口
|
||||||
@@ -59,11 +60,13 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 获取彩金池配置选项(id、name) */
|
/** 获取彩金池配置选项(含奖池名称) */
|
||||||
getLotteryConfigOptions(params?: Record<string, unknown>) {
|
async getLotteryConfigOptions(params?: Record<string, unknown>): Promise<LotteryPoolOption[]> {
|
||||||
return request.get<{ id: number; name: string }[]>({
|
const res = await request.get<any>({
|
||||||
url: '/core/dice/play_record/DicePlayRecord/getLotteryConfigOptions',
|
url: '/core/dice/play_record/DicePlayRecord/getLotteryConfigOptions',
|
||||||
params
|
params
|
||||||
})
|
})
|
||||||
|
const rows = (Array.isArray(res) ? res : (res?.data ?? [])) as Array<Record<string, unknown>>
|
||||||
|
return rows.map((r) => normalizeLotteryPoolOption(r))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import request from '@/utils/http'
|
import request from '@/utils/http'
|
||||||
|
import { normalizeLotteryPoolOption } from '@/views/plugin/dice/utils/lotteryPoolDisplay'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 大富翁-玩家 API接口
|
* 大富翁-玩家 API接口
|
||||||
@@ -84,16 +85,15 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取彩金池配置选项(DiceLotteryPoolConfig.id、name),供 lottery_config_id 下拉使用
|
* 获取彩金池配置选项,供 lottery_config_id 下拉使用(含奖池名称 display_name)
|
||||||
* @returns [ { id, name } ]
|
|
||||||
*/
|
*/
|
||||||
async getLotteryConfigOptions(params?: Record<string, unknown>): Promise<Array<{ id: number; name: string }>> {
|
async getLotteryConfigOptions(params?: Record<string, unknown>) {
|
||||||
const res = await request.get<any>({
|
const res = await request.get<any>({
|
||||||
url: '/core/dice/player/DicePlayer/getLotteryConfigOptions',
|
url: '/core/dice/player/DicePlayer/getLotteryConfigOptions',
|
||||||
params
|
params
|
||||||
})
|
})
|
||||||
const rows = (Array.isArray(res) ? res : (res?.data ?? [])) as Array<{ id: number; name: string }>
|
const rows = (Array.isArray(res) ? res : (res?.data ?? [])) as Array<Record<string, unknown>>
|
||||||
return rows.map((r) => ({ id: Number(r.id), name: String(r.name ?? r.id ?? '') }))
|
return rows.map((r) => normalizeLotteryPoolOption(r))
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -87,14 +87,10 @@
|
|||||||
getData()
|
getData()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 奖池类型展示:按 name 映射
|
const poolNameFormatter = (row: Record<string, unknown>) => {
|
||||||
const typeFormatter = (row: Record<string, unknown>) => {
|
const remark = String(row.remark ?? '').trim()
|
||||||
const n = String(row.name ?? '')
|
if (remark) return remark
|
||||||
if (n === 'default') return t('page.search.poolTypeNormal')
|
return String(row.name ?? '').trim() || '-'
|
||||||
if (n === 'free') return t('page.search.poolTypeFree')
|
|
||||||
if (n === 'killScore') return t('page.search.poolTypeKill')
|
|
||||||
if (n === 'up') return t('page.search.poolTypeT1')
|
|
||||||
return n || '-'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 权重列带 %
|
// 权重列带 %
|
||||||
@@ -132,8 +128,19 @@
|
|||||||
core: {
|
core: {
|
||||||
apiFn: api.list,
|
apiFn: api.list,
|
||||||
columnsFactory: () => [
|
columnsFactory: () => [
|
||||||
{ prop: 'name', label: 'page.table.name', align: 'center' },
|
{ prop: 'remark', label: 'page.table.poolName', minWidth: 120, align: 'center', formatter: poolNameFormatter },
|
||||||
{ prop: 'name', label: 'page.table.poolType', width: 100, align: 'center', formatter: typeFormatter },
|
{
|
||||||
|
prop: 'config_note',
|
||||||
|
label: 'page.table.configNote',
|
||||||
|
minWidth: 140,
|
||||||
|
align: 'center',
|
||||||
|
showOverflowTooltip: true,
|
||||||
|
formatter: (row: Record<string, unknown>) => {
|
||||||
|
const v = String(row.config_note ?? '').trim()
|
||||||
|
return v || '-'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ prop: 'name', label: 'page.table.name', width: 110, align: 'center' },
|
||||||
{
|
{
|
||||||
prop: 'safety_line',
|
prop: 'safety_line',
|
||||||
label: 'page.table.safetyLine',
|
label: 'page.table.safetyLine',
|
||||||
|
|||||||
@@ -15,12 +15,20 @@
|
|||||||
:disabled="dialogType === 'edit'"
|
:disabled="dialogType === 'edit'"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('form.labelRemark')" prop="remark">
|
<el-form-item :label="$t('page.form.poolName')" prop="remark">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="formData.remark"
|
v-model="formData.remark"
|
||||||
|
:placeholder="$t('page.form.placeholderPoolName')"
|
||||||
|
maxlength="200"
|
||||||
|
show-word-limit
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="$t('form.labelRemark')" prop="config_note">
|
||||||
|
<el-input
|
||||||
|
v-model="formData.config_note"
|
||||||
type="textarea"
|
type="textarea"
|
||||||
:rows="3"
|
:rows="3"
|
||||||
:placeholder="$t('page.form.placeholderRemark')"
|
:placeholder="$t('page.form.placeholderConfigNote')"
|
||||||
maxlength="500"
|
maxlength="500"
|
||||||
show-word-limit
|
show-word-limit
|
||||||
/>
|
/>
|
||||||
@@ -159,6 +167,7 @@
|
|||||||
dept_id: undefined as number | undefined,
|
dept_id: undefined as number | undefined,
|
||||||
name: '',
|
name: '',
|
||||||
remark: '',
|
remark: '',
|
||||||
|
config_note: '',
|
||||||
safety_line: 0 as number,
|
safety_line: 0 as number,
|
||||||
t1_weight: 0 as number,
|
t1_weight: 0 as number,
|
||||||
t2_weight: 0 as number,
|
t2_weight: 0 as number,
|
||||||
|
|||||||
@@ -143,6 +143,7 @@
|
|||||||
import api from '../../api/play_record/index'
|
import api from '../../api/play_record/index'
|
||||||
import TableSearch from './modules/table-search.vue'
|
import TableSearch from './modules/table-search.vue'
|
||||||
import EditDialog from './modules/edit-dialog.vue'
|
import EditDialog from './modules/edit-dialog.vue'
|
||||||
|
import { lotteryPoolRowLabel } from '@/views/plugin/dice/utils/lotteryPoolDisplay'
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
// 搜索表单
|
// 搜索表单
|
||||||
@@ -177,8 +178,7 @@
|
|||||||
|
|
||||||
const usernameFormatter = (row: Record<string, any>) =>
|
const usernameFormatter = (row: Record<string, any>) =>
|
||||||
row?.dicePlayer?.username ?? row?.player_id ?? '-'
|
row?.dicePlayer?.username ?? row?.player_id ?? '-'
|
||||||
const lotteryConfigNameFormatter = (row: Record<string, any>) =>
|
const lotteryConfigNameFormatter = (row: Record<string, any>) => lotteryPoolRowLabel(row)
|
||||||
row?.diceLotteryPoolConfig?.name ?? row?.lottery_config_id ?? '-'
|
|
||||||
const rewardTierFormatter = (row: Record<string, any>) => row?.reward_tier ?? '-'
|
const rewardTierFormatter = (row: Record<string, any>) => row?.reward_tier ?? '-'
|
||||||
|
|
||||||
/** 摇取点数格式化为 1,3,4,5,6,6 */
|
/** 摇取点数格式化为 1,3,4,5,6,6 */
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
<el-option
|
<el-option
|
||||||
v-for="item in lotteryConfigOptions"
|
v-for="item in lotteryConfigOptions"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
:label="item.name"
|
:label="lotteryPoolOptionLabel(item)"
|
||||||
:value="item.id"
|
:value="item.id"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
@@ -180,6 +180,10 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import api from '../../../api/play_record/index'
|
import api from '../../../api/play_record/index'
|
||||||
import { getChannelDeptRequestParams } from '@/composables/useChannelDeptScope'
|
import { getChannelDeptRequestParams } from '@/composables/useChannelDeptScope'
|
||||||
|
import {
|
||||||
|
lotteryPoolOptionLabel,
|
||||||
|
type LotteryPoolOption
|
||||||
|
} from '@/views/plugin/dice/utils/lotteryPoolDisplay'
|
||||||
import type { FormInstance } from 'element-plus'
|
import type { FormInstance } from 'element-plus'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -209,7 +213,7 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
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<LotteryPoolOption[]>([])
|
||||||
|
|
||||||
const initialFormData = {
|
const initialFormData = {
|
||||||
id: null as number | null,
|
id: null as number | null,
|
||||||
|
|||||||
@@ -155,6 +155,7 @@
|
|||||||
import TableSearch from './modules/table-search.vue'
|
import TableSearch from './modules/table-search.vue'
|
||||||
import EditDialog from './modules/edit-dialog.vue'
|
import EditDialog from './modules/edit-dialog.vue'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
|
import { lotteryPoolRowLabel } from '@/views/plugin/dice/utils/lotteryPoolDisplay'
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
// 搜索表单(与 play_record 对齐:方向、赢取平台币范围、是否中大奖、中奖档位、点数和)
|
// 搜索表单(与 play_record 对齐:方向、赢取平台币范围、是否中大奖、中奖档位、点数和)
|
||||||
@@ -181,8 +182,7 @@
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
const lotteryConfigNameFormatter = (row: Record<string, any>) =>
|
const lotteryConfigNameFormatter = (row: Record<string, any>) => lotteryPoolRowLabel(row)
|
||||||
row?.diceLotteryPoolConfig?.name ?? row?.lottery_config_id ?? '-'
|
|
||||||
const rewardTierFormatter = (row: Record<string, any>) => row?.reward_tier ?? '-'
|
const rewardTierFormatter = (row: Record<string, any>) => row?.reward_tier ?? '-'
|
||||||
|
|
||||||
/** 摇取点数格式化为 1,3,4,5,6 */
|
/** 摇取点数格式化为 1,3,4,5,6 */
|
||||||
|
|||||||
@@ -148,6 +148,11 @@
|
|||||||
getChannelDeptRequestParams,
|
getChannelDeptRequestParams,
|
||||||
useInjectedChannelDept
|
useInjectedChannelDept
|
||||||
} from '@/composables/useChannelDeptScope'
|
} from '@/composables/useChannelDeptScope'
|
||||||
|
import {
|
||||||
|
filterLotteryPoolOptionsByQuery,
|
||||||
|
lotteryPoolOptionLabel,
|
||||||
|
type LotteryPoolOption
|
||||||
|
} from '@/views/plugin/dice/utils/lotteryPoolDisplay'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
modelValue: Record<string, any>
|
modelValue: Record<string, any>
|
||||||
@@ -162,8 +167,8 @@
|
|||||||
const isExpanded = ref<boolean>(false)
|
const isExpanded = ref<boolean>(false)
|
||||||
const channelScope = useInjectedChannelDept()
|
const channelScope = useInjectedChannelDept()
|
||||||
|
|
||||||
const lotteryPoolAllOptions = ref<Array<{ id: number; name: string }>>([])
|
const lotteryPoolAllOptions = ref<LotteryPoolOption[]>([])
|
||||||
const lotteryPoolOptions = ref<Array<{ id: number; name: string }>>([])
|
const lotteryPoolOptions = ref<LotteryPoolOption[]>([])
|
||||||
const lotteryPoolLoading = ref(false)
|
const lotteryPoolLoading = ref(false)
|
||||||
|
|
||||||
function resolveDeptParams(): Record<string, unknown> {
|
function resolveDeptParams(): Record<string, unknown> {
|
||||||
@@ -177,11 +182,6 @@
|
|||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
|
|
||||||
function lotteryPoolOptionLabel(item: { id: number; name: string }): string {
|
|
||||||
const name = (item.name || '').trim()
|
|
||||||
return name ? `${name} (#${item.id})` : `#${item.id}`
|
|
||||||
}
|
|
||||||
|
|
||||||
async function loadLotteryPoolOptions() {
|
async function loadLotteryPoolOptions() {
|
||||||
lotteryPoolLoading.value = true
|
lotteryPoolLoading.value = true
|
||||||
try {
|
try {
|
||||||
@@ -197,15 +197,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function filterLotteryPoolOptions(query: string) {
|
function filterLotteryPoolOptions(query: string) {
|
||||||
const q = (query || '').trim().toLowerCase()
|
lotteryPoolOptions.value = filterLotteryPoolOptionsByQuery(lotteryPoolAllOptions.value, query)
|
||||||
if (!q) {
|
|
||||||
lotteryPoolOptions.value = [...lotteryPoolAllOptions.value]
|
|
||||||
return
|
|
||||||
}
|
|
||||||
lotteryPoolOptions.value = lotteryPoolAllOptions.value.filter((item) => {
|
|
||||||
const name = (item.name || '').toLowerCase()
|
|
||||||
return name.includes(q) || String(item.id).includes(q)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onLotteryPoolDropdownVisible(visible: boolean) {
|
function onLotteryPoolDropdownVisible(visible: boolean) {
|
||||||
|
|||||||
@@ -115,6 +115,7 @@
|
|||||||
import TableSearch from './modules/table-search.vue'
|
import TableSearch from './modules/table-search.vue'
|
||||||
import EditDialog from './modules/edit-dialog.vue'
|
import EditDialog from './modules/edit-dialog.vue'
|
||||||
import WalletOperateDialog from './modules/WalletOperateDialog.vue'
|
import WalletOperateDialog from './modules/WalletOperateDialog.vue'
|
||||||
|
import { lotteryPoolRowLabel } from '@/views/plugin/dice/utils/lotteryPoolDisplay'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const { copy } = useClipboard()
|
const { copy } = useClipboard()
|
||||||
@@ -141,10 +142,13 @@
|
|||||||
return cellValue != null && cellValue !== '' ? `${cellValue}%` : '-'
|
return cellValue != null && cellValue !== '' ? `${cellValue}%` : '-'
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据 lottery_config_id 显示彩金池配置名称
|
const lotteryConfigNameFormatter = (row: any) => {
|
||||||
const lotteryConfigNameFormatter = (row: any) =>
|
const label = lotteryPoolRowLabel(row)
|
||||||
row?.diceLotteryPoolConfig?.name ??
|
if (label === '-' && !row?.lottery_config_id) {
|
||||||
(row?.lottery_config_id ? `#${row.lottery_config_id}` : t('page.table.customConfig'))
|
return t('page.table.customConfig')
|
||||||
|
}
|
||||||
|
return label
|
||||||
|
}
|
||||||
|
|
||||||
// 表格
|
// 表格
|
||||||
const {
|
const {
|
||||||
|
|||||||
@@ -88,7 +88,7 @@
|
|||||||
<el-option
|
<el-option
|
||||||
v-for="item in lotteryConfigOptions"
|
v-for="item in lotteryConfigOptions"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
:label="(item.name && String(item.name).trim()) || `#${item.id}`"
|
:label="lotteryPoolOptionLabel(item)"
|
||||||
:value="item.id"
|
:value="item.id"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
@@ -97,12 +97,12 @@
|
|||||||
<el-form-item v-if="currentLotteryConfig" :label="$t('page.form.currentConfig')" class="current-config-block">
|
<el-form-item v-if="currentLotteryConfig" :label="$t('page.form.currentConfig')" class="current-config-block">
|
||||||
<div class="current-lottery-config">
|
<div class="current-lottery-config">
|
||||||
<div class="config-row">
|
<div class="config-row">
|
||||||
<span class="config-label">{{ $t('page.form.configLabelName') }}:</span>
|
<span class="config-label">{{ $t('page.form.configLabelPoolName') }}:</span>
|
||||||
<span>{{ currentLotteryConfig.name ?? '-' }}</span>
|
<span>{{ lotteryPoolDisplayLabel(currentLotteryConfig) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="config-row">
|
<div class="config-row">
|
||||||
<span class="config-label">{{ $t('page.form.configLabelType') }}:</span>
|
<span class="config-label">{{ $t('page.form.configLabelCode') }}:</span>
|
||||||
<span>{{ lotteryConfigTypeText(currentLotteryConfig.name) }}</span>
|
<span>{{ currentLotteryConfig.name ?? '-' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="config-row">
|
<div class="config-row">
|
||||||
<span class="config-label">{{ $t('page.form.configLabelWeights') }}:</span>
|
<span class="config-label">{{ $t('page.form.configLabelWeights') }}:</span>
|
||||||
@@ -185,6 +185,7 @@
|
|||||||
import api from '../../../api/player/index'
|
import api from '../../../api/player/index'
|
||||||
import lotteryConfigApi from '../../../api/lottery_pool_config/index'
|
import lotteryConfigApi from '../../../api/lottery_pool_config/index'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import { lotteryPoolDisplayLabel, lotteryPoolOptionLabel } from '@/views/plugin/dice/utils/lotteryPoolDisplay'
|
||||||
import { getChannelDeptRequestParams, withChannelDeptParams } from '@/composables/useChannelDeptScope'
|
import { getChannelDeptRequestParams, withChannelDeptParams } from '@/composables/useChannelDeptScope'
|
||||||
import { isSuperAdminUser } from '@/utils/channelLayout'
|
import { isSuperAdminUser } from '@/utils/channelLayout'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
|
|||||||
@@ -54,7 +54,7 @@
|
|||||||
<el-option
|
<el-option
|
||||||
v-for="item in lotteryConfigOptions"
|
v-for="item in lotteryConfigOptions"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
:label="item.name"
|
:label="lotteryPoolOptionLabel(item)"
|
||||||
:value="item.id"
|
:value="item.id"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
@@ -65,6 +65,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import api from '../../../api/player/index'
|
import api from '../../../api/player/index'
|
||||||
|
import { lotteryPoolOptionLabel } from '@/views/plugin/dice/utils/lotteryPoolDisplay'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
modelValue: Record<string, any>
|
modelValue: Record<string, any>
|
||||||
|
|||||||
@@ -29,6 +29,10 @@
|
|||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
@change="syncAnteFromSelect"
|
@change="syncAnteFromSelect"
|
||||||
>
|
>
|
||||||
|
<ElOption
|
||||||
|
:label="$t('page.weightTest.anteRandomOption')"
|
||||||
|
:value="RANDOM_ANTE_CONFIG_ID"
|
||||||
|
/>
|
||||||
<ElOption
|
<ElOption
|
||||||
v-for="item in anteOptions"
|
v-for="item in anteOptions"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
@@ -85,12 +89,18 @@
|
|||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
>
|
>
|
||||||
<ElOption
|
<ElOption
|
||||||
v-for="item in paidLotteryOptions"
|
v-for="item in lotteryOptions"
|
||||||
:key="item.id"
|
:key="'paid-pool-' + item.id"
|
||||||
:label="item.name"
|
:label="lotteryPoolOptionLabel(item)"
|
||||||
:value="item.id"
|
:value="item.id"
|
||||||
/>
|
/>
|
||||||
</ElSelect>
|
</ElSelect>
|
||||||
|
<div v-if="selectedPaidPool" class="pool-selected-hint">
|
||||||
|
{{ $t('page.weightTest.selectedPoolHint', { name: lotteryPoolDisplayLabel(selectedPaidPool) }) }}
|
||||||
|
</div>
|
||||||
|
<div v-if="selectedPaidPool" class="pool-weights-preview">
|
||||||
|
{{ poolTierWeightsText(selectedPaidPool) }}
|
||||||
|
</div>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
<template v-if="form.paid_lottery_config_id == null">
|
<template v-if="form.paid_lottery_config_id == null">
|
||||||
<div class="tier-label">{{ $t('page.weightTest.tierProbHint') }}</div>
|
<div class="tier-label">{{ $t('page.weightTest.tierProbHint') }}</div>
|
||||||
@@ -155,12 +165,18 @@
|
|||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
>
|
>
|
||||||
<ElOption
|
<ElOption
|
||||||
v-for="item in freeLotteryOptions"
|
v-for="item in lotteryOptions"
|
||||||
:key="item.id"
|
:key="'free-pool-' + item.id"
|
||||||
:label="item.name"
|
:label="lotteryPoolOptionLabel(item)"
|
||||||
:value="item.id"
|
:value="item.id"
|
||||||
/>
|
/>
|
||||||
</ElSelect>
|
</ElSelect>
|
||||||
|
<div v-if="selectedFreePool" class="pool-selected-hint">
|
||||||
|
{{ $t('page.weightTest.selectedPoolHint', { name: lotteryPoolDisplayLabel(selectedFreePool) }) }}
|
||||||
|
</div>
|
||||||
|
<div v-if="selectedFreePool" class="pool-weights-preview">
|
||||||
|
{{ poolTierWeightsText(selectedFreePool) }}
|
||||||
|
</div>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
<template v-if="form.free_lottery_config_id == null">
|
<template v-if="form.free_lottery_config_id == null">
|
||||||
<div class="tier-label">{{ $t('page.weightTest.tierProbHintFreeChain') }}</div>
|
<div class="tier-label">{{ $t('page.weightTest.tierProbHintFreeChain') }}</div>
|
||||||
@@ -218,6 +234,13 @@
|
|||||||
useInjectedChannelDept,
|
useInjectedChannelDept,
|
||||||
withChannelDeptParams
|
withChannelDeptParams
|
||||||
} from '@/composables/useChannelDeptScope'
|
} from '@/composables/useChannelDeptScope'
|
||||||
|
import {
|
||||||
|
lotteryPoolDisplayLabel,
|
||||||
|
lotteryPoolOptionLabel
|
||||||
|
} from '@/views/plugin/dice/utils/lotteryPoolDisplay'
|
||||||
|
|
||||||
|
/** 底注下拉「随机」选项值(非真实 ante_config.id) */
|
||||||
|
const RANDOM_ANTE_CONFIG_ID = -1
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
/** 父页面渠道栏选中值(弹窗 teleport 后 inject 可能失效) */
|
/** 父页面渠道栏选中值(弹窗 teleport 后 inject 可能失效) */
|
||||||
@@ -247,16 +270,26 @@
|
|||||||
paid_s_count: 100,
|
paid_s_count: 100,
|
||||||
paid_n_count: 100,
|
paid_n_count: 100,
|
||||||
kill_mode_enabled: false,
|
kill_mode_enabled: false,
|
||||||
test_safety_line: 5000
|
test_safety_line: 0
|
||||||
})
|
})
|
||||||
const lotteryOptions = ref<Array<{ id: number; name: string }>>([])
|
type LotteryPoolOption = {
|
||||||
const paidLotteryOptions = computed(() =>
|
id: number
|
||||||
lotteryOptions.value.filter((r) => r.name === 'default')
|
name: string
|
||||||
|
remark?: string
|
||||||
|
display_name?: string
|
||||||
|
t1_weight?: number
|
||||||
|
t2_weight?: number
|
||||||
|
t3_weight?: number
|
||||||
|
t4_weight?: number
|
||||||
|
t5_weight?: number
|
||||||
|
}
|
||||||
|
const lotteryOptions = ref<LotteryPoolOption[]>([])
|
||||||
|
const selectedPaidPool = computed(() =>
|
||||||
|
lotteryOptions.value.find((r) => r.id === form.paid_lottery_config_id) ?? null
|
||||||
|
)
|
||||||
|
const selectedFreePool = computed(() =>
|
||||||
|
lotteryOptions.value.find((r) => r.id === form.free_lottery_config_id) ?? null
|
||||||
)
|
)
|
||||||
const freeLotteryOptions = computed(() => {
|
|
||||||
const list = lotteryOptions.value.filter((r) => r.name === 'free')
|
|
||||||
return list.length > 0 ? list : lotteryOptions.value.filter((r) => r.name === 'default')
|
|
||||||
})
|
|
||||||
const defaultPoolInfo = ref<{ safety_line: number; kill_enabled: number; profit_amount: number } | null>(null)
|
const defaultPoolInfo = ref<{ safety_line: number; kill_enabled: number; profit_amount: number } | null>(null)
|
||||||
const running = ref(false)
|
const running = ref(false)
|
||||||
|
|
||||||
@@ -322,6 +355,15 @@
|
|||||||
return label ? `${label} (×${item.mult})` : `×${item.mult}`
|
return label ? `${label} (×${item.mult})` : `×${item.mult}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function poolTierWeightsText(pool: LotteryPoolOption): string {
|
||||||
|
const parts = tierKeys.map((t) => {
|
||||||
|
const key = `${t.toLowerCase()}_weight` as keyof LotteryPoolOption
|
||||||
|
const v = pool[key]
|
||||||
|
return `${t} ${v ?? 0}%`
|
||||||
|
})
|
||||||
|
return parts.join(' · ')
|
||||||
|
}
|
||||||
|
|
||||||
function syncAnteFromSelect() {
|
function syncAnteFromSelect() {
|
||||||
const opt = anteOptions.value.find((o) => o.id === form.ante_config_id)
|
const opt = anteOptions.value.find((o) => o.id === form.ante_config_id)
|
||||||
if (opt) {
|
if (opt) {
|
||||||
@@ -350,11 +392,13 @@
|
|||||||
async function loadDefaultPoolInfo() {
|
async function loadDefaultPoolInfo() {
|
||||||
try {
|
try {
|
||||||
const pool = await lotteryPoolApi.getCurrentPool(resolveDeptParams())
|
const pool = await lotteryPoolApi.getCurrentPool(resolveDeptParams())
|
||||||
|
const safetyLine = Number(pool?.safety_line ?? 0)
|
||||||
defaultPoolInfo.value = {
|
defaultPoolInfo.value = {
|
||||||
safety_line: Number(pool?.safety_line ?? 0),
|
safety_line: safetyLine,
|
||||||
kill_enabled: Number(pool?.kill_enabled ?? 1),
|
kill_enabled: Number(pool?.kill_enabled ?? 1),
|
||||||
profit_amount: Number(pool?.profit_amount ?? 0)
|
profit_amount: Number(pool?.profit_amount ?? 0)
|
||||||
}
|
}
|
||||||
|
form.test_safety_line = safetyLine
|
||||||
} catch {
|
} catch {
|
||||||
defaultPoolInfo.value = null
|
defaultPoolInfo.value = null
|
||||||
}
|
}
|
||||||
@@ -363,12 +407,34 @@
|
|||||||
async function loadLotteryOptions() {
|
async function loadLotteryOptions() {
|
||||||
try {
|
try {
|
||||||
const list = await lotteryPoolApi.getOptions(resolveDeptParams())
|
const list = await lotteryPoolApi.getOptions(resolveDeptParams())
|
||||||
lotteryOptions.value = list.map((r: { id: number; name: string }) => ({
|
lotteryOptions.value = list.map(
|
||||||
|
(r: {
|
||||||
|
id: number
|
||||||
|
name: string
|
||||||
|
remark?: string
|
||||||
|
display_name?: string
|
||||||
|
t1_weight?: number
|
||||||
|
t2_weight?: number
|
||||||
|
t3_weight?: number
|
||||||
|
t4_weight?: number
|
||||||
|
t5_weight?: number
|
||||||
|
}) => ({
|
||||||
id: r.id,
|
id: r.id,
|
||||||
name: r.name
|
name: r.name,
|
||||||
}))
|
remark: r.remark,
|
||||||
|
display_name: r.display_name,
|
||||||
|
t1_weight: r.t1_weight,
|
||||||
|
t2_weight: r.t2_weight,
|
||||||
|
t3_weight: r.t3_weight,
|
||||||
|
t4_weight: r.t4_weight,
|
||||||
|
t5_weight: r.t5_weight
|
||||||
|
})
|
||||||
|
)
|
||||||
|
const playerDefault = list.find((r: { name?: string }) => r.name === 'playerDefault')
|
||||||
const normal = list.find((r: { name?: string }) => r.name === 'default')
|
const normal = list.find((r: { name?: string }) => r.name === 'default')
|
||||||
if (normal) {
|
if (playerDefault) {
|
||||||
|
form.paid_lottery_config_id = playerDefault.id
|
||||||
|
} else if (normal) {
|
||||||
form.paid_lottery_config_id = normal.id
|
form.paid_lottery_config_id = normal.id
|
||||||
}
|
}
|
||||||
const freePool = list.find((r: { name?: string }) => r.name === 'free')
|
const freePool = list.find((r: { name?: string }) => r.name === 'free')
|
||||||
@@ -385,7 +451,6 @@
|
|||||||
function buildPayload() {
|
function buildPayload() {
|
||||||
const payload: Record<string, unknown> = {
|
const payload: Record<string, unknown> = {
|
||||||
ante: form.ante,
|
ante: form.ante,
|
||||||
ante_config_id: form.ante_config_id,
|
|
||||||
paid_s_count: form.paid_s_count,
|
paid_s_count: form.paid_s_count,
|
||||||
paid_n_count: form.paid_n_count,
|
paid_n_count: form.paid_n_count,
|
||||||
free_s_count: 0,
|
free_s_count: 0,
|
||||||
@@ -394,6 +459,11 @@
|
|||||||
kill_mode_enabled: form.kill_mode_enabled,
|
kill_mode_enabled: form.kill_mode_enabled,
|
||||||
test_safety_line: form.test_safety_line
|
test_safety_line: form.test_safety_line
|
||||||
}
|
}
|
||||||
|
if (form.ante_config_id === RANDOM_ANTE_CONFIG_ID) {
|
||||||
|
payload.ante_random = true
|
||||||
|
} else {
|
||||||
|
payload.ante_config_id = form.ante_config_id
|
||||||
|
}
|
||||||
if (form.paid_lottery_config_id != null) {
|
if (form.paid_lottery_config_id != null) {
|
||||||
payload.paid_lottery_config_id = form.paid_lottery_config_id
|
payload.paid_lottery_config_id = form.paid_lottery_config_id
|
||||||
} else {
|
} else {
|
||||||
@@ -408,12 +478,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function validateForm(): boolean {
|
function validateForm(): boolean {
|
||||||
if (form.ante_config_id == null || form.ante_config_id <= 0) {
|
const isRandomAnte = form.ante_config_id === RANDOM_ANTE_CONFIG_ID
|
||||||
|
if (!isRandomAnte && (form.ante_config_id == null || form.ante_config_id <= 0)) {
|
||||||
ElMessage.warning(t('page.weightTest.warnAnte'))
|
ElMessage.warning(t('page.weightTest.warnAnte'))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if (!isRandomAnte) {
|
||||||
syncAnteFromSelect()
|
syncAnteFromSelect()
|
||||||
if (form.ante == null || form.ante <= 0) {
|
}
|
||||||
|
if (!isRandomAnte && (form.ante == null || form.ante <= 0)) {
|
||||||
ElMessage.warning(t('page.weightTest.warnAnte'))
|
ElMessage.warning(t('page.weightTest.warnAnte'))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -563,6 +636,20 @@
|
|||||||
border-top: 1px dashed var(--el-border-color);
|
border-top: 1px dashed var(--el-border-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pool-selected-hint {
|
||||||
|
margin-top: 6px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--el-text-color-secondary);
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pool-weights-preview {
|
||||||
|
margin-top: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--el-text-color-regular);
|
||||||
|
font-family: ui-monospace, monospace;
|
||||||
|
}
|
||||||
|
|
||||||
.kill-mode-field {
|
.kill-mode-field {
|
||||||
max-width: 280px;
|
max-width: 280px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,6 +143,33 @@
|
|||||||
return Number(row.paid_n_count ?? 0)
|
return Number(row.paid_n_count ?? 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatTestSafetyLine(row: Record<string, unknown>): string {
|
||||||
|
const dash = t('page.detail.dash')
|
||||||
|
if (Number(row.kill_mode_enabled ?? 0) !== 1) {
|
||||||
|
return dash
|
||||||
|
}
|
||||||
|
const line = row.test_safety_line
|
||||||
|
if (line === null || line === undefined || line === '') {
|
||||||
|
return dash
|
||||||
|
}
|
||||||
|
const n = Number(line)
|
||||||
|
return Number.isFinite(n) ? String(n) : dash
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatAnteCell(row: Record<string, unknown>): string {
|
||||||
|
const ante = row.ante
|
||||||
|
if (ante === null || ante === undefined || ante === '') {
|
||||||
|
return t('page.detail.dash')
|
||||||
|
}
|
||||||
|
const snap = row.tier_weights_snapshot
|
||||||
|
const isRandom =
|
||||||
|
snap &&
|
||||||
|
typeof snap === 'object' &&
|
||||||
|
(snap as { ante_random?: boolean }).ante_random === true
|
||||||
|
const base = String(ante)
|
||||||
|
return isRandom ? `${base} (${t('page.table.anteRandom')})` : base
|
||||||
|
}
|
||||||
|
|
||||||
// 平台赚取金额展示(未完成或空显示 —)
|
// 平台赚取金额展示(未完成或空显示 —)
|
||||||
function formatPlatformProfit(v: unknown): string {
|
function formatPlatformProfit(v: unknown): string {
|
||||||
const dash = t('page.detail.dash')
|
const dash = t('page.detail.dash')
|
||||||
@@ -228,8 +255,16 @@
|
|||||||
{
|
{
|
||||||
prop: 'ante',
|
prop: 'ante',
|
||||||
label: 'page.table.ante',
|
label: 'page.table.ante',
|
||||||
width: 90,
|
width: 100,
|
||||||
align: 'center'
|
align: 'center',
|
||||||
|
formatter: (row: Record<string, unknown>) => formatAnteCell(row)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'test_safety_line',
|
||||||
|
label: 'page.table.testSafetyLine',
|
||||||
|
width: 100,
|
||||||
|
align: 'center',
|
||||||
|
formatter: (row: Record<string, unknown>) => formatTestSafetyLine(row)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
prop: 'play_again_count',
|
prop: 'play_again_count',
|
||||||
|
|||||||
@@ -20,6 +20,12 @@
|
|||||||
<el-descriptions-item :label="$t('page.detail.paidPlannedSpins')">
|
<el-descriptions-item :label="$t('page.detail.paidPlannedSpins')">
|
||||||
{{ record.paid_planned_spins ?? $t('page.detail.dash') }}
|
{{ record.paid_planned_spins ?? $t('page.detail.dash') }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item :label="$t('page.detail.testSafetyLine')">
|
||||||
|
{{ formatTestSafetyLineDetail(record) }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item :label="$t('page.table.ante')">
|
||||||
|
{{ formatAnteDetail(record) }}
|
||||||
|
</el-descriptions-item>
|
||||||
<el-descriptions-item :label="$t('page.detail.testCount')">
|
<el-descriptions-item :label="$t('page.detail.testCount')">
|
||||||
{{ formatTestCountDisplay(record) }}
|
{{ formatTestCountDisplay(record) }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
@@ -30,10 +36,10 @@
|
|||||||
{{ record.admin_name ?? record.admin_id ?? $t('page.detail.dash') }}
|
{{ record.admin_name ?? record.admin_id ?? $t('page.detail.dash') }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item :label="$t('page.detail.paidPoolId')">
|
<el-descriptions-item :label="$t('page.detail.paidPoolId')">
|
||||||
{{ record.paid_lottery_config_id ?? record.lottery_config_id ?? $t('page.detail.dash') }}
|
{{ formatRecordPaidPoolName(record) }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item :label="$t('page.detail.freePoolId')">
|
<el-descriptions-item :label="$t('page.detail.freePoolId')">
|
||||||
{{ record.free_lottery_config_id ?? $t('page.detail.dash') }}
|
{{ formatRecordFreePoolName(record) }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item :label="$t('page.detail.bigwinSnapshot')">
|
<el-descriptions-item :label="$t('page.detail.bigwinSnapshot')">
|
||||||
<template v-if="bigwinWeightDisplay.length">
|
<template v-if="bigwinWeightDisplay.length">
|
||||||
@@ -182,7 +188,7 @@
|
|||||||
<el-option
|
<el-option
|
||||||
v-for="opt in paidLotteryOptions"
|
v-for="opt in paidLotteryOptions"
|
||||||
:key="opt.id"
|
:key="opt.id"
|
||||||
:label="opt.name"
|
:label="lotteryPoolOptionLabel(opt)"
|
||||||
:value="opt.id"
|
:value="opt.id"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
@@ -199,7 +205,7 @@
|
|||||||
<el-option
|
<el-option
|
||||||
v-for="opt in freeLotteryOptions"
|
v-for="opt in freeLotteryOptions"
|
||||||
:key="opt.id"
|
:key="opt.id"
|
||||||
:label="opt.name"
|
:label="lotteryPoolOptionLabel(opt)"
|
||||||
:value="opt.id"
|
:value="opt.id"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
@@ -224,6 +230,11 @@
|
|||||||
import ArtBarChart from '@/components/core/charts/art-bar-chart/index.vue'
|
import ArtBarChart from '@/components/core/charts/art-bar-chart/index.vue'
|
||||||
import recordApi from '../../../api/reward_config_record/index'
|
import recordApi from '../../../api/reward_config_record/index'
|
||||||
import lotteryConfigApi from '../../../api/lottery_pool_config/index'
|
import lotteryConfigApi from '../../../api/lottery_pool_config/index'
|
||||||
|
import {
|
||||||
|
lotteryPoolLabelById,
|
||||||
|
lotteryPoolOptionLabel,
|
||||||
|
type LotteryPoolOption
|
||||||
|
} from '@/views/plugin/dice/utils/lotteryPoolDisplay'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
@@ -242,6 +253,9 @@
|
|||||||
over_play_count?: number
|
over_play_count?: number
|
||||||
chain_free_mode?: number | boolean | string
|
chain_free_mode?: number | boolean | string
|
||||||
paid_planned_spins?: number
|
paid_planned_spins?: number
|
||||||
|
ante?: number
|
||||||
|
kill_mode_enabled?: number
|
||||||
|
test_safety_line?: number
|
||||||
create_time?: string
|
create_time?: string
|
||||||
admin_id?: number | null
|
admin_id?: number | null
|
||||||
admin_name?: string
|
admin_name?: string
|
||||||
@@ -278,6 +292,33 @@
|
|||||||
return t('page.table.chainModeNo')
|
return t('page.table.chainModeNo')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatTestSafetyLineDetail(record: RecordRow | null): string {
|
||||||
|
if (!record) return t('page.detail.dash')
|
||||||
|
if (Number(record.kill_mode_enabled ?? 0) !== 1) {
|
||||||
|
return t('page.detail.killModeOff')
|
||||||
|
}
|
||||||
|
const line = record.test_safety_line
|
||||||
|
if (line === null || line === undefined || line === '') {
|
||||||
|
return t('page.detail.dash')
|
||||||
|
}
|
||||||
|
return String(line)
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatAnteDetail(record: RecordRow | null): string {
|
||||||
|
if (!record) return t('page.detail.dash')
|
||||||
|
const ante = record.ante
|
||||||
|
if (ante === null || ante === undefined || ante === '') {
|
||||||
|
return t('page.detail.dash')
|
||||||
|
}
|
||||||
|
const snap = record.tier_weights_snapshot
|
||||||
|
const isRandom =
|
||||||
|
snap &&
|
||||||
|
typeof snap === 'object' &&
|
||||||
|
(snap as { ante_random?: boolean }).ante_random === true
|
||||||
|
const base = String(ante)
|
||||||
|
return isRandom ? `${base} (${t('page.table.anteRandom')})` : base
|
||||||
|
}
|
||||||
|
|
||||||
function formatTestCountDisplay(record: RecordRow | null): string {
|
function formatTestCountDisplay(record: RecordRow | null): string {
|
||||||
if (!record) return t('page.detail.dash')
|
if (!record) return t('page.detail.dash')
|
||||||
const status = Number(record.status)
|
const status = Number(record.status)
|
||||||
@@ -316,7 +357,18 @@
|
|||||||
const importing = ref(false)
|
const importing = ref(false)
|
||||||
const importPaidLotteryConfigId = ref<number | null>(null)
|
const importPaidLotteryConfigId = ref<number | null>(null)
|
||||||
const importFreeLotteryConfigId = ref<number | null>(null)
|
const importFreeLotteryConfigId = ref<number | null>(null)
|
||||||
const lotteryConfigOptions = ref<Array<{ id: number; name: string }>>([])
|
const lotteryConfigOptions = ref<LotteryPoolOption[]>([])
|
||||||
|
|
||||||
|
function formatRecordPaidPoolName(record: RecordRow | null): string {
|
||||||
|
if (!record) return t('page.detail.dash')
|
||||||
|
const id = record.paid_lottery_config_id ?? record.lottery_config_id ?? null
|
||||||
|
return lotteryPoolLabelById(id, lotteryConfigOptions.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatRecordFreePoolName(record: RecordRow | null): string {
|
||||||
|
if (!record) return t('page.detail.dash')
|
||||||
|
return lotteryPoolLabelById(record.free_lottery_config_id ?? null, lotteryConfigOptions.value)
|
||||||
|
}
|
||||||
|
|
||||||
function tierWeightsToTableData(weightsMap: Record<string, number> | null | undefined) {
|
function tierWeightsToTableData(weightsMap: Record<string, number> | null | undefined) {
|
||||||
const dash = t('page.detail.dash')
|
const dash = t('page.detail.dash')
|
||||||
@@ -496,6 +548,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
(open) => {
|
||||||
|
if (open) {
|
||||||
|
void loadLotteryOptions()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
function openImport() {
|
function openImport() {
|
||||||
importPaidLotteryConfigId.value =
|
importPaidLotteryConfigId.value =
|
||||||
props.record?.paid_lottery_config_id ?? props.record?.lottery_config_id ?? null
|
props.record?.paid_lottery_config_id ?? props.record?.lottery_config_id ?? null
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
/** 彩金池选项/关联行通用结构 */
|
||||||
|
export interface LotteryPoolOption {
|
||||||
|
id: number
|
||||||
|
name?: string
|
||||||
|
remark?: string
|
||||||
|
display_name?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 彩金池后台展示名(奖池名称):优先 display_name / remark,不用内部 name 作为首选 */
|
||||||
|
export function lotteryPoolDisplayLabel(item?: LotteryPoolOption | null): string {
|
||||||
|
if (!item) {
|
||||||
|
return '-'
|
||||||
|
}
|
||||||
|
const display = String(item.display_name ?? '').trim()
|
||||||
|
if (display) {
|
||||||
|
return display
|
||||||
|
}
|
||||||
|
const remark = String(item.remark ?? '').trim()
|
||||||
|
if (remark) {
|
||||||
|
return remark
|
||||||
|
}
|
||||||
|
return String(item.name ?? '').trim() || '-'
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 下拉选项文案:默认仅奖池名称;withId=true 时附带 ID */
|
||||||
|
export function lotteryPoolOptionLabel(
|
||||||
|
item: LotteryPoolOption,
|
||||||
|
options?: { withId?: boolean }
|
||||||
|
): string {
|
||||||
|
const label = lotteryPoolDisplayLabel(item)
|
||||||
|
if (options?.withId && item.id > 0) {
|
||||||
|
return label !== '-' ? `${label} (#${item.id})` : `#${item.id}`
|
||||||
|
}
|
||||||
|
return label !== '-' ? label : `#${item.id}`
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 列表行关联彩金池(含 diceLotteryPoolConfig 关联) */
|
||||||
|
export function lotteryPoolRowLabel(row?: {
|
||||||
|
diceLotteryPoolConfig?: LotteryPoolOption | null
|
||||||
|
lottery_config_id?: number | null | string
|
||||||
|
} | null): string {
|
||||||
|
if (!row) {
|
||||||
|
return '-'
|
||||||
|
}
|
||||||
|
const pool = row.diceLotteryPoolConfig
|
||||||
|
if (pool && (pool.id || pool.remark || pool.name || pool.display_name)) {
|
||||||
|
return lotteryPoolDisplayLabel(pool)
|
||||||
|
}
|
||||||
|
const id = row.lottery_config_id
|
||||||
|
if (id !== null && id !== undefined && id !== '') {
|
||||||
|
return `#${id}`
|
||||||
|
}
|
||||||
|
return '-'
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 规范化接口返回的彩金池选项 */
|
||||||
|
export function normalizeLotteryPoolOption(raw: Record<string, unknown>): LotteryPoolOption {
|
||||||
|
const id = Number(raw.id ?? 0)
|
||||||
|
const name = String(raw.name ?? '')
|
||||||
|
const remark = String(raw.remark ?? '')
|
||||||
|
const displayName = String(raw.display_name ?? '').trim()
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
remark,
|
||||||
|
display_name: displayName !== '' ? displayName : remark !== '' ? remark : name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 按奖池名称 / 内部标识 / ID 过滤下拉 */
|
||||||
|
export function filterLotteryPoolOptionsByQuery(
|
||||||
|
list: LotteryPoolOption[],
|
||||||
|
query: string
|
||||||
|
): LotteryPoolOption[] {
|
||||||
|
const q = (query || '').trim().toLowerCase()
|
||||||
|
if (!q) {
|
||||||
|
return [...list]
|
||||||
|
}
|
||||||
|
return list.filter((item) => {
|
||||||
|
const label = lotteryPoolDisplayLabel(item).toLowerCase()
|
||||||
|
const code = String(item.name ?? '').toLowerCase()
|
||||||
|
return label.includes(q) || code.includes(q) || String(item.id).includes(q)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 根据 ID 从选项列表解析奖池名称 */
|
||||||
|
export function lotteryPoolLabelById(
|
||||||
|
poolId: number | null | undefined,
|
||||||
|
options: LotteryPoolOption[]
|
||||||
|
): string {
|
||||||
|
if (poolId == null || poolId <= 0) {
|
||||||
|
return '-'
|
||||||
|
}
|
||||||
|
const found = options.find((o) => o.id === poolId)
|
||||||
|
if (found) {
|
||||||
|
return lotteryPoolDisplayLabel(found)
|
||||||
|
}
|
||||||
|
return `#${poolId}`
|
||||||
|
}
|
||||||
@@ -143,6 +143,8 @@ class PlayStartLogic
|
|||||||
&& $poolProfitTotal >= $safetyLine
|
&& $poolProfitTotal >= $safetyLine
|
||||||
&& $configKill !== null;
|
&& $configKill !== null;
|
||||||
|
|
||||||
|
$playerLinkedPool = $this->resolvePlayerLinkedPoolConfig($player, $configDeptId);
|
||||||
|
|
||||||
if ($ticketType === self::LOTTERY_TYPE_FREE) {
|
if ($ticketType === self::LOTTERY_TYPE_FREE) {
|
||||||
// 免费抽奖券:使用本渠道 name=free 奖池档位权重;无 free 时回退 default
|
// 免费抽奖券:使用本渠道 name=free 奖池档位权重;无 free 时回退 default
|
||||||
$config = $configFree ?? $configType0;
|
$config = $configFree ?? $configType0;
|
||||||
@@ -151,9 +153,13 @@ class PlayStartLogic
|
|||||||
$config = $configKill;
|
$config = $configKill;
|
||||||
$usePoolWeights = true;
|
$usePoolWeights = true;
|
||||||
} else {
|
} else {
|
||||||
// 付费未触发杀分:按玩家 T*_weight 抽档,lottery_config_id 记 default
|
// 付费未触发杀分:关联 playerDefault 时实时读该池权重;否则按玩家行内 T*_weight
|
||||||
$config = $configType0;
|
$config = $configType0;
|
||||||
$usePoolWeights = false;
|
$usePoolWeights = false;
|
||||||
|
if ($playerLinkedPool !== null && $playerLinkedPool->isPlayerDefaultTemplate()) {
|
||||||
|
$usePoolWeights = true;
|
||||||
|
$config = $playerLinkedPool;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 按档位 T1-T5 抽取后,从 DiceReward 表按当前方向取该档位数据,再按 weight 抽取一条得到 grid_number
|
// 按档位 T1-T5 抽取后,从 DiceReward 表按当前方向取该档位数据,再按 weight 抽取一条得到 grid_number
|
||||||
@@ -263,6 +269,9 @@ class PlayStartLogic
|
|||||||
$record = null;
|
$record = null;
|
||||||
$settledWinCoin = $winCoin;
|
$settledWinCoin = $winCoin;
|
||||||
$configId = (int) $config->id;
|
$configId = (int) $config->id;
|
||||||
|
if ($ticketType === self::LOTTERY_TYPE_PAID && !$usePaidKill && $playerLinkedPool !== null) {
|
||||||
|
$configId = (int) $playerLinkedPool->id;
|
||||||
|
}
|
||||||
$type0ConfigId = (int) $configType0->id;
|
$type0ConfigId = (int) $configType0->id;
|
||||||
$rewardId = ($isWin === 1 && $superWinCoin > 0) ? 0 : $targetIndex; // 中豹子不记录原奖励配置 id
|
$rewardId = ($isWin === 1 && $superWinCoin > 0) ? 0 : $targetIndex; // 中豹子不记录原奖励配置 id
|
||||||
$configName = (string) ($config->name ?? '');
|
$configName = (string) ($config->name ?? '');
|
||||||
@@ -789,4 +798,24 @@ class PlayStartLogic
|
|||||||
'grants_free_ticket' => $grantsFreeTicket,
|
'grants_free_ticket' => $grantsFreeTicket,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 玩家已选彩金池配置(用于 playerDefault 运行时权重)
|
||||||
|
*/
|
||||||
|
private function resolvePlayerLinkedPoolConfig(DicePlayer $player, int $configDeptId): ?DiceLotteryPoolConfig
|
||||||
|
{
|
||||||
|
$linkedId = (int) ($player->lottery_config_id ?? 0);
|
||||||
|
if ($linkedId <= 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$cfg = DiceLotteryPoolConfig::find($linkedId);
|
||||||
|
if (!$cfg) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$poolDeptId = AdminScopeHelper::normalizeRecordDeptId($cfg->dept_id ?? null);
|
||||||
|
if ($poolDeptId !== AdminScopeHelper::normalizeRecordDeptId($configDeptId)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return $cfg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,19 +38,23 @@ class DiceLotteryPoolConfigController extends BaseController
|
|||||||
#[Permission('色子奖池配置列表', 'dice:lottery_pool_config:index:index')]
|
#[Permission('色子奖池配置列表', 'dice:lottery_pool_config:index:index')]
|
||||||
public function getOptions(Request $request): Response
|
public function getOptions(Request $request): Response
|
||||||
{
|
{
|
||||||
$query = DiceLotteryPoolConfig::field('id,name,t1_weight,t2_weight,t3_weight,t4_weight,t5_weight')
|
$query = DiceLotteryPoolConfig::field('id,name,remark,t1_weight,t2_weight,t3_weight,t4_weight,t5_weight')
|
||||||
->order('id', 'asc');
|
->order('id', 'asc');
|
||||||
AdminScopeHelper::applyConfigScope($query, $this->adminInfo ?? null, $request->input('dept_id'));
|
AdminScopeHelper::applyConfigScope($query, $this->adminInfo ?? null, $request->input('dept_id'));
|
||||||
$list = $query->select();
|
$list = $query->select();
|
||||||
$data = $list->map(function ($item) {
|
$data = $list->map(function ($item) {
|
||||||
|
$row = is_array($item) ? $item : $item->toArray();
|
||||||
|
$display = DiceLotteryPoolConfig::displayLabel($row);
|
||||||
return [
|
return [
|
||||||
'id' => (int) $item['id'],
|
'id' => (int) ($row['id'] ?? 0),
|
||||||
'name' => (string) ($item['name'] ?? ''),
|
'name' => (string) ($row['name'] ?? ''),
|
||||||
't1_weight' => (int) ($item['t1_weight'] ?? 0),
|
'remark' => (string) ($row['remark'] ?? ''),
|
||||||
't2_weight' => (int) ($item['t2_weight'] ?? 0),
|
'display_name' => $display,
|
||||||
't3_weight' => (int) ($item['t3_weight'] ?? 0),
|
't1_weight' => (int) ($row['t1_weight'] ?? 0),
|
||||||
't4_weight' => (int) ($item['t4_weight'] ?? 0),
|
't2_weight' => (int) ($row['t2_weight'] ?? 0),
|
||||||
't5_weight' => (int) ($item['t5_weight'] ?? 0),
|
't3_weight' => (int) ($row['t3_weight'] ?? 0),
|
||||||
|
't4_weight' => (int) ($row['t4_weight'] ?? 0),
|
||||||
|
't5_weight' => (int) ($row['t5_weight'] ?? 0),
|
||||||
];
|
];
|
||||||
})->toArray();
|
})->toArray();
|
||||||
return $this->success($data);
|
return $this->success($data);
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ class DicePlayRecordController extends BaseController
|
|||||||
#[Permission('玩家抽奖记录列表', 'dice:play_record:index:index')]
|
#[Permission('玩家抽奖记录列表', 'dice:play_record:index:index')]
|
||||||
public function getLotteryConfigOptions(Request $request): Response
|
public function getLotteryConfigOptions(Request $request): Response
|
||||||
{
|
{
|
||||||
$query = DiceLotteryPoolConfig::field('id,name')->order('id', 'asc');
|
$query = DiceLotteryPoolConfig::field('id,name,remark')->order('id', 'asc');
|
||||||
$requestDeptId = AdminScopeHelper::pickRequestDeptId(
|
$requestDeptId = AdminScopeHelper::pickRequestDeptId(
|
||||||
$request->input('dept_id'),
|
$request->input('dept_id'),
|
||||||
$request->all()
|
$request->all()
|
||||||
@@ -100,7 +100,13 @@ class DicePlayRecordController extends BaseController
|
|||||||
AdminScopeHelper::applyConfigScope($query, $this->adminInfo ?? null, $requestDeptId);
|
AdminScopeHelper::applyConfigScope($query, $this->adminInfo ?? null, $requestDeptId);
|
||||||
$list = $query->select();
|
$list = $query->select();
|
||||||
$data = $list->map(function ($item) {
|
$data = $list->map(function ($item) {
|
||||||
return ['id' => (int) $item['id'], 'name' => (string) ($item['name'] ?? '')];
|
$row = is_array($item) ? $item : $item->toArray();
|
||||||
|
return [
|
||||||
|
'id' => (int) ($row['id'] ?? 0),
|
||||||
|
'name' => (string) ($row['name'] ?? ''),
|
||||||
|
'remark' => (string) ($row['remark'] ?? ''),
|
||||||
|
'display_name' => DiceLotteryPoolConfig::displayLabel($row),
|
||||||
|
];
|
||||||
})->toArray();
|
})->toArray();
|
||||||
return $this->success($data);
|
return $this->success($data);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ class DicePlayerController extends BaseController
|
|||||||
#[Permission('玩家列表', 'dice:player:index:index')]
|
#[Permission('玩家列表', 'dice:player:index:index')]
|
||||||
public function getLotteryConfigOptions(Request $request): Response
|
public function getLotteryConfigOptions(Request $request): Response
|
||||||
{
|
{
|
||||||
$query = DiceLotteryPoolConfig::field('id,name')->order('id', 'asc');
|
$query = DiceLotteryPoolConfig::field('id,name,remark')->order('id', 'asc');
|
||||||
$requestDeptId = AdminScopeHelper::pickRequestDeptId(
|
$requestDeptId = AdminScopeHelper::pickRequestDeptId(
|
||||||
$request->input('dept_id'),
|
$request->input('dept_id'),
|
||||||
$request->all()
|
$request->all()
|
||||||
@@ -51,7 +51,13 @@ class DicePlayerController extends BaseController
|
|||||||
AdminScopeHelper::applyConfigScope($query, $this->adminInfo ?? null, $requestDeptId);
|
AdminScopeHelper::applyConfigScope($query, $this->adminInfo ?? null, $requestDeptId);
|
||||||
$list = $query->select();
|
$list = $query->select();
|
||||||
$data = $list->map(function ($item) {
|
$data = $list->map(function ($item) {
|
||||||
return ['id' => (int) $item['id'], 'name' => (string) ($item['name'] ?? '')];
|
$row = is_array($item) ? $item : $item->toArray();
|
||||||
|
return [
|
||||||
|
'id' => (int) ($row['id'] ?? 0),
|
||||||
|
'name' => (string) ($row['name'] ?? ''),
|
||||||
|
'remark' => (string) ($row['remark'] ?? ''),
|
||||||
|
'display_name' => DiceLotteryPoolConfig::displayLabel($row),
|
||||||
|
];
|
||||||
})->toArray();
|
})->toArray();
|
||||||
return $this->success($data);
|
return $this->success($data);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,6 +116,7 @@ class DiceRewardController extends BaseController
|
|||||||
'test_safety_line' => $post['test_safety_line'] ?? null,
|
'test_safety_line' => $post['test_safety_line'] ?? null,
|
||||||
'dept_id' => $post['dept_id'] ?? null,
|
'dept_id' => $post['dept_id'] ?? null,
|
||||||
'ante_config_id' => $post['ante_config_id'] ?? null,
|
'ante_config_id' => $post['ante_config_id'] ?? null,
|
||||||
|
'ante_random' => $post['ante_random'] ?? null,
|
||||||
];
|
];
|
||||||
$adminId = isset($this->adminInfo['id']) ? (int) $this->adminInfo['id'] : null;
|
$adminId = isset($this->adminInfo['id']) ? (int) $this->adminInfo['id'] : null;
|
||||||
$requestDeptId = AdminScopeHelper::pickRequestDeptId($request->input('dept_id'), $post);
|
$requestDeptId = AdminScopeHelper::pickRequestDeptId($request->input('dept_id'), $post);
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ class DiceAnteConfigLogic extends DiceBaseLogic
|
|||||||
public function add(array $data): mixed
|
public function add(array $data): mixed
|
||||||
{
|
{
|
||||||
return $this->transaction(function () use ($data) {
|
return $this->transaction(function () use ($data) {
|
||||||
|
$this->applyNameTitleFromMult($data);
|
||||||
$this->normalizeDefaultField($data);
|
$this->normalizeDefaultField($data);
|
||||||
$deptId = AdminScopeHelper::resolveConfigDeptId(null, $data['dept_id'] ?? AdminScopeHelper::DEFAULT_TEMPLATE_DEPT);
|
$deptId = AdminScopeHelper::resolveConfigDeptId(null, $data['dept_id'] ?? AdminScopeHelper::DEFAULT_TEMPLATE_DEPT);
|
||||||
if ((int) ($data['is_default'] ?? 0) === 1) {
|
if ((int) ($data['is_default'] ?? 0) === 1) {
|
||||||
@@ -38,6 +39,7 @@ class DiceAnteConfigLogic extends DiceBaseLogic
|
|||||||
$pickedDeptId = AdminScopeHelper::pickRequestDeptId($requestDeptId, $data);
|
$pickedDeptId = AdminScopeHelper::pickRequestDeptId($requestDeptId, $data);
|
||||||
$deptId = AdminScopeHelper::resolveConfigDeptId($adminInfo, $pickedDeptId);
|
$deptId = AdminScopeHelper::resolveConfigDeptId($adminInfo, $pickedDeptId);
|
||||||
return $this->transaction(function () use ($id, $data, $deptId, $adminInfo, $pickedDeptId) {
|
return $this->transaction(function () use ($id, $data, $deptId, $adminInfo, $pickedDeptId) {
|
||||||
|
$this->applyNameTitleFromMult($data);
|
||||||
$this->normalizeDefaultField($data);
|
$this->normalizeDefaultField($data);
|
||||||
if ((int) ($data['is_default'] ?? 0) === 1) {
|
if ((int) ($data['is_default'] ?? 0) === 1) {
|
||||||
$this->clearOtherDefaults((int) $id, $deptId);
|
$this->clearOtherDefaults((int) $id, $deptId);
|
||||||
@@ -92,6 +94,21 @@ class DiceAnteConfigLogic extends DiceBaseLogic
|
|||||||
$data['is_default'] = ((int) $data['is_default']) === 1 ? 1 : 0;
|
$data['is_default'] = ((int) $data['is_default']) === 1 ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 名称、标题随底注倍率自动设为 xN */
|
||||||
|
private function applyNameTitleFromMult(array &$data): void
|
||||||
|
{
|
||||||
|
if (!array_key_exists('mult', $data)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$mult = (int) $data['mult'];
|
||||||
|
if ($mult <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$label = 'x' . $mult;
|
||||||
|
$data['name'] = $label;
|
||||||
|
$data['title'] = $label;
|
||||||
|
}
|
||||||
|
|
||||||
private function clearOtherDefaults(?int $excludeId = null, int $deptId = AdminScopeHelper::DEFAULT_TEMPLATE_DEPT): void
|
private function clearOtherDefaults(?int $excludeId = null, int $deptId = AdminScopeHelper::DEFAULT_TEMPLATE_DEPT): void
|
||||||
{
|
{
|
||||||
$query = $this->model->where('is_default', 1);
|
$query = $this->model->where('is_default', 1);
|
||||||
|
|||||||
@@ -598,41 +598,100 @@ class DiceRewardLogic
|
|||||||
if ($configCw !== null) {
|
if ($configCw !== null) {
|
||||||
$tier = isset($configCw['tier']) ? trim((string) $configCw['tier']) : '';
|
$tier = isset($configCw['tier']) ? trim((string) $configCw['tier']) : '';
|
||||||
if ($tier !== '') {
|
if ($tier !== '') {
|
||||||
$rows[] = [
|
$rows[] = $this->buildReferenceRowFromLandingConfig(
|
||||||
'tier' => $tier,
|
$tier,
|
||||||
'direction' => DiceReward::DIRECTION_CLOCKWISE,
|
$configCw,
|
||||||
'weight' => self::WEIGHT_MIN,
|
DiceReward::DIRECTION_CLOCKWISE,
|
||||||
'grid_number' => $gridNumber,
|
$gridNumber,
|
||||||
'start_index' => $startId,
|
$startId
|
||||||
'end_index' => isset($configCw['id']) ? (int) $configCw['id'] : 0,
|
);
|
||||||
'ui_text' => $configCw['ui_text'] ?? '',
|
|
||||||
'real_ev' => $configCw['real_ev'] ?? null,
|
|
||||||
'remark' => $configCw['remark'] ?? '',
|
|
||||||
'type' => isset($configCw['type']) ? (int) $configCw['type'] : 0,
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($configCcw !== null) {
|
if ($configCcw !== null) {
|
||||||
$tier = isset($configCcw['tier']) ? trim((string) $configCcw['tier']) : '';
|
$tier = isset($configCcw['tier']) ? trim((string) $configCcw['tier']) : '';
|
||||||
if ($tier !== '') {
|
if ($tier !== '') {
|
||||||
$rows[] = [
|
$rows[] = $this->buildReferenceRowFromLandingConfig(
|
||||||
'tier' => $tier,
|
$tier,
|
||||||
'direction' => DiceReward::DIRECTION_COUNTERCLOCKWISE,
|
$configCcw,
|
||||||
'weight' => self::WEIGHT_MIN,
|
DiceReward::DIRECTION_COUNTERCLOCKWISE,
|
||||||
'grid_number' => $gridNumber,
|
$gridNumber,
|
||||||
'start_index' => $startId,
|
$startId
|
||||||
'end_index' => isset($configCcw['id']) ? (int) $configCcw['id'] : 0,
|
);
|
||||||
'ui_text' => $configCcw['ui_text'] ?? '',
|
|
||||||
'real_ev' => $configCcw['real_ev'] ?? null,
|
|
||||||
'remark' => $configCcw['remark'] ?? '',
|
|
||||||
'type' => isset($configCcw['type']) ? (int) $configCcw['type'] : 0,
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ['rows' => $rows, 'skipped' => $skipped];
|
return ['rows' => $rows, 'skipped' => $skipped];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对照表落点行:档位按结算金额推断,备注与奖励配置页规则一致
|
||||||
|
*
|
||||||
|
* @param array<string, mixed> $landingConfig
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
private function buildReferenceRowFromLandingConfig(
|
||||||
|
string $tier,
|
||||||
|
array $landingConfig,
|
||||||
|
int $direction,
|
||||||
|
int $gridNumber,
|
||||||
|
int $startId
|
||||||
|
): array {
|
||||||
|
$realEv = isset($landingConfig['real_ev']) ? (float) $landingConfig['real_ev'] : 0.0;
|
||||||
|
if ($tier !== 'BIGWIN') {
|
||||||
|
$inferred = $this->inferTierFromRealEv($realEv);
|
||||||
|
if ($inferred !== '') {
|
||||||
|
$tier = $inferred;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
'tier' => $tier,
|
||||||
|
'direction' => $direction,
|
||||||
|
'weight' => self::WEIGHT_MIN,
|
||||||
|
'grid_number' => $gridNumber,
|
||||||
|
'start_index' => $startId,
|
||||||
|
'end_index' => isset($landingConfig['id']) ? (int) $landingConfig['id'] : 0,
|
||||||
|
'ui_text' => $landingConfig['ui_text'] ?? '',
|
||||||
|
'real_ev' => $landingConfig['real_ev'] ?? null,
|
||||||
|
'remark' => $this->defaultRemarkForTier($tier),
|
||||||
|
'type' => isset($landingConfig['type']) ? (int) $landingConfig['type'] : 0,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按结算金额推断档位(与前端 generateIndexByRules 一致)
|
||||||
|
*/
|
||||||
|
private function inferTierFromRealEv(float $realEv): string
|
||||||
|
{
|
||||||
|
if ($realEv > 2) {
|
||||||
|
return 'T1';
|
||||||
|
}
|
||||||
|
if ($realEv > 1) {
|
||||||
|
return 'T2';
|
||||||
|
}
|
||||||
|
if ($realEv > 0) {
|
||||||
|
return 'T3';
|
||||||
|
}
|
||||||
|
if ($realEv < 0) {
|
||||||
|
return 'T4';
|
||||||
|
}
|
||||||
|
return 'T5';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 档位默认备注
|
||||||
|
*/
|
||||||
|
private function defaultRemarkForTier(string $tier): string
|
||||||
|
{
|
||||||
|
return match ($tier) {
|
||||||
|
'T1', 'BIGWIN' => '大奖',
|
||||||
|
'T2' => '小赚',
|
||||||
|
'T3' => '抽水',
|
||||||
|
'T4' => '惩罚',
|
||||||
|
'T5' => '再来一次',
|
||||||
|
default => '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 读出当前 dice_reward(用于对比/复用权重)。key = "direction:grid_number"
|
* 读出当前 dice_reward(用于对比/复用权重)。key = "direction:grid_number"
|
||||||
* @return array<string, array<string, mixed>>
|
* @return array<string, array<string, mixed>>
|
||||||
|
|||||||
@@ -283,7 +283,12 @@ class DiceRewardConfigRecordLogic extends DiceBaseLogic
|
|||||||
$paidN = isset($params['paid_n_count']) ? (int) $params['paid_n_count'] : 0;
|
$paidN = isset($params['paid_n_count']) ? (int) $params['paid_n_count'] : 0;
|
||||||
$chainFreeMode = !empty($params['chain_free_mode']);
|
$chainFreeMode = !empty($params['chain_free_mode']);
|
||||||
$killModeEnabled = !empty($params['kill_mode_enabled']);
|
$killModeEnabled = !empty($params['kill_mode_enabled']);
|
||||||
$testSafetyLine = isset($params['test_safety_line']) ? (int) $params['test_safety_line'] : 5000;
|
if (array_key_exists('test_safety_line', $params) && $params['test_safety_line'] !== null && $params['test_safety_line'] !== '') {
|
||||||
|
$testSafetyLine = (int) $params['test_safety_line'];
|
||||||
|
} else {
|
||||||
|
$defaultPool = DiceLotteryPoolConfig::findByNameForDept('default', $deptId);
|
||||||
|
$testSafetyLine = (int) ($defaultPool->safety_line ?? 0);
|
||||||
|
}
|
||||||
if ($testSafetyLine < 0) {
|
if ($testSafetyLine < 0) {
|
||||||
throw new ApiException('test_safety_line must be greater than or equal to 0');
|
throw new ApiException('test_safety_line must be greater than or equal to 0');
|
||||||
}
|
}
|
||||||
@@ -405,6 +410,9 @@ class DiceRewardConfigRecordLogic extends DiceBaseLogic
|
|||||||
if ($chainFreeMode) {
|
if ($chainFreeMode) {
|
||||||
$tierWeightsSnapshot['chain_free_mode'] = true;
|
$tierWeightsSnapshot['chain_free_mode'] = true;
|
||||||
}
|
}
|
||||||
|
if (!empty($params['ante_random'])) {
|
||||||
|
$tierWeightsSnapshot['ante_random'] = true;
|
||||||
|
}
|
||||||
|
|
||||||
$record = new DiceRewardConfigRecord();
|
$record = new DiceRewardConfigRecord();
|
||||||
$plannedPaidSpins = $paidS + $paidN;
|
$plannedPaidSpins = $paidS + $paidN;
|
||||||
@@ -494,6 +502,21 @@ class DiceRewardConfigRecordLogic extends DiceBaseLogic
|
|||||||
*/
|
*/
|
||||||
private function resolveWeightTestAnte(array $params, int $deptId): int
|
private function resolveWeightTestAnte(array $params, int $deptId): int
|
||||||
{
|
{
|
||||||
|
if (!empty($params['ante_random'])) {
|
||||||
|
$anteQuery = DiceAnteConfig::field('id,mult')->order('mult', 'asc');
|
||||||
|
ConfigScopeEditHelper::applyDeptIdWhere($anteQuery, $deptId);
|
||||||
|
$rows = $anteQuery->select()->toArray();
|
||||||
|
if ($rows === []) {
|
||||||
|
throw new ApiException('No ante config in current channel');
|
||||||
|
}
|
||||||
|
$picked = $rows[random_int(0, count($rows) - 1)];
|
||||||
|
$mult = (int) ($picked['mult'] ?? 0);
|
||||||
|
if ($mult <= 0) {
|
||||||
|
throw new ApiException('ANTE_MUST_POSITIVE');
|
||||||
|
}
|
||||||
|
return $mult;
|
||||||
|
}
|
||||||
|
|
||||||
$anteConfigId = isset($params['ante_config_id']) ? (int) $params['ante_config_id'] : 0;
|
$anteConfigId = isset($params['ante_config_id']) ? (int) $params['ante_config_id'] : 0;
|
||||||
if ($anteConfigId > 0) {
|
if ($anteConfigId > 0) {
|
||||||
$config = DiceAnteConfig::find($anteConfigId);
|
$config = DiceAnteConfig::find($anteConfigId);
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ use app\dice\model\DiceModel;
|
|||||||
*
|
*
|
||||||
* @property $id ID
|
* @property $id ID
|
||||||
* @property $name 名称
|
* @property $name 名称
|
||||||
* @property $remark 备注
|
* @property $remark 奖池名称(后台展示名)
|
||||||
|
* @property $config_note 配置备注
|
||||||
* @property $safety_line 安全线
|
* @property $safety_line 安全线
|
||||||
* @property $kill_enabled 是否启用杀分:0=关闭 1=开启
|
* @property $kill_enabled 是否启用杀分:0=关闭 1=开启
|
||||||
* @property $create_time 创建时间
|
* @property $create_time 创建时间
|
||||||
@@ -31,6 +32,9 @@ use app\dice\model\DiceModel;
|
|||||||
*/
|
*/
|
||||||
class DiceLotteryPoolConfig extends DiceModel
|
class DiceLotteryPoolConfig extends DiceModel
|
||||||
{
|
{
|
||||||
|
/** 玩家默认彩金池(新玩家关联;付费未杀分时运行时读取该池 T1–T5 权重) */
|
||||||
|
public const NAME_PLAYER_DEFAULT = 'playerDefault';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据表主键
|
* 数据表主键
|
||||||
* @var string
|
* @var string
|
||||||
@@ -43,6 +47,9 @@ class DiceLotteryPoolConfig extends DiceModel
|
|||||||
*/
|
*/
|
||||||
protected $table = 'dice_lottery_pool_config';
|
protected $table = 'dice_lottery_pool_config';
|
||||||
|
|
||||||
|
/** 列表/关联 JSON 附带奖池展示名 */
|
||||||
|
protected $append = ['display_name'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 按名称与渠道查找奖池配置(一键测试等场景,避免命中其他渠道同名配置)
|
* 按名称与渠道查找奖池配置(一键测试等场景,避免命中其他渠道同名配置)
|
||||||
*/
|
*/
|
||||||
@@ -53,12 +60,57 @@ class DiceLotteryPoolConfig extends DiceModel
|
|||||||
return $query->find();
|
return $query->find();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否玩家默认模板池(运行时按该池权重抽档,改池配置即对所有关联玩家生效)
|
||||||
|
*/
|
||||||
|
public function isPlayerDefaultTemplate(): bool
|
||||||
|
{
|
||||||
|
return (string) ($this->name ?? '') === self::NAME_PLAYER_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后台展示用奖池名称:优先 remark,否则 name
|
||||||
|
*
|
||||||
|
* @param array<string, mixed>|self $row
|
||||||
|
*/
|
||||||
|
public static function displayLabel($row): string
|
||||||
|
{
|
||||||
|
// 禁止对模型实例 toArray():append display_name 会再次触发本方法,导致内存耗尽
|
||||||
|
if ($row instanceof self) {
|
||||||
|
$data = $row->getData();
|
||||||
|
$remark = trim((string) ($data['remark'] ?? ''));
|
||||||
|
if ($remark !== '') {
|
||||||
|
return $remark;
|
||||||
|
}
|
||||||
|
return trim((string) ($data['name'] ?? ''));
|
||||||
|
}
|
||||||
|
$remark = trim((string) ($row['remark'] ?? ''));
|
||||||
|
if ($remark !== '') {
|
||||||
|
return $remark;
|
||||||
|
}
|
||||||
|
return trim((string) ($row['name'] ?? ''));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDisplayNameAttr(): string
|
||||||
|
{
|
||||||
|
$data = $this->getData();
|
||||||
|
$remark = trim((string) ($data['remark'] ?? ''));
|
||||||
|
if ($remark !== '') {
|
||||||
|
return $remark;
|
||||||
|
}
|
||||||
|
return trim((string) ($data['name'] ?? ''));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 名称 搜索
|
* 名称 搜索
|
||||||
*/
|
*/
|
||||||
public function searchNameAttr($query, $value)
|
public function searchNameAttr($query, $value)
|
||||||
{
|
{
|
||||||
$query->where('name', 'like', '%'.$value.'%');
|
$like = '%' . $value . '%';
|
||||||
|
$query->where(function ($q) use ($like) {
|
||||||
|
$q->where('name', 'like', $like)
|
||||||
|
->whereOr('remark', 'like', $like);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,13 +88,17 @@ class DicePlayRecord extends DiceModel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 按彩金池配置名称模糊(diceLotteryPoolConfig.name) */
|
/** 按彩金池奖池名称或内部标识模糊搜索 */
|
||||||
public function searchLotteryConfigNameAttr($query, $value)
|
public function searchLotteryConfigNameAttr($query, $value)
|
||||||
{
|
{
|
||||||
if ($value === '' || $value === null) {
|
if ($value === '' || $value === null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$ids = DiceLotteryPoolConfig::where('name', 'like', '%' . $value . '%')->column('id');
|
$like = '%' . $value . '%';
|
||||||
|
$ids = DiceLotteryPoolConfig::where(function ($q) use ($like) {
|
||||||
|
$q->where('name', 'like', $like)
|
||||||
|
->whereOr('remark', 'like', $like);
|
||||||
|
})->column('id');
|
||||||
if (!empty($ids)) {
|
if (!empty($ids)) {
|
||||||
$query->whereIn('lottery_config_id', $ids);
|
$query->whereIn('lottery_config_id', $ids);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
// +----------------------------------------------------------------------
|
// +----------------------------------------------------------------------
|
||||||
namespace app\dice\model\player;
|
namespace app\dice\model\player;
|
||||||
|
|
||||||
|
use app\dice\helper\AdminScopeHelper;
|
||||||
use app\dice\model\DiceModel;
|
use app\dice\model\DiceModel;
|
||||||
use app\dice\model\lottery_pool_config\DiceLotteryPoolConfig;
|
use app\dice\model\lottery_pool_config\DiceLotteryPoolConfig;
|
||||||
|
|
||||||
@@ -84,44 +85,61 @@ class DicePlayer extends DiceModel
|
|||||||
if ($name === null || $name === '') {
|
if ($name === null || $name === '') {
|
||||||
$model->setAttr('name', $uid);
|
$model->setAttr('name', $uid);
|
||||||
}
|
}
|
||||||
// 创建玩家时:未指定则自动保存 lottery_config_id 为 DiceLotteryPoolConfig name=default 的 id,没有则为 0
|
// 创建玩家时:未指定则关联 name=playerDefault(玩家默认彩金池),没有则为 0
|
||||||
try {
|
try {
|
||||||
$lotteryConfigId = $model->getAttr('lottery_config_id');
|
$lotteryConfigId = $model->getAttr('lottery_config_id');
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
$lotteryConfigId = null;
|
$lotteryConfigId = null;
|
||||||
}
|
}
|
||||||
if ($lotteryConfigId === null || $lotteryConfigId === '' || (int) $lotteryConfigId === 0) {
|
if ($lotteryConfigId === null || $lotteryConfigId === '' || (int) $lotteryConfigId === 0) {
|
||||||
$config = self::findDefaultLotteryConfigForPlayer($model);
|
$config = self::findPlayerDefaultLotteryConfigForPlayer($model);
|
||||||
$model->setAttr('lottery_config_id', $config ? (int) $config->id : 0);
|
$model->setAttr('lottery_config_id', $config ? (int) $config->id : 0);
|
||||||
}
|
}
|
||||||
// 彩金池权重默认取 name=default 的奖池配置
|
// 展示用权重:从玩家关联的彩金池复制(playerDefault 在抽奖时仍实时读池配置)
|
||||||
self::setDefaultWeightsFromLotteryConfig($model);
|
self::setDefaultWeightsFromLotteryConfig($model);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 按玩家所属渠道查找 default 彩金池配置
|
* 按玩家所属渠道查找玩家默认彩金池(name=playerDefault)
|
||||||
*/
|
*/
|
||||||
protected static function findDefaultLotteryConfigForPlayer(DicePlayer $model): ?DiceLotteryPoolConfig
|
protected static function findPlayerDefaultLotteryConfigForPlayer(DicePlayer $model): ?DiceLotteryPoolConfig
|
||||||
{
|
{
|
||||||
$query = DiceLotteryPoolConfig::where('name', 'default');
|
|
||||||
try {
|
try {
|
||||||
$deptId = $model->getAttr('dept_id');
|
$deptId = $model->getAttr('dept_id');
|
||||||
if ($deptId !== null && $deptId !== '' && $deptId > 0) {
|
|
||||||
$query->where('dept_id', $deptId);
|
|
||||||
}
|
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
// ignore
|
$deptId = null;
|
||||||
}
|
}
|
||||||
|
$normalizedDeptId = AdminScopeHelper::resolvePlayerConfigDeptId($model);
|
||||||
return $query->find();
|
if ($deptId !== null && $deptId !== '' && (int) $deptId > 0) {
|
||||||
|
$normalizedDeptId = (int) $deptId;
|
||||||
|
}
|
||||||
|
$config = DiceLotteryPoolConfig::findByNameForDept(
|
||||||
|
DiceLotteryPoolConfig::NAME_PLAYER_DEFAULT,
|
||||||
|
$normalizedDeptId
|
||||||
|
);
|
||||||
|
if ($config) {
|
||||||
|
return $config;
|
||||||
|
}
|
||||||
|
return DiceLotteryPoolConfig::findByNameForDept('default', $normalizedDeptId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从 DiceLotteryPoolConfig name=default 取 t1_weight~t5_weight 作为玩家未设置时的默认值
|
* 从玩家关联彩金池(或 playerDefault / default)取 t1_weight~t5_weight 作为未设置时的默认值
|
||||||
*/
|
*/
|
||||||
protected static function setDefaultWeightsFromLotteryConfig(DicePlayer $model): void
|
protected static function setDefaultWeightsFromLotteryConfig(DicePlayer $model): void
|
||||||
{
|
{
|
||||||
$config = self::findDefaultLotteryConfigForPlayer($model);
|
$config = null;
|
||||||
|
try {
|
||||||
|
$lotteryConfigId = (int) $model->getAttr('lottery_config_id');
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
$lotteryConfigId = 0;
|
||||||
|
}
|
||||||
|
if ($lotteryConfigId > 0) {
|
||||||
|
$config = DiceLotteryPoolConfig::find($lotteryConfigId);
|
||||||
|
}
|
||||||
|
if (!$config) {
|
||||||
|
$config = self::findPlayerDefaultLotteryConfigForPlayer($model);
|
||||||
|
}
|
||||||
if (!$config) {
|
if (!$config) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ namespace app\dice\service;
|
|||||||
|
|
||||||
use app\dice\helper\AdminScopeHelper;
|
use app\dice\helper\AdminScopeHelper;
|
||||||
use app\dice\logic\reward\DiceRewardLogic;
|
use app\dice\logic\reward\DiceRewardLogic;
|
||||||
|
use app\dice\model\lottery_pool_config\DiceLotteryPoolConfig;
|
||||||
use app\dice\model\reward\DiceReward;
|
use app\dice\model\reward\DiceReward;
|
||||||
use app\dice\model\reward_config\DiceRewardConfig;
|
use app\dice\model\reward_config\DiceRewardConfig;
|
||||||
use plugin\saiadmin\app\model\system\SystemDept;
|
use plugin\saiadmin\app\model\system\SystemDept;
|
||||||
@@ -209,9 +210,99 @@ class DiceChannelConfigService
|
|||||||
}
|
}
|
||||||
$this->ensureRewardReferenceForDept($deptId);
|
$this->ensureRewardReferenceForDept($deptId);
|
||||||
DiceRewardConfig::refreshCache($deptId);
|
DiceRewardConfig::refreshCache($deptId);
|
||||||
|
$this->ensurePlayerDefaultPoolForDept($deptId);
|
||||||
|
$this->migratePlayersDefaultPoolToPlayerDefault($deptId);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 为渠道补齐玩家默认彩金池 name=playerDefault(权重复制自 default)
|
||||||
|
*/
|
||||||
|
public function ensurePlayerDefaultPoolForDept(int $deptId): ?int
|
||||||
|
{
|
||||||
|
if (!$this->tableHasColumn('dice_lottery_pool_config', 'dept_id')) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$exists = Db::table('dice_lottery_pool_config')
|
||||||
|
->where('dept_id', $deptId)
|
||||||
|
->where('name', DiceLotteryPoolConfig::NAME_PLAYER_DEFAULT)
|
||||||
|
->count();
|
||||||
|
if ($exists > 0) {
|
||||||
|
return (int) Db::table('dice_lottery_pool_config')
|
||||||
|
->where('dept_id', $deptId)
|
||||||
|
->where('name', DiceLotteryPoolConfig::NAME_PLAYER_DEFAULT)
|
||||||
|
->value('id');
|
||||||
|
}
|
||||||
|
$defaultRow = Db::table('dice_lottery_pool_config')
|
||||||
|
->where('dept_id', $deptId)
|
||||||
|
->where('name', 'default')
|
||||||
|
->find();
|
||||||
|
if (!$defaultRow) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$defaultRow = (array) $defaultRow;
|
||||||
|
unset($defaultRow['id'], $defaultRow['row_id'], $defaultRow['create_time'], $defaultRow['update_time'], $defaultRow['delete_time']);
|
||||||
|
$defaultRow['name'] = DiceLotteryPoolConfig::NAME_PLAYER_DEFAULT;
|
||||||
|
$defaultRow['remark'] = '默认';
|
||||||
|
$defaultRow['safety_line'] = 0;
|
||||||
|
$defaultRow['kill_enabled'] = 0;
|
||||||
|
$defaultRow['profit_amount'] = 0;
|
||||||
|
$defaultRow['dept_id'] = $deptId;
|
||||||
|
return (int) Db::table('dice_lottery_pool_config')->insertGetId($defaultRow);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将仍关联 name=default 的玩家改为关联 playerDefault(杀分逻辑仍用 default 池)
|
||||||
|
*/
|
||||||
|
public function migratePlayersDefaultPoolToPlayerDefault(int $deptId): int
|
||||||
|
{
|
||||||
|
if (!$this->tableHasColumn('dice_player', 'dept_id')
|
||||||
|
|| !$this->tableHasColumn('dice_player', 'lottery_config_id')) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
$playerDefaultId = Db::table('dice_lottery_pool_config')
|
||||||
|
->where('dept_id', $deptId)
|
||||||
|
->where('name', DiceLotteryPoolConfig::NAME_PLAYER_DEFAULT)
|
||||||
|
->value('id');
|
||||||
|
if (!$playerDefaultId) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
$defaultPoolId = Db::table('dice_lottery_pool_config')
|
||||||
|
->where('dept_id', $deptId)
|
||||||
|
->where('name', 'default')
|
||||||
|
->value('id');
|
||||||
|
if (!$defaultPoolId) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return Db::table('dice_player')
|
||||||
|
->where('dept_id', $deptId)
|
||||||
|
->where('lottery_config_id', (int) $defaultPoolId)
|
||||||
|
->update(['lottery_config_id' => (int) $playerDefaultId]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 为全部渠道与默认模板补齐 playerDefault 奖池并迁移玩家关联
|
||||||
|
*/
|
||||||
|
public function ensurePlayerDefaultPoolsAllChannels(): array
|
||||||
|
{
|
||||||
|
$deptIds = [AdminScopeHelper::DEFAULT_TEMPLATE_DEPT];
|
||||||
|
foreach (SystemDept::column('id') as $id) {
|
||||||
|
$id = (int) $id;
|
||||||
|
if ($id > 0) {
|
||||||
|
$deptIds[] = $id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$deptIds = array_values(array_unique($deptIds));
|
||||||
|
$summary = [];
|
||||||
|
foreach ($deptIds as $deptId) {
|
||||||
|
$summary[$deptId] = [
|
||||||
|
'pool_id' => $this->ensurePlayerDefaultPoolForDept($deptId),
|
||||||
|
'players_migrated' => $this->migratePlayersDefaultPoolToPlayerDefault($deptId),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return $summary;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 按业务 id 从默认模板补齐配置(dice_config / dice_reward_config)
|
* 按业务 id 从默认模板补齐配置(dice_config / dice_reward_config)
|
||||||
*/
|
*/
|
||||||
@@ -297,6 +388,7 @@ class DiceChannelConfigService
|
|||||||
}
|
}
|
||||||
$summary[$deptId] = $this->copyDefaultConfigToDept($deptId);
|
$summary[$deptId] = $this->copyDefaultConfigToDept($deptId);
|
||||||
}
|
}
|
||||||
|
$summary['_player_default_pools'] = $this->ensurePlayerDefaultPoolsAllChannels();
|
||||||
return $summary;
|
return $summary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ class DiceLotteryPoolConfigValidate extends BaseValidate
|
|||||||
*/
|
*/
|
||||||
protected $rule = [
|
protected $rule = [
|
||||||
'name' => 'require',
|
'name' => 'require',
|
||||||
|
'remark' => 'max:200',
|
||||||
|
'config_note' => 'max:500',
|
||||||
't1_weight' => 'require',
|
't1_weight' => 'require',
|
||||||
't2_weight' => 'require',
|
't2_weight' => 'require',
|
||||||
't3_weight' => 'require',
|
't3_weight' => 'require',
|
||||||
@@ -43,6 +45,8 @@ class DiceLotteryPoolConfigValidate extends BaseValidate
|
|||||||
protected $scene = [
|
protected $scene = [
|
||||||
'save' => [
|
'save' => [
|
||||||
'name',
|
'name',
|
||||||
|
'remark',
|
||||||
|
'config_note',
|
||||||
't1_weight',
|
't1_weight',
|
||||||
't2_weight',
|
't2_weight',
|
||||||
't3_weight',
|
't3_weight',
|
||||||
@@ -51,6 +55,8 @@ class DiceLotteryPoolConfigValidate extends BaseValidate
|
|||||||
],
|
],
|
||||||
'update' => [
|
'update' => [
|
||||||
'name',
|
'name',
|
||||||
|
'remark',
|
||||||
|
'config_note',
|
||||||
't1_weight',
|
't1_weight',
|
||||||
't2_weight',
|
't2_weight',
|
||||||
't3_weight',
|
't3_weight',
|
||||||
|
|||||||
Reference in New Issue
Block a user