- 续审 Agent 声明(AgentSpec) + 结构化输出契约(ContinuityReview/Conflict 五类) - LangGraph 并行审子图(可扩四审) + collect 落 chapter_reviews 留痕 + review SSE(section/conflict) - 验收-side Repository:章节 accepted 版本晋升 + digest append-only + 审稿留痕/裁决 - API:review(SSE) + reviews 历史 + accept(单原子事务:晋升 version + 终稿 digest + 裁决留痕) - 冲突 gate:未决裁决拦截(CONFLICT_UNRESOLVED);digest 从终稿提炼(不变量#4) - 前端:审稿报告页 + 冲突就地标注 + 裁决(采纳/忽略/手改) + 未决禁验收 + 「本次将更新」清单 - M2 E2E:真实 DB + 多档位 mock 网关零 token 走通 写→审→裁决→验收→摘要入库 - 多 agent 协同台账(PROGRESS.md) + 共享记忆(memory/contracts·decisions·gotchas)
55 lines
1.9 KiB
TypeScript
55 lines
1.9 KiB
TypeScript
"use client";
|
||
|
||
import type { ReviewConflict } from "@/lib/review/sse";
|
||
|
||
interface AnnotatedTextProps {
|
||
text: string;
|
||
conflicts: ReviewConflict[];
|
||
// 当前聚焦的冲突下标(来自报告卡「跳转」),用于锚点联动。
|
||
focusedIndex: number | null;
|
||
onAnchorClick: (index: number) => void;
|
||
}
|
||
|
||
// 正文就地标注(UX §8.3 / §6.1)。
|
||
// M2 占位(R6):`where` 是文字定位(如「第4段」),M2 不做精确字符 range —
|
||
// 改为段级/锚点联动:每个冲突渲染为一枚朱砂波浪线锚点挂在正文上方,点击=回跳报告卡。
|
||
// 精确 inline range 标注留 M3+(需后端给字符 offset)。
|
||
export function AnnotatedText({
|
||
text,
|
||
conflicts,
|
||
focusedIndex,
|
||
onAnchorClick,
|
||
}: AnnotatedTextProps) {
|
||
return (
|
||
<div className="flex h-full flex-col">
|
||
{conflicts.length > 0 ? (
|
||
<div className="mb-3 flex flex-wrap gap-2 border-b border-line pb-3">
|
||
{conflicts.map((c, i) => (
|
||
<button
|
||
key={i}
|
||
type="button"
|
||
id={`anchor-${i}`}
|
||
onClick={() => onAnchorClick(i)}
|
||
aria-current={focusedIndex === i ? "true" : undefined}
|
||
className={`conflict-anchor rounded px-2 py-0.5 text-xs ${
|
||
focusedIndex === i
|
||
? "bg-cinnabar text-panel"
|
||
: "text-conflict hover:bg-[var(--color-conflict)]/10"
|
||
}`}
|
||
title={`${c.type}:${c.where || "正文"}`}
|
||
>
|
||
<span aria-hidden="true">⌇</span> {c.type}
|
||
{c.where ? ` · ${c.where}` : ""}
|
||
</button>
|
||
))}
|
||
</div>
|
||
) : null}
|
||
<article className="flex-1 overflow-auto whitespace-pre-wrap font-serif text-[17px] leading-[1.9] text-ink">
|
||
{text || (
|
||
<span className="text-ink-soft/60">(无待审正文,先去写作页起草本章)</span>
|
||
)}
|
||
</article>
|
||
</div>
|
||
);
|
||
}
|