1.优化奖励配置设置-创建奖励对照表单样式
This commit is contained in:
@@ -60,6 +60,7 @@
|
|||||||
"createRefPreviewImportNoop": "Mapping unchanged, nothing to import (existing weights kept)",
|
"createRefPreviewImportNoop": "Mapping unchanged, nothing to import (existing weights kept)",
|
||||||
"createRefPreviewDiff": "Diff (old → new)",
|
"createRefPreviewDiff": "Diff (old → new)",
|
||||||
"createRefPreviewNoDiff": "No change",
|
"createRefPreviewNoDiff": "No change",
|
||||||
|
"createRefPreviewWeightsSaved": "Weights saved",
|
||||||
"createRefSuccess": "Created for 26 dice points (5–30), clockwise + counter-clockwise: clockwise added {cwNew}, counter-clockwise added {ccwNew}; clockwise updated {cwUp}, counter-clockwise updated {ccwUp}{skippedPart}",
|
"createRefSuccess": "Created for 26 dice points (5–30), clockwise + counter-clockwise: clockwise added {cwNew}, counter-clockwise added {ccwNew}; clockwise updated {cwUp}, counter-clockwise updated {ccwUp}{skippedPart}",
|
||||||
"createRefSuccessSkipped": "; {n} point(s) used fallback start index",
|
"createRefSuccessSkipped": "; {n} point(s) used fallback start index",
|
||||||
"createRefSuccessSimple": "Created successfully",
|
"createRefSuccessSimple": "Created successfully",
|
||||||
|
|||||||
@@ -60,6 +60,7 @@
|
|||||||
"createRefPreviewImportNoop": "色子点数映射未变化,无需导入(已保留现有权重)",
|
"createRefPreviewImportNoop": "色子点数映射未变化,无需导入(已保留现有权重)",
|
||||||
"createRefPreviewDiff": "差异(旧 → 新)",
|
"createRefPreviewDiff": "差异(旧 → 新)",
|
||||||
"createRefPreviewNoDiff": "无变化",
|
"createRefPreviewNoDiff": "无变化",
|
||||||
|
"createRefPreviewWeightsSaved": "已保存权重",
|
||||||
"createRefSuccess": "已按 5-30 共 26 个点数、顺时针+逆时针创建:顺时针新增 {cwNew} 条、逆时针新增 {ccwNew} 条;顺时针更新 {cwUp} 条、逆时针更新 {ccwUp} 条{skippedPart}",
|
"createRefSuccess": "已按 5-30 共 26 个点数、顺时针+逆时针创建:顺时针新增 {cwNew} 条、逆时针新增 {ccwNew} 条;顺时针更新 {cwUp} 条、逆时针更新 {ccwUp} 条{skippedPart}",
|
||||||
"createRefSuccessSkipped": ";{n} 个点数使用兜底起始索引",
|
"createRefSuccessSkipped": ";{n} 个点数使用兜底起始索引",
|
||||||
"createRefSuccessSimple": "创建成功",
|
"createRefSuccessSimple": "创建成功",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<ElDialog
|
<ElDialog
|
||||||
v-model="visible"
|
v-model="visible"
|
||||||
:title="$t('page.configPage.createRefPreviewTitle')"
|
:title="$t('page.configPage.createRefPreviewTitle')"
|
||||||
width="980px"
|
width="860px"
|
||||||
align-center
|
align-center
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
@close="handleClose"
|
@close="handleClose"
|
||||||
@@ -31,15 +31,26 @@
|
|||||||
size="small"
|
size="small"
|
||||||
class="preview-table"
|
class="preview-table"
|
||||||
>
|
>
|
||||||
<ElTableColumn :label="$t('page.table.dicePoints')" prop="grid_number" width="120" align="center" />
|
<ElTableColumn :label="$t('page.table.dicePoints')" prop="grid_number" width="90" align="center" />
|
||||||
<ElTableColumn label="start_index" prop="start_index" width="110" align="center" />
|
<ElTableColumn label="start" prop="start_index" width="78" align="center" />
|
||||||
<ElTableColumn :label="$t('page.table.endIndex')" prop="id" width="110" align="center" />
|
<ElTableColumn :label="$t('page.table.endIndex')" prop="id" width="78" align="center" />
|
||||||
<ElTableColumn :label="$t('page.table.tier')" prop="tier" width="90" align="center" />
|
<ElTableColumn :label="$t('page.table.displayText')" prop="ui_text" width="90" align="center" show-overflow-tooltip />
|
||||||
<ElTableColumn :label="$t('page.table.displayText')" prop="ui_text" min-width="110" align="center" show-overflow-tooltip />
|
<ElTableColumn :label="$t('page.table.realEv')" prop="real_ev" width="90" align="center" show-overflow-tooltip />
|
||||||
<ElTableColumn :label="$t('page.table.realEv')" prop="real_ev" width="110" align="center" show-overflow-tooltip />
|
<ElTableColumn :label="$t('page.table.remark')" prop="remark" min-width="80" align="center" show-overflow-tooltip />
|
||||||
<ElTableColumn :label="$t('page.table.remark')" prop="remark" min-width="140" align="center" show-overflow-tooltip />
|
<ElTableColumn :label="$t('page.table.weight')" width="130" align="center">
|
||||||
<ElTableColumn :label="$t('page.table.weight')" prop="weight" width="110" align="center" />
|
<template #default="{ row }">
|
||||||
<ElTableColumn :label="$t('page.configPage.createRefPreviewDiff')" min-width="220" align="center">
|
<ElInputNumber
|
||||||
|
v-model="row.weight"
|
||||||
|
:min="1"
|
||||||
|
:max="10000"
|
||||||
|
:step="1"
|
||||||
|
controls-position="right"
|
||||||
|
size="small"
|
||||||
|
class="weight-input"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</ElTableColumn>
|
||||||
|
<ElTableColumn :label="$t('page.configPage.createRefPreviewDiff')" min-width="120" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<span v-if="row?.diff_changed" class="diff-text">
|
<span v-if="row?.diff_changed" class="diff-text">
|
||||||
{{ formatDiff(row) }}
|
{{ formatDiff(row) }}
|
||||||
@@ -62,15 +73,26 @@
|
|||||||
size="small"
|
size="small"
|
||||||
class="preview-table"
|
class="preview-table"
|
||||||
>
|
>
|
||||||
<ElTableColumn :label="$t('page.table.dicePoints')" prop="grid_number" width="120" align="center" />
|
<ElTableColumn :label="$t('page.table.dicePoints')" prop="grid_number" width="90" align="center" />
|
||||||
<ElTableColumn label="start_index" prop="start_index" width="110" align="center" />
|
<ElTableColumn label="start" prop="start_index" width="78" align="center" />
|
||||||
<ElTableColumn :label="$t('page.table.endIndex')" prop="id" width="110" align="center" />
|
<ElTableColumn :label="$t('page.table.endIndex')" prop="id" width="78" align="center" />
|
||||||
<ElTableColumn :label="$t('page.table.tier')" prop="tier" width="90" align="center" />
|
<ElTableColumn :label="$t('page.table.displayText')" prop="ui_text" width="90" align="center" show-overflow-tooltip />
|
||||||
<ElTableColumn :label="$t('page.table.displayText')" prop="ui_text" min-width="110" align="center" show-overflow-tooltip />
|
<ElTableColumn :label="$t('page.table.realEv')" prop="real_ev" width="90" align="center" show-overflow-tooltip />
|
||||||
<ElTableColumn :label="$t('page.table.realEv')" prop="real_ev" width="110" align="center" show-overflow-tooltip />
|
<ElTableColumn :label="$t('page.table.remark')" prop="remark" min-width="80" align="center" show-overflow-tooltip />
|
||||||
<ElTableColumn :label="$t('page.table.remark')" prop="remark" min-width="140" align="center" show-overflow-tooltip />
|
<ElTableColumn :label="$t('page.table.weight')" width="120" align="center">
|
||||||
<ElTableColumn :label="$t('page.table.weight')" prop="weight" width="110" align="center" />
|
<template #default="{ row }">
|
||||||
<ElTableColumn :label="$t('page.configPage.createRefPreviewDiff')" min-width="220" align="center">
|
<ElInputNumber
|
||||||
|
v-model="row.weight"
|
||||||
|
:min="1"
|
||||||
|
:max="10000"
|
||||||
|
:step="1"
|
||||||
|
controls-position="right"
|
||||||
|
size="small"
|
||||||
|
class="weight-input"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</ElTableColumn>
|
||||||
|
<ElTableColumn :label="$t('page.configPage.createRefPreviewDiff')" min-width="120" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<span v-if="row?.diff_changed" class="diff-text">
|
<span v-if="row?.diff_changed" class="diff-text">
|
||||||
{{ formatDiff(row) }}
|
{{ formatDiff(row) }}
|
||||||
@@ -175,15 +197,74 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toWeight(v: unknown): number {
|
||||||
|
const num = typeof v === 'number' && !Number.isNaN(v) ? v : Number(v)
|
||||||
|
if (Number.isNaN(num)) return 1
|
||||||
|
return Math.max(1, Math.min(10000, Math.floor(num)))
|
||||||
|
}
|
||||||
|
|
||||||
|
function collectDesiredWeights(): Record<string, number> {
|
||||||
|
const map: Record<string, number> = {}
|
||||||
|
for (const t of tierKeys) {
|
||||||
|
const tierData = preview.value?.[t]
|
||||||
|
if (!tierData) continue
|
||||||
|
const cw = Array.isArray(tierData[0]) ? tierData[0] : []
|
||||||
|
const ccw = Array.isArray(tierData[1]) ? tierData[1] : []
|
||||||
|
for (const r of cw) {
|
||||||
|
const gn = r?.grid_number != null ? Number(r.grid_number) : NaN
|
||||||
|
if (!Number.isNaN(gn)) map[`0:${gn}`] = toWeight(r?.weight)
|
||||||
|
}
|
||||||
|
for (const r of ccw) {
|
||||||
|
const gn = r?.grid_number != null ? Number(r.grid_number) : NaN
|
||||||
|
if (!Number.isNaN(gn)) map[`1:${gn}`] = toWeight(r?.weight)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map
|
||||||
|
}
|
||||||
|
|
||||||
|
async function applyWeights(desired: Record<string, number>) {
|
||||||
|
const res: any = await api.weightRatioList({ dept_id: props.deptId })
|
||||||
|
const raw = res?.data ?? res
|
||||||
|
const items: Array<{ id: number; weight: number }> = []
|
||||||
|
for (const t of tierKeys) {
|
||||||
|
const tierData = raw?.[t]
|
||||||
|
if (!tierData) continue
|
||||||
|
const list0 = Array.isArray(tierData[0]) ? tierData[0] : []
|
||||||
|
const list1 = Array.isArray(tierData[1]) ? tierData[1] : []
|
||||||
|
for (const r of list0) {
|
||||||
|
const rid = r?.reward_id != null ? Number(r.reward_id) : 0
|
||||||
|
const gn = r?.grid_number != null ? Number(r.grid_number) : NaN
|
||||||
|
if (rid > 0 && !Number.isNaN(gn)) {
|
||||||
|
const w = desired[`0:${gn}`]
|
||||||
|
if (w != null) items.push({ id: rid, weight: w })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const r of list1) {
|
||||||
|
const rid = r?.reward_id != null ? Number(r.reward_id) : 0
|
||||||
|
const gn = r?.grid_number != null ? Number(r.grid_number) : NaN
|
||||||
|
if (rid > 0 && !Number.isNaN(gn)) {
|
||||||
|
const w = desired[`1:${gn}`]
|
||||||
|
if (w != null) items.push({ id: rid, weight: w })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (items.length > 0) {
|
||||||
|
await api.batchUpdateWeights(items, { dept_id: props.deptId })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function handleImport() {
|
async function handleImport() {
|
||||||
submitting.value = true
|
submitting.value = true
|
||||||
try {
|
try {
|
||||||
const res: any = await api.createRewardReference({ dept_id: props.deptId })
|
const desired = collectDesiredWeights()
|
||||||
const data = res?.data ?? res
|
if (!meta.unchanged) {
|
||||||
if (data?.unchanged) {
|
await api.createRewardReference({ dept_id: props.deptId })
|
||||||
ElMessage.success(t('page.configPage.createRefPreviewImportNoop'))
|
await applyWeights(desired)
|
||||||
} else {
|
|
||||||
ElMessage.success(t('page.configPage.createRefPreviewImportOk'))
|
ElMessage.success(t('page.configPage.createRefPreviewImportOk'))
|
||||||
|
} else {
|
||||||
|
// 映射未变化:直接保存权重即可
|
||||||
|
await applyWeights(desired)
|
||||||
|
ElMessage.success(t('page.configPage.createRefPreviewWeightsSaved'))
|
||||||
}
|
}
|
||||||
emit('success')
|
emit('success')
|
||||||
handleClose()
|
handleClose()
|
||||||
@@ -210,12 +291,12 @@
|
|||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.dialog-body {
|
.dialog-body {
|
||||||
min-height: 240px;
|
min-height: 120px;
|
||||||
}
|
}
|
||||||
.preview-tip {
|
.preview-tip {
|
||||||
margin-bottom: 12px;
|
margin-bottom: 8px;
|
||||||
padding: 10px 12px;
|
padding: 8px 10px;
|
||||||
font-size: 13px;
|
font-size: 12px;
|
||||||
color: var(--el-text-color-regular);
|
color: var(--el-text-color-regular);
|
||||||
background: var(--el-fill-color-light);
|
background: var(--el-fill-color-light);
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
@@ -225,7 +306,10 @@
|
|||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
}
|
}
|
||||||
.preview-table {
|
.preview-table {
|
||||||
margin-top: 8px;
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
.weight-input {
|
||||||
|
width: 110px;
|
||||||
}
|
}
|
||||||
:deep(.row-diff td) {
|
:deep(.row-diff td) {
|
||||||
background: var(--el-color-warning-light-9);
|
background: var(--el-color-warning-light-9);
|
||||||
@@ -239,5 +323,23 @@
|
|||||||
.diff-text-ok {
|
.diff-text-ok {
|
||||||
color: var(--el-text-color-secondary);
|
color: var(--el-text-color-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 减少弹窗内容区与表格留白 */
|
||||||
|
:deep(.el-dialog__body) {
|
||||||
|
padding: 12px 14px;
|
||||||
|
}
|
||||||
|
:deep(.el-tabs__header) {
|
||||||
|
margin: 0 0 8px 0;
|
||||||
|
}
|
||||||
|
:deep(.el-tabs__item) {
|
||||||
|
height: 34px;
|
||||||
|
line-height: 34px;
|
||||||
|
}
|
||||||
|
:deep(.el-table .cell) {
|
||||||
|
padding: 4px 6px;
|
||||||
|
}
|
||||||
|
:deep(.el-table__row) {
|
||||||
|
height: 34px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -344,10 +344,14 @@ class DiceRewardLogic
|
|||||||
$compare = $this->compareReferenceRows($computed['rows'], $existing);
|
$compare = $this->compareReferenceRows($computed['rows'], $existing);
|
||||||
$unchanged = $compare['unchanged'];
|
$unchanged = $compare['unchanged'];
|
||||||
|
|
||||||
|
$specialGrids = [5, 10, 15, 20, 25, 30];
|
||||||
$previewRows = [];
|
$previewRows = [];
|
||||||
foreach ($computed['rows'] as $row) {
|
foreach ($computed['rows'] as $row) {
|
||||||
$key = $row['direction'] . ':' . $row['grid_number'];
|
$key = $row['direction'] . ':' . $row['grid_number'];
|
||||||
$weight = self::WEIGHT_MIN;
|
$gridNumber = isset($row['grid_number']) ? (int) $row['grid_number'] : 0;
|
||||||
|
$weight = $unchanged
|
||||||
|
? self::WEIGHT_MIN
|
||||||
|
: (in_array($gridNumber, $specialGrids, true) ? self::WEIGHT_MIN : 100);
|
||||||
$oldStart = null;
|
$oldStart = null;
|
||||||
$oldEnd = null;
|
$oldEnd = null;
|
||||||
$oldTier = null;
|
$oldTier = null;
|
||||||
@@ -358,8 +362,13 @@ class DiceRewardLogic
|
|||||||
$oldTier = isset($existing[$key]['tier']) ? (string) $existing[$key]['tier'] : null;
|
$oldTier = isset($existing[$key]['tier']) ? (string) $existing[$key]['tier'] : null;
|
||||||
$oldWeight = isset($existing[$key]['weight']) ? (int) $existing[$key]['weight'] : null;
|
$oldWeight = isset($existing[$key]['weight']) ? (int) $existing[$key]['weight'] : null;
|
||||||
}
|
}
|
||||||
|
// 映射未变化时:通常复用旧权重;但若旧权重为 1 且非特殊点数,则按新默认建议展示为 100(方便管理员快速落配置)
|
||||||
if ($unchanged && $oldWeight !== null) {
|
if ($unchanged && $oldWeight !== null) {
|
||||||
$weight = max(self::WEIGHT_MIN, min(self::WEIGHT_MAX, (int) $oldWeight));
|
$oldWeight = (int) $oldWeight;
|
||||||
|
$weight = max(self::WEIGHT_MIN, min(self::WEIGHT_MAX, $oldWeight));
|
||||||
|
if ($weight === self::WEIGHT_MIN && !in_array($gridNumber, $specialGrids, true)) {
|
||||||
|
$weight = 100;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$diffChanged = false;
|
$diffChanged = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user