2026-05-20-14-53-31 逆向结果复核与用户管理修复

This commit is contained in:
2026-05-20 15:08:20 +08:00
parent 2a599695e9
commit fd7f3387f7
12 changed files with 886 additions and 111 deletions

View File

@@ -39,6 +39,7 @@ interface ModelPoseRecord {
interface SegmentationResultRecord {
id: string;
schemaVersion?: number;
name: string;
createdAt: string;
segmentationScope: SegmentationExportScope;
@@ -183,6 +184,16 @@ function publicUser(user: UserRecord) {
return rest;
}
function parseUserPayload(body: unknown, existing?: UserRecord) {
const source = body && typeof body === 'object' ? body as Record<string, unknown> : {};
const name = typeof source.name === 'string' ? source.name.trim() : existing?.name ?? '';
const account = typeof source.account === 'string' ? source.account.trim() : existing?.account ?? '';
const department = typeof source.department === 'string' ? source.department.trim() : existing?.department ?? '';
const password = typeof source.password === 'string' ? source.password : existing?.password ?? '';
return { name, account, department, password };
}
function publicSession(state: AppState) {
const user = state.session.account
? state.users.find((candidate) => candidate.account === state.session.account)
@@ -314,6 +325,7 @@ function normalizeSegmentationResults(
);
return existing
.filter((record) => record?.schemaVersion === 2)
.map((record, index): SegmentationResultRecord => {
const rawStyles = record?.moduleStyles && typeof record.moduleStyles === 'object' && !Array.isArray(record.moduleStyles)
? record.moduleStyles
@@ -324,6 +336,7 @@ function normalizeSegmentationResults(
id: typeof record?.id === 'string' && record.id.trim()
? record.id.trim().slice(0, 80)
: `segmentation-${index}`,
schemaVersion: 2,
name: '逆向分割结果',
createdAt: typeof record?.createdAt === 'string' && record.createdAt.trim() ? record.createdAt : now(),
segmentationScope: record?.segmentationScope === 'all' ? 'all' : 'visible',
@@ -2001,6 +2014,86 @@ async function startServer() {
res.json(readState().users.map(publicUser));
});
app.post('/api/users', (req, res) => {
const state = readState();
const payload = parseUserPayload(req.body);
if (!payload.name || !payload.account || !payload.department || !payload.password) {
res.status(400).json({ message: '姓名、账号、科室和密码不能为空' });
return;
}
if (state.users.some((user) => user.account === payload.account)) {
res.status(409).json({ message: '账号已存在' });
return;
}
const nextId = Math.max(0, ...state.users.map((user) => user.id)) + 1;
const user: UserRecord = {
id: nextId,
name: payload.name,
account: payload.account,
password: payload.password,
department: payload.department,
date: today(),
};
state.users.push(user);
writeState(state);
res.status(201).json(publicUser(user));
});
app.patch('/api/users/:userId', (req, res) => {
const state = readState();
const userId = Number.parseInt(req.params.userId, 10);
const user = state.users.find((candidate) => candidate.id === userId);
if (!user) {
res.status(404).json({ message: '用户不存在' });
return;
}
const payload = parseUserPayload(req.body, user);
if (!payload.name || !payload.account || !payload.department || !payload.password) {
res.status(400).json({ message: '姓名、账号、科室和密码不能为空' });
return;
}
if (state.users.some((candidate) => candidate.id !== user.id && candidate.account === payload.account)) {
res.status(409).json({ message: '账号已存在' });
return;
}
const previousAccount = user.account;
user.name = payload.name;
user.account = payload.account;
user.department = payload.department;
user.password = payload.password;
if (state.session.account === previousAccount) {
state.session = { authenticated: true, account: user.account, lastUpdated: now() };
}
writeState(state);
res.json(publicUser(user));
});
app.delete('/api/users/:userId', (req, res) => {
const state = readState();
const userId = Number.parseInt(req.params.userId, 10);
const index = state.users.findIndex((candidate) => candidate.id === userId);
if (index === -1) {
res.status(404).json({ message: '用户不存在' });
return;
}
const user = state.users[index];
if (state.session.account === user.account) {
res.status(400).json({ message: '不能删除当前登录用户' });
return;
}
if (state.users.length <= 1) {
res.status(400).json({ message: '至少保留一个用户' });
return;
}
state.users.splice(index, 1);
writeState(state);
res.json({ ok: true, deletedId: user.id });
});
app.get('/api/projects', (_req, res) => {
res.json(readState().projects);
});
@@ -2118,6 +2211,7 @@ async function startServer() {
: project.moduleStyles;
const record: SegmentationResultRecord = {
id: `segmentation-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 7)}`,
schemaVersion: 2,
name: rawName || '逆向分割结果',
createdAt: now(),
segmentationScope: parseSegmentationScope(req.body?.segmentationScope),