const { execSync } = require('child_process'); let passed = 0; let failed = 0; function assert(condition, testName, detail = '') { if (condition) { console.log(` [PASS] ${testName}`); passed++; } else { console.error(` [FAIL] ${testName} - ${detail}`); failed++; } } console.log("========================================================"); console.log(" 订单详情实际收益查询口径与零侵入分成逻辑自动化验证"); console.log("========================================================\n"); // 1. 本地代码与规则定义检查 console.log("一、代码实现与规则检查:"); const fs = require('fs'); const path = require('path'); const orderControllerPath = path.resolve(__dirname, '../../application/admin/controller/shopro/order/Order.php'); const orderContent = fs.readFileSync(orderControllerPath, 'utf-8'); assert(orderContent.includes("buildPartnerSplit"), 'Order.php 包含 buildPartnerSplit 方法'); assert(orderContent.includes("matchedBatches"), 'buildPartnerSplit 精准匹配订单实际结算批次'); assert(!orderContent.includes("DailySettleService::run"), 'buildPartnerSplit 纯查询,绝不调用日结执行服务'); assert(!orderContent.includes("Wallet::change"), 'buildPartnerSplit 纯查询,绝不调用钱包变动方法'); const detailHtmlPath = path.resolve(__dirname, '../../application/admin/view/shopro/order/order/detail.html'); const detailHtmlContent = fs.readFileSync(detailHtmlPath, 'utf-8'); assert(detailHtmlContent.includes("本单奖池贡献"), 'detail.html 标明本单奖池贡献'); assert(detailHtmlContent.includes("total_share_cash"), 'detail.html 支持展示均分奖池现金贡献'); // 2. 线上实际查询与数据闭环验证 console.log("\n二、线上订单21真实收益数据验证:"); try { const remoteCmd = `sshpass -p 'Bjsslxz1' ssh -o StrictHostKeyChecking=no root@118.184.172.94 "php -r ' define(\\\"APP_PATH\\\", \\\"/www/wwwroot/henglian.gynhc.com/application/\\\"); require \\\"/www/wwwroot/henglian.gynhc.com/thinkphp/base.php\\\"; \\\\think\\\\App::initCommon(); \\$orderModel = new \\\\app\\\\admin\\\\model\\\\shopro\\\\order\\\\Order(); \\$order = \\$orderModel->with([\\\"user\\\", \\\"items\\\"])->where(\\\"id\\\", 21)->find(); \\$refClass = new ReflectionClass(\\\\app\\\\admin\\\\controller\\\\shopro\\\\order\\\\Order::class); \\$ctrl = \\$refClass->newInstanceWithoutConstructor(); \\$refMethod = \\$refClass->getMethod(\\\"buildPartnerSplit\\\"); \\$refMethod->setAccessible(true); \\$split = \\$refMethod->invoke(\\$ctrl, \\$order); echo json_encode(\\$split, JSON_UNESCAPED_UNICODE); '"`; const rawOutput = execSync(remoteCmd, { encoding: 'utf-8' }); // 过滤 ssh warning 输出,提取 json const jsonStart = rawOutput.indexOf('{'); const jsonStr = rawOutput.substring(jsonStart); const split = JSON.parse(jsonStr); assert(split.has_data === true, '订单 21 返回 has_data 为 true'); assert(split.total_instant_cash === '100.00', `本单即时现金分成准确为 100.00 (实际: ${split.total_instant_cash})`); assert(split.total_share_cash === '150.00', `本单均分奖池现金贡献准确为 150.00 (实际: ${split.total_share_cash})`); assert(split.total_all_cash === '250.00', `本单现金总支出准确为 250.00 (实际: ${split.total_all_cash})`); assert(split.total_voucher === '4.50', `兑换券释放额度准确为 4.50 (实际: ${split.total_voucher})`); const items = split.items || []; assert(items.length >= 7, `分成明细项包含即时奖与均分奖共 ${items.length} 条`); // 验证酒道馆加权奖 const venueItem = items.find(i => i.reward_type === 'venue_share'); assert(venueItem !== undefined, '包含酒道馆加权奖项'); if (venueItem) { assert(venueItem.user_count === 3, `酒道馆加权奖参与人数为 3 (实际: ${venueItem.user_count})`); assert(venueItem.each_amount === '33.33', `本单酒道馆人均准确为 33.33 (实际: ${venueItem.each_amount})`); assert(venueItem.total_amount === '100.00', `本单酒道馆贡献奖池准确为 100.00 (实际: ${venueItem.total_amount})`); assert(venueItem.formula.includes('本单贡献 100 / 3 = 33.33'), `公式自洽包含本单贡献 (实际: ${venueItem.formula})`); } // 验证区县加权奖 const countyItem = items.find(i => i.reward_type === 'county_share'); assert(countyItem !== undefined, '包含区县加权奖项'); if (countyItem) { assert(countyItem.user_count === 1, `区县加权奖参与人数为 1 (实际: ${countyItem.user_count})`); assert(countyItem.each_amount === '50.00', `本单区县人均准确为 50.00 (实际: ${countyItem.each_amount})`); assert(countyItem.total_amount === '50.00', `本单区县贡献奖池准确为 50.00 (实际: ${countyItem.total_amount})`); assert(countyItem.formula.includes('本单贡献 50 / 1 = 50.00'), `公式自洽包含本单贡献 (实际: ${countyItem.formula})`); } // 验证dmepa贡献 const madowItem = items.find(i => i.reward_type === 'madow_share'); assert(madowItem !== undefined, '包含每日获得dmepa项'); if (madowItem) { assert(madowItem.user_count === 9, `dmepa参与人数为 9 (实际: ${madowItem.user_count})`); assert(madowItem.total_amount === '3.00', `本单GMV贡献准确为 3.00 (实际: ${madowItem.total_amount})`); assert(madowItem.formula.includes('本单GMV 3 / 9'), `公式自洽包含本单GMV贡献 (实际: ${madowItem.formula})`); } } catch (err) { assert(false, '线上真实数据测试', err.message); } // 3. 验证纯查询零副作用(数据库数据未受任何修改) console.log("\n三、纯查询零副作用验证:"); try { const remoteVerifyCmd = `sshpass -p 'Bjsslxz1' ssh -o StrictHostKeyChecking=no root@118.184.172.94 "mysql -uhenglianshutong -phenglianshutong henglianshutong -e ' SELECT COUNT(*) as cnt FROM hla_shopro_partner_reward WHERE order_id = 21; '"`; const verifyOutput = execSync(remoteVerifyCmd, { encoding: 'utf-8' }); assert(verifyOutput.includes('4'), '订单 21 奖励流水表条数未被多增或篡改,保持原4条不变'); } catch (err) { assert(false, '零副作用验证', err.message); } console.log("\n========================================================"); console.log(` 测试完成:通过 ${passed} 项,失败 ${failed} 项`); console.log("========================================================"); if (failed > 0) { process.exit(1); } else { process.exit(0); }