kate522
ca9dc7794f
refactor(pay): 流水号扩至 22 字符,移除资金流水归档方案与删单守卫
四件事合在一笔,因为它们落在同一批文件里——OrderRepositoryCore 与流水契约测试
同时承载号码规则与订单清理逻辑,硬拆会产生引用不通的中间提交。
1) 号码熵。{YmdHis}{6 位随机} 在同一秒内只有 10^6 的取值空间,高并发下单会因
随机后缀碰撞触发 uniq_order_number / uniq_flow_number 冲突(每秒 3 单约
2.6 天撞一次,每秒 10 单约每天 4 次)。后缀扩到 8 位后空间升至 10^8
(+6.6 bit),撞号频率下降两个数量级。
选 8 位纯数字而非等长 base36:保持定长纯数字形态,号码仍可被运营从截图或
邮件整段复制、电话口述;且表默认排序规则是 utf8mb4_*_ci(大小写不敏感),
混入大小写字母会让唯一索引把 aB 与 Ab 判为重复行,反而凭空制造冲突。22 字符
仍满足 VARCHAR(32) 与网关 out_trade_no ≤ 32,拼上重试后缀 P999 后为 26 字符。
2) 自带订单号形态校验。create() 此前对调用方传入的 order_number 不做检查,传数组
会因 (string) 转换把字面量 "Array" 写进列。现收紧为「全数字、20 或 22 位」,
不合规即弃用并回落到分配器(WP_DEBUG 下留痕)。放行 20 位是为了兼容扩位前
分配的历史号码——该方法原有的注释就声明服务于导入、补单与幂等重放。
3) 流水表补 KEY idx_flow_created (created_at)。后台「资金流水」页默认视图是
WHERE 1=1 ORDER BY created_at DESC, id DESC LIMIT n 加同条件 COUNT(*),界面
上的日期区间筛选也只有 created_at 可用。此前没有任何以 created_at 为前导列的
索引(idx_flow_event_time 的前导列是 event_type,筛选时可空),于是每次翻页
都是全表扫描 + filesort,且与表大小无关地重复付出。
4) 移除归档方案与删单守卫。归档表 + 每日清理 cron 需要配套的归档浏览入口才闭环,
未闭环时运营会误以为记录丢失;而第 3 条的索引已覆盖它要解决的主要问题,且
不必在财务表上执行 DELETE。一并撤回删单 / 清理订单时对财务记录的拦截。
- BusinessNumber:后缀位数与上界收敛为 SUFFIX_DIGITS / SUFFIX_MAX,去掉三处
重复的魔法数字;类文档写明选型依据,避免日后被改回字母方案
- OrderRepositoryCore:新增 ORDER_NUMBER_PATTERN 与 is_scalar 守卫;
clear_closed_orders 与 delete_order 恢复单路签名(去掉 $force 与
$include_orders_with_records)
- DBMigratorPart2:流水表新增 idx_flow_created,并删除两张归档表 DDL
- PayOrders:清理与删除订单回到单路处理,移除 orders_clear_blocked /
order_delete_blocked 两条提示
- 删除 FinancialFlowRetention 类与 functions.php 中的引导注册
- 测试:BusinessNumberTest 期望值改 22 字符、越界用例改 10^8、补纯数字与 P999
余量断言;流水契约测试并入索引断言、归档移除的反向断言、号码重试与形态断言
按用户要求不写双路逻辑与数据迁移。新索引依赖 dbDelta 在下次迁移时补到既有表;
若此前已跑过迁移,两张归档空表需手工 DROP(未写迁移,故不自动处理)。
验证:PHPUnit 44 项 / 106 断言全部通过;node --test(已追踪用例)333 项 /
333 通过,含本地专用用例共 370 项全部通过;php -l 全部改动的 PHP 文件通过;
残留引用扫描确认 FinancialFlowRetention、两张归档表名、has_financial_records、
count_closed_orders_with_records、financial_records_exists_sql、两条 blocked
提示、$force 与 $include_orders_with_records 均已无残留。
2026-09-18 23:17:36 +08:00
..
2026-09-16 14:12:40 +08:00
2026-09-18 12:25:18 +08:00
2026-09-03 12:44:31 +08:00
2026-09-18 12:31:38 +08:00
2026-09-06 12:59:44 +08:00
2026-09-02 13:03:24 +08:00
2026-09-03 13:59:07 +08:00
2026-09-02 13:03:24 +08:00
2026-09-18 18:38:07 +08:00
2026-08-29 15:50:04 +08:00
2026-08-30 20:38:25 +08:00
2026-09-04 19:52:56 +08:00
2026-09-03 12:44:31 +08:00
2026-09-13 20:02:56 +08:00
2026-09-18 23:17:36 +08:00
2026-09-04 22:53:33 +08:00
2026-09-05 23:41:12 +08:00
2026-09-05 17:32:18 +08:00
2026-09-18 20:05:14 +08:00
2026-09-06 16:38:42 +08:00
2026-09-05 22:28:19 +08:00
2026-08-25 18:42:23 +08:00
2026-08-25 18:22:30 +08:00
2026-08-25 18:11:26 +08:00
2026-08-25 18:34:17 +08:00
2026-09-03 12:44:31 +08:00
2026-09-02 13:03:24 +08:00
2026-09-18 17:34:00 +08:00
2026-09-16 17:24:22 +08:00
2026-09-18 22:14:27 +08:00
2026-08-25 06:58:09 +08:00
2026-09-18 19:01:19 +08:00
2026-09-05 21:50:40 +08:00
2026-09-16 17:24:22 +08:00
2026-09-04 22:53:33 +08:00
2026-09-06 11:26:21 +08:00
2026-09-18 20:05:05 +08:00
2026-09-17 19:04:47 +08:00
2026-08-23 22:09:12 +08:00
2026-09-03 21:33:30 +08:00
2026-09-03 21:33:30 +08:00
2026-08-25 06:41:57 +08:00
2026-09-14 12:53:20 +08:00
2026-09-18 23:17:05 +08:00
2026-09-06 12:59:44 +08:00