From 28623cd1cb5adece98987cd9d9d5ef331649e659 Mon Sep 17 00:00:00 2001 From: 18628386721 <18628386721@163.com> Date: Wed, 29 Jul 2026 17:29:11 +0800 Subject: [PATCH] =?UTF-8?q?=E8=8A=82=E7=82=B9=E5=B1=9E=E6=80=A7=E5=B9=B3?= =?UTF-8?q?=E9=93=BA=20=E2=80=94=E2=80=94=20=E4=B8=8D=E5=88=86=E7=B1=BB,?= =?UTF-8?q?=E4=B9=9F=E4=B8=8D=E5=86=99=E6=95=B0=E6=8D=AE=E5=A5=91=E7=BA=A6?= =?UTF-8?q?=E5=A3=B0=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 分类卡(身份与命名 / 数据接口 / 类型与责任 / 链接活动实现 / 出边)全撤: 节点本来只决定这么几件事,分成五张小卡反而把四五个字段摊成半屏。 现在是一列字段直排,字段间一条细线断句: 节点 ID(只读)· 名称 · 说明 · 节点类型 · 链接实现 · 出边条件(每条一格)。 「数据接口 · 声明」整节删掉 —— 数据契约**归活动自己**,编排面不复述它。 链好实现后只留一枚直达钮:「去活动库看 X 的契约」。 顺带清掉两条一直漏网的说教横幅(前一轮 ⓘ 清扫时因为文案里夹了 没匹配上): 「编排不带岗位 ——…」与「审批点是系统内置要素 ——…」。前者的意思已收进 「节点类型」那行的提示,后者本就是常识性交代,不必占一整块。 CSS 里 .g-props/.g-propcol/.g-eprops/.g-prop* 与 .g-dif* 两组样式随之退役, 换成一条 .g-nodeform。 五闸绿。 Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m --- apps/web/src/app/styles/console.css | 30 +- .../features/gov-process/internal/panel.tsx | 284 ++++++------------ 2 files changed, 99 insertions(+), 215 deletions(-) diff --git a/apps/web/src/app/styles/console.css b/apps/web/src/app/styles/console.css index a727844..882559d 100644 --- a/apps/web/src/app/styles/console.css +++ b/apps/web/src/app/styles/console.css @@ -630,16 +630,13 @@ /* 两面都齐:一枚小检验章,别再占一整张卡 */ .g-okstamp { display: inline-flex; align-items: center; gap: 6px; margin-top: 4px; padding: 5px 11px; border: 1px solid rgba(46, 125, 79, .45); font: 600 10px/1 var(--sh-mono); letter-spacing: .08em; color: #2e7d4f; } -/* 属性小卡:三栏改版后右栏是**窄轨**(≈335),两列摊不开 —— 改单列竖排, - 顺序即阅读次序:身份 → 数据接口 → 类型与责任 → 装载 → 出边。长了在明细区自己滚。 */ -.g-nodecard .g-props { display: flex; flex-direction: column; align-items: stretch; gap: 12px; } -.g-propcol { min-width: 0; display: flex; flex-direction: column; gap: 12px; } -.g-nodecard .g-props.g-eprops { display: flex; flex-direction: column; align-items: stretch; gap: 12px; } -.g-nodecard .g-prop { border: 1px solid var(--sh-line); border-radius: 0; box-shadow: none; } -.g-nodecard .g-prop-h { padding: 8px 12px; background: #fff; font: 600 9px/1.5 var(--sh-mono); letter-spacing: .12em; text-transform: uppercase; color: var(--sh-steel); border-bottom: 1px solid var(--sh-line); } -.g-nodecard .g-prop-h svg { color: var(--sh-steel); opacity: .6; } -.g-nodecard .g-prop-h .x { font-size: 8.5px; font-weight: 600; letter-spacing: .04em; color: var(--sh-muted); text-align: right; } -.g-nodecard .g-prop-b { padding: 11px 12px 13px; gap: 11px; } +/* 节点属性**平铺**(2026-07-30):节点只决定几件事 —— 分类卡把四五个字段摊成半屏, + 撤掉;一列字段直排,字段之间一条细线断句就够。 */ +.g-nodeform { display: flex; flex-direction: column; gap: 0; } +.g-nodeform > .g-field { padding: 11px 2px; border-bottom: 1px dashed var(--line-soft); } +.g-nodeform > .g-field:last-child { border-bottom: 0; } +.g-nodeform > .g-note { margin: 11px 0 0; } +.g-nodeform > .g-btn { align-self: flex-start; margin-top: 11px; } /* 字段 = 图签小格:微墨签(mono 大写)+ 纸上填线(输入只留底线,聚焦底线转钢蓝) */ .g-nodecard .g-field { gap: 3px; } @@ -675,19 +672,6 @@ .g-maprow > .g-btn { grid-column: 6; justify-self: stretch; padding: 4px 0; display: inline-flex; align-items: center; justify-content: center; } .g-maparr { color: var(--sh-steel, #46586a); font-weight: 700; text-align: center; } -/* ── 节点属性 · 数据接口:契约即管道 —— 输入字段(名/型/来源)+ 输出口 ── */ -.g-dif { display: flex; flex-direction: column; gap: 2px; } -.g-dif + .g-dif { margin-top: 8px; } -.g-dif > em { font: 600 9px/1.6 var(--mono); font-style: normal; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-4); padding-bottom: 3px; border-bottom: 1px solid var(--line-soft); } -.g-dif-r { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 10px; padding: 4px 0; border-bottom: 1px dashed var(--line-soft); font-size: 11.5px; } -.g-dif-r:last-child { border-bottom: 0; } -.g-dif-r .k { font-family: var(--mono); font-weight: 700; color: var(--ink); } -.g-dif-r .k i { font-style: normal; font-family: var(--mono); font-size: 8.5px; font-weight: 600; letter-spacing: .06em; color: #8a5f1c; margin-left: 5px; padding: 1px 4px; border: 1px solid #e3d1a8; border-radius: 3px; } -.g-dif-r .t { font-family: var(--mono); font-size: 10px; color: var(--ink-4); } -.g-dif-r .s { margin-left: auto; font-size: 11px; color: var(--ink-3); } -.g-dif-r .s.ask { color: #8a5f1c; } -.g-dif-r .f { min-width: 0; font-family: var(--mono); font-size: 10.5px; color: var(--ink-3); overflow-wrap: anywhere; } - /* ── 运营中心 · 工作流 · 运行配置:一包一卡,里面两节(触发器 / 节点负责人)── */ .g-runconf { display: flex; flex-direction: column; gap: 4px; padding: 10px 14px 12px; } .g-runconf + .g-runconf { border-top: 1px dashed var(--line-soft); } diff --git a/apps/web/src/features/gov-process/internal/panel.tsx b/apps/web/src/features/gov-process/internal/panel.tsx index 1b1decc..88a6201 100644 --- a/apps/web/src/features/gov-process/internal/panel.tsx +++ b/apps/web/src/features/gov-process/internal/panel.tsx @@ -3,7 +3,9 @@ * * 一区一内容:三枚计数摆在货架顶端,底下就是包货架(触发器已独立成区)。 * 货架一流程一卡(不按版本平铺);进详情是**三栏**:左窄轨=版本(选中那版才出动作: - * 激活/停用 · 改名 · 删除)、中=流程图、右=节点属性(点图选节点,内容长了卡内滚,不拉长图)。 + * 激活/停用 · 改名 · 删除)、中=流程图、右=节点属性 —— **平铺一列字段,不分类**: + * 节点只决定 ID/名称/说明 · 类型 · 链接哪个活动 · 出边条件;数据契约归活动自己, + * 这里不写声明,要看去活动库看(点图选节点,内容长了卡内滚,不拉长图)。 * 「激活判据」不再单占一卡 —— 没选节点时,属性栏就地列出还差哪几条,点一条定位过去。 * * 版本是**运行时开关**,不是发布流程: @@ -35,7 +37,6 @@ import { Kpi, Note, PageHead, - Prop, QueryGate, Sec, Seg, @@ -401,8 +402,6 @@ function FlowLab({ setDirty(true); }; - const kindLabel = (n: FlowNode) => - n.kind === 'activity' ? (n.flavor === 'approval' ? '审批点' : '活动点') : n.kind === 'start' ? '调用接口' : '显式终点'; // 画布上的选中态:diagram-js 给每个形状挂了 data-element-id,外挂一个类,不改画布件 useEffect(() => { @@ -847,202 +846,103 @@ function FlowLab({ )} ) : ( - <> - {/* 两列手排(不用自动砌体):左列 = 身份与数据口,右列 = 类型与装载 —— - 卡数随节点种类变(审批点无装载卡),手排保证两列始终语义成组、高度可控 */} -
-
- - - - - + /* + * 节点属性**平铺**(2026-07-30 用户定「不用分类了」):不再分「身份/类型/装载/出边」 + * 几张小卡 —— 节点本来只决定这么几件,分类反而把四五个字段摊成半屏卡片。 + * 也不再摆数据契约声明:数据契约**归活动自己**,要看去活动库看(下面那枚钮直达)。 + */ +
+ + + + + patch((n) => ({ ...n, label: e.target.value }))} + /> + + {node.kind === 'activity' && ( + <> + patch((n) => ({ ...n, label: e.target.value }))} + value={node.sub ?? ''} + placeholder="如:照谱执行 / 临场演绎 / 人裁节点" + onChange={(e) => patch((n) => ({ ...n, sub: e.target.value === '' ? undefined : e.target.value }))} /> - {node.kind === 'activity' && ( - - - patch((n) => ({ ...n, sub: e.target.value === '' ? undefined : e.target.value })) - } - /> - + + patch((n) => ({ ...n, flavor: k === 'approval' ? ('approval' as const) : undefined }))} + /> + + + )} + + {node.kind === 'activity' && node.flavor !== 'approval' && ( + <> + + + + {refAct === undefined ? ( + 还没链接活动库里已安装的实现 —— 图可以照画照存,激活前链上即可。 + ) : ( + /* 数据契约归活动自己 —— 要看它吃什么吐什么,去活动库看 */ + )} - + + )} - {node.kind === 'activity' && node.flavor !== 'approval' && ( - /* - * 数据接口 —— **只声明,不做任何要求**(2026-07-30 用户定): - * 这里照着活动契约把「吃什么、吐什么」列出来,不标必填、不推来源、不校验类型。 - * 字段够不够、缺了怎么补,是**活动内实现**的事,不在编排层现形。 - * 数组照实写成 `T[]` —— 声明得看得出是一个还是一串。 - */ - - {refAct === undefined ? ( - 链接活动实现后,这里照它的契约列出吃什么、吐什么。 - ) : ( - <> -
- 输入 · {refAct.contract.inputFields.length} 字段 - {refAct.contract.inputFields.map((f) => ( -
- {f.name} - {f.type} -
- ))} -
-
- 输出 · {refAct.contract.outputPorts.length} 口 - {refAct.contract.outputPorts.map((port) => ( -
- {port.name} - - {port.fields.length > 0 - ? port.fields.map((f) => `${f.name} ${f.type}`).join(' · ') - : '(整包事实)'} - -
- ))} -
- - )} -
- )} -
- -
- ( + /* + * 出边条件:**分支归发起它的这个节点管**(Mastra 的 `.branch([[条件, 下一步], …])` + * 就挂在上一步上)—— 边本身不是可编辑对象,它只是画布上的一条线。 + */ + - {node.kind === 'activity' && ( - - - patch((n) => ({ ...n, flavor: k === 'approval' ? ('approval' as const) : undefined })) - } - /> - - )} - - 编排不带岗位 —— 负责人是运营时分配的:工作流绑了员工组按组轮值, - 没绑组全员轮值(最闲者先)。审批点与活动点同一口径。 - - {node.kind === 'activity' && node.flavor === 'approval' && ( - - 审批点是系统内置要素,不是活动 —— 声明即用、零开发、不进活动库(一个流程包里需要开发的 - 只有活动)。功能属性四件:审批岗位(复用负责人四策略解析)· 输入装配映射 · 驳回走向 - (声明式:回指定节点重开新实例 / 终止)· 催办阶梯。运行时它产出审批单而非任务。 - - )} - - - {node.kind === 'activity' && node.flavor !== 'approval' && ( - - - - - {refAct !== undefined ? ( - <> - {/* 实现方式(范式/版本)是装载信息,只读展示 —— 编排面不决定它 */} -
- - {refAct.paradigm === 'loop' ? '实现:案例 loop' : '实现:标准 flow'} - - - v{refAct.packageVersions[0]?.version ?? '—'} × a - {refAct.assetVersions.find((x) => x.effective)?.version ?? '—'} - -
- - - ) : ( - 还没链接活动库里已安装的实现 —— 图可以照画照存,激活前链上即可。 - )} -
- )} - - {outEdges.length > 0 && ( - /* - * 出边 · 分支(2026-07-30):**分支归发起它的这个节点管**(Mastra 的 - * `.branch([[条件, 下一步], …])` 就挂在上一步上)—— 所以条件填在这里, - * 边本身不再是可编辑对象:它只是画布上的一条线,表达顺序。 - * 条件读的是这个节点的输出字段;留空即默认兜底(至多一条)。 - */ - - {outEdges.map(({ edge, index }) => ( - - patchEdge(index, (x) => ({ ...x, condition: e.target.value }))} - /> - - ))} - - )} -
-
- + patchEdge(index, (x) => ({ ...x, condition: e.target.value }))} + /> + + ))} +
)}