export type FirstPassReviewStatus = 'approved' | 'revision_required' | 'pending_review' | 'unknown' export type FirstPassReviewStatusCount = { status: string count: number } export type FirstPassReviewSummary = { totalUploads: number totalApproved: number firstPassApproved: number rate: number | null statusBreakdown: { approved: number revisionRequired: number pendingReview: number unknown: number } readAt: string /** 作品过稿后台的增量检查状态;统计本身仍直接读取该后台。 */ syncStatus?: 'idle' | 'syncing' | 'ready' | 'error' lastSyncedAt?: string | null syncRowsChecked?: number } export function normalizeFirstPassReviewStatus(status: string): FirstPassReviewStatus { if (status === 'approved' || status === 'revision_required' || status === 'pending_review') { return status } return 'unknown' } /** * 首轮通过率 = V1 审核通过作品数 / 当前已通过作品数。 * * totalUploads 和状态拆分用于展示全部 V1 明细,不参与比率分母。 */ export function buildFirstPassReviewSummary( rows: FirstPassReviewStatusCount[], totalApproved: number, readAt = new Date(), ): FirstPassReviewSummary { const statusBreakdown = { approved: 0, revisionRequired: 0, pendingReview: 0, unknown: 0, } for (const row of rows) { const count = Math.max(0, Number(row.count) || 0) const normalizedStatus = normalizeFirstPassReviewStatus(row.status) if (normalizedStatus === 'approved') statusBreakdown.approved += count else if (normalizedStatus === 'revision_required') statusBreakdown.revisionRequired += count else if (normalizedStatus === 'pending_review') statusBreakdown.pendingReview += count else statusBreakdown.unknown += count } const totalUploads = Object.values(statusBreakdown).reduce((total, count) => total + count, 0) const approvedDenominator = Math.max(0, Number(totalApproved) || 0) const firstPassApproved = statusBreakdown.approved return { totalUploads, totalApproved: approvedDenominator, firstPassApproved, rate: approvedDenominator === 0 ? null : Math.round((firstPassApproved / approvedDenominator) * 1000) / 10, statusBreakdown, readAt: readAt.toISOString(), } }