-
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+ onUpdate('module', v)"
+ />
+ onUpdate('fields', v)"
+ @sync="syncFields"
+ />
+ onUpdate('listConfig', v)"
+ @update-groups="onGroupsSaved"
+ />
+ onUpdate('editConfig', v)"
+ @update-groups="onGroupsSaved"
+ />
+ onUpdate('queryConfig', v)"
+ />
+ onUpdate('powers', v)"
+ />
+
+
-
-
+
+
+
+
+
diff --git a/code/fms/开发规范.md b/code/fms/开发规范.md
index 7fdd8a70..80306be1 100644
--- a/code/fms/开发规范.md
+++ b/code/fms/开发规范.md
@@ -2,6 +2,7 @@
## 一、构建与测试
+- **不要过多封装**
- 完成功能后不主动执行构建和测试。
- 只有用户明确要求时,才执行构建、测试或启动服务。
- 交付时说明本次未执行构建和测试。
@@ -27,6 +28,7 @@
- 不使用 CSS 重复实现组件已有的尺寸、状态、交互和响应式能力。
- 新增 CSS 应限制在当前组件作用域内,避免影响其他页面。
- 不需要兼容移动端,按桌面端实现即可。
+- 表格尽量使用 `fms-table` 组件(项目封装的表格组件),不重复从零实现表格能力。
## 四、变更范围
diff --git a/code/fms/新数据库结构.md b/code/fms/新数据库结构.md
index c02601ca..c10f857d 100644
--- a/code/fms/新数据库结构.md
+++ b/code/fms/新数据库结构.md
@@ -6,6 +6,7 @@
- 字段来源于数据模块配置的查询视图。系统不创建业务字段,只同步视图字段,并维护其展示、编辑、查询和权限配置。
- 页面和业务逻辑不完全元数据化。海运等复杂业务页面由 Vue 页面显式组合多个数据模块,元数据只提供 Table、Form 和 Query 配置。
- 字段基础定义、列表、编辑、查询四个职责分离;一个字段可以只参与其中任一场景。
+- 编辑规则与列表布局解耦:`b_module_field_edit` 是通用编辑配置,FmsForm 和 FmsTable 可按自身规则消费;`b_module_field_list` 只描述列表展示,不保存编辑状态。
- 模块权限控制访问,操作权限控制按钮动作;操作权限必须依赖模块访问权限。
- 表名和字段名沿用旧系统的 `b_` 风格。全部 `b_id` 使用 `bigint` 雪花 ID,返回前端时序列化为字符串。
- 布尔字段统一使用 `int`,`1` 表示是、`0` 表示否;`b_xh` 数值越小越靠前。
@@ -17,16 +18,16 @@
b_module
|-- parent_id --> b_module
|-- 1:N --------> b_module_field
- |-- 1:N --------> b_module_field_edit_group
+ |-- 1:N --------> b_module_field_group -- parent_id --> b_module_field_group
|-- 1:N --------> b_module_power ---- 1:N ----> b_user_power
`-- 1:N --------> b_user_module
b_module_field
- |-- 0:N --------> b_module_field_list -- parent_id --> b_module_field_list
- |-- 0:1 --------> b_module_field_edit
+ |-- 0:N --------> b_module_field_list -- group_id --> b_module_field_group
+ |-- 0:1 --------> b_module_field_edit -- group_id --> b_module_field_group
`-- 0:1 --------> b_module_field_query
-b_module / b_module_field / b_module_field_list / b_module_field_edit_group / b_module_power
+b_module / b_module_field / b_module_field_list / b_module_field_group / b_module_power
`-- b_i18n --> b_i18n.b_key
```
@@ -58,15 +59,15 @@ b_module / b_module_field / b_module_field_list / b_module_field_edit_group / b_
- `b_parent_id` 外键引用 `b_module.b_id`;保存服务校验父节点不形成循环。
- `b_code` 唯一,格式为 `^[a-z][a-z0-9_]{1,49}$`;`b_route` 非空时唯一。
- `directory` 不能配置 `b_route`、`b_viewtable` 或 `b_savetable`。
-- `page` 必须配置 `b_route`,用于路由、菜单和页面编排;其业务数据由页面组合的数据模块提供。
-- `data` 不能显示菜单;应配置 `b_viewtable`,保存场景再按需配置 `b_savetable` 与 `b_keyfield`。
+- `page` 必须配置 `b_route`;其业务数据由页面组合的数据模块提供。
+- `data` 不能显示菜单且不能配置 `b_route`;必须配置 `b_viewtable`,保存场景再按需配置 `b_savetable` 与 `b_keyfield`。
- `b_canmenu`、`b_canuse` 只能为 `0` 或 `1`。建议建立 `(b_parent_id, b_xh, b_id)` 索引。
## 字段来源与同步
### `dbo.b_module_field`
-保存字段的基础定义,不保存列宽、表单位置、是否显示或查询位置等场景属性。字段来自数据模块的 `b_viewtable`,并以 `(b_module_id, b_field)` 作为稳定标识。
+保存字段的基础定义。字段来自数据模块的 `b_viewtable`,并以 `(b_module_id, b_field)` 作为稳定标识;列表、编辑和查询场景属性均由独立配置表维护。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
@@ -75,19 +76,18 @@ b_module / b_module_field / b_module_field_list / b_module_field_edit_group / b_
| `b_field` | `varchar(50)` | 视图字段名 |
| `b_name` | `nvarchar(100)` | 默认字段名称,由管理员维护 |
| `b_i18n` | `varchar(150)` | 多语言键 |
-| `b_field_type` | `varchar(30)` | `string`、`text`、`number`、`date`、`datetime`、`boolean`、`select_id` 或 `select_input` |
-| `b_value` | `nvarchar(500)` | 新增时默认值 |
-| `b_dict_code` | `varchar(100)` | 字典编码;非字典字段为空 |
+| `b_type` | `varchar(30)` | 字段控件类型:`input`、`textarea`、`number`、`money`、`date`、`datetime`、`switch` 或 `select` |
+| `b_default_value` | `nvarchar(500)` | 新增记录时的默认值 |
+| `b_options` | `nvarchar(max)` | 类型专属 JSON 配置,例如选择器来源、日期格式或金额精度 |
| `b_canuse` | `int` | 是否启用 |
-| `b_remark` | `nvarchar(500)` | 字段说明 |
-| `b_inputdatetime` | `datetime` | 首次同步创建时间 |
约束:
- `b_module_id` 外键引用 `b_module.b_id`,`(b_module_id, b_field)` 唯一。
-- `b_canuse` 只能为 `0` 或 `1`。建议建立 `(b_module_id, b_canuse, b_id)` 索引。
+- `b_canuse` 只能为 `0` 或 `1`;`b_options` 非空时通过 `ISJSON` 校验。建议建立 `(b_module_id, b_canuse, b_id)` 索引。
- 字段没有 list、edit 或 query 配置记录时,不参与对应场景。
-- `select_id` 保存选项 ID;`select_input` 支持从选项中选择或直接输入文本。字典型选择器使用 `b_dict_code`;视图型选择器的来源配置保存在 `b_module_field_edit.b_editor_options`。
+- `b_type` 是展示和编辑的唯一类型来源:Table 按它渲染默认显示器,Form 或可编辑 Table 按它选择控件。
+- `select` 是否允许自由输入、选项来源、值字段和显示字段均由 `b_options` 控制。
### 视图同步规则
@@ -95,90 +95,82 @@ b_module / b_module_field / b_module_field_list / b_module_field_edit_group / b_
1. 后端校验视图名并读取列名、SQL 类型和可空性等结构信息。
2. 按列名查找同模块的 `b_module_field`;新列创建字段基础记录。
-3. 同步更新 `b_field`、`b_field_type` 和 `b_canuse`。SQL 类型映射为 `string`、`text`、`number`、`date`、`datetime`、`boolean` 等基础类型;`select_id`、`select_input` 由管理员在同步后按业务语义调整。
+3. 新字段按 SQL 类型初始化 `b_type`,例如字符串映射为 `input`、长文本映射为 `textarea`、数值映射为 `number`、日期映射为 `date` 或 `datetime`、位值映射为 `switch`。已有字段不覆盖管理员维护的 `b_type` 与 `b_options`;`select`、`money` 等业务类型由管理员按语义调整。
4. 本次视图中不存在的已有字段保留其记录和全部场景配置,但将 `b_canuse` 置为 `0`。
-5. 不覆盖人工维护的 `b_name`、`b_i18n`、`b_value`、`b_dict_code` 和 `b_remark`,不物理删除字段或场景配置。
+5. 不覆盖人工维护的 `b_name`、`b_i18n`、`b_default_value` 与 `b_options`,不物理删除字段或场景配置。
## 列表配置
### `dbo.b_module_field_list`
-控制 Table 列、显示方式和多级表头。分组节点与字段节点通过 `b_parent_id` 组成任意层级的表头树;只读列表和可编辑 Table 共用本表。
-
-| 字段 | 类型 | 说明 |
-| --- | --- | --- |
-| `b_id` | `bigint` | 雪花 ID 主键 |
-| `b_module_id` | `bigint` | 所属模块 ID |
-| `b_parent_id` | `bigint` | 上级表头分组 ID;顶层为空 |
-| `b_kind` | `varchar(20)` | `group` 或 `field` |
-| `b_field_id` | `bigint` | 字段节点关联 `b_module_field.b_id`;分组节点为空 |
-| `b_title` | `nvarchar(100)` | 分组标题或字段标题覆盖值;字段为空时使用默认字段名称 |
-| `b_i18n` | `varchar(150)` | 分组多语言键或字段标题多语言键覆盖值 |
-| `b_visible` | `int` | 是否显示,默认 `1` |
-| `b_xh` | `int` | 同一父节点下的显示顺序,默认 `0` |
-| `b_width` | `int` | 字段列宽;分组节点为空 |
-| `b_sortable` | `int` | 是否允许排序,默认 `0` |
-| `b_display_type` | `varchar(30)` | 显示器类型,例如 `text`、`money`、`date`、`datetime`、`tag`;前端按类型使用统一显示规则 |
-| `b_canedit` | `int` | 是否允许表格单元格编辑,默认 `0` |
-
-约束:
-
-- `b_module_id` 外键引用 `b_module.b_id`,`b_parent_id` 外键引用本表 `b_id`,`b_field_id` 外键引用 `b_module_field.b_id`。
-- `group` 节点必须没有 `b_field_id`、`b_width`,且 `b_canedit = 0`;`field` 节点必须有 `b_field_id`。
-- 同一字段在同一模块的列树中最多出现一次,使用非空 `b_field_id` 的过滤唯一索引约束。
-- `b_parent_id` 必须指向同模块的 `group` 节点,且不能形成循环,由保存服务校验。
-- `b_visible`、`b_sortable`、`b_canedit` 只能为 `0` 或 `1`;`b_canedit = 1` 时必须存在对应编辑规则。
-- `b_display_type` 决定显示器及其格式化规则,例如 `money`、`date`、`datetime` 均由前端按统一规则渲染。建议建立 `(b_module_id, b_parent_id, b_xh, b_id)` 索引。
-- 不保存 `level`、`colspan`、`rowspan`;前端一次加载全部节点后,按 `b_parent_id`、`b_xh` 组装嵌套 `children` 并计算表头。隐藏分组的后代不显示;没有可见字段后代的分组不渲染。
-
-示例:
-
-```text
-费用(group)
-|-- 人工费(field)
-`-- 海运费(field)
-```
-
-## 编辑配置
-
-### `dbo.b_module_field_edit`
-
-控制 Form 和可编辑 Table 的共享编辑规则,以及字段在 Form 中的布局。表单分组仅是视觉分组,不表示页签、动态页面区域或主子表关系;分组标题和多语言由独立分组表维护。
+控制列表字段列。多级表头由 `b_module_field_group` 的 `list` 分组树表达;本表不保存编辑状态。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `b_id` | `bigint` | 雪花 ID 主键 |
| `b_module_id` | `bigint` | 所属模块 ID |
| `b_field_id` | `bigint` | 关联 `b_module_field.b_id` |
-| `b_editor` | `varchar(30)` | 例如 `input`、`textarea`、`select`、`date`、`switch` |
-| `b_edit_format` | `varchar(100)` | 编辑值格式 |
-| `b_editor_options` | `nvarchar(max)` | 编辑器专属 JSON 配置 |
-| `b_required` | `int` | 是否必填,默认 `0` |
-| `b_readonly` | `int` | 是否只读,默认 `0` |
-| `b_disabled` | `int` | 是否禁用,默认 `0` |
-| `b_placeholder` | `nvarchar(200)` | 输入提示 |
-| `b_canform` | `int` | 是否进入 Form,默认 `1` |
-| `b_edit_group` | `varchar(100)` | 关联 `b_module_field_edit_group.b_code`;不分组时为空 |
-| `b_edit_xh` | `int` | 编辑区域中的全局顺序,默认 `0` |
-| `b_edit_span` | `int` | Form 栅格宽度,默认 `24`,范围 `1` 至 `24` |
+| `b_group_id` | `bigint` | 所属分组 ID;为空时为顶层列 |
+| `b_title` | `nvarchar(100)` | 字段标题覆盖值;为空时使用默认字段名称 |
+| `b_i18n` | `varchar(150)` | 字段标题多语言键覆盖值 |
+| `b_visible` | `int` | 是否显示,默认 `1` |
+| `b_xh` | `int` | 同一分组内的显示顺序,默认 `0` |
+| `b_width` | `int` | 字段列宽 |
+| `b_sortable` | `int` | 是否允许排序,默认 `0` |
约束:
-- `b_module_id` 外键引用 `b_module.b_id`,`b_field_id` 外键引用 `b_module_field.b_id`;`(b_module_id, b_field_id)` 唯一,保存服务校验字段属于同一模块。
-- `b_required`、`b_readonly`、`b_disabled`、`b_canform` 只能为 `0` 或 `1`;`b_editor_options` 非空时通过 `ISJSON` 校验。
-- 非空 `b_edit_group` 必须引用同模块的启用分组;保存服务校验模块一致性。
-- 已分组字段按所属分组的 `b_xh` 排列,组内按 `b_edit_xh` 排列;未分组字段作为末尾默认区域,按 `b_edit_xh` 排列。建议建立 `(b_module_id, b_edit_xh, b_id)` 索引。
-- `b_canform = 0` 时,编辑规则仍可由可编辑 Table 使用。
+- `b_module_id` 外键引用 `b_module.b_id`,`b_field_id` 外键引用 `b_module_field.b_id`,`b_group_id` 引用同模块的 `b_module_field_group`。
+- `b_field_id` 必填;同一字段在同一模块的列表中最多出现一次,使用 `(b_module_id, b_field_id)` 唯一约束。
+- `b_visible`、`b_sortable` 只能为 `0` 或 `1`。
+- 字段列的显示器由关联字段的 `b_type` 与 `b_options` 决定,例如 `money`、`date`、`datetime` 均由前端按统一规则渲染。建议建立 `(b_module_id, b_group_id, b_xh, b_id)` 索引。
+- 不保存 `level`、`colspan`、`rowspan`;前端加载 Table 分组树和字段列后,按分组的 `b_parent_id`、`b_xh` 组装嵌套表头。隐藏分组的后代不显示;没有可见字段后代的分组不渲染。
-### `dbo.b_module_field_edit_group`
+示例:
-保存 Form 的视觉分组标题和多语言配置。一个模块可以有多个分组,字段通过 `b_edit_group` 引用其稳定编码。
+```text
+费用(`b_module_field_group`)
+|-- 人工费(`b_module_field_list.b_group_id` 指向费用)
+`-- 海运费(`b_module_field_list.b_group_id` 指向费用)
+```
+
+## 编辑配置
+
+### `dbo.b_module_field_edit`
+
+控制字段的通用编辑属性与编辑分组。控件类型、显示规则和类型专属参数统一由 `b_module_field.b_type`、`b_options` 决定;FmsForm 与 FmsTable 自行决定何时使用本配置。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `b_id` | `bigint` | 雪花 ID 主键 |
| `b_module_id` | `bigint` | 所属模块 ID |
-| `b_code` | `varchar(100)` | 分组稳定编码,例如 `basic`、`booking` |
+| `b_field_id` | `bigint` | 关联 `b_module_field.b_id` |
+| `b_required` | `int` | 是否必填,默认 `0` |
+| `b_readonly` | `int` | 是否只读,默认 `0` |
+| `b_disabled` | `int` | 是否禁用,默认 `0` |
+| `b_group_id` | `bigint` | 所属编辑分组 ID;不分组时为空 |
+| `b_xh` | `int` | 编辑场景中的显示顺序,默认 `0` |
+
+约束:
+
+- `b_module_id` 外键引用 `b_module.b_id`,`b_field_id` 外键引用 `b_module_field.b_id`;`(b_module_id, b_field_id)` 唯一,保存服务校验字段属于同一模块。
+- `b_required`、`b_readonly`、`b_disabled` 只能为 `0` 或 `1`。
+- `b_group_id` 必须关联同模块的 `b_module_field_group`;分组为空时字段进入默认编辑区域。
+- 已分组字段按分组的 `b_xh` 排列,组内按 `b_xh` 排列;默认区域字段按 `b_xh` 排列。
+
+## 布局分组
+
+### `dbo.b_module_field_group`
+
+统一保存列表多级表头和编辑分组。分组只负责布局,不定义编辑能力;列表或编辑用途由引用它的配置表决定。
+
+被 `b_module_field_list` 引用时,分组组成同一份 FmsTable 的多级表头;被 `b_module_field_edit` 引用时,分组组成同一份编辑界面中的业务区块,例如提单、订舱、报关、备注,不代表拆分为多个 Form。
+
+| 字段 | 类型 | 说明 |
+| --- | --- | --- |
+| `b_id` | `bigint` | 雪花 ID 主键 |
+| `b_module_id` | `bigint` | 所属模块 ID |
+| `b_parent_id` | `bigint` | 上级分组 ID;顶层为空 |
| `b_title` | `nvarchar(100)` | 默认分组标题 |
| `b_i18n` | `varchar(150)` | 分组标题多语言键 |
| `b_xh` | `int` | 分组显示顺序,默认 `0` |
@@ -186,11 +178,13 @@ b_module / b_module_field / b_module_field_list / b_module_field_edit_group / b_
约束:
-- `b_module_id` 外键引用 `b_module.b_id`,`(b_module_id, b_code)` 唯一。
+- `b_module_id` 外键引用 `b_module.b_id`;`b_id` 是分组的稳定关联键。
+- `b_parent_id` 必须引用同模块的分组且不能形成循环。
+- 多级分组可用于 FmsTable 表头;FmsForm 与 FmsTable 如何消费编辑分组由各自实现决定。
- `b_canuse` 只能为 `0` 或 `1`。建议建立 `(b_module_id, b_canuse, b_xh, b_id)` 索引。
-- 无字段引用的分组不渲染;分组停用时,其关联字段不在 Form 中显示。
+- 无字段引用的分组不渲染;分组停用时,其关联字段或列不显示。
-视图型选择器的 `b_editor_options` 示例:
+视图型选择器的 `b_options` 示例:
```json
{
@@ -202,7 +196,7 @@ b_module / b_module_field / b_module_field_list / b_module_field_edit_group / b_
}
```
-`select_id` 使用 `allowInput: false` 并保存 `valueField` 的值;`select_input` 可使用 `allowInput: true` 并保存选择值或用户输入文本。视图名、值字段和标签字段均须由后端校验。
+`select` 使用 `allowInput: false` 时保存 `valueField` 的值;设为 `true` 时可保存选择值或用户输入文本。视图名、值字段和标签字段均须由后端校验。
## 查询配置
@@ -299,13 +293,13 @@ b_module / b_module_field / b_module_field_list / b_module_field_edit_group / b_
```text
海运页面 m_sea(page:路由、菜单、权限、页面编排)
-|-- 海运主单 d_sea(data:Table / Form / Query)
-|-- 费用 d_charge(data:可编辑 Table)
-|-- 订舱 d_booking(data:独立表和主键时)
-`-- 箱明细 d_container(data:可编辑 Table)
+|-- 海运主单 d_sea(data)
+|-- 费用 d_charge(data)
+|-- 订舱 d_booking(data,独立表和主键时)
+`-- 箱明细 d_container(data)
```
-若订舱字段实际保存于海运主单表,不创建 `d_booking`,而在 `d_sea` 的 Form 中用 `b_module_field_edit_group` 和 `b_edit_group` 表达视觉分组。主子表关联、加载时机、保存顺序和页面布局均由业务 Vue 页面明确实现。
+若订舱字段实际保存于海运主单表,不创建 `d_booking`,而在 `d_sea` 的编辑配置中用 `b_group_id` 和 `b_xh` 定义编辑分组与顺序,分组标题来自 `b_module_field_group`。主子表关联、加载时机、保存顺序和页面布局均由业务 Vue 页面明确实现。
## 现有字段迁移
@@ -313,19 +307,19 @@ b_module / b_module_field / b_module_field_list / b_module_field_edit_group / b_
| 当前字段 | 目标位置 |
| --- | --- |
-| `b_type` | `b_module_field.b_field_type` |
+| `b_type` | `b_module_field.b_type` |
| `b_canlist` | `b_module_field_list.b_visible` |
| `b_width` | `b_module_field_list.b_width` |
-| `b_xh` | 初始化 `b_module_field_list.b_xh`、`b_module_field_edit.b_edit_xh` 与 `b_module_field_query.b_xh` |
-| `b_canform` | `b_module_field_edit.b_canform` |
+| `b_xh` | 初始化 `b_module_field_list.b_xh`、`b_module_field_edit.b_xh` 与 `b_module_field_query.b_xh` |
+| `b_canform` | 为原 Form 字段创建 `b_module_field_edit` 记录 |
| `b_must` | `b_module_field_edit.b_required` |
| `b_readonly` | `b_module_field_edit.b_readonly` |
| `b_canquery` | 创建 `b_module_field_query` 记录 |
-| `b_value` | 保留在 `b_module_field.b_value` |
+| `b_value` | 迁移为 `b_module_field.b_default_value` |
迁移步骤:
-1. 新建 list、edit、edit_group、query 表和必要索引,新增 `b_module.b_module_type` 与 `b_module_field.b_field_type` 的兼容列。
-2. 为原有字段创建顶层 `field` 列配置;根据原 `b_canform`、`b_canquery` 创建编辑和查询配置;初始 `b_canedit = 0`。
+1. 新建 list、edit、group、query 表和必要索引,新增 `b_module.b_module_type` 与 `b_module_field.b_type` 的兼容列。
+2. 为原有字段创建列表配置;根据原 `b_canform`、`b_canquery` 初始化编辑和查询配置。
3. 前端和后端改为读取新场景表,查询不再读取 list 配置;模块类型切换为读取 `b_module_type`。
4. 完成视图同步服务并验证新结构的读写稳定后,删除旧混合列和兼容字段。