feat(review): 重构项目级单方案验收协作

This commit is contained in:
yuzhe
2026-07-22 16:41:03 +08:00
parent 6091d61612
commit e7e268d4eb
45 changed files with 1830 additions and 812 deletions

View File

@@ -5,22 +5,29 @@ import type { Project, WorkCollection } from '../../shared/types.js';
const router = Router();
const reader = requireWriter;
type ProjectRow = Project & { customer_access_enabled: boolean | number; has_access_password: boolean | number; collection_count: number | string; work_count: number | string };
type ProjectRow = Project & { customer_access_enabled: boolean | number; has_access_password: boolean | number; collection_count: number | string; work_count: number | string; pending_count: number | string; changes_requested_count: number | string; approved_count: number | string };
type CollectionRow = WorkCollection & { work_count: number | string; approved_count: number | string };
function projectSelect(where: string) {
return `SELECT p.id, p.group_id, g.name AS group_name, p.name, p.slug, p.client_description, p.status, p.created_at,
return `SELECT p.id, p.group_id, g.name AS group_name, p.name, p.slug, p.client_description, p.status, p.review_status, p.review_completed_at, p.created_at,
p.customer_access_enabled, p.access_expires_at,
CASE WHEN p.access_password_hash != '' THEN 1 ELSE 0 END AS has_access_password,
COALESCE(cc.collection_count, 0) AS collection_count,
COALESCE(wc.work_count, 0) AS work_count
COALESCE(wc.work_count, 0) AS work_count,
COALESCE(wc.pending_count, 0) AS pending_count,
COALESCE(wc.changes_requested_count, 0) AS changes_requested_count,
COALESCE(wc.approved_count, 0) AS approved_count
FROM projects p
JOIN operation_groups g ON g.id = p.group_id
LEFT JOIN (SELECT project_id, COUNT(*) AS collection_count FROM collections GROUP BY project_id) cc ON cc.project_id = p.id
LEFT JOIN (SELECT c.project_id, COUNT(n.id) AS work_count FROM collections c LEFT JOIN notes n ON n.collection_id = c.id GROUP BY c.project_id) wc ON wc.project_id = p.id
LEFT JOIN (SELECT project_id, COUNT(*) AS work_count,
SUM(CASE WHEN review_status = 'pending' THEN 1 ELSE 0 END) AS pending_count,
SUM(CASE WHEN review_status = 'changes_requested' THEN 1 ELSE 0 END) AS changes_requested_count,
SUM(CASE WHEN review_status = 'approved' THEN 1 ELSE 0 END) AS approved_count
FROM notes GROUP BY project_id) wc ON wc.project_id = p.id
${where}`;
}
function projectJson(row: ProjectRow) { return { ...row, id: Number(row.id), group_id: Number(row.group_id), customer_access_enabled: Boolean(row.customer_access_enabled), has_access_password: Boolean(row.has_access_password), collection_count: Number(row.collection_count), work_count: Number(row.work_count) }; }
function projectJson(row: ProjectRow) { return { ...row, id: Number(row.id), group_id: Number(row.group_id), customer_access_enabled: Boolean(row.customer_access_enabled), has_access_password: Boolean(row.has_access_password), collection_count: Number(row.collection_count), work_count: Number(row.work_count), pending_count: Number(row.pending_count), changes_requested_count: Number(row.changes_requested_count), approved_count: Number(row.approved_count) }; }
function collectionJson(row: CollectionRow) { return { ...row, id: Number(row.id), project_id: Number(row.project_id), work_count: Number(row.work_count), approved_count: Number(row.approved_count) }; }
router.get('/', reader, async (req: AuthRequest, res: Response) => {