|
|
@@ -55,8 +55,7 @@
|
|
|
<el-table-column type="selection" width="55" align="center" :reserve-selection="true" />
|
|
|
<el-table-column label="等级" align="center" width="120">
|
|
|
<template #default="scope">
|
|
|
- <span v-if="scope.row.isBreak === 1" style="color: #e6a23c; font-weight: bold">{{ getDisplayLevel(scope.row) }}</span>
|
|
|
- <span v-else>{{ getDisplayLevel(scope.row) }}</span>
|
|
|
+ <span>{{ scope.row.levelNumber }}</span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
<el-table-column label="小盲预置分" align="center">
|
|
|
@@ -95,32 +94,6 @@
|
|
|
</div>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column label="是否休息" align="center" width="120">
|
|
|
- <template #default="scope">
|
|
|
- <el-select v-model="scope.row.isBreak" size="small" style="width: 100px">
|
|
|
- <el-option label="否" :value="0" />
|
|
|
- <el-option label="是" :value="1" />
|
|
|
- </el-select>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- <el-table-column label="休息时长" align="center" width="120">
|
|
|
- <template #default="scope">
|
|
|
- <div class="stepper-cell">
|
|
|
- <el-button size="small" text :disabled="scope.row.isBreak !== 1" @click="stepValue(scope.row, 'breakDurationMinutes', -1)">−</el-button>
|
|
|
- <span class="stepper-value" :style="{ opacity: scope.row.isBreak !== 1 ? 0.4 : 1 }">{{ scope.row.breakDurationMinutes ?? 0 }}</span>
|
|
|
- <el-button size="small" text :disabled="scope.row.isBreak !== 1" @click="stepValue(scope.row, 'breakDurationMinutes', 1)">+</el-button>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- <el-table-column label="展示顺序" align="center" width="120">
|
|
|
- <template #default="scope">
|
|
|
- <div class="stepper-cell">
|
|
|
- <el-button size="small" text @click="stepValue(scope.row, 'displayOrder', -1)">−</el-button>
|
|
|
- <span class="stepper-value">{{ scope.row.displayOrder ?? 0 }}</span>
|
|
|
- <el-button size="small" text @click="stepValue(scope.row, 'displayOrder', 1)">+</el-button>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
<el-table-column label="创建时间" align="center" prop="createdAt" width="180">
|
|
|
<template #default="scope">
|
|
|
<span>{{ parseTime(scope.row.createdAt, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
|
|
@@ -169,15 +142,6 @@
|
|
|
<el-form-item label="升级时间" prop="durationMinutes">
|
|
|
<el-input v-model="form.durationMinutes" placeholder="请输入升级时间" />
|
|
|
</el-form-item>
|
|
|
- <el-form-item label="是否休息" prop="isBreak">
|
|
|
- <el-radio-group v-model="form.isBreak">
|
|
|
- <el-radio :label="1">是</el-radio>
|
|
|
- <el-radio :label="0">否</el-radio>
|
|
|
- </el-radio-group>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="休息时长" prop="breakDurationMinutes">
|
|
|
- <el-input v-model="form.breakDurationMinutes" placeholder="请输入休息时长" />
|
|
|
- </el-form-item>
|
|
|
<el-form-item label="备注" prop="remark">
|
|
|
<el-input v-model="form.remark" placeholder="请输入备注" />
|
|
|
</el-form-item>
|
|
|
@@ -307,10 +271,7 @@ const initFormData: LevelsForm = {
|
|
|
updatedAt: undefined,
|
|
|
createUserId: undefined,
|
|
|
updateUserId: undefined,
|
|
|
- isBreak: 0,
|
|
|
- breakDurationMinutes: undefined,
|
|
|
- remark: undefined,
|
|
|
- displayOrder: undefined
|
|
|
+ remark: undefined
|
|
|
};
|
|
|
const data = reactive<PageData<LevelsForm, LevelsQuery>>({
|
|
|
form: { ...initFormData },
|
|
|
@@ -327,12 +288,9 @@ const data = reactive<PageData<LevelsForm, LevelsQuery>>({
|
|
|
updatedAt: undefined,
|
|
|
createUserId: undefined,
|
|
|
updateUserId: undefined,
|
|
|
- isBreak: undefined,
|
|
|
- breakDurationMinutes: undefined,
|
|
|
- displayOrder: undefined,
|
|
|
params: {},
|
|
|
- // 按展示顺序字段排序(级别不参与排序)
|
|
|
- orderByColumn: 'displayOrder',
|
|
|
+ // 按级别号排序
|
|
|
+ orderByColumn: 'levelNumber',
|
|
|
isAsc: 'asc'
|
|
|
},
|
|
|
rules: {
|
|
|
@@ -350,31 +308,19 @@ const { queryParams, form, rules } = toRefs(data);
|
|
|
const getList = async () => {
|
|
|
loading.value = true;
|
|
|
const res = await listLevels(queryParams.value);
|
|
|
- // 确保 isBreak 为数字类型,避免 select 显示 false/true,按展示顺序字段排序(级别不参与排序)
|
|
|
- levelsList.value = (res.rows || [])
|
|
|
- .map((item: any) => ({
|
|
|
- ...item,
|
|
|
- isBreak: item.isBreak === true || item.isBreak === 1 ? 1 : 0
|
|
|
- }))
|
|
|
- .sort((a, b) => (a.displayOrder || 0) - (b.displayOrder || 0));
|
|
|
+ levelsList.value = (res.rows || []).sort((a, b) => (a.levelNumber || 0) - (b.levelNumber || 0));
|
|
|
total.value = res.total;
|
|
|
loading.value = false;
|
|
|
};
|
|
|
|
|
|
-/** 独立排序方法:按展示顺序字段排序(用于插入和保存后重新排序) */
|
|
|
-const sortListByDisplayOrder = () => {
|
|
|
- levelsList.value.sort((a, b) => (a.displayOrder || 0) - (b.displayOrder || 0));
|
|
|
+/** 独立排序方法:按级别号排序(用于插入和保存后重新排序) */
|
|
|
+const sortListByLevelNumber = () => {
|
|
|
+ levelsList.value.sort((a, b) => (a.levelNumber || 0) - (b.levelNumber || 0));
|
|
|
};
|
|
|
|
|
|
-/** 计算显示级别:休息行不占级别,非休息行连续计算(如:1、2、休息(第2级后)、3、4...) */
|
|
|
-const getDisplayLevel = (row: LevelsVO): string | number => {
|
|
|
- const idx = levelsList.value.findIndex((r) => r.id === row.id);
|
|
|
- if (idx === -1) return row.levelNumber;
|
|
|
- const nonBreakBefore = levelsList.value.slice(0, idx).filter((r) => r.isBreak !== 1).length;
|
|
|
- if (row.isBreak === 1) {
|
|
|
- return `休息(第${nonBreakBefore}级后)`;
|
|
|
- }
|
|
|
- return nonBreakBefore + 1;
|
|
|
+/** 计算显示级别:直接返回级别号 */
|
|
|
+const getDisplayLevel = (row: LevelsVO): number => {
|
|
|
+ return row.levelNumber || 0;
|
|
|
};
|
|
|
|
|
|
/** 取消按钮 */
|
|
|
@@ -559,7 +505,7 @@ const submitFileForm = () => {
|
|
|
};
|
|
|
|
|
|
/** 行内步进器增减(步长=1) */
|
|
|
-const stepValue = (row: LevelsVO, field: 'smallBlind' | 'bigBlind' | 'ante' | 'durationMinutes' | 'breakDurationMinutes' | 'displayOrder', delta: number) => {
|
|
|
+const stepValue = (row: LevelsVO, field: 'smallBlind' | 'bigBlind' | 'ante' | 'durationMinutes', delta: number) => {
|
|
|
const val = (row[field] as number) || 0;
|
|
|
(row as any)[field] = Math.max(0, val + delta);
|
|
|
};
|
|
|
@@ -579,8 +525,7 @@ const validateRows = (): string[] => {
|
|
|
|
|
|
levelsList.value.forEach((row) => {
|
|
|
const errors: string[] = [];
|
|
|
- // 休息行不占级别(级别为0),跳过级别编号校验
|
|
|
- if (row.isBreak !== 1 && (!row.levelNumber || row.levelNumber <= 0)) {
|
|
|
+ if (!row.levelNumber || row.levelNumber <= 0) {
|
|
|
errors.push(`级别${row.levelNumber || '?'}:级别编号不能为空`);
|
|
|
}
|
|
|
if (row.smallBlind === null || row.smallBlind === undefined || row.smallBlind < 0) {
|
|
|
@@ -595,9 +540,6 @@ const validateRows = (): string[] => {
|
|
|
if (row.durationMinutes === null || row.durationMinutes === undefined || row.durationMinutes < 0) {
|
|
|
errors.push(`级别${row.levelNumber || '?'}:本级别持续时间(分钟)不能为空`);
|
|
|
}
|
|
|
- if (row.isBreak === 1 && (!row.breakDurationMinutes || row.breakDurationMinutes <= 0)) {
|
|
|
- errors.push(`级别${row.levelNumber || '?'}:休息级别为"是"时,休息分钟不能为0`);
|
|
|
- }
|
|
|
if (errors.length > 0) {
|
|
|
rowErrors.value.set(row.id, errors);
|
|
|
allErrors.push(...errors);
|
|
|
@@ -619,10 +561,7 @@ const handleInsertAfter = async (row: LevelsVO) => {
|
|
|
smallBlind: 0,
|
|
|
bigBlind: 0,
|
|
|
ante: 0,
|
|
|
- durationMinutes: 0,
|
|
|
- isBreak: 0,
|
|
|
- breakDurationMinutes: 0,
|
|
|
- displayOrder: 0
|
|
|
+ durationMinutes: 0
|
|
|
};
|
|
|
try {
|
|
|
await insertAfter(newLevel, row.levelNumber);
|
|
|
@@ -638,11 +577,7 @@ const handleInsertAfter = async (row: LevelsVO) => {
|
|
|
const idx = levelsList.value.findIndex((r) => r.id === row.id);
|
|
|
if (idx !== -1) {
|
|
|
levelsList.value.splice(idx + 1, 0, { ...newLevel, id: Date.now(), _isNew: true } as any);
|
|
|
- // 按行顺序重排展示顺序,再按展示顺序排序确保顺序正确
|
|
|
- levelsList.value.forEach((item, index) => {
|
|
|
- item.displayOrder = index + 1;
|
|
|
- });
|
|
|
- sortListByDisplayOrder();
|
|
|
+ sortListByLevelNumber();
|
|
|
}
|
|
|
|
|
|
proxy?.$modal.msgSuccess(`成功在第${row.levelNumber}级后插入第${newLevelNumber}级`);
|
|
|
@@ -682,18 +617,15 @@ const handleBatchSave = async () => {
|
|
|
}
|
|
|
});
|
|
|
|
|
|
- // 拉取全部数据(不分页,强制按展示顺序排序)
|
|
|
+ // 拉取全部数据(不分页,强制按级别号排序)
|
|
|
const allRes = await listLevels({
|
|
|
...queryParams.value,
|
|
|
pageNum: 1,
|
|
|
pageSize: 9999999,
|
|
|
- orderByColumn: 'displayOrder',
|
|
|
+ orderByColumn: 'levelNumber',
|
|
|
isAsc: 'asc'
|
|
|
});
|
|
|
- let allRows: LevelsVO[] = (allRes.rows || []).map((item: any) => ({
|
|
|
- ...item,
|
|
|
- isBreak: item.isBreak === true || item.isBreak === 1 ? 1 : 0
|
|
|
- }));
|
|
|
+ let allRows: LevelsVO[] = allRes.rows || [];
|
|
|
|
|
|
// 用本地编辑覆盖全量数据中对应的行(包括对新插入记录的编辑)
|
|
|
allRows.forEach((row) => {
|
|
|
@@ -713,23 +645,17 @@ const handleBatchSave = async () => {
|
|
|
smallBlind: localRow.smallBlind,
|
|
|
bigBlind: localRow.bigBlind,
|
|
|
ante: localRow.ante,
|
|
|
- durationMinutes: localRow.durationMinutes,
|
|
|
- isBreak: localRow.isBreak,
|
|
|
- breakDurationMinutes: localRow.breakDurationMinutes
|
|
|
+ durationMinutes: localRow.durationMinutes
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
|
|
|
- // ✅ 保存前按展示顺序排序(级别不参与排序);自动修正级别:休息行为0不占级别,正式级别连续递增
|
|
|
- allRows.sort((a, b) => (a.displayOrder || 0) - (b.displayOrder || 0));
|
|
|
+ // ✅ 保存前按级别号排序,然后重新计算级别:级别号连续递增
|
|
|
+ allRows.sort((a, b) => (a.levelNumber || 0) - (b.levelNumber || 0));
|
|
|
let expectedLevel = 1;
|
|
|
allRows.forEach((row) => {
|
|
|
- if (row.isBreak === 1) {
|
|
|
- row.levelNumber = 0;
|
|
|
- } else {
|
|
|
- row.levelNumber = expectedLevel++;
|
|
|
- }
|
|
|
+ row.levelNumber = expectedLevel++;
|
|
|
});
|
|
|
|
|
|
console.log('💾 准备保存的数据:', allRows); // 调试日志
|