feat(collections): 自动同步作品交付集验收状态
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
import { Router, type Response, type NextFunction } from 'express';
|
||||
import { upload } from '../upload.js';
|
||||
import { notesService } from '../services/notesService.js';
|
||||
import { recalculateCollectionStatus } from '../services/collectionsService.js';
|
||||
import { audit, canWriteProject, requireRole, requireWriter, type AuthRequest } from '../auth.js';
|
||||
import { database, withTransaction } from '../database.js';
|
||||
import fs from 'fs';
|
||||
@@ -181,8 +182,9 @@ router.patch('/:noteId/status', requireWriter, async (req: AuthRequest, res: Res
|
||||
res.status(400).json({ error: '无效的验收状态' });
|
||||
return;
|
||||
}
|
||||
const context = await database.one<{ project_id: number }>('SELECT c.project_id FROM notes n JOIN collections c ON c.id = n.collection_id WHERE n.id = ?', [id]);
|
||||
const context = await database.one<{ project_id: number; review_status: string }>('SELECT c.project_id, n.review_status FROM notes n JOIN collections c ON c.id = n.collection_id WHERE n.id = ?', [id]);
|
||||
if (context && !await canWriteProject(req, context.project_id)) { res.status(403).json({ error: '无权操作该作品' }); return; }
|
||||
if (context?.review_status === 'approved') { res.status(409).json({ error: '已通过作品只能由组管理员填写原因后重新打开' }); return; }
|
||||
if (!await notesService.setStatus(id, status)) {
|
||||
res.status(404).json({ error: '作品不存在' });
|
||||
return;
|
||||
@@ -194,7 +196,7 @@ router.post('/:noteId/reopen', requireRole('platform_admin', 'group_admin'), asy
|
||||
const id = Number(req.params.noteId);
|
||||
const reason = String(req.body?.reason ?? '').trim();
|
||||
if (!reason) { res.status(400).json({ error: '重新打开验收时必须填写原因' }); return; }
|
||||
const note = await database.one<{ review_status: string; version_number: number; project_id: number }>('SELECT n.review_status, n.version_number, c.project_id FROM notes n JOIN collections c ON c.id = n.collection_id WHERE n.id = ?', [id]);
|
||||
const note = await database.one<{ review_status: string; version_number: number; project_id: number; collection_id: number }>('SELECT n.review_status, n.version_number, n.collection_id, c.project_id FROM notes n JOIN collections c ON c.id = n.collection_id WHERE n.id = ?', [id]);
|
||||
if (!note) { res.status(404).json({ error: '作品不存在' }); return; }
|
||||
if (!await canWriteProject(req, note.project_id)) { res.status(403).json({ error: '无权操作该作品' }); return; }
|
||||
if (note.review_status !== 'approved') { res.status(409).json({ error: '只有已通过作品可以重新打开' }); return; }
|
||||
@@ -203,6 +205,7 @@ router.post('/:noteId/reopen', requireRole('platform_admin', 'group_admin'), asy
|
||||
await tx.execute("UPDATE notes SET review_status = 'pending' WHERE id = ?", [id]);
|
||||
await tx.execute("UPDATE work_versions SET review_status = 'pending' WHERE note_id = ? AND version_number = ?", [id, note.version_number]);
|
||||
await tx.execute("INSERT INTO review_events (note_id, version_number, event_type, from_status, to_status, reason, actor_name, actor_role) VALUES (?, ?, 'reopened', 'approved', 'pending', ?, ?, ?)", [id, note.version_number, reason, actor.display_name, actor.role]);
|
||||
await recalculateCollectionStatus(Number(note.collection_id), tx);
|
||||
});
|
||||
await audit(req, 'work.reopen', 'work', id, { reason, versionNumber: note.version_number });
|
||||
res.json({ success: true, status: 'pending' });
|
||||
|
||||
Reference in New Issue
Block a user