From 005b026a31cfe754505ba15e7d49e89a05797162 Mon Sep 17 00:00:00 2001 From: "wang.yu" Date: Tue, 18 Aug 2026 17:52:08 +0800 Subject: [PATCH] =?utf8?q?feat:=20=E9=A2=86=E5=9F=9F=E6=96=B9=E6=A1=88?= =?utf8?q?=E5=BA=93=E5=8D=87=E7=BA=A7=E4=B8=BA=E7=9C=9F=E5=AE=9E=E6=95=B0?= =?utf8?q?=E6=8D=AE=E5=BA=93=E9=A9=B1=E5=8A=A8=E7=9A=84=20CRUD?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit - Phase 0:移除领域方案库页 Search 行(含「同步方案库」占位按钮) - db-sidecar 新增 schema:domain_templates / device_templates + device_collection_points / device_template_domains / device_template_domain_templates(两处多对多)/ domain_pages / template_menu_items / knowledge_docs(doc_type 区分超链与文件,文件落盘 data/db/uploads/)/ ops_flows(仅占位) - 全套 CRUD 接口 /api/domain-templates(详情聚合设备·采集点·页面·菜单·文档·流程)、 /api/device-templates(图片 base64 上传)、/api/collection-points、/api/domain-pages、 /api/template-menu-items、/api/knowledge-docs(含 /file 下载)、/api/ops-flows - 前端 DomainLibrary + DomainDetail 内嵌编辑器(模板信息 / 设备与采集点 / 领域页面 Cube JSON / 模板菜单 / 知识文档 / 运维流程占位),openDomainTemplateId 控制 列表·新增·详情 切换 - 修复:sidecar 路由前缀由 /api/db 改为 /api(匹配代理层改写);设备 domain_ids 由 JSON 字符串 解析为数组;DomainDetail 修正 hooks 顺序 - 更新设计文档 5.9/5.10、尚未实现汇总、更新记录 - 提交变更 schema 的 DB 文件 --- app/page.tsx | 164 +++++++++++-- data/db/StationBuilder.sqlite | Bin 7483392 -> 8564736 bytes db-sidecar.mjs | 451 ++++++++++++++++++++++++++++++++++ public/design-doc.html | 38 +-- 4 files changed, 615 insertions(+), 38 deletions(-) diff --git a/app/page.tsx b/app/page.tsx index 1ac5497..c847939 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -170,6 +170,7 @@ export default function Home(){ const [domains,setDomains]=useState([]); const [muTree,setMuTree]=useState([]); const [pageStyles,setPageStyles]=useState([]); + const [openDomainTemplateId,setOpenDomainTemplateId]=useState(null); const [view,setView]=useState<"table"|"card">("table"); const [functionTab,setFunctionTab]=useState<"mu"|"cube"|"menu">("mu"); @@ -452,10 +453,11 @@ export default function Home(){ )} -
iStation StationBuilder / {["domains","domainDetail","styleLibrary"].includes(page)?meta[page].label:page==="projects"?"站点列表":`站点详情 / ${meta[page].label}`}

{meta[page].label}

{meta[page].subtitle}

{!["projects","domains","domainDetail","styleLibrary"].includes(page)&&}{page==="projects"&&}{page==="domains"&&}{page==="domainDetail"&&}
{(["basic","assets","functions","generate"] as PageKey[]).includes(page)&&}
+
iStation StationBuilder / {["domains","domainDetail","styleLibrary"].includes(page)?meta[page].label:page==="projects"?"站点列表":`站点详情 / ${meta[page].label}`}

{meta[page].label}

{meta[page].subtitle}

