|
|
# OA「choice」类型字段说明与数据供给
|
|
|
|
|
|
本文先说明 OA 模块里 **choice** 相关字段类型的含义(用普通人能懂的话),再说明在「选择事前流程」弹窗里,这类字段的数据从哪里来、如何展示。
|
|
|
|
|
|
---
|
|
|
|
|
|
## 一、OA 里「choice」到底是什么意思?
|
|
|
|
|
|
在 OA 的**流程表单设计**里,配置字段时有两种和「选择」有关的类型,最终在库里都存成 `type = choice`,靠另一个字段 `multiple` 区分:
|
|
|
|
|
|
| 配置时选的类型 | 界面上叫法 | 实际含义(人话) | 存库后 |
|
|
|
|----------------|------------|------------------|--------|
|
|
|
| **choice** | **人员选择** | 从系统用户名单里**选人**,可多选。例如「经办人」「参与人」。选项固定为「用户」,不能改成别的。 | `type=choice`,`multiple=10`,`selection_model=App\Models\User` |
|
|
|
| **choices** | **多选** | 从某一类**数据**里勾选多项。例如部门、项目、预算来源等。具体选项来自「下拉数据」配置的模型,或「数据选项」里手写的列表。 | 保存时被改成 `type=choice`,`multiple=1`,`selection_model` 按配置来 |
|
|
|
|
|
|
所以:
|
|
|
|
|
|
- **「人员选择」**:专门用来选人的,只能选用户,可多选。
|
|
|
- **「多选」**:通用多选,选什么是配置决定的(用户、部门、项目等),可多选。
|
|
|
|
|
|
两种在系统里都叫 **choice 类型**,只是「人员选择」和「多选」的配置不同。
|
|
|
|
|
|
---
|
|
|
|
|
|
## 二、选项从哪里来?(数据供给,人话版)
|
|
|
|
|
|
**无论是「人员选择」还是「多选」,选项列表都是同一条链路:**
|
|
|
|
|
|
1. 配置里有一个 **「下拉数据」**(即 `selection_model`),表示:从哪个**数据表/模型**拉选项。
|
|
|
- 人员选择:固定为用户表(`App\Models\User`)。
|
|
|
- 多选:在表单设计里选,比如用户、部门、项目等。
|
|
|
2. 前端调用接口:**根据「下拉数据」去要选项列表**。
|
|
|
接口:`GET /oa/flow/selection-options?selection_model=xxx`,
|
|
|
后端按这个模型查数据,返回 `[{id, value, label, name}, ...]`。
|
|
|
3. 用户填表时**选中的是 id**;存库时,多选一般存成 **一串 id**:
|
|
|
- 有的地方用 `|` 分隔,如 `123|456|789`;
|
|
|
- 有的地方用 `,` 分隔,如 `123,456,789`;
|
|
|
- 也可能是数组 `[123, 456, 789]`。
|
|
|
|
|
|
**总结**:
|
|
|
选项 = 按「下拉数据」从系统里查出来的列表;
|
|
|
用户选的是 id;存的是多个 id 拼成的一串或数组。展示时,再用 id 去选项列表里找对应的「名称」来显示。
|
|
|
|
|
|
---
|
|
|
|
|
|
## 三、在「选择事前流程」弹窗里,choice 列怎么回事?
|
|
|
|
|
|
弹窗里流程列表的**列**,有一部分来自 OA 流程模型的「列表展示字段」。如果某列是 **choice 类型**(即「人员选择」或「多选」),逻辑应该是:
|
|
|
|
|
|
- **选项**:和上面一样,按 `selection_model` 调 `getSelectionOptions` 拿选项列表。
|
|
|
- **展示**:每个格子里存的是 id(或 `id1|id2`、`id1,id2`),应当查选项列表转成「张三、李四」这类名称再显示。
|
|
|
|
|
|
但当前 **PreApprovalFlowPicker** 组件里:
|
|
|
|
|
|
- 加载选项时,只处理了 `select`、`radio`,**没有单独处理 `choice`**。
|
|
|
所以,如果某一列**仅是 choice**(没有同列的 select/radio 共用同一个 selection_model),这根列**不会去拉选项**。
|
|
|
- 格式化展示时,也只处理了 `select`、`radio`,**没有 `choice` 分支**。
|
|
|
结果就是:**直接显示原始存值**(例如 `123|456` 或 `123,456`),不会变成「张三、李四」。
|
|
|
|
|
|
因此:
|
|
|
**从设计上**,choice 的选项和数据供给与 select/radio 一样,都是 `selection_model` → 选项接口;
|
|
|
**从实现上**,弹窗里的 choice 列目前没有按「多选 + 选项映射」完整做,所以会看到一串 id 而不是人名或名称。
|
|
|
|
|
|
---
|
|
|
|
|
|
## 四、若要让 choice 列正常显示「名称」
|
|
|
|
|
|
需要至少做两件事:
|
|
|
|
|
|
1. **拉选项**:在加载列表列配置时,把 `choice` 也当作「有 `selection_model` 就要拉选项」的类型,和 select/radio 一起调 `getSelectionOptions`。
|
|
|
2. **展示时按多选解析**:
|
|
|
- 把单元格里的值解析成多个 id(支持 `|`、`,`、数组等);
|
|
|
- 用选项列表把每个 id 转成对应的 label/name;
|
|
|
- 用顿号或逗号拼接后显示,例如:「张三、李四、王五」。
|
|
|
|
|
|
这样,**choice 类型在「选择事前流程」弹窗里的数据供给和展示**就与 OA 的设计一致了,普通用户看到的是可读的「名称」而不是 id 串。
|
|
|
|
|
|
---
|
|
|
|
|
|
## 五、相关代码与接口(给开发看)
|
|
|
|
|
|
- OA 字段配置与保存:`backend/Modules/Oa/resources/views/admin/custom-model/set-fields.blade.php`(`choice` / `choices` 的隐藏、保存逻辑)。
|
|
|
- 选项接口:`GET /oa/flow/selection-options`,`FlowController::getSelectionOptions`;前端 `oaFlowAPI.getSelectionOptions(selection_model)`。
|
|
|
- 弹窗列表与格式化:`PreApprovalFlowPicker.vue` 的 `loadSubFormFieldsAndOptions`、`formatFieldValue`;可选参考 `ProcessQuery.vue` 里对 choice/choices 的 `parseChoiceValueToIds` 及多选展示逻辑。
|