+ {/* 状态 + 标签 */}
+
+
+
+
+ {SUPPORT_TICKET_STATUS_LABELS[detail.status] ?? detail.status}
+
+ {detail.status === 'REJECTED' && (
+ 此工单已被驳回
+ )}
+ {detail.status === 'PASSED' && (
+ 此工单已测试通过
+ )}
+
+
+ 创建于 {fmtTime(detail.createdAt)}
+
+
+
+
+ {/* 状态流转时间线 */}
+
状态流转}
+ styles={{ body: { padding: '12px 16px' } }}
+ >
+ {
+ const isRejected = detail.status === 'REJECTED';
+ const flowSteps: Array<{ key: SupportTicketStatusDto; time?: string | null; label: string }> = [
+ { key: 'PENDING_REVIEW', label: '待评审', time: detail.createdAt },
+ ...(!isRejected
+ ? [
+ { key: 'DEVELOPING' as SupportTicketStatusDto, label: '开发中', time: detail.reviewedAt },
+ { key: 'TESTING' as SupportTicketStatusDto, label: '测试中', time: null },
+ { key: 'PASSED' as SupportTicketStatusDto, label: '已通过', time: detail.completedAt },
+ ]
+ : [{ key: 'REJECTED' as SupportTicketStatusDto, label: '已驳回', time: detail.reviewedAt }]),
+ ];
+
+ const statusIdx = flowSteps.findIndex((s) => s.key === detail.status);
+
+ return flowSteps.map((step, idx) => {
+ const isCurrent = step.key === detail.status;
+ const isPast = !isRejected
+ ? idx < statusIdx
+ : step.key === 'PENDING_REVIEW' && statusIdx >= 1;
+ const isRejectedStep = step.key === 'REJECTED';
+
+ let dot: React.ReactNode;
+ let color: string | undefined;
+ if (isRejectedStep) {
+ dot = ;
+ color = 'red';
+ } else if (isCurrent) {
+ if (step.key === 'TESTING') {
+ dot = ;
+ } else {
+ dot = ;
+ }
+ } else if (isPast) {
+ dot = ;
+ color = 'green';
+ }
+
+ return {
+ dot,
+ color,
+ children: (
+
+
+ {step.label}
+
+ {step.time && (
+
+ {fmtTime(step.time)}
+
+ )}
+
+ ),
+ };
+ });
+ })()}
+ />
+
+
+ {/* 标题 & 内容 */}
+
+
+ {detail.title}
+
+
+ {detail.content || (
+ 暂无详细说明
+ )}
+
+
+
+ {/* 基本信息 */}
+
基本信息}
+ styles={{ body: { padding: '12px 16px' } }}
+ >
+
+
+
创建人
+
{detail.creatorName}
+
+
+
创建时间
+
{fmtTime(detail.createdAt)}
+
+
+
评审人
+
{detail.reviewerName || '—'}
+
+
+
评审时间
+
{detail.reviewedAt ? fmtTime(detail.reviewedAt) : '—'}
+
+
+ {detail.rejectReason && (
+
+
+ 驳回理由
+
+
+ {detail.rejectReason}
+
+
+ )}
+ {detail.remark && (
+
+
+ 备注
+
+
+ {detail.remark}
+
+
+ )}
+
+
+ {/* 关联开发任务 */}
+ {detail.linkedTasks?.length ? (
+
+ 关联开发任务
+
+ {detail.linkedTasks.length}
+
+
+ }
+ styles={{ body: { padding: 0 } }}
+ >
+ {detail.linkedTasks.map((t, idx) => (
+
+
+ {t.taskNo}
+
+
+ {t.content}
+
+ {t.status}
+
+ ))}
+
+ ) : null}
+
)}