20260719215738
This commit is contained in:
1 parent
35aa108a34
commit
cda7f16d3a
116 files changed
+11826
-3669
No files matched your search
+100
-51
@@ -17,8 +17,9 @@
|
||||
- 页面、查询条件、SQL、数据组织、校验和普通业务流程目前主要由前端完成。
|
||||
- 当前阶段暂不重点考虑客户端直接提交查询条件和 SQL 带来的安全风险。
|
||||
- 后端通用接口完成后应尽量保持稳定,普通业务优先修改前端配置和数据库配置。
|
||||
- 文件、报表、导入、导出以及通用接口无法覆盖的功能,可以增加特殊接口。
|
||||
- 文件、报表、导入和导出等能力也应建设为稳定的平台级通用接口,后续不得为具体业务模块增加特殊接口或后端代码。
|
||||
- 新数据库启用后,前端应逐步改为只提交 `module_id` 和结构化数据,不再直接指定任意表名或 SQL。
|
||||
- `G3HY2025` 旧数据库仅用于参考表结构和业务含义,新代码只面向 `FMS` 新数据库,不保留旧表结构的运行时兼容分支。
|
||||
|
||||
## 3. 现有通用接口
|
||||
|
||||
@@ -29,48 +30,60 @@
|
||||
| `POST` | `/api/data/loaddatabysql` | 执行完整查询 SQL |
|
||||
| `POST` | `/api/data/page` | 执行分页查询 |
|
||||
| `POST` | `/api/data/saveobjt` | 多表事务保存 |
|
||||
| `GET` | `/api/data/nextid` | 获取下一个雪花 ID |
|
||||
|
||||
### 3.1 登录
|
||||
|
||||
```json
|
||||
{
|
||||
"orgid": "G3HD",
|
||||
"username": "admin",
|
||||
"userid": "admin",
|
||||
"password": "123456"
|
||||
}
|
||||
```
|
||||
|
||||
登录成功后返回登录凭证和用户信息。后续请求携带登录凭证,不再重复提交 `orgid`。
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "操作成功",
|
||||
"data": {
|
||||
"token": "<jwt>",
|
||||
"orgid": "G3HD",
|
||||
"user": {
|
||||
"id": "admin",
|
||||
"name": "管理员"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 loaddata
|
||||
|
||||
用于表或视图的普通查询,不执行分页。
|
||||
|
||||
```json
|
||||
{
|
||||
"source": "v_bs_business",
|
||||
"fields": ["b_id", "b_state", "customer_name"],
|
||||
"where": "b_state = '草拟'",
|
||||
"view_name": "v_bs_business",
|
||||
"search_columns": ["b_id", "b_state", "v_customer_company"],
|
||||
"search_condition": "b_state = '草拟'",
|
||||
"order_by": "b_id desc"
|
||||
}
|
||||
```
|
||||
|
||||
- `source` 必填,表示表名或视图名。
|
||||
- `fields` 可省略,省略时返回全部字段。
|
||||
- `where` 可省略,由前端直接拼接,不包含 `WHERE` 关键字。
|
||||
- `order_by` 可省略,不包含 `ORDER BY` 关键字。
|
||||
- `view_name` 必填,表示表名或视图名。
|
||||
- `search_columns` 可省略,省略时返回全部字段。
|
||||
- `search_condition` 可省略,由前端直接拼接,不包含 `WHERE` 关键字。
|
||||
- `order_by` 可省略,只支持一个排序字段及可选的 `ASC` 或 `DESC`。
|
||||
|
||||
成功响应:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"code": 0,
|
||||
"message": "ok",
|
||||
"data": {
|
||||
"rows": [],
|
||||
"row_count": 0
|
||||
}
|
||||
"message": "操作成功",
|
||||
"data": []
|
||||
}
|
||||
```
|
||||
|
||||
@@ -84,7 +97,7 @@
|
||||
}
|
||||
```
|
||||
|
||||
成功响应与 `loaddata` 相同。
|
||||
成功响应与 `loaddata` 相同,`data` 直接为查询结果数组。
|
||||
|
||||
### 3.4 page
|
||||
|
||||
@@ -92,26 +105,29 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"sql": "select * from v_bs_business where b_state = '草拟'",
|
||||
"view_name": "v_bs_business",
|
||||
"search_columns": ["b_id", "b_state", "v_customer_company"],
|
||||
"search_condition": "b_state = '草拟'",
|
||||
"order_by": "b_id desc",
|
||||
"page_no": 1,
|
||||
"page_size": 20
|
||||
}
|
||||
```
|
||||
|
||||
- `sql` 必填,不包含分页语句。
|
||||
- `order_by` 必填,用于保证分页顺序稳定。
|
||||
- `view_name` 必填,表示分页查询使用的表或视图名称。
|
||||
- `search_columns` 可省略,省略时返回全部字段。
|
||||
- `search_condition` 可省略,由前端直接拼接,不包含 `WHERE` 关键字。
|
||||
- `order_by` 必填,用于保证分页顺序稳定;支持使用逗号分隔多个查询结果字段。
|
||||
- `page_no` 从 1 开始,默认值为 `1`。
|
||||
- `page_size` 默认值为 `20`。
|
||||
- 后端负责生成分页 SQL 和计算总记录数。
|
||||
- SQL Server 2022 使用 `COUNT_BIG(*) OVER()` 与 `OFFSET/FETCH` 在一次查询中返回当前页和总记录数;仅页码越界且当前页为空时补充执行总数查询。
|
||||
|
||||
成功响应:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"code": 0,
|
||||
"message": "ok",
|
||||
"message": "操作成功",
|
||||
"data": {
|
||||
"rows": [],
|
||||
"row_count": 0,
|
||||
@@ -168,7 +184,6 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"code": 0,
|
||||
"message": "保存成功",
|
||||
"data": null
|
||||
@@ -179,7 +194,6 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"code": 2001,
|
||||
"message": "保存失败",
|
||||
"data": {
|
||||
@@ -190,6 +204,18 @@
|
||||
}
|
||||
```
|
||||
|
||||
### 3.6 nextid
|
||||
|
||||
无请求体。成功时返回一个雪花 ID:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "操作成功",
|
||||
"data": 1946123456789012345
|
||||
}
|
||||
```
|
||||
|
||||
## 4. 统一约定
|
||||
|
||||
- JavaScript 和 Java 内部函数、方法及变量使用小驼峰命名法。
|
||||
@@ -198,11 +224,12 @@
|
||||
- API 路径使用全小写名称,JSON 多单词字段使用 `snake_case`。
|
||||
- `code = 0` 表示成功,非零值表示失败。
|
||||
- 前端根据 `code` 生成 `success` 字段,`code = 0` 时 `success = true`。
|
||||
- 查询结果统一放在 `data.rows` 中,没有数据时返回空数组。
|
||||
- `loaddata` 和 `loaddatabysql` 的查询结果直接放在 `data` 数组中;`page` 的分页记录放在 `data.rows` 中。
|
||||
- 过渡期查询条件和 SQL 由前端拼接,不使用参数占位符。
|
||||
- 不增加功能相同但名称不同的接口。
|
||||
- 不使用 `V2`、`V3`、`new`、`old`、`test` 或 `bak` 等临时名称。
|
||||
- 接口发生不兼容升级时,统一通过 `/api/v2` 等版本路径升级。
|
||||
- 前端和后端代码修改完成后默认不执行构建或测试命令,只进行静态检查;仅在用户明确要求时运行构建或测试。
|
||||
|
||||
## 5. 新数据库重构方案
|
||||
|
||||
@@ -213,10 +240,12 @@
|
||||
- 所有业务页面、页面布局、按钮、标签页、弹窗和业务流程仍由前端手工开发。
|
||||
- 模块配置只服务于通用 Table 和 Form 组件,不根据配置自动生成完整页面、路由或业务流程。
|
||||
- Table 根据模块配置渲染列、格式、查询项和排序;Form 根据模块配置渲染字段、控件、校验和分组。
|
||||
- 模块定义查询对象、保存对象、主键、字段配置和保存策略。
|
||||
- 模块定义查询对象、保存对象、可选业务主键和字段配置。
|
||||
- 前端只提交 `module_id`、结构化查询条件和待保存数据。
|
||||
- 后端根据模块配置解析允许访问的对象和字段,并使用参数化 SQL。
|
||||
- 通用保存负责简单单表模块,复杂业务由明确的业务处理器完成。
|
||||
- 单表和主子表保存都复用 `saveobjt`;手写页面负责组织多张表的变更,后端在一个事务中统一提交或回滚。
|
||||
- 后端只保留稳定的通用接口,不为模块分别新增查询、新增、修改、删除接口或处理器代码。
|
||||
- 复杂业务优先通过手写页面、数据库约束和通用事务保存组合实现,不建立模块处理器注册与分派机制。
|
||||
- 不将全部业务逻辑塞入配置表或动态 SQL。
|
||||
|
||||
### 5.2 数据库版本与基础规范
|
||||
@@ -225,7 +254,7 @@
|
||||
- 继续采用一个机构对应一个独立业务数据库的隔离方式,业务表不重复保存 `orgid`。
|
||||
- 技术主键统一使用雪花 ID,数据库类型为 `bigint`。主表主键固定为 `b_id`,子表主键固定为 `subid`。
|
||||
- 中文和多语言文本使用 `nvarchar`,长文本使用 `nvarchar(max)`,不使用 `text`。
|
||||
- 布尔值使用 `bit`,不再使用字符串形式的 `0`、`1`、空字符串或 `NULL` 表示多种状态。
|
||||
- 标志和状态字段使用 `tinyint` 等整数类型,不使用 `bit` 或字符串类型。二态字段仍以数字 `0`、`1` 表示,业务需要时允许扩展为 `2`、`3`、`4` 等状态;Java 端按数字处理,不映射为 `Boolean`。
|
||||
- 时间字段使用 `datetime2`。
|
||||
- 金额、单价、数量、汇率和税率不强制统一精度,根据每个字段的业务含义分别定义 `decimal` 的精度和小数位数。
|
||||
- 迁移旧字段时保留原有精度;新增字段必须在需求或表结构中明确精度,不使用 `float` 代替精确金额。
|
||||
@@ -237,7 +266,7 @@
|
||||
|
||||
- 新数据库的所有业务表、配置表和视图统一创建在 `dbo` 下,不创建其他 Schema。
|
||||
- 领域划分继续使用现有表名前缀,避免增加对象名称和通用接口的复杂度。
|
||||
- 模块配置保存数据库对象名称时统一按 `dbo.<对象名>` 处理,例如 `dbo.bs_business`、`dbo.cw_bill` 和 `dbo.v_bs_business`。
|
||||
- 模块配置中的数据库对象只保存裸对象名,不保存 `dbo.` 或其他架构前缀,例如 `bs_business`、`cw_bill` 和 `v_bs_business`。
|
||||
|
||||
| 表名前缀 | 用途 |
|
||||
| --- | --- |
|
||||
@@ -262,8 +291,9 @@
|
||||
| `dbo.s_module_group` | Form 分组子表,字段使用 `mx_` 前缀 |
|
||||
| `dbo.s_option_source` | 下拉框和字典数据源主表 |
|
||||
| `dbo.s_option_item` | 固定选项子表,字段使用 `mx_` 前缀 |
|
||||
| `dbo.s_function_node` | 统一功能树,组织目录、页面、分组和模块位置 |
|
||||
|
||||
菜单、角色和权限仍可使用独立系统表,但不属于 Table/Form 渲染配置。主子页面关系由手写页面负责组织,第一阶段不需要通过配置表生成。
|
||||
角色和权限仍使用独立系统表,不属于 Table/Form 渲染配置。菜单是功能树中 `b_show_in_menu = 1` 的目录和页面节点投影,页面节点可以直接绑定主模块;隐藏子模块可以挂在页面或其他模块下。主子页面关系仍由手写页面负责组织,功能树不自动生成页面或 Tab。
|
||||
|
||||
### 5.5 模块定义
|
||||
|
||||
@@ -275,15 +305,13 @@
|
||||
| `b_name` | 模块名称 |
|
||||
| `b_query_object` | 查询表或稳定查询视图 |
|
||||
| `b_save_object` | 保存目标表,只读模块允许为空 |
|
||||
| `b_key_field` | 保存对象主键字段 |
|
||||
| `b_key_strategy` | `snowflake`、`identity` 或 `manual` |
|
||||
| `b_save_mode` | `generic`、`custom` 或 `readonly` |
|
||||
| `b_handler_code` | 自定义处理器标识,通用模块为空 |
|
||||
| `b_key_field` | 系统主键字段,平台内部使用,普通主表固定为 `b_id` |
|
||||
| `b_business_key_field` | 可选业务主键字段,例如业务单号 |
|
||||
| `b_default_order` | 默认排序 |
|
||||
| `b_enabled` | 是否启用 |
|
||||
| `b_sort_order` | 模块排序 |
|
||||
|
||||
查询对象与保存对象必须分开:查询视图负责组合展示数据,保存表负责持久化可写字段。
|
||||
查询对象与保存对象必须分开:查询视图负责组合展示数据,保存表负责持久化可写字段。系统主键固定由后端生成雪花 ID,不在配置页面重复设置;业务主键是带唯一约束的业务字段,例如 `HY20270601`,通过 `b_business_key_field` 标识但不代替系统主键。
|
||||
|
||||
### 5.6 模块字段配置
|
||||
|
||||
@@ -294,14 +322,14 @@
|
||||
| 主键与归属 | `subid`、`mx_module_id` |
|
||||
| 字段映射 | `mx_field_code`、`mx_query_field`、`mx_save_field`、`mx_caption` |
|
||||
| 列表显示 | `mx_list_visible`、`mx_list_order`、`mx_list_width`、`mx_sortable`、`mx_display_format` |
|
||||
| 查询设置 | `mx_searchable`、`mx_search_order`、`mx_search_operator` |
|
||||
| 查询设置 | `mx_searchable`、`mx_search_order` |
|
||||
| 表单编辑 | `mx_form_visible`、`mx_form_group_code`、`mx_form_order`、`mx_form_span`、`mx_editable`、`mx_required`、`mx_component_type` |
|
||||
| 数据来源 | `mx_option_source_id`、`mx_default_rule`、`mx_validation_rule` |
|
||||
|
||||
- `mx_field_code` 是模块对前端暴露的稳定字段名。
|
||||
- `mx_query_field` 对应查询对象返回的字段。
|
||||
- `mx_save_field` 对应保存表字段,计算字段和只读字段可以为空。
|
||||
- `mx_search_operator` 使用受控枚举,例如 `eq`、`like`、`between` 或 `in`。
|
||||
- 字段配置不保存固定查询操作符。高级查询运行时根据字段类型提供 `eq`、`like`、`between`、`in` 等合法操作符,由用户为每条条件选择。
|
||||
- 主要配置使用明确字段保存,只有少量不稳定的组件扩展属性才考虑使用 JSON。
|
||||
|
||||
### 5.7 表单分组与选项来源
|
||||
@@ -312,9 +340,29 @@
|
||||
- 没有分组的字段放入默认分组,简单表单不强制配置分组数据。
|
||||
- 固定下拉选项保存在 `dbo.s_option_item`。
|
||||
- 数据库字典选项通过 `dbo.s_option_source` 指定允许查询的对象、值字段、显示字段和排序字段。
|
||||
- 复杂选项通过 `b_handler_code` 交给后端处理,不在配置表保存任意可执行 SQL。
|
||||
- 非固定、非模块查询的复杂选项由手写页面组件负责,不在配置表保存任意可执行 SQL,也不增加后端选项处理器。
|
||||
|
||||
### 5.8 通用组件与手写页面的边界
|
||||
### 5.8 功能树、菜单与模块
|
||||
|
||||
`dbo.s_function_node` 是技术管理和业务菜单共用的功能结构,不是页面生成配置。节点类型固定为 `directory`、`page`、`group` 和 `module`:
|
||||
|
||||
| 节点类型 | 用途 |
|
||||
| --- | --- |
|
||||
| `directory` | 业务域或功能目录,可以显示在菜单中 |
|
||||
| `page` | 已注册的手写页面,可以配置路由并显示在菜单中 |
|
||||
| `group` | 页面内部的技术分组,只在配置管理中显示 |
|
||||
| `module` | 指向一个 `s_module`,只在配置管理中显示 |
|
||||
|
||||
- 功能节点使用 `b_parent_id` 形成树,并包含 `b_name`、`b_page_code`、`b_module_id`、`b_route`、`b_icon`、`b_show_in_menu`、`b_enabled` 和 `b_sort_order`。
|
||||
- `module` 节点必须指定 `b_module_id`;`page` 节点也可以直接绑定主模块,同一个模块允许被多个功能节点引用。
|
||||
- `b_show_in_menu` 只允许用于 `directory` 和 `page` 节点。菜单隐藏不代表模块停用,也不代替权限判断。
|
||||
- 功能树中的模块父子关系只用于技术人员定位和分类,不定义保存事务、主子表外键或业务流程。
|
||||
- 页面和 Tab 继续手写。功能树只帮助定位模块和投影菜单,不根据树节点自动生成组件。
|
||||
- 迁移期间,功能树中的可见目录和页面按节点编码或路由与静态菜单合并;未登记菜单继续保留,完成全部路由核对后再移除静态回退。
|
||||
|
||||
模块管理页面左侧按功能树展示完整路径,并提供“未归档模块”虚拟节点。搜索至少匹配功能节点名称、模块编码、模块名称、查询对象和保存对象,结果必须保留祖先路径。左侧可以分别显示或隐藏模块节点和菜单节点;页面支持直接维护目录、页面、模块绑定和隐藏子模块位置。
|
||||
|
||||
### 5.9 通用组件与手写页面的边界
|
||||
|
||||
| 层级 | 负责内容 |
|
||||
| --- | --- |
|
||||
@@ -350,7 +398,7 @@
|
||||
- `ModuleForm` 负责渲染、收集数据和校验,但不自动决定保存时机;页面验证业务条件后再调用保存。
|
||||
- 特殊控件和复杂区域可以通过插槽由页面自行实现,不要求全部配置化。
|
||||
|
||||
### 5.9 查询与保存边界
|
||||
### 5.10 查询与保存边界
|
||||
|
||||
模块化后的推荐调用关系:
|
||||
|
||||
@@ -367,12 +415,11 @@ module_id
|
||||
- 前端不再提交任意 `view_name`、`table`、`key_field` 或完整 SQL。
|
||||
- 查询条件使用结构化格式提交,字段和操作符必须来自模块配置白名单。
|
||||
- 雪花 ID 由后端保存流程生成,不依赖前端提前申请。
|
||||
- `b_save_mode = generic` 只适用于基础资料等简单单表模块。
|
||||
- `b_save_mode = readonly` 用于报表、统计和日志查询。
|
||||
- `b_save_mode = custom` 用于业务单、费用、账单、发票等涉及主子表、状态流转和业务校验的模块。
|
||||
- 自定义处理器仍通过统一模块接口调用,不为每个页面随意增加不同形式的接口。
|
||||
- 配置 `b_save_object` 的模块可以参与通用保存,未配置保存对象的模块只读。
|
||||
- 手写主子页面可以将多张表的新增、修改和删除一次提交给 `saveobjt`,整个请求使用同一事务。
|
||||
- 后端不按模块编码分派自定义处理器,也不为具体页面增加特殊保存接口。
|
||||
|
||||
### 5.10 业务表设计原则
|
||||
### 5.11 业务表设计原则
|
||||
|
||||
- 每张业务表必须定义真实主键:主表固定使用 `b_id`,子表固定使用 `subid`。
|
||||
- 主表普通字段使用 `b_` 前缀,子表普通字段使用 `mx_` 前缀。
|
||||
@@ -381,20 +428,22 @@ module_id
|
||||
- 唯一性、非空、默认值和可校验的状态范围优先使用数据库约束保证。
|
||||
- 不使用空字符串同时表达未知、未填写和数值零。
|
||||
- 重要且允许多人编辑的业务表可以增加 `b_row_version` 或 `mx_row_version`,用于乐观锁控制。
|
||||
- 创建人、修改人和时间字段按业务审计要求添加,不由通用保存接口无条件补充。
|
||||
- 创建人、创建时间、修改人和修改时间字段仅在业务确有审计需求时添加,不作为所有表的固定字段;例如 `b_user` 不添加这些字段。
|
||||
- 删除策略根据业务确定;财务和审批数据通常使用作废或状态流转,不直接物理删除。
|
||||
|
||||
### 5.11 权限原则
|
||||
### 5.12 权限原则
|
||||
|
||||
- 权限至少控制模块的查看、新增、修改、删除和导出操作。
|
||||
- 菜单与模块分离,同一个模块可以出现在不同菜单位置,也可以作为隐藏子模块使用。
|
||||
- 菜单是功能树可见目录和页面节点的投影;页面菜单可以绑定模块,后续权限和多语言都以菜单节点为入口扩展。
|
||||
- 后端必须根据登录用户和 `module_id` 校验权限,不能只依赖前端隐藏按钮。
|
||||
- 字段级权限仅在确有业务需求时增加,第一阶段不提前复杂化。
|
||||
- `g3soft` 是内置超级管理员账号,初始密码为空。超级管理员身份由固定账号名识别,不在 `b_user` 中增加超级管理员或隐藏标志字段。
|
||||
- 普通 SQL 允许直接查询物理表 `dbo.b_user`,但数据库行级安全策略必须自动排除 `g3soft`;只有认证流程可以在当前数据库连接内临时读取该账号,且查询结束后必须立即清除临时权限。
|
||||
|
||||
### 5.12 重构实施顺序
|
||||
### 5.13 重构实施顺序
|
||||
|
||||
1. 确定数据库版本、字段命名、表名前缀和主键策略,所有对象固定使用 `dbo`。
|
||||
2. 建立模块、模块字段、表单分组和选项来源等最小配置表。
|
||||
1. 确定数据库版本、字段命名和表名前缀;系统主键固定使用雪花 ID,业务主键使用独立唯一业务字段。
|
||||
2. 建立模块、功能树、模块字段、表单分组和选项来源等最小配置表。
|
||||
3. 先实现一个简单基础资料页面,验证 `ModuleTable`、`ModuleForm`、通用查询和单表保存。
|
||||
4. 手工实现一个业务主子页面,验证组件组合、事务和自定义保存。
|
||||
5. 实现一个只读报表模块,验证查询、分页和导出边界。
|
||||
|
||||
Reference in new issue
Block a user