ltx 647bc39d27 feat: 完成体质报告小程序入口与教练资源播放优化
教练端在学生报告页录入体质数据并生成报告,新增报告查看页;学员端从报告页查看最新评估结果、体测指标与运动建议。请求统一走现有 QA 后端并携带登录令牌。

教学资源改用后台音频管理器,支持进度拖动、曲目切换、时长探测及网络异常时下载恢复;修正跳绳和开合跳动作提示文案。

验证:相关 JS 语法、页面 JSON 解析和 git diff --cached --check 均通过。
2026-10-23 16:48:58 +08:00

79 lines
2.5 KiB
JavaScript

import { getTeacherPostureReport, getTraineePostureReport } from '../../../utils/serve/posture';
function displayValue(value) {
if (value === null || value === undefined || value === '') return '';
if (typeof value === 'number') return String(Math.round(value * 100) / 100);
if (typeof value === 'string') return value;
return '';
}
function buildView(report) {
const input = report.inputNormalized || {};
const result = report.result || {};
const prescription = result.prescription || {};
const mapping = prescription.mapping || {};
const messages = result.messages || {};
const metrics = (report.metrics || []).map(item => ({
key: item.key || item.name,
name: item.name || item.label || item.key,
value: displayValue(item.currentValue),
unit: item.unit || '',
})).filter(item => item.value !== '');
const messageList = Object.keys(messages).map(key => ({ key, text: displayValue(messages[key]) })).filter(item => item.text);
return {
studentName: input.studentName || '',
testDate: input.testDate || (report.generatedAt || '').slice(0, 10),
age: result.age === null || result.age === undefined ? '' : String(result.age),
bmi: displayValue(result.bmi),
metrics,
messageList,
prescriptionSummary: displayValue(prescription.summary),
actions: Array.isArray(mapping.actions) ? mapping.actions : [],
homeTask: displayValue(mapping.homeTask),
disclaimer: (report.rule || {}).disclaimer || '',
};
}
Page({
data: {
teacherMode: false,
studentNo: '',
loading: true,
empty: false,
error: '',
view: {},
},
onLoad(options) {
this.setData({
teacherMode: options.mode === 'teacher',
studentNo: decodeURIComponent(options.studentNo || ''),
});
this.loadReport();
},
async loadReport() {
this.setData({ loading: true, error: '', empty: false });
try {
const res = this.data.teacherMode
? await getTeacherPostureReport(this.data.studentNo)
: await getTraineePostureReport();
const report = res.data || res;
if (!report || !report.success || !report.result) throw new Error('报告内容不完整');
this.setData({ view: buildView(report), loading: false });
} catch (e) {
const message = e.message || '报告加载失败';
this.setData({
loading: false,
empty: message.includes('未找到') || message.includes('暂无'),
error: message,
});
}
},
async onPullDownRefresh() {
await this.loadReport();
wx.stopPullDownRefresh();
},
});