fix: 增强充值队列与日结全链路幂等防重机制,彻底杜绝重复发放与脏写
这个提交包含在:
@@ -140,6 +140,48 @@ test('BaseJob 失败回调显式记录错误日志', () => {
|
||||
assert(baseJobContent.includes("Log::record('[QUEUE FAILED JOB]"), 'failed 回调必须记录 Log::record');
|
||||
});
|
||||
|
||||
// 8. 充值交易队列幂等防重复加余额 (addons/shopro/job/trade/OrderPaid.php)
|
||||
const tradeOrderPaidPath = path.join(rootDir, 'addons/shopro/job/trade/OrderPaid.php');
|
||||
assert(fs.existsSync(tradeOrderPaidPath), 'trade/OrderPaid.php 必须存在');
|
||||
const tradeOrderPaidContent = fs.readFileSync(tradeOrderPaidPath, 'utf8');
|
||||
|
||||
test('trade/OrderPaid 针对充值订单使用 lock(true) 排他锁', () => {
|
||||
assert(tradeOrderPaidContent.includes('->lock(true)->find()'), '必须对充值订单行加排他行锁');
|
||||
});
|
||||
|
||||
test('trade/OrderPaid 充值入账增加 recharge_processed 幂等防重复充值', () => {
|
||||
assert(tradeOrderPaidContent.includes("empty($ext['recharge_processed'])"), '必须判断 recharge_processed 标记');
|
||||
assert(tradeOrderPaidContent.includes("$ext['recharge_processed'] = time();"), '必须标记 recharge_processed 时间戳');
|
||||
assert(tradeOrderPaidContent.includes('STATUS_COMPLETED'), '充值完成必须置为 completed 状态');
|
||||
});
|
||||
|
||||
test('trade/OrderPaid 包含 handleFailure 阶梯延迟重试与上限告警机制', () => {
|
||||
assert(tradeOrderPaidContent.includes('function handleFailure('), '充值队列必须包含 handleFailure');
|
||||
assert(tradeOrderPaidContent.includes('[TradeOrderPaid CRITICAL]'), '达到上限必须记录严重系统告警');
|
||||
assert(tradeOrderPaidContent.includes('$delay = min(60, $attempts * 5);'), '必须使用阶梯延迟重试');
|
||||
});
|
||||
|
||||
// 9. 日结全链路幂等防重复发放保障
|
||||
const dailySettleServicePath = path.join(rootDir, 'addons/shopro/service/partner/DailySettleService.php');
|
||||
assert(fs.existsSync(dailySettleServicePath), 'DailySettleService.php 必须存在');
|
||||
const dailySettleServiceContent = fs.readFileSync(dailySettleServicePath, 'utf8');
|
||||
|
||||
test('DailySettleService::cashShare 与 cashShareMinute 增加 isNew 幂等防重判断', () => {
|
||||
assert(dailySettleServiceContent.includes('$isNew = ($record && !empty($record->_isNewCreated))'), '日结入账必须判定 isNew');
|
||||
});
|
||||
|
||||
const madowServicePath = path.join(rootDir, 'addons/shopro/service/partner/MadowService.php');
|
||||
const madowServiceContent = fs.readFileSync(madowServicePath, 'utf8');
|
||||
test('MadowService::share 增加 settle_date 幂等前置检查杜绝重复发放madow', () => {
|
||||
assert(madowServiceContent.includes("'settle_date', $settleDate)"), '必须检查当前结算日期是否已分发madow');
|
||||
});
|
||||
|
||||
const voucherServicePath = path.join(rootDir, 'addons/shopro/service/partner/VoucherService.php');
|
||||
const voucherServiceContent = fs.readFileSync(voucherServicePath, 'utf8');
|
||||
test('VoucherService::releaseByDate 增加 settle_date 幂等前置检查杜绝重复释放额度', () => {
|
||||
assert(voucherServiceContent.includes("'settle_date', $settleDate)"), '必须检查当前结算日期是否已释放券');
|
||||
});
|
||||
|
||||
console.log('\n----------------------------------------------------------------');
|
||||
console.log(`测试执行结果: 通过 ${passCount} 项, 失败 0 项`);
|
||||
console.log('================================================================\n');
|
||||
|
||||
在新工单中引用
屏蔽一个用户