{!["projects","domains","domainDetail","styleLibrary"].includes(page)&&}{page==="projects"&&}{(page==="domains"||page==="domainDetail")&&}{(page==="domains"||page==="domainDetail")&&openDomainTemplateId!=null&&}
{(["basic","assets","functions","generate"] as PageKey[]).includes(page)&&}
{page==="projects"&&} - {page==="domains"&&} - {page==="domainDetail"&&} + {(page==="domains"||page==="domainDetail")&&(openDomainTemplateId!=null + ? setOpenDomainTemplateId(null)} onCreated={setOpenDomainTemplateId}/> + : setOpenDomainTemplateId(id)}/>)} {page==="styleLibrary"&&} {page==="basic"&&} {page==="assets"&&} @@ -976,28 +978,144 @@ function Preview({site,tab,setTab,setModal,notify}:{site:SiteDetail|null;tab:"in return
{cube?.status==="generated"?"校验通过":"未生成"}
⬡ iStation{site?.name || "未命名站点"}⌕ ♧ ? ▦ W
站点监控 / {cube?.name}

{site?.name || "未命名站点"}

最后更新:刚刚 ↻
{[["设备在线率","92%","23 / 25"],["今日总能耗","12,480","kWh"],["未处理告警","7","高危 2"],["平均负载率","68%","较昨日 +3%"]].map((x,i)=>
{x[0]}{x[1]}{x[2]}
)}

近 7 日能源消耗 本周⌄

{["08/08","08/09","08/10","08/11","08/12","08/13","今天"].map(x=>{x})}

设备状态分布

72%在线
} -function DomainLibrary({go,notify}:{go:(p:PageKey)=>void;notify:(m:string)=>void}){ - const domains=[ - {icon:"♨",name:"燃气",desc:"城市燃气门站、调压站及管网监控标准方案",assets:18,flows:6,pages:7,docs:12,color:"gas"}, - {icon:"≋",name:"水务 · 自来水厂",desc:"覆盖取水、制水、送水及水质保障的完整方案",assets:24,flows:8,pages:9,docs:16,color:"water"}, - {icon:"☀",name:"新能源",desc:"光伏、储能与充电设施的一体化运营方案",assets:15,flows:5,pages:8,docs:10,color:"energy"}, - {icon:"▥",name:"数据中心",desc:"供配电、制冷、能耗和基础设施健康度方案",assets:28,flows:9,pages:10,docs:18,color:"dc"}, - ]; - return <>
DOMAIN SOLUTION LIBRARY

从成熟领域方案开始,而不是从零开始

复用已验证的资产模板、运维流程、Cube 领域页面、菜单组合和领域知识,快速交付客户站点。

4重点领域
34领域页面
56知识文档
72%预计提速
-
{domains.map((d,i)=>
{d.icon}
{i===1?"已验证":"可使用"}V{[2.1,3.4,1.8,4.2][i]}

{d.name}

{d.desc}

{d.assets}资产模板{d.flows}运维流程{d.pages}领域页面{d.docs}知识文档
)}
-
{[["▧","资产属性","设备类型、采集点位、数据范围、单位、报警规则与资产组层级"],["↻","运维流程表单","保养模板与流程、维修模板与流程,后续扩展巡检"],["▣","领域页面","一组可直接使用或微调的 Cube 扩展页面及动态 Panel"],["☷","解决方案菜单","MU 标准页面、Cube 页面、菜单层级及默认参数组合"],["▤","领域知识","PDF 文档、报警规则、维修规则和保养规则"]].map(x=>
{x[0]}{x[1]}{x[2]}
)}
- {[["水务 · 自来水厂","新增水质分析与药剂消耗页面","V3.4","王宇","今天 10:42","已发布"],["数据中心","更新冷源群控资产组模板","V4.2","陈晨","昨天 16:20","已发布"],["新能源","新增储能收益分析页面","V1.8","李静","08/12 14:08","评审中"]].map(x=>{x.slice(0,5).map(v=>)})}
领域方案更新内容版本负责人更新时间状态
{v}{x[5]}
+function fileToBase64(file:File){return new Promise<{filename:string;mime:string;data:string}>((resolve,reject)=>{const r=new FileReader();r.onload=()=>{const buf=new Uint8Array(r.result as ArrayBuffer);let bin="";for(const b of buf)bin+=String.fromCharCode(b);resolve({filename:file.name,mime:file.type||"application/octet-stream",data:btoa(bin)});};r.onerror=reject;r.readAsArrayBuffer(file);});} + +function DomainLibrary({go,notify,onOpen}:{go:(p:PageKey)=>void;notify:(m:string)=>void;onOpen:(id:number)=>void}){ + const [list,setList]=useState([]); + const [loading,setLoading]=useState(true); + const load=async()=>{ try{ setList(await fetchDb("/domain-templates") as any); }catch(e:any){ notify("加载失败:"+e.message); } finally{ setLoading(false); } }; + useEffect(()=>{ load(); },[]); + const del=async(id:number)=>{ if(!confirm("确定删除该领域方案?此操作不可恢复")) return; try{ await fetchDb(`/domain-templates/${id}`,{method:"DELETE"}); notify("已删除"); load(); }catch(e:any){ notify("删除失败:"+e.message); } }; + return <> +
DOMAIN SOLUTION LIBRARY

领域方案库

沉淀各领域标准方案,供客户站点直接使用或快速微调。

+ + {loading?

加载中…

: + + + {list.length===0 && } + {list.map((t:any)=>( + + + + + + ))} +
模板名称所属领域版本状态创建人设备/页面/文档操作
暂无方案,点击右上角「+ 新增领域方案」创建
{t.name}{t.domain_name}{t.version}{t.status==="available"?"可用":"不可用"}{t.creator||"—"}{t.device_count}/{t.page_count}/{t.doc_count}
} +
+ ; +} + +function CreateTemplate({doms,notify,onCreated}:{doms:any[];notify:(m:string)=>void;onCreated:(id:number)=>void}){ + const [domain_id,setDomainId]=useState(doms[0]?.id||0); + const [name,setName]=useState(""); const [description,setDesc]=useState(""); + const [status,setStatus]=useState("available"); const [version,setVersion]=useState("V1.0"); const [creator,setCreator]=useState(""); + const save=async()=>{ try{ const r:any=await fetchDb("/domain-templates",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({domain_id,name,description,status,version,creator})}); notify("已创建"); onCreated(r.id); }catch(e:any){ notify("创建失败:"+e.message); } }; + return
+ + + + + +