|
|
@@ -187,8 +187,10 @@
|
|
|
<div class="module-tabs" id="moduleTabs">
|
|
|
<div class="module-tab active" data-module="checkin">1.签到有礼</div>
|
|
|
<div class="module-tab" data-module="activity-invite">2.邀请有礼</div>
|
|
|
- <div class="module-tab" data-module="activity-checkin">3.签到送会员</div>
|
|
|
- <div class="module-tab" data-module="activity-lottery">4.比价抽奖</div>
|
|
|
+ <div class="module-tab" data-module="activity-lottery">3.比价抽奖</div>
|
|
|
+ <div class="module-tab" data-module="business-license">4.营业执照管理</div>
|
|
|
+ <div class="module-tab" data-module="activity-available">5.我可参加的活动</div>
|
|
|
+ <div class="module-tab" data-module="activity-rewards-tab">6.各种活动奖励</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 运营侧模块标签栏 -->
|
|
|
@@ -214,7 +216,7 @@ const SMS_CODE = () => document.getElementById('smsCode')?.value || '123456';
|
|
|
|
|
|
let stats = { pass: 0, fail: 0, pending: 0, total: 0 };
|
|
|
|
|
|
-const USER_MODULES = ['checkin', 'activity-invite', 'activity-checkin', 'activity-lottery'];
|
|
|
+const USER_MODULES = ['checkin', 'activity-invite', 'activity-lottery', 'business-license', 'activity-available', 'activity-rewards-tab'];
|
|
|
const ADMIN_MODULES = ['admin-checkin', 'admin-activity-invite', 'admin-activity-checkin', 'admin-activity-lottery'];
|
|
|
|
|
|
// ===================== 大整数安全JSON解析 =====================
|
|
|
@@ -431,8 +433,10 @@ function renderModule(module) {
|
|
|
switch (module) {
|
|
|
case 'checkin': html = renderCheckinModule(); break;
|
|
|
case 'activity-invite': html = renderActivityInviteModule(); break;
|
|
|
- case 'activity-checkin': html = renderActivityCheckinModule(); break;
|
|
|
case 'activity-lottery': html = renderActivityLotteryModule(); break;
|
|
|
+ case 'business-license': html = renderBusinessLicenseModule(); break;
|
|
|
+ case 'activity-available': html = renderActivityAvailableModule(); break;
|
|
|
+ case 'activity-rewards-tab': html = renderActivityRewardsModule(); break;
|
|
|
case 'admin-checkin': html = renderAdminCheckinModule(); break;
|
|
|
case 'admin-activity-invite': html = renderAdminActivityInviteModule(); break;
|
|
|
case 'admin-activity-checkin': html = renderAdminActivityCheckinModule(); break;
|
|
|
@@ -631,6 +635,26 @@ const FIELD_DESC = {
|
|
|
['data[].chanceId', 'Long', '抽奖机会ID'],
|
|
|
['data[].createTime', 'DateTime', '抽奖时间']
|
|
|
],
|
|
|
+ 'activityRewards': [
|
|
|
+ ['data.records[].id', 'Long', '记录ID'],
|
|
|
+ ['data.records[].userId', 'Long', '用户ID'],
|
|
|
+ ['data.records[].activityType', 'String', '活动类型:INVITE/CHECKIN/LOTTERY'],
|
|
|
+ ['data.records[].rewardName', 'String', '奖励名称'],
|
|
|
+ ['data.records[].rewardDays', 'Integer', '奖励会员天数'],
|
|
|
+ ['data.records[].rewardLevel', 'String', '奖励会员等级'],
|
|
|
+ ['data.records[].rewardType', 'String', '奖励类型:MEMBERSHIP/EMPTY'],
|
|
|
+ ['data.records[].createTime', 'DateTime', '中奖/奖励时间'],
|
|
|
+ ['data.records[].inviterId', 'Long', '邀请人ID(INVITE类型)'],
|
|
|
+ ['data.records[].inviteeId', 'Long', '被邀请人ID(INVITE类型)'],
|
|
|
+ ['data.records[].status', 'Integer', '状态:0正常/1已撤销(INVITE)'],
|
|
|
+ ['data.records[].checkinCount', 'Integer', '签到天数(CHECKIN类型)'],
|
|
|
+ ['data.records[].cycleDesc', 'String', '周期描述(CHECKIN类型)'],
|
|
|
+ ['data.records[].prizeName', 'String', '奖品名称(LOTTERY类型)'],
|
|
|
+ ['data.total', 'Long', '总记录数'],
|
|
|
+ ['data.current', 'Long', '当前页'],
|
|
|
+ ['data.size', 'Long', '每页条数'],
|
|
|
+ ['data.pages', 'Long', '总页数']
|
|
|
+ ],
|
|
|
'adminActivityInviteConfig': [
|
|
|
['data.id', 'Long', '配置ID(固定1)'],
|
|
|
['data.enabled', 'Integer', '是否启用:0-停用 1-启用'],
|
|
|
@@ -697,6 +721,26 @@ const FIELD_DESC = {
|
|
|
['data.size', 'Long', '每页条数'],
|
|
|
['data.pages', 'Long', '总页数']
|
|
|
],
|
|
|
+ 'adminActivityRewards': [
|
|
|
+ ['data.records[].id', 'Long', '记录ID'],
|
|
|
+ ['data.records[].userId', 'Long', '用户ID(邀请类型为邀请人ID)'],
|
|
|
+ ['data.records[].activityType', 'String', '活动类型:INVITE-邀请/CHECKIN-签到/LOTTERY-比价抽奖'],
|
|
|
+ ['data.records[].rewardName', 'String', '奖励名称'],
|
|
|
+ ['data.records[].rewardDays', 'Integer', '奖励会员天数'],
|
|
|
+ ['data.records[].rewardLevel', 'String', '奖励会员等级'],
|
|
|
+ ['data.records[].rewardType', 'String', '奖励类型:MEMBERSHIP/EMPTY'],
|
|
|
+ ['data.records[].createTime', 'DateTime', '中奖/奖励时间'],
|
|
|
+ ['data.records[].inviterId', 'Long', '邀请人ID(INVITE类型)'],
|
|
|
+ ['data.records[].inviteeId', 'Long', '被邀请人ID(INVITE类型)'],
|
|
|
+ ['data.records[].status', 'Integer', '状态:0-正常/1-已撤销(INVITE类型)'],
|
|
|
+ ['data.records[].checkinCount', 'Integer', '周期内签到天数(CHECKIN类型)'],
|
|
|
+ ['data.records[].cycleDesc', 'String', '周期描述(CHECKIN类型)'],
|
|
|
+ ['data.records[].prizeName', 'String', '奖品名称(LOTTERY类型)'],
|
|
|
+ ['data.total', 'Long', '总记录数'],
|
|
|
+ ['data.current', 'Long', '当前页'],
|
|
|
+ ['data.size', 'Long', '每页条数'],
|
|
|
+ ['data.pages', 'Long', '总页数']
|
|
|
+ ],
|
|
|
'businessLicenseInfo': [
|
|
|
['data.id', 'Long', '执照ID(null=未上传)'],
|
|
|
['data.userId', 'Long', '用户ID'],
|
|
|
@@ -827,7 +871,7 @@ function toNumberIfSafe(v) {
|
|
|
return num;
|
|
|
}
|
|
|
|
|
|
-// ==================== 用户端:签到模块 ====================
|
|
|
+// ==================== 用户端:签到有礼模块(含基础签到 + 周期签到送会员) ====================
|
|
|
function renderCheckinModule() {
|
|
|
return `
|
|
|
<div class="batch-buttons">
|
|
|
@@ -839,8 +883,11 @@ function renderCheckinModule() {
|
|
|
${testSection('checkin-calendar', '当月签到日历', 'GET', 'get', '/api/checkin/calendar?year=2026&month=7', '需认证', 'auth-required',
|
|
|
[{label:'年份(year,可选)', name:'year', placeholder:'2026', default:'2026'},
|
|
|
{label:'月份(month,可选)', name:'month', placeholder:'7', default:'7'}], true, 'checkinCalendar', '获取指定月份的签到日历,不传默认当月')}
|
|
|
- ${testSection('checkin-records', '我的签到记录', 'GET', 'get', '/api/checkin/records?limit=30', '需认证', 'auth-required',
|
|
|
- [{label:'条数(limit,可选)', name:'limit', placeholder:'30', default:'30'}], true, null, '获取当前用户的签到历史记录,按签到日期倒序')}`;
|
|
|
+ ${testSection('checkin-records', '我的签到记录(分页)', 'GET', 'get', '/api/checkin/records?page=1&size=20', '需认证', 'auth-required',
|
|
|
+ [{label:'页码(page)', name:'page', placeholder:'1', default:'1'},
|
|
|
+ {label:'每页(size)', name:'size', placeholder:'20', default:'20'}], true, null, '获取当前用户的签到记录,分页返回,按签到日期倒序')}
|
|
|
+ ${testSection('activity-checkin-status', '周期签到进度', 'GET', 'get', '/api/activity/checkin-cycle/status', '需认证', 'auth-required', null, true, 'activityCheckinStatus', '查询当前周期签到进度:周期起止日、已签到天数、是否达标、累计/剩余可领取次数')}
|
|
|
+ ${testSection('activity-checkin-rewards', '周期奖励记录', 'GET', 'get', '/api/activity/checkin-cycle/rewards', '需认证', 'auth-required', null, true, 'activityCheckinCycleRewards', '获取签到周期达标奖励记录:每个周期的签到天数、是否已发放、发放时间')}`;
|
|
|
}
|
|
|
|
|
|
// ==================== 用户端:邀请有礼模块 ====================
|
|
|
@@ -853,16 +900,6 @@ function renderActivityInviteModule() {
|
|
|
${testSection('activity-invite-rewards', '我的邀请奖励记录', 'GET', 'get', '/api/invite/rewards', '需认证', 'auth-required', null, true, 'activityInviteRewards', '获取邀请奖励记录列表,包含被邀请人信息、注册状态、奖励月数')}`;
|
|
|
}
|
|
|
|
|
|
-// ==================== 用户端:签到送会员模块(旧版独立接口,周期信息已整合到签到状态接口) ====================
|
|
|
-function renderActivityCheckinModule() {
|
|
|
- return `
|
|
|
- <div class="batch-buttons">
|
|
|
- <button class="btn btn-warning btn-sm" onclick="runActivityCheckinTests()">运行全部签到送会员测试</button>
|
|
|
- </div>
|
|
|
- ${testSection('activity-checkin-status', '签到送会员周期状态(旧版)', 'GET', 'get', '/api/activity/checkin-cycle/status', '需认证', 'auth-required', null, true, 'activityCheckinStatus', '【旧版】查询当前周期签到进度。新版签到状态已整合周期信息到 /api/checkin/status')}
|
|
|
- ${testSection('activity-checkin-rewards', '我的签到周期奖励记录', 'GET', 'get', '/api/activity/checkin-cycle/rewards', '需认证', 'auth-required', null, true, 'activityCheckinCycleRewards', '获取签到周期达标奖励记录:每个周期的签到天数、是否已发放、发放时间')}`;
|
|
|
-}
|
|
|
-
|
|
|
// ==================== 用户端:比价抽奖模块 ====================
|
|
|
function renderActivityLotteryModule() {
|
|
|
return `
|
|
|
@@ -873,8 +910,16 @@ function renderActivityLotteryModule() {
|
|
|
${testSection('activity-lottery-status', '比价抽奖活动状态', 'GET', 'get', '/api/activity/lottery/status', '需认证', 'auth-required', null, true, 'activityLotteryStatus', '查询抽奖活动状态:是否开启、是否满足资格、今日可用机会')}
|
|
|
${testSection('activity-lottery-draw', '执行抽奖', 'POST', 'post', '/api/activity/lottery/draw', '需认证', 'auth-required', null, true, 'activityLotteryDraw', '消耗一次抽奖机会,随机抽取奖品(会员/爬虫次数/谢谢参与)')}
|
|
|
${testSection('activity-lottery-records', '我的抽奖记录', 'GET', 'get', '/api/activity/lottery/records?limit=20', '需认证', 'auth-required',
|
|
|
- [{label:'条数(limit,可选)', name:'limit', placeholder:'20', default:'20'}], true, 'activityLotteryRecords', '获取当前用户的抽奖历史记录,包含奖品名称、奖励类型、会员天数、是否中奖等完整中奖信息')}
|
|
|
- ${testSection('business-license-info', '我的营业执照信息', 'GET', 'get', '/api/business-license/info', '需认证', 'auth-required', null, true, 'businessLicenseInfo', '查询当前用户的营业执照提交状态和审核结果。审核通过后可在比价抽奖中获得额外抽奖机会')}
|
|
|
+ [{label:'条数(limit,可选)', name:'limit', placeholder:'20', default:'20'}], true, 'activityLotteryRecords', '获取当前用户的抽奖历史记录,包含奖品名称、奖励类型、会员天数、是否中奖等完整中奖信息')}`;
|
|
|
+}
|
|
|
+
|
|
|
+// ==================== 用户端:营业执照管理(公用模块) ====================
|
|
|
+function renderBusinessLicenseModule() {
|
|
|
+ return `
|
|
|
+ <div class="batch-buttons">
|
|
|
+ <button class="btn btn-warning btn-sm" onclick="runBusinessLicenseTests()">运行营业执照测试</button>
|
|
|
+ </div>
|
|
|
+ ${testSection('business-license-info', '我的营业执照信息', 'GET', 'get', '/api/business-license/info', '需认证', 'auth-required', null, true, 'businessLicenseInfo', '查询当前用户的营业执照提交状态和审核结果。审核通过后可在多种活动中获得权益:比价抽奖额外机会、邀请有礼资格认定等')}
|
|
|
${testSection('business-license-upload', '提交营业执照(JSON)', 'POST', 'post', '/api/business-license/upload', '需认证', 'auth-required',
|
|
|
[
|
|
|
{label:'执照图片URL(licenseImageUrl)', name:'licenseImageUrl', placeholder:'https://example.com/license.jpg', default:''},
|
|
|
@@ -884,6 +929,29 @@ function renderActivityLotteryModule() {
|
|
|
], true, 'businessLicenseInfo', '上传营业执照参与资质审核。审核通过后可获认证标识、解锁邀请有礼奖励、获取比价抽奖资格')}`;
|
|
|
}
|
|
|
|
|
|
+// ==================== 用户端:我可参加的活动(统一摘要) ====================
|
|
|
+function renderActivityAvailableModule() {
|
|
|
+ return `
|
|
|
+ <div class="batch-buttons">
|
|
|
+ <button class="btn btn-warning btn-sm" onclick="runActivityAvailableTests()">运行活动摘要测试</button>
|
|
|
+ </div>
|
|
|
+ ${testSection('activity-available', '我可参加的活动列表', 'GET', 'get', '/api/activity/available', '需认证', 'auth-required', null, true, 'activityAvailable', '一次性获取三种活动(邀请有礼、签到有礼、比价抽奖)的当前状态摘要:是否启用、时间窗内、奖励统计、签到进度、抽奖资格')}`;
|
|
|
+}
|
|
|
+
|
|
|
+// ==================== 用户端:各种活动奖励(统一查询) ====================
|
|
|
+function renderActivityRewardsModule() {
|
|
|
+ return `
|
|
|
+ <div class="batch-buttons">
|
|
|
+ <button class="btn btn-warning btn-sm" onclick="runActivityRewardsTabTests()">运行奖励查询测试</button>
|
|
|
+ </div>
|
|
|
+ ${testSection('activity-rewards', '我的中奖/奖励记录(三种活动按类型分页)', 'GET', 'get', '/api/activity/rewards?type=LOTTERY&page=1&size=20', '需认证', 'auth-required',
|
|
|
+ [
|
|
|
+ {label:'活动类型(type)', name:'type', placeholder:'INVITE/CHECKIN/LOTTERY', default:'LOTTERY'},
|
|
|
+ {label:'页码(page)', name:'page', placeholder:'1', default:'1'},
|
|
|
+ {label:'每页(size)', name:'size', placeholder:'20', default:'20'}
|
|
|
+ ], true, 'activityRewards', '按活动类型分页查询当前用户的三种活动中奖/奖励记录。type: INVITE-邀请有礼 / CHECKIN-签到有礼 / LOTTERY-比价抽奖')}`;
|
|
|
+}
|
|
|
+
|
|
|
// ==================== 运营端:签到管理模块 ====================
|
|
|
function renderAdminCheckinModule() {
|
|
|
return `
|
|
|
@@ -1037,7 +1105,14 @@ function renderAdminActivityLotteryModule() {
|
|
|
{label:'页码(page)', name:'page', placeholder:'1', default:'1'},
|
|
|
{label:'每页(size)', name:'size', placeholder:'20', default:'20'},
|
|
|
{label:'用户ID(userId,可选)', name:'userId', placeholder:'1', default:''}
|
|
|
- ], true, 'adminLotteryRecord', '分页查询所有用户的抽奖中奖记录,支持按用户ID筛选,按时间倒序')}`;
|
|
|
+ ], true, 'adminLotteryRecord', '分页查询所有用户的抽奖中奖记录,支持按用户ID筛选,按时间倒序')}
|
|
|
+ ${testSection('admin-activity-rewards', '统一中奖/奖励记录(三种活动)', 'GET', 'get', '/api/admin/activity/rewards?type=LOTTERY&page=1&size=20&userId=1', '需认证', 'auth-required',
|
|
|
+ [
|
|
|
+ {label:'活动类型(type)', name:'type', placeholder:'INVITE/CHECKIN/LOTTERY', default:'LOTTERY'},
|
|
|
+ {label:'页码(page)', name:'page', placeholder:'1', default:'1'},
|
|
|
+ {label:'每页(size)', name:'size', placeholder:'20', default:'20'},
|
|
|
+ {label:'用户ID(userId,可选)', name:'userId', placeholder:'1', default:''}
|
|
|
+ ], true, 'adminActivityRewards', '按活动类型统一查询三种活动的中奖/奖励记录。type: INVITE-邀请有礼 / CHECKIN-签到有礼 / LOTTERY-比价抽奖')}`;
|
|
|
}
|
|
|
|
|
|
// ===================== 批量测试 ====================
|
|
|
@@ -1140,8 +1215,10 @@ function clearAllResults() {
|
|
|
// 用户侧/运营侧快捷批量运行
|
|
|
function runCheckinTests() { runBatchTests('checkin'); }
|
|
|
function runActivityInviteTests() { runBatchTests('activity-invite'); }
|
|
|
-function runActivityCheckinTests() { runBatchTests('activity-checkin'); }
|
|
|
function runActivityLotteryTests() { runBatchTests('activity-lottery'); }
|
|
|
+function runBusinessLicenseTests() { runBatchTests('business-license'); }
|
|
|
+function runActivityAvailableTests() { runBatchTests('activity-available'); }
|
|
|
+function runActivityRewardsTabTests() { runBatchTests('activity-rewards'); }
|
|
|
function runAdminCheckinTests() { runBatchTests('admin-checkin'); }
|
|
|
function runAdminActivityInviteTests() { runBatchTests('admin-activity-invite'); }
|
|
|
function runAdminActivityCheckinTests() { runBatchTests('admin-activity-checkin'); }
|
|
|
@@ -1151,7 +1228,7 @@ function runAdminActivityLotteryTests() { runBatchTests('admin-activity-lottery'
|
|
|
function validate_checkinStatus(result) { return result.data?.code === 200 && result.data?.data?.checkedToday !== undefined; }
|
|
|
function validate_checkinDo(result) { return result.data?.code === 200 && result.data?.data?.id; }
|
|
|
function validate_checkinCalendar(result) { return result.data?.code === 200 && result.data?.data?.checkedDates !== undefined; }
|
|
|
-function validate_checkinRecords(result) { return result.data?.code === 200 && Array.isArray(result.data?.data); }
|
|
|
+function validate_checkinRecords(result) { return result.data?.code === 200 && result.data?.data?.records !== undefined; }
|
|
|
function validate_adminCheckinConfig(result) { return result.data?.code === 200 && result.data?.data?.id; }
|
|
|
function validate_adminCheckinConfigUpdate(result) { return result.data?.code === 200 && result.data?.data?.id; }
|
|
|
function validate_adminCheckinPeriods(result) { return result.data?.code === 200 && Array.isArray(result.data?.data); }
|
|
|
@@ -1169,6 +1246,8 @@ function validate_activityCheckinRewards(result) { return result.data?.code ===
|
|
|
function validate_activityLotteryStatus(result) { return result.data?.code === 200 && result.data?.data?.enabled !== undefined; }
|
|
|
function validate_activityLotteryPrizes(result) { return result.data?.code === 200 && Array.isArray(result.data?.data); }
|
|
|
function validate_activityLotteryRecords(result) { return result.data?.code === 200 && Array.isArray(result.data?.data); }
|
|
|
+function validate_activityRewards(result) { return result.data?.code === 200 && result.data?.data?.records !== undefined; }
|
|
|
+function validate_activityAvailable(result) { return result.data?.code === 200 && Array.isArray(result.data?.data?.activities); }
|
|
|
function validate_activityLotteryDraw(result) { return result.data?.code === 200 && result.data?.data?.prizeName !== undefined; }
|
|
|
function validate_adminActivityInviteConfig(result) { return result.data?.code === 200 && result.data?.data?.id; }
|
|
|
function validate_adminActivityInviteRevoke(result) { return result.data?.code === 200 && result.data?.data !== undefined; }
|
|
|
@@ -1180,6 +1259,7 @@ function validate_adminActivityLotteryPrizeUpdate(result) { return result.data?.
|
|
|
function validate_adminActivityLotteryPrizeDelete(result) { return result.data?.code === 200; }
|
|
|
|
|
|
function validate_adminActivityLotteryRecords(result) { return result.data?.code === 200 && result.data?.data?.records !== undefined; }
|
|
|
+function validate_adminActivityRewards(result) { return result.data?.code === 200 && result.data?.data?.records !== undefined; }
|
|
|
function validate_businessLicenseInfo(result) { return result.data?.code === 200 && result.data?.data !== undefined; }
|
|
|
function validate_businessLicenseUpload(result) { return result.data?.code === 200; }
|
|
|
|