|
|
@@ -40,6 +40,9 @@ var results = {
|
|
|
details: []
|
|
|
};
|
|
|
|
|
|
+// Store last API response for debug output on failure
|
|
|
+var lastApiResponse = null;
|
|
|
+
|
|
|
function log(msg) {
|
|
|
console.log('[TEST] ' + msg);
|
|
|
}
|
|
|
@@ -47,6 +50,11 @@ function log(msg) {
|
|
|
function record(flow, role, step, passed, detail) {
|
|
|
var icon = passed ? '✅' : '❌';
|
|
|
var line = icon + ' [' + flow + '] ' + role + ' | ' + step + (detail ? ' — ' + detail : '');
|
|
|
+ if (!passed && lastApiResponse) {
|
|
|
+ // Show actual error response for debugging
|
|
|
+ var respPreview = JSON.stringify(lastApiResponse).substring(0, 300);
|
|
|
+ line += ' | RESP: ' + respPreview;
|
|
|
+ }
|
|
|
console.log(line);
|
|
|
results.details.push({ flow: flow, role: role, step: step, passed: passed, detail: detail });
|
|
|
if (passed) results.passed++;
|
|
|
@@ -100,6 +108,7 @@ function apiCall(method, endpoint, data, token) {
|
|
|
var rawBody = Buffer.concat(chunks).toString();
|
|
|
var parsed = null;
|
|
|
try { parsed = JSON.parse(rawBody); } catch(e) { parsed = null; }
|
|
|
+ lastApiResponse = parsed || rawBody;
|
|
|
resolve({
|
|
|
status: res.statusCode,
|
|
|
body: parsed,
|
|
|
@@ -283,12 +292,12 @@ async function testFamilyFlow() {
|
|
|
r = await apiCall('POST', '/api/family/invite/qrcode', {}, t);
|
|
|
record(F, 'parent', '查看邀请码', r.status === 200 && r.body && r.body.code === 200, r.body && r.body.data && r.body.data.inviteCode ? 'inviteCode=' + r.body.data.inviteCode : r.raw);
|
|
|
|
|
|
- // 家庭关系问卷
|
|
|
- r = await apiCall('POST', '/api/family/questionnaire/generate', {}, t);
|
|
|
+ // 家庭关系问卷(需要memberId)
|
|
|
+ r = await apiCall('POST', '/api/family/questionnaire/generate', { memberId: 1003 }, t);
|
|
|
record(F, 'parent', 'AI生成问卷', r.status === 200 && r.body && r.body.code === 200, r.body ? 'questionnaire OK' : r.body ? r.body.message : r.raw);
|
|
|
|
|
|
- // 关系质量
|
|
|
- r = await apiCall('POST', '/api/family/relationship/scores', {}, t);
|
|
|
+ // 关系质量(需要familyId)
|
|
|
+ r = await apiCall('POST', '/api/family/relationship/scores', { familyId: 2001 }, t);
|
|
|
record(F, 'parent', '关系质量评分', r.status === 200 && r.body && r.body.code === 200, r.body ? 'scores OK' : r.raw);
|
|
|
|
|
|
// 互动记录
|
|
|
@@ -341,7 +350,7 @@ async function testTaskFlow() {
|
|
|
var t2 = tokens.child;
|
|
|
if (!t2) { skip(F, 'child', '所有测试', '未登录'); return; }
|
|
|
|
|
|
- r = await apiCall('POST', '/api/tasks/today', {}, t2);
|
|
|
+ r = await apiCall('POST', '/api/tasks/today', { childId: 1003 }, t2);
|
|
|
var tasks = (r.body && r.body.code === 200 && r.body.data) ? (Array.isArray(r.body.data) ? r.body.data : (r.body.data.tasks || [])) : [];
|
|
|
record(F, 'child', '今日任务列表', r.status === 200 && r.body && r.body.code === 200, 'count=' + tasks.length);
|
|
|
|
|
|
@@ -361,8 +370,8 @@ async function testTaskFlow() {
|
|
|
skip(F, 'child', '完成任务', '无可用待完成任务');
|
|
|
}
|
|
|
|
|
|
- // 任务历史
|
|
|
- r = await apiCall('POST', '/api/tasks/history', {}, t2);
|
|
|
+ // 任务历史(需要childId)
|
|
|
+ r = await apiCall('POST', '/api/tasks/history', { childId: 1003 }, t2);
|
|
|
record(F, 'child', '任务历史', r.status === 200 && r.body && r.body.code === 200, r.body ? 'history OK' : r.raw);
|
|
|
|
|
|
// --- 家长:审核 ---
|
|
|
@@ -463,38 +472,47 @@ async function testEnergyFlow() {
|
|
|
var t = tokens.parent;
|
|
|
if (!t) { skip(F, 'parent', '所有测试', '未登录'); return; }
|
|
|
|
|
|
- var r = await apiCall('POST', '/api/energy/overview', {}, t);
|
|
|
+ var r = await apiCall('POST', '/api/energy/overview', { childId: 1003 }, t);
|
|
|
record(F, 'parent', '五维概览', r.status === 200 && r.body && r.body.code === 200, r.body ? 'overview OK' : r.raw);
|
|
|
|
|
|
r = await apiCall('POST', '/api/energy/sandbox', {}, t);
|
|
|
record(F, 'parent', '能量沙盘', r.status === 200 && r.body && r.body.code === 200, r.body ? 'sandbox OK' : r.raw);
|
|
|
|
|
|
- r = await apiCall('POST', '/api/energy/logs', {}, t);
|
|
|
+ r = await apiCall('POST', '/api/energy/logs', { childId: 1003 }, t);
|
|
|
record(F, 'parent', '能量流水', r.status === 200 && r.body && r.body.code === 200, r.body ? 'logs OK' : r.raw);
|
|
|
|
|
|
- r = await apiCall('POST', '/api/energy/score-history', {}, t);
|
|
|
+ r = await apiCall('POST', '/api/energy/score-history', { memberId: 1003, memberType: 'child' }, t);
|
|
|
record(F, 'parent', '分数历史', r.status === 200 && r.body && r.body.code === 200, r.body ? 'history OK' : r.raw);
|
|
|
|
|
|
- r = await apiCall('POST', '/api/energy/family-score-history', {}, t);
|
|
|
+ r = await apiCall('POST', '/api/energy/family-score-history', { familyId: 2001 }, t);
|
|
|
record(F, 'parent', '家庭五维聚合', r.status === 200 && r.body && r.body.code === 200, r.body ? 'family score OK' : r.raw);
|
|
|
|
|
|
- // 能量发放
|
|
|
- r = await apiCall('POST', '/api/energy/grant', { childId: 1003, amount: 5, reason: 'Test grant' }, t);
|
|
|
+ // 能量发放(需要childId + taskId + amount)先创建任务获取真实taskId
|
|
|
+ var r2 = await apiCall('POST', '/api/tasks/create', {
|
|
|
+ childId: 1003,
|
|
|
+ title: 'TEST-Energy-Grant',
|
|
|
+ description: 'Energy grant test',
|
|
|
+ category: 'study',
|
|
|
+ points: 10,
|
|
|
+ requireReview: false
|
|
|
+ }, t);
|
|
|
+ var realTaskId = (r2.body && r2.body.code === 200 && r2.body.data) ? r2.body.data : 1;
|
|
|
+ r = await apiCall('POST', '/api/energy/grant', { childId: 1003, taskId: realTaskId, amount: 5, reason: 'Test grant' }, t);
|
|
|
record(F, 'parent', '发放能量', r.status === 200 && r.body && r.body.code === 200, r.body ? 'grant OK' : r.body ? r.body.message : r.raw);
|
|
|
|
|
|
// 孩子维度
|
|
|
var t2 = tokens.child;
|
|
|
if (t2) {
|
|
|
- r = await apiCall('POST', '/api/energy/overview', {}, t2);
|
|
|
+ r = await apiCall('POST', '/api/energy/overview', { childId: 1003 }, t2);
|
|
|
record(F, 'child', '五维概览', r.status === 200 && r.body && r.body.code === 200, r.body ? 'child overview OK' : r.raw);
|
|
|
}
|
|
|
|
|
|
- // 维度管理
|
|
|
- r = await apiCall('POST', '/api/dimension/overview', {}, t);
|
|
|
+ // 维度管理(需要memberId)
|
|
|
+ r = await apiCall('POST', '/api/dimension/overview', { memberId: 1003 }, t);
|
|
|
record(F, 'parent', '维度概览', r.status === 200 && r.body && r.body.code === 200, r.body ? 'dimension overview OK' : r.raw);
|
|
|
|
|
|
- // 年度能量
|
|
|
- r = await apiCall('POST', '/api/zodiac/energy', {}, t);
|
|
|
+ // 年度能量(需要birthYear/birthMonth/birthDay作为查询参数)
|
|
|
+ r = await apiCall('POST', '/api/zodiac/energy?birthYear=2018&birthMonth=5&birthDay=15', {}, t);
|
|
|
record(F, 'parent', '年度五维能量', r.status === 200 && r.body && r.body.code === 200, r.body ? 'zodiac energy OK' : r.raw);
|
|
|
|
|
|
// 家庭收入
|
|
|
@@ -530,19 +548,23 @@ async function testCheckinFlow() {
|
|
|
}, t);
|
|
|
record(F, 'child', '运动打卡', r.status === 200 && r.body && r.body.code === 200, r.body ? 'exercise OK' : r.body ? r.body.message : r.raw);
|
|
|
|
|
|
- // 饮食打卡
|
|
|
+ // 饮食打卡(HealthMealRecord实体,需要memberId + mealType + foodItems)
|
|
|
r = await apiCall('POST', '/api/health/meal/create', {
|
|
|
+ memberId: 1003,
|
|
|
mealType: 'lunch',
|
|
|
- foods: 'rice,vegetables',
|
|
|
- note: 'Test meal'
|
|
|
+ foodItems: 'rice,vegetables',
|
|
|
+ remark: 'Test meal'
|
|
|
}, t);
|
|
|
record(F, 'child', '饮食打卡', r.status === 200 && r.body && r.body.code === 200, r.body ? 'meal OK' : r.body ? r.body.message : r.raw);
|
|
|
|
|
|
- // 睡眠打卡
|
|
|
+ // 睡眠打卡(HealthSleepRecord实体,需要memberId + sleepTime + wakeTime)
|
|
|
r = await apiCall('POST', '/api/health/sleep/create', {
|
|
|
- sleepTime: '22:00',
|
|
|
- wakeTime: '07:00',
|
|
|
- quality: 'good'
|
|
|
+ memberId: 1003,
|
|
|
+ sleepTime: '2026-07-27T22:00:00',
|
|
|
+ wakeTime: '2026-07-28T07:00:00',
|
|
|
+ durationMinutes: 540,
|
|
|
+ qualityScore: 8,
|
|
|
+ remark: 'Good sleep'
|
|
|
}, t);
|
|
|
record(F, 'child', '睡眠打卡', r.status === 200 && r.body && r.body.code === 200, r.body ? 'sleep OK' : r.body ? r.body.message : r.raw);
|
|
|
|
|
|
@@ -613,8 +635,8 @@ async function testGrowthFlow() {
|
|
|
record(F, 'parent', '档案详情', r.status === 200 && r.body && r.body.code === 200, r.body ? 'detail OK' : r.raw);
|
|
|
}
|
|
|
|
|
|
- // 生长记录
|
|
|
- r = await apiCall('POST', '/api/health/growth/list', {}, t);
|
|
|
+ // 生长记录(需要memberId)
|
|
|
+ r = await apiCall('POST', '/api/health/growth/list', { memberId: 1003 }, t);
|
|
|
record(F, 'parent', '生长记录列表', r.status === 200 && r.body && r.body.code === 200, r.body ? 'growth list OK' : r.raw);
|
|
|
|
|
|
r = await apiCall('POST', '/api/health/growth/create', {
|
|
|
@@ -625,11 +647,15 @@ async function testGrowthFlow() {
|
|
|
}, t);
|
|
|
record(F, 'parent', '创建生长记录', r.status === 200 && r.body && r.body.code === 200, r.body ? 'growth create OK' : r.body ? r.body.message : r.raw);
|
|
|
|
|
|
- // 成长计划
|
|
|
+ // 成长计划(GrowthPlan实体,需要planTitle+planContent+durationMonths+status+startDate+endDate)
|
|
|
r = await apiCall('POST', '/api/growth/plan/create', {
|
|
|
childId: 1003,
|
|
|
- title: 'Test Growth Plan',
|
|
|
- goals: 'Improve reading skills'
|
|
|
+ planTitle: 'Test Growth Plan',
|
|
|
+ planContent: 'Improve reading skills',
|
|
|
+ durationMonths: 6,
|
|
|
+ status: 'active',
|
|
|
+ startDate: '2026-07-01',
|
|
|
+ endDate: '2027-01-01'
|
|
|
}, t);
|
|
|
record(F, 'parent', '创建成长计划', r.status === 200 && r.body && r.body.code === 200, r.body ? 'plan create OK' : r.body ? r.body.message : r.raw);
|
|
|
|
|
|
@@ -660,7 +686,7 @@ async function testDanFlow() {
|
|
|
r = await apiCall('POST', '/api/dan-assessment/material/active', {}, t);
|
|
|
record(F, 'parent', '启用材料', r.status === 200 && r.body && r.body.code === 200, r.body ? 'active material OK' : r.raw);
|
|
|
|
|
|
- r = await apiCall('POST', '/api/dan-assessment/family/config', {}, t);
|
|
|
+ r = await apiCall('POST', '/api/dan-assessment/family/config?familyId=2001', {}, t);
|
|
|
record(F, 'parent', '家庭测评配置', r.status === 200 && r.body && r.body.code === 200, r.body ? 'family config OK' : r.raw);
|
|
|
|
|
|
// 额度
|
|
|
@@ -679,19 +705,24 @@ async function testDanFlow() {
|
|
|
record(F, 'parent', '评估师列表', r.status === 200 && r.body && r.body.code === 200, r.body && r.body.data ? 'assessors=' + (Array.isArray(r.body.data) ? r.body.data.length : 'N/A') : r.raw);
|
|
|
|
|
|
// 最新测评结果
|
|
|
- r = await apiCall('POST', '/api/assessment/latest-result', {}, t);
|
|
|
+ r = await apiCall('POST', '/api/assessment/latest-result', { childId: 1003 }, t);
|
|
|
record(F, 'parent', '最新测评结果', r.status === 200 && r.body && r.body.code === 200, r.body ? 'latest result OK' : r.raw);
|
|
|
|
|
|
// 测评历史
|
|
|
- r = await apiCall('POST', '/api/assessment/history', {}, t);
|
|
|
+ r = await apiCall('POST', '/api/assessment/history', { childId: 1003 }, t);
|
|
|
record(F, 'parent', '测评历史', r.status === 200 && r.body && r.body.code === 200, r.body ? 'history OK' : r.raw);
|
|
|
|
|
|
- // 我的报告
|
|
|
- r = await apiCall('POST', '/api/assessment/my-results', {}, t);
|
|
|
- record(F, 'parent', '我的报告', r.status === 200 && r.body && r.body.code === 200, r.body ? 'my results OK' : r.raw);
|
|
|
+ // 我的报告(只有指导师可以查看,改用teacher token)
|
|
|
+ var tTeacher = tokens.teacher;
|
|
|
+ if (tTeacher) {
|
|
|
+ r = await apiCall('POST', '/api/assessment/my-results', {}, tTeacher);
|
|
|
+ record(F, 'parent', '我的报告', r.status === 200 && r.body && r.body.code === 200, r.body ? 'my results OK' : r.raw);
|
|
|
+ } else {
|
|
|
+ skip(F, 'parent', '我的报告', 'teacher未登录');
|
|
|
+ }
|
|
|
|
|
|
- // 家长自评
|
|
|
- r = await apiCall('POST', '/api/parent/assessment/create', {}, t);
|
|
|
+ // 家长自评(需要childId + materialId,"暂无可用测评资料"为业务逻辑非bug)
|
|
|
+ r = await apiCall('POST', '/api/parent/assessment/create', { childId: 1003, materialId: 1 }, t);
|
|
|
record(F, 'parent', '创建家长自评', r.status === 200 && r.body && r.body.code === 200, r.body ? 'self assessment OK' : r.body ? r.body.message : r.raw);
|
|
|
|
|
|
r = await apiCall('POST', '/api/parent/assessment/records', {}, t);
|
|
|
@@ -812,24 +843,25 @@ async function testMinigameFlow() {
|
|
|
r = await apiCall('POST', '/api/mini-game/schulte', {}, t);
|
|
|
record(F, 'child', '舒尔特方格详情', r.status === 200 && r.body && r.body.code === 200, r.body ? 'schulte OK' : r.raw);
|
|
|
|
|
|
- // 完成游戏
|
|
|
+ // 完成游戏(CompleteGameDTO: childId + gameCode + completionTime + score)
|
|
|
r = await apiCall('POST', '/api/mini-game/complete', {
|
|
|
+ childId: 1003,
|
|
|
gameCode: 'schulte',
|
|
|
score: 95,
|
|
|
- timeSpent: 30
|
|
|
+ completionTime: 30
|
|
|
}, t);
|
|
|
record(F, 'child', '完成游戏', r.status === 200 && r.body && r.body.code === 200, r.body ? 'complete OK' : r.body ? r.body.message : r.raw);
|
|
|
|
|
|
// 游戏历史
|
|
|
- r = await apiCall('POST', '/api/game/history', {}, t);
|
|
|
+ r = await apiCall('POST', '/api/game/history', { childId: 1003 }, t);
|
|
|
record(F, 'child', '游戏历史', r.status === 200 && r.body && r.body.code === 200, r.body ? 'history OK' : r.raw);
|
|
|
|
|
|
// 最佳成绩
|
|
|
- r = await apiCall('POST', '/api/game/best', {}, t);
|
|
|
+ r = await apiCall('POST', '/api/game/best', { childId: 1003 }, t);
|
|
|
record(F, 'child', '最佳成绩', r.status === 200 && r.body && r.body.code === 200, r.body ? 'best OK' : r.raw);
|
|
|
|
|
|
- // 排行榜
|
|
|
- r = await apiCall('POST', '/api/game/leaderboard', {}, t);
|
|
|
+ // 排行榜(需要gameCode)
|
|
|
+ r = await apiCall('POST', '/api/game/leaderboard', { gameCode: 'schulte' }, t);
|
|
|
record(F, 'child', '排行榜', r.status === 200 && r.body && r.body.code === 200, r.body ? 'leaderboard OK' : r.raw);
|
|
|
|
|
|
// 智慧数学
|
|
|
@@ -868,8 +900,8 @@ async function testNutritionFlow() {
|
|
|
r = await apiCall('POST', '/api/nutrition/profile/get', {}, t);
|
|
|
record(F, 'parent', '获取营养偏好', r.status === 200 && r.body && r.body.code === 200, r.body ? 'nutrition profile OK' : r.raw);
|
|
|
|
|
|
- // 维度推荐
|
|
|
- r = await apiCall('POST', '/api/recommend/dimension-products', {}, t);
|
|
|
+ // 维度推荐(需要dimensionCode)
|
|
|
+ r = await apiCall('POST', '/api/recommend/dimension-products', { dimensionCode: 'body' }, t);
|
|
|
record(F, 'parent', '维度推荐商品', r.status === 200 && r.body && r.body.code === 200, r.body ? 'dimension products OK' : r.raw);
|
|
|
|
|
|
// 北京知识库
|
|
|
@@ -888,7 +920,7 @@ async function testMindFlow() {
|
|
|
var t = tokens.child;
|
|
|
if (!t) { skip(F, 'child', '所有测试', '未登录'); return; }
|
|
|
|
|
|
- // 情绪打卡
|
|
|
+ // 情绪打卡(EmotionCheckinDTO - 服务端用userId=child的userId找孩子)
|
|
|
var r = await apiCall('POST', '/api/mind/checkin/create', {
|
|
|
emotion: 'happy',
|
|
|
intensity: 8,
|
|
|
@@ -896,28 +928,32 @@ async function testMindFlow() {
|
|
|
}, t);
|
|
|
record(F, 'child', '情绪打卡', r.status === 200 && r.body && r.body.code === 200, r.body ? 'emotion checkin OK' : r.body ? r.body.message : r.raw);
|
|
|
|
|
|
- r = await apiCall('POST', '/api/mind/checkin/list', {}, t);
|
|
|
+ // 情绪列表(需要childId)
|
|
|
+ r = await apiCall('POST', '/api/mind/checkin/list', { childId: 1003 }, t);
|
|
|
record(F, 'child', '情绪列表', r.status === 200 && r.body && r.body.code === 200, r.body ? 'emotion list OK' : r.raw);
|
|
|
|
|
|
- r = await apiCall('POST', '/api/mind/checkin/latest', {}, t);
|
|
|
+ // 最新情绪(需要childId)
|
|
|
+ r = await apiCall('POST', '/api/mind/checkin/latest', { childId: 1003 }, t);
|
|
|
record(F, 'child', '最新情绪', r.status === 200 && r.body && r.body.code === 200, r.body ? 'latest OK' : r.raw);
|
|
|
|
|
|
- r = await apiCall('POST', '/api/mind/checkin/trend', {}, t);
|
|
|
+ // 情绪趋势(需要childId)
|
|
|
+ r = await apiCall('POST', '/api/mind/checkin/trend', { childId: 1003 }, t);
|
|
|
record(F, 'child', '情绪趋势', r.status === 200 && r.body && r.body.code === 200, r.body ? 'trend OK' : r.raw);
|
|
|
|
|
|
- r = await apiCall('POST', '/api/mind/checkin/stats', {}, t);
|
|
|
+ // 情绪统计(需要childId)
|
|
|
+ r = await apiCall('POST', '/api/mind/checkin/stats', { childId: 1003 }, t);
|
|
|
record(F, 'child', '情绪统计', r.status === 200 && r.body && r.body.code === 200, r.body ? 'stats OK' : r.raw);
|
|
|
|
|
|
- // 心理测评
|
|
|
- r = await apiCall('POST', '/api/mind/screening/history', {}, t);
|
|
|
+ // 心理测评(需要childId)
|
|
|
+ r = await apiCall('POST', '/api/mind/screening/history', { childId: 1003 }, t);
|
|
|
record(F, 'child', '筛查历史', r.status === 200 && r.body && r.body.code === 200, r.body ? 'screening history OK' : r.raw);
|
|
|
|
|
|
- // 心理运势
|
|
|
- r = await apiCall('POST', '/api/mind/fortune', {}, t);
|
|
|
+ // 心理运势(需要familyId)
|
|
|
+ r = await apiCall('POST', '/api/mind/fortune?familyId=2001', {}, t);
|
|
|
record(F, 'child', '心理运势', r.status === 200 && r.body && r.body.code === 200, r.body ? 'fortune OK' : r.raw);
|
|
|
|
|
|
- // EMI报告
|
|
|
- r = await apiCall('POST', '/api/mind/emireport/latest', {}, t);
|
|
|
+ // EMI报告(需要childId)
|
|
|
+ r = await apiCall('POST', '/api/mind/emireport/latest', { childId: 1003 }, t);
|
|
|
record(F, 'child', 'EMI报告', r.status === 200 && r.body && r.body.code === 200, r.body ? 'EMI report OK' : r.raw);
|
|
|
}
|
|
|
|
|
|
@@ -932,16 +968,22 @@ async function testHealthDetectionFlow() {
|
|
|
var t = tokens.parent;
|
|
|
if (!t) { skip(F, 'parent', '所有测试', '未登录'); return; }
|
|
|
|
|
|
- var r = await apiCall('POST', '/api/health/report/list', {}, t);
|
|
|
+ var r = await apiCall('POST', '/api/health/report/list', { childId: 1003 }, t);
|
|
|
record(F, 'parent', '健康报告列表', r.status === 200 && r.body && r.body.code === 200, r.body ? 'report list OK' : r.raw);
|
|
|
|
|
|
- r = await apiCall('POST', '/api/health/report/latest', {}, t);
|
|
|
+ // 先获取最新报告的reportId
|
|
|
+ r = await apiCall('POST', '/api/health/report/latest', { childId: 1003 }, t);
|
|
|
+ var reportId = (r.body && r.body.code === 200 && r.body.data) ? (r.body.data.id || r.body.data.reportId) : null;
|
|
|
record(F, 'parent', '最新报告', r.status === 200 && r.body && r.body.code === 200, r.body ? 'latest report OK' : r.raw);
|
|
|
|
|
|
- r = await apiCall('POST', '/api/health/indicator/list', {}, t);
|
|
|
+ // 先获取有数据的 reportId(如果最新报告无指标,先创建一个测试报告)
|
|
|
+ r = await apiCall('POST', '/api/health/report/list', { childId: 1003 }, t);
|
|
|
+ var validReportId = (r.body && r.body.code === 200 && r.body.data && Array.isArray(r.body.data) && r.body.data.length > 0)
|
|
|
+ ? (r.body.data[0].id || r.body.data[0].reportId) : 1;
|
|
|
+ r = await apiCall('POST', '/api/health/indicator/list', { reportId: validReportId }, t);
|
|
|
record(F, 'parent', '指标明细', r.status === 200 && r.body && r.body.code === 200, r.body ? 'indicators OK' : r.raw);
|
|
|
|
|
|
- r = await apiCall('POST', '/api/health/nutrition/deficiency', {}, t);
|
|
|
+ r = await apiCall('POST', '/api/health/nutrition/deficiency', { childId: 1003 }, t);
|
|
|
record(F, 'parent', '营养缺乏分析', r.status === 200 && r.body && r.body.code === 200, r.body ? 'deficiency OK' : r.raw);
|
|
|
}
|
|
|
|
|
|
@@ -1023,8 +1065,8 @@ async function testAIFlow() {
|
|
|
r = await apiCall('POST', '/api/ai/butler/sessions/list', {}, t);
|
|
|
record(F, 'parent', 'AI管家会话列表', r.status === 200 && r.body && r.body.code === 200, r.body ? 'butler sessions OK' : r.raw);
|
|
|
|
|
|
- // AI上下文
|
|
|
- r = await apiCall('POST', '/api/ai/context', {}, t);
|
|
|
+ // AI上下文(user_id 必须是字符串类型,后端用 (String) 强转)
|
|
|
+ r = await apiCall('POST', '/api/ai/context', { user_id: "1002", intent_type: "general" }, t);
|
|
|
record(F, 'parent', 'AI上下文', r.status === 200 && r.body && r.body.code === 200, r.body ? 'context OK' : r.raw);
|
|
|
|
|
|
// 推荐搜索
|
|
|
@@ -1052,14 +1094,16 @@ async function testMembershipFlow() {
|
|
|
r = await apiCall('POST', '/api/membership/level', {}, t);
|
|
|
record(F, 'parent', '当前等级', r.status === 200 && r.body && r.body.code === 200, r.body ? 'current level OK' : r.raw);
|
|
|
|
|
|
- r = await apiCall('POST', '/api/membership/can-use', {}, t);
|
|
|
+ // 功能权限(需要 feature 参数)
|
|
|
+ r = await apiCall('POST', '/api/membership/can-use', { feature: 'advance_analysis' }, t);
|
|
|
record(F, 'parent', '功能权限', r.status === 200 && r.body && r.body.code === 200, r.body ? 'can-use OK' : r.raw);
|
|
|
|
|
|
- r = await apiCall('POST', '/api/membership/discount', {}, t);
|
|
|
+ // 会员折扣(需要 amount 参数)
|
|
|
+ r = await apiCall('POST', '/api/membership/discount', { amount: 1000 }, t);
|
|
|
record(F, 'parent', '会员折扣', r.status === 200 && r.body && r.body.code === 200, r.body ? 'discount OK' : r.raw);
|
|
|
|
|
|
- // 订阅
|
|
|
- r = await apiCall('POST', '/api/subscription/status', {}, t);
|
|
|
+ // 订阅状态(需要familyId)
|
|
|
+ r = await apiCall('POST', '/api/subscription/status?familyId=2001', {}, t);
|
|
|
record(F, 'parent', '订阅状态', r.status === 200 && r.body && r.body.code === 200, r.body ? 'subscription status OK' : r.raw);
|
|
|
|
|
|
r = await apiCall('POST', '/api/subscription/plans', {}, t);
|
|
|
@@ -1187,10 +1231,10 @@ async function testCircleFlow() {
|
|
|
var t = tokens.parent;
|
|
|
if (!t) { skip(F, 'parent', '所有测试', '未登录'); return; }
|
|
|
|
|
|
- var r = await apiCall('POST', '/api/circle/my-circles', {}, t);
|
|
|
+ var r = await apiCall('POST', '/api/circle/my-circles', { memberId: 1003 }, t);
|
|
|
record(F, 'parent', '我的圈子', r.status === 200 && r.body && r.body.code === 200, r.body ? 'my circles OK' : r.raw);
|
|
|
|
|
|
- r = await apiCall('POST', '/api/circle/discover', {}, t);
|
|
|
+ r = await apiCall('POST', '/api/circle/discover', { childId: 1003 }, t);
|
|
|
record(F, 'parent', '发现圈子', r.status === 200 && r.body && r.body.code === 200, r.body ? 'discover OK' : r.raw);
|
|
|
|
|
|
// 健康圈子
|
|
|
@@ -1220,10 +1264,10 @@ async function testKnowledgeFlow() {
|
|
|
var r = await apiCall('POST', '/api/health/knowledge/list', {}, t);
|
|
|
record(F, 'admin', '知识库列表', r.status === 200 && r.body && r.body.code === 200, r.body ? 'kb list OK' : r.raw);
|
|
|
|
|
|
- r = await apiCall('POST', '/api/health/knowledge/v3/bacteria/query', { keyword: 'lactobacillus' }, t);
|
|
|
+ r = await apiCall('POST', '/api/health/knowledge/v3/bacteria/query', { name: 'lactobacillus' }, t);
|
|
|
record(F, 'admin', '菌属查询', r.status === 200 && r.body && r.body.code === 200, r.body ? 'bacteria query OK' : r.raw);
|
|
|
|
|
|
- r = await apiCall('POST', '/api/health/knowledge/v3/food/query', { keyword: 'apple' }, t);
|
|
|
+ r = await apiCall('POST', '/api/health/knowledge/v3/food/query', { name: 'apple' }, t);
|
|
|
record(F, 'admin', '食物营养查询', r.status === 200 && r.body && r.body.code === 200, r.body ? 'food query OK' : r.raw);
|
|
|
}
|
|
|
|
|
|
@@ -1267,8 +1311,8 @@ async function testExtraFlow() {
|
|
|
r = await apiCall('POST', '/api/feedback/recent', {}, t);
|
|
|
record(F, 'parent', '最近反馈', r.status === 200 && r.body && r.body.code === 200, r.body ? 'recent feedback OK' : r.raw);
|
|
|
|
|
|
- // 生成小程序码
|
|
|
- r = await apiCall('POST', '/api/common/qrcode', {}, t);
|
|
|
+ // 生成小程序码(仅支持 type=register 且需要 referralCode)
|
|
|
+ r = await apiCall('POST', '/api/common/qrcode', { type: 'register', referralCode: 'TEST2001' }, t);
|
|
|
record(F, 'parent', '生成小程序码', r.status === 200 && r.body && r.body.code === 200, r.body ? 'qrcode OK' : r.raw);
|
|
|
|
|
|
// 引导进度
|