From 0b587ad917ff6b0319a97650f036c11f58a246ef Mon Sep 17 00:00:00 2001 From: "wang.yu" Date: Tue, 18 Aug 2026 21:05:57 +0800 Subject: [PATCH] =?utf8?q?=E9=A2=86=E5=9F=9F=E6=96=B9=E6=A1=88=E5=BA=93?= =?utf8?q?=E9=87=8D=E6=9E=84=E4=B8=BA=E5=A4=9A=E8=8F=9C=E5=8D=95=EF=BC=9A?= =?utf8?q?=E5=88=97=E8=A1=A8/=E5=8D=A1=E7=89=87=E5=88=87=E6=8D=A2=E3=80=81?= =?utf8?q?=E8=AE=BE=E5=A4=87=E6=A8=A1=E7=89=88=E7=8B=AC=E7=AB=8B=E9=A1=B5?= =?utf8?q?=E3=80=81=E9=80=89=E7=94=A8=E8=AE=BE=E5=A4=87=E6=A8=A1=E7=89=88?= =?utf8?q?=E5=85=B3=E8=81=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit - 导航拆分:领域方案库模块下新增「领域方案」「设备模版」;领域分类改为 GET /api/domains 动态二级菜单,点击按 domainFilter 筛选方案 - 领域方案列表支持列表/卡片视图切换 - 新增独立「设备模版」页(DeviceTemplates),独立维护设备模版与采集点、所属领域多选 - 方案详情设备面板改为「选用设备模版」勾选器,保存即重写 device_template_domain_templates 关联 - 后端 domain-templates 更新支持 device_template_ids 重关联 - 设计文档升级至 v0.6,更新 4.2/5.9/5.10 与 changelog --- app/globals.css | 34 ++++++ app/page.tsx | 136 +++++++++++++++++------ db-sidecar.mjs | 7 ++ public/design-doc-assets/placeholder.svg | 8 ++ public/design-doc.html | 65 ++++++----- 5 files changed, 193 insertions(+), 57 deletions(-) create mode 100644 public/design-doc-assets/placeholder.svg diff --git a/app/globals.css b/app/globals.css index 4094a87..e81791d 100644 --- a/app/globals.css +++ b/app/globals.css @@ -185,3 +185,37 @@ .modal-console-head{background:#0f1722;color:#9fd0e6;font-size:12px;padding:6px 10px;border-bottom:1px solid #1c2a38} .modal-console-body{background:#0f1722;color:#cfe3f0;font:12px/1.5 "SFMono-Regular",Consolas,"Liberation Mono",Menlo,monospace;margin:0;padding:10px 12px;max-height:240px;overflow:auto;white-space:pre-wrap;word-break:break-word} +/* ===== 视图切换(列表/卡片) ===== */ +.view-toggle{display:inline-flex;border:1px solid var(--line);border-radius:3px;overflow:hidden} +.view-toggle button{border:0;background:#fff;color:#666;height:28px;padding:0 12px;font-size:11px} +.view-toggle button+button{border-left:1px solid var(--line)} +.view-toggle button.active{background:var(--blue);color:#fff} +/* ===== 领域方案卡片视图 ===== */ +.domain-card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(245px,1fr));gap:12px;padding:6px 0} +.domain-card{border:1px solid var(--line);border-top:3px solid var(--blue);background:#fff;padding:14px;display:flex;flex-direction:column;gap:9px;cursor:pointer;transition:.15s} +.domain-card:hover{box-shadow:0 6px 18px #0001;border-top-color:var(--blue2)} +.domain-card>header{display:flex;align-items:center;justify-content:space-between;gap:8px} +.domain-card h3{font-size:15px;margin:0} +.domain-card .badge{display:inline-block;align-self:flex-start;background:var(--pale);color:var(--blue2);border:1px solid #cfeaf6;border-radius:10px;padding:1px 10px;font-size:10px} +.domain-card .meta{display:flex;gap:14px;color:#888;font-size:11px} +.domain-card .meta b{color:#333;font-size:13px;margin-right:3px} +.domain-card .card-actions{display:flex;gap:14px;margin-top:2px;padding-top:8px;border-top:1px solid #f0f2f3} +/* ===== 设备模版 ===== */ +.device-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:12px;padding:4px 0} +.device-card{border:1px solid var(--line);background:#fff;padding:14px} +.device-card-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px} +.device-card-head b{font-size:14px} +.cp-list{margin-top:10px} +.cp-list>b{display:flex;align-items:center;gap:8px;font-size:12px} +.cp-list .data-table{margin-top:6px} +.chk{display:flex;flex-wrap:wrap;gap:8px} +.chk-item{display:inline-flex;align-items:center;gap:5px;font-size:12px;background:#f6f8f9;border:1px solid #e6e9eb;border-radius:3px;padding:4px 9px;cursor:pointer} +.chk-item input{margin:0;accent-color:var(--blue)} +/* ===== 方案详情:选用设备模版 ===== */ +.device-picker{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:8px} +.picker-item{display:flex;align-items:center;gap:9px;border:1px solid var(--line);background:#fff;border-radius:4px;padding:9px 11px;cursor:pointer} +.picker-item.on{border-color:var(--blue);background:#f4fbff} +.picker-item input{margin:0;accent-color:var(--blue)} +.picker-name{font-weight:bold;font-size:12px} +.picker-doms{margin-left:auto;color:#888;font-size:10px;max-width:42%;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap} + diff --git a/app/page.tsx b/app/page.tsx index c5a52e6..4397c88 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -2,7 +2,7 @@ import { useEffect, useMemo, useRef, useState, type PointerEvent as ReactPointerEvent } from "react"; -type PageKey = "login" | "projects" | "basic" | "assets" | "functions" | "generate" | "result" | "preview" | "domains" | "domainDetail" | "styleLibrary"; +type PageKey = "login" | "projects" | "basic" | "assets" | "functions" | "generate" | "result" | "preview" | "domains" | "domainDetail" | "styleLibrary" | "deviceTemplates"; type ModalKey = "" | "feedback" | "download" | "history" | "prompt" | "completePrompt"; const meta: Record = { @@ -15,7 +15,8 @@ const meta: Record = result:{label:"站点结果",icon:"◫",subtitle:"集中查看、预览、校验并下载站点交付物"}, preview:{label:"Cube 页面预览",icon:"▣",subtitle:"检查单个 Cube 页面效果,并通过反馈快速重新生成"}, domains:{label:"领域方案库",icon:"◆",subtitle:"沉淀各领域标准方案,供客户站点直接使用或快速微调"}, - domainDetail:{label:"水务 · 自来水厂方案",icon:"◇",subtitle:"查看领域资产、运维流程、Cube 页面、菜单及知识内容"}, + domainDetail:{label:"方案详情",icon:"◇",subtitle:"查看领域资产、运维流程、Cube 页面、菜单及知识内容"}, + deviceTemplates:{label:"设备模版",icon:"⬡",subtitle:"独立管理设备模版与采集点,供领域方案选用"}, styleLibrary:{label:"页面样式库",icon:"❖",subtitle:"沉淀可复用的 Cube 仪表盘页面样式(配色与视觉主题),供站点页面快速套用"}, }; @@ -171,6 +172,8 @@ export default function Home(){ const [muTree,setMuTree]=useState([]); const [pageStyles,setPageStyles]=useState([]); const [openDomainTemplateId,setOpenDomainTemplateId]=useState(null); + const [domainFilter,setDomainFilter]=useState(null); + const [domainOptions,setDomainOptions]=useState<{id:number;name:string}[]>([]); const [view,setView]=useState<"table"|"card">("table"); const [functionTab,setFunctionTab]=useState<"mu"|"cube"|"menu">("mu"); @@ -292,12 +295,13 @@ export default function Home(){ setLoading(true); Promise.all([ fetchDb("/sites") as Promise, - fetchDb("/domains") as Promise<{name:string}[]>, + fetchDb("/domains") as Promise<{id:number;name:string}[]>, fetchDb("/mu-tree") as Promise, fetchDb("/page-styles") as Promise, ]).then(([s,d,m,ps])=>{ setSites(s||[]); setDomains((d||[]).map(x=>x.name)); + setDomainOptions((d||[]).map(x=>({id:x.id,name:x.name}))); setMuTree(m||[]); setPageStyles(ps||[]); }).catch(e=>notify("加载失败: "+e.message)).finally(()=>setLoading(false)); @@ -431,7 +435,7 @@ export default function Home(){ return
⬡
iStationiStation TeamStationBuilder⌄
设计方案wang.yu@advantech.com
iStation Team
-