fix(core): 修复新建项目脚本助手串台旧项目脚本(Playwright 实测发现)
后台 hydrate 期间进入刚建的项目,pipelineProject 会先闪出旧项目(projectDetail 滞后), 脚本助手 chat 用旧项目的 currentScript 初始化并持久化到新项目 key,导致空项目错显 「已有3镜脚本」、行30 三选项不出现。修: - 新建项目 onCreate 即时 setProjectDetail(created)+插入 projects,pipeline 不再闪旧项目 - PipelinePage 按 project.id key,切项目时 chat 等状态干净重挂 - chat auto 派生提示(「已有N镜」)不落 localStorage,杜绝跨项目串台 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -567,7 +567,13 @@ export function App() {
|
|||||||
onBack={() => navigate("projects")}
|
onBack={() => navigate("projects")}
|
||||||
onCreate={async (payload) => {
|
onCreate={async (payload) => {
|
||||||
const created = await action(() => api.createProject(payload), "项目已创建");
|
const created = await action(() => api.createProject(payload), "项目已创建");
|
||||||
if (created) navigate("pipeline", { projectId: created.id });
|
if (created) {
|
||||||
|
// 立刻把新项目落到 detail/列表,避免后台 hydrate 期间 pipeline 先闪出旧项目数据
|
||||||
|
// (旧项目的脚本会污染新项目的脚本助手 chat)
|
||||||
|
setProjectDetail(created);
|
||||||
|
setProjects((prev) => (prev.some((p) => p.id === created.id) ? prev : [created, ...prev]));
|
||||||
|
navigate("pipeline", { projectId: created.id });
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
onCreateProduct={(payload) => action(() => api.createProduct(payload), "")}
|
onCreateProduct={(payload) => action(() => api.createProduct(payload), "")}
|
||||||
/>
|
/>
|
||||||
@@ -657,6 +663,7 @@ export function App() {
|
|||||||
const textModel = modelConfigs.find((m) => m.capability === "text" && m.status === "active") || modelConfigs.find((m) => m.capability === "text");
|
const textModel = modelConfigs.find((m) => m.capability === "text" && m.status === "active") || modelConfigs.find((m) => m.capability === "text");
|
||||||
return (
|
return (
|
||||||
<PipelinePage
|
<PipelinePage
|
||||||
|
key={pipelineProject.id}
|
||||||
project={pipelineProject}
|
project={pipelineProject}
|
||||||
scriptModelName={textModel?.display_name || textModel?.name || "AI"}
|
scriptModelName={textModel?.display_name || textModel?.name || "AI"}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
|
|||||||
@@ -573,7 +573,7 @@ export function PipelinePage(props: {
|
|||||||
const chatBodyRef = useRef<HTMLDivElement | null>(null);
|
const chatBodyRef = useRef<HTMLDivElement | null>(null);
|
||||||
// 对话记录(本地会话态):生成动作可追溯,不再是「点了按钮、对话区永远空着」
|
// 对话记录(本地会话态):生成动作可追溯,不再是「点了按钮、对话区永远空着」
|
||||||
// kind=progress:进度提示流(行33),steps 逐条滚动出现,done 后折叠成一行结果
|
// kind=progress:进度提示流(行33),steps 逐条滚动出现,done 后折叠成一行结果
|
||||||
type ChatMsg = { id: number; role: "ai" | "user"; text: string; time: string; kind?: "progress"; steps?: string[]; done?: boolean };
|
type ChatMsg = { id: number; role: "ai" | "user"; text: string; time: string; kind?: "progress"; steps?: string[]; done?: boolean; auto?: boolean };
|
||||||
const nowHm = () => new Date().toTimeString().slice(0, 5);
|
const nowHm = () => new Date().toTimeString().slice(0, 5);
|
||||||
const msgIdRef = useRef(1);
|
const msgIdRef = useRef(1);
|
||||||
const nextMsgId = () => msgIdRef.current++;
|
const nextMsgId = () => msgIdRef.current++;
|
||||||
@@ -591,13 +591,14 @@ export function PipelinePage(props: {
|
|||||||
}
|
}
|
||||||
} catch { /* 解析失败则回退默认 */ }
|
} catch { /* 解析失败则回退默认 */ }
|
||||||
return currentScript
|
return currentScript
|
||||||
? [{ id: nextMsgId(), role: "ai", text: `当前已有 ${currentScript.segments?.length ?? 0} 镜脚本(${currentScript.is_adopted ? "已采用" : "待采用"})。直接输入修改意见可整体重写。`, time: nowHm() }]
|
? [{ id: nextMsgId(), role: "ai", auto: true, text: `当前已有 ${currentScript.segments?.length ?? 0} 镜脚本(${currentScript.is_adopted ? "已采用" : "待采用"})。直接输入修改意见可整体重写。`, time: nowHm() }]
|
||||||
: [];
|
: [];
|
||||||
});
|
});
|
||||||
// 落盘:丢掉未完成的 progress 流(那是临时态),只保留最近 60 条
|
// 落盘:auto 派生提示(「已有N镜」)不落盘——它跟当前脚本状态绑定,持久化会在切项目时串台;
|
||||||
|
// 未完成的 progress 流也不落盘(临时态);只保留最近 60 条真实对话
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
try {
|
try {
|
||||||
const slim = chatMsgs.filter((m) => m.kind !== "progress" || m.done).slice(-60);
|
const slim = chatMsgs.filter((m) => !m.auto && (m.kind !== "progress" || m.done)).slice(-60);
|
||||||
localStorage.setItem(chatKey, JSON.stringify(slim));
|
localStorage.setItem(chatKey, JSON.stringify(slim));
|
||||||
} catch { /* localStorage 不可用则忽略 */ }
|
} catch { /* localStorage 不可用则忽略 */ }
|
||||||
}, [chatKey, chatMsgs]);
|
}, [chatKey, chatMsgs]);
|
||||||
|
|||||||
Reference in New Issue
Block a user