From 19c97d148f15faa869d044c5745a68a453079cd9 Mon Sep 17 00:00:00 2001 From: zlwu <704541015@qq.com> Date: Mon, 27 Jul 2026 18:17:38 +0800 Subject: [PATCH] docs(oa): add department select control design and mockup Capture the approved OA form designer dept control contract (multi/single, {id,name} path snapshot, mobile full-screen picker) and a Fresh Mint HTML demo. Co-authored-by: Cursor --- docs/mockups/oa-dept-select-demo.html | 922 ++++++++++++++++++ .../specs/2026-07-27-oa-dept-select-design.md | 202 ++++ 2 files changed, 1124 insertions(+) create mode 100644 docs/mockups/oa-dept-select-demo.html create mode 100644 docs/superpowers/specs/2026-07-27-oa-dept-select-design.md diff --git a/docs/mockups/oa-dept-select-demo.html b/docs/mockups/oa-dept-select-demo.html new file mode 100644 index 00000000..87fd5ba3 --- /dev/null +++ b/docs/mockups/oa-dept-select-demo.html @@ -0,0 +1,922 @@ + + + + + + OA · 部门选择控件 Demo(Fresh Mint) + + + +
+ + +
+ + + +
+ +

① 设计器:「2 表单设计」左侧组件库

+

「部门」出现在增强分组;拖到画布后,右侧可配标题 / 必填 / 单多选等。

+ +
+ + +
+
画布 · PC
+
+
+ + +
+
+
+ +
请输入▾
+
+
+ +
+ 中科兴皖 / 研发中心 / 前端组 + ▾ +
+
+
+ +
请输入▾
+
+
+
+
+ + +
+ +

② 发起页:运行时选择(可点选试用)

+

左侧交互;右侧同步展示将写入 form_data 的值形态(建议锁定一种契约)。

+ +
+
+

填报表单

+
+ +
+
+ 请选择部门 +
+ +
+
+ +
+ +
+

form_data 预览

