|
@@ -129,7 +129,7 @@
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
</el-table>
|
|
</el-table>
|
|
|
|
|
|
|
|
- <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
|
|
|
|
|
|
+ <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="applyPagination" />
|
|
|
|
|
|
|
|
<div class="blind-levels-footer">
|
|
<div class="blind-levels-footer">
|
|
|
<el-button type="primary" :loading="saveLoading" @click="handleBatchSave">保存</el-button>
|
|
<el-button type="primary" :loading="saveLoading" @click="handleBatchSave">保存</el-button>
|
|
@@ -254,6 +254,8 @@ const blindLevelsFormRef = ref<ElFormInstance>();
|
|
|
const uploadRef = ref<ElUploadInstance>();
|
|
const uploadRef = ref<ElUploadInstance>();
|
|
|
const uploadFile = ref<File | null>(null);
|
|
const uploadFile = ref<File | null>(null);
|
|
|
const rowErrors = ref<Map<string | number, string[]>>(new Map());
|
|
const rowErrors = ref<Map<string | number, string[]>>(new Map());
|
|
|
|
|
+// 全量数据(前端分页,保证跨页显示级别连续)
|
|
|
|
|
+const allData = ref<BlindLevelsVO[]>([]);
|
|
|
|
|
|
|
|
const props = defineProps({
|
|
const props = defineProps({
|
|
|
blindStructureId: {
|
|
blindStructureId: {
|
|
@@ -339,19 +341,34 @@ const data = reactive<PageData<BlindLevelsForm, BlindLevelsQuery>>({
|
|
|
|
|
|
|
|
const { queryParams, form, rules } = toRefs(data);
|
|
const { queryParams, form, rules } = toRefs(data);
|
|
|
|
|
|
|
|
-/** 查询线下盲注等级列表 */
|
|
|
|
|
|
|
+/** 查询线下盲注等级列表(一次性加载全部数据,前端分页) */
|
|
|
const getList = async () => {
|
|
const getList = async () => {
|
|
|
loading.value = true;
|
|
loading.value = true;
|
|
|
- const res = await listBlindLevels(queryParams.value);
|
|
|
|
|
- // 确保 isBreak 为数字类型,避免 select 显示 false/true,按展示顺序字段排序(级别不参与排序)
|
|
|
|
|
- blindLevelsList.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));
|
|
|
|
|
- total.value = res.total;
|
|
|
|
|
- loading.value = false;
|
|
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await listBlindLevels({
|
|
|
|
|
+ ...queryParams.value,
|
|
|
|
|
+ pageNum: 1,
|
|
|
|
|
+ pageSize: 999999
|
|
|
|
|
+ });
|
|
|
|
|
+ allData.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));
|
|
|
|
|
+ total.value = allData.value.length;
|
|
|
|
|
+ applyPagination();
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loading.value = false;
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/** 根据当前页码和每页条数,从全量数据中截取当前页 */
|
|
|
|
|
+const applyPagination = () => {
|
|
|
|
|
+ const pageNum = queryParams.value.pageNum || 1;
|
|
|
|
|
+ const pageSize = queryParams.value.pageSize || 10;
|
|
|
|
|
+ const start = (pageNum - 1) * pageSize;
|
|
|
|
|
+ blindLevelsList.value = allData.value.slice(start, start + pageSize);
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
/** 独立排序方法:按展示顺序字段排序(用于插入和保存后重新排序) */
|
|
/** 独立排序方法:按展示顺序字段排序(用于插入和保存后重新排序) */
|
|
@@ -359,11 +376,11 @@ const sortListByDisplayOrder = () => {
|
|
|
blindLevelsList.value.sort((a, b) => (a.displayOrder || 0) - (b.displayOrder || 0));
|
|
blindLevelsList.value.sort((a, b) => (a.displayOrder || 0) - (b.displayOrder || 0));
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-/** 计算显示级别:休息行不占级别,非休息行连续计算(如:1、2、休息(第2级后)、3、4...) */
|
|
|
|
|
|
|
+/** 计算显示级别:基于全量数据计算,跨页级别连续 */
|
|
|
const getDisplayLevel = (row: BlindLevelsVO): string | number => {
|
|
const getDisplayLevel = (row: BlindLevelsVO): string | number => {
|
|
|
- const idx = blindLevelsList.value.findIndex((r) => r.id === row.id);
|
|
|
|
|
|
|
+ const idx = allData.value.findIndex((r) => r.id === row.id);
|
|
|
if (idx === -1) return row.levelNumber;
|
|
if (idx === -1) return row.levelNumber;
|
|
|
- const nonBreakBefore = blindLevelsList.value.slice(0, idx).filter((r) => r.isBreak !== 1).length;
|
|
|
|
|
|
|
+ const nonBreakBefore = allData.value.slice(0, idx).filter((r) => r.isBreak !== 1).length;
|
|
|
if (row.isBreak === 1) {
|
|
if (row.isBreak === 1) {
|
|
|
return `休息(第${nonBreakBefore}级后)`;
|
|
return `休息(第${nonBreakBefore}级后)`;
|
|
|
}
|
|
}
|
|
@@ -600,9 +617,9 @@ const validateRows = (): string[] => {
|
|
|
return allErrors;
|
|
return allErrors;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-/** 在指定级别后插入(默认全0,本地插入不刷新列表) */
|
|
|
|
|
|
|
+/** 在指定级别后插入(调用API后重新加载全量数据) */
|
|
|
const handleInsertAfter = async (row: BlindLevelsVO) => {
|
|
const handleInsertAfter = async (row: BlindLevelsVO) => {
|
|
|
- if (insertLoading.value) return; // 防止重复点击
|
|
|
|
|
|
|
+ if (insertLoading.value) return;
|
|
|
insertLoading.value = true;
|
|
insertLoading.value = true;
|
|
|
const newLevelNumber = (row.levelNumber || 0) + 1;
|
|
const newLevelNumber = (row.levelNumber || 0) + 1;
|
|
|
const newLevel: BlindLevelsForm = {
|
|
const newLevel: BlindLevelsForm = {
|
|
@@ -619,26 +636,9 @@ const handleInsertAfter = async (row: BlindLevelsVO) => {
|
|
|
};
|
|
};
|
|
|
try {
|
|
try {
|
|
|
await insertAfter(newLevel, row.levelNumber);
|
|
await insertAfter(newLevel, row.levelNumber);
|
|
|
-
|
|
|
|
|
- // 关键修复:插入新级别后,将后续所有记录的levelNumber+1,避免编号重复
|
|
|
|
|
- blindLevelsList.value.forEach((item) => {
|
|
|
|
|
- if (item.levelNumber >= newLevelNumber && item.id !== row.id) {
|
|
|
|
|
- item.levelNumber += 1;
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // 本地插入新行到正确位置
|
|
|
|
|
- const idx = blindLevelsList.value.findIndex((r) => r.id === row.id);
|
|
|
|
|
- if (idx !== -1) {
|
|
|
|
|
- blindLevelsList.value.splice(idx + 1, 0, { ...newLevel, id: Date.now(), _isNew: true } as any);
|
|
|
|
|
- // 按行顺序重排展示顺序,再按展示顺序排序确保顺序正确
|
|
|
|
|
- blindLevelsList.value.forEach((item, index) => {
|
|
|
|
|
- item.displayOrder = index + 1;
|
|
|
|
|
- });
|
|
|
|
|
- sortListByDisplayOrder();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
proxy?.$modal.msgSuccess(`成功在第${row.levelNumber}级后插入第${newLevelNumber}级`);
|
|
proxy?.$modal.msgSuccess(`成功在第${row.levelNumber}级后插入第${newLevelNumber}级`);
|
|
|
|
|
+ // 重新加载全量数据,保证 allData 与后端一致
|
|
|
|
|
+ await getList();
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
proxy?.$modal.msgError('插入失败,请重试');
|
|
proxy?.$modal.msgError('插入失败,请重试');
|
|
|
console.error('Insert after error:', error);
|
|
console.error('Insert after error:', error);
|
|
@@ -647,9 +647,9 @@ const handleInsertAfter = async (row: BlindLevelsVO) => {
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-/** 批量保存(先拉取全部数据,合并当前页编辑后一起提交) */
|
|
|
|
|
|
|
+/** 批量保存(直接用全量数据,合并当前页编辑后一起提交) */
|
|
|
const handleBatchSave = async () => {
|
|
const handleBatchSave = async () => {
|
|
|
- if (!blindLevelsList.value || blindLevelsList.value.length === 0) {
|
|
|
|
|
|
|
+ if (!allData.value || allData.value.length === 0) {
|
|
|
proxy?.$modal.msgError('没有数据可保存');
|
|
proxy?.$modal.msgError('没有数据可保存');
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
@@ -663,58 +663,13 @@ const handleBatchSave = async () => {
|
|
|
|
|
|
|
|
saveLoading.value = true;
|
|
saveLoading.value = true;
|
|
|
try {
|
|
try {
|
|
|
- // ✅ 关键修复:只收集已存在记录的编辑内容(不包括新插入的临时记录)
|
|
|
|
|
- // 原因:新插入的记录已经通过 insertAfter() API 在后端创建了,
|
|
|
|
|
- // 如果再提交会导致重复数据!
|
|
|
|
|
- const localEdits = new Map<string | number, BlindLevelsVO>();
|
|
|
|
|
-
|
|
|
|
|
- blindLevelsList.value.forEach((row) => {
|
|
|
|
|
- if (row.id && !(row as any)._isNew) {
|
|
|
|
|
- // 只收集已存在的记录,忽略 _isNew 标记的临时记录
|
|
|
|
|
- localEdits.set(row.id, row);
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // 拉取全部数据(不分页,强制按展示顺序排序)
|
|
|
|
|
- const allRes = await listBlindLevels({
|
|
|
|
|
- ...queryParams.value,
|
|
|
|
|
- pageNum: 1,
|
|
|
|
|
- pageSize: 9999999,
|
|
|
|
|
- orderByColumn: 'displayOrder',
|
|
|
|
|
- isAsc: 'asc'
|
|
|
|
|
- });
|
|
|
|
|
- let allRows: BlindLevelsVO[] = (allRes.rows || []).map((item: any) => ({
|
|
|
|
|
|
|
+ // 直接用全量数据(blindLevelsList 中的行是 allData 的引用,编辑已同步)
|
|
|
|
|
+ const allRows = allData.value.map((item: any) => ({
|
|
|
...item,
|
|
...item,
|
|
|
isBreak: item.isBreak === true || item.isBreak === 1 ? 1 : 0
|
|
isBreak: item.isBreak === true || item.isBreak === 1 ? 1 : 0
|
|
|
}));
|
|
}));
|
|
|
|
|
|
|
|
- // 用本地编辑覆盖全量数据中对应的行(包括对新插入记录的编辑)
|
|
|
|
|
- allRows.forEach((row) => {
|
|
|
|
|
- if (row.id && localEdits.has(row.id)) {
|
|
|
|
|
- Object.assign(row, localEdits.get(row.id));
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // ✅ 特殊处理:将用户对新插入记录的编辑合并到后端返回的对应记录上
|
|
|
|
|
- blindLevelsList.value.forEach((localRow) => {
|
|
|
|
|
- if ((localRow as any)._isNew && localRow.levelNumber) {
|
|
|
|
|
- // 找到后端数据中相同 levelNumber 的记录(就是刚才 insertAfter 创建的)
|
|
|
|
|
- const backendRow = allRows.find(r => r.levelNumber === localRow.levelNumber);
|
|
|
|
|
- if (backendRow) {
|
|
|
|
|
- // 将用户的编辑内容合并到后端记录上
|
|
|
|
|
- Object.assign(backendRow, {
|
|
|
|
|
- smallBlind: localRow.smallBlind,
|
|
|
|
|
- bigBlind: localRow.bigBlind,
|
|
|
|
|
- ante: localRow.ante,
|
|
|
|
|
- durationMinutes: localRow.durationMinutes,
|
|
|
|
|
- isBreak: localRow.isBreak,
|
|
|
|
|
- breakDurationMinutes: localRow.breakDurationMinutes
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // ✅ 保存前按展示顺序排序(级别不参与排序);自动修正级别:休息行为0不占级别,正式级别连续递增
|
|
|
|
|
|
|
+ // 保存前按展示顺序排序;自动修正级别:休息行为0不占级别,正式级别连续递增
|
|
|
allRows.sort((a, b) => (a.displayOrder || 0) - (b.displayOrder || 0));
|
|
allRows.sort((a, b) => (a.displayOrder || 0) - (b.displayOrder || 0));
|
|
|
let expectedLevel = 1;
|
|
let expectedLevel = 1;
|
|
|
allRows.forEach((row) => {
|
|
allRows.forEach((row) => {
|
|
@@ -725,7 +680,6 @@ const handleBatchSave = async () => {
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
- console.log('💾 准备保存的数据:', allRows); // 调试日志
|
|
|
|
|
await batchSave(allRows as BlindLevelsForm[]);
|
|
await batchSave(allRows as BlindLevelsForm[]);
|
|
|
proxy?.$modal.msgSuccess('保存成功');
|
|
proxy?.$modal.msgSuccess('保存成功');
|
|
|
await getList();
|
|
await getList();
|