# ERP 动态配置、多租户、多公司与多语言需求分析 > 文档版本:V1.1 > 编制日期:2026-09-30 > 修订日期:2026-09-30 > 适用范围:FMS/ERP 新系统规划、产品设计、数据库设计、接口设计和开发验收 > 文档状态:需求基线草案(多语言与配置版本方案已修订) > > **V1.1 修订范围**:第 10 章(引入变更集、无状态/有状态配置、类型注册表)、第 11 章(三层存储模型、角色能力边界、双重循环回退链、可覆盖白名单)、以及 3.5 / 9.4 / 13.2 / 19.4 / 22 / 23 章的配套修订。其余章节保持 V1.0 原文。 ## 1. 文档说明 本文档用于明确 ERP 系统在以下方面的总体需求和设计边界: - 一个租户一个数据库的物理隔离模式; - 一个租户包含多个公司、子公司和组织; - 动态字段、动态表单、动态流程和动态权限; - 简体中文、繁体中文、英文等多语言能力; - 公司级业务、集团级共享资料和集团汇总报表; - 与现有 FMS SQL 驱动、模块配置和工作流设计保持一致。 本文档是系统级需求分析,不替代各业务模块的详细需求、接口协议、数据库字段设计和页面原型。后续销售、采购、库存、财务等模块应以本文档的边界和基础模型为前提继续细化。 ## 2. 建设目标 ### 2.1 总体目标 建设一个面向企业集团和内部业务团队的 ERP/FMS 系统,通过稳定的业务内核和可版本化的配置能力,支持不同租户在不复制代码的情况下适配不同的组织结构、字段、流程、权限和语言。 系统不是通用低代码平台,不要求所有页面、业务规则和复杂业务组件都由用户拖拽生成。系统采用以下原则: > 固定核心业务能力,配置变化部分,代码承载复杂业务逻辑,插件承载专业差异。 ### 2.2 具体目标 1. 每个租户拥有独立数据库,方便备份、迁移、恢复和维护。 2. 一个租户可以包含多个公司、子公司、分公司和组织机构。 3. 公司之间可以共享基础资料,也可以保持独立的业务和财务数据。 4. 支持字段、表单、查询、编号、流程、权限、打印模板等动态配置。 5. 支持用户界面、配置项、基础资料和业务快照的多语言处理。 6. 核心业务数据可通过 SQL 高效查询、统计、导出和扩展。 7. 所有配置均支持草稿、校验、发布、生效、停用和回滚。 8. 支持单租户备份、恢复、复制到测试环境和迁移到其他数据库。 9. 支持公司级报表、集团汇总报表和后续合并分析能力。 ## 3. 设计原则 ### 3.1 租户隔离原则 一个租户对应一个业务数据库。租户业务表不再依赖 `tenant_id` 实现日常数据隔离,数据库边界本身就是租户隔离边界。 租户注册信息与数据库连接信息由租户注册表维护。首期可以使用配置文件,后续在租户数量、部署实例或平台运维需求增加时再切换为可选平台库;租户自己的用户、组织、配置和业务数据始终放在租户数据库。 ### 3.2 公司隔离原则 租户数据库内部允许多个公司共存,但所有公司级业务和财务数据必须带有 `company_id`。公司是业务、库存、结算、账簿和报表的主要归属边界。 ### 3.3 配置与代码边界 以下内容优先配置化: - 字段定义、字段标签和字段分组; - 列表和表单布局; - 查询条件、排序、显示格式和导出字段; - 编号规则、字典和枚举; - 审批节点、审批人和审批条件; - 角色、字段权限和数据范围; - 打印模板、通知模板和简单校验。 以下内容必须由代码保证: - 库存扣减、锁定、释放和成本计算; - 财务过账、反过账和账簿一致性; - 单据状态的关键流转约束; - 并发控制、幂等处理和跨模块数据一致性; - 复杂税务、结算、汇率和合并抵销逻辑。 ### 3.4 数据模型原则 - 核心业务数据使用关系表,不使用全量 EAV 模型。 - 高频查询和关键业务字段使用正式列。 - 变化频繁的扩展字段可使用 JSON 或扩展值表。 - 需要筛选、排序、统计的扩展字段应具备可索引方案。 - 历史单据保存名称、规格、地址、税率、价格等业务快照。 - 配置、元数据和业务数据分离存储。 ### 3.5 现有 FMS 规范兼容 系统实现应延续现有 FMS 规范: - 使用 SQL 驱动的查询和数据处理方式; - 系统配置、元数据和权限表使用 `s_` 前缀; - 业务表沿用现有 `b_` 或业务域前缀; - 字段采用小写 `snake_case`; - JSON 仅承载布局、查询和用户偏好等适合 JSON 的结构; - 多语言采用三层存储:系统默认层与租户覆盖层使用租户库关系表,硬编码兜底层使用代码资源文件,历史单据使用业务快照(详见 11.1); - 权限过滤必须落实到后端查询或写入逻辑; - 不使用触发器代替业务层规则。 ## 4. 业务概念模型 ```text 平台 └── 租户 Tenant:一个客户集团或客户账号,对应一个数据库 ├── 公司 Company:集团总部、子公司、分公司、法人实体 │ ├── 组织 Organization:部门、岗位、成本中心 │ ├── 仓库 Warehouse │ └── 账簿 Ledger ├── 集团共享基础资料 └── 公司专属基础资料 ``` ### 4.1 租户 租户是平台级概念,代表一个独立客户或集团客户。租户具备: - 独立数据库; - 独立的配置和业务数据; - 独立的备份和恢复周期; - 独立的模块授权和版本状态; - 独立的默认语言、时区和区域设置。 ### 4.2 公司 公司是租户内部的法人实体、经营主体或业务主体。公司至少需要维护: - 公司编码和名称; - 上级公司; - 公司类型; - 法人、税号和注册地址; - 默认币种和默认语言; - 时区和会计日历; - 默认账簿和财务期间; - 银行账户、开票主体和税务信息; - 启停用状态。 ### 4.3 组织 组织是公司的内部管理单元,包括部门、业务部、采购部、仓储部、财务部、成本中心等。组织支持树形层级,可用于审批、权限、负责人、费用归属和数据范围。 ### 4.4 共享范围 基础资料应支持集团共享和公司专属两种范围: ```text GROUP 集团内公司均可使用 COMPANY 仅指定公司可使用 ORG 仅指定组织或组织范围可使用 ``` 共享不代表可以跨公司直接交易。业务单据仍必须指定实际业务公司、结算公司和相关组织。 ## 5. 系统总体架构 ```text 前端应用层 ├── 平台管理 ├── 基础资料 ├── 销售管理 ├── 采购管理 ├── 库存管理 ├── 费用与结算 ├── 财务管理 ├── 报表中心 └── 系统配置 通用能力层 ├── 业务对象与元数据 ├── 动态表单与列表 ├── 工作流与审批 ├── 权限与数据范围 ├── 多语言与区域化 ├── 编号与字典 ├── 附件与打印 ├── 审计日志 └── 通知消息 租户运行层 ├── 租户识别 ├── 数据库路由 ├── 数据源连接池 ├── 配置版本管理 ├── 租户数据库迁移 ├── 备份恢复 └── 租户健康检查 数据层 ├── 租户连接注册(文件/平台库) ├── 租户数据库 ├── 消息队列 └── 分析库/数仓 ``` ### 5.1 租户注册表与平台库(可选) 系统必须能够根据租户标识找到对应数据库。租户注册信息不强制要求使用平台库,首期可以使用按租户维护的配置文件: ```text config/tenants/tenant-a.json config/tenants/tenant-b.json ``` 注册表至少维护: - 租户编码和状态; - 数据库标识和部署模式; - 当前数据库版本; - 数据库健康状态; - 域名或登录入口映射; - 模块授权和启用功能; - 迁移、备份和恢复任务状态。 当需要在线开通租户、多实例部署、统一运维或集中查看所有租户状态时,可将同一套注册信息迁移到平台库。平台库只负责控制平面,不保存租户业务明细。 ### 5.2 租户数据库 每个租户数据库保存本租户的完整业务数据,包括: - 用户成员和组织架构; - 公司、账簿、仓库和基础资料; - 系统模块、字段、流程、权限和语言配置; - 销售、采购、库存、费用和财务数据; - 租户级审计日志和业务操作记录。 ## 6. 功能需求总览 | 编号 | 功能域 | 主要内容 | 优先级 | | ------ | ---------- | ---------------------------------------- | ------ | | FR-001 | 平台与租户 | 租户开通、数据库登记、状态管理 | P0 | | FR-002 | 公司与组织 | 多公司、子公司、组织树、仓库和账簿 | P0 | | FR-003 | 用户与权限 | 用户、角色、公司范围、组织范围、字段权限 | P0 | | FR-004 | 元数据配置 | 模块、字段、对象和关系配置 | P0 | | FR-005 | 动态页面 | 列表、表单、详情、查询和导出配置 | P0 | | FR-006 | 工作流 | 状态、节点、条件、审批人和动作 | P0 | | FR-007 | 多语言 | 界面、配置、主数据和单据快照多语言 | P0 | | FR-008 | 基础资料 | 客户、供应商、产品、分类、价格和税率 | P0 | | FR-009 | 销售采购 | 订单、审批、收发货、结算和对账 | P1 | | FR-010 | 库存 | 仓库、库存、批次、序列号、调拨和盘点 | P1 | | FR-011 | 财务 | 账簿、期间、应收应付、凭证和报表 | P1 | | FR-012 | 报表 | 公司报表、集团汇总、导出和分析 | P1 | | FR-013 | 运维 | 迁移、备份、恢复、监控和审计 | P0 | ## 7. 平台与租户管理需求 ### 7.1 租户开通 租户开通可以由部署工具、运维人员或平台管理员完成: 1. 创建租户基本资料; 2. 创建或绑定租户数据库; 3. 执行数据库初始化脚本; 4. 写入基础语言、时区和默认参数; 5. 创建首个租户管理员; 6. 分配默认模块和权限; 7. 写入租户注册文件或平台库; 8. 记录初始化结果和数据库版本。 租户注册表应抽象为统一的 `TenantRegistry` 接口。首期使用文件实现,后续可以替换为平台库实现,不改变业务模块代码。 ### 7.2 租户数据库模式 系统应支持以下数据库部署模式: - `shared_instance`:同一数据库实例中的独立数据库; - `dedicated_instance`:独立数据库实例; - `external_database`:外部托管或私有化数据库。 默认采用独立数据库,是否独立实例由租户规模、性能和部署要求决定。 ### 7.3 租户状态 租户状态至少包括: ```text CREATING 初始化中 ACTIVE 正常使用 READ_ONLY 只读维护 SUSPENDED 暂停访问 MIGRATING 数据迁移中 ARCHIVED 已归档 ``` 不同状态下,登录、查询、保存、审批、导出和后台任务应有明确限制。 ## 8. 公司、组织和账簿需求 ### 8.1 公司管理 系统支持在一个租户数据库内维护多个公司,并支持公司树: ```text 集团总部 ├── 上海子公司 ├── 苏州子公司 └── 香港子公司 ``` 公司管理功能包括: - 新增、编辑、停用公司; - 设置上级公司和公司类型; - 设置默认语言、时区和币种; - 设置会计日历和财务期间; - 维护税务、银行和开票资料; - 配置公司级编号规则、审批规则和权限; - 查看公司数据量、业务状态和启用模块。 ### 8.2 组织管理 组织树使用父子关系维护,支持: - 部门、岗位、成本中心等组织类型; - 组织移动和层级调整; - 负责人和分管人员; - 组织有效期; - 用户多组织任职; - 审批节点按组织、岗位或负责人取值。 ### 8.3 仓库和账簿 仓库必须归属公司,可进一步归属组织。账簿必须归属公司,并明确: - 本位币; - 会计年度; - 会计期间; - 科目体系; - 是否允许过账; - 结账状态。 ## 9. 用户、角色和权限需求 ### 9.1 权限层次 系统权限至少分为: ```text 平台权限 租户权限 公司权限 组织权限 仓库权限 模块权限 按钮权限 字段权限 数据权限 业务动作权限 ``` ### 9.2 用户业务上下文 用户登录后形成统一的业务上下文: ```text tenant_id 当前租户标识 company_id 当前公司 organization_id 当前组织 ledger_id 当前账簿 language 当前语言 timezone 当前时区 currency 当前显示或业务币种 user_id 当前用户 ``` 用户可以切换的范围由权限决定。普通用户可能只能切换组织,集团财务可以切换公司和账簿。 ### 9.3 数据权限 数据权限支持: - 仅本人创建的数据; - 所属组织数据; - 所属组织及下级组织数据; - 指定公司数据; - 指定仓库数据; - 指定客户、供应商或业务负责人数据; - 自定义条件数据。 数据权限必须在后端 SQL 或数据访问层执行,前端隐藏不能代替后端权限过滤。 ### 9.4 超级管理员与租户用户 > V1.1 新增。本章是第 10 章配置版本与第 11 章多语言的能力边界前提。 系统区分两类角色,其能力差异是全局性的,不只作用于多语言: | 角色 | 持有方 | 是否交付客户 | 主要能力 | | ---------- | -------------- | ------------------ | ------------------------------------------------------------ | | 超级管理员 | 运维或开发团队 | **否**,不交付租户 | 新增/删除语言、配置语言默认值、修改任意配置与文案、对租户白名单做例外放行、平台级运维操作 | | 租户用户 | 客户方 | 是 | 在授权范围内修改文案取值与配置,**不能新增语言、不能语言级配置、不能修改锁定文本** | 租户用户对文案的修改结果**对整个租户生效**,不是每个登录账号各改各的。租户内所有用户看到同一份文案;个人语言偏好只决定"使用哪一门语言",不决定"某个词如何翻译"。 这条约束的实操价值在于:用户报障时会复述屏幕上的文案,若同一租户内不同人看到不同叫法,运维无法据此定位问题。 ## 10. 动态配置需求 ### 10.1 配置对象 系统至少支持以下配置对象: - 业务模块; - 数据对象; - 字段定义; - 主子表关系; - 列表布局; - 表单布局; - 查询方案; - 编号规则; - 字典和枚举; - 工作流; - 权限和数据范围; - 打印模板; - 通知模板; - 公式和简单规则。 ### 10.2 动态字段 支持以下字段类型: - 文本、多行文本; - 整数、数值、金额; - 日期、时间、日期时间; - 单选、多选、下拉树; - 用户、部门、公司、仓库、客户等关联字段; - 附件、图片; - 公式字段; - 子表和明细字段。 字段配置包括: - 编码、名称和数据类型; - 是否启用; - 是否必填; - 默认值; - 可见、只读和禁用条件; - 查询、排序和导出能力; - 权限级别; - 公司作用域; - 多语言标签; - 校验和格式化规则。 ### 10.3 动态表单和列表 表单支持: - 分组、选项卡和折叠面板; - 字段栅格和列宽; - 条件显示、条件只读和条件必填; - 主表与子表; - 自定义组件; - 用户个性化布局; - 根据公司、角色或单据状态使用不同布局。 列表支持: - 动态列; - 固定列和排序; - 多条件查询; - 条件组和逻辑组合; - 汇总、分组和统计; - 导出字段控制; - 用户保存查询方案。 ### 10.4 配置生命周期与元模型 配置发布必须经过: ```text 草稿 → 校验 → 测试 → 发布 → 生效 → 停用/回滚 ``` 发布前校验包括: - 字段和编码重复检查; - 关联对象存在性检查; - 流程节点可达性检查; - 必填字段可填写检查; - 公式字段引用检查; - 权限是否造成无人审批检查; - 删除或停用字段对历史数据的影响检查。 配置版本必须保留发布人、发布时间、变更说明和前一版本引用。 > V1.1 修订:上述生命周期是**完整链路**,适用于结构型与行为型配置。展示型、内容型(含翻译)按 10.7 的类型注册表跳过"测试"环节,直接发布。 **统一元模型。** 10.1 列举的全部配置对象共用一套版本机制,不为每类各造一套: ```text 配置对象 config_object —— 一个可版本化的单元(字段定义、列表布局、工作流、打印模板……) ├── 工作副本 —— 唯一一份,可反复编辑 ├── 版本快照 —— 发布时整体冻结,发布后不可变 └── 指针 —— 当前版本 + 上一版本 变更集 change_set —— 打包多个配置对象的工作单元,见 10.5 ``` 参考表结构(沿用 `s_` 前缀与 `snake_case` 命名): ```text s_config_object (tenant_id, object_type, object_code) s_config_version (object_id, version_no, status, content_json) s_config_release (object_id, current_version_id, previous_version_id, released_by, released_at) s_change_set (tenant_id, set_code, status, released_by, released_at) s_change_set_item (change_set_id, object_id, before_version_id, after_version_id) ``` **整包快照,不做行级 diff。** 单个配置对象通常为几百行 JSON,整体冻结最简单、最不易出错,回滚即移动指针。版本比对通过两个版本的 JSON 并排展示实现,**不实现三方合并**。 **配置作用域:租户级默认 + 公司级稀疏覆盖。**(V1.1 补充) 本节新增的公司级覆盖机制只作用于「表现与行为」类配置对象;结构性定义仍由租户统一,详见下方「配置对象的作用域划分」。三层结构与第 11 章多语言的「覆盖层 → 默认层 → 兜底层」一致,表述与之对齐: ```text 多语言:租户覆盖层 → 系统默认层 → 硬编码兜底层 配置: 公司级覆盖 → 租户级默认 → 系统内置 ``` 原 `s_config_object` / `s_config_version` / `s_config_release` 定义保持不变;公司级覆盖通过新增两张表实现,不改变对象的租户级定义: ```text s_config_override (object_id, company_id, current_version_id, previous_version_id) s_config_override_version (object_id, company_id, version_no, content_json, status, released_by, released_at) ``` 解析规则: ```text 最终生效配置 = 公司级覆盖(company_id) 存在 → 取公司级已发布版本 否则 → 取租户级已发布版本 ``` **覆盖粒度为「对象级整包覆盖」,不做字段级合并。** 理由:字段级合并会产生"字段 A 来自公司版、字段 B 来自租户版"的组合,租户升级后可能出现公司版与租户版字段结构不一致的诡异状态,且无法预测。整包覆盖语义清晰、可预期。 **稀疏覆盖,不做全量复制。** 公司级覆盖必须是稀疏的: - 公司创建时,覆盖表为空,零初始化; - 租户级默认值变更后,自动传播到所有未做覆盖的公司; - 公司删除覆盖,即回退到租户级默认。 **为什么不做「创建公司时复制全量租户配置」。** 该做法下,租户后续优化无法传播到已有公司,N 个公司产生 N 份副本,改一次通用规则要改 N 次,与多语言全量复制的缺陷完全相同。 **配套要求:租户版与公司版差异比对。** 系统提供「查看租户版与本公司版差异」的比对功能(两个 JSON 并排展示即可),使公司管理员能判断是否需要同步租户级更新。 **配置对象的作用域划分。** | 配置对象 | 租户级 | 公司级覆盖 | 说明 | | --- | --- | --- | --- | | 业务模块、数据对象、主子表关系 | 定义 | ❌ | 结构型,租户统一 | | 字段定义(编码、名称、数据类型) | 定义 | ❌ | 结构性定义租户统一 | | 字段使用属性(必填、显隐、只读、默认值、标签) | 默认 | ✅ | 10.2 已有「公司作用域」 | | 列表布局、表单布局、查询方案 | 默认 | ✅ | 10.3 已支持按公司 | | 编号规则 | 默认 | ✅ | 8.1 明确要求 | | 工作流、审批规则 | 默认 | ✅ | 8.1 明确要求 | | 权限和数据范围 | 默认 | ✅ | 9.1 已有公司权限层 | | 打印模板、通知模板 | 默认 | ✅ | 抬头、税号、logo 常为公司专属 | | 字典和枚举 | 默认 | ✅ 有限 | 允许公司增改项文案,不允许改编码 | | 公式和简单规则 | 默认 | ❌ | 逻辑一致性优先 | > 原则:**结构性定义租户统一,表现与行为规则允许公司覆盖。** > > 作用域止于公司:组织级、仓库级不设配置作用域(仅权限可下沉到组织/仓库)。配置继续下沉会导致配置量爆炸且无法维护。 **作用域边界规则。** 1. **删除公司级覆盖 = 回退到租户级默认**,不等同于停用或删除该配置。 2. **孤儿覆盖校验**:租户级对象被停用或删除后,其下的公司级覆盖应被标记为孤儿覆盖,纳入发布前校验清单与运维巡检,不得静默失效。 3. **公司停用或归档时,其覆盖随之失效**,不进入解析链。 4. **权限、编号规则、打印模板复用同一套覆盖机制**,不得各造一套。 **共享内核(建议)。**「租户级默认 + 公司级稀疏覆盖 + 优先级解析」是本文档中反复出现的结构,至少四处复用同一模式——多语言(11.4 公司级 overlay)、配置(本次新增)、权限(9.1 公司权限层)、编号规则(8.1 公司级编号规则)。建议抽象为共享内核统一实现,避免四处各造一套导致行为不一致。 ### 10.5 变更集 > V1.1 新增。V1.1 补充:支持租户级与公司级混合作用域。 ERP 中最常见的操作是"加字段 → 改表单 → 改列表列 → 改打印模板"的组合修改。若只能单对象独立发布,会产生"字段已加但表单未放置"的中间态不一致。因此配置以**变更集**为发布单元: - 变更集包含 N 个配置对象的草稿变更; - 提交时执行**跨对象一致性校验**; - **原子发布**:全部成功或全部不生效,不得出现半发布状态(呼应 19.4); - **回滚以变更集为最小单位**。 **跨对象校验**是相比单对象发布的最大增量价值:可校验"表单引用的字段是否存在""列表列引用的字段是否已停用""打印模板引用的字段是否仍可见"这类约束,而这些在分开发布时无法校验。 **变更集项的作用域。**(V1.1 补充)`s_change_set_item` 增加 `scope` 与 `company_id`: ```text s_change_set_item (change_set_id, object_id, before_version_id, after_version_id, scope, company_id) ``` - `scope` 取 `TENANT` 或 `COMPANY`; - `scope = COMPANY` 时 `company_id` 必填,指向公司级覆盖(见 10.4); - `scope = TENANT` 时 `company_id` 为空。 **允许同一变更集混合租户级与公司级项。** 典型场景:「加字段(租户级)+ 改 A 公司表单(公司级)」必须能一起发,否则又会退回"字段已加但公司表单未更新"的中间态。 **原子发布与原子回滚仍以变更集为单位,跨作用域一并回退**,不因作用域不同而拆分。 **跨对象校验需具备作用域意识**:例如校验"表单引用的字段在该公司是否可见/启用",而非仅校验租户级。校验清单增加「孤儿覆盖检查」(见 10.4 作用域边界规则)。 **占用锁**:配置对象进入某个变更集后,其他变更集不得再将其加入,系统应提示"该对象已在 XXX 变更集中"。占用锁的键扩展为 `(object, scope, company_id)` 组合,避免同一公司级对象被两个变更集同时占用。采用占用锁而非三方合并。 ### 10.6 无状态配置与有状态配置 > V1.1 新增。本节决定配置变更对在途业务单据的影响方式。 配置按是否持有运行时状态分为两类: | 类型 | 典型例子 | 生效规则 | | -------------- | ---------------------------------------------------- | ------------------------------------------------------------ | | **无状态配置** | 必填、显隐、只读、校验规则、显示格式、打印模板、翻译、编号规则的格式定义(前缀、日期格式、位数、补位规则) | **实时求值,永远以最新为准**。发布后立刻对所有单据生效 | | **有状态配置** | 工作流、审批节点、审批规则 | **实例创建时绑定 `config_version`**,按绑定版本执行完毕,不受后续发布影响 | **为什么有状态配置必须绑定版本。** 审批流原为 A→B→C 三级,改为 A→C 两级后回滚:若按"最新为准",已走完 C 的单据在回滚后缺失 B 级审批,已发生的业务动作无法处理;仍卡在 C 的单据则无法确定 B 级算通过还是未通过。审批流改版时,在途单据必然被此类问题撞上。 **编号规则不属于有状态配置。** 编号规则需拆为两部分理解: - 编号格式的规则部分(前缀、日期格式、位数、补位方式等)是**无状态配置**,修改后实时求值、立即生效,与必填、显隐等同类,无需版本绑定; - **计数器本身不是配置,而是运行时数据**。它需要解决的是并发安全问题(数据库序列、独立计数表或乐观锁),与配置版本机制无关,不进入 `s_config_version` 版本体系。 因此,需要版本绑定的配置仅包括工作流与审批流实例。不应为编号计数器生成版本快照。 **影响面**:版本绑定仅作用于"改版那一刻正在审批中的少数单据",新单据照常走最新版本。 **配套硬约束:** 1. **字段只能停用,不能物理删除**。10.4 校验清单中"删除或停用字段对历史数据的影响检查"升级为硬约束。 2. **保存与提交的校验强度不同**。新规则将某字段设为必填后,审批中的历史单据该字段可能为空,若保存时强制校验,该单据将既无法编辑也无法提交,形成死单。规则:**保存时降级为警告,提交/审核时强制校验**,使老单据可补填后继续流转。 3. **运行时与发布分离**。运行时永远读取已发布版本,草稿修改不影响线上。单据与流程实例记录其绑定的 `config_version`;打印模板同理,历史单据打印使用开单时的模板版本。 ### 10.7 类型注册表与校验器 > V1.1 新增。 使用**声明式类型注册表**替代散落的 if-else 判断。新增一类配置对象时,只需增加一条注册记录与一个校验器,不改引擎。 | 类型 | 例子 | 变更频率 / 风险 | 是否审批 | 生命周期 | | ------ | ---------------------------- | --------------- | ------------ | ---------------------- | | 展示型 | 列表布局、查询方案、打印模板 | 高 / 低 | 否 | 跳过测试环节,直接发布 | | 内容型 | 翻译、字典、枚举文案 | 高 / 低 | 否(轻量档) | 轻量发布,见 11.10 | | 结构型 | 字段定义、对象关系 | 低 / 高 | 是 | 校验 + 审批 | | 行为型 | 工作流、审批规则、编号规则 | 中 / 高 | 是 | 校验 + 审批 | ### 10.8 回滚语义 > V1.1 新增。 回滚 = 指针拨回上一版本,**物理上不删除任何数据**。 - 无状态配置:回滚后立即按旧版本求值。 - 有状态配置:新实例按旧版本执行,在途实例按绑定版本执行完毕。 - 存在在途实例时给出**强提示,但不硬性禁止**。管理员在回滚时具备判断力,强行拦截导致卡单才是更严重的事故。 ### 10.9 设计边界 > V1.1 新增。以下内容明确不在本期范围内,避免后续被误加: - **不新建通用审批流引擎承载"配置审批"**,复用第 15 章已有的工作流能力。 - **不自动生成配置变更的数据迁移脚本或 DDL**。结构型变更走"影响评估 + 只停用不删除"。 - **不做行级 diff,不做冲突三方合并**。 ## 11. 多语言与区域化需求 ### 11.1 多语言存储策略 > V1.1 整节重写。原"混合存储(代码资源 + 租户库)"改为三层模型,并明确角色能力边界。 多语言文本分三层存储。**注意:系统默认层(第 2 层)走数据库而非代码资源文件**,原因是"超级管理员新增语言、配置语言默认值"是运行时的、不发版的动作,代码资源文件无法承载。 | 层级 | 内容 | 存储位置 | 可修改方 | 生效方式 | | -------------------------- | ------------------------------ | --------------------------------------------------- | ------------------------------------ | ----------------------- | | 第 3 层 租户覆盖层 overlay | 该租户**改过的 key**,只存差异 | 租户数据库 `s_i18n_overlay` | 租户(白名单内)、超级管理员(全部) | 保存即生效 | | 第 2 层 系统默认层 | 系统默认翻译值,全量 | 租户数据库 `s_i18n_resource` / `s_i18n_translation` | **仅超级管理员** | 保存即生效,不发版 | | 第 1 层 硬编码兜底层 | 系统能跑起来的最小文案集 | 代码资源文件 | 开发(随版本发布) | 仅在第 2 层不可用时生效 | 关键约束: - **第 1 层不是全量翻译**,只放错误提示、语言名称本身等最小集,其唯一职责是"数据库不可用时界面仍能渲染、不白屏"。 - **租户 overlay 只存差异**,大部分租户该表是空的——空表即零初始化、租户秒级可用。 - **动态字段标签、流程节点名、字典文案等天生没有代码默认值的内容直接归入第 2 层**,不属于 overlay 概念。overlay 仅指"第 2 层已有默认值、租户要覆盖"的部分。 - 平台库不负责保存租户业务翻译。 按内容性质归类: | 内容类型 | 归属层级 | 示例 | | -------------- | ---------------------------------- | ------------------------------------------ | | 系统默认文案 | 第 2 层 | 菜单、按钮、系统提示、固定错误码 | | 租户改写文案 | 第 3 层 | 菜单显示名、按钮文案、业务校验提示 | | 租户动态配置 | 第 2 层 | 动态字段标题、表单分组、流程名称、字典翻译 | | 租户业务主数据 | 主表 + 翻译表 | 产品、分类、客户类型、供应商类型 | | 可编辑模板 | 第 2 层 / 租户数据库 | 打印模板、邮件模板、通知模板 | | 用户语言偏好 | 租户数据库用户配置,可辅以本地缓存 | 当前语言、日期格式、数字格式 | | 历史单据内容 | 业务单据快照字段 | 产品名称、客户名称、税率、单位名称 | ### 11.2 角色能力边界 > V1.1 新增,承接 9.4。 本文档中的"租户"实质上是**受限的普通用户**,不是可以自由定制的独立租户。多语言能力边界如下: | 能力 | 超级管理员 | 租户用户 | | ------------------------- | -------------------- | ---------------------- | | 新增语言 | ✅ 运行时配置,不发版 | ❌ | | 删除/停用语言 | ✅ | ❌ | | 配置语言默认值(第 2 层) | ✅ | ❌ | | 修改具体文案取值 | ✅ 全部 | ✅ 白名单内 | | 修改结果的生效范围 | 全局 | **整个租户**,非账号级 | 租户用户**不能新增语言、不能删除语言、不能配置语言包的默认值**,只能修改已有语言中某些文案的取值。修改结果对整个租户生效,租户内所有用户看到同一份文案;个人语言偏好只决定"使用哪一门语言",不决定"某个词如何翻译"。 ### 11.3 支持范围 系统设计上支持: - 简体中文 `zh-CN`; - 繁体中文 `zh-TW`; - 英文 `en-US`; - 日文 `ja-JP`; - 后续扩展其他语言。 首期实际启用语言由项目范围确定,但数据模型和接口不得写死单一语言。新增语言由超级管理员在运行时配置,不需要发版。 ### 11.4 读取与回退规则 > V1.1 修订:删除原 11.2 与 11.5 两处互相冲突的回退链,合并为唯一一条,并改为双重循环模型。 原 V1.0 的 11.2 与 11.5 对回退链描述不一致(一处写"系统代码资源"、一处写"系统基础语言"),且把"语言"和"来源"两个正交维度压成了一维。统一模型如下: ```text 语言候选 L = [用户语言, 当前公司默认语言, 租户默认语言, 系统基础语言] (去重) 来源优先 S = [租户 overlay, 公司级 overlay, 系统默认层, 硬编码兜底层, 原始 key 末段] 遍历顺序:先遍历语言,后遍历来源 for l in L: for s in S: 命中即返回 ``` **为什么要先语言后来源。** 若先遍历来源,会出现同一页面上半部分日文、下半部分中文(overlay 只有中文则出中文、默认层有日文则出日文)。ERP 中语言混屏会被当作缺陷上报,比缺翻译更严重。先遍历语言可保证整屏语言一致,全部未命中才整体降级。 **语言候选受"系统已启用语言"约束**:候选列表 = 系统已启用语言 ∩ 用户语言偏好。系统未启用某语言时,即使用户浏览器语言匹配也不得采用,应回退到系统基础语言。 代码资源与数据库资源应使用统一的语言编码和资源键。系统文案使用资源键,例如 `common.save`;动态配置和业务主数据使用对象编码、字段编码或资源 ID 关联翻译表。 缺少翻译时不得导致页面报错,应显示回退语言,并允许超级管理员查看缺失翻译清单。 ### 11.5 多语言内容类型与可覆盖白名单 > V1.1 修订:原 11.1 与 11.4 冲突(11.1 将菜单、按钮归入代码资源,隐含租户不可改;11.4 又写两者"共同覆盖")。此处统一拆分。 数据库与代码资源共同覆盖以下内容: 1. 菜单、按钮、提示和系统消息; 2. 动态字段、表单分组和流程节点; 3. 字典、分类和枚举项; 4. 产品、物料、客户分类和供应商分类; 5. 打印模板标题和固定文本; 6. 通知、邮件和消息模板; 7. 单据打印时使用的历史名称快照。 其中**允许租户覆盖**与**锁死不给改**的划分如下: | 允许租户覆盖 | 不允许租户覆盖(锁死) | | ---------------------- | ------------------------ | | 菜单显示名 | 技术错误码、异常堆栈文案 | | 按钮文案 | 日志关键字、审计术语 | | 表单/字段标签、分组名 | 权限拒绝的标准文案 | | 业务校验提示、业务消息 | 升级提示、系统状态提示 | | 打印模板抬头 | | **锁死理由**:用户报障时会复述屏幕上的错误文案,若该文案可被租户改写,运维无法用它检索日志与工单,问题定位链路会断。 **白名单授予方式**:按**模块 + 类别**批量授予,不逐 key 配置;超级管理员可对单个 key 做例外放行。 ### 11.6 业务主数据翻译 产品、分类等主数据采用主表加翻译表的方式: ```text product product_translation dictionary_item dictionary_item_translation ``` 不建议把所有翻译内容拼接在单个 JSON 字段中,以便后续查询、导入、导出、校验和维护。 ### 11.7 单据快照 单据创建或审核时,需要根据业务要求保存以下快照: - 产品编码和名称; - 规格型号; - 客户或供应商名称; - 公司名称、地址和税号; - 银行信息; - 币种和汇率; - 税率和税额; - 付款条件; - 单位名称。 历史单据展示和打印优先使用快照,不能因主数据后续改名而改变历史事实。 > V1.1 补充:快照需区分两类,名称类快照的语言维度待业务方确认(见第 22 章待确认项 14)。 - **事实性快照**:金额、税率、数量、编码、税号、地址等与语言无关的信息,必须原样存储,不因主数据后续变更而改变。 - **名称类快照**:产品名称、客户名称、单位名称等。原 11.7 只要求存快照,未说明存哪个语言。实际场景:去年以中文开单,今年客户要求补打英文版发票,快照中只有中文名。 名称类快照提供三个选项供业务方决策: | 选项 | 做法 | 评价 | | ---- | ------------------------ | -------------------------------------------- | | a | 仅存开单时的那一种语言 | 补打其他语言无法输出,财务与合规场景常不满足 | | b | 带 `lang` 维度存多份 | 最稳妥,存储量翻倍 | | c | 仅存主数据 ID + 当前翻译 | 违反"历史事实不可变"原则 | **建议折中**:按开单语言存一份,同时保留主数据 ID,允许按当前翻译补打,但单据上须标注"依据当前资料翻译"。 ### 11.8 区域化 系统分别配置语言、时区、日期格式、数字格式和币种,不将这些概念混为一谈。配置优先级为: ```text 用户设置 → 公司设置 → 租户设置 → 系统默认 ``` ### 11.9 缓存与资源治理 > V1.1 新增。以下条目为原 V1.0 缺失项,缺失会导致上线后返工。 1. **缓存**:多语言是每次渲染都读取的高频数据,必须缓存。按 `lang` 整包加载进内存(通常几十 KB),超级管理员修改默认值或租户修改 overlay 时发送缓存失效事件。 2. **单一数据源**:避免前端与后端各维护一份资源文件导致不同步。以 key 为中心单一维护,构建期分发,或由后端统一提供 i18n 接口。 3. **key 命名规范**:使用语义化 key,如 `sales.order.status.pending`。**禁止使用英文原文作为 key**——以原文为 key 时,修改一次英文就要改动所有语言包。 4. **Excel 导入导出**:超级管理员批量配置翻译、批量查找替换的刚需。缺失此能力,翻译运营最终会退化为直接改数据库。 5. **zh-TW 独立维护**:不得依赖简体自动转繁体。打印/列印、软件/軟體、文件/檔案 等用词差异必须独立维护。 6. **废弃 key 治理**:废弃 key 标记为 `deprecated` 后静默保留,版本升级时不得硬删除,由清理工具另行处理。 7. **占位符与复数**:至少支持 ICU MessageFormat(如 `{count, plural, ...}`)。中文无复数变化,但英文、俄文有,后期补齐成本高。 ### 11.10 翻译与配置版本体系的关系 > V1.1 新增。本节落定"翻译是否纳入配置版本体系"。 **结论:翻译纳入同一套版本模型(10.4 元模型、10.5 变更集),但发布门槛设为最低档(轻量档)。** 排除理由: - ❌ **不走严格审批**(同结构型):修改错别字也要等审批,运营会绕过系统直接改数据库。 - ❌ **不独立于版本体系之外**:否则没有发布/回滚、没有审计、没有批量导入导出;且翻译与配置存在联动(新增字段时,字段标签翻译需与字段定义一同发布),两套体系无法实现原子发布,与 10.5 的变更集机制直接冲突。 轻量档的具体形态: | 能力 | 翻译是否具备 | | ----------------------------------- | ------------ | | 版本快照、一键回滚 | ✅ | | 变更审计(谁改的、什么时候改的) | ✅ | | 可进入变更集、与配置原子发布 | ✅ | | 走审批才能生效 | ❌ | | 必须走「草稿→校验→测试→发布」全链路 | ❌ | **热修复通道**:翻译属于高频、低风险、改错字类的操作,必须支持"改完立刻生效"的快速通道,10.4 的完整生命周期对其过重。翻译与「展示型」配置同属轻量档。 ## 12. 核心业务需求 ### 12.1 基础资料 基础资料包括: - 客户、供应商和其他往来单位; - 产品、物料、服务和分类; - 单位、仓库、库位和批次规则; - 价格表、付款条件和结算方式; - 税率、币种和汇率; - 银行账户和开票信息; - 业务员、部门和负责人。 每项资料需要明确: - 集团共享还是公司专属; - 谁可以查看和使用; - 是否允许停用; - 是否允许被历史单据引用; - 是否支持多语言; - 是否需要版本或有效期。 ### 12.2 销售管理 销售流程至少支持: ```text 报价 → 销售订单 → 审批 → 发货/出库 → 开票 → 收款/结算 ``` 销售单据必须记录销售公司、销售组织、客户、仓库、币种、价格和税务信息。 ### 12.3 采购管理 采购流程至少支持: ```text 采购申请 → 采购订单 → 审批 → 收货/入库 → 发票 → 付款/结算 ``` 采购公司、采购组织、收货仓库、供应商和结算主体可以按业务规则分别指定。 ### 12.4 库存管理 库存管理至少支持: - 入库、出库、调拨和退货; - 库存锁定和释放; - 盘点和库存调整; - 批次、保质期和序列号; - 公司间调拨; - 委托、寄售和其他库存所有权; - 库存成本和库存余额。 库存数据必须明确公司、仓库、货主、产品和计量单位。 ### 12.5 财务和结算 财务能力至少包括: - 公司独立账簿; - 会计年度和期间; - 应收、应付和往来核销; - 费用、收款、付款和预收预付; - 汇率和币种处理; - 单据结算状态; - 记账和反记账; - 公司级财务报表。 财务单据必须归属公司和账簿。已过账数据不得通过普通编辑直接修改。 ### 12.6 公司间交易 系统预留公司间交易能力,支持: - 公司间销售和采购; - 公司间调拨; - 代收代付; - 内部往来; - 公司间应收应付; - 集团内部抵销标识。 公司间交易应记录: ```text source_company_id target_company_id intercompany_transaction_id ``` ## 13. 数据模型要求 ### 13.1 租户注册信息 首期可以使用配置文件维护以下信息,后续也可以将其迁移到平台库: ```text tenant_registry tenant_database tenant_module_license tenant_migration_task tenant_backup_task tenant_domain_mapping ``` 平台管理员、授权和运维任务是否进入平台库,根据部署模式决定;不影响租户数据库内的用户、公司和业务数据。 ### 13.2 租户数据库核心对象 ```text s_user s_role s_user_role s_company s_organization s_warehouse s_ledger s_user_company s_user_organization s_module s_field s_module_schema s_workflow s_permission s_i18n_resource s_i18n_translation s_i18n_overlay s_audit_log ``` > V1.1 新增以下配置版本与多语言对象(对应 10.4、10.5、11.1): ```text s_config_object s_config_version s_config_release s_change_set s_change_set_item s_i18n_release ``` 其中 `s_i18n_overlay` 只保存租户改过的 key(11.1 第 3 层),`s_i18n_release` 保存翻译版本快照(11.10)。 ### 13.3 业务表通用字段 公司级业务表原则上包括: ```text company_id organization_id 可选 created_by created_at updated_by updated_at status ``` 库存业务根据场景增加: ```text warehouse_id owner_type owner_id ``` 财务业务根据场景增加: ```text ledger_id fiscal_year fiscal_period currency_code exchange_rate ``` ### 13.4 数据库设计边界 核心字段使用关系列;动态字段根据访问频率采用 JSON 或扩展值表。不得为了追求绝对动态而将所有字段转换为 `entity_id + field_name + field_value` 的全量 EAV 结构。 ## 14. 数据库路由和运行时需求 ### 14.1 请求路由 请求处理流程: ```text 请求进入 → 解析域名、登录信息或令牌 → 识别租户 → 读取租户注册表(配置文件或平台库) → 获取租户数据库标识 → 选择数据源和连接池 → 设置公司和组织上下文 → 执行业务查询或写入 → 清理上下文 ``` ### 14.2 数据源管理 系统应支持: - 按租户动态创建数据源; - 连接池复用和空闲释放; - 租户数据库健康检查; - 连接失败重试和熔断; - 数据库只读状态; - 租户迁移期间禁止普通写入; - 日志记录租户、数据库和请求编号。 ### 14.3 注册表实现和跨租户限制 `TenantRegistry` 至少支持文件实现和平台库实现两种方式。文件更新应具备格式校验、版本号和原子替换能力;平台库更新应具备事务和审计能力。 日常业务接口禁止跨租户查询和跨租户事务。平台级统计通过事件、CDC 或分析库实现,不在业务请求中遍历全部租户数据库。 ## 15. 工作流与审批需求 ### 15.1 流程模型 工作流采用状态机模型,包括: - 草稿; - 提交; - 审批中; - 已通过; - 已驳回; - 已取消; - 已完成; - 已关闭。 ### 15.2 审批节点 审批人来源支持: - 指定用户; - 指定角色; - 部门负责人; - 公司负责人; - 业务负责人; - 发起人上级; - 按金额、公司、组织或字段条件计算。 ### 15.3 业务动作 流程节点可以触发: - 状态变更; - 发送通知; - 写入审计记录; - 生成下一张业务单据; - 锁定或释放库存; - 触发打印或导出; - 调用受控的业务处理器。 库存、财务和结算等关键动作必须经过业务处理器,不允许只依赖通用配置执行任意写入。 ## 16. 审计、日志和可追溯性 系统应记录: - 登录、退出和租户切换; - 公司和组织切换; - 配置创建、发布和回滚; - 权限授予、撤销和变更; - 单据创建、修改、提交、审批和作废; - 库存和财务关键动作; - 导出、打印、备份和恢复; - 平台管理员跨租户操作。 审计记录至少包含: ```text operator_id tenant_code company_id operation_type object_type object_id request_id before_value after_value created_at ``` ## 17. 备份、恢复和迁移需求 ### 17.1 租户级备份 系统支持单个租户执行: - 全量备份; - 增量备份; - 指定时间点恢复; - 备份文件校验; - 备份保留策略; - 备份下载或转移; - 恢复到临时数据库。 ### 17.2 租户迁移 迁移流程: ```text 申请迁移 → 检查租户状态 → 创建迁移前备份 → 切换只读 → 导出或复制数据库 → 校验数据和版本 → 更新租户连接文件或注册表记录 → 健康检查 → 恢复正常访问 ``` ### 17.3 数据库版本 每个租户数据库必须维护当前结构版本。升级任务支持: - 版本扫描; - 分批升级; - 失败重试; - 单租户暂停升级; - 升级前备份; - 执行记录和耗时; - 失败原因和人工处理标记。 ## 18. 报表和分析需求 ### 18.1 公司级报表 首期支持: - 销售明细和汇总; - 采购明细和汇总; - 库存余额和收发存; - 应收应付; - 费用和结算; - 公司利润和经营分析。 ### 18.2 集团级报表 支持按公司、公司树、组织、区域、币种和期间汇总。集团报表需要考虑: - 不同公司的本位币; - 汇率折算; - 公司间交易识别; - 内部往来抵销; - 集团科目映射; - 合并范围和有效期。 ### 18.3 分析数据来源 日常交易查询使用租户数据库。跨公司和大数据量分析可通过事件或 CDC 同步到分析库,避免报表查询影响交易库。 ## 19. 非功能需求 ### 19.1 性能 - 常用列表查询应支持分页、排序和条件下推; - 查询和数据权限尽量在 SQL 层完成; - 不能在应用层加载全量数据后再过滤; - 大型报表支持异步生成; - 导入导出支持分批处理和进度反馈; - 租户数据源应具备连接池上限和空闲回收机制。 ### 19.2 可维护性 - 配置和业务逻辑分离; - 租户数据库支持独立升级和恢复; - 数据库迁移脚本可重复执行或具备明确版本记录; - 核心业务规则集中实现; - 动态模块不复制大量相同接口和页面代码。 ### 19.3 可扩展性 - 支持新增公司和子公司; - 支持新增语言(由超级管理员运行时配置,不需要发版); - 支持新增模块、字段和流程; - 支持独立数据库实例和外部数据库; - 支持后续拆分库存、财务和分析服务; - 支持公司级数据导出和迁移。 ### 19.4 一致性 - 关键业务操作必须幂等; - 库存和财务更新必须有明确事务边界; - 已审核、已过账和已结算单据不能普通修改; - 失败操作必须可重试或进入人工处理队列; - 配置发布不能产生半发布状态(由 10.5 变更集的原子发布保证)。 ## 20. 实施阶段建议 ### 阶段一:平台基础和租户底座 - 租户连接配置或注册表; - 租户开通和数据库路由; - 数据库初始化和版本迁移; - 用户、角色、公司和组织; - 多语言基础资源; - 审计日志; - 备份和健康检查。 ### 阶段二:动态配置底座 - 模块和字段元数据; - 动态列表和查询; - 动态表单; - 字典和编号规则; - 配置版本、发布和回滚; - 基础权限和数据范围。 ### 阶段三:核心业务 - 客户、供应商和产品; - 销售和采购; - 仓库、库存和调拨; - 基础结算; - 工作流和审批。 ### 阶段四:财务和集团能力 - 账簿和期间; - 应收应付; - 费用和付款; - 公司间交易; - 集团汇总报表; - 汇率和合并分析。 ### 阶段五:增强能力 - 分析库和数据同步; - 高级打印模板; - 规则引擎; - 外部系统接口; - 独立数据库实例; - 私有化部署和租户迁移工具。 ## 21. 验收标准 ### 21.1 租户隔离 - 新建两个租户并分别初始化数据库; - 租户 A 的业务查询不能读取租户 B 的数据; - 平台管理员切换租户有审计记录; - 单个租户可以独立备份和恢复; - 单个租户数据库可以迁移而不影响其他租户。 ### 21.2 多公司 - 同一租户可以创建总部、子公司和分公司; - 用户可被授权一个或多个公司; - 公司级单据必须带 `company_id`; - 基础资料可设置集团共享或公司专属; - 公司级库存、账簿和报表相互隔离; - 集团管理员可查看授权范围内的汇总数据。 ### 21.3 动态配置 - 可新增自定义字段并在列表、表单和详情中使用; - 可配置字段显隐、只读、必填和权限; - 可配置流程并完成提交、审批、驳回和完成; - 配置发布后可回滚到上一版本; - 配置变更不会破坏历史单据展示。 ### 21.4 多语言 - 用户可切换界面语言; - 动态字段、字典和流程名称可翻译; - 产品和基础资料支持多语言名称; - 缺少翻译时按规则回退; - 历史单据使用名称和税率快照; - 打印模板可按语言输出。 ### 21.5 运行维护 - 可查看每个租户数据库版本; - 可执行租户级升级和失败重试; - 可查看迁移、备份和恢复任务状态; - 连接异常和数据库不可用时有明确错误提示; - 大型跨公司报表不会阻塞日常单据操作。 ## 22. 待确认事项 以下内容在进入详细设计前需要由业务方确认: 1. 首期实际支持哪些语言; 2. 公司是否需要独立财务账簿和独立税务主体; 3. 是否首期实现公司间销售、采购和内部结算; 4. 首期支持哪些库存所有权类型; 5. 是否需要批次、序列号和保质期管理; 6. 租户数据库使用同一实例还是按规模分级部署; 7. 数据库备份保留周期和恢复时间目标; 8. 集团报表是否需要汇率折算和内部抵销; 9. 是否需要外部财务、税务、OA、CRM 或电商接口; 10. 哪些动态字段需要进入正式列或统计索引; 11. 业务配置是否需要测试环境和审批发布(V1.1 已按 10.7 类型注册表给出分类门槛,仍需业务方确认接受度); 12. 私有化部署是否作为首期交付范围; 13. 租户可覆盖的系统文本白名单范围是否完整(见 11.5,需确认锁死清单); 14. 历史单据名称快照是否需要支持多语言补打(见 11.7,选项 a/b/c 需业务方拍板); 15. 有状态配置(审批流、工作流)在途单据采用"实例绑定版本"的接受度(见 10.6); 16. 翻译变更纳入配置发布流程后,运营流程是否可配合(见 11.10); 17. 硬编码兜底层(11.1 第 1 层)最小文案集的具体范围。 ## 23. 结论 平台库不是业务运行的硬性前提。对于租户数量较少、每个客户独立部署或由运维维护配置文件的场景,使用租户注册文件即可;当需要在线租户管理、集中运维、多实例同步或统一平台权限时,再启用平台库。无论采用哪种注册方式,业务代码保持一套,租户业务数据库保持独立。 系统采用以下总体方案: ```text 代码 = 一套,租户差异通过配置、元数据和受控插件实现 一个租户 = 一个独立数据库 一个租户 = 多个公司、子公司和组织 公司 = 业务、库存和财务归属边界 组织 = 权限、审批和经营管理边界 基础资料 = 支持集团共享或公司独立 配置能力 = 动态字段、表单、流程、权限和打印 多语言 = 界面、配置、主数据和历史单据快照(三层存储:租户覆盖 / 系统默认 / 硬编码兜底) 租户 = 受限用户,可改文案取值,不可新增语言 超级管理员 = 运维持有,不交付客户,负责语言新增与默认值配置 配置发布 = 以变更集为单元,跨对象校验,原子发布与原子回滚 配置变更 = 无状态实时生效,有状态绑定版本跑完 集团分析 = 公司维度汇总,必要时同步到分析库 核心业务 = 由代码保证,不完全交给低代码配置 ``` 最终目标不是把 ERP 做成一个万能低代码工具,而是建设一个具有稳定业务内核、清晰数据边界、可配置扩展能力和可独立运维能力的企业业务平台。 | | | | ---- | ---- | | | | | | | | | | | | | | | |