]> acesimba.cloud Git - StationBuilder.git/commitdiff
设备模板编辑页-区分来源显示返回设备模板列表或返回站点编辑
authorroot <root@localhost.localdomain>
Mon, 14 Sep 2026 03:42:16 +0000 (11:42 +0800)
committerroot <root@localhost.localdomain>
Mon, 14 Sep 2026 03:42:16 +0000 (11:42 +0800)
app/page.tsx

index e9b08ed0f0c6ee88eaac5cec605b0c42a3278bcb..036e122d86026b3d25ed06ea258331928f50db34 100644 (file)
@@ -690,7 +690,7 @@ export default function Home(){
         ? <DomainDetail id={openDomainTemplateId==="create"?null:openDomainTemplateId} go={go} notify={notify} onBack={()=>setOpenDomainTemplateId(null)} onCreated={setOpenDomainTemplateId} viewCompletePrompt={viewDtCompletePrompt} viewCompleteAssetsPrompt={viewDtCompleteAssetsPrompt} viewCompleteCubesPrompt={viewDtCompleteCubesPrompt} pageStyles={pageStyles}/>
         : <CompanyDomainLibrary go={go} notify={notify} onOpen={(id:number)=>setOpenDomainTemplateId(id)} domainFilter={domainFilter} domainOptions={domainOptions}/>)}
       {page==="styleLibrary"&&<CompanyPageStyleLibrary pageStyles={pageStyles} loadPageStyles={loadPageStyles} notify={notify}/>}
-      {page==="deviceTemplates"&&<CompanyDeviceTemplates notify={notify} onViewCpPrompt={viewDeviceCpCompletePrompt}/>}
+      {page==="deviceTemplates"&&<CompanyDeviceTemplates notify={notify} onViewCpPrompt={viewDeviceCpCompletePrompt} go={go} siteId={siteId}/>}
       {page==="toolSettings"&&<InternalToolSettings model={model} onModelChange={setModel} notify={notify}/>}
       {page==="domainSettings"&&<DomainSettings domains={domainOptions} notify={notify} onDeleted={handleDomainDeleted}/>}
       {(page==="basic"||(page==="siteEdit"&&siteEditSection==="basic"))&&<Basic site={site} domains={domains} onChange={saveSiteBasic} onAddDomain={addDomain} onUpload={uploadFile} saving={saving} notify={notify} onViewCompletePrompt={viewCompletePrompt} go={go} siteId={siteId} siteHierarchy={siteHierarchy}/>}
@@ -2648,7 +2648,7 @@ function CompanyDomainLibrary({go,notify,onOpen,domainFilter,domainOptions}:{go:
   </>;
 }
 
-function CompanyDeviceTemplates({notify,onViewCpPrompt}:{notify:(m:string)=>void;onViewCpPrompt:(id:number)=>void}){
+function CompanyDeviceTemplates({notify,onViewCpPrompt,go,siteId}:{notify:(m:string)=>void;onViewCpPrompt:(id:number)=>void;go:(p:PageKey,sid?:number|"new")=>void;siteId:number}){
   const [list,setList]=useState<any[]>([]);
   const [loading,setLoading]=useState(true);
   const [openId,setOpenId]=useState<number|"create"|null>(null);
@@ -2657,22 +2657,23 @@ function CompanyDeviceTemplates({notify,onViewCpPrompt}:{notify:(m:string)=>void
   const [pointFilter,setPointFilter]=useState<""|"configured"|"empty">("");
   const [pageIndex,setPageIndex]=useState(1);
   const [pageSize,setPageSize]=useState(10);
+  const [fromSite,setFromSite]=useState(false);
   const {confirm,el:confirmEl}=useConfirm();
   const load=async()=>{ try{ setList(await fetchDb("/device-templates") as any[]); }catch(e:any){ notify("加载失败:"+e.message); }finally{ setLoading(false); } };
   useEffect(()=>{ load(); },[]);
   // 支持从外部通过 URL 参数 openTemplate 自动打开指定模板编辑页
-  useEffect(()=>{ const p=new URLSearchParams(window.location.search); const tid=p.get("openTemplate"); if(tid){ setOpenId(Number(tid)); window.history.replaceState({}, "", "?page=deviceTemplates"); } },[]);
+  useEffect(()=>{ const p=new URLSearchParams(window.location.search); const tid=p.get("openTemplate"); if(tid){ setFromSite(true); setOpenId(Number(tid)); window.history.replaceState({}, "", "?page=deviceTemplates"); } },[]);
   const pointCount=(row:any)=>(row.collection_points||[]).length;
   const domainNames=(row:any)=>{ try{ return JSON.parse(row.domain_names||"[]") as string[]; }catch{ return []; } };
   const remove=async(row:any)=>{ if(!(await confirm(`确定删除设备模板「${row.name}」?`))) return; try{ await fetchDb(`/device-templates/${row.id}`,{method:"DELETE"}); setPreview(null); await load(); notify("设备模板已删除"); }catch(e:any){ notify("删除失败:"+e.message); } };
   const counts=useMemo(()=>({all:list.length,configured:list.filter(x=>pointCount(x)>0).length,empty:list.filter(x=>pointCount(x)===0).length}),[list]);
   const filtered=useMemo(()=>list.filter(row=>(!pointFilter||(pointFilter==="configured"?pointCount(row)>0:pointCount(row)===0))&&(!query.trim()||`${row.name} ${row.description||""}`.toLowerCase().includes(query.trim().toLowerCase()))),[list,pointFilter,query]);
   useEffect(()=>setPageIndex(1),[pointFilter,query]);
-  if(openId==="create") return <><div className="resource-back"><button className="text-button" onClick={()=>setOpenId(null)}>← 返回设备模板</button></div><DeviceTemplateCreate notify={notify} onDone={async(id:number)=>{await load();setOpenId(id);}} onCancel={()=>setOpenId(null)}/></>;
+  if(openId==="create") return <><div className="resource-back"><button className="text-button" onClick={()=>{setOpenId(null);if(fromSite)go("siteEdit",siteId);}}>{fromSite?"← 返回站点编辑":"← 返回设备模板列表"}</button></div><DeviceTemplateCreate notify={notify} onDone={async(id:number)=>{await load();setOpenId(id);}} onCancel={()=>setOpenId(null)}/></>;
   if(typeof openId==="number"){
     const dev=list.find(d=>d.id===openId);
     if(!dev) return <div className="empty-state">加载中…</div>;
-    return <><div className="resource-back"><button className="text-button" onClick={()=>setOpenId(null)}>← 返回设备模板</button></div><DeviceTemplateCard dev={dev} notify={notify} onChange={load} onBack={()=>setOpenId(null)} onViewCpPrompt={onViewCpPrompt}/></>;
+    return <><div className="resource-back"><button className="text-button" onClick={()=>{setOpenId(null);if(fromSite)go("siteEdit",siteId);}}>{fromSite?"← 返回站点编辑":"← 返回设备模板列表"}</button></div><DeviceTemplateCard dev={dev} notify={notify} onChange={load} onBack={()=>setOpenId(null)} onViewCpPrompt={onViewCpPrompt}/></>;
   }
   return <>{confirmEl}
     <div className="company-status-tabs" role="tablist" aria-label="设备模板状态筛选">{[