20260904232445
This commit is contained in:
1 parent
4e167df0f0
commit
1b01a31252
19 files changed
+1099
-1013
No files matched your search
+134
-25
@@ -116,7 +116,22 @@ src/components/fms-record-picker/FmsRecordPickerModal.vue
|
||||
- 查询条件默认使用 `s_field_query`;
|
||||
- 字段标题、类型和格式使用 `s_field`。
|
||||
|
||||
动作可以另外指定展示列,但不复制一整套列表和查询配置。
|
||||
动作不新建模块,也不复制一套字段定义。它只在来源模块的基础配置上,引用并裁剪本次选择器需要的展示列和查询项。
|
||||
|
||||
动作可以配置:
|
||||
|
||||
```text
|
||||
展示列模式:inherit / explicit
|
||||
查询条件模式:inherit / explicit
|
||||
```
|
||||
|
||||
含义如下:
|
||||
|
||||
- `inherit`:沿用来源模块启用的 `s_field_view` 或 `s_field_query`;
|
||||
- `explicit`:只使用动作配置中明确引用的展示列或查询项;
|
||||
- `explicit` 且没有配置项:表示本动作明确不提供对应的展示列或用户查询项,不能再解释为“继承默认配置”。
|
||||
|
||||
动作字段配置只保存对既有配置的引用,不重新定义字段名称、类型、权限和操作符。来源模块仍然是字段定义的唯一来源。
|
||||
|
||||
## 四、单选、多选和重复选择是三件事
|
||||
|
||||
@@ -181,7 +196,7 @@ append / replace multiple + forbid + warn
|
||||
|
||||
### 查询条件到底配置在哪里
|
||||
|
||||
客户在选择器中看到并填写的查询项,配置在**来源模块**的查询配置中,也就是现有的 `s_field_query`(模块管理中的“查询”页签)。
|
||||
客户在选择器中看到并填写的查询项,基础配置仍然来自**来源模块**的 `s_field_query`(模块管理中的“查询”页签)。动作可以选择直接继承,也可以通过动作查询配置引用其中的子集。
|
||||
|
||||
例如来源模块 `bs_business_history` 的“查询”页签配置了:
|
||||
|
||||
@@ -192,7 +207,7 @@ append / replace multiple + forbid + warn
|
||||
客户:下拉选择
|
||||
```
|
||||
|
||||
打开 `FmsRecordPickerModal` 时,组件读取这个来源模块的查询配置,自动显示这些查询控件。客户填写后点击“查询”,这些条件只影响本次弹窗的数据列表。
|
||||
打开 `FmsRecordPickerModal` 时,后端先按动作的 `b_query_mode` 解析有效查询项,再返回给组件渲染。客户填写后点击“查询”,这些条件只影响本次弹窗的数据列表。
|
||||
|
||||
动作配置中的 `s_module_action_filter` 是另一回事。它保存的是动作必须带上的固定条件,客户看不到,也不能修改,例如“只能查当前客户的历史记录”。
|
||||
|
||||
@@ -209,7 +224,19 @@ s_module_action_filter 系统强制追加的固定条件
|
||||
来源模块查询条件 AND 动作固定条件
|
||||
```
|
||||
|
||||
第一版建议直接复用来源模块的 `s_field_query`,不再为每个动作单独复制一套查询字段。只有以后出现“同一个来源模块,不同动作需要显示完全不同的查询项”时,再增加动作专用查询字段配置。
|
||||
动作查询配置只引用来源模块已有的 `s_field_query` 记录,不复制字段定义或查询语义。这样同一个来源模块可以支持多个选择器动作,每个动作使用不同的查询项集合。
|
||||
|
||||
例如:
|
||||
|
||||
```text
|
||||
来源模块查询配置:业务单号、发货人、收货人、客户、发生日期、状态
|
||||
|
||||
选择历史发货人:业务单号、发货人、发生日期
|
||||
选择历史收货人:业务单号、收货人、发生日期
|
||||
选择历史费用:费用名称、发生日期、币种、状态
|
||||
```
|
||||
|
||||
动作固定条件不进入用户查询区。用于固定过滤、去重和关联的技术字段可以不显示,也不能作为用户临时查询项。
|
||||
|
||||
### 1. 动作固定条件
|
||||
|
||||
@@ -223,7 +250,7 @@ s_module_action_filter 系统强制追加的固定条件
|
||||
|
||||
### 2. 用户临时查询条件
|
||||
|
||||
这是用户在弹窗中输入的条件,例如费用名称、日期、状态、编码等。默认复用来源模块的 `s_field_query` 配置,使用和普通列表页面相同的查询控件。
|
||||
这是用户在弹窗中输入的条件,例如费用名称、日期、状态、编码等。动作使用 `inherit` 时复用来源模块的 `s_field_query`;使用 `explicit` 时只显示动作引用的查询项,控件和操作符仍由被引用的来源查询配置决定。
|
||||
|
||||
例如来源模块配置了:
|
||||
|
||||
@@ -233,7 +260,7 @@ s_module_action_filter 系统强制追加的固定条件
|
||||
币种:下拉选择
|
||||
```
|
||||
|
||||
选择器就显示这些查询项。用户点击查询后,条件和动作固定条件一起生效。
|
||||
选择器按动作的有效查询项显示这些查询控件。用户点击查询后,条件和动作固定条件一起生效。
|
||||
|
||||
### 3. 前端只传结构化条件,不传 SQL
|
||||
|
||||
@@ -345,6 +372,8 @@ b_customer_id b_customer_id
|
||||
|
||||
映射配置应从源模块和目标模块的字段元数据中选择字段,保存字段 ID,不让用户手工填写字段名。
|
||||
|
||||
字段映射不是新的字段定义。来源字段和目标字段都必须引用现有 `s_field`,字段名称、类型、可空性、写入模式和启用状态始终以 `s_field` 为准。
|
||||
|
||||
每条映射还可以配置:
|
||||
|
||||
```text
|
||||
@@ -357,6 +386,23 @@ b_customer_id b_customer_id
|
||||
|
||||
如果目标是子表,运行时根据 `s_relation` 自动补齐父 ID、临时 ID 和排序号。目标字段的只读、计算、系统字段规则仍然有效,不能通过动作配置绕过。
|
||||
|
||||
动作配置只能缩小字段范围,不能提升字段权限。运行时的有效字段按以下规则计算:
|
||||
|
||||
```text
|
||||
可展示/可查询来源字段
|
||||
= 动作引用的字段
|
||||
∩ 来源模块中存在且启用的字段
|
||||
∩ 当前用户拥有 view 权限的字段
|
||||
|
||||
可写目标字段
|
||||
= 动作映射的字段
|
||||
∩ 目标模块中存在且启用的字段
|
||||
∩ 当前用户拥有 edit 权限的字段
|
||||
∩ s_field.b_writemode 允许写入
|
||||
```
|
||||
|
||||
固定过滤字段、去重主键和关系父 ID 等技术字段可以不展示给用户,但后端只能将它们用于动作执行,不能因为动作配置而把它们作为普通可见字段返回。
|
||||
|
||||
## 七、重复选择的运行规则
|
||||
|
||||
系统需要同时考虑三种“已经选过”的数据:
|
||||
@@ -385,13 +431,13 @@ b_customer_id b_customer_id
|
||||
|
||||
## 八、动作类型
|
||||
|
||||
第一阶段只支持有限的动作类型:
|
||||
动作类型先定义为有限集合;第一阶段只落地 `copy` 和 `append`:
|
||||
|
||||
```text
|
||||
pick 选择一条记录,返回关联值
|
||||
copy 选择一条记录,复制到当前主表
|
||||
append 选择多条记录,追加到目标子表
|
||||
replace 选择多条记录,替换目标子表
|
||||
replace 选择多条记录,替换目标子表(后续阶段)
|
||||
```
|
||||
|
||||
不要一开始支持任意脚本或任意客户端函数。遇到特殊转换时,增加明确命名的转换类型或受控处理器。
|
||||
@@ -411,15 +457,20 @@ b_name 动作名称
|
||||
b_module_id 目标模块
|
||||
b_action_type pick/copy/append/replace
|
||||
b_source_module_id 来源模块
|
||||
b_target_module_id 结果写入的目标模块;写入当前主表时可等于目标模块
|
||||
b_target_relation_id 主表到目标子表的关系;写入主表时为空
|
||||
b_selection_mode single/multiple
|
||||
b_reselect_policy forbid/allow
|
||||
b_duplicate_behavior skip/warn/error
|
||||
b_target_scope main/detail
|
||||
b_dedupe_field_id 来源去重字段
|
||||
b_view_mode inherit/explicit
|
||||
b_query_mode inherit/explicit
|
||||
b_canuse
|
||||
b_xh
|
||||
```
|
||||
|
||||
`b_target_scope = main/detail` 不足以表达一个模块有多个子表,因此使用目标模块和目标关系确定写入位置。`b_view_mode` 与 `b_query_mode` 用于区分“未配置,继承来源模块”和“明确配置为空,不显示/不提供查询项”。
|
||||
|
||||
### `s_module_action_filter`
|
||||
|
||||
保存动作固定过滤条件:
|
||||
@@ -440,18 +491,32 @@ b_xh
|
||||
|
||||
### `s_module_action_column`
|
||||
|
||||
保存动作专用展示列覆盖:
|
||||
保存动作引用的展示列:
|
||||
|
||||
```text
|
||||
b_id
|
||||
b_action_id
|
||||
b_source_field_id
|
||||
b_source_field_view_id 引用来源模块的 s_field_view
|
||||
b_visible
|
||||
b_xh
|
||||
b_width_override
|
||||
```
|
||||
|
||||
动作使用 `explicit` 模式时,只显示被引用的 `s_field_view`;`inherit` 模式下直接使用来源模块的 `s_field_view`。动作不复制字段定义、字段标题或字段权限。
|
||||
|
||||
### `s_module_action_query`
|
||||
|
||||
保存动作引用的用户查询项:
|
||||
|
||||
```text
|
||||
b_id
|
||||
b_action_id
|
||||
b_source_field_query_id 引用来源模块的 s_field_query
|
||||
b_visible
|
||||
b_width
|
||||
b_xh
|
||||
```
|
||||
|
||||
没有动作列配置时,直接使用来源模块的 `s_field_view`。
|
||||
动作使用 `explicit` 模式时,只显示被引用的 `s_field_query`;`inherit` 模式下直接使用来源模块的 `s_field_query`。查询字段的类型和操作符以被引用的来源查询配置为准,第一版不在动作表中重复定义。
|
||||
|
||||
### `s_module_action_mapping`
|
||||
|
||||
@@ -470,6 +535,29 @@ b_is_dedupe_key
|
||||
b_xh
|
||||
```
|
||||
|
||||
### 动作配置与字段权限的关系
|
||||
|
||||
动作定义和权限定义分开保存:
|
||||
|
||||
```text
|
||||
s_module_action
|
||||
描述动作如何查、如何选、如何映射
|
||||
|
||||
s_power
|
||||
b_power_type = action
|
||||
描述谁可以执行这个动作
|
||||
```
|
||||
|
||||
动作编码使用目标模块编码和动作编码组成稳定身份,例如:
|
||||
|
||||
```text
|
||||
cw_business.select_history_fee
|
||||
```
|
||||
|
||||
对应的 `s_power` 动作权限使用目标模块和动作编码建立关联,操作为 `execute`。动作配置不能绕过 `s_power`,字段权限也不能被动作配置提升。后端必须同时校验动作执行权限、来源字段 `view` 权限和目标字段 `edit` 权限。
|
||||
|
||||
来源字段被停用、删除或当前用户无权查看时,动作应在配置校验或运行时被判定为无效,不能静默删掉映射项继续执行。
|
||||
|
||||
## 十、运行时流程
|
||||
|
||||
```text
|
||||
@@ -477,7 +565,7 @@ b_xh
|
||||
↓
|
||||
业务页面上的按钮打开 FmsRecordPickerModal,并传入当前表单上下文
|
||||
↓
|
||||
读取来源模块的列表列和查询配置
|
||||
解析动作的展示列模式和查询条件模式,引用来源模块配置的对应子集
|
||||
↓
|
||||
解析动作固定条件
|
||||
↓
|
||||
@@ -498,7 +586,7 @@ b_xh
|
||||
|
||||
选择器不负责保存数据库。映射结果先进入当前页面的草稿、diff 和校验流程,和手工新增的数据一样,最后统一保存。
|
||||
|
||||
建议选择确认事件返回记录或 patch,不返回 SQL:
|
||||
建议选择确认事件返回记录或 patch,不返回 SQL。客户端确认时只提交来源记录的稳定主键,后端重新读取来源记录并生成 patch:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -538,10 +626,14 @@ b_xh
|
||||
### 动作执行器(建议放在后端或独立服务层)
|
||||
|
||||
- 读取并校验动作配置;
|
||||
- 解析动作专用展示列和查询项,并与来源模块配置做一致性校验;
|
||||
- 校验用户对来源模块的访问权限;
|
||||
- 校验当前用户是否拥有动作对应的 `s_power` 执行权限;
|
||||
- 校验来源字段 `view` 权限、目标字段 `edit` 权限和字段写入模式;
|
||||
- 解析当前主表、子表、用户和日期等值来源;
|
||||
- 校验字段 ID、目标模块和操作符;
|
||||
- 生成参数化查询;
|
||||
- 根据选中的来源主键重新读取来源数据;
|
||||
- 执行去重检查和字段映射。
|
||||
|
||||
### 业务页面
|
||||
@@ -554,9 +646,12 @@ b_xh
|
||||
## 十二、安全和校验要求
|
||||
|
||||
- 来源模块必须通过当前用户权限校验;
|
||||
- 动作必须通过对应的 `s_power` `execute` 权限校验;
|
||||
- 后端不能信任前端传来的任意字段、任意 SQL 或任意脚本;
|
||||
- 过滤条件必须使用字段 ID、操作符和值的结构化表达;
|
||||
- 后端按字段类型限制可用操作符;
|
||||
- 动作展示列和查询项只能引用来源模块中存在且启用的 `s_field_view` / `s_field_query`;
|
||||
- 动作配置只能缩小来源模块字段范围,不能提升字段 `view` / `edit` 权限;
|
||||
- 映射目标必须属于目标模块或目标子模块;
|
||||
- `readOnly`、`computed`、`system` 字段的写入规则继续生效;
|
||||
- 来源字段删除或停用后,动作配置显示为无效并禁止启用;
|
||||
@@ -578,6 +673,8 @@ b_xh
|
||||
- 主表字段映射;
|
||||
- 子表追加;
|
||||
- `forbid` 和 `allow` 两种重复选择策略;
|
||||
- 动作展示列和查询条件的 `inherit / explicit` 两种模式;
|
||||
- 来源字段和目标字段权限交集校验;
|
||||
- 分页和重新打开弹窗后的已选状态。
|
||||
|
||||
### 第二阶段:增加数据库配置
|
||||
@@ -587,9 +684,10 @@ b_xh
|
||||
- `s_module_action`;
|
||||
- `s_module_action_filter`;
|
||||
- `s_module_action_column`;
|
||||
- `s_module_action_query`;
|
||||
- `s_module_action_mapping`。
|
||||
|
||||
同时增加动作配置的启用校验和无效字段提示。
|
||||
动作列和动作查询项只引用来源模块已有的 `s_field_view` / `s_field_query`,不复制字段定义。同步增加动作配置的启用校验、字段权限校验和无效字段提示。
|
||||
|
||||
### 第三阶段:迁移业务操作
|
||||
|
||||
@@ -601,19 +699,30 @@ b_xh
|
||||
4. 选择历史费用;
|
||||
5. 选择箱子或其他业务子表记录。
|
||||
|
||||
迁移完成后,删除页面中按业务名称编写的专用选择弹窗和字段匹配代码。
|
||||
`replace`、复合去重键、`OR` 条件和自定义脚本转换不作为第一阶段的必要能力。迁移完成后,删除页面中按业务名称编写的专用选择弹窗和字段匹配代码。
|
||||
|
||||
## 十四、仍需确定的事项
|
||||
## 十四、已确定和仍需确定的事项
|
||||
|
||||
- 动作按钮是否只复用模块权限,还是需要单独的动作权限;
|
||||
- `append` 追加时重复记录默认提示后跳过,还是直接阻止确认;
|
||||
- `replace` 替换时是否需要保留被替换行的来源关系;
|
||||
- 是否允许业务配置自定义去重字段组合,而不只是单个主键;
|
||||
- 特殊字段转换是否需要一个受控的转换器注册表;
|
||||
### 已确定
|
||||
|
||||
- 来源模块是数据、字段和基础查询配置的唯一来源,不为每个选择器复制模块;
|
||||
- 动作只引用并裁剪来源模块已有的 `s_field_view` / `s_field_query`;
|
||||
- 动作展示列和查询项通过 `inherit / explicit` 明确区分继承和显式空配置;
|
||||
- 字段权限由 `s_power` 的 `field/view/edit` 规则统一控制,动作配置不能提升权限;
|
||||
- 动作执行权限使用独立的 `s_power` `action/execute` 权限;
|
||||
- 第一版优先实现 `fill/copy` 和 `append`,`replace` 延后;
|
||||
- 固定过滤、去重和关系字段可以隐藏,但不能作为普通可见数据返回前端。
|
||||
|
||||
### 仍需确定
|
||||
|
||||
- `append` 追加时重复记录默认采用 `warn + skip`,还是直接阻止确认;
|
||||
- `replace` 后续是否保留被替换行的来源关系;
|
||||
- 是否允许复合去重键,而不只是单个稳定主键;
|
||||
- 特殊字段转换是否需要受控的转换器注册表;
|
||||
- 是否需要动作配置的预览和测试执行功能;
|
||||
- 来源模块是视图时,如何配置稳定主键;
|
||||
- 来源模块为视图且 `b_keyfield` 不可靠时,是否允许配置受控的复合稳定键;
|
||||
- 业务页面是否允许少量自定义动作插槽。
|
||||
|
||||
## 十五、一句话总结
|
||||
|
||||
把“历史记录选择”当成一种可配置的业务动作:配置决定查什么、怎么筛、能不能重复选、选中后写到哪里;通用选择器负责展示和选择;业务页面只接收结果并统一保存。这样既能复用现有模块元数据,也能避免页面代码里出现 SQL 拼接和隐含的字段对应关系。
|
||||
把“历史记录选择”当成一种可配置的业务动作:来源模块负责数据和字段定义,动作决定本次选择器展示哪些列、提供哪些查询项、怎么筛、能不能重复选以及选中后写到哪里;字段权限和动作执行权限由权限模型统一校验;通用选择器负责展示和选择;业务页面只接收结果并统一保存。这样无需为不同选择器复制模块,也能避免页面代码里出现 SQL 拼接和隐含的字段对应关系。
|
||||
Reference in new issue
Block a user