feat(版本详情): 优化任务统计与测试轮次

This commit is contained in:
Script Generator
2026-06-26 15:12:24 +08:00
parent 914e6180c1
commit 2d802318fa
16 changed files with 631 additions and 65 deletions

View File

@@ -12,9 +12,10 @@ import { BugDetailDrawer } from './BugDetailDrawer';
import { Pagination, usePagination } from '@/components/Pagination';
import { SearchInput, matchTitleOrNo } from '@/components/SearchInput';
import { useDebouncedValue } from '@/hooks/useDebouncedValue';
import { BUG_STATUS_LABEL, BUG_SEVERITY_LABEL, bugIntervals } from '@/lib/bug';
import { formatWorkHours, calcTwoMetrics } from '@/lib/work-hours';
import { BUG_STATUS_LABEL, BUG_SEVERITY_LABEL, aggregateBugActualHours, bugIntervals } from '@/lib/bug';
import { calcTwoMetrics } from '@/lib/work-hours';
import { isMemberReference, resolveMemberDisplayName } from '@/lib/member-system';
import { buildEffortSummaryMetrics, sumPositiveHours } from '@/lib/effort-summary';
import type { BugStatus, BugSeverity } from '@/lib/bug';
interface Props {
@@ -43,7 +44,17 @@ export function BugTab({ versionId, requirementIds }: Props) {
const closedCount = versionBugs.filter((b) => b.status === 'closed' || b.status === 'rejected').length;
const criticalCount = versionBugs.filter((b) => b.severity === 'critical' && b.status !== 'closed' && b.status !== 'rejected').length;
const resolveRate = versionBugs.length > 0 ? Math.round(((fixedCount + closedCount) / versionBugs.length) * 100) : 0;
const { calendarHours: bugCalendarHours, manhours: bugManhours } = useMemo(() => calcTwoMetrics(bugIntervals(versionBugs)), [versionBugs]);
const bugActualHours = useMemo(() => aggregateBugActualHours(versionBugs), [versionBugs]);
const { manhours: bugManhours } = useMemo(() => calcTwoMetrics(bugIntervals(versionBugs)), [versionBugs]);
const effortMetrics = useMemo(
() => buildEffortSummaryMetrics({
aiEstimateHours: sumPositiveHours(versionBugs, (bug) => bug.aiEstimateHours),
estimateHours: sumPositiveHours(versionBugs, (bug) => bug.estimateHours),
actualHours: bugActualHours,
manhours: bugManhours,
}),
[versionBugs, bugActualHours, bugManhours],
);
const [filterAssignee, setFilterAssignee] = useState('');
const [filterStatus, setFilterStatus] = useState('');
@@ -97,9 +108,11 @@ export function BugTab({ versionId, requirementIds }: Props) {
<span className="text-[11px] text-red-600 bg-red-50 px-1.5 py-0.5 rounded font-medium">{criticalCount} </span>
)}
<span className="text-[11px] text-[var(--ink-muted)]"> {resolveRate}%</span>
{bugManhours > 0 && (
<span className="text-[11px] text-[var(--ink-muted)]"> {formatWorkHours(bugCalendarHours)} / {formatWorkHours(bugManhours)}</span>
)}
{effortMetrics.map((metric) => (
<span key={metric.label} className="text-[11px] text-[var(--ink-muted)] shrink-0">
{metric.label} <span className="tabular-nums text-[var(--ink)]">{metric.value}</span>
</span>
))}
</div>
<div className="flex items-center gap-2 px-1 flex-wrap">