From 1e4eac65592f15a476b5ac07e09791747a9122ad Mon Sep 17 00:00:00 2001 From: "wang.yu" Date: Wed, 19 Aug 2026 08:53:42 +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=88=97=E8=A1=A8=E5=A2=9E=E5=BC=BA=E6=8E=92=E5=BA=8F?= =?utf8?q?=E4=B8=8E=E7=AD=9B=E9=80=89(=E5=88=97=E9=87=8D=E6=8E=92+?= =?utf8?q?=E7=AD=9B=E9=80=89=E6=A0=8F)?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit - 列顺序改为 所属领域→方案名称→版本→状态→创建人→设备/页面/文档→操作 - 版本/状态列收窄, 所属领域/方案名称列加宽 - 新增筛选栏: 查找(方案名称/创建人) + 所属领域下拉 + 状态下拉 + 条数 - 四列(所属领域/方案名称/状态/创建人)可点击排序, 升/降切换带 ▲▼ - 同步设计文档至 v0.15 --- app/globals.css | 11 ++++++++++ app/page.tsx | 49 ++++++++++++++++++++++++++++++++++++++---- public/design-doc.html | 28 +++++++++++++----------- 3 files changed, 72 insertions(+), 16 deletions(-) diff --git a/app/globals.css b/app/globals.css index f159897..fd6cc8e 100644 --- a/app/globals.css +++ b/app/globals.css @@ -84,6 +84,17 @@ .data-table.editable .trash{border:0;background:transparent;color:var(--red);font-size:15px;cursor:pointer;line-height:1} .data-table.editable .trash:hover{color:#d63723} +/* ===== 领域方案库:列表筛选栏 + 可排序列头 ===== */ +.filter-bar{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:10px} +.filter-bar .filter-search{flex:1 1 220px;min-width:180px;height:30px;border:1px solid #d9dee2;border-radius:3px;padding:0 10px;font-size:12px;background:#fff} +.filter-bar .filter-search:focus{border-color:var(--blue);outline:none} +.filter-bar select{height:30px;border:1px solid #d9dee2;border-radius:3px;padding:0 8px;font-size:12px;background:#fff;color:#444} +.filter-bar select:focus{border-color:var(--blue);outline:none} +.filter-bar .filter-count{margin-left:auto;font-size:12px} +.data-table th.sortable{cursor:pointer;user-select:none;white-space:nowrap} +.data-table th.sortable:hover{color:var(--blue)} +.data-table th.sortable .sort-ind{color:var(--blue);font-size:10px} + /* ===== Assets 资产配置 ===== */ .empty-row td{background:#fafbfc} .empty-row input{color:#b7bcc0;background:#fafbfc} diff --git a/app/page.tsx b/app/page.tsx index 03fabbc..a5b25c1 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -989,25 +989,66 @@ function DomainLibrary({go,notify,onOpen,domainFilter,domainOptions}:{go:(p:Page const [list,setList]=useState([]); const [loading,setLoading]=useState(true); const [view,setView]=useState<"list"|"card">("list"); + const [q,setQ]=useState(""); + const [domainSel,setDomainSel]=useState(domainFilter!=null?String(domainFilter):""); + const [statusSel,setStatusSel]=useState(""); + const [sort,setSort]=useState<{key:""|"domain"|"name"|"status"|"creator";dir:1|-1}>({key:"",dir:1}); const load=async()=>{ try{ setList(await fetchDb("/domain-templates") as any); }catch(e:any){ notify("加载失败:"+e.message); } finally{ setLoading(false); } }; useEffect(()=>{ load(); },[]); - const filtered=list.filter(t=>!domainFilter||t.domain_id===domainFilter); const del=async(id:number)=>{ if(!confirm("确定删除该领域方案?此操作不可恢复")) return; try{ await fetchDb(`/domain-templates/${id}`,{method:"DELETE"}); notify("已删除"); load(); }catch(e:any){ notify("删除失败:"+e.message); } }; + const statusLabel=(s:string)=>s==="available"?"可用":"不可用"; + const toggleSort=(key:"domain"|"name"|"status"|"creator")=>setSort(s=>s.key===key?{key,dir:(s.dir*-1) as 1|-1}:{key,dir:1}); + const sortInd=(key:"domain"|"name"|"status"|"creator")=>sort.key===key?({sort.dir===1?"▲":"▼"}):null; + const filtered=list + .filter(t=>domainSel===""||String(t.domain_id)===domainSel) + .filter(t=>statusSel===""||t.status===statusSel) + .filter(t=>{ const k=q.trim().toLowerCase(); if(!k) return true; return (t.name||"").toLowerCase().includes(k)||(t.creator||"").toLowerCase().includes(k); }) + .sort((a:any,b:any)=>{ + if(!sort.key) return 0; + let av:string,bv:string; + if(sort.key==="domain"){ av=a.domain_name; bv=b.domain_name; } + else if(sort.key==="name"){ av=a.name; bv=b.name; } + else if(sort.key==="status"){ av=statusLabel(a.status); bv=statusLabel(b.status); } + else { av=a.creator||""; bv=b.creator||""; } + av=String(av).toLowerCase(); bv=String(bv).toLowerCase(); + if(avbv) return 1*sort.dir; return 0; + }); return <>
DOMAIN SOLUTION LIBRARY

领域方案库

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

{domainOptions.map(d=>
{list.filter(t=>t.domain_id===d.id).length}{d.name}
)}
- d.id===domainFilter)?.name||""}`:"领域方案列表"} tools={
+
}> +
+ setQ(e.target.value)} placeholder="查找 方案名称 / 创建人" /> + + + 共 {filtered.length} 条 +
{loading?

加载中…

: filtered.length===0?

暂无方案,点击右上角「+ 新增领域方案」创建

: view==="list"? ( - +
方案名称所属领域版本状态创建人设备/页面/文档操作
+ + + + + + + + {filtered.map((t:any)=>( - + diff --git a/public/design-doc.html b/public/design-doc.html index 46635ba..5d2d386 100644 --- a/public/design-doc.html +++ b/public/design-doc.html @@ -85,7 +85,7 @@
-

文档版本:v0.14 最后更新:2026-08-19 修改人:wang.yu 状态:开发中(演示数据已标注)

+

文档版本:v0.15 最后更新:2026-08-19 修改人:wang.yu 状态:开发中(演示数据已标注)

StationBuilder 产品与交互设计方案

1. 文档说明

@@ -479,37 +479,40 @@

5.9 领域方案库(domains)

-

领域方案库已从硬编码演示改为真实数据库驱动。列表与详情编辑器同一页面内通过 openDomainTemplateId state 切换:null=列表,"create"=新增表单,number=该方案详情编辑器。列表支持列表 / 卡片两种视图切换(右上角视图切换按钮,view state 控制);点击左侧「领域分类」下的某个领域会按 domainFilter 自动筛选该领域方案。

+

领域方案库已从硬编码演示改为真实数据库驱动。列表与详情编辑器同一页面内通过 openDomainTemplateId state 切换:null=列表,"create"=新增表单,number=该方案详情编辑器。列表支持列表 / 卡片两种视图切换(右上角视图切换按钮,view state 控制)。列表上方提供筛选栏:文本查找框(匹配 方案名称 / 创建人)、所属领域下拉、状态下拉,结果实时过滤并显示条数;列头 所属领域 / 方案名称 / 状态 / 创建人 可点击排序(升/降切换,带 ▲▼ 指示),卡片视图复用同一筛选与排序结果。

toggleSort("domain")}>所属领域{sortInd("domain")}toggleSort("name")}>方案名称{sortInd("name")}版本toggleSort("status")}>状态{sortInd("status")}toggleSort("creator")}>创建人{sortInd("creator")}设备/页面/文档操作
{t.name}{t.domain_name}{t.version}{t.domain_name}{t.name}{t.version} {t.status==="available"?"可用":"不可用"} {t.creator||"—"} {t.device_count}/{t.page_count}/{t.doc_count}
- + +
元素功能数据来源交互效果
领域方案列表表格展示全部领域方案(模板名称 / 所属领域 / 版本 / 状态 / 创建人 / 设备·页面·文档数 / 操作)GET /api/db/domain-templates(含 domain_name、device_count、page_count、doc_count)每行「编辑」→ 打开该方案详情编辑器;「删除」→ 确认后 DELETE /api/db/domain-templates/:id(级联删除 device_template_domain_templates)并刷新;空列表提示「点击右上角新增」
筛选栏(查找 / 所属领域 / 状态 / 条数)列表实时筛选与计数本地 state(q / domainSel / statusSel),作用于 GET /api/db/domain-templates 结果查找框按 方案名称/创建人 模糊匹配;所属领域、状态下拉精确过滤;右上角显示「共 N 条」
领域方案列表表格展示全部领域方案(所属领域 / 方案名称 / 版本 / 状态 / 创建人 / 设备·页面·文档数 / 操作)GET /api/db/domain-templates(含 domain_name、device_count、page_count、doc_count)每行「编辑」→ 打开该方案详情编辑器;「删除」→ 确认后 DELETE /api/db/domain-templates/:id(级联删除 device_template_domain_templates)并刷新;空列表提示「点击右上角新增」
「+ 新增领域方案」新建领域方案,进入新增表单—同页切到 CreateTemplate 表单:所属领域(select 来自 GET /api/domains)、模板名称、版本、状态(可用/不可用)、创建人、领域描述;POST /api/db/domain-templates 成功后自动打开该方案详情编辑器
搜索 / 筛选 / 同步方案库(历史功能)—已按计划 Phase 0 移除整行(含「同步方案库」占位按钮) 已移除

5.9.1 交互细节

-
领域方案库
领域方案库:列表视图,支持列表/卡片切换、按领域分类筛选,点击「编辑」进入方案详情。
+
领域方案库
领域方案库:列表视图,上方为筛选栏(查找方案名称/创建人、所属领域、状态),列头 所属领域/方案名称/状态/创建人 可点击排序;支持列表/卡片切换。

① 字段 / 表格逐列(列表表格,仅展示 + 操作):

- - - - - + + + + +
列数据来源是否可编辑编辑类型上线范围
方案名称GET /api/db/domain-templates(name)只读(列表态)文本方案标识
所属领域domain_name只读文本侧栏领域分类维度
版本version只读文本方案版本
状态status只读Status 标签(可用/不可用)是否可选入站点方案
创建人creator只读文本—
所属领域domain_name只读文本侧栏领域分类维度;列宽较宽,列头可点击排序
方案名称GET /api/db/domain-templates(name)只读(列表态)文本方案标识;列宽最宽(弹性),列头可点击排序
版本version只读文本方案版本;列宽收窄
状态status只读Status 标签(可用/不可用)是否可选入站点方案;列宽收窄,列头可点击排序
创建人creator只读文本—;列头可点击排序
设备 / 页面 / 文档聚合 device_count / page_count / doc_count只读数字方案体量概览
操作 / 编辑·删除编辑→onOpen(id);删除→DELETE(级联删关联)触发动作按钮(删除二次确认)打开详情 / 删除方案
-

顶部 domain-hero-stats 按领域统计方案数(本地计算),纯展示;侧栏「领域分类」按钮设置 domainFilter 筛选。

+

顶部 domain-hero-stats 按领域统计方案数(本地计算),纯展示。列表列顺序为 所属领域 → 方案名称 → 版本 → 状态 → 创建人 → 设备/页面/文档 → 操作;其中 所属领域 / 方案名称 / 状态 / 创建人 四列点击列头可排序(升/降切换,表头右侧显示 ▲/▼)。

② 按钮与操作

- + + + + -
按钮点击效果编辑方式确定 / 取消 / 关闭
视图切换 列表 ▤ / 卡片 ▦setView 本地—无弹窗(卡片态点卡片即打开详情)
侧栏领域分类按钮setDomainFilter(d.id) 筛选—无弹窗
查找框(方案名称 / 创建人)setQ 本地模糊匹配 name/creator输入文本无弹窗,实时过滤并显示条数
所属领域下拉setDomainSel 本地按 domain_id 过滤选择(全部 / 各行业)无弹窗,实时过滤
状态下拉setStatusSel 本地按 status 过滤选择(全部 / 可用 / 不可用)无弹窗,实时过滤
可排序列头(所属领域 / 方案名称 / 状态 / 创建人)toggleSort 本地,升/降切换点击列头无弹窗,表头右侧显示 ▲/▼;再次点击反向
编辑onOpen(id) → 方案详情——
删除DELETE /api/db/domain-templates/:id(级联 device_template_domain_templates)—二次确认后删除并刷新
+ 新增领域方案setOpenDomainTemplateId("create") → 同页 CreateTemplate 表单表单填写保存(POST)后自动打开详情;取消收起
清除领域筛选setDomainFilter(null)—无弹窗

③ 导航流

    @@ -728,6 +731,7 @@

    11.1 版本变更记录(Changelog)

    + -- 2.43.0
    版本日期修改人说明
    v0.152026-08-19wang.yu领域方案库列表增强:列顺序调整为「所属领域 → 方案名称 → 版本 → 状态 → 创建人 → 设备/页面/文档 → 操作」,版本/状态列收窄、所属领域/方案名称列加宽;新增筛选栏(查找 方案名称/创建人 + 所属领域下拉 + 状态下拉 + 条数)与可排序列头(所属领域/方案名称/状态/创建人,升降切换带 ▲▼),卡片视图复用同结果。
    v0.142026-08-19wang.yu左侧目录(TOC)贴齐浏览器最左侧:.doc-layout 取消 margin:0 auto 自动居中(改为 margin:0; padding-left:12px),宽屏下不再左右留白,目录紧贴视口左缘。
    v0.132026-08-18wang.yu截图显示宽度由 500px 调整为 360px(.figure img 的 max-width),等比例缩放并居中,适配常见浏览宽度。
    v0.122026-08-18wang.yu统一文档内所有截图显示尺寸:修改 .figure img 为 max-width:500px; height:auto 并居中,所有页面截图等比例压缩至 500px 宽,宽度一致。