2026-07-14-oa-approval-dingtalk-design.md 29 KB

OA 审批模块设计文档(钉钉交互 · Fresh Mint 皮肤)

日期: 2026-07-14
状态: 已批准(实现计划见 docs/superpowers/plans/2026-07-14-oa-approval-dingtalk.md)
界面模式: 对标钉钉「OA审批」;视觉遵循 docs/web-admin-ui-spec-fresh-mint.md
建设方案: 方案 2 — 前端借用开源设计器能力改造,后端 Python 自研引擎

决策记录:

  • 独立「OA审批」模块,V1 暂不对接细胞存储等业务工单
  • 交互完全对齐钉钉 OA 审批(四步配置 + 审批中心办理)
  • 皮肤使用本系统 Fresh Mint(主色 #10b981),不照搬钉钉蓝
  • 引擎必须用 Python;现有未使用工作流可整套按钉钉模型重做
  • 表单底座:FormCreate 或 VForm3(实现计划中择一)
  • 流程设计器:AntFlow 式竖向树重写进本仓,废弃 AntV X6
  • V1 含:公式、数据联动、关联审批、附件上传;不含 AI 与其它复杂能力(见范围)
  • 附件走现有对象存储(MinIO)上传链路;表单字段与发起/详情展示均须支持多附件
  • 审批人不复用 sys_role:另建独立「工作流角色」;动态审批人含「发起人部门负责人」「发起人的主管」;「总经理 / 董事长」等为预置工作流角色(全局成员,非按发起人部门变化)
  • 发起人的主管:无直属主管时默认回退为发起人部门负责人(可在高级设置关闭该回退)
  • 表单双端:form_schema_json 为唯一真相;Web 管理端先交付填报/审批;控件与交互须可适配移动端,为后续小程序/H5 复用同一 Schema(见 §4.6)

取代关系: 本设计取代 docs/superpowers/specs/2026-05-13-workflow-module-design.md 作为后续实现权威;旧 wf_* / X6 路径标记废弃。


1. 目标与范围

1.1 目标

在 zkxw 的 web-admin + Python backend 中交付独立的钉钉式审批能力:管理员可配置审批应用(基础设置 / 表单设计 / 流程设计 / 高级设置),全员可在审批中心发起与办理。

1.2 V1 包含

能力 说明
审批分组与应用列表 类似钉钉模板管理入口
四步配置向导 基础设置 → 表单设计 → 流程设计 → 高级设置 → 发布
表单控件(V1 清单) 见 §4.5;按钉钉控件库裁剪,排除 AI/手写签名/通讯录人员类/身份证等
附件上传 「附件」控件;发起/详情可上传、预览、下载、删除;存储 MinIO(见 §4.3)
公式、数据联动 「计算公式」控件 + 字段级联动;后端权威求值
关联审批 「关联审批单」控件;详情可跳转;不自动串子流程
竖向流程树 发起人、审批人、抄送人、条件分支、结束;中间「+」插入
工作流角色 独立于 sys_role:含自定义角色 + 预置角色(总经理、董事长等,见 §3.3)
审批人策略 指定成员、工作流角色(含预置)、发起人部门负责人、发起人的主管、发起人自选;或签 / 会签
高级设置(子集) 撤销、审批人去重、意见是否必填、允许加签;无直属主管时回退部门负责人(默认开)
审批中心 发起、待处理、已处理、我发起的、抄送我的、详情(Web 先做)
表单双端适配 设计器 PC/手机预览;Schema 与控件语义可复用到移动端(见 §4.6);V1 移动端运行时可为占位/二期,但控件不得绑死仅 PC 组件
租户隔离与版本锁定 发布版本;实例绑定发起时版本

1.3 V1 不包含

  • 全部 AI 能力(含表单 AI 控件)
  • 发票 / 客户等业务控件
  • 打印模板、审批结束后的自动化任务
  • 手写签名、限时提醒、子流程
  • 身份证、联系人、外部联系人、行业通讯录部门(按产品确认不做)
  • 与现有业务工单(协议、出库等)对接
  • 用 sys_role(菜单/数据权限角色)作为审批人解析来源
  • 钉钉增强区未纳入 V1 的控件:明细/表格、地点、评分、级联/分类(见 §4.5「二期」)

1.4 非目标

  • 引入 Java / .NET 工作流运行时作为生产引擎
  • 迁移旧 wf_* 历史数据(当前未使用,可放弃)
  • 将「所有部门主管」做成一个静态工作流角色来代替动态部门负责人(错误模型,V1 禁止作为实现路径)

2. 整体架构

web-admin · 「OA审批」独立模块
├── 审批管理(配置)
│   ├── 应用列表 / 分组
│   ├── 工作流角色管理(独立于系统角色)
│   └── 四步向导
│       ├── 基础设置(自研)
│       ├── 表单设计(FormCreate/VForm3 改造 + Mint)
│       ├── 流程设计(AntFlow 风格树改造 + Mint)
│       └── 高级设置(自研,V1 子集)
└── 审批中心(办理)
    ├── 发起(模板列表 → 填单)
    ├── 待处理 / 已处理 / 我发起的 / 抄送我的
    └── 详情(表单回显 + 进度 + 关联审批)

backend Python · oa_approval 子系统
├── 定义层:应用、版本、分组、工作流角色、发布校验
├── 运行时:发起、任务、条件、公式、联动、关联、审批人解析、高级设置生效
└── 数据:oa_* 表(见第 3 节)

边界:

  • 配置产物统一为 JSON,由后端校验并持久化
  • 前端设计器不执行不可信脚本;公式仅允许受控表达式 AST / 白名单函数
  • sys_role 只负责菜单/数据权限;审批人解析只读 oa_role* 与组织(sys_dept / 用户部门),不读 sys_role 成员
  • 旧 backend/app/**/workflow* 与 web-admin/src/views/system/workflow/** 不再演进,菜单隐藏或提示迁移

3. 数据模型与版本

所有表遵循工程公共字段规范:id → 业务字段 → tenant_no … → del_flag。

表名 用途
oa_app_group 审批分组
oa_app 审批应用(图标、名称、说明、发起范围、管理员范围等)
oa_app_version 版本:form_schema_json、flow_tree_json、advanced_settings_json、status=draft|published、version_no、is_latest_published
oa_role 工作流角色(与 sys_role 无关):名称、编码、role_kind=custom|preset、备注、启用状态
oa_role_user 工作流角色成员:oa_role_id + user_id
oa_instance 实例:app_id、app_version_id、form_data_json、status、发起人、initiator_dept_id 等
(组织补齐) sys_user.supervisor_user_id(或等价):直属主管,供「发起人的主管」解析;sys_dept.leader_user_id(或等价):部门负责人稳定关联用户
oa_task 任务:实例、节点 key、类型(approval/cc)、处理人、状态、意见
oa_relation 关联审批:from_instance_id、to_instance_id、可选控件 field_key

3.1 版本规则

  1. 编辑只写入草稿版本(或从已发布克隆出新草稿)。
  2. 「发布」校验通过后,该版本变为 published,并对新发起生效。
  3. 实例创建时绑定 app_version_id;此后改应用不影响已发起单据。
  4. 公式与数据联动配置保存在 form_schema_json 字段属性内。
  5. 高级设置保存在 advanced_settings_json,由任务 API 读取。

3.2 JSON 约定(概念)

  • form_schema_json: 控件树 + 每字段 props(标题、必填、公式、联动规则、关联审批过滤等)
  • flow_tree_json: 钉钉式节点树(非 BPMN);节点含 type、name、approverConfig、conditionGroups、children 等
  • approverConfig.assigneeType(概念枚举,V1 全量支持):
    • users — 指定成员(user_id 列表)
    • oa_roles — 指定工作流角色(oa_role_id / 预置编码,运行时展开成员;含总经理、董事长)
    • dept_leader — 发起人部门负责人(动态)
    • direct_supervisor — 发起人的主管(动态,读发起人直属主管)
    • initiator_select — 发起人自选
  • advanced_settings_json: 撤销、去重、意见、加签等开关与参数

具体字段级 schema 在实现计划中固化,并提供前后端 TypeScript / Pydantic 镜像类型。

3.3 审批人机制对照(V1 必做)

机制 配置侧文案(建议) 用途 是否按发起人变化
sys_role (不出现在流程选人里) 菜单 / 数据权限 否;审批引擎不读取
oa_role 自定义 工作流角色 如「财务审批」「法务审批」 否;展开 oa_role_user
oa_role 预置 总经理 / 董事长 等 公司级特殊岗位,一人或少数人 否;全局同一批人
dept_leader 发起人部门负责人 审「部门头」 是(按发起人部门)
direct_supervisor 发起人的主管 审「直属上级」 是(按发起人本人)
users / initiator_select 指定成员 / 发起人自选 定点人或发起时点人 视配置

禁止:把「所有部门负责人」或「所有主管」收成一个静态角色,来冒充 dept_leader / direct_supervisor。

预置工作流角色(SHALL)

租户初始化(或模块首次启用)时种子写入,编码固定、不可删、可改成员与显示名备注:

预置编码 默认名称 说明
GM 总经理 节点可选「工作流角色 → 总经理」
CHAIRMAN 董事长 节点可选「工作流角色 → 董事长」
  • role_kind=preset;管理员只维护成员,不可删除预置行。
  • 后续若再加「副总经理」等,以同样方式扩预置表/种子,不引入第三套角色体系。
  • 流程设计器中预置角色与自定义角色分组合展示,避免和动态项混淆。

dept_leader 解析(发起人部门负责人)

  1. 取实例 initiator_dept_id(发起时写入;多部门时按发起页选定,默认主部门)。
  2. 查该部门 leader_user_id(须稳定关联 sys_user.id,见 §9)。
  3. 无有效用户 → 创建任务失败,明确错误(不可静默跳过)。

direct_supervisor 解析(发起人的主管)

与「部门负责人」语义分离:主管是人对人的汇报关系,不一定等于所在部门负责人。

  1. V1 SHALL 为用户补齐直属主管字段(建议 sys_user.supervisor_user_id),在用户管理中可维护。
  2. 运行时优先取发起人的 supervisor_user_id(有效且未停用)。
  3. 回退(默认开启):若直属主管为空或无效 → 按 dept_leader 规则解析发起人部门负责人。
    • 开关落在应用版本 advanced_settings_json(建议键名 supervisorFallbackToDeptLeader,默认 true);关闭后主管缺失则创建任务失败并提示「请维护直属主管或部门负责人」。
    • 发生回退时,任务详情/审批进度上可标注来源为「部门负责人(主管回退)」,避免误以为配了直属主管。
  4. 若解析结果等于发起人本人(配错数据),去重规则生效前亦应报错或按高级设置「发起人=审批人自动通过」处理。

4. 前端 UI 设计

4.1 菜单结构(建议)

OA审批
├── 审批管理          → 应用列表 / 进入四步配置
├── 工作流角色        → oa_role 维护与成员绑定(不进系统角色菜单)
├── 发起审批          → 按分组展示可发起模板
├── 待处理
├── 已处理
├── 我发起的
└── 抄送我的

详情不单独挂菜单:从列表进入路由 /oa-approval/instances/:id(名称以实现时路由表为准)。

4.2 配置 · 四步(对齐钉钉截图交互)

  1. 基础设置: 图标、表单名称(≤50)、所在分组、表单说明(≤100)、谁可发起(全部 / 指定成员)、表单管理员(全部 OA 管理员 / 指定)。
  2. 表单设计: 左控件库 / 中画布(PC · 手机切换)/ 右属性面板;顶栏预览、发布;扩展公式、数据联动、关联审批、附件控件。
  3. 流程设计: 竖向居中树;节点卡片色系用 Mint 语义色区分类型(非钉钉蓝橙硬抄,但需类型可辨);节点间「+」插入;缩放控件可选。审批人/抄送人配置面板 V1 必提供(对齐钉钉常见项):
    • 指定成员
    • 工作流角色(自定义 + 预置:总经理、董事长)
    • 发起人部门负责人
    • 发起人的主管
    • 发起人自选
    • 或签 / 会签
  4. 高级设置: 左子菜单 + 右配置区;V1 实现「高级流程设置」内撤销 / 去重 / 意见 / 加签 / 无直属主管时回退部门负责人(默认开启);AI、打印模板等菜单可灰显「二期」。

UI Token:按钮、标签、步骤高亮使用 Fresh Mint;布局密度与信息架构对齐钉钉,不混用小程序 #0a9f6d。

模式索引:实现前在 docs/web-admin-ui-pattern-index.md / OpenSpec ui-conventions 登记(可沿用或扩展 P24)。

4.3 附件上传(SHALL)

对齐钉钉「附件」控件能力,并遵循本仓 ui-conventions 附件上传卡片化布局与 architecture-conventions 对象存储约定:

项 要求
设计器 控件库提供「附件」;属性至少支持:标题、是否必填、允许的文件类型(可选)、最大个数、单文件大小上限提示
发起 / 编辑填报 选择文件后立即上传(复用现有 fetchUploadAttachment 或等价 admin 上传 API);上传触发区与已传文件卡片同一行;支持预览 / 下载 / 删除
详情 / 审批页 只读展示附件列表,可预览、下载;审批人默认不可改发起人已传附件(除非后续扩展「可编辑字段」权限,V1 不做)
存储 MinIO 对象存储;form_data_json 中该字段存 URL 列表(多个以逗号分隔 URL,与现有附件字段惯例一致)
校验 必填时无附件不可提交;类型/个数超限前端拦截并提示,后端发起接口再次校验

权威 UI 参考:ProtocolFormDialog.vue「协议附件」卡片交互;色与尺寸跟 Fresh Mint,不自造第二套上传样式。

4.4 办理中心(对齐钉钉办理侧)

页面 行为
发起 模板宫格/分组 → 填单(含附件即时上传)→(发起人自选时)选人 → 提交
待处理 列表 → 详情:表单只读(附件可预览下载)+ 同意/拒绝/意见/加签 + 进度时间轴
已处理 列表 → 详情只读
我发起的 列表 → 详情;按高级设置允许撤销
抄送我的 列表 → 详情只读知会
详情 表单回显、进度、关联审批跳转

列表页遵循 web-admin 标准列表骨架(筛选 / 工具栏 / 表格 / 分页);详情可用抽屉或独立页,优先信息结构清晰。

4.5 表单控件清单(V1,对齐钉钉裁剪)

对照钉钉 OA「表单设计」左侧控件库;本次做 / 不做如下。

本次做(设计器左侧须出现)

分组 控件 说明
布局 分栏 两列等布局
基础 单行输入框
基础 多行输入框
基础 数字输入框
基础 单选框
基础 多选框
基础 日期
基础 日期区间
基础 说明文字 只读提示
基础 电话 手机号等,可校验格式
增强 图片 上传图片
增强 金额 金额录入(千分位等按现有金额组件习惯)
增强 附件 MinIO;见 §4.3
增强 部门 选本系统组织树(非行业通讯录)
增强 省市区 省/市/区级联
增强 计算公式 与字段公式能力一致
增强 关联审批单 见关联审批

字段属性侧:必填、标题、提示文字、默认值;以及已定的数据联动配置(不单独占控件位)。

本次不做(钉钉有,明确排除)

控件 原因
AI 控件 产品排除
手写签名 产品排除 / 复杂项
身份证 产品排除
联系人 产品排除
外部联系人 产品排除
行业通讯录部门 产品排除(用本系统「部门」代替组织选择)

二期(钉钉有,暂不进 V1)

明细/表格、地点、评分、级联/分类(非省市区)。若业务急需可单项加开,不默认出现在 V1 控件库。

4.6 Web / 移动端兼容(SHALL)

产品意图:同一审批应用须能在 Web 端与移动端 发起、填写、审批查看;兼容性是一等约束,不是「以后再说的样式问题」。

配置只做一次(Web 设计器);表达式层(Schema + form_data + 校验 + 引擎)两端共用;各端只负责自家 UI 皮肤与交互壳。

4.6.1 兼容性契约(必须同时满足)

# 契约 要求
C1 同一 Schema Web / 移动只消费同一份 form_schema_json;禁止「Web 一份、手机再配一份」
C2 同一 form_data 字段值的 JSON 形状、类型两端一致;任一端提交的数据另一端必须能回显与再编辑(权限允许时)
C3 同一后端校验 必填、格式、附件个数、公式/联动结果以服务端为准;移动端不得绕过
C4 同一控件字典 每个控件有稳定 type(如 input/textarea/number/radio/checkbox/date/dateRange/html/phone/image/money/attachment/dept/region/formula/relatedApproval/column);禁止仅存在于 FormCreate 内部的未登记 type 进已发布版本
C5 布局可降级 column(分栏)在宽度 < 768(或手机预览)时 必须 降为单列;Schema 可带 layout.mobile 提示,但缺省行为已定
C6 无端锁定依赖 Schema / form_data 禁止 出现:DOM 引用、Element Plus 组件实例、仅浏览器 File 对象、本地绝对路径;附件只存可访问 URL
C7 API 共用 发起/详情/待办等走同一套 /api/admin/oa-approval/*(或后续为小程序增加的同语义网关);移动端不另造业务存储

4.6.2 form_data 值类型约定(兼容核心)

两端写入/读取必须遵循(实现计划落成 TypeScript + Pydantic 镜像):

控件 JSON 值形态 说明
单行/多行/说明/电话 string
数字/金额 number 或可解析数字字符串(发布时锁定一种,全局一致) 两端展示格式可不同,存储一致
单选 string(选项 value)
多选 string[]
日期 string(YYYY-MM-DD)
日期区间 { start: string, end: string }
图片/附件 string(多个 URL 英文逗号拼接,与现有附件惯例一致)
部门 string(deptId)或 { id, name }(发布时锁定一种) 回显名可由端补全
省市区 string[] 或 { province, city, district }(锁定一种)
关联审批单 string(instanceId)或 string[]
计算公式 与所引用字段同类型;只读展示 以服务端计算结果为准

选项类控件的 options[].value / label 必须是纯 JSON 可序列化数据,禁止函数。

4.6.3 交互兼容(各端可不同壳,语义相同)

能力 Web 移动端
文本/数字/金额/电话 Element 输入框 uni-app input;键盘类型匹配(number/tel)
单选/多选 radio/checkbox radio/checkbox 或行动面板,值仍走 C2
日期/区间 日期面板 picker / 日历弹层
部门/省市区 下拉树/级联 全屏或半屏选择器(禁止依赖宽屏下拉才能选完)
图片/附件 卡片上传 + 预览 相册/相机 + 预览;上传同一 MinIO API
分栏 多列 grid 自动单列
触达 常规 可点区域建议 ≥44×44
皮肤 Fresh Mint 三墙 Token;禁止混用主色

4.6.4 设计器与验收

  • 表单设计步骤 必须 提供 PC / 手机(375)预览;发布前建议在手机预览下过一遍全部 V1 控件。
  • 控件字典与值类型表作为 发布校验 的一部分:未知 type 或违反值形态约定的草稿不可发布。
  • 兼容性验收:同一实例用 Web 发起填写 → 移动端打开详情字段完整;或移动端填写 → Web 审批详情完整(移动运行时上线后执行;V1 至少用手机预览 + 契约单测/字典校验保障)。

4.6.5 交付分期(不降低兼容标准)

阶段 交付 兼容要求
V1 Web 配置 + Web 办理;控件字典、值类型、手机预览、服务端校验全部到位 Schema/form_data 已按双端契约实现,不得留下只能 Web 跑的结构
移动端运行时(可紧随或并行立项) 小程序/H5:发起、待办、详情渲染器 只加渲染器与路由,不改编排模型

不做:为移动端复制第二套表单配置;「仅 PC / 仅手机可见」字段(除非另开需求)。


5. 后端运行时

5.1 发起

  1. 校验发起人是否在应用「谁可发起」范围内
  2. 加载最新 published 版本(或指定版本策略,默认最新已发布)
  3. 校验 form_data(含附件必填、URL 合法性、个数上限);执行公式与数据联动(服务端权威)
  4. 写入 oa_instance,绑定版本
  5. 写入关联审批 oa_relation(若有)
  6. 从流程树推进:解析审批人 → 创建 oa_task

5.2 任务推进

  • 审批节点:或签 / 会签聚合
  • 条件分支:使用表单字段 + 系统变量(如发起人部门)满足则走对应分支
  • 抄送:生成知会类任务(或只记抄送关系,V1 需在待办「抄送我的」可见);抄送人策略与审批人策略同源四类(成员 / 工作流角色 / 部门负责人 / 自选)
  • 结束:实例 completed / rejected(拒绝 = 整单结束;打回 = 同实例退回重提,见 2026-07-15-oa-approval-progress-timeline-design.md。原「V1 不做复杂回退」表述已废止,打回按该文档分阶段 P1 落地)

5.3 审批人解析(SHALL)

引擎按节点 approverConfig.assigneeType 解析处理人集合,不得查询 sys_role / sys_user_role:

assigneeType 解析逻辑
users 直接使用配置的 user_ids(租户内有效用户)
oa_roles 查 oa_role_user 展开成员并去重(含预置 GM / CHAIRMAN)
dept_leader 按 §3.3 从发起人部门解析部门负责人
direct_supervisor 按 §3.3:先直属主管,缺省则默认回退部门负责人(高级设置可关)
initiator_select 使用发起时提交的自选人列表

空集合:创建任务前失败并返回可读错误(除非高级设置未来定义「审批人为空」策略;V1 默认失败)。

示例(验收用):

  • 请假节点 = dept_leader:部门 A 张三发起 → A 负责人待办;部门 B 李四发起 → B 负责人待办。
  • 报销二级 = direct_supervisor:指向张三的 supervisor_user_id,与是否部门负责人无关。
  • 重大事项末节点 = oa_roles + GM / CHAIRMAN:无论谁发起,均由绑定的总经理/董事长处理。

5.4 公式与数据联动

  • 仅支持受控表达式(字段引用、四则、常用函数如 IF/SUM 等白名单)
  • 发起页可即时预览;提交与关键写操作必须以服务端结果为准
  • 求值失败返回明确错误,禁止静默写空

5.5 关联审批

  • 控件选择本租户内、当前用户有权查看的实例
  • 持久化到 oa_relation
  • 详情页展示并跳转;V1 不因关联自动发起新流程

5.6 高级设置生效

在对应 API 中读取实例绑定版本的 advanced_settings_json:撤销窗口、去重、意见必填、加签开关、supervisorFallbackToDeptLeader(默认 true)。

5.7 工作流角色管理

  • 自定义角色:CRUD 名称/编码、启用停用、绑定/解绑用户
  • 预置角色(总经理、董事长):仅维护成员与显示名,禁止删除;role_code 固定为 GM / CHAIRMAN
  • 流程设计器下拉只列出本租户启用的 oa_role(预置置顶分组)
  • 删除或停用已被已发布流程引用的自定义角色:V1 允许停用但运行时成员为空则报错;硬删除前须提示引用(实现计划细化)

5.8 发布校验(SHALL)

发布前必须通过:

  • 表单至少一个可填字段
  • 流程树从发起人可达结束
  • 每个条件分支组有完整出线
  • 审批节点审批人策略合法:users / oa_roles 引用非空,或 dept_leader / direct_supervisor / initiator_select 已明确选择
  • 引用预置角色时角色存在且启用(成员可在运行时再校验非空)

6. 权限

场景 规则
编辑应用 / 工作流角色 具备 OA 审批管理类系统菜单权限的用户(仍用 sys_role 控制能否进入配置台);表单管理员可编对应应用
看到并发起模板 「谁可发起」为全部,或命中指定成员
处理待办 仅任务指派人
看详情 发起人、任务参与人(审批/抄送)、表单管理员、系统管理员(租户内)
租户 所有读写带当前用户 tenant_no,不信任客户端租户覆盖

说明:进菜单用 sys_role,批给谁用 oa_role / dept_leader / 指定人 —— 两套职责分离。数据权限与多角色并集语义遵循现有 permission-conventions(仅作用于是否能访问配置/列表等系统能力)。


7. API 轮廓(前缀建议)

注册于 app/api/__init__.py 与 app/main.py,走现有 admin 鉴权 / 加密 / 审计中间件。

  • GET/POST /api/admin/oa-approval/groups
  • GET/POST/PUT /api/admin/oa-approval/apps
  • GET/PUT .../apps/{id}/draft(三份 JSON + 基础信息)
  • POST .../apps/{id}/publish
  • GET/POST/PUT/DELETE .../oa-roles(工作流角色)
  • PUT .../oa-roles/{id}/users(成员绑定)
  • GET .../templates(可发起列表)
  • POST .../instances(发起)
  • GET .../tasks/pending|done|mine|cc
  • GET .../instances/{id}
  • POST .../tasks/{id}/approve|reject|add-sign|withdraw

具体路径与 schema 在实现计划中展开。


8. 旧工作流处置

项 动作
菜单 system/workflow/* 隐藏或跳转提示「请使用 OA审批」
wf_* 表 保留库表不影响上线;后续迭代删除
FlowDesigner.vue (X6) 停止维护
OpenSpec workflow-conventions 后续独立变更修订,对齐本设计的钉钉模型措辞

9. 风险与开放点

风险 / 开放点 处理
FormCreate vs VForm3 选型 实现计划第 0 步做短 spike(许可证、Element Plus 亲和、公式扩展成本)后锁定
公式引擎安全性 白名单 AST,禁止 eval 任意代码
关联审批权限过滤 必须复用详情可见性规则,防越权点选
开源设计器 UI 与 Mint 冲突 仅复用交互与数据结构思想,样式统一走本项目 Token
与需求 §2.1.11 措辞 需求原文写「配置角色 / SQL 模式」;本设计以独立 oa_role + dept_leader 覆盖同等场景,不采用 SQL 任意语句,避免注入面;引擎语言仍为 Python
sys_dept.leader 与 user_id 部门页已按用户选择负责人,但列类型历史为字符串;V1 必须补齐稳定的 leader_user_id(或等价)以便 dept_leader 解析
用户无直属主管字段 V1 必须增加 sys_user.supervisor_user_id(或等价)并在用户管理可维护,否则「发起人的主管」无法落地
总经理/董事长人数 预置角色允许多成员时按节点或签/会签执行;通常各绑 1 人

10. 成功标准

  1. 管理员可在 Fresh Mint 皮肤下,用钉钉式四步发布一个「请假」类应用(含条件分支与抄送)。
  2. 员工可发起、审批、在「我发起的/抄送我的」看到记录。
  3. 公式与数据联动在提交后结果正确且不可被前端篡改绕过。
  4. 关联审批可选择并跳转详情。
  5. 带附件控件的应用可发起并上传文件;详情可预览/下载;文件落在 MinIO。
    5b. 表单设计器可切换 PC/手机预览;form_schema_json 控件类型可映射到未来移动端渲染(无端绑定死结)。
  6. 工作流角色(含预置总经理/董事长)可维护成员并在节点选用;引擎不依赖 sys_role。
  7. 「发起人部门负责人」:部门 A 张三 → A 负责人;部门 B 李四 → B 负责人。
  8. 「发起人的主管」:有直属主管则待办落主管;无主管时(默认回退开)落部门负责人,详情可辨认回退来源;关闭回退后无主管则失败提示。
  9. 节点选用预置「总经理」「董事长」时,任意发起人均由对应角色成员审批。
  10. 旧 X6 工作流不再作为主路径出现在菜单中。

11. 参考材料

  • 用户提供的钉钉 OA 审批截图(基础设置 / 表单设计 / 流程设计 / 高级设置)
  • docs/中科兴皖需求V0.3.md §2.1.11
  • openspec/changes/zkxw-engineering-standards/specs/workflow-conventions/spec.md(将后续修订)
  • docs/web-admin-ui-spec-fresh-mint.md
  • 旧设计:docs/superpowers/specs/2026-05-13-workflow-module-design.md(废弃主路径)