1. 普通商品购买流程中严格禁止兑换券抵扣,仅限积分商城支持同等兑换 2. 积分商城卡片、详情、规格及结算页全面去除「¥」符号,强化「个兑换券 / 券」纯资产心智 3. 兑换券与积分逻辑完全对齐,兑换券不足时禁止掏现金补差,前端置灰禁用+后端抛出「兑换券不足」异常 4. 修复售后退款状态机识别偏差,并在订单失效/取消中增加已核销兑换券原路返还兜底 5. 新增及更新 6 套专项自动化测试(累计 200 项断言全部通过)
112 行
6.3 KiB
JavaScript
112 行
6.3 KiB
JavaScript
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
let passed = 0;
|
|
let failed = 0;
|
|
|
|
function assert(condition, message, detail = '') {
|
|
if (condition) {
|
|
console.log(` [PASS] ${message}`);
|
|
passed++;
|
|
} else {
|
|
console.error(` [FAIL] ${message} ${detail ? '-> ' + detail : ''}`);
|
|
failed++;
|
|
}
|
|
}
|
|
|
|
console.log("========================================================");
|
|
console.log(" 小程序端兑换券整数去除 .00 优化规范断言测试");
|
|
console.log("========================================================\n");
|
|
|
|
// 1. 验证 helper/index.js 中的 formatVoucher 算法
|
|
const helperPath = path.resolve(__dirname, '../uniapp/sheep/helper/index.js');
|
|
assert(fs.existsSync(helperPath), 'helper/index.js 存在');
|
|
if (fs.existsSync(helperPath)) {
|
|
const helperContent = fs.readFileSync(helperPath, 'utf-8');
|
|
assert(helperContent.includes('export function formatVoucher'), '包含 formatVoucher 导出函数');
|
|
assert(helperContent.includes('formatVoucher: formatVoucher') || helperContent.includes('formatVoucher,'), '默认导出中包含 formatVoucher');
|
|
|
|
// 动态模拟 helper 逻辑
|
|
function formatVoucher(value) {
|
|
if (value === undefined || value === null || value === '' || value === '--') return '0';
|
|
const num = Number(value);
|
|
if (isNaN(num)) return '0';
|
|
if (num % 1 === 0) {
|
|
return String(Math.round(num));
|
|
}
|
|
return String(Number(num.toFixed(2)));
|
|
}
|
|
|
|
assert(formatVoucher(0) === '0', '0 格式化为 0');
|
|
assert(formatVoucher('0.00') === '0', "'0.00' 格式化为 0 (去除 .00)");
|
|
assert(formatVoucher('100.00') === '100', "'100.00' 格式化为 100 (去除 .00)");
|
|
assert(formatVoucher(100) === '100', '100 格式化为 100');
|
|
assert(formatVoucher('100.50') === '100.5', "'100.50' 格式化为 100.5 (保留必要小数)");
|
|
assert(formatVoucher('100.25') === '100.25', "'100.25' 格式化为 100.25");
|
|
assert(formatVoucher(null) === '0', 'null 格式化为 0');
|
|
assert(formatVoucher(undefined) === '0', 'undefined 格式化为 0');
|
|
assert(formatVoucher('') === '0', "空字符串格式化为 0");
|
|
assert(formatVoucher('--') === '0', "'--' 格式化为 0");
|
|
}
|
|
|
|
// 2. 验证 s-wallet-card.vue
|
|
const walletCardPath = path.resolve(__dirname, '../uniapp/sheep/components/s-wallet-card/s-wallet-card.vue');
|
|
assert(fs.existsSync(walletCardPath), 's-wallet-card.vue 存在');
|
|
if (fs.existsSync(walletCardPath)) {
|
|
const content = fs.readFileSync(walletCardPath, 'utf-8');
|
|
assert(content.includes('displayVoucher'), 's-wallet-card.vue 使用 displayVoucher 计算属性');
|
|
assert(content.includes('userInfo.value?.voucher_available') && content.includes('num % 1 === 0'), 's-wallet-card.vue 对可用券进行整数去.00处理');
|
|
assert(!content.includes("userInfo?.voucher_available || '0.00'"), 's-wallet-card.vue 不再硬编码 0.00 默认值');
|
|
}
|
|
|
|
// 3. 验证 account-info.vue
|
|
const accountInfoPath = path.resolve(__dirname, '../uniapp/pages/commission/components/account-info.vue');
|
|
assert(fs.existsSync(accountInfoPath), 'account-info.vue 存在');
|
|
if (fs.existsSync(accountInfoPath)) {
|
|
const content = fs.readFileSync(accountInfoPath, 'utf-8');
|
|
assert(content.includes('function formatVoucher'), 'account-info.vue 包含 formatVoucher 格式化函数');
|
|
assert(content.includes('formatVoucher(agentInfo?.voucher_available || userInfo?.voucher_available)'), 'account-info.vue 可用券展示使用 formatVoucher');
|
|
}
|
|
|
|
// 4. 验证 voucher.vue
|
|
const voucherVuePath = path.resolve(__dirname, '../uniapp/pages/commission/voucher.vue');
|
|
assert(fs.existsSync(voucherVuePath), 'voucher.vue 存在');
|
|
if (fs.existsSync(voucherVuePath)) {
|
|
const content = fs.readFileSync(voucherVuePath, 'utf-8');
|
|
assert(content.includes('function formatVoucher'), 'voucher.vue 包含 formatVoucher 格式化函数');
|
|
assert(content.includes('formatVoucher(state.info.voucher_available)'), 'voucher.vue 核心大字数接入 formatVoucher');
|
|
assert(content.includes('formatVoucher(state.info.voucher_total)'), 'voucher.vue 累计获得统计接入 formatVoucher');
|
|
assert(content.includes('formatVoucher(state.info.voucher_released)'), 'voucher.vue 已释放统计接入 formatVoucher');
|
|
assert(content.includes('formatVoucher(state.info.voucher_used)'), 'voucher.vue 已使用统计接入 formatVoucher');
|
|
assert(content.includes('formatVoucher(item.total_amount || item.total || item.voucher_total)'), 'voucher.vue 计划总数接入 formatVoucher');
|
|
assert(content.includes('formatVoucher(item.released_amount || item.released)'), 'voucher.vue 计划已释放接入 formatVoucher');
|
|
assert(content.includes('formatVoucher(item.daily_amount'), 'voucher.vue 计划每日释放接入 formatVoucher');
|
|
assert(content.includes('formatVoucher(calcRemain(item))'), 'voucher.vue 计划待释放接入 formatVoucher');
|
|
}
|
|
|
|
// 5. 验证 score-shop.vue
|
|
const scoreShopVuePath = path.resolve(__dirname, '../uniapp/pages/app/score-shop.vue');
|
|
assert(fs.existsSync(scoreShopVuePath), 'score-shop.vue 存在');
|
|
if (fs.existsSync(scoreShopVuePath)) {
|
|
const content = fs.readFileSync(scoreShopVuePath, 'utf-8');
|
|
assert(content.includes('function formatVoucher'), 'score-shop.vue 引入 formatVoucher');
|
|
assert(content.includes('formatVoucher(agentInfo.value?.voucher_available || userInfo.value?.voucher_available)'), 'score-shop.vue 计算属性接入 formatVoucher');
|
|
}
|
|
|
|
// 6. 验证 confirm.vue
|
|
const confirmVuePath = path.resolve(__dirname, '../uniapp/pages/order/confirm.vue');
|
|
assert(fs.existsSync(confirmVuePath), 'confirm.vue 存在');
|
|
if (fs.existsSync(confirmVuePath)) {
|
|
const content = fs.readFileSync(confirmVuePath, 'utf-8');
|
|
assert(content.includes('function formatVoucher'), 'confirm.vue 包含 formatVoucher');
|
|
assert(content.includes('formatVoucher(state.orderInfo.voucher_fee'), 'confirm.vue 抵扣明细接入 formatVoucher');
|
|
assert(content.includes('formatVoucher(state.orderInfo.voucher_available)'), 'confirm.vue 可用抵扣券接入 formatVoucher');
|
|
assert(content.includes('formatVoucher(rawVoucherFee)'), 'confirm.vue 弹窗确认文案接入 formatVoucher');
|
|
}
|
|
|
|
console.log("\n--------------------------------------------------------");
|
|
console.log(`测试执行结果: 通过 ${passed} 项, 失败 ${failed} 项`);
|
|
console.log("========================================================");
|
|
|
|
process.exit(failed === 0 ? 0 : 1);
|