20261007220117
This commit is contained in:
1 parent
9217b3fa42
commit
8b1ec67609
275 files changed
+20026
-49299
No files matched your search
@@ -0,0 +1,447 @@
|
||||
# FMS 新系统核心架构实施计划 V1.0
|
||||
|
||||
> 文档版本:V1.0
|
||||
> 编制日期:2026-09-30
|
||||
> 适用范围:FMS/ERP 新系统第一阶段核心架构重构
|
||||
> 执行方式:由多个 AI 按任务卡顺序执行,人负责最终取舍和验收
|
||||
|
||||
## 1. 计划目标
|
||||
|
||||
本计划用于指导其他 AI 实现 FMS 新系统第一阶段核心架构。
|
||||
|
||||
第一阶段只解决以下问题:
|
||||
|
||||
- SQL Server 数据库如何迁移和版本化;
|
||||
- 租户数据库如何连接和路由;
|
||||
- 用户、公司、组织、仓库和账簿如何形成统一上下文;
|
||||
- 业务域如何组织自己的表、SQL、服务、接口和页面;
|
||||
- SQL 如何成为查询、报表和数据处理的主要实现;
|
||||
- 简单基础资料如何使用通用 CRUD;
|
||||
- 核心业务如何使用专用 SQL 和业务处理器;
|
||||
- 如何用一个完整业务域验证架构。
|
||||
|
||||
第一阶段不实现完整 ERP,也不建设通用低代码平台。
|
||||
|
||||
## 2. 已确定的架构约束
|
||||
|
||||
其他 AI 执行所有任务时必须遵守以下约束:
|
||||
|
||||
1. SQL Server 是第一阶段唯一数据库目标。
|
||||
2. 一个租户对应一个数据库,租户库内不使用 `tenant_id` 做日常业务过滤。
|
||||
3. 业务域代码包是代码组织中心。
|
||||
4. 真实业务表和 SQL 视图是事实来源。
|
||||
5. SQL 文件是查询、报表和数据处理的主要实现。
|
||||
6. 业务代码负责业务动作、事务和复杂业务规则。
|
||||
7. 页面配置只负责表现和少量参数。
|
||||
8. 不做全量 EAV,不做运行时任意生成业务表。
|
||||
9. 通用 CRUD 只用于简单基础资料,不作为核心业务默认实现。
|
||||
10. 工作流负责流程编排,库存、财务和结算动作必须由业务处理器完成。
|
||||
11. 第一阶段不引入通用配置版本引擎、通用公式引擎和通用规则解释器。
|
||||
12. 内部开发人员可以直接维护 SQL,不增加 SQL 安全沙箱、ORM 替代层或复杂 SQL DSL。
|
||||
13. 所有新代码必须遵守统一目录、命名和 SQL 文件风格。
|
||||
|
||||
## 3. 阶段依赖
|
||||
|
||||
```text
|
||||
T0 架构基线和代码规范
|
||||
↓
|
||||
T1 SQL Migration 和数据库运行时
|
||||
↓
|
||||
T2 租户路由和业务上下文
|
||||
↓
|
||||
T3 系统基础数据和权限
|
||||
↓
|
||||
T4 业务域模板和 SQL 调用约定
|
||||
↓
|
||||
T5 客户或产品示例业务域
|
||||
↓
|
||||
T6 工作流、审计和多语言接入
|
||||
↓
|
||||
T7 第一阶段验收和旧设计迁移清单
|
||||
```
|
||||
|
||||
T0 到 T4 必须顺序完成。T5 完成后,T6 可以拆分给不同 AI,但最终必须统一接口和风格。
|
||||
|
||||
## 4. 任务 T0:架构基线和代码规范
|
||||
|
||||
### 4.1 目标
|
||||
|
||||
把新架构的原则转成开发人员和 AI 都能执行的规则。
|
||||
|
||||
### 4.2 工作内容
|
||||
|
||||
- 阅读并理解以下文档:
|
||||
- `ERP动态配置多租户多公司多语言需求分析.md`;
|
||||
- `FMS新系统核心表结构设计.md`;
|
||||
- `FMS新系统核心架构设计.md`。
|
||||
- 确定 SQL Server 版本和连接方式;
|
||||
- 确定数据库迁移目录和文件命名;
|
||||
- 确定业务域目录结构;
|
||||
- 确定表名、字段名、索引、主键和时间字段规范;
|
||||
- 确定 SQL 文件参数和返回结果规范;
|
||||
- 明确哪些旧设计暂时不迁移。
|
||||
|
||||
### 4.3 输出物
|
||||
|
||||
```text
|
||||
开发规范补充文档
|
||||
SQL Migration 目录
|
||||
业务域目录模板
|
||||
SQL 文件示例
|
||||
架构决策记录
|
||||
```
|
||||
|
||||
### 4.4 验收标准
|
||||
|
||||
- 新增一个业务域时不需要重新发明目录结构;
|
||||
- SQL 文件可以被数据库工具独立执行和验证;
|
||||
- 不存在同时使用两套字段命名和 SQL 组织方式的说明;
|
||||
- 其他 AI 可以只读本阶段输出物开始后续工作。
|
||||
|
||||
## 5. 任务 T1:SQL Migration 和数据库运行时
|
||||
|
||||
### 5.1 目标
|
||||
|
||||
让每个租户数据库可以可靠地初始化、升级和记录结构版本。
|
||||
|
||||
### 5.2 工作内容
|
||||
|
||||
- 创建迁移记录表;
|
||||
- 实现迁移文件扫描和顺序执行;
|
||||
- 实现重复执行判断;
|
||||
- 记录迁移名称、版本、checksum、执行时间和结果;
|
||||
- 支持初始化新租户数据库;
|
||||
- 支持租户数据库版本查询;
|
||||
- 补充失败迁移的人工处理方式。
|
||||
|
||||
### 5.3 Migration 规则
|
||||
|
||||
```text
|
||||
V001__create_core_tables.sql
|
||||
V002__create_company_tables.sql
|
||||
V003__create_audit_tables.sql
|
||||
```
|
||||
|
||||
Migration 可以包含建表、改表、索引、视图、约束和必要的数据回填。
|
||||
|
||||
Migration 不负责页面布局和用户偏好,也不作为通用配置表使用。
|
||||
|
||||
### 5.4 验收标准
|
||||
|
||||
- 空数据库可以从零初始化;
|
||||
- 已执行的迁移不会重复执行;
|
||||
- 迁移失败时可以明确定位文件和错误;
|
||||
- 两个租户数据库可以独立升级;
|
||||
- 应用启动时可以读取数据库结构版本。
|
||||
|
||||
## 6. 任务 T2:租户路由和业务上下文
|
||||
|
||||
### 6.1 目标
|
||||
|
||||
建立统一的数据库连接、租户识别和请求上下文,不让业务域自行处理这些基础问题。
|
||||
|
||||
### 6.2 工作内容
|
||||
|
||||
- 定义 `TenantRegistry` 接口;
|
||||
- 首期使用配置文件实现租户注册;
|
||||
- 实现租户数据库连接创建和复用;
|
||||
- 实现请求级数据库连接选择;
|
||||
- 实现请求级业务上下文;
|
||||
- 请求结束后清理上下文;
|
||||
- 记录当前租户、用户、公司和请求编号。
|
||||
|
||||
### 6.3 上下文结构
|
||||
|
||||
```text
|
||||
tenant_code
|
||||
user_id
|
||||
company_id
|
||||
organization_id
|
||||
warehouse_id
|
||||
ledger_id
|
||||
language
|
||||
timezone
|
||||
currency
|
||||
request_id
|
||||
```
|
||||
|
||||
### 6.4 验收标准
|
||||
|
||||
- 同一个请求内所有业务 SQL 使用同一个租户数据库;
|
||||
- 业务域不需要自己读取租户配置文件;
|
||||
- 用户可以切换授权公司并重新建立上下文;
|
||||
- 上下文不会泄漏到下一个请求;
|
||||
- 日志可以定位租户、用户、公司和请求。
|
||||
|
||||
## 7. 任务 T3:系统基础数据和权限
|
||||
|
||||
### 7.1 目标
|
||||
|
||||
建立所有业务域依赖的用户、角色、公司、组织、仓库和账簿。
|
||||
|
||||
### 7.2 第一批表
|
||||
|
||||
```text
|
||||
s_user
|
||||
s_role
|
||||
s_user_role
|
||||
s_role_permission
|
||||
s_role_data_scope
|
||||
s_company
|
||||
s_organization
|
||||
s_warehouse
|
||||
s_ledger
|
||||
s_user_company
|
||||
s_user_organization
|
||||
s_user_warehouse
|
||||
s_user_ledger
|
||||
```
|
||||
|
||||
### 7.3 权限范围
|
||||
|
||||
首期只实现:
|
||||
|
||||
- 用户可用公司;
|
||||
- 用户可用组织;
|
||||
- 用户可用仓库;
|
||||
- 模块访问权限;
|
||||
- 业务动作权限;
|
||||
- 全部、指定公司、本组织、本组织及下级、本人和指定仓库等简单数据范围。
|
||||
|
||||
不实现角色继承、拒绝权限和通用权限表达式。
|
||||
|
||||
### 7.4 验收标准
|
||||
|
||||
- 一个用户可以属于多个公司;
|
||||
- 一个用户可以在不同公司拥有不同角色;
|
||||
- 公司、组织、仓库和账簿不会混用编码;
|
||||
- 权限查询可以使用 SQL 完成;
|
||||
- 所有业务查询可以取得当前公司上下文。
|
||||
|
||||
## 8. 任务 T4:业务域模板和 SQL 调用约定
|
||||
|
||||
### 8.1 目标
|
||||
|
||||
建立所有业务域共同遵守的实现模板,解决“一个文件一个风格”的问题。
|
||||
|
||||
### 8.2 业务域模板
|
||||
|
||||
```text
|
||||
domains/<domain_code>/
|
||||
├── migration/
|
||||
├── sql/
|
||||
├── repository/
|
||||
├── service/
|
||||
├── api/
|
||||
├── page/
|
||||
└── i18n/
|
||||
```
|
||||
|
||||
### 8.3 SQL 文件命名
|
||||
|
||||
```text
|
||||
<object>_list.sql
|
||||
<object>_detail.sql
|
||||
<object>_save.sql
|
||||
<object>_<action>.sql
|
||||
<object>_report.sql
|
||||
```
|
||||
|
||||
### 8.4 访问约定
|
||||
|
||||
- 查询由 repository 调用 SQL;
|
||||
- 保存由 repository 调用保存 SQL或 service 组织多条 SQL;
|
||||
- 业务动作由 service 作为唯一入口;
|
||||
- 页面只调用 API;
|
||||
- 业务域不直接修改另一个业务域的内部表;
|
||||
- 复杂业务必须有明确事务边界;
|
||||
- 简单资料才允许使用通用 CRUD。
|
||||
|
||||
### 8.5 验收标准
|
||||
|
||||
- 创建新业务域只需复制模板并替换业务名称;
|
||||
- list、detail、save、action 的代码结构统一;
|
||||
- SQL 不散落在页面、控制器和配置数据库中;
|
||||
- 通用 CRUD 的适用范围有明确示例。
|
||||
|
||||
## 9. 任务 T5:客户或产品示例业务域
|
||||
|
||||
### 9.1 目标
|
||||
|
||||
用一条完整业务链路验证新架构,而不是先建设一个空的通用引擎。
|
||||
|
||||
### 9.2 推荐对象
|
||||
|
||||
优先选择客户或产品,不要一开始选择库存或财务。
|
||||
|
||||
### 9.3 工作内容
|
||||
|
||||
```text
|
||||
SQL Migration
|
||||
→ b_customer 或 b_product
|
||||
→ 查询 SQL
|
||||
→ 保存 SQL
|
||||
→ 业务域 service
|
||||
→ API
|
||||
→ 页面
|
||||
→ 公司范围
|
||||
→ 审计
|
||||
→ 多语言名称
|
||||
```
|
||||
|
||||
### 9.4 验收标准
|
||||
|
||||
- 可以在 SQL Server 中直接执行列表和详情查询;
|
||||
- 页面不需要通用模块解释器才能运行;
|
||||
- 保存过程经过明确的 repository/service;
|
||||
- 公司范围可以生效;
|
||||
- 关键变更有审计记录;
|
||||
- 新增字段可以通过 Migration 完成;
|
||||
- 业务域目录、SQL 命名和代码风格符合 T4。
|
||||
|
||||
## 10. 任务 T6:工作流、审计和多语言接入
|
||||
|
||||
### 10.1 工作流
|
||||
|
||||
保留 `wf_*` 工作流子系统,但绑定业务动作,不绑定任意页面配置:
|
||||
|
||||
```text
|
||||
sales_order.submit
|
||||
sales_order.approve
|
||||
purchase_order.submit
|
||||
expense.approve
|
||||
```
|
||||
|
||||
工作流实例固定流程版本,真正的库存、财务和结算动作由业务域 service 执行。
|
||||
|
||||
### 10.2 审计
|
||||
|
||||
审计至少记录:
|
||||
|
||||
```text
|
||||
user_id
|
||||
company_id
|
||||
domain_code
|
||||
business_id
|
||||
operation
|
||||
before_value
|
||||
after_value
|
||||
request_id
|
||||
occurred_at
|
||||
```
|
||||
|
||||
### 10.3 多语言
|
||||
|
||||
第一阶段只实现:
|
||||
|
||||
```text
|
||||
s_i18n_type
|
||||
s_i18n
|
||||
```
|
||||
|
||||
业务主数据按业务域使用翻译表。暂不实现多层 overlay、翻译变更集和运行时语言管理。
|
||||
|
||||
### 10.4 验收标准
|
||||
|
||||
- 工作流可以调用一个业务域动作;
|
||||
- 流程实例记录固定的流程版本;
|
||||
- 业务动作和审批动作有审计记录;
|
||||
- 系统文案和主数据翻译可以按语言读取;
|
||||
- 翻译读取不影响业务 SQL 查询。
|
||||
|
||||
## 11. 任务 T7:第一阶段验收和旧设计迁移清单
|
||||
|
||||
### 11.1 验收重点
|
||||
|
||||
第一阶段不是验收页面数量,而是验收架构是否成立:
|
||||
|
||||
- SQL 是事实来源;
|
||||
- 业务域可以独立拥有表、SQL、服务和页面;
|
||||
- 不依赖通用模块解释器才能运行;
|
||||
- 简单对象可以使用通用 CRUD;
|
||||
- 核心动作使用专用 service 和 SQL;
|
||||
- 多公司上下文贯通查询、保存、权限和审计;
|
||||
- 数据库结构变更通过 Migration 管理;
|
||||
- 代码目录和 SQL 风格统一。
|
||||
|
||||
### 11.2 旧设计迁移分类
|
||||
|
||||
```text
|
||||
保留:真实业务表、成熟 SQL、工作流运行表
|
||||
迁移:散落 SQL、通用保存调用、模块页面配置
|
||||
降级:s_module、s_field、s_module_schema 只做登记和表现
|
||||
后置:全局配置版本、通用规则引擎、多层配置覆盖
|
||||
删除:以元数据解释器为中心的核心业务运行时
|
||||
```
|
||||
|
||||
## 12. 给其他 AI 的执行规则
|
||||
|
||||
每个 AI 接任务时必须先阅读:
|
||||
|
||||
1. `FMS新系统核心架构设计.md`;
|
||||
2. `FMS新系统核心架构实施计划.md`;
|
||||
3. 与当前任务直接相关的旧设计文档。
|
||||
|
||||
每个 AI 的任务输出必须包含:
|
||||
|
||||
```text
|
||||
完成内容
|
||||
修改文件
|
||||
数据库变更
|
||||
验证方式
|
||||
未完成事项
|
||||
风险或需要人工决策的地方
|
||||
```
|
||||
|
||||
执行限制:
|
||||
|
||||
- 不得自行增加通用配置引擎;
|
||||
- 不得把业务逻辑放进页面 JSON;
|
||||
- 不得为一个业务对象创建第二套 SQL 调用方式;
|
||||
- 不得修改无关业务域;
|
||||
- 不得为了“以后可能需要”提前抽象;
|
||||
- 不得删除旧表或旧接口,除非任务明确要求迁移;
|
||||
- 不得把 SQL 改写成 ORM 查询作为默认方案;
|
||||
- 不得只提交页面而没有 SQL、服务和验收说明。
|
||||
|
||||
## 13. 第一张任务卡
|
||||
|
||||
可以把下面内容直接交给第一个 AI:
|
||||
|
||||
```text
|
||||
你负责 FMS 新系统核心架构实施计划的 T0 任务:架构基线和代码规范。
|
||||
|
||||
请先阅读:
|
||||
1. FMS新系统核心架构设计.md
|
||||
2. FMS新系统核心架构实施计划.md
|
||||
3. FMS新系统核心表结构设计.md
|
||||
4. 开发规范.md
|
||||
|
||||
你的目标是确定 SQL Server、Migration、业务域目录、SQL 文件命名、数据库命名和业务动作入口规范。
|
||||
|
||||
要求:
|
||||
- 不实现业务模块;
|
||||
- 不新增通用低代码引擎;
|
||||
- 不修改无关文件;
|
||||
- 不把 SQL 改写成 ORM 查询;
|
||||
- 输出一份开发规范补充文档;
|
||||
- 提供一个客户或产品业务域的空目录模板;
|
||||
- 提供至少三个 SQL 文件示例;
|
||||
- 最后报告修改文件、验证方式和未决问题。
|
||||
```
|
||||
|
||||
## 14. 计划结论
|
||||
|
||||
第一阶段的正确顺序不是先做一个“万能模块引擎”,而是:
|
||||
|
||||
```text
|
||||
统一规范
|
||||
→ 数据库迁移
|
||||
→ 租户和公司上下文
|
||||
→ 系统基础数据
|
||||
→ 业务域模板
|
||||
→ 一个完整业务域
|
||||
→ 工作流和通用能力
|
||||
```
|
||||
|
||||
先用一个真实业务域验证架构,再决定哪些能力值得抽象。所有通用能力都必须来自实际重复,而不是来自对未来场景的猜测。
|
||||
@@ -0,0 +1,732 @@
|
||||
# FMS 新系统核心架构设计 V2.0
|
||||
|
||||
> 文档版本:V2.0
|
||||
> 编制日期:2026-09-30
|
||||
> 文档状态:核心架构设计草案
|
||||
> 适用范围:FMS/ERP 新系统第一阶段重构
|
||||
|
||||
## 1. 文档目的
|
||||
|
||||
本文档重新定义 FMS 新系统的核心架构,重点解决以下问题:
|
||||
|
||||
- SQL 是系统的第一等公民;
|
||||
- 代码风格和模块实现方式统一;
|
||||
- 第一阶段保持简单,不建设通用低代码平台;
|
||||
- 真实业务表、业务 SQL 和业务代码拥有清晰边界;
|
||||
- 支持一个租户多个公司,但不提前建设复杂的平台能力。
|
||||
|
||||
本文档替代旧设计中以 `s_module`、通用 CRUD 和动态 JSON 为中心的架构思路。旧表结构中的业务数据、工作流和可复用 SQL 可以迁移,但运行时中心需要重新组织。
|
||||
|
||||
## 2. 根本改变
|
||||
|
||||
### 2.1 旧架构
|
||||
|
||||
旧设计的主链路是:
|
||||
|
||||
```text
|
||||
s_module
|
||||
→ s_field
|
||||
→ s_module_schema
|
||||
→ 通用 SQL 拼接
|
||||
→ 通用保存
|
||||
→ 页面
|
||||
```
|
||||
|
||||
它的优点是页面和简单模块创建较快,缺点是业务模块逐渐依赖元数据解释器,容易变成一个低代码平台。
|
||||
|
||||
### 2.2 新架构
|
||||
|
||||
新设计的主链路是:
|
||||
|
||||
```text
|
||||
业务域代码包
|
||||
→ 真实 SQL 表和视图
|
||||
→ 业务查询与业务动作
|
||||
→ API / 页面
|
||||
```
|
||||
|
||||
新系统的中心不再是全局模块元数据,而是**业务域代码包**。每个业务域自己拥有表结构、迁移、SQL、业务动作和页面入口。
|
||||
|
||||
```text
|
||||
客户域
|
||||
├── 数据库迁移
|
||||
├── 业务表和视图
|
||||
├── 查询 SQL
|
||||
├── 保存 SQL
|
||||
├── 业务动作
|
||||
├── 接口
|
||||
├── 页面
|
||||
└── 多语言资源
|
||||
```
|
||||
|
||||
### 2.3 核心原则
|
||||
|
||||
```text
|
||||
业务域是组织中心
|
||||
SQL 表和视图是事实来源
|
||||
SQL 文件是查询和处理的主要实现
|
||||
业务代码负责动作和事务
|
||||
页面是业务域的使用界面
|
||||
配置只解决少量表现和参数问题
|
||||
```
|
||||
|
||||
## 3. 总体架构
|
||||
|
||||
```text
|
||||
租户注册配置
|
||||
│
|
||||
▼
|
||||
租户数据库路由
|
||||
│
|
||||
▼
|
||||
SQL Server 租户数据库
|
||||
├── 系统内核
|
||||
│ ├── 用户、角色和业务上下文
|
||||
│ ├── 公司、组织、仓库和账簿
|
||||
│ ├── 多语言和审计
|
||||
│ └── 文件和运行记录
|
||||
├── 业务域
|
||||
│ ├── 客户和供应商
|
||||
│ ├── 产品和基础资料
|
||||
│ ├── 销售
|
||||
│ ├── 采购
|
||||
│ ├── 库存
|
||||
│ └── 财务
|
||||
├── 工作流
|
||||
└── SQL 视图和报表
|
||||
```
|
||||
|
||||
运行时链路:
|
||||
|
||||
```text
|
||||
请求
|
||||
→ 租户路由
|
||||
→ 建立用户和公司上下文
|
||||
→ 进入业务域
|
||||
→ 执行查询或业务动作
|
||||
→ SQL 事务
|
||||
→ 审计记录
|
||||
→ 返回结果
|
||||
```
|
||||
|
||||
## 4. 核心内核
|
||||
|
||||
核心内核只提供所有业务域都需要的能力,不负责解释所有业务。
|
||||
|
||||
### 4.1 租户路由
|
||||
|
||||
第一阶段采用一个租户一个数据库:
|
||||
|
||||
- 租户注册信息使用配置文件;
|
||||
- 一个租户对应一个 SQL Server 数据库;
|
||||
- 租户库内不重复使用 `tenant_id` 过滤业务数据;
|
||||
- 数据库连接由统一的 `TenantRegistry` 获取;
|
||||
- 每个租户数据库单独执行迁移并记录版本。
|
||||
|
||||
平台库、在线租户开通和集中运维不进入第一阶段。
|
||||
|
||||
### 4.2 业务上下文
|
||||
|
||||
每次请求建立统一上下文:
|
||||
|
||||
```text
|
||||
tenant_code
|
||||
user_id
|
||||
company_id
|
||||
organization_id
|
||||
warehouse_id
|
||||
ledger_id
|
||||
language
|
||||
timezone
|
||||
currency
|
||||
request_id
|
||||
```
|
||||
|
||||
上下文由运行时创建,业务域只能读取,不由页面自行拼接。SQL 和业务动作通过上下文得到当前公司、用户和账簿。
|
||||
|
||||
### 4.3 基础表
|
||||
|
||||
第一阶段的系统基础表:
|
||||
|
||||
```text
|
||||
s_user
|
||||
s_role
|
||||
s_user_role
|
||||
s_company
|
||||
s_organization
|
||||
s_warehouse
|
||||
s_ledger
|
||||
s_user_company
|
||||
s_user_organization
|
||||
s_user_warehouse
|
||||
s_user_ledger
|
||||
s_i18n_type
|
||||
s_i18n
|
||||
s_audit_log
|
||||
s_file
|
||||
```
|
||||
|
||||
角色先采用简单模型,不实现角色继承和复杂拒绝规则。公司、组织、仓库和账簿是明确的独立对象,不使用一个 `org_id` 代替它们。
|
||||
|
||||
## 5. 业务域代码包
|
||||
|
||||
### 5.1 业务域定义
|
||||
|
||||
业务域是新系统的主要代码组织单位,例如:
|
||||
|
||||
```text
|
||||
customer
|
||||
supplier
|
||||
product
|
||||
sales
|
||||
purchase
|
||||
inventory
|
||||
finance
|
||||
workflow
|
||||
```
|
||||
|
||||
一个业务域负责自己的:
|
||||
|
||||
- 业务表和表关系;
|
||||
- 数据库迁移;
|
||||
- 查询视图;
|
||||
- 查询 SQL;
|
||||
- 保存 SQL;
|
||||
- 业务动作;
|
||||
- 事务边界;
|
||||
- API;
|
||||
- 页面;
|
||||
- 多语言资源;
|
||||
- 审计事件。
|
||||
|
||||
业务域之间通过明确的业务表关系、SQL 查询和服务接口协作,不通过全局 JSON 规则互相解释。
|
||||
|
||||
### 5.2 业务对象
|
||||
|
||||
业务对象仍然存在,但它属于业务域,而不是全局通用元数据引擎。
|
||||
|
||||
一个业务对象至少包含:
|
||||
|
||||
```text
|
||||
对象编码
|
||||
主表或视图
|
||||
查询 SQL
|
||||
保存方式
|
||||
业务动作
|
||||
```
|
||||
|
||||
例如销售订单:
|
||||
|
||||
```text
|
||||
sales_order
|
||||
├── b_sales_order
|
||||
├── b_sales_order_line
|
||||
├── sales_order_list.sql
|
||||
├── sales_order_save.sql
|
||||
├── submit_sales_order()
|
||||
└── approve_sales_order()
|
||||
```
|
||||
|
||||
### 5.3 业务域目录
|
||||
|
||||
建议使用以下代码组织方式:
|
||||
|
||||
```text
|
||||
fms/
|
||||
├── core/
|
||||
│ ├── tenant/
|
||||
│ ├── context/
|
||||
│ ├── auth/
|
||||
│ ├── audit/
|
||||
│ └── i18n/
|
||||
├── domains/
|
||||
│ ├── customer/
|
||||
│ │ ├── migration/
|
||||
│ │ ├── sql/
|
||||
│ │ ├── repository/
|
||||
│ │ ├── service/
|
||||
│ │ ├── api/
|
||||
│ │ └── page/
|
||||
│ ├── product/
|
||||
│ ├── sales/
|
||||
│ ├── purchase/
|
||||
│ ├── inventory/
|
||||
│ └── finance/
|
||||
├── workflow/
|
||||
└── shared/
|
||||
```
|
||||
|
||||
每个业务域使用同一种目录结构,不允许某个模块把 SQL 放数据库字段、另一个模块把 SQL 放页面代码、第三个模块再放配置 JSON。
|
||||
|
||||
## 6. SQL 设计
|
||||
|
||||
### 6.1 SQL 的职责
|
||||
|
||||
SQL 负责:
|
||||
|
||||
- 查询;
|
||||
- 关联;
|
||||
- 分组和统计;
|
||||
- 排序和分页;
|
||||
- 批量更新;
|
||||
- 事务内的数据处理;
|
||||
- 报表和视图。
|
||||
|
||||
业务代码负责:
|
||||
|
||||
- 业务动作入口;
|
||||
- 事务编排;
|
||||
- 状态变化;
|
||||
- 幂等处理;
|
||||
- 跨模块规则;
|
||||
- 库存和财务业务约束。
|
||||
|
||||
### 6.2 SQL 文件规范
|
||||
|
||||
SQL 统一放在业务域目录下:
|
||||
|
||||
```text
|
||||
domains/sales/sql/
|
||||
├── order_list.sql
|
||||
├── order_detail.sql
|
||||
├── order_save.sql
|
||||
├── order_submit.sql
|
||||
└── order_report.sql
|
||||
```
|
||||
|
||||
SQL 命名统一使用:
|
||||
|
||||
```text
|
||||
对象_动作.sql
|
||||
```
|
||||
|
||||
例如:
|
||||
|
||||
```text
|
||||
customer_list.sql
|
||||
customer_save.sql
|
||||
customer_disable.sql
|
||||
sales_order_submit.sql
|
||||
inventory_lock.sql
|
||||
```
|
||||
|
||||
### 6.3 通用 CRUD 的边界
|
||||
|
||||
新架构不移除通用 CRUD,但不把通用 CRUD 作为所有业务的默认核心。它可以用于简单基础资料,核心业务必须由业务域自己的 SQL 和业务动作实现。
|
||||
|
||||
以下内容不再作为系统核心:
|
||||
|
||||
- 数据库中的 `b_query_sql` 作为所有模块的默认查询入口;
|
||||
- `b_save_table` 驱动所有业务模块的通用保存;
|
||||
- `b_order_sql` 在运行时任意拼接排序;
|
||||
- 全局 `data / virtual` 模块解释器;
|
||||
- 页面 JSON 中的业务公式和业务写入规则;
|
||||
- 一张通用配置表承载所有业务行为。
|
||||
|
||||
内部开发人员可以自由编写 SQL,但 SQL 由对应业务域维护,并与代码和迁移一起发布。
|
||||
|
||||
### 6.4 通用保存边界
|
||||
|
||||
通用保存仅用于简单基础资料。以下内容必须使用业务域专用服务和 SQL:
|
||||
|
||||
- 库存扣减、锁定和释放;
|
||||
- 采购和销售状态推进;
|
||||
- 财务过账和反过账;
|
||||
- 公司间交易;
|
||||
- 审批提交和审批动作;
|
||||
- 任何需要多个业务表一致提交的操作。
|
||||
|
||||
## 7. 数据库模型
|
||||
|
||||
### 7.1 表分层
|
||||
|
||||
```text
|
||||
s_* 系统内核和控制数据
|
||||
b_* 业务主表和业务明细表
|
||||
wf_* 工作流定义和运行数据
|
||||
```
|
||||
|
||||
核心业务表使用真实列和真实关系,不使用全量 EAV。
|
||||
|
||||
### 7.2 公司字段
|
||||
|
||||
公司级业务表根据业务实际需要包含:
|
||||
|
||||
```text
|
||||
company_id
|
||||
organization_id
|
||||
warehouse_id
|
||||
ledger_id
|
||||
```
|
||||
|
||||
跨公司业务另外保存:
|
||||
|
||||
```text
|
||||
source_company_id
|
||||
target_company_id
|
||||
settlement_company_id
|
||||
```
|
||||
|
||||
共享基础资料不复制多份,使用共享范围或公司关联表表达。
|
||||
|
||||
### 7.3 动态字段
|
||||
|
||||
第一阶段不支持普通用户通过页面配置直接创建数据库字段。新增业务字段使用:
|
||||
|
||||
```text
|
||||
迁移脚本增加物理列或扩展表
|
||||
→ 更新查询 SQL 和视图
|
||||
→ 更新页面字段定义
|
||||
→ 增加多语言资源
|
||||
```
|
||||
|
||||
字段分为:
|
||||
|
||||
1. 核心字段:真实列,参与业务逻辑和统计;
|
||||
2. 扩展字段:通过迁移增加的可选列或扩展表字段;
|
||||
3. 低频扩展:JSON,仅用于非核心展示。
|
||||
|
||||
需要筛选、排序、统计或导出的字段不能只放在 JSON 中。
|
||||
|
||||
运行时字段分为两种情况:
|
||||
|
||||
- **表现字段**:标签、显隐、只读、排序和布局可以运行时调整;
|
||||
- **物理字段**:需要存储、查询、排序、统计或导出的字段,必须通过 SQL Migration 增加物理列或扩展表。
|
||||
|
||||
后续如果确实需要管理员在线增加物理字段,可以增加一个受控的字段变更服务,由它生成并执行 SQL Migration,同时更新视图、字段定义和页面配置。这个过程仍然是数据库结构变更,不是普通 JSON 配置。
|
||||
|
||||
### 7.4 数据库约束
|
||||
|
||||
数据库负责结构完整性:
|
||||
|
||||
- 主键;
|
||||
- 外键;
|
||||
- 唯一索引;
|
||||
- 非空约束;
|
||||
- 必要 CHECK;
|
||||
- 查询和关联索引。
|
||||
|
||||
不使用触发器替代库存、财务和审批业务流程。业务规则放在业务域服务和事务 SQL 中。
|
||||
|
||||
## 8. 页面和配置
|
||||
|
||||
### 8.1 页面不是元数据生成的
|
||||
|
||||
核心业务页面由业务域代码实现。页面可以复用通用列表、表单和查询组件,但页面的字段、动作和业务行为由业务域明确声明。
|
||||
|
||||
页面配置只保存:
|
||||
|
||||
- 列显示顺序;
|
||||
- 列宽;
|
||||
- 表单分组;
|
||||
- 查询默认值;
|
||||
- 用户个人偏好;
|
||||
- 显示格式。
|
||||
|
||||
不使用 JSON 描述完整业务页面和业务处理器。
|
||||
|
||||
### 8.2 模块表的定位
|
||||
|
||||
如果保留 `s_module`,它只用于:
|
||||
|
||||
- 菜单和路由登记;
|
||||
- 权限对象登记;
|
||||
- 模块名称和多语言资源键;
|
||||
- 业务域对象的索引。
|
||||
|
||||
它不负责:
|
||||
|
||||
- 生成所有 SQL;
|
||||
- 推断所有保存逻辑;
|
||||
- 承载业务状态;
|
||||
- 解释任意 JSON 规则。
|
||||
|
||||
### 8.3 公司差异
|
||||
|
||||
第一阶段不建设通用的租户、公司、部门、角色多层配置继承。
|
||||
|
||||
确实存在公司差异时,在具体业务表中直接使用 `company_id`,例如:
|
||||
|
||||
```text
|
||||
s_number_rule(company_id, domain_code, field_code)
|
||||
wf_binding(company_id, domain_code, event_code)
|
||||
s_print_template(company_id, template_code)
|
||||
```
|
||||
|
||||
不把所有差异都抽象为一个通用覆盖引擎。
|
||||
|
||||
## 9. 权限
|
||||
|
||||
权限采用简单的角色模型:
|
||||
|
||||
```text
|
||||
s_role
|
||||
s_user_role
|
||||
s_role_permission
|
||||
s_role_data_scope
|
||||
s_user_company
|
||||
```
|
||||
|
||||
权限对象绑定业务域和业务动作:
|
||||
|
||||
```text
|
||||
customer.read
|
||||
customer.create
|
||||
sales_order.submit
|
||||
sales_order.approve
|
||||
inventory.adjust
|
||||
finance.post
|
||||
```
|
||||
|
||||
第一阶段支持:
|
||||
|
||||
- 用户可用公司;
|
||||
- 用户可用组织;
|
||||
- 用户可用仓库;
|
||||
- 模块访问权限;
|
||||
- 业务动作权限;
|
||||
- 简单数据范围。
|
||||
|
||||
不实现角色继承、拒绝权限和通用权限表达式。复杂范围由对应业务域的 SQL 实现。
|
||||
|
||||
## 10. 工作流
|
||||
|
||||
工作流是业务域的流程编排器,不是业务规则中心。
|
||||
|
||||
工作流绑定业务域动作:
|
||||
|
||||
```text
|
||||
sales_order.submit
|
||||
sales_order.approve
|
||||
purchase_order.submit
|
||||
expense.approve
|
||||
```
|
||||
|
||||
工作流可以决定:
|
||||
|
||||
- 下一节点;
|
||||
- 审批人;
|
||||
- 当前流程状态;
|
||||
- 需要调用哪个业务动作。
|
||||
|
||||
业务域负责真正的动作:
|
||||
|
||||
- 销售订单批准后是否允许出库;
|
||||
- 采购收货如何增加库存;
|
||||
- 财务单据如何过账;
|
||||
- 审批失败如何补偿。
|
||||
|
||||
工作流实例固定流程版本,历史审批记录只追加不修改。
|
||||
|
||||
## 11. 多语言
|
||||
|
||||
第一阶段保持简单:
|
||||
|
||||
```text
|
||||
s_i18n_type
|
||||
s_i18n
|
||||
```
|
||||
|
||||
系统文案使用稳定资源键:
|
||||
|
||||
```text
|
||||
sales.order.name
|
||||
sales.order.customer
|
||||
action.submit
|
||||
```
|
||||
|
||||
业务主数据使用业务域自己的翻译表:
|
||||
|
||||
```text
|
||||
b_product
|
||||
b_product_translation
|
||||
b_customer
|
||||
b_customer_translation
|
||||
```
|
||||
|
||||
系统资源可以放在代码资源文件或租户库中,但必须统一一种来源。第一阶段不实现三层 overlay、翻译变更集和运行时语言管理。
|
||||
|
||||
历史单据保存产品名称、客户名称、税率、地址、币种和金额等快照。
|
||||
|
||||
## 12. 配置和版本
|
||||
|
||||
第一阶段不建设覆盖所有对象的通用配置版本引擎。
|
||||
|
||||
配置分为三类:
|
||||
|
||||
| 类型 | 实现方式 |
|
||||
| --- | --- |
|
||||
| 数据库结构 | SQL Migration |
|
||||
| 业务逻辑 | 代码和业务 SQL |
|
||||
| 页面表现 | 页面代码和少量布局配置 |
|
||||
| 工作流 | 独立流程版本表 |
|
||||
| 业务参数 | 明确的参数表 |
|
||||
|
||||
只有工作流、编号规则、打印模板等确实需要历史追溯的内容,才单独设计版本。
|
||||
|
||||
### 12.1 SQL Migration
|
||||
|
||||
SQL Migration 是按顺序执行、可追踪的数据库结构变更脚本。例如:
|
||||
|
||||
```text
|
||||
migration/
|
||||
├── V001__create_company.sql
|
||||
├── V002__create_customer.sql
|
||||
└── V003__add_customer_tax_no.sql
|
||||
```
|
||||
|
||||
迁移工具在每个租户数据库中记录已执行的版本。发布新代码时,先执行缺少的迁移,再启动依赖新结构的代码。
|
||||
|
||||
Migration 可以包含:
|
||||
|
||||
- 建表、改表和删表;
|
||||
- 增加或停用字段;
|
||||
- 创建视图、索引和约束;
|
||||
- 初始化字典和系统数据;
|
||||
- 必要的数据回填。
|
||||
|
||||
Migration 不等于运行时页面配置。页面配置可以立即保存,数据库结构变化则必须经过迁移记录。
|
||||
|
||||
数据库迁移记录:
|
||||
|
||||
```text
|
||||
schema_version
|
||||
migration_name
|
||||
checksum
|
||||
executed_at
|
||||
```
|
||||
|
||||
## 13. 代码风格和目录规范
|
||||
|
||||
新系统的代码按业务域组织,不按页面组织,也不按一组通用配置表组织。
|
||||
|
||||
```text
|
||||
domains/
|
||||
sales/
|
||||
migration/
|
||||
sql/
|
||||
repository/
|
||||
service/
|
||||
api/
|
||||
page/
|
||||
i18n/
|
||||
```
|
||||
|
||||
统一要求:
|
||||
|
||||
- 一个业务动作只有一个主要入口;
|
||||
- SQL 统一放业务域的 `sql` 目录;
|
||||
- 页面只调用业务域 API,不直接写业务 SQL;
|
||||
- 业务域不通过另一个域的内部表直接修改数据;
|
||||
- 数据库表、SQL、服务、接口和页面使用同一业务名称;
|
||||
- 新增抽象必须来自至少两个真实业务域的重复需求。
|
||||
|
||||
数据库命名在新系统中一次确定:
|
||||
|
||||
- 表名使用小写 `snake_case`;
|
||||
- 系统表使用 `s_`;
|
||||
- 业务表使用 `b_` 或明确业务域前缀;
|
||||
- 工作流表使用 `wf_`;
|
||||
- 字段命名统一使用一套规则,不再混用 `b_`、`mx_` 和裸字段名。
|
||||
|
||||
## 14. 第一阶段建设范围
|
||||
|
||||
第一阶段只建设架构内核和一条完整业务链路。
|
||||
|
||||
### 14.1 必须完成
|
||||
|
||||
1. SQL Server 迁移工具和数据库版本表;
|
||||
2. 租户数据库连接和路由;
|
||||
3. 用户、角色、公司、组织、仓库和账簿;
|
||||
4. 统一业务上下文;
|
||||
5. 业务域目录和 SQL 调用约定;
|
||||
6. 基础权限和公司范围;
|
||||
7. 审计日志;
|
||||
8. 基础多语言;
|
||||
9. 一个业务域的表、SQL、服务、接口和页面完整闭环。
|
||||
|
||||
### 14.2 建议示例
|
||||
|
||||
建议先做客户或产品域:
|
||||
|
||||
```text
|
||||
SQL Migration
|
||||
→ 真实业务表
|
||||
→ 查询 SQL
|
||||
→ 保存 SQL
|
||||
→ 业务域服务
|
||||
→ API
|
||||
→ 页面
|
||||
→ 公司权限
|
||||
→ 审计
|
||||
```
|
||||
|
||||
这个示例必须验证“业务域代码包是中心”,不只是验证通用页面是否能显示。
|
||||
|
||||
### 14.3 第一阶段不做
|
||||
|
||||
- 以全局 `s_module` 驱动的通用 CRUD 作为核心业务默认实现;
|
||||
- 全局 `s_field` 驱动的运行时字段创建;
|
||||
- 通用页面设计器;
|
||||
- 通用公式和规则解释器;
|
||||
- 全对象配置版本和变更集;
|
||||
- 多层公司配置覆盖;
|
||||
- 复杂多语言发布体系;
|
||||
- 集团分析库和跨租户业务查询。
|
||||
|
||||
## 15. 第一阶段验收标准
|
||||
|
||||
### 15.1 架构中心
|
||||
|
||||
- 一个业务域拥有自己的迁移、SQL、服务和页面;
|
||||
- 业务域可以不依赖通用模块解释器运行;
|
||||
- 页面配置不能替代业务代码;
|
||||
- 工作流只能调用明确登记的业务动作。
|
||||
|
||||
### 15.2 SQL 驱动
|
||||
|
||||
- 业务查询可以直接在 SQL Server 中验证;
|
||||
- 复杂查询使用业务域 SQL 文件或视图;
|
||||
- 业务表和关联关系是真实 SQL 结构;
|
||||
- 新增可统计字段需要物理列或索引扩展;
|
||||
- 不为了页面功能复制业务表。
|
||||
|
||||
### 15.3 简单和一致
|
||||
|
||||
- 同类业务域使用相同目录和调用流程;
|
||||
- 不存在同一类配置的多种格式;
|
||||
- 不存在同一业务动作的多个通用入口;
|
||||
- 数据库迁移和代码可以一起发布;
|
||||
- 第一阶段不依赖通用低代码运行时。
|
||||
|
||||
## 16. 旧设计迁移原则
|
||||
|
||||
旧设计不是全部废弃,而是按职责迁移:
|
||||
|
||||
| 旧内容 | 新系统处理方式 |
|
||||
| --- | --- |
|
||||
| 真实业务表 | 保留并按业务域归属整理 |
|
||||
| 业务 SQL | 移入对应业务域 `sql` 目录 |
|
||||
| `wf_*` 工作流表 | 保留,改为绑定业务动作 |
|
||||
| `s_module` | 降为菜单、权限和对象索引 |
|
||||
| `s_field` | 降为字段说明,不负责运行时造字段 |
|
||||
| `s_module_schema` | 页面局部配置,不作为核心运行时 |
|
||||
| 通用保存接口 | 仅保留简单基础资料使用 |
|
||||
| JSON 公式和动态规则 | 迁移到业务代码或 SQL |
|
||||
| `b_query_sql` 等全局 SQL 字段 | 逐步迁移到业务域 SQL 文件 |
|
||||
|
||||
## 17. 最终架构关系
|
||||
|
||||
```text
|
||||
业务域代码包是组织中心
|
||||
SQL 表和视图是事实来源
|
||||
SQL 文件是查询和处理的主要实现
|
||||
业务代码负责动作和事务
|
||||
页面负责交互
|
||||
工作流负责流程编排
|
||||
少量配置负责表现和参数
|
||||
```
|
||||
|
||||
新系统不是旧系统增加一层配置,也不是把旧模块表重新命名。它的核心变化是:
|
||||
|
||||
> **从元数据驱动的通用模块,改成业务域驱动的 SQL 应用。**
|
||||
Reference in new issue
Block a user