|
@@ -0,0 +1,664 @@
|
|
|
|
|
+# AIDOP 双模式对接 UAT 配置操作指南(S5–S7 重点 · T8 / MES+WMS)
|
|
|
|
|
+
|
|
|
|
|
+| 项 | 内容 |
|
|
|
|
|
+|----|------|
|
|
|
|
|
+| 读者 | UAT 测试人员、实施配置人员 |
|
|
|
|
|
+| 范围 | **S5 物料仓 / S6 制造 / S7 成品仓** 与第三方 **T8(DB)**、**MES+WMS(API)** 双模式对接 |
|
|
|
|
|
+| 版本基线 | Web ≥ `2.4.258` · server ≥ `1.0.264` · UpdateScripts `1.0.259`–`1.0.264` |
|
|
|
|
|
+| 上游 | [`AIDOP双模式全模块对接交付级任务书.md`](./AIDOP双模式全模块对接交付级任务书.md) |
|
|
|
|
|
+| 编写日期 | 2026-07-24 |
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 0. 先读懂:两条测试路 + 两条数据管线
|
|
|
|
|
+
|
|
|
|
|
+### 0.1 两条对接路(本指南核心)
|
|
|
|
|
+
|
|
|
|
|
+| 路 | 第三方 | 协议 | 典型用途 |
|
|
|
|
|
+|----|--------|------|----------|
|
|
|
|
|
+| **路 A · T8 / 本库 DB** | T8 SQL Server + 本库业务表 | DB 直连 | KPI 看板刷新;本库收货/IPQC/入库贴源入站 |
|
|
|
|
|
+| **路 B · MES+WMS API** | 第三方 MES / WMS(可用 Mock 代替) | HTTP API | 同一业务对象用 API 抽数,验与 DB 路键一致 |
|
|
|
|
|
+
|
|
|
|
|
+> **双模式交付含义**:同一业务对象在 `mdp_entity` 同时有 **DB 实体** 与 **`*_API` 实体**,落同一 `mdp_stg_*` → `mdp_std_*`;回写走 `mdp_outbox`,禁止前端直连外部写。
|
|
|
|
|
+
|
|
|
|
|
+> **回写机制(一句话)**:业务合格闭环时先幂等写入 `mdp_outbox`,再由定时 Job 按 `QMS_API` 配置把 payload 里的 `path/method/body` 用 HTTP 推给第三方,失败可重试、禁止前端直连外部写。
|
|
|
|
|
+
|
|
|
|
|
+### 0.2 S5–S7 两条管线(不要混测)
|
|
|
|
|
+
|
|
|
|
|
+| 管线 | 入口 API | 读什么 | 写什么 | 是否碰 T8 |
|
|
|
|
|
+|------|----------|--------|--------|-----------|
|
|
|
|
|
+| **业务贴源入站** | `…/s5-purchase-receipt-mdp/inbound` 等 | 本库表或 WMS/MES API | `mdp_stg_*` → `mdp_std_*` | 否(报工例外见 §4.2) |
|
|
|
|
|
+| **KPI 刷新** | `…/s5-mdp/refresh` 等 | **T8** 聚合 SQL | `ado_s9_kpi_*` / DWD | 是 |
|
|
|
|
|
+
|
|
|
|
|
+AIDOPB 等「无 T8」租户:**只测业务入站 + 造数**,不要对 `s5/s6/s7-mdp/refresh` 期望出 T8 KPI。
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 1. 环境与账号前置
|
|
|
|
|
+
|
|
|
|
|
+| 检查项 | 要求 | 如何确认 |
|
|
|
|
|
+|--------|------|----------|
|
|
|
|
|
+| 业务库 | MySQL `aidopdev` 已执行到 `1.0.264` | `SELECT entity_code FROM mdp_entity WHERE entity_code LIKE 'S6_REPORT%'` 有 2 行 |
|
|
|
|
|
+| 后端服务 | Admin.NET 已启动,插件含 AiDOP | 浏览器或 Postman 能访问 `/api/AidopKanban/...` |
|
|
|
|
|
+| 前端 | 登录后能开数据中台菜单 | `/aidop/data-platform/sources`、`/sync-tasks` |
|
|
|
|
|
+| Demo 租户(有 T8) | `TenantId = 797403760988229`,T8 账套 `ztid = pbxfxp` | 见 §6 租户映射 |
|
|
|
|
|
+| AIDOPB(无 T8) | `TenantId = 824585161322565`,用种子造数 | `aidopb_b2_*.sql` |
|
|
|
|
|
+| Mock(测 API 路) | `127.0.0.1:8018`,Token `uat-mock-token` | 见 §3.2 |
|
|
|
|
|
+
|
|
|
|
|
+API 前缀(控制器匿名开放,UAT 可直接调):
|
|
|
|
|
+
|
|
|
|
|
+```text
|
|
|
|
|
+POST /api/AidopKanban/<路由>
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 2. 配置中心页面(操作入口)
|
|
|
|
|
+
|
|
|
|
|
+| 页面 | 路径 | 做什么 |
|
|
|
|
|
+|------|------|--------|
|
|
|
|
|
+| 数据源管理 | `/aidop/data-platform/sources` | 查看 `mdp_source`、健康状态 |
|
|
|
|
|
+| 同步配置中心 | `/aidop/data-platform/sync-tasks` | 任务 / 实体 / **调度策略**(FULL·INCR·ROLLING)/ 参数·公式 |
|
|
|
|
|
+| 任务日志 | `/aidop/data-platform/sync-logs` | 按 `jobCode` 查运行结果 |
|
|
|
|
|
+| 链路监视 | `/aidop/data-platform/mdp-monitor` | 运行与血缘辅助 |
|
|
|
|
|
+
|
|
|
|
|
+调度:在同步任务行 → **更多 → 调度策略**,设置:
|
|
|
|
|
+
|
|
|
|
|
+- `syncWindowType`:`FULL` / `INCR` / `ROLLING`
|
|
|
|
|
+- `syncWindowValue`:如 `30d`、`7d`(ROLLING 用)
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 3. 数据源配置(必做)
|
|
|
|
|
+
|
|
|
|
|
+### 3.1 当前库侧四类源(对照)
|
|
|
|
|
+
|
|
|
|
|
+在库中确认(或在「数据源管理」页查看):
|
|
|
|
|
+
|
|
|
|
|
+| source_code | 类型 | status | 用途 | UAT 注意 |
|
|
|
|
|
+|-------------|------|--------|------|----------|
|
|
|
|
|
+| `AIDOPDEV_MYSQL` | DB | **1** | S5 收货 / S6 IPQC / S7 入库 **业务入站 DB 路** | 本库,勿停用 |
|
|
|
|
|
+| `T8_V5_SQLSERVER` | DB | **1** | S5–S7 **KPI**;S6 报工 DB 实体 | 连不上则 KPI/报工 DB 路失败 |
|
|
|
|
|
+| `WMS_API` | API | **1** | MES/WMS **入站 API 路**(Mock 或真源) | 切真源只改 URL/Token |
|
|
|
|
|
+| `QMS_API` | API | **0(默认)** | IQC/IPQC/FQC **回写目标** | 真推前改 URL 后置 `status=1` |
|
|
|
|
|
+
|
|
|
|
|
+核对 SQL:
|
|
|
|
|
+
|
|
|
|
|
+```sql
|
|
|
|
|
+SELECT source_code, source_type, status, db_type, db_host, db_name,
|
|
|
|
|
+ api_base_url, api_auth_type, health_status, health_msg, last_health_check
|
|
|
|
|
+FROM mdp_source
|
|
|
|
|
+WHERE source_code IN ('AIDOPDEV_MYSQL','T8_V5_SQLSERVER','WMS_API','QMS_API');
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 3.2 启动 Mock(路 B 无真实 MES/WMS 时)
|
|
|
|
|
+
|
|
|
|
|
+```bat
|
|
|
|
|
+cd doc\db\mdp\mock_api
|
|
|
|
|
+pip install -r requirements.txt
|
|
|
|
|
+set MOCK_TOKEN=uat-mock-token
|
|
|
|
|
+python -m uvicorn mock_server:app --host 127.0.0.1 --port 8018
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+浏览器或 curl:
|
|
|
|
|
+
|
|
|
|
|
+```text
|
|
|
|
|
+GET http://127.0.0.1:8018/health
|
|
|
|
|
+GET http://127.0.0.1:8018/__endpoints
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+`WMS_API` 必须与 Mock 一致:
|
|
|
|
|
+
|
|
|
|
|
+```sql
|
|
|
|
|
+UPDATE mdp_source
|
|
|
|
|
+SET api_base_url = 'http://127.0.0.1:8018',
|
|
|
|
|
+ api_auth_type = 'TOKEN',
|
|
|
|
|
+ api_auth_config = JSON_OBJECT('token','uat-mock-token'),
|
|
|
|
|
+ status = 1,
|
|
|
|
|
+ update_time = NOW()
|
|
|
|
|
+WHERE source_code = 'WMS_API';
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 3.3 切到真实 MES / WMS(路 B 真源)
|
|
|
|
|
+
|
|
|
|
|
+由实施提供 BaseUrl 与 Token 后执行(示例):
|
|
|
|
|
+
|
|
|
|
|
+```sql
|
|
|
|
|
+UPDATE mdp_source
|
|
|
|
|
+SET api_base_url = 'https://<真实-MES-或-WMS-主机>/', -- 无尾斜杠也可,执行器会拼 path
|
|
|
|
|
+ api_auth_type = 'TOKEN',
|
|
|
|
|
+ api_auth_config = JSON_OBJECT('token','<真实Token>'),
|
|
|
|
|
+ status = 1,
|
|
|
|
|
+ update_time = NOW()
|
|
|
|
|
+WHERE source_code = 'WMS_API';
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+真实接口契约(与 Mock / 执行器对齐,缺一不可):
|
|
|
|
|
+
|
|
|
|
|
+| 约定 | 值 |
|
|
|
|
|
+|------|-----|
|
|
|
|
|
+| 方法 | `GET` |
|
|
|
|
|
+| 鉴权 | `Authorization: Bearer <token>` |
|
|
|
|
|
+| 列表路径 | 响应 JSON 的 `data.list`(数组) |
|
|
|
|
|
+| 行去重键 | 每行字段 `bizKey`(与 `dedup_key_path` 一致) |
|
|
|
|
|
+| 业务字段 | 与对应 DB 源表字段同名(如 `Domain/Receiver/Line`、`djbh`、`noid/kgdate`) |
|
|
|
|
|
+
|
|
|
|
|
+端点与实体对照见 §4 表。
|
|
|
|
|
+
|
|
|
|
|
+### 3.4 切到真实 QMS(回写推送)
|
|
|
|
|
+
|
|
|
|
|
+```sql
|
|
|
|
|
+UPDATE mdp_source
|
|
|
|
|
+SET api_base_url = 'https://<真实-QMS>/',
|
|
|
|
|
+ api_auth_type = 'TOKEN',
|
|
|
|
|
+ api_auth_config = JSON_OBJECT('token','<Token>'),
|
|
|
|
|
+ status = 1, -- 启用后 Outbox Job 才会真推
|
|
|
|
|
+ update_time = NOW()
|
|
|
|
|
+WHERE source_code = 'QMS_API';
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+`status=0` 时:业务仍会**写入** `mdp_outbox`,但推送 Job **不会**对外部成功投递——UAT 可先验「有 Outbox 行」,再开真推。
|
|
|
|
|
+
|
|
|
|
|
+回写机制、对方接口约定与 Postman/接单 Mock 见 **§5.1**。
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 4. S5–S7 实体与入站对照(测试必查表)
|
|
|
|
|
+
|
|
|
|
|
+### 4.1 业务对象 ↔ 实体 ↔ 贴源表
|
|
|
|
|
+
|
|
|
|
|
+| 模块 | 业务对象 | DB 实体 `entity_code` | API 实体 | Mock/真源 path | 贴源 stg | 标准层 std | 业务键 `biz_key_expr` |
|
|
|
|
|
+|------|----------|----------------------|----------|----------------|----------|------------|----------------------|
|
|
|
|
|
+| S5 | 采购收货明细 | `S5_PURCHASE_RECEIPT_DETAIL` | `…_DETAIL_API` | `/api/receipt` | `mdp_stg_purchase_receipt` | `mdp_std_purchase_receipt` | Domain,Receiver,Line |
|
|
|
|
|
+| S5 | 采购收货主 | `S5_PURCHASE_RECEIPT_MASTER` | `…_MASTER_API` | `/api/receipt-master` | 同上 | 同上 | Domain,Receiver |
|
|
|
|
|
+| S6 | IPQC 头 | `S6_IPQC_INSPECTION_HEAD` | `…_HEAD_API` | `/api/ipqc` | `mdp_stg_ipqc_pull` | `mdp_std_ipqc_inspection` | djbh |
|
|
|
|
|
+| S6 | 报工(T8/MES) | `S6_REPORT`(源=T8) | `S6_REPORT_API` | `/api/mes/report` | `mdp_stg_s6_report` | `mdp_std_s6_report` | noid,kgdate |
|
|
|
|
|
+| S7 | 成品入库主 | `S7_NBR_MASTER` | `…_MASTER_API` | `/api/production-receipt` | `mdp_stg_production_receipt` | `mdp_std_production_receipt` | Domain,Nbr |
|
|
|
|
|
+| S7 | 成品入库明细 | `S7_NBR_DETAIL` | `…_DETAIL_API` | `/api/production-receipt-detail` | 同上 | 同上 | Domain,Nbr,Line |
|
|
|
|
|
+
|
|
|
|
|
+核对实体:
|
|
|
|
|
+
|
|
|
|
|
+```sql
|
|
|
|
|
+SELECT e.entity_code, e.source_table_name, e.source_api_path, e.target_table_name,
|
|
|
|
|
+ e.biz_key_expr, e.sync_mode, e.status, s.source_code, s.source_type
|
|
|
|
|
+FROM mdp_entity e
|
|
|
|
|
+JOIN mdp_source s ON s.id = e.source_id
|
|
|
|
|
+WHERE e.entity_code IN (
|
|
|
|
|
+ 'S5_PURCHASE_RECEIPT_DETAIL','S5_PURCHASE_RECEIPT_DETAIL_API',
|
|
|
|
|
+ 'S5_PURCHASE_RECEIPT_MASTER','S5_PURCHASE_RECEIPT_MASTER_API',
|
|
|
|
|
+ 'S6_IPQC_INSPECTION_HEAD','S6_IPQC_INSPECTION_HEAD_API',
|
|
|
|
|
+ 'S6_REPORT','S6_REPORT_API',
|
|
|
|
|
+ 'S7_NBR_MASTER','S7_NBR_MASTER_API',
|
|
|
|
|
+ 'S7_NBR_DETAIL','S7_NBR_DETAIL_API'
|
|
|
|
|
+)
|
|
|
|
|
+ORDER BY e.entity_code;
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 4.2 入站 / KPI 接口一览(复制即用)
|
|
|
|
|
+
|
|
|
|
|
+**业务入站(贴源)**
|
|
|
|
|
+
|
|
|
|
|
+```http
|
|
|
|
|
+POST /api/AidopKanban/s5-purchase-receipt-mdp/inbound?tenantId=0&fullRefresh=true
|
|
|
|
|
+POST /api/AidopKanban/s6-ipqc-inspection-mdp/inbound?tenantId=0&fullRefresh=true
|
|
|
|
|
+POST /api/AidopKanban/s6-report-mdp/inbound?tenantId=0&fullRefresh=true
|
|
|
|
|
+POST /api/AidopKanban/s6-report-mdp/inbound?tenantId=0&fullRefresh=true&entityCode=S6_REPORT_API
|
|
|
|
|
+POST /api/AidopKanban/s7-production-receipt-mdp/inbound?tenantId=0&fullRefresh=true
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+| 参数 | 含义 |
|
|
|
|
|
+|------|------|
|
|
|
|
|
+| `tenantId` | 落库租户;业务样板常用 `0` 或 Demo 租户 |
|
|
|
|
|
+| `fullRefresh` | `true`=全量忽略水位 |
|
|
|
|
|
+| `entityCode` | **仅报工接口支持**;默认 `S6_REPORT`(T8),API 路传 `S6_REPORT_API` |
|
|
|
|
|
+
|
|
|
|
|
+**KPI(T8)**
|
|
|
|
|
+
|
|
|
|
|
+```http
|
|
|
|
|
+POST /api/AidopKanban/s5-mdp/refresh?targetTenantId=797403760988229&targetFactoryId=1
|
|
|
|
|
+POST /api/AidopKanban/s6-mdp/refresh?targetTenantId=797403760988229&targetFactoryId=1
|
|
|
|
|
+POST /api/AidopKanban/s7-mdp/refresh?targetTenantId=797403760988229&targetFactoryId=1
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 4.3 重要:收货 / IPQC / 入库 inbound 如何切到 API 路
|
|
|
|
|
+
|
|
|
|
|
+当前实现里,下列 inbound **代码写死 DB 实体编码**(不接 `entityCode` 参数):
|
|
|
|
|
+
|
|
|
|
|
+- `S5_PURCHASE_RECEIPT_DETAIL`(及主表由服务内部联动)
|
|
|
|
|
+- `S6_IPQC_INSPECTION_HEAD`
|
|
|
|
|
+- `S7_NBR_MASTER`(及明细)
|
|
|
|
|
+
|
|
|
|
|
+Dispatcher 规则:**实体上 `source_api_path` 非空,或所属 `mdp_source.source_type=API` → 走 API 执行器**。
|
|
|
|
|
+
|
|
|
|
|
+因此 UAT 测 **MES/WMS API 路** 有两种做法(二选一):
|
|
|
|
|
+
|
|
|
|
|
+#### 做法甲(推荐 · 临时改 DB 实体指向 API,测完改回)
|
|
|
|
|
+
|
|
|
|
|
+以 S5 收货为例(测前备份 `source_id` / `source_api_path`):
|
|
|
|
|
+
|
|
|
|
|
+```sql
|
|
|
|
|
+-- 切到 API 路(挂 WMS_API + path)
|
|
|
|
|
+UPDATE mdp_entity e
|
|
|
|
|
+JOIN mdp_source s ON s.source_code = 'WMS_API'
|
|
|
|
|
+SET e.source_id = s.id,
|
|
|
|
|
+ e.source_api_path = '/api/receipt',
|
|
|
|
|
+ e.update_time = NOW()
|
|
|
|
|
+WHERE e.entity_code = 'S5_PURCHASE_RECEIPT_DETAIL';
|
|
|
|
|
+
|
|
|
|
|
+-- 调用 inbound 后,改回本库 DB 路(示例:挂回 AIDOPDEV_MYSQL,清空 path)
|
|
|
|
|
+UPDATE mdp_entity e
|
|
|
|
|
+JOIN mdp_source s ON s.source_code = 'AIDOPDEV_MYSQL'
|
|
|
|
|
+SET e.source_id = s.id,
|
|
|
|
|
+ e.source_api_path = NULL,
|
|
|
|
|
+ e.update_time = NOW()
|
|
|
|
|
+WHERE e.entity_code = 'S5_PURCHASE_RECEIPT_DETAIL';
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+同理:
|
|
|
|
|
+
|
|
|
|
|
+| 测对象 | 改哪个 entity_code | 临时 `source_api_path` |
|
|
|
|
|
+|--------|-------------------|------------------------|
|
|
|
|
|
+| S5 收货 | `S5_PURCHASE_RECEIPT_DETAIL`(主表若一并抽则还有 MASTER) | `/api/receipt`(主:`/api/receipt-master`) |
|
|
|
|
|
+| S6 IPQC | `S6_IPQC_INSPECTION_HEAD` | `/api/ipqc` |
|
|
|
|
|
+| S7 入库 | `S7_NBR_MASTER`(明细 `S7_NBR_DETAIL`) | `/api/production-receipt`(明细:`…-detail`) |
|
|
|
|
|
+
|
|
|
|
|
+#### 做法乙(不改配置 · 跑契约脚本)
|
|
|
|
|
+
|
|
|
|
|
+不经过 inbound HTTP,直接用 Mock 载荷双路写 stg→std 比键:
|
|
|
|
|
+
|
|
|
|
|
+```bat
|
|
|
|
|
+cd doc\db\mdp\contract_tests
|
|
|
|
|
+set MOCK_TOKEN=uat-mock-token
|
|
|
|
|
+python run_contract_s5_s6_s7.py
|
|
|
|
|
+python run_contract_s6_report.py
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+适合「契约一致性」验收;**不等于**完整 inbound 联调。
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 5. 分场景操作步骤(给测试人员逐步勾选)
|
|
|
|
|
+
|
|
|
|
|
+### 场景 A · 对接 T8(DB):KPI + 报工
|
|
|
|
|
+
|
|
|
|
|
+**目标**:证明 T8 连通、账套映射正确、KPI / 报工能出数。
|
|
|
|
|
+
|
|
|
|
|
+1. [ ] 确认 `T8_V5_SQLSERVER.status=1`,网络可达(见 §3.1)。
|
|
|
|
|
+2. [ ] 确认租户映射:`pbxfxp` → `797403760988229`(§6);或 refresh 显式带 `targetTenantId`。
|
|
|
|
|
+3. [ ] 登录 Demo 租户(或用匿名 API)。
|
|
|
|
|
+4. [ ] 调用 KPI:
|
|
|
|
|
+ - `POST …/s5-mdp/refresh?targetTenantId=797403760988229&targetFactoryId=1`
|
|
|
|
|
+ - 同理 `s6-mdp/refresh`、`s7-mdp/refresh`
|
|
|
|
|
+5. [ ] 验收 KPI:
|
|
|
|
|
+
|
|
|
|
|
+```sql
|
|
|
|
|
+SELECT module_code, metric_code, metric_value, biz_date, tenant_id, calc_time
|
|
|
|
|
+FROM ado_s9_kpi_value_l1_day
|
|
|
|
|
+WHERE tenant_id = 797403760988229
|
|
|
|
|
+ORDER BY calc_time DESC
|
|
|
|
|
+LIMIT 50;
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+6. [ ] 报工 DB 路:`POST …/s6-report-mdp/inbound?fullRefresh=true`(默认 `S6_REPORT`→T8 `Cj_Bg_Head_Rep`)。
|
|
|
|
|
+7. [ ] 验收报工:
|
|
|
|
|
+
|
|
|
|
|
+```sql
|
|
|
|
|
+SELECT source_system, source_biz_key, process_status, sync_batch_id, sync_time
|
|
|
|
|
+FROM mdp_stg_s6_report
|
|
|
|
|
+ORDER BY id DESC LIMIT 20;
|
|
|
|
|
+
|
|
|
|
|
+SELECT work_order_no, report_date, report_qty, source_biz_key, sync_batch_id
|
|
|
|
|
+FROM mdp_std_s6_report
|
|
|
|
|
+ORDER BY id DESC LIMIT 20;
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**通过标准**:refresh 不抛「未找到 ztid 映射」;KPI 或报工至少一侧有新增/更新行(T8 当日无业务时允许 0 行但接口 `ok=true`)。
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### 场景 B · 对接本库 DB:S5 收货 / S6 IPQC / S7 入库
|
|
|
|
|
+
|
|
|
|
|
+**目标**:本库有源数据时,业务入站打通 stg→std。
|
|
|
|
|
+
|
|
|
|
|
+1. [ ] 确认 `AIDOPDEV_MYSQL.status=1`,对应 DB 实体 `status=1` 且 `source_api_path` 为空。
|
|
|
|
|
+2. [ ] (可选)灌样板:`doc/db/mdp/s5_dual_mode_sample_seed.sql`、`s6_s7_dual_mode_sample_seed.sql`;AIDOPB 用 `aidopb_b2_*.sql`。
|
|
|
|
|
+3. [ ] 依次调用:
|
|
|
|
|
+
|
|
|
|
|
+```http
|
|
|
|
|
+POST /api/AidopKanban/s5-purchase-receipt-mdp/inbound?fullRefresh=true
|
|
|
|
|
+POST /api/AidopKanban/s6-ipqc-inspection-mdp/inbound?fullRefresh=true
|
|
|
|
|
+POST /api/AidopKanban/s7-production-receipt-mdp/inbound?fullRefresh=true
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+4. [ ] 验收(示例 S5):
|
|
|
|
|
+
|
|
|
|
|
+```sql
|
|
|
|
|
+SELECT source_system, source_biz_key, process_status, sync_batch_id
|
|
|
|
|
+FROM mdp_stg_purchase_receipt
|
|
|
|
|
+ORDER BY id DESC LIMIT 20;
|
|
|
|
|
+
|
|
|
|
|
+SELECT source_system, source_biz_key, receiver, item_num, qty_received, sync_batch_id
|
|
|
|
|
+FROM mdp_std_purchase_receipt
|
|
|
|
|
+ORDER BY id DESC LIMIT 20;
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+S6 / S7 将表名换成 `mdp_stg_ipqc_pull` / `mdp_std_ipqc_inspection`、`mdp_stg_production_receipt` / `mdp_std_production_receipt`。
|
|
|
|
|
+
|
|
|
|
|
+5. [ ] 配置中心:打开任务 `S5_PURCHASE_RECEIPT_INBOUND` / `S6_IPQC_INSPECTION_INBOUND` / `S7_PRODUCTION_RECEIPT_INBOUND` → 调度设 `FULL` 或 `ROLLING`+`30d`,再手工触发或等 Job。
|
|
|
|
|
+
|
|
|
|
|
+**通过标准**:接口返回 `ok=true`;stg 有 `PENDING→DONE`;std 出现对应 `source_biz_key`。源表 0 行时允许处理数为 0。
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### 场景 C · 对接第三方 MES+WMS(API):Mock 或真源
|
|
|
|
|
+
|
|
|
|
|
+**目标**:API 路能落同一 stg/std,且业务键与 DB 路一致。
|
|
|
|
|
+
|
|
|
|
|
+#### C1 · Mock 联调(无真系统时)
|
|
|
|
|
+
|
|
|
|
|
+1. [ ] 启动 Mock(§3.2),确认 `WMS_API` 指向 `8018`。
|
|
|
|
|
+2. [ ] **报工 API**(最简单,支持 `entityCode`):
|
|
|
|
|
+
|
|
|
|
|
+```http
|
|
|
|
|
+POST /api/AidopKanban/s6-report-mdp/inbound?fullRefresh=true&entityCode=S6_REPORT_API
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+3. [ ] **收货 / IPQC / 入库**:按 §4.3 做法甲临时改实体 → 调对应 inbound → **改回 DB**。
|
|
|
|
|
+4. [ ] 或跑契约脚本(§4.3 做法乙)。
|
|
|
|
|
+5. [ ] 对比键(手工):
|
|
|
|
|
+
|
|
|
|
|
+```sql
|
|
|
|
|
+-- 将 BATCH_DB / BATCH_API 换成实际 sync_batch_id
|
|
|
|
|
+SELECT source_biz_key FROM mdp_std_purchase_receipt WHERE sync_batch_id = 'BATCH_DB'
|
|
|
|
|
+ORDER BY 1;
|
|
|
|
|
+SELECT source_biz_key FROM mdp_std_purchase_receipt WHERE sync_batch_id = 'BATCH_API'
|
|
|
|
|
+ORDER BY 1;
|
|
|
|
|
+-- 两集合应一致(契约脚本已自动化此断言)
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+#### C2 · 真实 MES/WMS
|
|
|
|
|
+
|
|
|
|
|
+1. [ ] 按 §3.3 改 `WMS_API` 的 URL/Token。
|
|
|
|
|
+2. [ ] 用 Postman 先直连对方接口,确认 `data.list` + `bizKey` + 业务字段。
|
|
|
|
|
+3. [ ] 再按 C1 步骤走 inbound / 契约。
|
|
|
|
|
+4. [ ] 记录对方环境、账号、样例 `bizKey`、成功 `sync_batch_id` 到 UAT 证据表。
|
|
|
|
|
+
|
|
|
|
|
+**通过标准**:API 路 std 非空(有源时);与 DB 路(或契约双路)`source_biz_key` 集合一致;`mdp_sync_log` / 接口响应无鉴权失败。
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### 场景 D · 回写 Outbox(IQC / IPQC / FQC → QMS)
|
|
|
|
|
+
|
|
|
|
|
+> 机制详见下方 **§5.1**;本场景只列操作勾选。
|
|
|
|
|
+
|
|
|
|
|
+| action_code | 触发业务动作 | target_source |
|
|
|
|
|
+|-------------|--------------|---------------|
|
|
|
|
|
+| `S5_IQC_RESULT_PUSH` | IQC 检验单主管通过且判定**合格** | `QMS_API` |
|
|
|
|
|
+| `S6_REPORT_PUSH` | IPQC 主管判定合格结束 | `QMS_API` |
|
|
|
|
|
+| `S7_FQC_RESULT_PUSH` | FQC 主管通过且合格 | `QMS_API` |
|
|
|
|
|
+
|
|
|
|
|
+步骤:
|
|
|
|
|
+
|
|
|
|
|
+1. [ ] 在对应模块完成一张合格闭环单据(租户正确)。
|
|
|
|
|
+2. [ ] 查 Outbox(SQL 见 §5.1.4)。
|
|
|
|
|
+3. [ ] 确认 `status=0` 且 `payload_json` 含 `path/method/body`。
|
|
|
|
|
+4. [ ] 真推:§3.4 启用 `QMS_API` → 等 `MdpOutboxPushJob`(约 60s)→ `status=1`。
|
|
|
|
|
+5. [ ] 幂等:同一单据再点一次,不应新增相同 `idem_key`。
|
|
|
|
|
+6. [ ] (可选)用 Postman 模拟对方接单端,核对 URL/Body(§5.1.5)。
|
|
|
|
|
+
|
|
|
|
|
+**通过标准**:合格闭环后必有 Outbox 行;重复操作不双插;`QMS_API.status=0` 时允许长期待推但不报业务失败;启用后 HTTP 2xx 且 `status=1`。
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 5.1 回写给第三方:机制 · 对方约定 · Postman
|
|
|
|
|
+
|
|
|
|
|
+### 5.1.1 机制总览
|
|
|
|
|
+
|
|
|
|
|
+```text
|
|
|
|
|
+业务合格闭环(IQC/IPQC/FQC 主管通过)
|
|
|
|
|
+ │
|
|
|
|
|
+ ▼ 幂等 INSERT(失败不阻断业务)
|
|
|
|
|
+ mdp_outbox(status=0 待推)
|
|
|
|
|
+ │
|
|
|
|
|
+ ▼ MdpOutboxPushJob 约每 60 秒扫描
|
|
|
|
|
+ MdpApiPushExecutor
|
|
|
|
|
+ │ 读 mdp_source(target_source_code,默认 QMS_API,须 status=1)
|
|
|
|
|
+ │ 解析 payload_json:{ path, method, body }
|
|
|
|
|
+ ▼
|
|
|
|
|
+ HTTP method → api_base_url + path
|
|
|
|
|
+ Header: Authorization: Bearer <token>(api_auth_type=TOKEN/BEARER)
|
|
|
|
|
+ Body: payload.body(JSON)
|
|
|
|
|
+ │
|
|
|
|
|
+ ▼
|
|
|
|
|
+ 对方系统返回 2xx → outbox.status=1,记下 response_json
|
|
|
|
|
+ 非 2xx / 异常 → retry_count+1;未满 3 次保持 status=0 待重试;满 3 次 status=2 失败
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**硬约束**:前端 / 看板 **禁止** 直连第三方写接口;只允许业务服务写 Outbox + Job 推送。
|
|
|
|
|
+
|
|
|
|
|
+### 5.1.2 payload 约定(对方必须按此接)
|
|
|
|
|
+
|
|
|
|
|
+`mdp_outbox.payload_json` 固定形状:
|
|
|
|
|
+
|
|
|
|
|
+```json
|
|
|
|
|
+{
|
|
|
|
|
+ "path": "/iqc/result",
|
|
|
|
|
+ "method": "POST",
|
|
|
|
|
+ "body": { "...业务字段..." }
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+执行器实际请求:
|
|
|
|
|
+
|
|
|
|
|
+| 项 | 规则 |
|
|
|
|
|
+|----|------|
|
|
|
|
|
+| URL | `{QMS_API.api_base_url}` + `{path}`(path 以 `/` 开头) |
|
|
|
|
|
+| Method | payload.`method`,默认 `POST` |
|
|
|
|
|
+| Auth | `TOKEN`/`BEARER`:`Authorization: Bearer <api_auth_config.token>`;另支持 BASIC / APIKEY |
|
|
|
|
|
+| Content-Type | `application/json` |
|
|
|
|
|
+| Body | 仅发送 `body` 对象(不是整个 payload) |
|
|
|
|
|
+
|
|
|
|
|
+### 5.1.3 S5–S7 当前已接线的回写动作
|
|
|
|
|
+
|
|
|
|
|
+| action_code | 触发条件 | idem_key | 实际 HTTP | body 主要字段 |
|
|
|
|
|
+|-------------|----------|----------|-----------|---------------|
|
|
|
|
|
+| `S5_IQC_RESULT_PUSH` | IQC 主管通过且 `pd=0`(合格) | 检验单号 `FBILLNO` | `POST {base}/iqc/result` | `billId, billNo, pd, dhsl, bhgsl, action` |
|
|
|
|
|
+| `S6_REPORT_PUSH` | IPQC 整批合格结束 | 单据号 `djbh` | `POST {base}/ipqc/result` | `billId, billNo, jgpd, jyhgsl, jybhgsl, action` |
|
|
|
|
|
+| `S7_FQC_RESULT_PUSH` | FQC 主管通过且 `pd=0`(合格) | 检验单号 `FBILLNO` | `POST {base}/fqc/result` | `billId, billNo, pd, hgsl, bhgsl, action` |
|
|
|
|
|
+
|
|
|
|
|
+> 名称说明:任务书里 S6 出站 action 叫 `S6_REPORT_PUSH`,当前实装挂在 **IPQC 合格** 闭环(不是报工入库)。报工入站是 `S6_REPORT` / `S6_REPORT_API`,与此出站不同。
|
|
|
|
|
+
|
|
|
|
|
+对方系统需提供(或 Mock)上述三个 path;鉴权方式与 `QMS_API` 配置一致。
|
|
|
|
|
+
|
|
|
|
|
+### 5.1.4 Outbox 状态与验收 SQL
|
|
|
|
|
+
|
|
|
|
|
+| status | 含义 |
|
|
|
|
|
+|--------|------|
|
|
|
|
|
+| `0` | 待推 / 重试中 |
|
|
|
|
|
+| `1` | 推送成功(HTTP 2xx) |
|
|
|
|
|
+| `2` | 最终失败(重试 ≥ 3 或目标源未配置) |
|
|
|
|
|
+
|
|
|
|
|
+```sql
|
|
|
|
|
+SELECT id, tenant_id, target_source_code, action_code, idem_key,
|
|
|
|
|
+ status, retry_count, error_msg,
|
|
|
|
|
+ payload_json, LEFT(IFNULL(response_json,''), 300) AS resp_preview,
|
|
|
|
|
+ create_time, update_time
|
|
|
|
|
+FROM mdp_outbox
|
|
|
|
|
+WHERE action_code IN ('S5_IQC_RESULT_PUSH','S6_REPORT_PUSH','S7_FQC_RESULT_PUSH')
|
|
|
|
|
+ORDER BY id DESC
|
|
|
|
|
+LIMIT 30;
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+启用真推前:
|
|
|
|
|
+
|
|
|
|
|
+```sql
|
|
|
|
|
+-- 目标源必须 status=1 且 api_base_url 可达
|
|
|
|
|
+SELECT source_code, status, api_base_url, api_auth_type, api_auth_config
|
|
|
|
|
+FROM mdp_source WHERE source_code = 'QMS_API';
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 5.1.5 对方接口约定(给 MES/QMS 厂商)
|
|
|
|
|
+
|
|
|
|
|
+请满足:
|
|
|
|
|
+
|
|
|
|
|
+1. 提供 BaseUrl,例如 `https://qms.partner.local/api`。
|
|
|
|
|
+2. 实现(或网关转发)至少:
|
|
|
|
|
+ - `POST /iqc/result`
|
|
|
|
|
+ - `POST /ipqc/result`
|
|
|
|
|
+ - `POST /fqc/result`
|
|
|
|
|
+3. 鉴权:Bearer Token(与我方 `mdp_source.api_auth_config.token` 一致)。
|
|
|
|
|
+4. 成功返回 **HTTP 2xx**(建议 `{"code":0,"message":"ok"}`);非 2xx 我方会重试最多 3 次。
|
|
|
|
|
+5. 按 `body.billNo`(或 `billId`)做幂等,避免我方重试导致对方重复记账。
|
|
|
|
|
+
|
|
|
|
|
+样例请求(S5 IQC,Postman 可先手工打对方):
|
|
|
|
|
+
|
|
|
|
|
+```http
|
|
|
|
|
+POST https://<QMS-BaseUrl>/iqc/result
|
|
|
|
|
+Authorization: Bearer <token>
|
|
|
|
|
+Content-Type: application/json
|
|
|
|
|
+
|
|
|
|
|
+{
|
|
|
|
|
+ "billId": 123456789,
|
|
|
|
|
+ "billNo": "IQC20260724001",
|
|
|
|
|
+ "pd": 0,
|
|
|
|
|
+ "dhsl": 100,
|
|
|
|
|
+ "bhgsl": 0,
|
|
|
|
|
+ "action": "S5_IQC_RESULT_PUSH"
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 5.1.6 UAT 用 Postman / 本地 Mock 接单(可选)
|
|
|
|
|
+
|
|
|
|
|
+**目的**:在没有真实 QMS 时,验证 Job 真的发出了 HTTP。
|
|
|
|
|
+
|
|
|
|
|
+1. 用任意 HTTP 接单工具监听(示例:Postman Mock Server、webhook.site,或本机临时服务)。
|
|
|
|
|
+2. 把 `QMS_API` 指过去并 `status=1`(§3.4)。
|
|
|
|
|
+3. 走一张 IQC/IPQC/FQC **合格**闭环。
|
|
|
|
|
+4. 约 1 分钟内:接单端收到 `POST …/iqc|ipqc|fqc/result`;库中对应 Outbox `status=1`。
|
|
|
|
|
+5. 若一直 `status=0`:查 Job 是否调度、`QMS_API.status`、`error_msg`、网络出站。
|
|
|
|
|
+
|
|
|
|
|
+本地快速 Mock 接单示例(Python,仅 UAT):
|
|
|
|
|
+
|
|
|
|
|
+```python
|
|
|
|
|
+# 另开终端:python -m pip install flask && python qms_mock_receiver.py
|
|
|
|
|
+from flask import Flask, request
|
|
|
|
|
+app = Flask(__name__)
|
|
|
|
|
+
|
|
|
|
|
+@app.post("/iqc/result")
|
|
|
|
|
+@app.post("/ipqc/result")
|
|
|
|
|
+@app.post("/fqc/result")
|
|
|
|
|
+def recv():
|
|
|
|
|
+ print(request.path, request.get_json())
|
|
|
|
|
+ return {"code": 0, "message": "ok"}
|
|
|
|
|
+
|
|
|
|
|
+if __name__ == "__main__":
|
|
|
|
|
+ app.run(host="0.0.0.0", port=8020)
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+```sql
|
|
|
|
|
+UPDATE mdp_source
|
|
|
|
|
+SET api_base_url = 'http://127.0.0.1:8020',
|
|
|
|
|
+ api_auth_type = 'TOKEN',
|
|
|
|
|
+ api_auth_config = JSON_OBJECT('token','uat-mock-token'),
|
|
|
|
|
+ status = 1,
|
|
|
|
|
+ update_time = NOW()
|
|
|
|
|
+WHERE source_code = 'QMS_API';
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 5.1.7 与入站的区别(避免测混)
|
|
|
|
|
+
|
|
|
|
|
+| | 入站(第三方 → DOP) | 回写(DOP → 第三方) |
|
|
|
|
|
+|--|---------------------|----------------------|
|
|
|
|
|
+| 配置源 | `WMS_API` / 本库 / T8 | `QMS_API` |
|
|
|
|
|
+| 载体 | `mdp_entity` + Pull 执行器 | `mdp_outbox` + Push 执行器 |
|
|
|
|
|
+| 触发 | inbound API / 同步任务 | 业务合格闭环 |
|
|
|
|
|
+| 方向 | GET 拉 `data.list` | POST 推 `body` |
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 6. 租户与 T8 账套映射(KPI / 报工必读)
|
|
|
|
|
+
|
|
|
|
|
+| 项 | 值 |
|
|
|
|
|
+|----|-----|
|
|
|
|
|
+| 内置映射 | `pbxfxp` → `797403760988229`(Demo / AIDOP) |
|
|
|
|
|
+| 配置覆盖 | `appsettings` 段 `AidopMdp:ZtidTenantMap`,例如 `{ "pbxfxp": "797403760988229" }` |
|
|
|
|
|
+| 显式覆盖 | refresh 传 `targetTenantId>0` |
|
|
|
|
|
+| 失败策略 | **未映射 ztid 直接报错,绝不回退固定租户** |
|
|
|
|
|
+
|
|
|
|
|
+AIDOPB(`824585161322565`)无 T8:不要用它的租户去跑依赖 T8 的 KPI,除非单独配置了 ztid 映射。
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 7. 验收清单(S5–S7 签字用)
|
|
|
|
|
+
|
|
|
|
|
+| # | 检查项 | 路 | 证据 | 结果 |
|
|
|
|
|
+|---|--------|----|------|------|
|
|
|
|
|
+| 1 | `AIDOPDEV_MYSQL` / `T8_V5_SQLSERVER` / `WMS_API` 状态正确 | A/B | §3.1 SQL 截图 | ☐ |
|
|
|
|
|
+| 2 | S5 收货 inbound → stg/std | A | batch_id + 行数 | ☐ |
|
|
|
|
|
+| 3 | S6 IPQC inbound → stg/std | A | 同上 | ☐ |
|
|
|
|
|
+| 4 | S7 入库 inbound → stg/std | A | 同上 | ☐ |
|
|
|
|
|
+| 5 | S5–S7 KPI refresh(Demo 租户) | A·T8 | KPI SQL | ☐ |
|
|
|
|
|
+| 6 | S6 报工 T8 inbound | A·T8 | stg/std | ☐ |
|
|
|
|
|
+| 7 | S6 报工 API inbound(Mock 或真源) | B | `entityCode=S6_REPORT_API` | ☐ |
|
|
|
|
|
+| 8 | S5/S6/S7 API 路(改实体或契约脚本)与 DB 键一致 | B | 契约 PASS 或键对比 | ☐ |
|
|
|
|
|
+| 9 | IQC/IPQC/FQC Outbox 写入 | A | `mdp_outbox` | ☐ |
|
|
|
|
|
+| 10 | (可选)QMS 真推成功 | B | Outbox status 成功 | ☐ |
|
|
|
|
|
+| 11 | 调度 FULL/INCR/ROLLING 各验一次(任选一任务) | A | 调度抽屉 + 日志 | ☐ |
|
|
|
|
|
+
|
|
|
|
|
+自动化辅助:
|
|
|
|
|
+
|
|
|
|
|
+```bat
|
|
|
|
|
+cd doc\db\mdp\contract_tests
|
|
|
|
|
+python run_contract_s5_s6_s7.py
|
|
|
|
|
+python run_contract_s6_report.py
|
|
|
|
|
+python e2e_api_to_std_s5.py
|
|
|
|
|
+python e2e_api_to_std_s6.py
|
|
|
|
|
+python e2e_api_to_std_s7.py
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+(需本机 Python、`pymysql`/`requests`、Mock 已起、库账号环境变量见 `_db.py`。)
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 8. 常见问题
|
|
|
|
|
+
|
|
|
|
|
+| 现象 | 原因 | 处理 |
|
|
|
|
|
+|------|------|------|
|
|
|
|
|
+| inbound 仍读本库,不走 Mock | 实体仍挂 `AIDOPDEV_MYSQL` 且无 `source_api_path` | 按 §4.3 临时改实体,或只测 `S6_REPORT_API` |
|
|
|
|
|
+| API 401 | Token 与 `api_auth_config` / `MOCK_TOKEN` 不一致 | 三者改成同一值 |
|
|
|
|
|
+| KPI 报「未找到 ztid 映射」 | 账套未配置 | 配 `AidopMdp:ZtidTenantMap` 或传 `targetTenantId` |
|
|
|
|
|
+| Outbox 有行但不推 | `QMS_API.status=0` | 预期;真推前 §3.4 |
|
|
|
|
|
+| T8 超时 / 连不上 | 防火墙或账号 | 先 DBA 测 `T8_V5_SQLSERVER` 连接;KPI/报工 DB 路暂停 |
|
|
|
|
|
+| AIDOPB 无 KPI | D3:无 T8 | 用业务种子测入站,不测 T8 refresh |
|
|
|
|
|
+| 契约脚本连库失败 | 默认连 `127.0.0.1` | 设环境变量 `MDP_DB_HOST/PORT/USER/PASSWORD/NAME` |
|
|
|
|
|
+| `S6_REPORT` 实体不存在 | 未执行 `1.0.264` 或无 T8 源 | 执行 UpdateScript;确认 `T8_V5_SQLSERVER` 存在 |
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 9. 测试记录建议字段(粘贴到用例系统)
|
|
|
|
|
+
|
|
|
|
|
+```text
|
|
|
|
|
+环境:aidopdev / 前端版本 / 后端版本
|
|
|
|
|
+租户:________ ztid:________
|
|
|
|
|
+路:□ T8-DB □ 本库-DB □ Mock-API □ 真MES/WMS-API
|
|
|
|
|
+对象:□ S5收货 □ S6-IPQC □ S6报工 □ S7入库 □ KPI □ Outbox
|
|
|
|
|
+请求:方法/URL/参数
|
|
|
|
|
+sync_batch_id:________
|
|
|
|
|
+stg 行数 / std 行数 / 样例 source_biz_key:
|
|
|
|
|
+Outbox action / idem_key / status:
|
|
|
|
|
+结论:□ 通过 □ 失败 问题单:________
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 10. 相关文件索引
|
|
|
|
|
+
|
|
|
|
|
+| 类型 | 路径 |
|
|
|
|
|
+|------|------|
|
|
|
|
|
+| 交付任务书 | `doc/plan/AIDOP双模式全模块对接交付级任务书.md` |
|
|
|
|
|
+| Mock | `doc/db/mdp/mock_api/` |
|
|
|
|
|
+| 契约 / e2e | `doc/db/mdp/contract_tests/` |
|
|
|
|
|
+| 样板种子 | `doc/db/mdp/s5_dual_mode_sample_seed.sql`、`s6_s7_dual_mode_sample_seed.sql` |
|
|
|
|
|
+| DDL | `server/Admin.NET.Web.Entry/UpdateScripts/1.0.259.sql` … `1.0.264.sql` |
|
|
|
|
|
+| 租户映射 | `server/Plugins/.../Infrastructure/AidopSourceTenantMap.cs` |
|
|
|
|
|
+| 入站 API | `server/Plugins/.../Controllers/AidopKanbanController.cs` |
|