const fs = require('fs'); const path = require('path'); const assert = require('assert'); console.log('========================================================'); console.log(' dmepa 1 分钟增量结算与兑换券 1 分钟释放规范自动化测试'); console.log('========================================================\n'); let passCount = 0; function test(name, fn) { try { fn(); console.log(` [PASS] ${name}`); passCount++; } catch (err) { console.error(` [FAIL] ${name}: ${err.message}`); process.exit(1); } } // 1. VoucherService 验证 const voucherServicePath = path.resolve(__dirname, '../addons/shopro/service/partner/VoucherService.php'); assert(fs.existsSync(voucherServicePath), 'VoucherService.php 文件存在'); const voucherContent = fs.readFileSync(voucherServicePath, 'utf-8'); test('VoucherService 包含 releaseMinute() 分钟级释放方法', () => { assert(voucherContent.includes('function releaseMinute()'), '必须定义 releaseMinute()'); }); test('VoucherService 包含标准次日起算逻辑', () => { assert(voucherContent.includes("date('Y-m-d', strtotime('+1 day', $this->orderTime($order)))"), '起算日期下单次日生效起算'); }); test('VoucherService 分钟释放使用 NULL 结算日规避唯一索引冲突', () => { assert(voucherContent.includes("'settle_date' => null"), 'settle_date 必须设为 null 避开 uk_daily_user_type 限制'); assert(voucherContent.includes("$virtualOrderId = -(intval($plan->id) * 1000"), 'order_id 必须使用负数虚拟 ID 避开 uk_order_user_type 限制'); }); // 2. MadowService 验证 const madowServicePath = path.resolve(__dirname, '../addons/shopro/service/partner/MadowService.php'); assert(fs.existsSync(madowServicePath), 'MadowService.php 文件存在'); const madowContent = fs.readFileSync(madowServicePath, 'utf-8'); test('MadowService 包含 shareMinute() 分钟级dmepa分红方法', () => { assert(madowContent.includes('function shareMinute('), '必须定义 shareMinute()'); }); test('MadowService 分钟分红使用防重虚拟 order_id 与 NULL 结算日', () => { assert(madowContent.includes("'settle_date' => null"), 'settle_date 必须设为 null'); assert(madowContent.includes("$virtualOrderId = min(-100000,"), '必须保证递减全局虚拟 order_id'); }); // 3. DailySettleService 验证 const dailySettlePath = path.resolve(__dirname, '../addons/shopro/service/partner/DailySettleService.php'); assert(fs.existsSync(dailySettlePath), 'DailySettleService.php 文件存在'); const settleContent = fs.readFileSync(dailySettlePath, 'utf-8'); test('DailySettleService 包含 runMinute() 总调度入口', () => { assert(settleContent.includes('function runMinute()'), '必须定义 runMinute()'); }); test('DailySettleService runMinute 调度兑换券与dmepa结算', () => { assert(settleContent.includes('releaseMinute()'), '调用 releaseMinute() 释放兑换券'); assert(settleContent.includes('shareMinute('), '调用 shareMinute() 发放dmepa'); assert(settleContent.includes("'madow_settled'] = 1"), '订单必须打上 madow_settled 标记防止重复均分'); assert(settleContent.includes('partner_settle_minute.lock'), '包含独立互斥锁保障并发安全'); }); // 4. PartnerSettle.php 控制台命令验证 const partnerSettlePath = path.resolve(__dirname, '../addons/shopro/console/PartnerSettle.php'); assert(fs.existsSync(partnerSettlePath), 'PartnerSettle.php 文件存在'); const cmdContent = fs.readFileSync(partnerSettlePath, 'utf-8'); test('PartnerSettle 默认执行标准日结模式(结算昨天)', () => { assert(cmdContent.includes("partner daily settle start"), '默认执行标准日结'); assert(cmdContent.includes("run($date, $rerun)"), '默认调用 DailySettleService::run()'); }); test('PartnerSettle 支持 --minute 显式触发分钟调度', () => { assert(cmdContent.includes("$input->getOption('minute')"), '支持 -m/--minute 参数'); assert(cmdContent.includes("runMinute()"), '支持按需调用 runMinute()'); }); console.log('\n--------------------------------------------------------'); console.log(`测试执行结果: 通过 ${passCount} 项, 失败 0 项`); console.log('========================================================\n');