Files
SmartSeniorHMOS/entry/src/main/ets/pages/family/FamilyReportCard.ets
T
CAPTAIN1275 baf307e9d5 chore(hmos): 导入生产环境鸿蒙工程
- 以 D:\SmartSenior 生产工程为源,纳入 AppScope、entry、cjagent、hvigor 及根配置
- 移除 build-profile.json5 的 signingConfigs(p12/p7b/cer 路径与加密口令)及 products.signingConfig 引用
- 不纳入本地与开发产物:local.properties、.idea、.hvigor、.codegenie、demo、backup_a2a_native、SESSION_LOG.md、build_err.txt、build/、oh_modules
- .gitignore 追加 .codegenie 与密钥文件通配(*.p12/*.p7b/*.cer/*.jks/*.keystore/*.pem)
2026-09-29 18:44:37 +08:00

204 lines
7.5 KiB
Plaintext

// 家属 · 碰一碰分享接收页:渲染对方设备碰一碰传来的长者健康报告卡
// 数据来源:EntryAbility.reportData 解析 smartsenior://report?data=<JSON> 写入 AppStorage.pendingReportData
import { HealthReportData } from '../../utils/KnockShare';
import { FontScaleLevel, FONT_SCALE_MAP } from '../../utils/FontScale';
@Entry
@Component
struct FamilyReportCard {
@StorageProp('fontScale') fontScaleLevel: FontScaleLevel = 'system';
private scaleFor(): number {
return FONT_SCALE_MAP[this.fontScaleLevel] ?? 1.0;
}
@StorageProp('pendingReportData') reportStr: string = '';
@State report: HealthReportData | null = null;
@State parseFailed: boolean = false;
aboutToAppear(): void {
if (this.reportStr.length === 0) {
this.parseFailed = true;
return;
}
try {
const raw = JSON.parse(this.reportStr) as HealthReportData;
// 防御旧版发送端:报告字段可能整体缺失,统一补默认值避免 undefined 崩溃
this.report = {
name: raw.name ?? '',
gender: raw.gender ?? '',
age: raw.age ?? 0,
room: raw.room ?? '',
care_level: raw.care_level ?? '',
health_score: raw.health_score ?? null,
status: raw.status ?? '',
risks: raw.risks ?? [],
medical_history: raw.medical_history ?? '',
allergies: raw.allergies ?? '',
medications: raw.medications ?? [],
caregiver: raw.caregiver ?? '',
emergency_contact: raw.emergency_contact ?? '',
report_title: raw.report_title ?? '',
report_period: raw.report_period ?? '',
report_summary: raw.report_summary ?? '',
report_ai: raw.report_ai ?? '',
shared_at: raw.shared_at ?? '',
};
} catch (err) {
this.parseFailed = true;
}
}
@Builder
InfoRow(label: string, value: string) {
Row({ space: 12 }) {
Text(label)
.fontSize(Math.round(16 * this.scaleFor()))
.fontColor($r('app.color.text_secondary'))
.width(88)
Text(value.length > 0 ? value : '--')
.fontSize(Math.round(16 * this.scaleFor()))
.fontColor($r('app.color.text_primary'))
.layoutWeight(1)
}
.width('100%')
}
build() {
Scroll() {
Column({ space: 16 }) {
if (this.parseFailed) {
Text('未收到健康报告数据')
.fontSize(Math.round(18 * this.scaleFor()))
.fontColor($r('app.color.text_secondary'))
.margin({ top: 120 })
Text('请与对方设备碰一碰后重新接收')
.fontSize(Math.round(14 * this.scaleFor()))
.fontColor($r('app.color.inactive_tab'))
} else if (this.report !== null) {
// 报告头
Column({ space: 8 }) {
Text('长者健康报告')
.fontSize(Math.round(14 * this.scaleFor()))
.fontColor('#FFFFFF')
.opacity(0.9)
Text(this.report.name)
.fontSize(Math.round(32 * this.scaleFor()))
.fontWeight(FontWeight.Bold)
.fontColor('#FFFFFF')
Text(`${this.report.age}岁 · ${this.report.gender}${this.report.room.length > 0 ? ' · ' + this.report.room : ''}`)
.fontSize(Math.round(15 * this.scaleFor()))
.fontColor('#FFFFFF')
.opacity(0.9)
if (this.report.health_score !== null) {
Text(`健康评分 ${this.report.health_score}`)
.fontSize(Math.round(15 * this.scaleFor()))
.fontWeight(FontWeight.Medium)
.fontColor('#FFFFFF')
.padding({ left: 14, right: 14, top: 6, bottom: 6 })
.backgroundColor('#33FFFFFF')
.borderRadius(16)
}
}
.width('100%')
.padding(24)
.borderRadius(18)
.linearGradient({
angle: 135,
colors: [[$r('app.color.accent_blue'), 0], ['#5B8DEF', 1]]
})
.alignItems(HorizontalAlign.Center)
Text(this.report.care_level)
.fontSize(Math.round(14 * this.scaleFor()))
.fontColor($r('app.color.accent_blue'))
.width('100%')
// 报告内容
Column({ space: 14 }) {
Text('健康信息')
.fontSize(Math.round(17 * this.scaleFor()))
.fontWeight(FontWeight.Bold)
.fontColor($r('app.color.text_primary'))
.width('100%')
this.InfoRow('健康状态', this.report.status)
this.InfoRow('风险标签', this.report.risks.length > 0 ? this.report.risks.join('、') : '')
this.InfoRow('病史', this.report.medical_history)
this.InfoRow('过敏', this.report.allergies)
this.InfoRow('常用药物', this.report.medications.length > 0 ? this.report.medications.join('、') : '')
this.InfoRow('主责护理员', this.report.caregiver)
this.InfoRow('紧急联系人', this.report.emergency_contact)
}
.width('100%')
.padding(18)
.backgroundColor($r('app.color.background_card'))
.borderRadius(14)
.alignItems(HorizontalAlign.Start)
if (this.report.report_title.length > 0) {
// AI 健康报告(周期总结 + AI 分析)
Column({ space: 10 }) {
Row({ space: 6 }) {
Text('AI 健康报告')
.fontSize(Math.round(16 * this.scaleFor()))
.fontWeight(FontWeight.Bold)
.fontColor($r('app.color.accent_blue'))
Text(this.report.report_title)
.fontSize(Math.round(13 * this.scaleFor()))
.fontColor($r('app.color.text_secondary'))
.layoutWeight(1)
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
}
.width('100%')
if (this.report.report_period.length > 0) {
Text(this.report.report_period)
.fontSize(Math.round(12 * this.scaleFor()))
.fontColor($r('app.color.inactive_tab'))
.width('100%')
}
if (this.report.report_summary.length > 0) {
Text(this.report.report_summary)
.fontSize(Math.round(14 * this.scaleFor()))
.fontColor($r('app.color.text_primary'))
.width('100%')
.lineHeight(Math.round(22 * this.scaleFor()))
}
if (this.report.report_ai.length > 0) {
Divider().color($r('app.color.background'))
Text('AI 分析')
.fontSize(Math.round(13 * this.scaleFor()))
.fontWeight(FontWeight.Medium)
.fontColor($r('app.color.accent_blue'))
.width('100%')
Text(this.report.report_ai)
.fontSize(Math.round(14 * this.scaleFor()))
.fontColor($r('app.color.text_primary'))
.width('100%')
.lineHeight(Math.round(22 * this.scaleFor()))
}
}
.width('100%')
.padding(18)
.backgroundColor($r('app.color.background_card'))
.borderRadius(14)
.alignItems(HorizontalAlign.Start)
}
Text(`分享时间:${this.report.shared_at}`)
.fontSize(Math.round(12 * this.scaleFor()))
.fontColor($r('app.color.inactive_tab'))
.width('100%')
}
}
.width('100%')
.padding({ left: 16, right: 16, top: 72, bottom: 30 })
}
.width('100%')
.height('100%')
.scrollBar(BarState.Auto)
.edgeEffect(EdgeEffect.Spring)
.align(Alignment.Top)
.backgroundColor($r('app.color.background'))
}
}