+
+
+
展示文案(全路径)
+
—
+
+
+
存库值(推荐)
+
—
+
+
+
当前方案说明
+
单选:值为部门 id 字符串。
+
+
+
+ 规格草案:部门控件 type = "dept"(后端发布白名单已预留)。 + 勿存组件实例 / DOM;名称可按 id 在详情侧补全路径。 +
+
+
+
+ + + +
+
+ 选择部门 + +
+ +
+ +
+
+ + + + diff --git a/docs/superpowers/specs/2026-07-27-oa-dept-select-design.md b/docs/superpowers/specs/2026-07-27-oa-dept-select-design.md new file mode 100644 index 00000000..01dad2a8 --- /dev/null +++ b/docs/superpowers/specs/2026-07-27-oa-dept-select-design.md @@ -0,0 +1,202 @@ +# OA「部门选择」控件设计文档 + +**日期:** 2026-07-27 +**范围:** `web-admin` 审批设计器步骤 2(表单设计)+ 发起/详情运行时;`backend` 发布白名单已有 `dept`,补齐值形态校验与打印 +**状态:** 已评审待实现 + +--- + +## 1. 背景与目标 + +OA 审批「2 表单设计」需提供可拖拽的 **部门** 控件,供发起人选择本租户组织树(`sys_dept`),与钉钉式「部门」及既有规格 `docs/superpowers/specs/2026-07-14-oa-approval-dingtalk-design.md` §4.5 / §4.6 对齐。 + +当前发布字典已允许 `type: "dept"`,但设计器与运行时尚未落地自定义控件。 + +### 1.1 产品结论(已确认) + +| 项 | 结论 | +|----|------| +| 选择能力 | 默认可多选;设计器属性可改为仅单选 | +| 存值 | 单选 `{ id, name }`;多选同结构数组 | +| `name` | **全路径快照**(分隔符 ` / `) | +| 可选范围 | **任意层级**均可选(非仅末级) | +| 实现路径 | 自定义 `type=dept`(对齐关联审批四层扩展);PC 用 `el-tree-select` | +| 移动兼容 | 窄屏禁止仅依赖宽屏下拉;须全屏/半屏选择器;Schema/`form_data` 双端同一份 | + +### 1.2 非目标 + +- 行业通讯录部门 +- 用本控件结果改写审批人解析(仍用发起人部门 / `oa_role` 等既有策略) +- 本期实现小程序页面(但契约与交互必须可映射) +- 本控件「参与流程条件分支」(对象/多选不便进比较器;需要时二期单开) + +--- + +## 2. 架构 + +对齐 FormCreate / FcDesigner **四层扩展**(与「关联审批单」同路径): + +| 层 | 内容 | +|----|------| +| Runtime | `OaDeptSelect.vue`:`v-model` 为对象或对象数组 | +| FormCreate 组件注册 | `formCreate.component('dept', …)` | +| DragRule | `menu: 'main'`;`name/label` 为部门;`props.multiple` 默认 `true` | +| 双侧注册 | 主应用(发起/详情)+ `oa-fc-host`(设计器 iframe)均调用 `setupOaDeptSelect` | + +数据源:现有 `fetchDeptTree()`(本租户组织树),不另造 API。 + +``` +[设计器 DragRule] → form_schema_json.type = "dept" + ↓ +[OaDeptSelect] ← fetchDeptTree + ↓ +form_data[field] = { id, name } | { id, name }[] + ↓ +[后端发起校验] → 详情 / 打印优先展示 name 快照 +``` + +--- + +## 3. Schema 与属性 + +### 3.1 规则形态(示例) + +```json +{ + "type": "dept", + "field": "Fxxxx", + "title": "所属部门", + "info": "", + "$required": false, + "props": { + "multiple": true, + "max": null + } +} +``` + +### 3.2 设计器可配属性 + +| 属性 | 说明 | +|------|------| +| 标题 / 提示信息 / 必填 | 与现有控件一致 | +| 允许多选 | Switch,**默认 `true`**;`false` 时仅单选 | +| 最大可选数 | 可选;仅多选时生效;不填则不限制 | + +树下拉节点文案:**本级名称**;选中后输入框 / 发起页 / 详情 / 打印:**全路径**(与 `tree-path` 约定一致)。 + +--- + +## 4. `form_data` 契约(锁定) + +```ts +type DeptValueItem = { + id: string // sys_dept.id + name: string // 提交时全路径快照,如 "中科兴皖 / 研发中心 / 前端组" +} + +// 单选(props.multiple === false) +type DeptFormValueSingle = DeptValueItem | null + +// 多选(props.multiple === true,默认) +type DeptFormValueMulti = DeptValueItem[] +``` + +约束: + +- `id`、`name` 均为非空字符串。 +- **禁止**写入 DOM、组件实例、仅本级名却标注为全路径、或与 `multiple` 不一致的标量/对象混用。 +- 组织改名/调整后,历史实例 **SHALL** 仍展示提交时的 `name` 快照;不强制按 `id` 重算路径。 +- 后端 **SHALL NOT** 强制校验 `id` 仍存在于当前组织树(允许已删/历史部门快照可读)。 + +本决定更新钉钉规格 §4.6 值类型表中「部门」一行的歧义:发布锁定为 **`{ id, name }` / 数组**,不再使用裸 `string` deptId。 + +--- + +## 5. 运行时交互 + +### 5.1 PC(视口宽度 ≥ 768) + +- 使用 `el-tree-select`(或等价树选)。 +- `multiple` 跟随 `props.multiple`。 +- 触发条/标签展示全路径;多选以 chip 展示,可删除单条。 + +### 5.2 窄屏 / 设计器手机预览(宽度 < 768) + +对齐双端规格:「部门/省市区 → 移动端 **全屏或半屏选择器**,禁止依赖宽屏下拉才能选完」。 + +- 表单项为触发条(展示已选全路径或占位「请选择部门」)。 +- 点击后打开 **抽屉或全屏面板**:搜索 + 组织树 +(多选)勾选 + 取消/确定。 +- 未点「确定」前不写回 `v-model`。 +- 与 PC 共用同一 `v-model` 形态,仅交互壳不同。 + +### 5.3 只读 + +详情 / 审批页:仅展示路径文案(单选一个 `name`;多选多个 `name` 用中文顿号「、」拼接),不可打开选择器。 + +### 5.4 条件分支 + +`dept` **不**注册「参与流程条件分支」开关;`CONDITION_ELIGIBLE_TYPES` **不**包含 `dept`。 + +--- + +## 6. 校验 + +### 6.1 前端 + +- 必填:单选无值或 `null`;多选空数组 → 拦截提示。 +- 多选且配置了 `max`:达到上限不可再选并提示。 +- 窄屏面板未确认不算变更。 + +### 6.2 后端(发起 / 再次提交) + +- 按 schema 遍历 `type === "dept"`。 +- 单选:非必填允许缺省/`null`;否则须为 `{ id, name }`。 +- 多选:须为数组;每项为 `{ id, name }`;必填则 `length >= 1`;有 `max` 则 `length <= max`。 +- 发布:`ALLOWED_CONTROL_TYPES` 已含 `dept`,保持即可。 + +--- + +## 7. 打印与详情 + +- 单选:输出 `name`。 +- 多选:多个 `name` 用中文顿号「、」拼接。 +- **SHALL NOT** 将对象 JSON 原样打印到纸面。 +- 实现落点:`oa-approval-print`(及详情只读渲染)对 `type === "dept"` 特判。 + +--- + +## 8. 主要改动面 + +| 区域 | 文件(预期) | +|------|----------------| +| Runtime | `web-admin/src/components/oa-approval/OaDeptSelect.vue` | +| DragRule | `web-admin/src/utils/oa-dept-select-rule.ts` | +| 注册 | `web-admin/src/utils/oa-form-create-dept.ts`;`oa-fc-host/main.ts`;主应用 form-create 注册点 | +| 打印 | `web-admin/src/utils/oa-approval-print.ts` | +| 后端校验 | `backend/app/services/oa_publish.py` 或发起校验模块中的 form_data 校验 | +| Demo(可选) | `docs/mockups/oa-dept-select-demo.html` 与实现对齐 | + +--- + +## 9. 验收标准 + +1. 「2 表单设计」左侧组件库出现「部门」,可拖入画布;属性可关闭多选。 +2. PC:树选可用;设计器切换手机预览(或窄视口)时可用半屏/全屏选完,不必依赖宽屏下拉。 +3. 提交后 `form_data` 形态符合 §4;组织改名后旧实例仍显示快照路径。 +4. 含 `dept` 的应用可发布;未知 `type` 仍拒绝。 +5. 无该控件的旧应用行为不变。 +6. 详情与打印展示人类可读路径,不出现原始 JSON。 + +--- + +## 10. 测试建议 + +- 单元:`form_data` 形态校验(单选/多选/必填/max)。 +- 手工:设计器拖入 → 发起多选/单选 → 详情/打印;窄屏或手机预览走完选择;改部门名称后回看历史单。 + +--- + +## 11. 开放问题 + +无。若二期要做「部门字段参与条件分支」或小程序原生页,另开变更,不修改本节契约。