128 行
6.5 KiB
JavaScript
128 行
6.5 KiB
JavaScript
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);
|
||
}
|