From 33b9b00bb0c61052a1e37191bcddeb2b1d15a936 Mon Sep 17 00:00:00 2001 From: liuwenxin <1009266660@qq.com> Date: Tue, 20 Oct 2026 10:55:57 +0800 Subject: [PATCH] =?UTF-8?q?docs(tplus):=20=E6=96=B0=E5=A2=9E=20T+12.3=20?= =?UTF-8?q?=E5=85=AD=E7=B1=BB=E5=AD=97=E6=AE=B5=E6=98=A0=E5=B0=84=E8=8D=89?= =?UTF-8?q?=E6=A1=88=E4=B8=8E=E9=9C=80=E6=B1=82=E6=B8=85=E5=8D=95=20v1.5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 全量解析 T+12.3 数据字典(1,457 页 / 931 表 / 21,019 字段,0 失败),按 v1.4 的 75 项逐项回填 T+ 候选字段、类型、枚举与系统目标列;必须项候选覆盖率 91.4%。v1.5 补齐 IT 收敛表(13 项 + 1 组业务裁决)与不覆盖字段 12 条,并修复 v1.4 单 sheet 与 21 项/#20 笔误。 Co-Authored-By: Claude Code --- docs/T+字段映射草案_v0.1_2026-10-20.md | 289 ++++++++++++++++++ ...接数据需求清单_v1.5_2026-10-20.xlsx | Bin 0 -> 32007 bytes 2 files changed, 289 insertions(+) create mode 100644 docs/T+字段映射草案_v0.1_2026-10-20.md create mode 100644 docs/T+对接数据需求清单_v1.5_2026-10-20.xlsx diff --git a/docs/T+字段映射草案_v0.1_2026-10-20.md b/docs/T+字段映射草案_v0.1_2026-10-20.md new file mode 100644 index 0000000..7b041a6 --- /dev/null +++ b/docs/T+字段映射草案_v0.1_2026-10-20.md @@ -0,0 +1,289 @@ +# T+ 12.3 字段映射草案(v0.1,2026-10-20) + +> 本文仅记录字段级事实与页面索引,不复制厂商文档正文。 +> 基线:`docs/T+对接数据需求清单_v1.4_2026-10-19.xlsx`(75 项)+ v1.3 IT 18 项 + 《T+12.3数据字典》。 + +## 0. 结论摘要 + +- 覆盖:清单 **75/75** 项均已给出 T+ 侧候选字段与系统目标列; +- 状态分布:候选待确认 42 / 字典明确 23 / 未检出 9 / 需 IT 1; +- 数据字典无法让 IT 18 项中的任何一项完全闭环;但 9 项可改写为「候选字段选择题」,6 项部分可答,2 项纯 IT,1 项转业务。 +- 收敛后:**13 项 IT 待确认 + 1 组业务裁决**(见第 12 节)。 +- 关键缺口:人员工号/入职日期/试用期无字段、客户 status 缺失、回款 payment_method/confirm_status 待补、明细行无显式行号、无源端更新时间与负向事件模型。 + +## 1. 编制说明与证据等级 + +| 标记 | 含义 | +| --- | --- | +| `D` | 字典明确 | +| `D?` | 候选待确认 | +| `IT` | 需 IT | +| `B` | 需业务 | +| `S` | 系统自维护 | +| `N` | 未检出 | + +- `D` 仅用于字段存在、类型明确且语义直接匹配的项;涉及「取哪个字段 / 业务口径」一律标 `D?` 或 `IT`。 +- 字典来源为 T+ 12.3 SchemaDoc;同一字段可能标注 `T+12.1/12.2/12.3` 版本,映射按 12.3 可用为准。 + +## 2. 公共字段与同步元数据 + +| 序号 | 数据项 | T+ 表.字段(字典) | T+ 类型/长度 | 枚举/取值 | 系统目标表.字段 | 转换/清洗规则 | 必要性 | 确认状态 | 来源/字典页 | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| 1 | T+ 原始单据号 / 档案编码 | 各表 code(人员/存货/客户/订单/出库/收付款单均有) | nvarchar(30~64) | — | personnel/products/customers/businesses/shipments/receipts.source_no | TRIM;作废重开是否换号待 IT(#4) | 必须 | D? | AA_Person.code、AA_Inventory.code、AA_Partner.code、SA_SaleOrder.code、SA_SaleDelivery.code、ARAP_ReceivePayment.code | +| 2 | T+ 系统内部标识 | 各表 id(整型主键) | int(4) | — | 六表 t_plus_id | int → 字符串存储;辅助对账/改名追溯 | 建议 | D | 各表 id(主键) | + +系统侧六张主表已预留 `source_no / t_plus_id / sync_batch_no / synced_at`;`source_no` 当前为普通索引,IT 确认幂等键后升级唯一约束。 + +## 3. 人员档案 + +人员主档;隶属关系需经部门树/部门负责人推断,T+ 无直属上级字段。 + +| 序号 | 数据项 | T+ 表.字段(字典) | T+ 类型/长度 | 枚举/取值 | 系统目标表.字段 | 转换/清洗规则 | 必要性 | 确认状态 | 来源/字典页 | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| 1 | 人员唯一编码(工号)★ | AA_Person.code | nvarchar(32) | — | personnel.source_no(建议补 personnel_code) | TRIM;编码优先、姓名辅助核对;是否即工号待 IT(#19) | 必须 | D? | AA_Person.code(编号) | +| 2 | 姓名 | AA_Person.name | nvarchar(200) | — | personnel.personnel_name | TRIM;仅辅助核对,不作唯一键 | 必须 | D | AA_Person.name(名称) | +| 3 | 在职状态 | AA_Person.disabled | tinyint(1) | 0 启用 / 1 停用(候选) | personnel.status(1 在职 / 0 离职) | disabled=1 → 0;无离职日期字段,离职时间需 IT 确认 | 必须 | D? | AA_Person.disabled(停用) | +| 4 | 是否试用期 | 未检出 | — | — | personnel.is_probation | T+ 人员档案无试用期字段;系统内人工维护或按入职日期规则推导 | 必须 | N | AA_Person 全表检索无 probation/试用 字段 | +| 5 | 入职日期 | 未检出(仅 madeDate 制单日期、birthday 出生日期) | — | — | personnel.hire_date | T+ 无入职日期字段;确认是否有自定义项承载,否则人工维护 | 必须 | N | AA_Person 全表检索无 hire/entry/入职 字段 | +| 6 | 联系电话 | AA_Person.mobilePhoneNo / officePhoneNo | nvarchar(20) / nvarchar(100) | — | personnel.phone | 优先 mobilePhoneNo,空则 officePhoneNo;日志脱敏 | 建议 | D | AA_Person.mobilePhoneNo(手机)、officePhoneNo(办公电话) | +| 7 | 业务员 ↔ 营销经理隶属关系 | AA_Person.iddepartment → AA_Department.idparent / iddirector | int(4) | — | personnel.manager_id | T+ 人员档案无直属上级字段;可经部门树/部门负责人推断,规则待确认;否则系统人工指定 | 必须 | D? | AA_Person.iddepartment(部门id);AA_Department.idparent(上级id)、iddirector(部门负责人) | +| 8 | 人员负责区域 / 产品辐射范围 | 未检出(可用 priuserdefnvc* 自定义项承载,需 IT 确认) | — | — | personnel_regions.region_name | 无专门字段则系统内人工维护 | 建议 | N | AA_Person 无区域/辐射范围字段 | +| 9 | 银行账户名 / 账号 / 开户行 | 未检出(AA_Partner 有银行账号字段,人员档案无) | — | — | 暂不落库 | 一期不采集;如后续代发工资再扩展 | 可选 | N | AA_Person 无银行账户字段 | + +## 4. 产品档案 + +产品主档不含库存量与售价,数量取现存量表、价格取价目表/订单明细。 + +| 序号 | 数据项 | T+ 表.字段(字典) | T+ 类型/长度 | 枚举/取值 | 系统目标表.字段 | 转换/清洗规则 | 必要性 | 确认状态 | 来源/字典页 | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| 1 | 产品名称 | AA_Inventory.name | nvarchar(200) | — | products.product_name | TRIM;与规格型号组成系统组合唯一键 | 必须 | D | AA_Inventory.name(名称) | +| 2 | 规格型号 | AA_Inventory.specification | nvarchar(200) | — | products.spec_model | 空值归一为空串 | 必须 | D | AA_Inventory.specification(规格型号) | +| 3 | 计量单位 | AA_Inventory.idunit → 计量单位表 | int(4) | — | products.unit | 按 idunit join 单位表取名称;单位表名待索引确认 | 建议 | D? | AA_Inventory.idunit(计量单位id)、idunitgroup | +| 4 | 数量 | ST_CurrentStock.baseQuantity(现存量) | decimal(13) | — | products.stock_quantity | 按存货+仓库汇总;语义(现存量/在途/累计销量)待 IT(#12) | 必须 | D? | ST_CurrentStock.baseQuantity(主计量数量);AA_Inventory 无库存量字段 | +| 5 | 销售单价 | AA_InventoryPrice(零售价/批发价)、AA_InventoryUnitPrice.retailPrice;订单明细实际成交价 | decimal(13~17) / nvarchar(1000) 公式 | — | products.sale_price | 产品档案参考价取价目表;绩效以订单/发货明细实际单价为准 | 必须 | D? | AA_InventoryPrice、AA_InventoryUnitPrice;AA_Inventory 无销售单价字段 | +| 6 | 产品分类(类目) | AA_Inventory.idinventoryclass → AA_InventoryClass.name | int(4) | — | products.product_category | T+ 分类仅辅助判定市政水利/轨交;系统分类人工维护不覆盖 | 必须 | D? | AA_Inventory.idinventoryclass(存货分类id)、AA_InventoryClass.name | +| 7 | 计量单位换算关系(如存在) | AA_Inventory_MultiUnit / AA_InventoryUnitPrice.rateOfExchange | decimal(13) | — | 暂不实现(系统单单位存储) | 如业务有多单位换算需求,另行设计 | 可选 | D? | AA_Inventory_MultiUnit、AA_InventoryUnitPrice.rateOfExchange(换算率) | + +## 5. 业务单据(销售订单) + +成本额在订单明细仅有最新成本,出库明细才有成本金额;销售额需按数量×单价计算。 + +| 序号 | 数据项 | T+ 表.字段(字典) | T+ 类型/长度 | 枚举/取值 | 系统目标表.字段 | 转换/清洗规则 | 必要性 | 确认状态 | 来源/字典页 | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| 1 | 订单单号 | SA_SaleOrder.code | nvarchar(30) | — | businesses.source_no | TRIM;不得写入内部 business_no | 必须 | D | SA_SaleOrder.code(编号) | +| 2 | 业务(订单)日期 | SA_SaleOrder.voucherdate | datetime(8) | — | businesses.business_date | 截断为 DATE | 必须 | D | SA_SaleOrder.voucherdate(单据日期) | +| 3 | 客户标识 | SA_SaleOrder.idcustomer → AA_Partner.code | int(4) | — | businesses.customer_id | 按客户编码解析;回退公司名称+负责人 | 必须 | D? | SA_SaleOrder.idcustomer(客户id)、idsettlecustomer(结算客户id) | +| 4 | 负责营销人员 | SA_SaleOrder.idclerk → AA_Person.code | int(4) | — | businesses.owner_personnel_id | 按人员编码解析;新插入写 T+ 负责人、更新是否覆盖人工归属待裁决 | 必须 | D? | SA_SaleOrder.idclerk(业务员id) | +| 5 | 协助营销人员 | 未检出独立协助人字段 | — | — | businesses.assistant_personnel_id | 业务已回馈 T+ 合同只挂单一负责人;协助人系统内记录 | 建议 | N | SA_SaleOrder 无 assist/协助 字段 | +| 6 | 特殊业务标记 | SA_SaleOrder.idbusinesstype → 业务类型表 | int(4) | 业务类型枚举待字典/IT 提供 | businesses.is_special | 业务类型是否等同特殊业务待确认;无则人工标记 | 必须 | D? | SA_SaleOrder.idbusinesstype(业务类型id) | +| 7 | 明细行 · 产品名称 + 规格 | SA_SaleOrder_b.idinventory → AA_Inventory.name/specification | int(4) | — | business_items.product_name / spec_model | 冗余固化名称与规格;未建档产品允许自由录入 | 必须 | D | SA_SaleOrder_b.idinventory(存货id) | +| 8 | 明细行 · 数量 | SA_SaleOrder_b.quantity | decimal(13) | — | business_items.quantity | 主计量数量;需 >0 校验 | 必须 | D | SA_SaleOrder_b.quantity(数量)、baseQuantity(主计量数量) | +| 9 | 明细行 · 销售单价 | SA_SaleOrder_b.price / taxPrice | decimal(13) | — | business_items.sale_price | price 为不含税单价、taxPrice 为含税单价;取哪个待确认 | 必须 | D? | SA_SaleOrder_b.price(单价)、taxPrice(含税单价) | +| 10 | 明细行 · 销售额 | SA_SaleOrder_b 无「销售额」字段;由数量×单价计算,或 taxAmount−tax | decimal(13) | — | business_items.sale_amount | 系统按数量×单价固化;T+ 用于对账 | 必须 | D? | SA_SaleOrder_b.quantity、price、taxAmount、tax | +| 11 | 明细行 · 成本额 ★ | SA_SaleOrder_b.LatestCost(最新成本);SA_SaleDelivery_b.costPrice/costAmount | decimal(13) | — | business_items.cost_amount | 取订单最新成本还是出库成本、成本类型/时点待 IT(#1) | 必须 | D? | SA_SaleOrder_b.LatestCost;SA_SaleDelivery_b.costPrice/costAmount/CostPriceGetType | +| 12 | 项目 / 工程编号或名称(如存在) | SA_SaleOrder.idproject → 项目表 | int(4) | — | 建议预留 project_code(当前不落库) | 按项目查询与报表归集;是否建列待业务 | 可选 | D? | SA_SaleOrder.idproject(项目id)、SA_SaleOrder_b.idproject | +| 13 | 服务类 / 维修类及其他收入单据(如存在) | 未检索到服务/维修类独立单据表 | — | — | 暂人工录入 | 业务规则未定前不纳入自动同步 | 可选 | N | SA_* 表索引未发现服务/维修类主表 | + +## 6. 发货单据(销售出库/发货) + +发货日期有四个候选字段;运费未在发货单据检出。 + +| 序号 | 数据项 | T+ 表.字段(字典) | T+ 类型/长度 | 枚举/取值 | 系统目标表.字段 | 转换/清洗规则 | 必要性 | 确认状态 | 来源/字典页 | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| 1 | 发货单号 | SA_SaleDelivery.code | nvarchar(30) | — | shipments.source_no | TRIM;不得写入内部 shipment_no | 必须 | D | SA_SaleDelivery.code(编号) | +| 2 | 发货日期 ★ | SA_SaleDelivery.voucherdate / SendDate / deliveryDate / auditeddate | datetime(8) | — | shipments.ship_date | 四个日期候选:单据日期/送货日期(T+12.3)/交货日期/审核日期;取哪个待 IT(#2) | 必须 | D? | SA_SaleDelivery.voucherdate、SendDate、deliveryDate、auditeddate | +| 3 | 关联订单号 | SA_SaleDelivery.SourceVoucherCode / idsourcevouchertype;明细 saleOrderCode/saleOrderId | nvarchar(50) / int(4) | — | shipments.business_id | 按订单号解析;主关联路径待 IT(#5) | 必须 | D? | SA_SaleDelivery.SourceVoucherCode、SA_SaleDelivery_b.saleOrderCode/saleOrderId/saleOrderDetailId | +| 4 | 运费金额 | 未检出运费字段(明细有 origExpenseAmount 费用分摊金额) | decimal(13) | — | shipments.freight_amount | T+ 运费可能在费用单/其他单据,需 IT 确认;系统暂人工 | 必须 | N | SA_SaleDelivery/SA_SaleDelivery_b 无 freight/运费字段 | +| 5 | 发货总金额 | SA_SaleDelivery.amount / taxAmount | decimal(13) | — | shipments.total_amount | 系统按明细汇总,不直写;T+ 金额用于对账 | 必须 | D | SA_SaleDelivery.amount(金额)、taxAmount(含税金额) | +| 6 | 明细行 · 产品/规格/数量/单价/行金额 | SA_SaleDelivery_b.idinventory / quantity / price / taxPrice / taxAmount | decimal(13) | — | shipment_items.product_name/spec_model/quantity/sale_price/amount | 行金额由系统按数量×单价固化;T+ 用于对账 | 必须 | D | SA_SaleDelivery_b.quantity、price、taxPrice、taxAmount | +| 7 | 发货单状态 | SA_SaleDelivery.voucherState / isCancel / auditeddate | int(4) / tinyint(1) | 单据状态枚举待 IT 提供 | 不落库(v1.4 统一) | 仅推已生效单据;状态随行供同步校验 | 必须 | D | SA_SaleDelivery.voucherState(单据状态)、isCancel(状态) | +| 8 | 承运商 / 物流单号 | SA_SaleDelivery.deliveryMode(运输方式 id) | int(4) | 运输方式枚举表待确认 | 暂不落库 | 承运商/物流单号无独立字段;如需建列再扩展 | 可选 | D? | SA_SaleDelivery.deliveryMode(运输方式) | + +## 7. 回款单据(收款/核销) + +到账日期无银行到账日字段;收款方式取结算方式表;确认/核销状态字段存在但枚举待 IT。 + +| 序号 | 数据项 | T+ 表.字段(字典) | T+ 类型/长度 | 枚举/取值 | 系统目标表.字段 | 转换/清洗规则 | 必要性 | 确认状态 | 来源/字典页 | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| 1 | 回款单号 | ARAP_ReceivePayment.code | nvarchar(30) | — | receipts.source_no | TRIM;不得写入内部 receipt_batch_no | 必须 | D | ARAP_ReceivePayment.code(编号) | +| 2 | 到账日期 ★ | ARAP_ReceivePayment.voucherDate / auditedDate / createdTime | datetime(8) | — | receipts.receipt_date | 无银行到账日字段;取单据日期/审核日期/创建时间哪个待 IT(#3) | 必须 | D? | ARAP_ReceivePayment.voucherDate、auditedDate、createdTime | +| 3 | 回款金额 | ARAP_ReceivePayment.amount(本币)/ origAmount(原币) | decimal(13) | — | receipts.amount | 取本币金额;一期禁负数,红字规则待 #8 | 必须 | D | ARAP_ReceivePayment.amount、origAmount | +| 4 | 关联订单号 | ARAP_ReceivePayment.SaleOrderCode/SaleOrderID;明细 saleordercode/saleorderid/sourceordercode | nvarchar(50) / int(4) | — | receipts.business_id | 回款↔订单按订单号解析;回款↔发货批次系统人工指定 | 必须 | D? | ARAP_ReceivePayment.SaleOrderCode/SaleOrderID;ARAP_ReceivePayment_b.saleordercode/sourceordercode | +| 5 | 收款方式 | ARAP_ReceivePayment.IdSettleStyle → AA_SettleStyle.code/name | int(4) | 结算方式枚举表(AA_SettleStyle:code/name/停用) | receipts.payment_method(待补列) | 枚举映射;完整枚举清单需 IT 提供 | 必须 | D? | ARAP_ReceivePayment.IdSettleStyle;AA_SettleStyle | +| 6 | 以物抵顶物说明 | 收款方式(以物抵顶枚举值)+ ARAP_ReceivePayment.memo | int(4) / nvarchar(200) | 以物抵顶对应结算方式代码待 IT 提供 | receipts.is_barter / remark | 按结算方式识别;抵顶物说明暂入备注 | 建议 | D? | ARAP_ReceivePayment.IdSettleStyle、memo | +| 7 | 回款确认 / 核销状态 | ARAP_ReceivePayment.cancelState / voucherstate / auditedDate | int(4) / datetime(8) | 核销/单据状态枚举待 IT 提供 | receipts.confirm_status(待补列) | 字段存在;哪个可作为人工确认依据待 IT(#16) | 必须 | D? | ARAP_ReceivePayment.cancelState(核销状态)、voucherstate(单据状态) | +| 8 | 银行流水号 / 回单参考号 | 未检出银行流水号/回单号字段(MultiSettle.documentCode 为票据号) | — | — | 建议预留 bank_serial_no | 需 IT 确认是否有对应字段 | 建议 | N | ARAP_ReceivePayment/ARAP_ReceivePayment_MultiSettle 仅票据号 | +| 9 | 票据信息(票号 / 到期日 / 贴现说明) | ARAP_ReceivePayment_MultiSettle.documentCode / amount / idsettlestyle | nvarchar(30) / decimal(13) | 票据类型枚举待 IT | 系统暂以备注承载 | 无票据到期日字段;承兑到期核销信息需 IT 确认 | 建议 | D? | ARAP_ReceivePayment_MultiSettle.documentCode(票据号) | +| 10 | 币种 / 汇率(如存在外币业务) | ARAP_ReceivePayment.idcurrency / exchangeRate | int(4) / decimal(13) | 币种表待索引 | 一期不落库(人民币记账) | 如存在外币业务再扩展 | 可选 | D | ARAP_ReceivePayment.idcurrency、exchangeRate | + +## 8. 客户档案 + +采用往来单位表 AA_Partner;客户编码/停用字段存在,status 列需系统补。 + +| 序号 | 数据项 | T+ 表.字段(字典) | T+ 类型/长度 | 枚举/取值 | 系统目标表.字段 | 转换/清洗规则 | 必要性 | 确认状态 | 来源/字典页 | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| 1 | 公司名称 | AA_Partner.name | nvarchar(200) | — | customers.company_name | TRIM;与负责人组成系统唯一键 | 必须 | D | AA_Partner.name(名称) | +| 2 | 负责人姓名 | AA_Partner.Contact(联系人)/ representative(法人代表) | nvarchar(50) | — | customers.owner_name | 「负责人」对应 Contact 还是 representative 待 IT/业务确认 | 必须 | D? | AA_Partner.Contact、representative | +| 3 | 客户编码 / 状态 / 启用停用时间 | AA_Partner.code / disabled / madeDate / updated | nvarchar(32) / tinyint(1) | disabled 0 启用 / 1 停用(候选) | customers.source_no / status(待补列) | 启停时间无独立列,可用 updated 近似(需 IT 确认) | 必须 | D? | AA_Partner.code、disabled、madeDate、updated | +| 4 | 联系人 / 电话 / 地址 / 行业 | AA_Partner.Contact / TelephoneNo / MobilePhone / CustomerAddress / iddistrict | nvarchar(30~200) | — | customers.contact_person / contact_phone / address / industry | 行业无直接字段;地区按 iddistrict 关联 | 可选 | D? | AA_Partner.Contact、TelephoneNo、MobilePhone、CustomerAddress、iddistrict | +| 5 | 开票信息(税号 / 开票名称 / 开票地址电话) | AA_Partner.taxRegcode / name / CustomerAddress | nvarchar(50~200) | — | 系统暂仅供展示,不落库 | 税号存在;开票地址电话需 IT 确认字段 | 可选 | D? | AA_Partner.taxRegcode(纳税号)、CustomerAddress | + +## 9. 同步完整性与补充字段 + +时间戳与负向字段部分存在;无统一事件表、无明细行号、无手续费字段。 + +| 序号 | 数据项 | T+ 表.字段(字典) | T+ 类型/长度 | 枚举/取值 | 系统目标表.字段 | 转换/清洗规则 | 必要性 | 确认状态 | 来源/字典页 | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| 1 | 数据最后更新时间 / 单据创建时间 / 修改时间 | 各表 createdTime/createdtime、updated、madeDate、auditedDate、ts | datetime(8) / timestamp(8) | — | 建议新增 source_created_at / source_updated_at(当前无) | 本地 update_time 不可作为源端水位;增量水位字段待 IT(#9) | 必须 | D? | 各表 updated/createdTime;ts(分布时间戳) | +| 2 | 变更类型 / 单据事件:新增、修改、删除、作废、红冲、退货、冲销 | 各表 isCancel(状态)、isCounteractDelivery(冲抵销货)、returnQuntity(退货数量) | int(4) / tinyint(1) / decimal(13) | 状态/事件枚举待 IT 提供 | 建议事件表(当前无) | 无统一变更事件表;负向事实需事件模型,规则待 #8 | 必须 | D? | SA_SaleOrder.isCancel、SA_SaleDelivery.isCounteractDelivery、SA_SaleDelivery_b.returnQuntity | +| 3 | 单据状态 / 财务审核状态 / 状态变更时间 | voucherState / auditedDate / auditor / auditorid | int(4) / datetime(8) / nvarchar(50) | 单据状态枚举待 IT | 不落库(仅同步校验) | 仅推已生效单据;状态随行校验 | 必须 | D | SA_SaleOrder/SA_SaleDelivery/ARAP_ReceivePayment 的 voucherState、auditedDate | +| 4 | 明细行行号 / 行状态 / 行级变更事件 | 明细表主键 ID、code(明细编号);无显式行号字段 | int(4) / nvarchar(30) | — | 建议补 source_line_no / source_item_id | 确认 code 是否即行号;否则用 T+ 明细 ID 作行级幂等键(待 IT) | 必须 | D? | SA_SaleOrder_b.id/code、SA_SaleDelivery_b.ID/code、ARAP_ReceivePayment_b.id/detailCode | +| 5 | 税率 / 税额 / 价税合计 / 折扣或折让 | 明细表 taxRate、tax、taxAmount、origTaxAmount、discount、discountRate、discountAmount | decimal(13) | — | 待业务 #20 答复后决定是否建列 | 字段齐全;金额是否含税、折扣关联方式待业务 | 必须 | D? | SA_SaleOrder_b/SA_SaleDelivery_b 税额与折扣字段 | +| 6 | 发货客户 / 收货人 / 收货地址 / 联系电话 | SA_SaleDelivery.idcustomer / address / contactPhone / idSendPerson / idConsignor | int(4) / nvarchar(100~200) | — | 建议预留(当前无列) | 用于核对发货对象与代发情形 | 必须 | D | SA_SaleDelivery.idcustomer、address、contactPhone、idSendPerson、idConsignor | +| 7 | 发货业务员 / 发货组织 / 仓库 | SA_SaleDelivery.idclerk / iddepartment / idwarehouse | int(4) | — | 建议预留(当前无列) | 识别代发、调拨与多组织差异 | 必须 | D | SA_SaleDelivery.idclerk、iddepartment、idwarehouse | +| 8 | 发货退回 / 红字发货 / 退回数量 / 退回金额 / 原发货单关联 | SA_SaleDelivery.isCounteractDelivery、_b.returnQuntity/returnQuntity2/backSentQuantity、sourceVoucher* | tinyint(1) / decimal(13) / nvarchar(50) | 冲抵/退货枚举待 IT | 待业务 #21 答复后决定是否建列 | 原单关联字段存在;是否冲减绩效待业务 | 必须 | D? | SA_SaleDelivery.isCounteractDelivery、SA_SaleDelivery_b.returnQuntity、backSentQuantity | +| 9 | 收款客户 / 经手人 / 财务审核状态 | ARAP_ReceivePayment.idpartner / idHandler / auditor / voucherstate | int(4) / nvarchar(50) / int(4) | — | 建议预留(当前无列) | 核对实际付款主体与经办责任 | 必须 | D | ARAP_ReceivePayment.idpartner、idHandler、auditor、voucherstate | +| 10 | 收款分配明细 / 分配金额 / 未分配金额 / 分配对象 | ARAP_ReceivePayment_b(源单/订单/金额/未结算)、ARAP_StrikeBalance(核销) | decimal(13) / int(4) | — | 人工指定发货批次的辅助参考 | 分配关系仅参考;系统仍人工指定(对照表 #18) | 必须 | D? | ARAP_ReceivePayment_b.saleordercode/amount/origNoSettleAmount;ARAP_StrikeBalance | +| 11 | 预收款 / 保证金 / 代收款 / 折让 / 抵扣 | ARAP_ReceivePayment.paymentAmount/origPaymentAmount(预收/预付)、overPayment(超收转预收)、allowances(折让) | decimal(13) | — | 待业务 #22 答复后决定是否建列 | 字段存在;是否计入绩效回款待业务 | 必须 | D? | ARAP_ReceivePayment.paymentAmount、overPayment、allowances | +| 12 | 手续费 / 交易费用 / 收款净额 | 未检出手续费/交易费用字段 | — | — | 待业务 #23 答复后决定 | 需 IT 确认手续费是否在其他单据/字段 | 必须 | N | ARAP_ReceivePayment 无 fee/charge 字段 | +| 13 | 红字收款 / 收款作废 / 收款退回 / 冲销及原单关联 | ARAP_ReceivePayment.voucherstate / isReceiveFlag;ARAP_StrikeBalance 冲销 | int(4) / tinyint(1) | 作废/红字状态枚举待 IT | 待业务 #24 答复后决定 | 无红字收款专用字段;负向事实需事件模型 | 必须 | D? | ARAP_ReceivePayment.voucherstate、isReceiveFlag;ARAP_StrikeBalance | +| 14 | 客户编码 / 客户状态 / 启用停用时间 | AA_Partner.code / disabled | nvarchar(32) / tinyint(1) | disabled 0 启用 / 1 停用 | customers.source_no / status(待补列) | 同六-3;客户编码唯一性待 IT | 必须 | D | AA_Partner.code、disabled | +| 15 | 客户分类 / 渠道 / 区域 / 所属组织 | AA_Partner.idpartnerclass / customerType / iddistrict / idMarketingOrgan | int(4) | 分类/客商类型枚举待 IT | customers.customer_type(不覆盖);渠道无列 | 系统客户分类人工维护;渠道/区域作备考 | 必须 | D? | AA_Partner.idpartnerclass、customerType、iddistrict、idMarketingOrgan | +| 16 | 客户名称变更 / 编码停用合并前后的对应关系 | AA_Partner.code(终身不变)+ updated;无变更历史表(待确认) | nvarchar(32) | — | 靠 source_no 追溯同一主体 | 改名/换负责人/合并靠 code 串同一主体;变更历史需 IT 确认 | 必须 | D? | AA_Partner.code、updated、HasEverChanged | +| 17 | 人员部门 / 岗位 / 调岗时间 / 离职和组织变更时间 | AA_Person.iddepartment / position / updated;调岗历史表待确认 | int(4) / datetime(8) | — | 不落库(备考/排查) | 字段部分存在;调岗/离职时间需 IT 确认 | 必须 | D? | AA_Person.iddepartment、position、updated | +| 18 | 产品编码 / 产品状态 / 启用停用时间 | AA_Inventory.code / disabled / madeDate | nvarchar(32) / tinyint(1) | disabled 0 启用 / 1 停用 | products.source_no / status | 稳定匹配;停用后历史明细仍可回溯 | 必须 | D | AA_Inventory.code、disabled、MadeRecordDate | +| 19 | 字典和枚举取值范围 / 编码与名称对照说明 | 枚举表:AA_SettleStyle、业务类型表、状态字典(需随数据导出) | — | 枚举字典随数据提供 | 同步映射表 | 不能只给代码;需编码与名称对照 | 必须 | D? | AA_SettleStyle、AA_BusinessType 等枚举表 | +| 20 | 对账汇总信息 / 数据记录数 / 数量合计 / 金额合计 / 抽取时间 | 由 IT 提供抽取汇总(接口/视图层) | — | — | 同步日志/对账表 | 记录明细条数、金额合计、抽取时间 | 必须 | IT | 字典不提供;需对接方式确定 | +| 21 | 单据历史版本 / 修改留痕(如 T+ 提供) | 未检索到统一单据历史版本表(待 IT 确认) | — | — | 系统同步快照可比对 | 无此数据不阻塞 | 可选 | D? | 表索引未见 history 类表 | + +## 10. 跨表关联与键 + +| 关系 | T+ 字段(字典) | 系统目标 | 状态 | +| --- | --- | --- | --- | +| 人员唯一键 | AA_Person.code | personnel.source_no(建议补 personnel_code) | D? | +| 客户唯一键 | AA_Partner.code;名称+联系人 | customers.source_no;company_name+owner_name | D? | +| 订单→发货 | SA_SaleDelivery.SourceVoucherCode / _b.saleOrderCode/saleOrderId | shipments.business_id | D? | +| 订单/发货→回款 | ARAP_ReceivePayment.SaleOrderCode/SaleOrderID;_b.saleordercode | receipts.business_id | D? | +| 回款→发货批次 | 系统人工指定(对照表 #18) | receipts.shipment_id | S | +| 明细行幂等 | 明细表 ID/code;无显式行号 | 建议补 source_line_no | D? | + +## 11. 枚举与状态 + +| 枚举 | T+ 来源 | 备注 | +| --- | --- | --- | +| 收款/结算方式 | AA_SettleStyle(code/name/disabled) | 完整枚举需随数据导出 | +| 单据状态 | 各单据 voucherState / isCancel | 仅同步校验,不落库 | +| 核销状态 | ARAP_ReceivePayment.cancelState | 含义待 IT | +| 业务类型 | SA_SaleOrder.idbusinesstype → 业务类型表 | 是否等同特殊业务待确认 | +| 产品分类 | AA_InventoryClass | 仅辅助系统分类人工维护 | + +## 12. 系统侧目标表缺口 + +| 缺口 | 说明 | 建议 | +| --- | --- | --- | +| `personnel.personnel_code` | T+ 工号/编码是否即 `source_no` 未定 | 若不等则补唯一列 | +| `customers.status` / 启停时间 | T+ 有 disabled,系统无列 | 补 status 与停用时间 | +| `receipts.payment_method` / `confirm_status` | T+ 有结算方式与核销状态 | 补两列并接枚举 | +| `source_created_at` / `source_updated_at` | 本地 update_time 不可作源端水位 | 补列或建 staging 表 | +| `source_line_no` / `source_item_id` | 明细表无行号 | 补列支持行级幂等 | +| 负向事件模型 | 无删除/作废/红冲/退货事件表 | 设计事件表或冲销单 | +| `sync_log` / 失败明细表 | 完全缺失 | 同步模块前置 | +| T+ 配置项 | `.env` 有 `T_PLUS_*`,`Settings` 未定义 | 补配置字段与校验 | + +## 13. IT 待确认事项收敛(18 → 13 + 1 组业务) + +| 新# | 原# | 事项 | 字典证据 | 字典可答 | 仍需确认 | 优先级 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | 1 | 成本额字段与成本口径 | SA_SaleOrder_b.LatestCost;SA_SaleDelivery_b.costPrice/costAmount/CostPriceGetType;AA_Inventory.invSCost/latestCost/avagCost | 字段存在性、类型精度、挂在订单还是出库单 | 请确认绩效成本取哪个字段(订单最新成本 / 出库成本 / 其他),取数时点与精度 | 高(阻塞核算) | +| 2 | 2+3 | 发货日与到账日口径 | 发货:SA_SaleDelivery.voucherdate/SendDate/deliveryDate/auditeddate;到账:ARAP_ReceivePayment.voucherDate/auditedDate/createdTime | 各日期字段存在性与类型 | 请分别确认发货日、到账日取哪个字段;签收日/银行到账日能否从 T+ 获取 | 高 | +| 3 | 4 | 幂等键与作废重开 | 各表 code + id 主键;SA_SaleOrder.ismodifiedcode、HasEverChanged | 编码字段与主键关系 | 各单据 code 是否唯一终身不变;作废重开是否换号;建议以 code 作 source_no | 高 | +| 4 | 5 | 三单关联与核销路径 | SA_SaleDelivery.SourceVoucherCode/idsourcevouchertype;SA_SaleDelivery_b.saleOrderCode/saleOrderId;ARAP_ReceivePayment.SaleOrderCode/SaleOrderID;ARAP_ReceivePayment_b;ARAP_StrikeBalance | 关联字段与核销表存在性 | 请确认订单→发货→回款的主关联路径(按单号还是 ID),以及分批发货/部分核销如何取 | 高 | +| 5 | 6 | 人员编码/工号与经理隶属 | AA_Person.code/name/iddepartment/isSalesman;AA_Department.idparent/iddirector | 编码/部门/负责人字段存在;无直属上级字段 | AA_Person.code 是否即工号;业务员→营销经理隶属在 T+ 如何维护(部门负责人?自定义项?) | 高 | +| 6 | 7 | 对接方式与安全 | 字典不涉及 | 无 | REST/视图/中间表/文件;只读账号与凭据、接口文档、样例数据 | 高 | +| 7 | 8 | 负数/红字/退货/冲销规则 | SA_SaleDelivery.isCounteractDelivery;SA_SaleDelivery_b.returnQuntity/backSentQuantity;ARAP_ReceivePayment.voucherstate;ARAP_StrikeBalance | 负向字段/单据形式存在性 | 负向单据的实际使用形式、原单关联字段、是否推送;绩效影响转业务 | 高 | +| 8 | 9 | 存量起始与增量水位 | 各表 updated/createdTime/madeDate/auditedDate/ts | 时间戳字段存在性 | 存量起始日期;增量用哪个时间戳(updated? ts?);时区 | 中 | +| 9 | 10+v1.4#18 | 客户主数据匹配与变更 | AA_Partner.code/name/Contact/representative/disabled/updated | 编码/名称/负责人/停用字段 | 客户唯一键;改名/换负责人/合并如何映射同一主体;负责人取 Contact 还是 representative | 中 | +| 10 | 11+16 | 收款方式与确认/核销枚举 | ARAP_ReceivePayment.IdSettleStyle;AA_SettleStyle.code/name;ARAP_ReceivePayment.cancelState/voucherstate | 枚举表与状态字段存在性 | 收款方式完整枚举与以物抵顶对应代码;核销/确认状态枚举含义及可否作为人工确认依据 | 高 | +| 11 | 12+13 | 产品数量语义与发货单价 | ST_CurrentStock.baseQuantity;AA_InventoryPrice/AA_InventoryUnitPrice;SA_SaleDelivery_b.price/taxPrice | 数量/价格字段存在性 | 产品「数量」取现存量/在途/累计销量;发货单价取订单价还是发货时价、含税与否 | 中 | +| 12 | 14+17 | 低频字段存在性:特殊业务标记/市场拓展计划 | SA_SaleOrder.idbusinesstype;AA_Person 自定义项;未检出市场拓展计划表 | 字段/表存在性 | 特殊业务是否有可识别字段;市场拓展计划 T+ 是否有表可提供;无则人工维护 | 低 | +| 13 | 15 | 同步窗口 | 字典不涉及 | 无 | 每周同步时间点,避开结账/备份;失败重试策略 | 低 | +| B1 | 18 | 业务裁决 5 项 | 税额/折扣/退货/预收/手续费字段已定位(待答复后决定是否建列) | 字段存在性 | 含税口径、退货红字冲减、预收/保证金/代收、手续费净额、负绩效表述 | 业务裁决 | + +### 原 18 项对照 + +| 原# | 事项 | 原优先级 | 收敛去向 | +| --- | --- | --- | --- | +| 1 | 成本额取数口径 | 高(阻塞核算) | 1 | +| 2 | 发货日期口径 | 高 | 2 | +| 3 | 到账日期口径 | 高 | 2 | +| 4 | 幂等唯一键 | 高 | 3 | +| 5 | 三单关联键 | 高 | 4 | +| 6 | 人员匹配键与经理隶属(v1.2 更新) | 高 | 5 | +| 7 | 对接方式与安全 | 高 | 6 | +| 8 | 负数 / 红字 / 退货 / 冲销处理规则 | 高 | 7 | +| 9 | 存量范围与增量口径 | 中 | 8 | +| 10 | 客户档案匹配与唯一键 | 中 | 9 | +| 11 | 收款方式枚举 | 中 | 10 | +| 12 | 产品「数量」语义 | 中 | 11 | +| 13 | 发货单价口径 | 中 | 11 | +| 14 | 特殊业务标记 | 低 | 12 | +| 15 | 同步窗口 | 低 | 13 | +| 16 | 回款确认 / 核销状态 | 高 | 10 | +| 17 | 市场拓展计划数据 | 低 | 12 | +| 18 | 口径裁决 5 项(移交业务方) | 业务裁决 | B1 | + +## 14. 待确认清单 + +**IT(13 项)**:见第 13 节新# 1–13。 + +**业务(1 组)**:含税口径、退货红字冲减、预收/保证金/代收、手续费净额、负绩效表述(原 #18 / 待澄清 #20–#24)。 + +**系统侧(不阻塞 IT)**:补 `personnel_code`、`customers.status`、`receipts.payment_method/confirm_status`、`source_updated_at`、`source_line_no`、`sync_log` 与 T+ 配置项。 + +## 15. 验证记录 + +- 解包:1,457 个 HTML、`.hhc/.hhk` 齐全、零字节 0; +- 全量解析:1,457 页、938 个 Table 类型页、**931 张表、21,019 个字段、0 失败页**; +- 编码:逐页检测,GB18030(无替换字符); +- 抽样核验:六类主表结构一致(6 列字段表),关键字段逐项比对通过; +- 输入 SHA-256:`3e8cd3146e22bdebe8bacda56b5dafbbd8be744c4279d7b2bbf3d7ecdc7e2726`; + +## 附录 A:六类主表索引 + +| 类别 | T+ 表 | 字典页 GUID | +| --- | --- | --- | +| 人员 | AA_Person | `fcd00c17-6778-4c6a-90ae-3f0dbaf2c102` | +| 产品 | AA_Inventory | `93b57dfa-4ca4-411d-a883-6d26c8e01787` | +| 客户 | AA_Partner | `871e93dd-c2cf-4bd2-af91-cbeb5951ac5e` | +| 业务 | SA_SaleOrder | `9a51f8a9-658a-4f7c-9372-8af2257511ee` | +| 发货 | SA_SaleDelivery | `bef98b52-c9f0-4d80-8e62-8968cced5b52` | +| 回款 | ARAP_ReceivePayment | `709de6e4-3b3d-4cf8-b5ed-5f657d42599a` | + +## 附录 B:75 项覆盖矩阵 + +| 节 | 项数 | 已映射 | +| --- | --- | --- | +| 公共要求 | 2 | 2 | +| 人员 | 9 | 9 | +| 产品 | 7 | 7 | +| 业务 | 13 | 13 | +| 发货 | 8 | 8 | +| 回款 | 10 | 10 | +| 客户 | 5 | 5 | +| 同步完整性 | 21 | 21 | + +## 附录 C:失败页 + +无(`failures.csv` 为空)。 + +## 附录 D:复现方法 + +```text +1. C:/Windows/hh.exe -decompile +2. py -3.14 -I 03_extract_fields.py --extracted --out +3. py -3.14 -I 08_build_md.py --out --target +``` + +--- + +*本文档由数据字典解析与人工核验生成,字段候选未经 IT 确认前不得视为同步契约。* diff --git a/docs/T+对接数据需求清单_v1.5_2026-10-20.xlsx b/docs/T+对接数据需求清单_v1.5_2026-10-20.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..dddc231360ca9cca24260f8326bd3efdf0a87488 GIT binary patch literal 32007 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 literal 0 HcmV?d00001