fix: 修复批量删除 undefined/失败问题(POST 替代 DELETE body)
Deploy to Server / deploy (push) Successful in 1m38s
Deploy to Server / deploy (push) Successful in 1m38s
- 批量删除改走 POST /users/batch-remove(稳定保证 body 可被 Express 解析),同时增强 DELETE /batch 兼容 query string 回退 - 前端 usersApi.batchRemove 改用 POST 请求;批量删除函数新增 ok 标志位校验 + ?? 0 防 undefined,catch 分支带前缀明确提示失败原因 - npm run build 通过
This commit is contained in:
@@ -66,11 +66,7 @@ export const usersApi = {
|
|||||||
results: Array<{ idx: number; ok: boolean; id?: number; error?: string; item: any }>;
|
results: Array<{ idx: number; ok: boolean; id?: number; error?: string; item: any }>;
|
||||||
}>('/users/batch', { items }).then(r => r.data),
|
}>('/users/batch', { items }).then(r => r.data),
|
||||||
batchRemove: (ids: number[]) =>
|
batchRemove: (ids: number[]) =>
|
||||||
api.request<{ ok: boolean; deleted: number; total: number }>({
|
api.post<{ ok: boolean; deleted: number; total: number }>('/users/batch-remove', { ids }).then(r => r.data),
|
||||||
url: '/users/batch',
|
|
||||||
method: 'DELETE',
|
|
||||||
data: { ids },
|
|
||||||
}).then(r => r.data),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const activitiesApi = {
|
export const activitiesApi = {
|
||||||
|
|||||||
@@ -165,11 +165,15 @@ export default function Users() {
|
|||||||
if (!confirm(`确认删除选中的 ${selectedCount} 名部员?相关的时长登记也会一并删除,此操作不可撤销。`)) return;
|
if (!confirm(`确认删除选中的 ${selectedCount} 名部员?相关的时长登记也会一并删除,此操作不可撤销。`)) return;
|
||||||
try {
|
try {
|
||||||
const result = await usersApi.batchRemove(Array.from(selectedIds));
|
const result = await usersApi.batchRemove(Array.from(selectedIds));
|
||||||
alert(`批量删除完成:共提交 ${result.total} 条,实际删除 ${result.deleted} 条`);
|
if (!result || result.ok === false) {
|
||||||
|
alert('批量删除失败:' + ((result as any)?.error || '未知错误'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
alert(`批量删除完成:共提交 ${result.total ?? 0} 条,实际删除 ${result.deleted ?? 0} 条`);
|
||||||
clearSelection();
|
clearSelection();
|
||||||
load();
|
load();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
alert(errMsg(e));
|
alert('批量删除失败:' + errMsg(e));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -237,9 +237,13 @@ router.post('/batch', authMiddleware, (req: AuthRequest, res: Response) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
router.delete('/batch', authMiddleware, (req: AuthRequest, res: Response) => {
|
router.delete('/batch', authMiddleware, (req: AuthRequest, res: Response) => {
|
||||||
const { ids } = req.body || {};
|
const ids = Array.isArray((req.body || {}).ids)
|
||||||
|
? (req.body as any).ids
|
||||||
|
: Array.isArray((req.query || {}).ids)
|
||||||
|
? [].concat((req.query as any).ids as any)
|
||||||
|
: null;
|
||||||
if (!Array.isArray(ids) || ids.length === 0) {
|
if (!Array.isArray(ids) || ids.length === 0) {
|
||||||
return res.status(400).json({ error: '请选择要删除的部员' });
|
return res.status(400).json({ ok: false, error: '请选择要删除的部员' });
|
||||||
}
|
}
|
||||||
const db = getDb();
|
const db = getDb();
|
||||||
const list: number[] = [];
|
const list: number[] = [];
|
||||||
@@ -248,7 +252,7 @@ router.delete('/batch', authMiddleware, (req: AuthRequest, res: Response) => {
|
|||||||
if (!isNaN(n) && n > 0 && !list.includes(n)) list.push(n);
|
if (!isNaN(n) && n > 0 && !list.includes(n)) list.push(n);
|
||||||
}
|
}
|
||||||
if (list.length === 0) {
|
if (list.length === 0) {
|
||||||
return res.status(400).json({ error: '请选择有效的部员' });
|
return res.status(400).json({ ok: false, error: '请选择有效的部员' });
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
db.execCompat('BEGIN');
|
db.execCompat('BEGIN');
|
||||||
@@ -263,7 +267,38 @@ router.delete('/batch', authMiddleware, (req: AuthRequest, res: Response) => {
|
|||||||
res.json({ ok: true, deleted: count, total: list.length });
|
res.json({ ok: true, deleted: count, total: list.length });
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
try { db.execCompat('ROLLBACK'); } catch {}
|
try { db.execCompat('ROLLBACK'); } catch {}
|
||||||
res.status(500).json({ error: e?.message || '批量删除失败' });
|
res.status(500).json({ ok: false, error: e?.message || '批量删除失败' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
router.post('/batch-remove', authMiddleware, (req: AuthRequest, res: Response) => {
|
||||||
|
const { ids } = req.body || {};
|
||||||
|
if (!Array.isArray(ids) || ids.length === 0) {
|
||||||
|
return res.status(400).json({ ok: false, error: '请选择要删除的部员' });
|
||||||
|
}
|
||||||
|
const db = getDb();
|
||||||
|
const list: number[] = [];
|
||||||
|
for (const id of ids) {
|
||||||
|
const n = Number(id);
|
||||||
|
if (!isNaN(n) && n > 0 && !list.includes(n)) list.push(n);
|
||||||
|
}
|
||||||
|
if (list.length === 0) {
|
||||||
|
return res.status(400).json({ ok: false, error: '请选择有效的部员' });
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
db.execCompat('BEGIN');
|
||||||
|
const del = db.prepareCompat('DELETE FROM users WHERE id = ?');
|
||||||
|
let count = 0;
|
||||||
|
for (const id of list) {
|
||||||
|
const r = del.run(id);
|
||||||
|
count += (r?.changes ?? 0);
|
||||||
|
}
|
||||||
|
db.execCompat('COMMIT');
|
||||||
|
db.save();
|
||||||
|
res.json({ ok: true, deleted: count, total: list.length });
|
||||||
|
} catch (e: any) {
|
||||||
|
try { db.execCompat('ROLLBACK'); } catch {}
|
||||||
|
res.status(500).json({ ok: false, error: e?.message || '批量删除失败' });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user