文件
Henglianshutong/tests/verify_team_center_full_spec.js

116 行
6.8 KiB
JavaScript

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

/**
* 团队作战中心全功能补齐与手机号脱敏专项验证测试
* 覆盖范围:
* 1. 服务端:Agent.php 手机号脱敏与收益业绩统计
* 2. 服务端:Index.php 收益明细 buyer_id 穿透过滤与 buyer_info
* 3. 移动端:team.vue 专属邀请码、团队收益看板、卡片脱敏、一键拨打/复制/查收益
* 4. 移动端:rewards.vue 穿透筛选提示、参数捕获与 API 传参
* 5. 移动端:index.vue 收益中心首页团队快捷入口看板
*/
const fs = require('fs');
const path = require('path');
let passCount = 0;
let failCount = 0;
function assert(condition, testName, detail = '') {
if (condition) {
console.log(` \x1b[32m[PASS]\x1b[0m ${testName}`);
passCount++;
} else {
console.error(` \x1b[31m[FAIL]\x1b[0m ${testName} - ${detail}`);
failCount++;
}
}
console.log('========================================================');
console.log(' 团队作战中心全功能闭环与手机号脱敏专项验证测试');
console.log('========================================================\n');
// 1. 服务端 Agent.php 校验
const agentPhpPath = path.resolve(__dirname, '../addons/shopro/controller/commission/Agent.php');
assert(fs.existsSync(agentPhpPath), 'Agent.php 控制器存在');
if (fs.existsSync(agentPhpPath)) {
const content = fs.readFileSync(agentPhpPath, 'utf-8');
assert(content.includes("use app\\admin\\model\\shopro\\partner\\Reward as RewardModel;"), 'Agent.php 引入了 RewardModel');
assert(content.includes('$user->mobile = $maskedMobile;'), 'Agent.php 覆写了 $user->mobile 为脱敏号码');
assert(content.includes('$user->mobile_hide = $maskedMobile;'), 'Agent.php 提供了 $user->mobile_hide 字段');
assert(content.includes('$user->mobile_raw = $rawMobile;'), 'Agent.php 保留了 $user->mobile_raw 供客户端外呼');
assert(content.includes('$user->parentUser->mobile = $pMasked;'), 'Agent.php 对所属间推推荐人手机号执行了脱敏');
assert(content.includes("'team_total_consume'"), 'getTeamHealthSummary 返回团队自购总业绩');
assert(content.includes("'team_total_reward'"), 'getTeamHealthSummary 返回团队贡献总收益');
assert(content.includes("'team_month_reward'"), 'getTeamHealthSummary 返回本月团队贡献收益');
assert(content.includes("'team_order_count'"), 'getTeamHealthSummary 返回团队总订单数');
}
// 2. 服务端 partner/Index.php 校验
const partnerIndexPhpPath = path.resolve(__dirname, '../addons/shopro/controller/partner/Index.php');
assert(fs.existsSync(partnerIndexPhpPath), 'partner/Index.php 控制器存在');
if (fs.existsSync(partnerIndexPhpPath)) {
const content = fs.readFileSync(partnerIndexPhpPath, 'utf-8');
assert(content.includes("intval($this->request->param('buyer_id', 0))"), 'rewards 接口接收 buyer_id 参数');
assert(content.includes("$query->where('buyer_id', $buyerId);"), 'rewards 接口支持按 buyer_id 过滤明细');
assert(content.includes("'buyer_info' => $buyerInfo"), 'rewards 接口返回穿透成员信息 buyer_info');
}
// 3. 移动端 team.vue 校验
const teamVuePath = path.resolve(__dirname, '../uniapp/pages/commission/team.vue');
assert(fs.existsSync(teamVuePath), 'team.vue 页面文件存在');
if (fs.existsSync(teamVuePath)) {
const content = fs.readFileSync(teamVuePath, 'utf-8');
// 专属邀请码
assert(content.includes('专属邀请码:'), 'team.vue 包含专属邀请码标签');
assert(content.includes('HL{{ userInfo.id ||'), 'team.vue 包含 HL + 用户ID 的邀请码渲染');
assert(content.includes('onCopyInviteCode'), 'team.vue 包含 onCopyInviteCode 复制方法');
assert(content.includes('onCopyShareLink'), 'team.vue 包含 onCopyShareLink 复制链接方法');
// 团队收益看板
assert(content.includes('team-wealth-box'), 'team.vue 包含 team-wealth-box 团队收益看板');
assert(content.includes('state.summary.team_total_reward'), 'team.vue 绑定团队贡献总收益');
assert(content.includes('state.summary.team_total_consume'), 'team.vue 绑定团队自购总业绩');
assert(content.includes('state.summary.team_month_reward'), 'team.vue 绑定本月贡献收益');
assert(content.includes('state.summary.team_order_count'), 'team.vue 绑定团队订单数');
// 手机号脱敏展示与操作
assert(content.includes('item.mobile_hide'), 'team.vue 列表卡片展示脱敏手机号');
assert(content.includes('state.currentMember.mobile_hide'), 'team.vue 抽屉详情展示脱敏手机号');
assert(content.includes('btn-reward'), 'team.vue 列表卡片提供直达收益流水按钮');
assert(content.includes('onJumpRewards(item.id, item.nickname)'), 'team.vue 卡片支持一键穿透查收益流水');
assert(content.includes('onJumpRewards(state.currentMember.id, state.currentMember.nickname)'), 'team.vue 抽屉支持一键穿透查收益流水');
}
// 4. 移动端 rewards.vue 校验
const rewardsVuePath = path.resolve(__dirname, '../uniapp/pages/commission/rewards.vue');
assert(fs.existsSync(rewardsVuePath), 'rewards.vue 页面文件存在');
if (fs.existsSync(rewardsVuePath)) {
const content = fs.readFileSync(rewardsVuePath, 'utf-8');
assert(content.includes('buyer-filter-bar'), 'rewards.vue 包含 buyer-filter-bar 穿透筛选提示条');
assert(content.includes('onClearBuyerFilter'), 'rewards.vue 包含 onClearBuyerFilter 清除筛选方法');
assert(content.includes('options?.buyer_id'), 'rewards.vue onLoad 中捕获 buyer_id 参数');
assert(content.includes('params.buyer_id = state.buyerId;'), 'rewards.vue 请求 API 时传递 buyer_id');
}
// 5. 移动端 index.vue 校验
const indexVuePath = path.resolve(__dirname, '../uniapp/pages/commission/index.vue');
assert(fs.existsSync(indexVuePath), 'index.vue 页面文件存在');
if (fs.existsSync(indexVuePath)) {
const content = fs.readFileSync(indexVuePath, 'utf-8');
assert(content.includes('team-quick-card'), 'index.vue 包含 team-quick-card 快捷看板');
assert(content.includes('团队作战中心'), 'index.vue 明确展示团队作战中心标题');
assert(content.includes('/pages/commission/team'), 'index.vue 点击直达 /pages/commission/team');
}
// 6. 算法测试:脱敏与邀请码逻辑
const testMobile = "13912345678";
const maskedMobile = testMobile.replace(/^(\d{3})\d{4}(\d{4})$/, '$1****$2');
assert(maskedMobile === "139****5678", `手机号脱敏算法验证正常: ${maskedMobile}`);
const testUserId = 2048;
const inviteCode = `HL${testUserId}`;
assert(inviteCode === "HL2048", `邀请码生成格式符合规范: ${inviteCode}`);
console.log('\n--------------------------------------------------------');
console.log(`测试结果统计: 通过 ${passCount} 项, 失败 ${failCount} 项`);
console.log('========================================================');
process.exit(failCount === 0 ? 0 : 1);