From: wang.yu Date: Mon, 17 Aug 2026 01:52:53 +0000 (+0800) Subject: feat: 支持针对 Cube 页面提出修改意见并重新生成(保留累积提示词) X-Git-Url: http://acesimba.cloud/gitweb/?a=commitdiff_plain;h=c4a25db1ef068398f750bf214d6f99816787d61b;p=StationBuilder.git feat: 支持针对 Cube 页面提出修改意见并重新生成(保留累积提示词) - 后端新增 POST /api/sites/:id/cubes/:cubeId/refine:基于当前已生成 JSON + 修改意见 重新生成,修改意见以「--- 修改意见(时间)---」形式累积写入 cubes.prompt; /prompt 端点改为返回已存储(含历史修改意见)的提示词 - 前端 Result 页每个已生成 Cube 增加「✎ 修改意见」按钮,弹窗提交后刷新站点数据, 缩略图(依赖 generated_at)与新标签页预览自动更新 - 强化 refine 对删除类意见的可靠性:提示词列出当前面板清单并明确删/移/增/改规则, 生成后校验删除是否真正生效,未生效则重试最多 3 次并指名待删面板 - 修复 Modal 漏传 feedbackCube/refineCube/refining 导致「提交并重新生成」无效的缺陷 --- diff --git a/app/page.tsx b/app/page.tsx index ad2878e..63cbcdf 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -166,6 +166,8 @@ export default function Home(){ const [view,setView]=useState<"table"|"card">("table"); const [functionTab,setFunctionTab]=useState<"mu"|"cube"|"menu">("mu"); const [previewTab,setPreviewTab]=useState<"info"|"json"|"feedback">("info"); + const [feedbackCube,setFeedbackCube]=useState(null); + const [refining,setRefining]=useState(false); const notify=(m:string)=>{setToast(m);window.setTimeout(()=>setToast(""),2200);}; @@ -190,6 +192,31 @@ export default function Home(){ }catch(e:any){ notify("读取提示词失败: "+e.message); } }; + const openFeedback=(cube:Cube)=>{ + if(!cube.id){ notify("请先生成该页面再提出修改意见"); return; } + setFeedbackCube(cube); + setModal("feedback"); + }; + const refineCube=async(cube:Cube, feedback:string)=>{ + if(!site?.id || !cube.id) return; + if(!feedback.trim()){ notify("请填写修改意见"); return; } + setRefining(true); + try{ + await fetchDb(`/sites/${site.id}/cubes/${cube.id}/refine`, { + method:"POST", + headers:{"Content-Type":"application/json"}, + body:JSON.stringify({feedback}), + }); + notify(`已根据修改意见重新生成「${cube.name}」`); + const refreshed:SiteDetail = await fetchDb(`/sites/${site.id}`); + setSite(refreshed); + setSiteId(site.id); + setModal(""); + setFeedbackCube(null); + }catch(e:any){ notify("重新生成失败:"+(e?.message||e)); } + finally{ setRefining(false); } + }; + useEffect(()=>{ if(aiEndRef.current) aiEndRef.current.scrollIntoView({block:"end"}); }, [aiMessages, aiOpen]); // load sites and domains @@ -359,10 +386,10 @@ export default function Home(){ {page==="assets"&&} {page==="functions"&&} {page==="generate"&&} - {page==="result"&&} + {page==="result"&&} {page==="preview"&&} {(["basic","assets","functions"] as PageKey[]).includes(page)&&
} - {toast&&
✓{toast}
}{modal&&setModal("")} notify={notify} promptData={promptData}/>} + {toast&&
✓{toast}
}{modal&&setModal("")} notify={notify} promptData={promptData} feedbackCube={feedbackCube} refineCube={refineCube} refining={refining}/>} {!aiOpen&&
{[[site.assets.filter(a=>a.type).length,"Asset 资产","类设备"],[site.mu.length,"MU 页面","已配置"],[generated.length,"Cube 页面",generated.length===site.cubes.length?"校验全部通过":"部分未生成"],[generated.length+1,"交付文件","JSON+ZIP"]].map(x=>
{x[1]}{x[0]}{x[2]}
)}
-
setModal("feedback")}>✎ 提出修改意见}>
{site.cubes.map((cube,i)=>
{cube.status==="generated"?"校验通过":"未生成"}Cube

{cube.name}

{cube.content || "无描述"}

{cube.id&&}{cube.id&&}
)}
; +
viewSitePrompt()}>查看站点提示词}>
{site.cubes.map((cube,i)=>
{cube.status==="generated"?"校验通过":"未生成"}Cube

{cube.name}

{cube.content || "无描述"}

{cube.id&&}{cube.id&&}{cube.status==="generated"&&}
)}
; } function Preview({site,tab,setTab,setModal,notify}:{site:SiteDetail|null;tab:"info"|"json"|"feedback";setTab:(t:"info"|"json"|"feedback")=>void;setModal:(m:ModalKey)=>void;notify:(m:string)=>void}){ @@ -727,4 +754,12 @@ function DomainDetail({go,notify}:{go:(p:PageKey)=>void;notify:(m:string)=>void}
{[["▤","自来水厂工艺说明.pdf","PDF · 3.2 MB"],["△","水质报警规则集","18 条规则"],["⚒","水泵维修规则","12 条规则"],["↻","设备保养规则","16 条规则"]].map(x=>
{x[0]}{x[1]}{x[2]}
)}
} -function Modal({type,close,notify,promptData}:{type:Exclude;close:()=>void;notify:(m:string)=>void;promptData?:{name:string;text:string}|null}){const title={feedback:"确认修改影响",download:"下载站点交付物",history:"版本历史",prompt:`生成提示词 · ${promptData?.name||""}`}[type];return
e.stopPropagation()}>

{title}

{type==="feedback"&&<>
系统已识别本次修改范围
  • 当前页面 JSON将重新生成
  • 页面模拟数据将同步更新
  • Asset Excel不受影响
  • 其他 Cube 页面不受影响