优化奖励配置/按规则一键生成表
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
"colDisplayText": "Display Text",
|
||||
"colDisplayTextEn": "Display Text (EN)",
|
||||
"colRealEv": "Real Settlement",
|
||||
"colRealReward": "Player Real Reward",
|
||||
"colTier": "Tier",
|
||||
"colRemark": "Remark",
|
||||
"placeholderTierSelect": "Tier",
|
||||
@@ -53,7 +54,7 @@
|
||||
"infoNoBigwin": "No BIGWIN rows. Set tier to BIGWIN in the Reward Index tab first.",
|
||||
"btnRuleGenerate": "Generate by rules",
|
||||
"ruleGenerateTitle": "Generate reward index by rules",
|
||||
"ruleGenerateRules": "[Generation logic (same as Create Reward Reference)]\n• 26 cells ordered by id ascending are positions 0–25; each row’s grid_number is 5–30 and unique.\n• Roll D (5–30): start at the cell whose grid_number equals D (start_index); clockwise landing = (start position + D) mod 26; counter-clockwise = start − D (if negative, +26).\n• Each reference row’s “dice points” column is the roll D; tier / real_ev / display text come from the config at the landing id.\n\n[Leopard rolls]\nFor rolls 5, 10, 15, 20, 25, 30, clockwise and counter-clockwise landing tiers must NOT be T4 or T5 (avoid leopard roll + penalty / try again).\n\n[real_ev vs tier]\nreal < −100 → T4; −100 < real < 0 → T3; 0 < real < 100 → T2; 100 < real < 500 → T1; T5 “try again” real_ev=0. Set per-tier real_ev standards below; values are written into the config and can be edited later.\n\n[Inputs]\nT1/T4/T5: fixed weighted counts. T2: minimum weighted count — clockwise and counter-clockwise must satisfy the corresponding constraints (one value per tier, applied to both directions). real_ev standards: one value per tier. Generated T1–T4 use ui_text / ui_text_en = 100 + real_ev (same EN); T5 uses “try again” / “Once again”. Remarks still distinguish break-even vs small win where applicable.",
|
||||
"ruleGenerateRules": "[Generation logic (same as Create Reward Reference)]\n• 26 cells ordered by id ascending are positions 0–25; each row’s grid_number is 5–30 and unique.\n• Roll D (5–30): start at the cell whose grid_number equals D (start_index); clockwise landing = (start position + D) mod 26; counter-clockwise = start − D (if negative, +26).\n• Each reference row’s “dice points” column is the roll D; tier / real_ev / display text come from the config at the landing id.\n\n[Leopard rolls]\nFor rolls 5, 10, 15, 20, 25, 30, clockwise and counter-clockwise landing tiers must NOT be T4 or T5 (avoid leopard roll + penalty / once again).\n\n[Settlement amount vs tier]\nSettlement < 0 → T4; 0 < Settlement < 100 → T3; 100 < Settlement < 200 → T2; Settlement > 200 → T1; T5 “once again” settlement = 0. You can set a unified settlement standard for each tier below; generated rows write those values into the config, and details can be edited later in the table.\n\n[Inputs in this dialog]\nCount: T1/T4/T5 are fixed; T2 is minimum. Clockwise and counter-clockwise weighted counts (each roll result counts once) must each satisfy the entered values; T1, T4, and T5 are entered separately.\nSettlement standard: all cells in the same tier use the same value. On generation, T1–T4 use ui_text / ui_text_en = settlement real_ev; T5 is fixed to \"再来一次\" / \"Once again\". Remarks still distinguish break-even / small win, etc.",
|
||||
"ruleGenT1Row": "T1 (big prize)",
|
||||
"ruleGenT2Row": "T2 (small win / break-even)",
|
||||
"ruleGenT3RealEvOnly": "T3 (rake)",
|
||||
@@ -63,10 +64,10 @@
|
||||
"ruleGenFixedCount": "Fixed count (CW & CCW)",
|
||||
"ruleGenRealEvStd": "real_ev standard",
|
||||
"ruleGenRealEvEditHint": "After saving, you can still edit display text, EN, real_ev and remarks per row in the table above.",
|
||||
"ruleGenInvalidT1RealEv": "T1 real_ev must satisfy 100 < value < 500",
|
||||
"ruleGenInvalidT2RealEv": "T2 real_ev must satisfy 0 < value < 100",
|
||||
"ruleGenInvalidT3RealEv": "T3 real_ev must satisfy -100 < value < 0",
|
||||
"ruleGenInvalidT4RealEv": "T4 real_ev must satisfy value < -100",
|
||||
"ruleGenInvalidT1RealEv": "T1 settlement amount must satisfy: value > 200",
|
||||
"ruleGenInvalidT2RealEv": "T2 settlement amount must satisfy: 100 < value < 200",
|
||||
"ruleGenInvalidT3RealEv": "T3 settlement amount must satisfy: 0 < value < 100",
|
||||
"ruleGenInvalidT4RealEv": "T4 settlement amount must satisfy: value < 0",
|
||||
"ruleGenInvalidT5RealEv": "T5 “try again” real_ev must be 0",
|
||||
"ruleGenT1Min": "T1 fixed count (CW & CCW)",
|
||||
"ruleGenT2Min": "T2 min (CW & CCW)",
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
"colDicePoints": "色子点数",
|
||||
"colDisplayText": "显示文本",
|
||||
"colDisplayTextEn": "显示文本(英文)",
|
||||
"colRealEv": "真实结算",
|
||||
"colRealEv": "结算金额",
|
||||
"colRealReward": "玩家实际中奖",
|
||||
"colTier": "所属档位",
|
||||
"colRemark": "备注",
|
||||
"placeholderTierSelect": "档位",
|
||||
@@ -53,7 +54,7 @@
|
||||
"infoNoBigwin": "暂无 BIGWIN 档位配置,请先在「奖励索引」中设置 tier 为 BIGWIN",
|
||||
"btnRuleGenerate": "按规则生成",
|
||||
"ruleGenerateTitle": "按规则生成奖励索引",
|
||||
"ruleGenerateRules": "【生成逻辑(与创建奖励对照一致)】\n• 盘面 26 格按 id 升序为位置 0~25;每条配置的 grid_number 为 5~30 且不重复。\n• 摇取点数 D(5~30):起点为「grid_number=D」所在格位的 id(即 start_index),顺时针落点位置 = (起点位置 + D) mod 26,逆时针落点 = 起点位置 − D(若小于 0 则 +26)。\n• 对照表每条记录的「色子点数」列为摇取点数 D;档位、真实结算、显示文案取自落点格位对应 id 的配置。\n\n【豹子摇取点数】\n摇取点数为 5、10、15、20、25、30 时,其顺/逆时针落点档位不能为 T4、T5(避免对照表上出现豹子点数 + 惩罚/再来一次)。\n\n【real_ev 与 tier】\nreal < −100 → T4;−100 < real < 0 → T3;0 < real < 100 → T2;100 < real < 500 → T1;T5「再来一次」real_ev=0。下方可为各档位填写统一的 real_ev 标准,生成时写入配置;细则可稍后在表格中再改。\n\n【本弹窗输入】\n条数:T1/T4/T5「固定」;T2「不少于」——顺时针与逆时针的加权条数(每条摇取结果计一次)须分别满足所填数值;T1、T4 与 T5 分开填写。\nreal_ev 标准:同档位各格使用同一数值。生成时 T1~T4 的 ui_text / ui_text_en 均为「100+真实结算」;T5 固定为「再来一次」/「Once again」。备注仍区分完美回本/小赚等。",
|
||||
"ruleGenerateRules": "【生成逻辑(与创建奖励对照一致)】\n• 盘面 26 格按 id 升序为位置 0~25;每条配置的 grid_number 为 5~30 且不重复。\n• 摇取点数 D(5~30):起点为「grid_number=D」所在格位的 id(即 start_index),顺时针落点位置 = (起点位置 + D) mod 26,逆时针落点 = 起点位置 − D(若小于 0 则 +26)。\n• 对照表每条记录的「色子点数」列为摇取点数 D;档位、真实结算、显示文案取自落点格位对应 id 的配置。\n\n【豹子摇取点数】\n摇取点数为 5、10、15、20、25、30 时,其顺/逆时针落点档位不能为 T4、T5(避免对照表上出现豹子点数 + 惩罚/再来一次)。\n\n【结算金额 与 档位】\n结算金额 < 0 → T4;0 < 结算金额 < 100 → T3;100 < 结算金额 < 200 → T2;200 < 结算金额 → T1;T5「再来一次」结算金额=0。下方可为各档位填写统一的 结算金额 标准,生成时写入配置;细则可稍后在表格中再改。\n\n【本弹窗输入】\n条数:T1/T4/T5「固定」;T2「不少于」——顺时针与逆时针的加权条数(每条摇取结果计一次)须分别满足所填数值;T1、T4 与 T5 分开填写。\n结算金额 标准:同档位各格使用同一数值。生成时 T1~T4 的 显示文本 / 显示文本(英文) = 结算金额;T5 固定为「再来一次」/「Once again」。备注仍区分完美回本/小赚等。",
|
||||
"ruleGenT1Row": "T1 大奖",
|
||||
"ruleGenT2Row": "T2 小赚/回本",
|
||||
"ruleGenT3RealEvOnly": "T3 抽水",
|
||||
@@ -61,13 +62,13 @@
|
||||
"ruleGenT5Row": "T5 再来一次",
|
||||
"ruleGenMinCount": "最少条数",
|
||||
"ruleGenFixedCount": "固定条数(顺/逆)",
|
||||
"ruleGenRealEvStd": "real_ev 标准",
|
||||
"ruleGenRealEvStd": "结算金额",
|
||||
"ruleGenRealEvEditHint": "生成并保存后,仍可在本页表格中逐条修改显示文案、英文、真实结算与备注。",
|
||||
"ruleGenInvalidT1RealEv": "T1 的 real_ev 须满足:100 < 值 < 500",
|
||||
"ruleGenInvalidT2RealEv": "T2 的 real_ev 须满足:0 < 值 < 100",
|
||||
"ruleGenInvalidT3RealEv": "T3 的 real_ev 须满足:-100 < 值 < 0",
|
||||
"ruleGenInvalidT4RealEv": "T4 的 real_ev 须满足:值 < -100",
|
||||
"ruleGenInvalidT5RealEv": "T5「再来一次」的 real_ev 须为 0",
|
||||
"ruleGenInvalidT1RealEv": "T1 的 结算金额 满足:200 < 值",
|
||||
"ruleGenInvalidT2RealEv": "T2 的 结算金额 满足:100 < 值 < 200",
|
||||
"ruleGenInvalidT3RealEv": "T3 的 结算金额 满足:0 < 值 < 100",
|
||||
"ruleGenInvalidT4RealEv": "T4 的 结算金额 满足:值 < 0",
|
||||
"ruleGenInvalidT5RealEv": "T5「再来一次」的 结算金额 须为 0",
|
||||
"ruleGenT1Min": "T1 固定条数(顺/逆)",
|
||||
"ruleGenT2Min": "T2 最少条数(顺/逆)",
|
||||
"ruleGenT4Max": "T4 固定条数(顺/逆)",
|
||||
|
||||
@@ -78,12 +78,18 @@
|
||||
<template #default="{ row }">
|
||||
<ElInputNumber
|
||||
v-model="row.real_ev"
|
||||
@change="handleRealEvChange(row)"
|
||||
controls-position="right"
|
||||
size="small"
|
||||
class="full-width"
|
||||
/>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn :label="$t('page.configPage.colRealReward')" min-width="130" align="center">
|
||||
<template #default="{ row }">
|
||||
<span>{{ calcRealReward(row.real_ev) }}</span>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn :label="$t('page.configPage.colTier')" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<ElSelect
|
||||
@@ -162,6 +168,7 @@
|
||||
<template #default="{ row }">
|
||||
<ElInputNumber
|
||||
v-model="row.real_ev"
|
||||
@change="handleRealEvChange(row)"
|
||||
controls-position="right"
|
||||
size="small"
|
||||
class="full-width"
|
||||
@@ -481,6 +488,24 @@
|
||||
}
|
||||
}
|
||||
|
||||
function calcRealReward(realEv: unknown): number {
|
||||
const n = typeof realEv === 'number' && !Number.isNaN(realEv) ? realEv : Number(realEv)
|
||||
if (Number.isNaN(n)) {
|
||||
return -100
|
||||
}
|
||||
return n - 100
|
||||
}
|
||||
|
||||
function handleRealEvChange(row: IndexRow) {
|
||||
const n =
|
||||
typeof row.real_ev === 'number' && !Number.isNaN(row.real_ev)
|
||||
? row.real_ev
|
||||
: Number(row.real_ev)
|
||||
const text = Number.isNaN(n) ? '' : String(n)
|
||||
row.ui_text = text
|
||||
row.ui_text_en = text
|
||||
}
|
||||
|
||||
async function handleCreateRewardReference() {
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
|
||||
@@ -22,7 +22,11 @@
|
||||
<el-input v-model="formData.ui_text_en" :placeholder="$t('page.form.placeholderUiTextEn')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('page.form.labelRealEv')" prop="real_ev">
|
||||
<el-input-number v-model="formData.real_ev" :placeholder="$t('page.form.placeholderRealEv')" />
|
||||
<el-input-number
|
||||
v-model="formData.real_ev"
|
||||
:placeholder="$t('page.form.placeholderRealEv')"
|
||||
@change="handleRealEvChange"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('page.form.labelTier')" prop="tier">
|
||||
<el-select
|
||||
@@ -237,6 +241,16 @@
|
||||
console.log('表单验证失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const handleRealEvChange = () => {
|
||||
const n =
|
||||
typeof formData.real_ev === 'number' && !Number.isNaN(formData.real_ev)
|
||||
? formData.real_ev
|
||||
: Number(formData.real_ev)
|
||||
const text = Number.isNaN(n) ? '' : String(n)
|
||||
formData.ui_text = text
|
||||
formData.ui_text_en = text
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -53,12 +53,12 @@ export interface TierRealEvStandards {
|
||||
T5: number
|
||||
}
|
||||
|
||||
/** 默认标准(与常见业务约定一致:100<T1<500,等) */
|
||||
/** 默认标准(与规则弹窗说明一致) */
|
||||
export const DEFAULT_TIER_REAL_EV_STANDARDS: TierRealEvStandards = {
|
||||
T1: 400,
|
||||
T2: 50,
|
||||
T3: -80,
|
||||
T4: -140,
|
||||
T1: 300,
|
||||
T2: 150,
|
||||
T3: 50,
|
||||
T4: -40,
|
||||
T5: 0
|
||||
}
|
||||
|
||||
@@ -66,16 +66,16 @@ export const DEFAULT_TIER_REAL_EV_STANDARDS: TierRealEvStandards = {
|
||||
* 校验档位与 real_ev 区间是否一致;通过返回 null,否则返回 i18n 键名(不含 page.configPage. 前缀)
|
||||
*/
|
||||
export function validateTierRealEvStandards(s: TierRealEvStandards): string | null {
|
||||
if (!Number.isFinite(s.T1) || !(s.T1 > 100 && s.T1 < 500)) {
|
||||
if (!Number.isFinite(s.T1) || !(s.T1 > 200)) {
|
||||
return 'ruleGenInvalidT1RealEv'
|
||||
}
|
||||
if (!Number.isFinite(s.T2) || !(s.T2 > 0 && s.T2 < 100)) {
|
||||
if (!Number.isFinite(s.T2) || !(s.T2 > 100 && s.T2 < 200)) {
|
||||
return 'ruleGenInvalidT2RealEv'
|
||||
}
|
||||
if (!Number.isFinite(s.T3) || !(-100 < s.T3 && s.T3 < 0)) {
|
||||
if (!Number.isFinite(s.T3) || !(s.T3 > 0 && s.T3 < 100)) {
|
||||
return 'ruleGenInvalidT3RealEv'
|
||||
}
|
||||
if (!Number.isFinite(s.T4) || !(s.T4 < -100)) {
|
||||
if (!Number.isFinite(s.T4) || !(s.T4 < 0)) {
|
||||
return 'ruleGenInvalidT4RealEv'
|
||||
}
|
||||
if (!Number.isFinite(s.T5) || s.T5 !== 0) {
|
||||
@@ -271,10 +271,21 @@ export function generateTiers(input: GenerateTierInput): GenerateTierResult {
|
||||
return { ok: false, message: '在当前盘面与约束下未找到可行解,请调整 T1/T4/T5 固定条数或放宽 T2 下限后重试' }
|
||||
}
|
||||
|
||||
function uiTextByTierWhenStandards(
|
||||
tier: IndexTier,
|
||||
realEv: number
|
||||
): { ui_text: string; ui_text_en: string } {
|
||||
if (tier === 'T5') {
|
||||
return { ui_text: '再来一次', ui_text_en: 'Once again' }
|
||||
}
|
||||
const value = String(realEv)
|
||||
return { ui_text: value, ui_text_en: value }
|
||||
}
|
||||
|
||||
/** 展示文案:直接使用真实结算值(中英文相同) */
|
||||
function uiTextFromRealEv(realEv: number): { ui_text: string; ui_text_en: string } {
|
||||
const s = String(realEv)
|
||||
return { ui_text: s, ui_text_en: s }
|
||||
const value = String(realEv)
|
||||
return { ui_text: value, ui_text_en: value }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -315,31 +326,31 @@ export function buildRowsFromTiers(
|
||||
if (standards !== undefined) {
|
||||
if (tier === 'T1') {
|
||||
real_ev = standards.T1
|
||||
const f = uiTextFromRealEv(real_ev)
|
||||
const f = uiTextByTierWhenStandards(tier, real_ev)
|
||||
ui_text = f.ui_text
|
||||
ui_text_en = f.ui_text_en
|
||||
remark = '大奖格'
|
||||
} else if (tier === 'T2') {
|
||||
real_ev = standards.T2
|
||||
const f = uiTextFromRealEv(real_ev)
|
||||
const f = uiTextByTierWhenStandards(tier, real_ev)
|
||||
ui_text = f.ui_text
|
||||
ui_text_en = f.ui_text_en
|
||||
remark = standards.T2 <= 1 ? '完美回本' : '小赚'
|
||||
} else if (tier === 'T3') {
|
||||
real_ev = standards.T3
|
||||
const f = uiTextFromRealEv(real_ev)
|
||||
const f = uiTextByTierWhenStandards(tier, real_ev)
|
||||
ui_text = f.ui_text
|
||||
ui_text_en = f.ui_text_en
|
||||
remark = '抽水'
|
||||
} else if (tier === 'T4') {
|
||||
real_ev = standards.T4
|
||||
const f = uiTextFromRealEv(real_ev)
|
||||
const f = uiTextByTierWhenStandards(tier, real_ev)
|
||||
ui_text = f.ui_text
|
||||
ui_text_en = f.ui_text_en
|
||||
remark = '惩罚'
|
||||
} else {
|
||||
real_ev = standards.T5
|
||||
const f = uiTextFromRealEv(real_ev)
|
||||
const f = uiTextByTierWhenStandards(tier, real_ev)
|
||||
ui_text = f.ui_text
|
||||
ui_text_en = f.ui_text_en
|
||||
remark = '前端需要在播放一次动画(特殊)'
|
||||
|
||||
Reference in New Issue
Block a user