+ {(() => {
+ // 实际开始日期
+ const vPlansAll = plans.filter((p) => p.versionId === version.id);
+ const vReqsAll = requirements.filter((r) => r.versionId === version.id);
+ const vReqIdsAll = new Set(vReqsAll.map((r) => r.id));
+ const vDTs = devTasks.filter((t) => vReqIdsAll.has(t.requirementId));
+ const vTCsAll = testCases.filter((c) => c.versionId === version.id);
+ const vBugsAll = bugs.filter((b) => b.versionId === version.id);
- const startDates: string[] = [];
- vPlansAll.forEach((p) => { if (p.actualStartAt) startDates.push(p.actualStartAt); });
- vDTs.forEach((t) => { if (t.startDate) startDates.push(t.startDate); });
- vTCsAll.forEach((c) => { if (c.startedAt) startDates.push(c.startedAt); });
- const actualStart = startDates.length > 0 ? startDates.sort()[0].slice(0, 10) : (version.startDate ?? null);
+ const startDates: string[] = [];
+ vPlansAll.forEach((p) => { if (p.actualStartAt) startDates.push(p.actualStartAt); });
+ vDTs.forEach((t) => { if (t.startDate) startDates.push(t.startDate); });
+ vTCsAll.forEach((c) => { if (c.startedAt) startDates.push(c.startedAt); });
+ const actualStart = startDates.length > 0 ? startDates.sort()[0].slice(0, 10) : (version.startDate ?? null);
- // 实际截止日期
- const endDates: string[] = [];
- vPlansAll.forEach((p) => { if (p.completedAt) endDates.push(p.completedAt); });
- vDTs.forEach((t) => { if (t.completedAt) endDates.push(t.completedAt); });
- vTCsAll.forEach((c) => { if (c.completedAt) endDates.push(c.completedAt); });
- vBugsAll.forEach((b) => { if (b.closedAt) endDates.push(b.closedAt); });
- const actualEnd = endDates.length > 0 ? endDates.sort().reverse()[0].slice(0, 10) : null;
+ // 实际截止日期
+ const endDates: string[] = [];
+ vPlansAll.forEach((p) => { if (p.completedAt) endDates.push(p.completedAt); });
+ vDTs.forEach((t) => { if (t.completedAt) endDates.push(t.completedAt); });
+ vTCsAll.forEach((c) => { if (c.completedAt) endDates.push(c.completedAt); });
+ vBugsAll.forEach((b) => { if (b.closedAt) endDates.push(b.closedAt); });
+ const actualEnd = endDates.length > 0 ? endDates.sort().reverse()[0].slice(0, 10) : null;
- // 逾期天数
- const deadline = version.expectedReleaseDate;
- let overdueDays = 0;
- if (deadline && actualEnd) {
- overdueDays = Math.floor((new Date(actualEnd).getTime() - new Date(deadline).getTime()) / (1000 * 60 * 60 * 24));
- }
+ // 逾期天数
+ const deadline = version.expectedReleaseDate;
+ let overdueDays = 0;
+ if (deadline && actualEnd) {
+ overdueDays = Math.floor((new Date(actualEnd).getTime() - new Date(deadline).getTime()) / (1000 * 60 * 60 * 24));
+ }
- return (
-
-
-
- 开始
- {actualStart ?? '未开始'}
-
-
- 预计截止
- {deadline ?? '未设置'}
-
- {actualEnd && (
-
- 实际截止
- {actualEnd}
-
- )}
- {overdueDays > 0 && (
-
逾期 {overdueDays} 天
- )}
-
-
- 已耗时 {elapsedDays} 天
-
+ return (
+
+
+
+ 开始
+ {actualStart ?? '未开始'}
- );
- })()}
-
+
+ 预计截止
+ {deadline ?? '未设置'}
+
+ {actualEnd && (
+
+ 实际截止
+ {actualEnd}
+
+ )}
+ {overdueDays > 0 && (
+
逾期 {overdueDays} 天
+ )}
+
+
+ 已耗时 {elapsedDays} 天
+
+