From ffe8a0900cbce7b9fc2556e14f2fcd79891218e9 Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Mon, 10 Aug 2026 15:36:50 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 二期/README.md | 4 +- 二期/二期费用项目数据归属决策记录.md | 120 +++++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 二期/二期费用项目数据归属决策记录.md diff --git a/二期/README.md b/二期/README.md index 233682c..196707b 100644 --- a/二期/README.md +++ b/二期/README.md @@ -6,7 +6,7 @@ - 二期继续按“平台—客户”两级开发。`tenant_id > 0` / `tenantId` 当前表示客户 ID,用于客户隔离;`tenant_id=0` 是平台技术作用域。 - 不新增真实租户、租户选择器或租户级 RBAC,也不把兼容字段重定义为上级租户。历史路径、字段与配置名继续保留。 -- 平台公共仓库、快递公司、托盘、库位等公共资源统一归属平台技术作用域 `tenant_id=0`,不绑定客户;客户往来单位、订单、文件和费用继续按所属客户 `tenant_id>0` 严格隔离。`10001` 是客户 ID,不得用于公共资源归属。 +- 平台公共仓库、快递公司、托盘、库位和费用项目统一归属平台技术作用域 `tenant_id=0`,不绑定客户;客户往来单位、订单、文件和费用明细仍按所属客户 `tenant_id>0` 严格隔离,费用明细引用公共 `fee_item_id`。`10001` 是客户 ID,不得用于公共资源归属。 ## 文档 @@ -16,6 +16,7 @@ - [二期开发规划:头程到仓](二期开发规划.md) - [二期头程计费模块规划](二期计费财务模块规划.md) - [二期头程计费需求确认表](二期计费财务需求确认表.md) +- [二期费用项目数据归属决策记录](二期费用项目数据归属决策记录.md) - [二期头程计费需求确认表(Excel,保留历史文件名)](二期计费财务需求确认表.xlsx) - [二期产品待确认事项(发产品填写)](二期产品待确认事项.md) - [二期开发进度表](二期开发进度表.md) @@ -57,6 +58,7 @@ - [二期开发进度表](二期开发进度表.md) - [二期头程计费模块规划](二期计费财务模块规划.md) - [二期头程计费需求确认表](二期计费财务需求确认表.md) +- [二期费用项目数据归属决策记录](二期费用项目数据归属决策记录.md) - [二期产品待确认事项](二期产品待确认事项.md) - [二期需求确认清单:产品与业务确认](二期需求确认清单.md) diff --git a/二期/二期费用项目数据归属决策记录.md b/二期/二期费用项目数据归属决策记录.md new file mode 100644 index 0000000..7c520a3 --- /dev/null +++ b/二期/二期费用项目数据归属决策记录.md @@ -0,0 +1,120 @@ +# 二期费用项目数据归属决策记录 + +> 形成日期:2026-08-10 +> 状态:已确认 +> 决策范围:`费用类型.xls` 中 110 条费用类型的数据归属、初始化和存量迁移 +> 关联确认项:[二期 V2 需求确认清单](二期V2需求确认清单.md) C6、[二期头程计费需求确认表](二期计费财务需求确认表.md) P2-Q14 + +## 一、最终结论 + +- 费用项目是平台公共主数据,`fl_fee_item.tenant_id` 固定为 `0`,全平台使用同一套费用编码和项目定义。 +- 客户费用明细仍是客户隔离数据,`fl_inbound_fee_detail.tenant_id > 0`;其 `fee_item_id` 直接引用 `tenant_id = 0` 的公共费用项目。 +- 不再按客户复制费用项目,不建立“客户 ID + 模板版本”的初始化副本,也不允许用客户级费用项目承接公共定义。 +- `tenant_id = 0` 只是平台技术作用域,不增加用户可见的租户层级、租户选择器或租户级运营流程。 +- 本结论只确定费用项目主数据归属。计费单位、币种、税率、自动/人工、触发节点、价格规则和结算范围仍按 C6/P2-Q14 单独确认;110 条公共项目处于 `ACTIVE` 不等于 110 条都自动参与二期计费。 + +## 二、源文件核对 + +受控源文件:`费用类型.xls`。 + +| 核对项 | 结果 | +|---|---| +| SHA-256 | `395C9CA71816E79C7745E224E63CF79A4AB782140364F63C8374B396DF38CDB4` | +| 工作表 | `费用类型` | +| 数据范围 | 1 行表头 + 110 条数据,共 111 行、13 列 | +| 国内/国际 | 国内 84 条、国际 26 条 | +| 真实表头 | 分类、国内国际、费用类型名称、货柜应付、货柜应收、仓储应付、仓储应收、平摊费用、说明、创建人、创建日期、更新人、更新日期 | +| 源编码 | 源表没有费用编码列 | +| 语义重复 | `国内国际 + 费用类型名称` 无重复 | + +源表不包含计费单位、币种、税率、价格、公式或触发节点,不能从费用名称推断这些配置。 + +## 三、初始化口径 + +### 3.1 稳定标识 + +- 按受控源表数据行序生成固定编码 `FEE_TYPE_001` 至 `FEE_TYPE_110`。编码一经发布不得因排序、展示名称或分类调整重新生成。 +- 固定主键为 `193000000001000001` 至 `193000000001000110`,编码序号与主键末三位一一对应。 +- 110 条记录全部写入 `tenant_id = 0`、`status = ACTIVE`、`deleted = 0`。 +- `fee_code` 使用平台全局唯一索引,不再使用 `(tenant_id, fee_code)` 客户内唯一索引。 + +### 3.2 字段映射 + +| Excel 字段 | 数据库字段 | 规则 | +|---|---|---| +| 分类 | `category` | 去除首尾空白,保留源值 | +| 国内国际 | `trade_scope` | 国内映射 `DOMESTIC`,国际映射 `INTERNATIONAL` | +| 费用类型名称 | `fee_type_name` | 去除首尾空白,保留业务名称 | +| 货柜应付/货柜应收 | `pickup_payable` / `pickup_receivable` | “参与”映射 `1`,其他值映射 `0` | +| 仓储应付/仓储应收 | `warehouse_payable` / `warehouse_receivable` | “参与”映射 `1`,其他值映射 `0` | +| 平摊费用 | `allocation_fee` | “参与”映射 `1`,其他值映射 `0` | +| 说明 | `description` | 空值写 `NULL`,非空保留源值 | +| 创建人/创建日期 | `created_by`、`created_by_name`、`created_at` | 纯数字创建人可写入 ID;原文本始终保存在名称字段;日期按源日期零时刻写入 | +| 更新人/更新日期 | `updated_by`、`updated_by_name`、`updated_at` | 有源值时保留;缺失时沿用创建信息,避免用迁移执行时间覆盖历史 | + +若目标固定主键或固定编码已有完全一致的公共记录,重复执行保持原记录及其历史字段不变;若已有记录状态、删除标记或业务语义不同,按冲突处理,不自动覆盖。 + +## 四、存量迁移 + +迁移采用“先预检、后写入”的安全顺序,不对客户级费用项目直接执行批量 `UPDATE tenant_id = 0`。 + +1. 建立 110 条临时种子并校验总数、国内/国际数量、固定编码和语义键唯一性。 +2. 预检固定主键占用、平台同码异义、平台同义异码、平台空编码和客户存量映射完整性。 +3. 客户级项目只在完整业务语义一致时允许映射。空编码和历史兼容编码 `MANUAL_<原ID>` 可按 `trade_scope + fee_type_name` 映射;其他异码、字段差异或无法匹配项均中止。 +4. 预检费用明细归属:明细必须属于客户;迁移前若明细引用客户级项目,该项目必须属于同一客户。任何跨客户引用均中止。 +5. 幂等插入缺失的公共费用项目,建立“旧客户项目 ID -> 固定公共项目 ID”临时映射。 +6. 先更新 `fl_inbound_fee_detail.fee_item_id`,再删除已完成映射的客户级主数据,保持外键始终有效。 +7. 将 `uk_fee_item_code` 重建为全局单列唯一索引,并将 `fee_code` 收紧为非空。 + +冲突时脚本先返回冲突行再 `SIGNAL SQLSTATE '45000'`。结果集使用以下 `conflict_type`: + +- `FIXED_ID_CONFLICT` +- `PUBLIC_CODE_CONFLICT` +- `PUBLIC_SEMANTIC_CONFLICT` +- `PUBLIC_EMPTY_CODE` +- `UNMAPPED_CUSTOMER_ITEM` +- `CUSTOMER_CODE_CONFLICT` +- `CUSTOMER_SEMANTIC_CONFLICT` +- `CROSS_CUSTOMER_DETAIL_REFERENCE` + +不得绕过冲突预检继续执行,也不得通过名称模糊匹配、临时改码或忽略历史引用来强行合并。冲突应先导出、由业务确认唯一映射,再调整受控迁移脚本。 + +## 五、幂等与强校验 + +同一版本脚本重复执行必须满足: + +- 110 条固定 ID 和固定编码已存在时不重复插入,不覆盖可保留的创建、更新历史。 +- 不再存在 `tenant_id > 0` 的 `fl_fee_item`。 +- 110 条固定公共项目全部为 `tenant_id = 0`、`ACTIVE`、`deleted = 0`。 +- `uk_fee_item_code` 恰好是 `fee_code` 单列全局唯一索引,`fee_code` 非空。 +- 所有费用明细 `tenant_id > 0`,且引用的费用项目 `tenant_id = 0`。 +- 固定编码、固定主键、国内 84 条、国际 26 条和合计 110 条保持一致。 + +模块迁移位于 `firstleg/src/main/resources/db/phase2-published-freight-detail-migration.sql`;测试和存量环境仍只通过 `deploy/sql/头程数据库统一增量-MySQL8.sql` 执行。两个入口必须保持相同种子和迁移断言。 + +## 六、范围边界 + +本决策不扩展以下能力: + +- 应收应付、账龄、授信、账单、对账、收付款、核销、发票和税务申报。 +- 汇率结算、本位币折算、会计科目、凭证、总账、利润和法定财务报表。 +- 仅为覆盖 110 条费用而建设的通用计费表达式、复杂审批或客户自定义费用平台。 +- 在初始化脚本中补造计费单位、默认币种、税率、价格、公式、触发节点或自动计费规则。 + +## 七、验证记录 + +- 已只读核对受控 Excel 的工作表、13 个表头、110 条记录、84/26 范围和 SHA-256。 +- 已对模块迁移和统一增量做静态 SQL 审查,并核对两处 110 条种子完全一致。 +- 本地未启动 Java、Nacos 或 MySQL,也未连接测试环境执行数据库变更;因此尚无真实存量数据冲突结果、外键重映射结果或重复执行数据库证据。 +- 上线前先用只读查询核对存量规模并完成备份;实际冲突预检由统一增量在任何费用数据改写前执行。出现冲突结果和 `SIGNAL` 时必须停止,预检无冲突后脚本才进入外键重映射与初始化,最终以末尾强校验和唯一 `PASS` 为准。 + +## 八、确认记录 + +| 决策项 | 最终结论 | 状态 | +|---|---|---| +| 数据归属 | `fl_fee_item.tenant_id = 0`,平台公共主数据 | 已确认 | +| 客户费用明细 | `tenant_id > 0`,引用公共 `fee_item_id` | 已确认 | +| 初始化范围 | Excel 110 条全部初始化为 `ACTIVE` 公共项目 | 已确认 | +| 编码策略 | `FEE_TYPE_001` 至 `FEE_TYPE_110`,固定主键一一对应 | 已确认 | +| 客户级存量处理 | 完整预检、外键重映射、删除已映射副本;冲突中止 | 已确认 | +| 计费字段与规则 | 继续由 C6/P2-Q14 单独确认,不从 Excel 推断 | 未被本决策扩大 |