# FMS 审批流程设置器交互设计 > 本文以 `D:\workspace\code\test\Workflow-Vue3` 的钉钉式审批设置交互为参考,重定 FMS 流程配置器的产品方向。参考的是纵向流程树、节点间添加入口、条件分支和属性抽屉等交互,不是照搬其 Vue 代码或旧版数据结构。 > > 本文取代本文件之前“线性卡片模式 + LogicFlow 高级模式”的交互方案。FMS 工作流的表结构、版本、审批执行和审计约束仍以《FMS工作流与审批设计.md》为准;其中 §19 对画布引擎的选型是旧交互方案,**本次配置器的交互入口以本文为准**。编辑器必须把 UI 树转换为 FMS 的 `wf_node` / `wf_edge` / `wf_actor_rule` 领域模型,不能另造一套执行数据。 ## 1. 结论 **应该把 FMS 审批流程设置器设计成仿钉钉的树形流程编辑器。** 它不是“先做一个简单卡片页,再把复杂流程交给画布”的双编辑器,而是始终以一条可读的纵向审批路径为主干,条件分支在主干中展开成并列分支,分支内部继续递归呈现审批、抄送或嵌套条件。 普通管理员的核心操作应当是: 1. 在流程节点之间点击“+”; 2. 选择审批人、抄送人或条件分支; 3. 点击节点卡片,在右侧抽屉内完成设置; 4. 从页面直接看到审批顺序、分支条件和配置错误; 5. 校验通过后保存草稿、模拟并发布。 ```text 视觉与操作:钉钉式纵向流程树 配置数据:FMS WorkflowDraft / wf_* 领域模型 执行与审计:FMS 工作流服务 ``` ## 2. 参考交互在 FMS 中的对应 | 参考项目的设计 | FMS 中的产品行为 | FMS 的数据落点 | | --- | --- | --- | | 开始节点、发起人设置 | 流程入口固定显示;可发起范围在流程绑定/适用范围设置中配置 | `wf_binding`,不把发起范围伪装成审批人节点 | | 节点间“+”弹出审批人、抄送人、条件分支 | 任何可插入位置都用同一种添加入口 | 插入操作更新领域节点和连线 | | 审批、抄送节点卡片 | 卡片显示节点名称、人员摘要和配置状态;点击打开属性抽屉 | `wf_node`、`wf_actor_rule` | | 递归渲染 `childNode` 和条件分支 | 分支中可以继续添加审批、抄送和子条件 | UI 树编译为 `wf_node`、`wf_edge` | | 条件抽屉和条件优先级 | 使用业务字段选择器与结构化 AND/OR 条件;未命中时走固定兜底分支 | `wf_edge.b_condition_json`、`b_priority` | | 页面缩放 | 流程较长或分支较宽时可缩放、定位;缩放只影响视图 | `wf_version.b_canvas_json` 仅在确有布局需要时保存视图状态 | | 发布前错误列表 | 错误定位到具体节点或条件分支,修正后可重新校验 | 前端体验校验 + 后端最终校验 | 不照搬参考项目的 `nodeConfig`/`conditionNodes` 持久化格式、`sh_*` 表、Element UI 组件或图片字体资源。人员名称只用于显示,提交和执行必须使用稳定编码。 ## 3. 产品范围与边界 ### 3.1 本次设计器支持 - 开始节点和结束节点(固定,不允许删除); - 人工审批节点; - 抄送节点; - 条件分支(互斥路由),支持嵌套; - 分支内和分支后的纵向后续节点; - 单人、或签、会签、串行会签,以及当前工作流模型支持的其他审批方式; - 保存草稿、校验、模拟、发布和版本只读查看。 ### 3.2 本次不把以下能力塞进“高级画布”兜底 本次不要求用户在钉钉式树形编辑器与 LogicFlow 之间切换,也不以安装或继续维护 LogicFlow 作为交互重构前提。并行网关、服务节点、循环、任意跨支路连线等当前树形交互无法安全表达的拓扑,不得静默压平成树;若已有数据包含这些拓扑,应清楚提示“不支持在此编辑器中修改”,保留原草稿,不能保存覆盖。 如果将来业务确实要求并行审批或更一般的图拓扑,应先补充对应的树形交互和运行语义,再单独评估是否需要图编辑器。那是明确的后续产品决策,不是本次默认入口。 ## 4. 页面布局 ```text ┌──────────────────────────────────────────────────────────────────┐ │ 返回 流程名称 草稿状态 保存草稿 校验 模拟 发布 版本历史 │ ├──────────────────────────────────────────────────────────────────┤ │ 流程基本信息 / 流程适用范围 │ ├──────────────────────────────────────────────────────────────────┤ │ │ │ 开始 / 发起范围 │ │ │ │ │ + │ │ 部门负责人审批 ──摘要 │ │ │ │ │ + │ │ ┌────── 条件分支(并列显示)──────┐ │ │ │ 金额 > 10,000 │ 其他情况 │ │ │ │ 审批节点 │ 抄送节点 │ │ │ └───────────────────────────────┘ │ │ │ │ │ 流程结束 │ │ │ │ 缩放 - 100% + / 适应宽度 │ └──────────────────────────────────────────────────────────────────┘ ``` - 主编辑区显示完整纵向流程树;分支横向并排,分支内容各自纵向排列。 - 节点卡片只显示用户读得懂的摘要,不显示节点编码、数据库字段名或 JSON。 - 点击节点主体打开右侧属性抽屉;节点名支持就地改名;错误标记和摘要始终可见。 - 右上角固定显示缩放、适应画布和返回流程列表等轻量导航,不以自由拖拽画布作为日常操作。 - 编辑流程的头部状态必须区分未修改、未保存、保存中、已保存和保存失败;发布不能代替保存草稿。 ## 5. 流程结构和条件分支 ### 5.1 面向界面的树形草稿 界面可以使用递归结构方便渲染和交互,但它只是 `WorkflowDraft` 的编辑投影,不是接口或数据库的第二套真相: ```ts type FlowItem = | { kind: 'step'; nodeKey: string; next: FlowItem | null } | { kind: 'branch'; gatewayKey: string; branches: Array<{ edgeKey: string; label: string; priority: number; condition: ConditionAst | null; child: FlowItem | null; }>; next: FlowItem | null; // 所有条件路径汇合后的公共后续流程 }; ``` - `step` 节点映射开始、人工审批、抄送、结束等领域节点。 - `branch` 映射一个 `exclusive_gateway` 领域节点及其多条出边。 - 分支 `child` 是该路径专属的节点;`next` 是条件分支之后所有路径的公共后续。 - 运行顺序始终由编译后的有向边决定,不依赖卡片的数组索引或 CSS 排列。 ### 5.2 领域图映射 FMS 草稿继续使用 `nodes` 和 `edges` 的扁平有向图。新增并测试独立的双向适配: ```text workflowDraftToTree(draft) // 展示/编辑投影 workflowTreeToDraft(tree, draftMetadata) // 生成 FMS 节点和连线 ``` 适配规则: 1. 条件分支生成一个 `exclusive_gateway` 节点;每个条件项生成从网关出发的一条边。 2. 命中条件分支的边保存结构化条件 AST;兜底分支保存 `condition: null`,并且必须唯一、固定在最后。 3. 显式条件按优先级依次判断;优先级保存到边顺序/`b_priority`,不能依赖节点名称或数组渲染顺序隐式表达。 4. 各分支末端连到该分支块的公共后续节点。嵌套条件也按相同规则递归编译。 5. 从领域图反向构树时,必须能识别分支出口和公共后续。存在循环、并行、交叉连线、分支无法唯一汇合等树形 UI 无法表达的拓扑时,返回明确的不支持原因,禁止丢边、猜测或静默保存。 6. 树投影在加载—保存—重新加载后必须保持节点编码、条件、优先级、审批人规则及拓扑一致。 UI 的树形结构可在内存中使用,但不能把整个 `childNode` JSON 写进 `wf_version` 或新增卡片专用表。`b_canvas_json` 只可保存必要的缩放/布局偏好,不是执行模型。 ### 5.3 默认兜底分支 - 添加条件分支时,默认创建至少一个“条件”分支和一个“其他情况”分支。 - “其他情况”代表条件 `null`,必须有且仅有一个,并固定为最后一项;用户不能把它改成普通条件或删除后仍发布。 - 可以通过左右移动按钮调整显式条件的优先级;条件标签允许改名,但改名不改变条件表达式。 - 删除包含节点的分支前要提示将删除的子树;删到只剩一条路径时,需确认是移除网关并提升剩余路径,还是取消操作,不做无提示结构变更。 ## 6. 关键交互 ### 6.1 添加、插入、删除和排序 - 所有节点之间提供统一“+”入口,弹出“审批人 / 抄送人 / 条件分支”。 - 在线性路径插入节点时,原前驱和后继关系改为 `前驱 → 新节点 → 后继`。 - 在某条件分支内添加节点,只影响该分支子树;在分支块下方添加则是所有分支共用的后续。 - 普通节点提供编辑、复制、删除;固定开始/结束节点不可删除;上下移动按钮仅用于同一线性路径内调整顺序。 - 删除节点或子树前明确说明受影响的节点和连接;撤销/取消时恢复完整草稿。 - 节点卡片不支持任意拖到另一条支路上。跨支路调整通过删除/插入操作明确完成,避免拓扑悄悄改变。 ### 6.2 节点摘要卡片 人工审批卡片显示:名称、审批人摘要、审批方式、驳回策略/时限(空间足够时)、错误或警告数量。 抄送卡片显示:抄送人摘要,并明确“只通知,不产生待办,不影响流程判定”。 条件分支卡片显示:分支名、条件摘要或“其他情况”、优先级和该支路配置问题。长条件截断显示,悬停或展开可看完整表达式。 ### 6.3 人工审批属性抽屉 抽屉按照使用频率排序: 1. 节点名称; 2. 审批人规则; 3. 审批方式; 4. 驳回/退回策略; 5. 审批时限; 6. 审批行为和表单策略(低频项放“高级设置”)。 审批人来源使用 FMS 选择器,展示可读名称、提交稳定编码:指定用户、发起人、发起人直属领导、部门负责人、岗位、组织角色、业务字段用户、后端注册的自定义解析器。编码不可要求普通用户手填。 审批方式按 `constants.js` 中 FMS 枚举提供单人、或签、会签、串行会签、N 人通过和按比例通过;需要人数或比例时就地显示参数和即时校验。节点级转交、委托、加签、抢占、意见必填等只展示后端确实支持的选项,未接入的能力不能伪装成可生效配置。 ### 6.4 抄送属性抽屉 - 选择一名或多名用户、岗位或组织角色;卡片显示人员名称。 - 抄送不展示审批方式、驳回策略等无关选项。 - 如果 FMS 运行模型支持“允许发起人补选抄送人”,作为单独选项;否则不照搬参考项目中的开关。 ### 6.5 条件设置抽屉 - 条件字段来自当前流程绑定模块的 `s_field`;不允许手输列名、SQL 或任意表达式。 - 按字段类型提供操作符和值控件(数字、文本、枚举、人员等);保存结构化 AST。 - 支持一个条件内的 AND/OR 组合;不同分支之间按优先级互斥匹配。 - “其他情况”不编辑表达式,只说明“之前的条件均未满足时进入此分支”。 - 发起人条件、业务字段条件是否可用按 FMS 后端校验能力确定;参考实现中的旧 `columnId`、`optType` 等字段不能直接成为 FMS 契约。 ### 6.6 流程基本信息与发起范围 流程名称、编码、业务模块、触发事件、适用组织、匹配条件、生效区间和业务状态映射属于流程/绑定设置,不作为流程中的审批步骤。开始节点卡片可展示“谁可以发起”的摘要,点击后编辑对应绑定设置。 ## 7. 校验、保存和发布 - 首次编辑或点击“校验”后,所有缺少审批人、抄送人或有效条件的节点显示错误状态。 - 错误列表按流程顺序汇总,点击错误能滚动到对应分支并打开相关抽屉。 - 前端即时校验负责可理解的操作反馈;保存草稿和发布接口仍由后端校验节点、连线、规则、字段、版本和权限。 - 发布前必须再次服务端校验。校验失败时不得显示发布成功或改变版本状态。 - 已发布版本只读;修改必须进入新的草稿版本。运行中的实例继续使用原发布版本。 - “模拟”使用后端模拟能力时,展示命中的绑定、条件路径及解析后的审批人;服务未接入时清楚标注不可用,不用本地假结果冒充。 - 保存、发布必须经工作流服务;禁止通过通用 CRUD 直接写 `wf_*` 表或直接修改业务单据审批状态。 后端接口尚未接通时,页面可以先完成编辑和本地校验,但必须明确“草稿保存/发布服务未接入”,不能只在浏览器中保存后提示成功。 ## 8. FMS 前端改造建议 当前设计器已有 `WorkflowDraft`、节点卡片、属性抽屉、条件构造器和 LogicFlow 画布雏形;重构重点是改编辑结构,不是重建审批引擎。 | 现有区域 | 调整方向 | | --- | --- | | `WorkflowDesigner.vue` / `WorkflowModeTabs.vue` | 移除“流程步骤 / LogicFlow 高级画布”的双模式产品入口;流程树成为唯一主编辑视图 | | `WorkflowStepEditor.vue` | 从“只允许单链路”的编辑器改成递归流程树根视图,不能遇到分支就阻止编辑 | | `WorkflowStepCard.vue` | 保留摘要卡片职责;支持树中审批、抄送和固定节点 | | `WorkflowStepInsert.vue` | 增加条件分支入口,并统一节点间添加菜单 | | `WorkflowPropertyDrawer.vue` | 按节点类型展示审批、抄送、条件等设置;基本信息和绑定单独处理 | | `domain.js` | 新增领域图与递归 UI 树双向转换、分支插入/删除/排序、拓扑完整性检测 | | `WorkflowCanvas.vue` 及 LogicFlow 相关代码 | 不作为本次主流程编辑入口;可暂留未挂载组件,待确认不再依赖后再清理,不要为本方案继续扩展双模式 | 建议在 `designer/` 下增加职责清楚的递归组件,例如 `WorkflowTreeNode.vue` 和 `WorkflowBranchGroup.vue`。节点组件负责渲染/发出操作意图,领域操作集中放 `domain.js`,避免组件直接拼接 `edges`。 ## 9. 实施顺序 1. **锁定领域映射和能力边界**:确认 FMS 当前可执行的条件网关语义、默认出口、边优先级和分支汇合规则,不改运行表含义。 2. **先做适配与测试**:覆盖线性流程、单层分支、多节点分支、分支后公共节点、嵌套分支、默认出口、优先级、未知/不支持拓扑及加载保存往返。 3. **搭树形主视图**:实现递归分支布局、节点间添加菜单、分支加项/排序、卡片摘要、缩放和错误定位。 4. **接入节点抽屉**:复用并完善 FMS 审批人/抄送人选择器和结构化条件构造器,不复制参考项目的旧接口字段。 5. **接工作流服务**:接草稿读取/保存、校验、模拟、发布和版本查看;未实现的动作显示真实状态。 6. **移除旧交互入口**:树形设计器和现有草稿回归验证通过后,移除模式切换入口;是否删除 LogicFlow 依赖另行检查全项目引用后再做。 ## 10. 验收标准 ### 交互验收 - 初次打开能看到开始到结束的纵向流程,不要求先理解画布工具。 - 每个节点间的加号都能插入审批人、抄送人或条件分支。 - 条件分支可并列展示;每个分支内能继续增加节点和嵌套条件;分支下方的节点明确是公共后续。 - 条件分支有唯一且固定在末尾的“其他情况”路径;显式条件可调整优先级。 - 审批人/抄送人/条件设置均通过抽屉和选择器完成,卡片展示可读摘要。 - 错误列表能定位到出错节点;缩放不改变流程结构;删除/改序有明确反馈。 ### 数据验收 - 树形编辑生成的执行草稿仍是 FMS `nodes` / `edges` / `actorRules`,没有新增卡片 JSON 真相源或卡片专用表。 - 线性、条件分支、嵌套分支和分支后公共节点加载—编辑—保存—重载保持拓扑与优先级不变。 - 不支持的图结构不能被自动扁平化、丢弃或覆盖保存。 - 条件值和审批人编码使用 FMS 领域契约;展示名称不参与运行解析。 - 前端发布校验不能替代后端校验,已发布版本不可原地修改。 ## 11. 明确不做 - 不再把“线性钉钉卡片 + LogicFlow 高级模式”作为本次目标方案。 - 不把 Workflow-Vue3 的旧递归 JSON 原样写入数据库,不迁移其 `sh_set` / `sh_record` 语义。 - 不复制参考项目的源码、图片、字体图标或 Element UI 实现;只按其公开交互模式在 FMS 组件体系中实现。 - 不因为编辑器重构就新增审批人固定列、卡片顺序列或第二套审批流程表。 - 不允许树形 UI 假装支持循环、并行或任意图连接;超出本次树形拓扑的定义必须明确保护并提示。