diff --git a/client/src/pages/admin/Users.tsx b/client/src/pages/admin/Users.tsx index 0ed9a24..9b265e3 100644 --- a/client/src/pages/admin/Users.tsx +++ b/client/src/pages/admin/Users.tsx @@ -349,18 +349,29 @@ export default function Users() { volunteer_no: r.volunteer_no || null, group_ids: r.group_ids, })); + console.log('[DEBUG] batch payload items (first 3):', JSON.stringify(items.slice(0, 3), null, 2)); const result = await usersApi.batch(items); + console.log('[DEBUG] batch response:', result); setBatchErrors(''); - const msg = `批量添加完成:共 ${result.total} 条,成功 ${result.success} 条,失败 ${result.failed} 条`; + const totalActualWritten = result.results.filter(r => r.ok).reduce((sum: number, r: any) => sum + (r?.groups_written ?? 0), 0); + const totalExpectedWritten = result.results.filter(r => r.ok).reduce((sum: number, r: any) => sum + (r?.groups_expected ?? 0), 0); + const msg = `批量添加完成:共 ${result.total} 条,成功 ${result.success} 条,失败 ${result.failed} 条 +工作组写入:实际 ${totalActualWritten} 条,期望 ${totalExpectedWritten} 条`; if (result.failed === 0) { - alert(msg); + const mis = result.results.filter((r: any) => r.ok && (r?.groups_written ?? 0) !== (r?.groups_expected ?? 0)); + if (mis.length === 0) { + alert(msg); + } else { + const lines = mis.slice(0, 20).map((r: any) => `第${r.idx + 1}行 ${r.item.name}:期望 ${r.groups_expected} 组,实际写入 ${r.groups_written} 组(后端解析 group_ids_out=${JSON.stringify(r.group_ids_out ?? [])})`).join('\n'); + alert(`${msg}\n\n工作组未全部写入(前20):\n${lines}`); + } setBatchOpen(false); setBatchText(''); load(); } else { const failLines = result.results .filter((r) => !r.ok) - .map((r) => `第${r.idx + 1}行 [${r.item.class} ${r.item.name}]:${r.error}`) + .map((r: any) => `第${r.idx + 1}行 [${r.item.class} ${r.item.name}]:${r.error}(后端接收 group_ids_count=${r.group_ids_count ?? 'N/A'},内容=${JSON.stringify(r.group_ids_seen ?? null)})`) .join('\n'); alert(`${msg}\n\n失败明细:\n${failLines}`); load(); diff --git a/server/src/routes/users.ts b/server/src/routes/users.ts index 87c344f..14aa43b 100644 --- a/server/src/routes/users.ts +++ b/server/src/routes/users.ts @@ -214,17 +214,36 @@ router.post('/batch', authMiddleware, (req: AuthRequest, res: Response) => { try { const info = insertUser.run(cls, name, volunteer_no, firstGroup); const userId = Number(info.lastInsertRowid); + let ugCount = 0; if (groups.length > 0) { const insertUG = db.prepareCompat('INSERT OR IGNORE INTO user_groups (user_id, group_id) VALUES (?,?)'); - for (const gid of groups) insertUG.run(userId, gid); + for (const gid of groups) { + const ugInfo = insertUG.run(userId, gid); + if ((ugInfo?.changes ?? 0) > 0) ugCount++; + } } success++; - results.push({ idx: i, ok: true, id: userId, item: raw }); + results.push({ + idx: i, + ok: true, + id: userId, + item: raw, + groups_written: ugCount, + groups_expected: groups.length, + group_ids_out: groups.slice(), + } as any); } catch (e: any) { failed++; let err = e?.message || '添加失败'; if (String(err).includes('UNIQUE')) err = '该班级下已存在同名部员'; - results.push({ idx: i, ok: false, error: err, item: raw }); + results.push({ + idx: i, + ok: false, + error: err, + item: raw, + group_ids_seen: Array.isArray(raw.group_ids) ? raw.group_ids : null, + group_ids_count: Array.isArray(raw.group_ids) ? raw.group_ids.length : 0, + } as any); } } db.execCompat('COMMIT');