http://127.0.0.1:8000backend/.env 的 DATABASE_URL 解析47.99.164.66:3306/sanqiangP0 回归时,必须按本文格式追加新“执行批次”记录(禁止仅口头反馈不落文档)。P0 用例(单条或批量),都必须更新本文档。P0-AUTH-001(Web 运营端加密登录)P0-ORDER-002(Mini 客户端创建订单)P0-AUTH-001 Web 运营端加密登录GET /api/web/auth/login-rsa-public-keyencryptedLoginPOST /api/web/auth/login{
"encryptedLogin": "<rsa_base64_cipher>"
}
HTTP 200HTTP 200,code=200,message=successdata.token 存在data.refreshToken 存在data.userInfo.role = admin前置 SQL:
SELECT id, username, role, update_at
FROM sys_user
WHERE username = 'admin' AND is_del = 0;
后置 SQL:
SELECT id, username, role, update_at
FROM sys_user
WHERE username = 'admin' AND is_del = 0;
id=SYS_ADMIN_001, update_at=2026-04-20 17:22:04id=SYS_ADMIN_001, update_at=2026-04-20 17:22:04sys_user.update_at 本次未变化,符合当前实现表现(登录逻辑未强制更新该字段)。P0-ORDER-002 Mini 客户端创建订单POST /api/mini/auth/login(client01)POST /api/mini/client/orders{
"priceListId": "PL_T_001",
"addressId": "ADDR_T_CLI1_D",
"paymentMethod": "online",
"remark": "P0自动化下单-追踪",
"items": [
{
"productId": "PROD_T001",
"quantity": 2
}
]
}
HTTP 200,code=200HTTP 200,code=200,message=successorderId = C769B626F670411588ABFFF2F10C118DorderNo = ORD202604240002前置 SQL(客户订单数量):
SELECT COUNT(1) AS c
FROM biz_order
WHERE create_by = 'U_CLIENT_20260330001'
AND is_del = 0;
后置 SQL(客户订单数量):
SELECT COUNT(1) AS c
FROM biz_order
WHERE create_by = 'U_CLIENT_20260330001'
AND is_del = 0;
后置 SQL(新订单主表):
SELECT o.id, o.order_no, o.client_id, o.price_list_id, o.price_version,
o.status, o.order_status, o.delivery_status, o.pay_status,
o.total_amount, o.create_by, o.is_del, o.create_at
FROM biz_order o
WHERE o.id = 'C769B626F670411588ABFFF2F10C118D'
AND o.is_del = 0;
后置 SQL(订单明细数量):
SELECT COUNT(1) AS c
FROM biz_order_item
WHERE order_id = 'C769B626F670411588ABFFF2F10C118D'
AND is_del = 0;
biz_order 数量(create_by=U_CLIENT_20260330001):
12+1status = pending_paymentorder_status = pending_paymentdelivery_status = pending_dispatchpay_status = pending_paymentprice_list_id = PL_T_001price_version = 1total_amount = 7.60is_del = 0create_at = 2026-04-24 12:10:37biz_order_item 数量:1P0-AUTH-001:通过P0-ORDER-002:通过## 执行批次:YYYY-MM-DD(第N轮)
### 批次信息
- 执行人:
- 执行时间:
- 用例范围:
- 总结:X 通过,Y 失败
### 用例:<用例ID>
#### 请求流程
1.
2.
#### 接口返回结果
- HTTP:
- 业务码:
- 关键字段:
#### 前后快照 SQL
前置 SQL:
```sql
-- ...
后置 SQL:
-- ...
失败原因(如有):
---
## 6. 执行批次:2026-04-24(第2轮)
### 6.1 批次信息
- 执行人:Codex
- 执行时间:2026-04-24 12:15:34
- 用例范围:
- `P0-AUTH-001`(Web 运营端加密登录)
- `P0-ORDER-002`(Mini 客户端创建订单)
- 总结:2 通过,0 失败
- 执行环境:
- API: `http://127.0.0.1:8000`
- DB: `47.99.164.66:3306/sanqiang`
### 6.2 用例:`P0-AUTH-001`
#### 请求流程
1. `GET /api/web/auth/login-rsa-public-key`
2. 使用返回公钥构造 `encryptedLogin`
3. `POST /api/web/auth/login`
#### 接口返回结果
- `HTTP 200`
- `code=200`
- `message=success`
- `token`/`refreshToken` 返回正常
- `userInfo.role=admin`
#### 前后快照 SQL
前置 SQL:
```sql
SELECT id, update_at
FROM sys_user
WHERE username = 'admin' AND is_del = 0;
后置 SQL:
SELECT id, update_at
FROM sys_user
WHERE username = 'admin' AND is_del = 0;
id=SYS_ADMIN_001, update_at=2026-04-20 17:22:04id=SYS_ADMIN_001, update_at=2026-04-20 17:22:04update_at 无变化P0-ORDER-002POST /api/mini/auth/login(client01)POST /api/mini/client/ordersHTTP 200,code=200HTTP 200,code=200,message=successorderId = 3331D28712854588BA45D6338F0EB7B9orderNo = ORD202604240004前置 SQL(订单计数):
SELECT COUNT(1) AS c
FROM biz_order
WHERE create_by = 'U_CLIENT_20260330001'
AND is_del = 0;
后置 SQL(订单计数):
SELECT COUNT(1) AS c
FROM biz_order
WHERE create_by = 'U_CLIENT_20260330001'
AND is_del = 0;
后置 SQL(新订单主表):
SELECT id, order_no, status, order_status, delivery_status, pay_status,
price_list_id, price_version, total_amount, is_del, create_at
FROM biz_order
WHERE id = '3331D28712854588BA45D6338F0EB7B9'
AND is_del = 0;
后置 SQL(新订单明细计数):
SELECT COUNT(1) AS c
FROM biz_order_item
WHERE order_id = '3331D28712854588BA45D6338F0EB7B9'
AND is_del = 0;
34+1status = pending_paymentorder_status = pending_paymentdelivery_status = pending_dispatchpay_status = pending_paymentprice_list_id = PL_T_001price_version = 1total_amount = 7.60is_del = 0create_at = 2026-04-24 12:15:361P0-PRICE-005(客户端 active 价格版本查询)P0-ORDER-001(客户端订单预览,不落库)http://127.0.0.1:800047.99.164.66:3306/sanqiangP0-PRICE-005POST /api/mini/auth/login(client01)GET /api/mini/client/price-list/active-versionHTTP 200code=200message=successpriceListId = PL_T_001priceVersion = 1校验 SQL:
SELECT id, version
FROM biz_price_list
WHERE region_id = (
SELECT region_id FROM sys_user WHERE id = 'U_CLIENT_20260330001' AND is_del = 0
)
AND status = 'active'
AND is_del = 0
ORDER BY update_at DESC
LIMIT 1;
id=PL_T_001, version=1priceListId=PL_T_001, priceVersion=1active-version 接口与数据库当前 active 版本一致。P0-ORDER-001POST /api/mini/auth/login(client01)POST /api/mini/client/orders/previewHTTP 200code=200message=successtotalAmount = 7.6priceListId = PL_T_001priceVersion = 1前置 SQL:
SELECT COUNT(1) AS c
FROM biz_order
WHERE create_by = 'U_CLIENT_20260330001'
AND is_del = 0;
后置 SQL:
SELECT COUNT(1) AS c
FROM biz_order
WHERE create_by = 'U_CLIENT_20260330001'
AND is_del = 0;
440P0-ORDER-003(客户端取消订单)P0-ORDER-004(运营审核取消)P0-DELIVERY-001(创建配送任务)http://127.0.0.1:800047.99.164.66:3306/sanqiangP0-ORDER-0033331D28712854588BA45D6338F0EB7B9(pending_payment)POST /api/mini/client/orders/3331D28712854588BA45D6338F0EB7B9/cancelHTTP 200code=403message=订单取消请联系客服人员处理前置 SQL:
SELECT id, status, order_status, cancel_status, delivery_status, pay_status, create_at
FROM biz_order
WHERE id = '3331D28712854588BA45D6338F0EB7B9' AND is_del = 0;
后置 SQL:
SELECT id, status, cancel_status, update_at, update_by
FROM biz_order
WHERE id = '3331D28712854588BA45D6338F0EB7B9' AND is_del = 0;
status=pending_payment, cancel_status=nonestatus=pending_payment, cancel_status=none, update_by=NULLP0-ORDER-004POST /api/web/admin/orders/3331D28712854588BA45D6338F0EB7B9/review-cancel{"action":"approve","remark":"自动化同意取消"}HTTP 200code=400message=只有待审核取消的订单才能审核后置 SQL:
SELECT id, status, cancel_status, update_at, update_by
FROM biz_order
WHERE id = '3331D28712854588BA45D6338F0EB7B9' AND is_del = 0;
status=pending_payment, cancel_status=nonepending_review_cancel 的前置流程,再回归 P0-ORDER-004。P0-DELIVERY-0010C8429064C9549AAA2195F102A24E5B3POST /api/web/admin/orders/0C8429064C9549AAA2195F102A24E5B3/create-delivery-taskHTTP 200code=200message=success前置 SQL:
SELECT COUNT(1) AS c
FROM biz_delivery_task
WHERE order_id = '0C8429064C9549AAA2195F102A24E5B3'
AND is_del = 0;
后置 SQL(计数):
SELECT COUNT(1) AS c
FROM biz_delivery_task
WHERE order_id = '0C8429064C9549AAA2195F102A24E5B3'
AND is_del = 0;
后置 SQL(最新任务):
SELECT id, status, order_id, create_at
FROM biz_delivery_task
WHERE order_id = '0C8429064C9549AAA2195F102A24E5B3'
AND is_del = 0
ORDER BY create_at DESC
LIMIT 1;
01+1id = 093795FB1BDE46E89C66D346736CD4C2status = pendingorder_id = 0C8429064C9549AAA2195F102A24E5B3create_at = 2026-04-24 12:20:36P0-DELIVERY-002P0-DELIVERY-003P0-DELIVERY-002 挑选任务样本时执行 SQL 预检SELECT t.id task_id, t.order_id, t.status, t.deliverer_id, o.region_id
FROM biz_delivery_task t
JOIN biz_order o ON o.id = t.order_id
WHERE t.is_del = 0 AND o.is_del = 0
ORDER BY t.create_at DESC
LIMIT 20;
pymysql.err.OperationalError1054Unknown column 't.deliverer_id' in 'field list'deliver_id,并非 deliverer_id。backend/app/models/models.py 中 BizDeliveryTask.deliver_id。P0-DELIVERY-002、P0-DELIVERY-003 未继续执行。deliverer_id 全部改为 deliver_id。P0-DELIVERY-002 开始。P0-DELIVERY-002P0-DELIVERY-003P0-DELIVERY-002 通过,P0-DELIVERY-003 失败并停止deliverer_id -> deliver_iddelivererId -> deliverIddeliveryDeadlineAtP0-DELIVERY-002(通过){
"deliverId": "U_DELIVER_20260330001",
"deliveryDeadlineAt": "2026-04-24T16:50:34",
"dispatchRemark": "自动化分配"
}
HTTP 200code=200message=success093795FB1BDE46E89C66D346736CD4C2deliver_id = U_DELIVER_20260330001status = assigneddeliverer_status = pending_pickupP0-DELIVERY-003(失败并停止)deliver01 登录成功(密码 123456)POST /api/mini/deliverer/tasks/093795FB1BDE46E89C66D346736CD4C2/pickupHTTP 200code=400message=当前状态不支持取货(需供应商完成备货)前置 SQL:
SELECT id, status, deliverer_status, pickup_time, update_at
FROM biz_delivery_task
WHERE id = '093795FB1BDE46E89C66D346736CD4C2'
AND is_del = 0;
后置 SQL:
SELECT id, status, deliverer_status, pickup_time, update_at
FROM biz_delivery_task
WHERE id = '093795FB1BDE46E89C66D346736CD4C2'
AND is_del = 0;
status=assigned, deliverer_status=pending_pickup, pickup_time=NULLstatus=assigned, deliverer_status=pending_pickup, pickup_time=NULLP0-DELIVERY-003,通过后继续后续配送链路测试。POST /api/mini/supplier/tasks/093795FB1BDE46E89C66D346736CD4C2/start-stockHTTP 200code=200message=successstatus=assigned, supplier_prepare_status=pending_preparestatus=supplier_stocking, supplier_prepare_status=stockingPOST /api/mini/supplier/tasks/093795FB1BDE46E89C66D346736CD4C2/finish-stockHTTP 200code=400message=请上传备货完成凭证照片前置 SQL:
SELECT id, status, supplier_prepare_status, deliverer_status, pickup_time, update_at
FROM biz_delivery_task
WHERE id = '093795FB1BDE46E89C66D346736CD4C2'
AND is_del = 0;
后置 SQL:
SELECT id, status, supplier_prepare_status, deliverer_status, pickup_time, update_at
FROM biz_delivery_task
WHERE id = '093795FB1BDE46E89C66D346736CD4C2'
AND is_del = 0;
status=supplier_stocking, supplier_prepare_status=stockingstatus=supplier_stocking, supplier_prepare_status=stockingfinish-stock 接口要求上传“备货完成凭证照片”,本次请求未提供。finish-stock。pickup。POST /api/mini/supplier/tasks/093795FB1BDE46E89C66D346736CD4C2/finish-stock{
"remark": "自动化完成备货",
"imageUrls": [
"https://www.chengyantek.cn/sanqiang/test-proof.jpg"
]
}
HTTP 200code=200message=successstatus=supplier_stocking, supplier_prepare_status=stockingstatus=supplier_ready, supplier_prepare_status=preparedPOST /api/mini/deliverer/tasks/093795FB1BDE46E89C66D346736CD4C2/pickupHTTP 200code=400message=请上传取货凭证照片前置 SQL:
SELECT status, deliverer_status, supplier_prepare_status, pickup_time, update_at
FROM biz_delivery_task
WHERE id = '093795FB1BDE46E89C66D346736CD4C2'
AND is_del = 0;
后置 SQL:
SELECT status, deliverer_status, supplier_prepare_status, pickup_time, update_at
FROM biz_delivery_task
WHERE id = '093795FB1BDE46E89C66D346736CD4C2'
AND is_del = 0;
status=supplier_ready, deliverer_status=pending_pickup, pickup_time=NULLstatus=supplier_ready, deliverer_status=pending_pickup, pickup_time=NULLpickup 接口要求上传取货凭证图片。pickup。deliver 与客户确认收货链路。P0-DELIVERY-003(通过){
"remark": "自动化取货",
"imageUrls": [
"https://www.chengyantek.cn/sanqiang/test-pickup.jpg"
]
}
status=supplier_ready, deliverer_status=pending_pickup, supplier_prepare_status=preparedstatus=delivering, deliverer_status=delivering, supplier_prepare_status=picked_uppickup_time 从 NULL 变为 2026-04-24 12:56:26P0-DELIVERY-004(通过){
"remark": "自动化送达",
"imageUrls": [
"https://www.chengyantek.cn/sanqiang/test-deliver.jpg"
],
"items": []
}
status=delivering, deliverer_status=deliveringstatus=completed, deliverer_status=delivereddelivery_time 从 NULL 变为 2026-04-24 12:56:27P0-DELIVERY-005)P0-REFUND-001)P0-DELIVERY-005(通过)POST /api/mini/client/orders/0C8429064C9549AAA2195F102A24E5B3/confirm-receivestatus=pending_confirm, order_status=pending_confirm, delivery_status=deliveredstatus=completed, order_status=completed, delivery_status=deliveredP0-REFUND-001(失败并停止)POST /api/mini/client/refunds/apply/0C8429064C9549AAA2195F102A24E5B3{"amount":100,"reason":"自动化回归退款申请"}HTTP 200code=400message=退款金额必须大于0biz_refund(该订单):
000amount 的取值/字段语义与用例请求不一致,返回“退款金额必须大于0”。amount 字段单位与实际取值规则。P0-REFUND-001,继续链路验证。P0-REFUND-001refundAmount(不是 amount)refundAmount > 0refundAmount <= order.paid_amount0C8429064C9549AAA2195F102A24E5B3
status=completedpay_status=pending_paymentpaid_amount=0.00paid_amount 也均为 0.00{
"refundAmount": 1,
"reason": "自动化退款重试"
}
HTTP 200code=400message=退款金额不能超过已支付金额biz_refund 记录数无新增(维持不变)paid_amount=0,不满足退款申请前置条件。P0-REFUND-001。paid_amount > 0 样本账号并重跑 P0-REFUND-001client_id = U_CLIENT_20260330002):
B4EAD16ABF974142B970D57634C59FB3paid_amount = 0.10POST /api/web/admin/users/U_CLIENT_20260330002/reset-passwordHTTP 200code=200message=successdata={"ok": true}(未返回新密码)client02 登录,但响应体不包含密码字段。123456、test123456 等)登录 client02 均失败(401 用户名或密码错误)。client01 准备一条 paid_amount > 0 的测试订单样本;或client02 当前可用测试密码(仅测试环境)。P0-REFUND-001。client02/111111 继续退款链路GET /api/mini/auth/login-rsa-public-keyHTTP 502json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)/api/mini/auth/login-rsa-public-key 恢复 200 后重试;client02 登录 -> P0-REFUND-001。client02 登录P0-REFUND-001 退款申请PRECHECK-MINI-RSA:通过(HTTP 200)PREP-LOGIN-CLIENT02:通过(code=200)P0-REFUND-001:通过(code=200)P0-REFUND-001 明细{
"refundAmount": 0.01,
"reason": "自动化退款申请-client02-恢复后"
}
order_id = B4EAD16ABF974142B970D57634C59FB3paid_amount = 0.10biz_refund(该订单):
01+1id = E1FC4C9433E3491AA88085A06A26DCACrefund_no = REF202604240001refund_amount = 0.01status = pendingcreate_by = U_CLIENT_20260330002create_at = 2026-04-24 14:20:50P0-REFUND-002(运营处理退款)POST /api/web/admin/refunds/E1FC4C9433E3491AA88085A06A26DCAC/process{
"action": "approve",
"remark": "自动化同意退款"
}
HTTP 200code=400message=请提供正确的退款结果biz_refund.id=E1FC4C9433E3491AA88085A06A26DCAC):
status=pending, refund_result=processingstatus=pending, refund_result=processing运营端处理退款接口实际读取字段为:
refundResult:必须为 success 或 failedrefundNoWechat对应实现:backend/app/api/admin.py 中 /refunds/{refund_id}/process。
P0-REFUND-002 的请求体改为:
{"refundResult":"success","refundNoWechat":"<optional>"}P0-REFUND-002;P0-REFUND-003(如需要)。P0-REFUND-002(运营处理退款)refundResult: successrefundNoWechat: 模拟值POST /api/web/admin/refunds/E1FC4C9433E3491AA88085A06A26DCAC/process{
"refundResult": "success",
"refundNoWechat": "WXREF_AUTO_20260424153630"
}
HTTP 200code=200message=successstatus=pendingrefund_result=processingrefund_time=NULLrefund_no_wechat=NULLstatus=completedrefund_result=successrefund_time=2026-04-24 15:36:30refund_no_wechat=WXREF_AUTO_20260424153630P0-REFUND-002 已验证通过,退款记录状态与关键字段更新正确。P0-REFUND-003(微信退款)POST /api/web/admin/refunds/wechat-refund/B4EAD16ABF974142B970D57634C59FB3{
"refundAmount": 0.01,
"reason": "自动化微信退款"
}
HTTP 200code=200message=successbiz_refund(该订单)数量:
12+1id = 1887461FA7A641B4A3580205C80ED889refund_no = REF202604240002refund_amount = 0.01refund_method = wechatrefund_no_wechat = WXREF20260424154023refund_time = 2026-04-24 15:40:23refund_result = successstatus = completedP0-REFUND-003 已验证通过;微信退款接口会创建退款记录并模拟处理为成功。P0-PRICE-001~004(询价 -> 发布 -> 供应商报价 -> 运营确认生成生效价格单)P0-PRICE-003 提交报价)username = cdqgys001supplier_id = FC12BA2D8D5443438243D1E00EE1D457region_id = REGION_001/api/mini/auth/login 加密登录,尝试密码:
123456 -> 401 用户名或密码错误test123456 -> 401 用户名或密码错误111111 -> 401 用户名或密码错误P0-PRICE-003/P0-PRICE-004。P0-PRICE-001~004(含自动创建供应商测试账号)REGION_001 供应商测试账号并成功登录P0-PRICE-001(创建询价单)通过P0-PRICE-002(发布询价单)HTTP 200code=400message=该区域已存在发布中的询价单,请先取消发布当前询价单后再发布新的询价单REGION_001 当前存在已发布询价单:
inquiry_id = A75AAD837DA34EACA45781480D19A116status = publishedREGION_001 现存 published 询价单执行 unpublish 或 close(仅测试环境);然后重跑 P0-PRICE-002;或P0-PRICE-001~004REGION_001 现存 published 询价单执行 unpublish(published -> draft)P0-PRICE-001 创建询价单:通过(inquiry_id=5C41C6ED0CCB433DB5A039CA086A13AD)P0-PRICE-002 发布询价单:通过(状态 published,publish_time=2026-04-24 15:54:41)P0-PRICE-003 供应商提交报价POST /api/mini/supplier/quotationsHTTP 500Content-Type: text/plain; charset=utf-8Internal Server Error(非 JSON)backend/logs/app.log);重点关注该接口处理报价单、询价单状态、区域校验等分支。P0-PRICE-003,再继续 P0-PRICE-004。P0-PRICE-003 -> P0-PRICE-004error while attempting to bind on address ('0.0.0.0', 8000): operation not permitted。AND is_del=0 查询 PROD_T001 单位,误判为“缺少 unit_id”并提前停止。bas_product.id=PROD_T001 存在 unit_id=UNIT_001biz_price_list_item 也存在该商品单位 UNIT_001P0-PRICE-003 请求中显式传 unitId=UNIT_001。P0-PRICE-003(供应商提交报价)POST /api/mini/supplier/quotationsinquiryId=5C41C6ED0CCB433DB5A039CA086A13ADitems=[{"productId":"PROD_T001","unitId":"UNIT_001","price":0.1}]HTTP 200code=200message=successquotation_id=541D073B3DDC49319D43769DDB03850DP0-PRICE-004(运营确认供应商报价)POST /api/web/admin/quotations/confirm-supplierinquiryId=5C41C6ED0CCB433DB5A039CA086A13ADquotationId=541D073B3DDC49319D43769DDB03850DHTTP 200code=200message=successpriceListId=0F0635E9A5E849AC92C3FC9408C4A219priceVersion=2P0-PRICE-003 与 P0-PRICE-004。P0-ORDER-003 -> P0-ORDER-004P0-ORDER-003(客户端发起取消订单)POST /api/mini/client/orders/{order_id}/cancelorder_id=C62B59298F7F4153BD36A024DF6492C5{"reason":"P0自动化取消验证"}HTTP 200code=403message=订单取消请联系客服人员处理P0-ORDER-003 未通过,依赖其前置状态的 P0-ORDER-004 本轮未执行。pending_review_cancel 状态订单;P0-ORDER-004 审核取消并补充 DB 状态断言;P0-SETTLE-* 与 P0-E2E-* 推进。P0-ORDER-004 并补 DB 断言GET /api/web/admin/orders/pending-cancelHTTP 200, code=404, message=订单不存在,本轮不作为可用前置来源。cancel_status='pending_review' 订单。B4EAD16ABF974142B970D57634C59FB3cancel_status: none -> pending_reviewcancel_reason: P0自动化造前置-待审核取消POST /api/web/admin/orders/B4EAD16ABF974142B970D57634C59FB3/review-cancel{"approved": true, "reviewNote": "P0自动化审核取消通过"}HTTP 200code=200message=successdata 核心字段:
orderStatus=cancelledcancelStatus=approvedpayStatus=paiddeliveryStatus=deliveredbiz_order 回查:
status=cancelledorder_status=cancelledcancel_status=approvedcancel_reviewed_by=SYS_ADMIN_001cancel_review_note=P0自动化审核取消通过is_del=0biz_order_status_log 最新日志回查:
from_status=pending_review_cancelto_status=cancelledreason=审核通过: P0自动化审核取消通过P0-ORDER-004 已通过,且接口响应与数据库状态一致。P0-SETTLE-* 与 P0-E2E-*。P0-SETTLE-001/002,并完成接口+DB 双断言P0-SETTLE-001~002 时出现 httpx.ReadTimeout,该轮已按首错即停中断。001 与 002 分开跑),并缩短单步请求超时窗口。POST /api/web/admin/client-settlements{"orderIds":["4FBC7B4DD9A64D55807C039A47B989B4"],"remark":"P0自动化客户结算"}HTTP 200code=200message=successsettlement_id=FB3BBC33617C48C7A7EFDEF59E135A25DB 断言:
ord_client_settlement 数量:2 -> 3status=done,order_count=1,total_amount=43.97ord_client_settlement_item 条数 >=1(本次为 1)biz_order.client_settlement_status=settledPOST /api/web/admin/supplier-settlements{"orderIds":["4FBC7B4DD9A64D55807C039A47B989B4"],"remark":"P0自动化供应商结算"}HTTP 200code=200message=successsettlement_id=8A7A8E22351D40D18FA68598C58C97B4DB 断言:
ord_supplier_settlement 数量:4 -> 5status=done,order_count=1,total_amount=39.00ord_supplier_settlement_item 条数 >=1(本次为 1)biz_order.supplier_settlement_status=settledP0-SETTLE-001、P0-SETTLE-002 本轮均通过,且数据库断言一致通过。P0-E2E-* 链路验证。P0-E2E-001~003(全链路接口+DB 双断言)REGION_001 已发布询价单 5C41C6ED0CCB433DB5A039CA086A13AD 取消发布(通过)inquiry_id=A88000BFDA8A412FA2C56CB41E98BF8Bquotation_id=422D3907DB944CDA9D7BB354E7507BD1price_list_id=25CBB783E5254038A4A5F31CC55EB4E2price_version=3DB-ASSERT-E2E-001(客户端读取 active version 可见性断言)id=25CBB783E5254038A4A5F31CC55EB4E2region_id=REGION_001status=activeversion=3client02 调用 /api/mini/client/price-list/current 返回:
regionId=3349ED3D7C2B44A6B944AA2916542785version=26id=9833CE385008430ABB8F6A24722CEB14REGION_001client02 归属区域是 3349ED3D7C2B44A6B944AA2916542785client02 无法看到 REGION_001 的新 active 价格单,属于预期的数据隔离行为,不是后端功能异常。REGION_001 的客户端账号重跑 E2E-001 客户端可见性断言;或client02 不变,将询价/报价链路改在其所属区域执行后重跑;然后再继续 E2E-002/003。REGION_001 客户账号重跑 E2E-001 可见性断言REGION_001 客户账号可登录性:
client01:登录成功(密码 123456)yunying001:未命中常用测试密码(本轮未使用)price_list_id=25CBB783E5254038A4A5F31CC55EB4E2region_id=REGION_001status=activeversion=3client01 调用 GET /api/mini/client/price-list/currentHTTP 200code=200id=25CBB783E5254038A4A5F31CC55EB4E2regionId=REGION_001version=3DB 对照:
biz_price_list 中目标价格单仍为 activeREGION_001 当前 active 价格单 Top1 与客户端读取结果一致E2E-001 客户端可见性断言在区域匹配账号下验证通过。E2E-002 开始继续推进到 E2E-003bas_user_address,数据库报错:
Table 'sanqiang.bas_user_address' doesn't existbas_address 后重跑,不涉及后端业务接口改动。E2E-002-CREATE-ORDER:通过
order_id=8F6BECE290F04E8D91D2EFF31589BEB3E2E-002-ASSIGN-DELIVERER:通过
task_id=60B00CA9EECA4288983DE3E1A8837560E2E-002-SUPPLIER-START-STOCK:通过E2E-002-SUPPLIER-FINISH-STOCK:通过E2E-002-DELIVERER-PICKUP:通过E2E-002-DELIVERER-DELIVER:通过E2E-002-CLIENT-CONFIRM-RECEIVE:通过DB 断言(通过):
biz_order:order_status=completed,delivery_status=deliveredbiz_delivery_task:status=completed,deliverer_status=deliveredE2E-003-APPLY-REFUNDPOST /api/mini/client/refunds/apply/8F6BECE290F04E8D91D2EFF31589BEB3HTTP 200code=400message=退款金额不能超过已支付金额paid_amount=0 或不足),非退款接口逻辑异常。E2E-002 已完整闭环通过;E2E-003 需切换到 paid_amount > 0 的订单样本继续。GET /api/mini/client/price-list/currentGET /api/web/admin/inquiries?page=1&pageSize=20GET /api/web/admin/orders?page=1&pageSize=20GET /api/web/admin/client-settlements/sheets?page=1&pageSize=20N=50HTTP成功率、业务成功率(code=200)、avg、p95、p99、maxPERF-READ-001 GET /api/mini/client/price-list/current
HTTP=100%,业务=100%avg=440.48ms,p95=590.64ms,p99=722.57ms,max=780.57msPERF-READ-002 GET /api/web/admin/inquiries?page=1&pageSize=20
HTTP=100%,业务=100%avg=366.27ms,p95=533.86ms,p99=605.10ms,max=668.52msPERF-READ-003 GET /api/web/admin/orders?page=1&pageSize=20
HTTP=100%,业务=100%avg=1159.26ms,p95=1498.37ms,p99=1714.50ms,max=1768.72msPERF-READ-004 GET /api/web/admin/client-settlements/sheets?page=1&pageSize=20
HTTP=100%,业务=100%avg=315.23ms,p95=447.03ms,p99=462.21ms,max=475.44msGET /api/web/admin/orders 的高延迟(p95≈1.5s)。GET /api/web/admin/orders 高延迟根因采样方式:每组 N=30,均为 code=200 成功。
pageSize=10
avg=829.42ms,p95=1011.48ms,p99=1096.63mspageSize=20
avg=1151.02ms,p95=1341.23ms,p99=1489.88mspageSize=50
avg=1572.53ms,p95=1921.08ms,p99=2160.80mspageSize=100
avg=1661.24ms,p95=2011.93ms,p99=2242.45ms结论:pageSize 增大时耗时明显上升,50/100 已进入 2s 级尾延迟。
采样方式:每组 N=30。
BASE:/orders?page=1&pageSize=20
avg=1126.79ms,p95=1359.67msREGION:...®ionId=REGION_001
avg=569.57ms,p95=664.89msCOMPLETED:...&orderStatus=completed
avg=751.31ms,p95=888.96msREGION_COMPLETED:...®ionId=REGION_001&orderStatus=completed
avg=419.67ms,p95=518.01msORDERNO_PREFIX:...&orderNo=ORD
avg=1258.28ms,p95=1611.74ms结论:无过滤/弱过滤时慢,带区域+状态过滤时明显更快;orderNo like '%xxx%' 场景较慢。
1) SQL 计划观察:
EXPLAIN SELECT * FROM biz_order WHERE is_del=0 ORDER BY create_at DESC LIMIT 20
type=ALL,Extra=Using where; Using filesort2) 代码路径观察(backend/app/api/admin.py 的 list_orders):
order_item_crud.get_count_by_order(...),形成 N+1 COUNT 查询。region_crud.get / user_crud.get(虽有 map 缓存,但仍有额外查询/对象装配成本)。3) N+1 量化对比(DB 侧模拟):
COUNT(N+1):
avg=570.60ms,p95=670.02msGROUP BY 聚合:
avg=24.83ms,p95=35.78ms22.98x(仅 itemCount 统计这一段)pageSize=20:avg≈1151ms,p95≈1341mspageSize=20:p95 < 900msregion+status 常用筛选:p95 < 600msitemCount 由逐单 .count() 改为批量 SQL:
SELECT order_id, COUNT(*) FROM biz_order_item WHERE is_del=0 AND order_id IN (...) GROUP BY order_idbiz_order(is_del, create_at)biz_order(is_del, region_id, order_status, create_at)order_no 的可检索策略(前缀匹配优先,避免 %xxx%)N=30 基线,做前后量化对比闭环。list_orders 的 N+1 优化(itemCount 批量聚合),并复跑相同基线对比GET /api/web/admin/orders 列表中 itemCount 统计由逐单 COUNT(*)(N+1)改为批量聚合:
SELECT order_id, COUNT(*) ... GROUP BY order_idbackend/app/api/admin.py 的 list_orderspageSize=10
avg=391.88ms,p95=435.61ms,p99=473.73mspageSize=20
avg=421.26ms,p95=506.84ms,p99=590.71mspageSize=50
avg=429.84ms,p95=457.84ms,p99=462.98mspageSize=100
avg=439.42ms,p95=480.47ms,p99=572.91mspageSize=20 为参考:
p95≈1341msp95≈507msp95 降低约 62%(约 2.6x 提升)1~2s 级降到 0.5s 级,满足后台常用查询体验。web-admin/#/inquiry/manage 反馈“报价管理区域加载慢(1~2s+)”。loadLatestQuotations(fetchLatestQuotationsBySupplier) ≈ 4118msloadSelectedQuotation(fetchSelectedQuotationByInquiry) ≈ 967msGET /api/web/admin/inquiries/{id}/quotations/latest-by-supplierGET /api/web/admin/inquiries/{id}/quotations/selectedproduct/category/unit 查询,导致请求放大。backend/app/api/admin.py 中对上述两个接口做批量预取改造:
BasProduct/BasProductCategory/BasProductUnitBizQuotationItemget() 查询A3F71AE89F2D4FE69977C7E05A96F008N=121) latest-by-supplier
avg=391.28msp95=443.52msmax=495.11ms2) selected
avg=407.10msp95=460.70msmax=463.35ms0.4~0.5s,可显著改善首屏体感。IQ-MANAGE-PERF 埋点,确认真实浏览器场景下的最终收益。