diff --git a/frontend/src/app/contracts/[id]/page.tsx b/frontend/src/app/contracts/[id]/page.tsx index 982a22d2..3a845258 100644 --- a/frontend/src/app/contracts/[id]/page.tsx +++ b/frontend/src/app/contracts/[id]/page.tsx @@ -574,7 +574,7 @@ export default function GeneratedContractDetailPage({ params }: { params: Promis : ""; const auditTimelineItems = auditTimeline?.items ?? []; const auditActionSummaryItems = useMemo( - () => Object.entries(auditTimeline?.summary.by_action ?? {}) + () => Object.entries(auditTimeline?.summary?.by_action ?? {}) .sort(([, leftCount], [, rightCount]) => rightCount - leftCount) .slice(0, 6), [auditTimeline], @@ -597,8 +597,18 @@ export default function GeneratedContractDetailPage({ params }: { params: Promis const canCommentOnVersionDiff = !isObserverRole && Boolean(detail); const canSubmitApproval = Boolean(approvalSummary?.can_submit ?? (!pendingApproval && canEditCurrentContract)); const shouldShowApprovalResubmit = approvalNextAction?.code === "revise_and_resubmit"; - const shouldShowApprovalSubmitButton = canSubmitApproval || Boolean(pendingApproval); + const isApprovalRelevant = Boolean(pendingApproval || approvalHistory.length || shouldShowApprovalResubmit); + const shouldPromoteApprovalAction = Boolean( + pendingApproval + || shouldShowApprovalResubmit + || (canSubmitApproval && autoReview?.risk_level === "high") + ); + const shouldShowApprovalSubmitButton = shouldPromoteApprovalAction; const shouldShowApprovalWorkbenchAction = Boolean(pendingApproval || approvalHistory.length || shouldShowApprovalResubmit); + const visibleContractDetailAnchors = useMemo( + () => contractDetailAnchors.filter((item) => item.href !== "#contract-approval" || isApprovalRelevant || shouldShowApprovalSubmitButton), + [isApprovalRelevant, shouldShowApprovalSubmitButton], + ); const completedSignoffTask = useMemo( () => lifecycleTasks.find((task) => task.task_type === "signoff" && task.status === "completed") ?? lifecycleTasks.find((task) => task.task_type === "signoff") @@ -620,7 +630,7 @@ export default function GeneratedContractDetailPage({ params }: { params: Promis ? `${formatLifecycleStatus(detail.lifecycle?.status)} · ${formatDueStatus(detail.lifecycle)} · ${detail.lifecycle?.counterparty_name || "未记录相对方"}` : "暂无生命周期信息"; const signoffSummaryText = `签署证据 ${signoffArchiveSummary?.signoff_evidence_count ?? 0} · 归档证据 ${signoffArchiveSummary?.archive_evidence_count ?? 0}`; - const auditSummaryText = `留痕 ${auditTimeline?.summary.total ?? 0} 条${auditActionSummaryItems.length ? ` · ${auditActionSummaryItems.slice(0, 2).map(([action, count]) => `${formatAuditActionLabel(action)} ${count}`).join(" / ")}` : ""}`; + const auditSummaryText = `留痕 ${auditTimeline?.summary?.total ?? 0} 条${auditActionSummaryItems.length ? ` · ${auditActionSummaryItems.slice(0, 2).map(([action, count]) => `${formatAuditActionLabel(action)} ${count}`).join(" / ")}` : ""}`; const versionSummaryText = `版本 ${versionRows.length} 个 · 最新 ${latestVersionLabel} · 差异 ${versionDiff?.summary.change_count ?? 0} 处`; const lifecycleTaskSummaryText = `履约任务 ${lifecycleTasks.length} 个 · 待处理 ${openLifecycleTasks.length} 个`; const isSignedLifecycle = ["signed", "effective", "expiring", "expired", "terminated", "archived"].includes(detail?.lifecycle?.status ?? ""); @@ -666,7 +676,7 @@ export default function GeneratedContractDetailPage({ params }: { params: Promis ? "先按退回意见修改合同,再重新提交审批,避免审批人重复退回。" : pendingApproval ? "合同已进入审批流,可查看流转记录或进入审批工作台处理。" - : "先确认正文和真实预览,再进入编辑、提交审批或下载归档。"; + : "先确认正文和真实预览,再进入编辑或下载;需要审批时可从更多入口提交。"; const contractContentSection = (