-
- {/* 风险详情(胶囊条上方) */}
+ {/* 1. 风险详情 - 最上方 */}
{riskTags.length > 0 && (
@@ -286,7 +247,25 @@ export default function VersionDetailPage() {
)}
- {/* Capsule stages */}
+ {/* 2. 统计卡片 */}
+ {(() => {
+ const vPlans = plans.filter((p) => p.versionId === version.id);
+ const pendingResearch = vPlans.filter((p) => p.type === 'research' && p.status !== 'completed').length;
+ const pendingProduct = vPlans.filter((p) => p.type === 'product' && p.status !== 'completed').length;
+ return (
+
+
+ 0} />
+ 0} />
+
+
+ 0} />
+
+
+ );
+ })()}
+
+ {/* 3. 状态胶囊 */}
{(() => {
const vPlans = plans.filter((p) => p.versionId === version.id);
const researchPlans = vPlans.filter((p) => p.type === 'research');
@@ -356,7 +335,67 @@ export default function VersionDetailPage() {
return
;
})()}
- {/* 双栏:加班排名 + 原因占比 */}
+ {/* 4. 项目总耗时 + 参与人员 + 相关链接 */}
+
+
+
+
+
+
+ {version.startDate ?? '未设置'}
+ —
+ {version.expectedReleaseDate ?? '未设置'}
+
+
+
+ 已耗时 {elapsedDays} 天
+
+
+
+
+
参与人员
+ {(() => {
+ const planMembers = plans
+ .filter((p) => p.versionId === version.id)
+ .map((p) => ({ role: p.type === 'research' ? 'research' as const : p.type === 'product' ? 'product' as const : 'ui' as const, name: p.owner }));
+ const roleLabel: Record
= { research: '调研', product: '产品', ui: 'UI' };
+ const seen = new Set();
+ const dedupPlanMembers = planMembers.filter((m) => {
+ const key = `${m.role}:${m.name}`;
+ if (seen.has(key)) return false;
+ seen.add(key);
+ return true;
+ });
+ const existingKeys = new Set((version.members ?? []).map((m) => `${m.role}:${m.name}`));
+ const extraMembers = dedupPlanMembers.filter((m) => !existingKeys.has(`${m.role}:${m.name}`));
+ const allMembers = [...(version.members ?? []), ...extraMembers];
+ if (allMembers.length === 0) return 暂无成员;
+ return (
+
+ {allMembers.map((m, i) => (
+
+ {roleLabel[m.role] ?? m.role}
+ {m.name}
+
+ ))}
+
+ );
+ })()}
+
+
+
+
+
相关链接
+
+ } label="调研报告" url={version.links?.research} />
+ } label="原型地址" url={version.links?.prototype} />
+ } label="UI设计稿" url={version.links?.ui} />
+
+
+
+
+
+ {/* 5. 加班时长排名 + 加班原因占比 */}
{/* 参与人员加班排名 */}
@@ -554,72 +593,11 @@ export default function VersionDetailPage() {
);
})()}
- {/* 双栏:日期信息 + 相关链接 */}
-
-
-
-
-
-
- {version.startDate ?? '未设置'}
- —
- {version.expectedReleaseDate ?? '未设置'}
-
-
-
- 已耗时 {elapsedDays} 天
-
-
-
-
-
参与人员
- {(() => {
- const planMembers = plans
- .filter((p) => p.versionId === version.id)
- .map((p) => ({ role: p.type === 'research' ? 'research' as const : p.type === 'product' ? 'product' as const : 'ui' as const, name: p.owner }));
- const roleLabel: Record
= { research: '调研', product: '产品', ui: 'UI' };
- // 按 role+name 去重(同阶段同一人只显示一次)
- const seen = new Set();
- const dedupPlanMembers = planMembers.filter((m) => {
- const key = `${m.role}:${m.name}`;
- if (seen.has(key)) return false;
- seen.add(key);
- return true;
- });
- const existingKeys = new Set((version.members ?? []).map((m) => `${m.role}:${m.name}`));
- const extraMembers = dedupPlanMembers.filter((m) => !existingKeys.has(`${m.role}:${m.name}`));
- const allMembers = [...(version.members ?? []), ...extraMembers];
- if (allMembers.length === 0) return 暂无成员;
- return (
-
- {allMembers.map((m, i) => (
-
- {roleLabel[m.role] ?? m.role}
- {m.name}
-
- ))}
-
- );
- })()}
-
-
-
-
-
相关链接
-
- } label="调研报告" url={version.links?.research} />
- } label="原型地址" url={version.links?.prototype} />
- } label="UI设计稿" url={version.links?.ui} />
-
-
-
-
-
- {/* 健康趋势(最底部) */}
-
+ {/* 健康趋势 - 暂时不显示 */}
+ {/*
健康趋势
-
+
*/}
);
})()