import { generatePostureReport } from '../../../utils/serve/posture'; const bodyFields = [ { key: 'heightCm', label: '身高', unit: 'cm' }, { key: 'weightKg', label: '体重', unit: 'kg' }, { key: 'waistCm', label: '腰围', unit: 'cm' }, { key: 'bodyFatPercent', label: '体脂率', unit: '%' }, { key: 'muscleMassKg', label: '肌肉量', unit: 'kg' }, ]; const testFields = [ { key: 'sprint50mSeconds', label: '50米跑', unit: '秒' }, { key: 'standingLongJumpCm', label: '立定跳远', unit: 'cm' }, { key: 'plankSeconds', label: '平板支撑', unit: '秒' }, { key: 'gripStrengthKg', label: '握力', unit: 'kg' }, { key: 'ropeSkipCount', label: '一分钟跳绳', unit: '个' }, { key: 'ropeSkip30SecCount', label: '30秒跳绳', unit: '个' }, { key: 'vitalCapacityMl', label: '肺活量', unit: 'ml' }, { key: 'restingHeartRateBpm', label: '静息心率', unit: '次/分' }, { key: 'stepTestHeartRateBpm', label: '台阶测试恢复心率', unit: '次/分' }, { key: 'obstacleRun15mSeconds', label: '15米绕障碍跑', unit: '秒' }, { key: 'quadrantJumpSeconds', label: '十字象限跳', unit: '秒' }, { key: 'reactionTimeSeconds', label: '选择反应时', unit: '秒' }, { key: 'balanceBeamSeconds', label: '走平衡木', unit: '秒' }, { key: 'singleLegStandSeconds', label: '闭眼单脚站立', unit: '秒' }, { key: 'sitReachCm', label: '坐位体前屈', unit: 'cm' }, ]; const allFields = bodyFields.concat(testFields); const today = () => { const date = new Date(); return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`; }; function normalizeSex(value) { const text = String(value || '').toLowerCase(); if (text === '1' || text === '男' || text === 'male') return 0; if (text === '2' || text === '女' || text === 'female') return 1; return -1; } Page({ data: { studentNo: '', studentName: '', className: '', birthDate: '', testDate: today(), sexIndex: -1, sexOptions: ['男', '女'], gradeIndex: -1, gradeOptions: ['一年级', '二年级', '三年级', '四年级', '五年级', '六年级', '七年级', '八年级', '九年级', '高一', '高二', '高三'], bodyFields, testFields, values: {}, submitting: false, }, onLoad(options) { const gradeId = Number(decodeURIComponent(options.gradeId || '')); this.setData({ studentNo: decodeURIComponent(options.studentNo || ''), studentName: decodeURIComponent(options.studentName || ''), className: decodeURIComponent(options.className || ''), sexIndex: normalizeSex(decodeURIComponent(options.sex || '')), gradeIndex: Number.isInteger(gradeId) && gradeId >= 1 && gradeId <= 12 ? gradeId - 1 : -1, }); }, onBirthDateChange(e) { this.setData({ birthDate: e.detail.value }); }, onTestDateChange(e) { this.setData({ testDate: e.detail.value }); }, onSexChange(e) { this.setData({ sexIndex: Number(e.detail.value) }); }, onGradeChange(e) { this.setData({ gradeIndex: Number(e.detail.value) }); }, onNumberInput(e) { const key = e.currentTarget.dataset.key; this.setData({ [`values.${key}`]: e.detail.value }); }, buildPayload() { const { studentNo, studentName, className, birthDate, testDate, sexIndex, gradeIndex, values } = this.data; if (!studentNo || !studentName || !birthDate || !testDate || sexIndex < 0 || gradeIndex < 0) { throw new Error('请补齐出生日期、测试日期、性别和年级'); } if (testDate < birthDate) throw new Error('测试日期不能早于出生日期'); const numbers = {}; allFields.forEach(field => { const raw = values[field.key]; if (raw === undefined || String(raw).trim() === '') return; const value = Number(raw); if (!Number.isFinite(value) || (field.key !== 'sitReachCm' && value <= 0)) { throw new Error(`请检查${field.label}的数值`); } numbers[field.key] = value; }); if (!numbers.heightCm || !numbers.weightKg) throw new Error('请填写身高和体重'); const tests = {}; testFields.forEach(field => { if (numbers[field.key] !== undefined) tests[field.key] = numbers[field.key]; }); return { assessmentType: 'student', studentName, studentId: studentNo, birthDate, testDate, sex: sexIndex === 0 ? 'male' : 'female', grade: String(gradeIndex + 1), className, heightCm: numbers.heightCm, weightKg: numbers.weightKg, ...(numbers.waistCm !== undefined ? { waistCm: numbers.waistCm } : {}), bodyComposition: { ...(numbers.bodyFatPercent !== undefined ? { bodyFatPercent: numbers.bodyFatPercent } : {}), ...(numbers.muscleMassKg !== undefined ? { muscleMassKg: numbers.muscleMassKg } : {}), }, tests, }; }, async submit() { if (this.data.submitting) return; let payload; try { payload = this.buildPayload(); } catch (e) { wx.showToast({ title: e.message, icon: 'none' }); return; } this.setData({ submitting: true }); wx.showLoading({ title: '生成报告中', mask: true }); try { const response = await generatePostureReport(this.data.studentNo, payload); if (!response.data || !response.data.success || !response.data.result) { throw new Error('评价服务未返回有效报告'); } wx.hideLoading(); wx.redirectTo({ url: '/subpackage/parent/posture-report/posture-report?mode=teacher&studentNo=' + encodeURIComponent(this.data.studentNo), }); } catch (e) { wx.hideLoading(); wx.showModal({ title: '生成失败', content: e.message || '请稍后重试', showCancel: false }); } finally { this.setData({ submitting: false }); } }, });