fix: 调研/产品/UI 改为手动点击"开始"触发计时

去掉"到了计划日期自动变进行中"的逻辑,改为用户手动点击:
- pending 状态显示蓝色"开始"按钮
- 点击后记录 actualStartAt(精确时间戳)
- 进行中才显示"完成"按钮

跟开发/测试逻辑一致:状态由用户主动触发,时间戳准确。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Script Generator
2026-06-12 16:38:03 +08:00
parent 7af9206bec
commit feba142ee9

View File

@@ -1,7 +1,7 @@
'use client';
import { useState } from 'react';
import { Plus, Pencil, Trash2, X, Check, ExternalLink, FileUp, Link2 } from 'lucide-react';
import { Plus, Pencil, Trash2, X, Check, ExternalLink, FileUp, Link2, Play } from 'lucide-react';
import type { VersionPlan, PlanTask } from '@/lib/version-plan';
import { calcPlanDuration, formatDuration, calcTotalDuration, calcPlanProgress, calcLinkedReqProgress } from '@/lib/version-plan';
@@ -56,19 +56,11 @@ export function PlanTab({ plans, versionId, versionDeadline, currentUserName, pl
<div className="space-y-3">
{typePlans.map((plan) => {
const now = new Date().toISOString();
const nowDate = now.slice(0, 10);
// 自动进入进行中(到了计划开始日期)
const shouldAutoStart = plan.status === 'pending' && plan.startTime <= nowDate;
if (shouldAutoStart && !plan.actualStartAt) {
onUpdate(plan.id, { status: 'in_progress' });
}
const effectiveStatus = shouldAutoStart ? 'in_progress' : plan.status;
// 耗时用实际时间戳计算
const actualStart = plan.actualStartAt || (shouldAutoStart ? now : null);
const dur = effectiveStatus === 'completed' && plan.completedAt && actualStart
? calcPlanDuration(actualStart, plan.completedAt)
: effectiveStatus === 'in_progress' && actualStart
? calcPlanDuration(actualStart, now)
const dur = plan.status === 'completed' && plan.completedAt && plan.actualStartAt
? calcPlanDuration(plan.actualStartAt, plan.completedAt)
: plan.status === 'in_progress' && plan.actualStartAt
? calcPlanDuration(plan.actualStartAt, now)
: { days: 0, hours: 0 };
const durText = dur.days > 0 || dur.hours > 0 ? formatDuration(dur.days, dur.hours) : '-';
return (
@@ -77,8 +69,8 @@ export function PlanTab({ plans, versionId, versionDeadline, currentUserName, pl
<div className="flex-1">
<div className="flex items-center gap-2 mb-1.5">
<span className="text-[13px] font-medium text-[var(--ink)]">{plan.title}</span>
<span className={`inline-flex items-center rounded-md px-2 py-0.5 text-[10px] font-medium border ${STATUS_STYLE[effectiveStatus]}`}>
{STATUS_LABEL[effectiveStatus]}
<span className={`inline-flex items-center rounded-md px-2 py-0.5 text-[10px] font-medium border ${STATUS_STYLE[plan.status]}`}>
{STATUS_LABEL[plan.status]}
</span>
</div>
<div className="flex items-center gap-4 text-[12px] text-[var(--ink-soft)]">
@@ -164,7 +156,7 @@ export function PlanTab({ plans, versionId, versionDeadline, currentUserName, pl
) : null;
})}
</div>
{calcLinkedReqProgress(plan.linkedRequirementIds, plan.completedRequirementIds) === 100 && effectiveStatus !== 'completed' && (
{calcLinkedReqProgress(plan.linkedRequirementIds, plan.completedRequirementIds) === 100 && plan.status !== 'completed' && (
<div className="mt-2 rounded-lg bg-green-50 border border-green-200 px-3 py-2 flex items-center justify-between">
<span className="text-[12px] text-green-700"></span>
<button onClick={() => setCompletingPlan(plan)} className="text-[11px] font-medium text-green-700 hover:text-green-900 underline"></button>
@@ -174,11 +166,18 @@ export function PlanTab({ plans, versionId, versionDeadline, currentUserName, pl
)}
</div>
<div className="flex items-center gap-1 ml-3">
{effectiveStatus !== 'completed' && (
<>
{plan.status === 'pending' && (
<button onClick={() => onUpdate(plan.id, { status: 'in_progress' })} className="h-7 px-2 flex items-center gap-1 rounded-md text-[11px] font-medium text-blue-600 hover:bg-blue-50 border border-blue-200" title="开始">
<Play className="h-3 w-3" />
</button>
)}
{plan.status !== 'completed' && plan.status !== 'pending' && (
<button onClick={() => setCompletingPlan(plan)} className="h-7 w-7 flex items-center justify-center rounded-md text-green-600 hover:bg-green-50" title="标记完成">
<Check className="h-3.5 w-3.5" />
</button>
)}
{plan.status !== 'completed' && (
<>
<button onClick={() => setEditingPlan(plan)} className="h-7 w-7 flex items-center justify-center rounded-md text-[var(--ink-muted)] hover:bg-[var(--bg-subtle)]" title="编辑">
<Pencil className="h-3.5 w-3.5" />
</button>