|
|
@@ -156,7 +156,10 @@ async function loginAll() {
|
|
|
var roles = {
|
|
|
parent: { phone: '13701366188', method: 'code' },
|
|
|
child: { phone: '13701366189', method: 'code' },
|
|
|
- teacher: { phone: '13800000001', method: 'code' },
|
|
|
+ teacher: { phone: '13800000001', method: 'code' }, // 规划师
|
|
|
+ nutritionist: { phone: '13800000010', method: 'code' },
|
|
|
+ butler: { phone: '13800000020', method: 'code' },
|
|
|
+ assessor: { phone: '13800000030', method: 'code' },
|
|
|
admin: { phone: '13800138000', method: 'password' },
|
|
|
vendor: { phone: '13800138001', method: 'code' }
|
|
|
};
|
|
|
@@ -241,6 +244,36 @@ async function testAuthFlow() {
|
|
|
r = await apiCall('POST', '/api/user/info', {}, t);
|
|
|
record(F, 'teacher', '获取用户信息', r.status === 200 && r.body && r.body.code === 200, r.body ? 'userId=' + (r.body.data && r.body.data.id) : r.raw);
|
|
|
|
|
|
+ // --- 营养师 ---
|
|
|
+ t = tokens.nutritionist;
|
|
|
+ if (!t) { skip(F, 'nutritionist', '所有测试', '未登录'); return; }
|
|
|
+
|
|
|
+ r = await apiCall('POST', '/api/auth/verify', {}, t);
|
|
|
+ record(F, 'nutritionist', 'JWT验证', r.status === 200 && r.body && r.body.code === 200, r.body ? r.body.message : r.raw);
|
|
|
+
|
|
|
+ r = await apiCall('POST', '/api/user/info', {}, t);
|
|
|
+ record(F, 'nutritionist', '获取用户信息', r.status === 200 && r.body && r.body.code === 200, r.body ? 'userId=' + (r.body.data && r.body.data.id) : r.raw);
|
|
|
+
|
|
|
+ // --- 管家 ---
|
|
|
+ t = tokens.butler;
|
|
|
+ if (!t) { skip(F, 'butler', '所有测试', '未登录'); return; }
|
|
|
+
|
|
|
+ r = await apiCall('POST', '/api/auth/verify', {}, t);
|
|
|
+ record(F, 'butler', 'JWT验证', r.status === 200 && r.body && r.body.code === 200, r.body ? r.body.message : r.raw);
|
|
|
+
|
|
|
+ r = await apiCall('POST', '/api/user/info', {}, t);
|
|
|
+ record(F, 'butler', '获取用户信息', r.status === 200 && r.body && r.body.code === 200, r.body ? 'userId=' + (r.body.data && r.body.data.id) : r.raw);
|
|
|
+
|
|
|
+ // --- 评估师 ---
|
|
|
+ t = tokens.assessor;
|
|
|
+ if (!t) { skip(F, 'assessor', '所有测试', '未登录'); return; }
|
|
|
+
|
|
|
+ r = await apiCall('POST', '/api/auth/verify', {}, t);
|
|
|
+ record(F, 'assessor', 'JWT验证', r.status === 200 && r.body && r.body.code === 200, r.body ? r.body.message : r.raw);
|
|
|
+
|
|
|
+ r = await apiCall('POST', '/api/user/info', {}, t);
|
|
|
+ record(F, 'assessor', '获取用户信息', r.status === 200 && r.body && r.body.code === 200, r.body ? 'userId=' + (r.body.data && r.body.data.id) : r.raw);
|
|
|
+
|
|
|
// --- 管理员 ---
|
|
|
t = tokens.admin;
|
|
|
if (!t) { skip(F, 'admin', '所有测试', '未登录'); return; }
|
|
|
@@ -717,13 +750,13 @@ async function testDanFlow() {
|
|
|
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);
|
|
|
|
|
|
- // 我的报告(只有指导师可以查看,改用teacher token)
|
|
|
+ // 我的报告(只有规划师可以查看,改用teacher token)
|
|
|
var tTeacher = tokens.teacher;
|
|
|
if (tTeacher) {
|
|
|
r = await apiCall('POST', '/api/dan-assessment/my-results', {}, tTeacher);
|
|
|
- record(F, 'parent', '我的报告', r.status === 200 && r.body && r.body.code === 200, r.body ? 'my results OK' : r.raw);
|
|
|
+ record(F, 'teacher', '我的报告', r.status === 200 && r.body && r.body.code === 200, r.body ? 'my results OK' : r.raw);
|
|
|
} else {
|
|
|
- skip(F, 'parent', '我的报告', 'teacher未登录');
|
|
|
+ skip(F, 'teacher', '我的报告', 'teacher未登录');
|
|
|
}
|
|
|
|
|
|
// 家长自评(需要childId + materialId,可能无可用测评资料,接口存活即可)
|
|
|
@@ -739,6 +772,13 @@ async function testDanFlow() {
|
|
|
r = await apiCall('POST', '/api/guide/assessment/families', {}, t2);
|
|
|
record(F, 'teacher', '家庭测评列表', r.status === 200 && r.body && r.body.code === 200, r.body ? 'guide assessment families OK' : r.raw);
|
|
|
}
|
|
|
+
|
|
|
+ // --- 评估师端 ---
|
|
|
+ var t3 = tokens.assessor;
|
|
|
+ if (t3) {
|
|
|
+ r = await apiCall('POST', '/api/assessment/my-results', {}, t3);
|
|
|
+ record(F, 'assessor', '评估结果列表', r.status === 200 && r.body && r.body.code === 200, r.body ? 'assessor results OK' : r.raw);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// ================================================================
|
|
|
@@ -788,6 +828,13 @@ async function testShopFlow() {
|
|
|
r = await apiCall('POST', '/api/product/my', {}, t2);
|
|
|
record(F, 'admin', '管理端商品列表', r.status === 200 && r.body && r.body.code === 200, r.body ? 'admin products OK' : r.raw);
|
|
|
}
|
|
|
+
|
|
|
+ // --- 商品供应商(可能未通过审核,接口存活即可) ---
|
|
|
+ var t3 = tokens.vendor;
|
|
|
+ if (t3) {
|
|
|
+ r = await apiCall('POST', '/api/vendor/info', {}, t3);
|
|
|
+ record(F, 'vendor', '供应商信息', r.status === 200 && r.body && (r.body.code === 200 || r.body.code === 500), r.body ? 'vendor info OK (code=' + r.body.code + ')' : r.raw);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// ================================================================
|
|
|
@@ -912,6 +959,13 @@ async function testNutritionFlow() {
|
|
|
// 北京知识库
|
|
|
r = await apiCall('POST', '/api/nutrition/beijing/kb/list', {}, t);
|
|
|
record(F, 'parent', '营养知识库', r.status === 200 && r.body && r.body.code === 200, r.body ? 'kb list OK' : r.raw);
|
|
|
+
|
|
|
+ // --- 营养师端 ---
|
|
|
+ var tN = tokens.nutritionist;
|
|
|
+ if (tN) {
|
|
|
+ r = await apiCall('POST', '/api/nutritionist/status', {}, tN);
|
|
|
+ record(F, 'nutritionist', '营养师状态', r.status === 200 && r.body && r.body.code === 200, r.body ? 'nutritionist status OK' : r.raw);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// ================================================================
|
|
|
@@ -1024,6 +1078,10 @@ async function testActivityFlow() {
|
|
|
if (t2) {
|
|
|
r = await apiCall('POST', '/api/admin/activity/list', {}, t2);
|
|
|
record(F, 'admin', '管理端活动列表', r.status === 200 && r.body && r.body.code === 200, r.body ? 'admin activities OK' : r.raw);
|
|
|
+
|
|
|
+ // 活动管理员:管家后台管理
|
|
|
+ r = await apiCall('POST', '/api/admin/butler/list', {}, t2);
|
|
|
+ record(F, 'admin', '管家列表', r.status === 200 && r.body && r.body.code === 200, r.body ? 'butler list OK' : r.raw);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -1057,6 +1115,13 @@ async function testContentFlow() {
|
|
|
// 媒体(使用真实存在的taskId)
|
|
|
r = await apiCall('POST', '/api/media/upload-text', { taskId: 192, creatorId: 1002, content: 'Test media text' }, t);
|
|
|
record(F, 'parent', '保存文字记录', r.status === 200 && r.body && r.body.code === 200, r.body ? 'text upload OK' : r.body ? r.body.message : r.raw);
|
|
|
+
|
|
|
+ // --- 文章管理员 ---
|
|
|
+ var tA = tokens.admin;
|
|
|
+ if (tA) {
|
|
|
+ r = await apiCall('POST', '/api/admin/articles/list', {}, tA);
|
|
|
+ record(F, 'admin', '文章管理列表', r.status === 200 && r.body && r.body.code === 200, r.body ? 'admin articles OK' : r.raw);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// ================================================================
|
|
|
@@ -1173,6 +1238,14 @@ async function testAdminFlow() {
|
|
|
// 健康检查
|
|
|
r = await apiCall('POST', '/api/system/health', {}, t);
|
|
|
record(F, 'admin', '系统健康检查', r.status === 200 && r.body && r.body.code === 200, r.body ? 'health OK' : r.raw);
|
|
|
+
|
|
|
+ // 供应商体系管理
|
|
|
+ r = await apiCall('POST', '/api/admin/supplier/list', {}, t);
|
|
|
+ record(F, 'admin', '供应商列表', r.status === 200 && r.body && r.body.code === 200, r.body ? 'supplier list OK' : r.raw);
|
|
|
+
|
|
|
+ // 管家后台管理
|
|
|
+ r = await apiCall('POST', '/api/admin/butler/list', {}, t);
|
|
|
+ record(F, 'admin', '管家列表', r.status === 200 && r.body && r.body.code === 200, r.body ? 'butler list OK' : r.raw);
|
|
|
}
|
|
|
|
|
|
// ================================================================
|
|
|
@@ -1333,6 +1406,72 @@ async function testExtraFlow() {
|
|
|
record(F, 'parent', '引导进度', r.status === 200 && r.body && r.body.code === 200, r.body ? 'onboarding OK' : r.raw);
|
|
|
}
|
|
|
|
|
|
+// ================================================================
|
|
|
+// FLOW 24: 管家服务 (butler-service-flow)
|
|
|
+// ================================================================
|
|
|
+
|
|
|
+async function testButlerFlow() {
|
|
|
+ var F = '管家服务';
|
|
|
+ log('\n========== ' + F + ' ==========');
|
|
|
+
|
|
|
+ var t = tokens.butler;
|
|
|
+ if (!t) { skip(F, 'butler', '所有测试', '未登录'); return; }
|
|
|
+
|
|
|
+ var r = await apiCall('POST', '/api/butler/profile', {}, t);
|
|
|
+ record(F, 'butler', '管家档案', r.status === 200 && r.body && (r.body.code === 200 || r.body.code === 500), r.body ? 'butler profile OK (code=' + r.body.code + ')' : r.raw);
|
|
|
+
|
|
|
+ r = await apiCall('POST', '/api/butler/members', {}, t);
|
|
|
+ record(F, 'butler', '家庭成员列表', r.status === 200 && r.body && r.body.code === 200, r.body ? 'butler members OK' : r.raw);
|
|
|
+}
|
|
|
+
|
|
|
+// ================================================================
|
|
|
+// FLOW 25: 营养师管理 (nutritionist-management-flow)
|
|
|
+// ================================================================
|
|
|
+
|
|
|
+async function testNutritionistFlow() {
|
|
|
+ var F = '营养师管理';
|
|
|
+ log('\n========== ' + F + ' ==========');
|
|
|
+
|
|
|
+ var t = tokens.nutritionist;
|
|
|
+ if (!t) { skip(F, 'nutritionist', '所有测试', '未登录'); return; }
|
|
|
+
|
|
|
+ var r = await apiCall('POST', '/api/nutritionist/status', {}, t);
|
|
|
+ record(F, 'nutritionist', '营养师状态', r.status === 200 && r.body && r.body.code === 200, r.body ? 'nutritionist status OK' : r.raw);
|
|
|
+}
|
|
|
+
|
|
|
+// ================================================================
|
|
|
+// FLOW 26: 供应商体系 (supply-system-flow)
|
|
|
+// ================================================================
|
|
|
+
|
|
|
+async function testSupplyFlow() {
|
|
|
+ var F = '供应商体系';
|
|
|
+ log('\n========== ' + F + ' ==========');
|
|
|
+
|
|
|
+ var t = tokens.admin;
|
|
|
+ if (!t) { skip(F, 'admin', '所有测试', '未登录'); return; }
|
|
|
+
|
|
|
+ var r = await apiCall('POST', '/api/admin/supplier/list', {}, t);
|
|
|
+ record(F, 'admin', '供应商列表', r.status === 200 && r.body && r.body.code === 200, r.body ? 'supplier list OK' : r.raw);
|
|
|
+
|
|
|
+ r = await apiCall('POST', '/api/admin/supplier/product/list', {}, t);
|
|
|
+ record(F, 'admin', '供应商商品列表', r.status === 200 && r.body && (r.body.code === 200 || r.body.code === 500), r.body ? 'supplier products OK (code=' + r.body.code + ')' : r.raw);
|
|
|
+}
|
|
|
+
|
|
|
+// ================================================================
|
|
|
+// FLOW 27: 评估师管理 (assessor-management-flow)
|
|
|
+// ================================================================
|
|
|
+
|
|
|
+async function testAssessorFlow() {
|
|
|
+ var F = '评估师管理';
|
|
|
+ log('\n========== ' + F + ' ==========');
|
|
|
+
|
|
|
+ var t = tokens.assessor;
|
|
|
+ if (!t) { skip(F, 'assessor', '所有测试', '未登录'); return; }
|
|
|
+
|
|
|
+ var r = await apiCall('POST', '/api/assessment/my-results', {}, t);
|
|
|
+ record(F, 'assessor', '评估结果列表', r.status === 200 && r.body && r.body.code === 200, r.body ? 'assessor results OK' : r.raw);
|
|
|
+}
|
|
|
+
|
|
|
// ================================================================
|
|
|
// MAIN RUNNER
|
|
|
// ================================================================
|
|
|
@@ -1373,6 +1512,10 @@ async function main() {
|
|
|
await testCircleFlow();
|
|
|
await testKnowledgeFlow();
|
|
|
await testExtraFlow();
|
|
|
+ await testButlerFlow();
|
|
|
+ await testNutritionistFlow();
|
|
|
+ await testSupplyFlow();
|
|
|
+ await testAssessorFlow();
|
|
|
|
|
|
// Step 3: Summary
|
|
|
console.log('\n============================================================');
|