fix(web): 审稿面板去重标题/去英文 slug + 伏笔待登记数实时递减 + 移动端决策栏 + 对比度修复
This commit is contained in:
@@ -6,6 +6,9 @@ import { useRouter } from "next/navigation";
|
||||
import {
|
||||
AlertTriangle,
|
||||
CheckCircle2,
|
||||
ChevronDown,
|
||||
ClipboardCheck,
|
||||
LocateFixed,
|
||||
RotateCcw,
|
||||
Square,
|
||||
} from "lucide-react";
|
||||
@@ -101,6 +104,11 @@ export function ReviewReport({
|
||||
const editorRef = useRef<HTMLTextAreaElement>(null);
|
||||
// 回炉中漂移段在终稿里定位到的原文(null=未打开 RefineView)。内容锚定位,非位置 idx。
|
||||
const [refineText, setRefineText] = useState<string | null>(null);
|
||||
// 伏笔「仍待处理」数:由 ForeshadowSuggestions 上抛(已登记/已回收的已扣除)。
|
||||
// null=尚未上报,回退到原始建议数,避免首帧闪「无建议」。
|
||||
const [foreshadowRemaining, setForeshadowRemaining] = useState<number | null>(
|
||||
null,
|
||||
);
|
||||
const seededRef = useRef(false);
|
||||
|
||||
// 进页一次性把历史留痕(冲突 + 伏笔建议 + 节奏)种入流状态(无需重审即可裁决/查看)。
|
||||
@@ -143,6 +151,8 @@ export function ReviewReport({
|
||||
const foreshadow = review.state.foreshadow;
|
||||
const pace = review.state.pace;
|
||||
const style = review.state.style;
|
||||
// 伏笔徽标/验收预览统一用「仍待处理数」(随登记/回收递减);未上报前回退原始建议数。
|
||||
const foreshadowOpen = foreshadowRemaining ?? foreshadow.length;
|
||||
const sectionStatus = (name: string): string | undefined =>
|
||||
review.state.sections.find((s) => s.name === name)?.status;
|
||||
|
||||
@@ -469,6 +479,8 @@ export function ReviewReport({
|
||||
conflicts={conflicts}
|
||||
focusedIndex={focusedIndex}
|
||||
onAnchorClick={focusRegion}
|
||||
projectId={project.id}
|
||||
chapterNo={chapterNo}
|
||||
editorRef={editorRef}
|
||||
/>
|
||||
</div>
|
||||
@@ -490,7 +502,6 @@ export function ReviewReport({
|
||||
<div className="space-y-3">
|
||||
<ReviewSectionPanel
|
||||
title="一致性"
|
||||
subtitle="continuity"
|
||||
statusLabel={
|
||||
reviewing
|
||||
? "审稿中"
|
||||
@@ -537,7 +548,7 @@ export function ReviewReport({
|
||||
<details
|
||||
key={group.type}
|
||||
open={unresolvedInGroup > 0}
|
||||
className="rounded border border-line/70 bg-bg/35 p-2"
|
||||
className="group rounded border border-line/70 bg-bg/35 p-2"
|
||||
>
|
||||
<summary className="flex cursor-pointer list-none items-center justify-between gap-2 text-xs font-semibold text-ink">
|
||||
<span className="flex items-center gap-2">
|
||||
@@ -550,10 +561,16 @@ export function ReviewReport({
|
||||
{group.items.length}
|
||||
</Badge>
|
||||
</span>
|
||||
<span className="font-mono text-[11px] text-ink-soft">
|
||||
{unresolvedInGroup > 0
|
||||
? `${unresolvedInGroup} 未裁决`
|
||||
: "已处理"}
|
||||
<span className="flex items-center gap-1.5">
|
||||
<span className="font-mono text-2xs text-ink-soft">
|
||||
{unresolvedInGroup > 0
|
||||
? `${unresolvedInGroup} 未裁决`
|
||||
: "已处理"}
|
||||
</span>
|
||||
<ChevronDown
|
||||
className="h-4 w-4 text-ink-soft transition-transform group-open:rotate-180"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</span>
|
||||
</summary>
|
||||
<ul className="mt-3 space-y-3">
|
||||
@@ -583,18 +600,17 @@ export function ReviewReport({
|
||||
|
||||
<ReviewSectionPanel
|
||||
title="伏笔"
|
||||
subtitle="foreshadow-analyst"
|
||||
statusLabel={
|
||||
sectionStatus("foreshadow") === "incomplete"
|
||||
? "未完成"
|
||||
: foreshadow.length > 0
|
||||
? `${foreshadow.length} 建议`
|
||||
: foreshadowOpen > 0
|
||||
? `${foreshadowOpen} 待登记`
|
||||
: "无建议"
|
||||
}
|
||||
statusVariant={
|
||||
sectionStatus("foreshadow") === "incomplete"
|
||||
? "warning"
|
||||
: foreshadow.length > 0
|
||||
: foreshadowOpen > 0
|
||||
? "accent"
|
||||
: "success"
|
||||
}
|
||||
@@ -605,11 +621,11 @@ export function ReviewReport({
|
||||
incomplete={sectionStatus("foreshadow") === "incomplete"}
|
||||
projectId={project.id}
|
||||
chapterNo={chapterNo}
|
||||
onRemainingChange={setForeshadowRemaining}
|
||||
/>
|
||||
</ReviewSectionPanel>
|
||||
<ReviewSectionPanel
|
||||
title="节奏"
|
||||
subtitle="pace-checker"
|
||||
statusLabel={
|
||||
sectionStatus("pace") === "incomplete"
|
||||
? "未完成"
|
||||
@@ -633,7 +649,6 @@ export function ReviewReport({
|
||||
</ReviewSectionPanel>
|
||||
<ReviewSectionPanel
|
||||
title="文风"
|
||||
subtitle="style"
|
||||
statusLabel={
|
||||
sectionStatus("style") === "incomplete"
|
||||
? "未完成"
|
||||
@@ -667,20 +682,52 @@ export function ReviewReport({
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
<section className="mt-4">
|
||||
<section id="accept-panel" className="mt-4 scroll-mt-4">
|
||||
<AcceptPanel
|
||||
projectId={project.id}
|
||||
chapterNo={chapterNo}
|
||||
reviewed={initialReview !== undefined || review.state.phase === "done"}
|
||||
conflictCount={conflictCount}
|
||||
unresolvedCount={resolved ? 0 : unresolved}
|
||||
foreshadowCount={foreshadow.length}
|
||||
foreshadowCount={foreshadowOpen}
|
||||
accepting={accept.status === "accepting"}
|
||||
result={accept.result}
|
||||
onAccept={() => void onAccept()}
|
||||
/>
|
||||
</section>
|
||||
</aside>
|
||||
|
||||
{/* 移动端(<lg 单列)快捷条:编辑器在上、审稿/验收在下,滚一整屏才够得着——
|
||||
固定底栏直接「跳到未裁决」或「去验收」,免去长滚。桌面端隐藏(右栏常驻可见)。 */}
|
||||
{hasReport && !accept.result ? (
|
||||
<div className="fixed inset-x-0 bottom-0 z-30 flex items-center gap-2 border-t border-line bg-panel/95 px-4 py-2 backdrop-blur supports-[backdrop-filter]:bg-panel/80 lg:hidden">
|
||||
<span className="flex-1 truncate text-xs text-ink-soft">
|
||||
{unresolved > 0 ? `${unresolved} 项冲突待裁决` : "可验收本章"}
|
||||
</span>
|
||||
{unresolved > 0 ? (
|
||||
<Button
|
||||
onClick={jumpToNextUnresolved}
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
>
|
||||
<LocateFixed className="h-4 w-4" aria-hidden="true" />
|
||||
跳到未裁决
|
||||
</Button>
|
||||
) : null}
|
||||
<Button
|
||||
onClick={() =>
|
||||
document
|
||||
.getElementById("accept-panel")
|
||||
?.scrollIntoView({ behavior: "smooth", block: "center" })
|
||||
}
|
||||
variant="primary"
|
||||
size="sm"
|
||||
>
|
||||
<ClipboardCheck className="h-4 w-4" aria-hidden="true" />
|
||||
去验收
|
||||
</Button>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
</AppShell>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user