- 以 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)
226 lines
7.5 KiB
Plaintext
226 lines
7.5 KiB
Plaintext
// 老人端 · 我的面板(ArkTS 严格类型,无 any)
|
||
// 对齐小程序 ElderlyProfilePanel:账号卡 + 菜单 + 退出登录
|
||
import { router } from '@kit.ArkUI';
|
||
import { promptAction } from '@kit.ArkUI';
|
||
import { common } from '@kit.AbilityKit';
|
||
import { BusinessError } from '@kit.BasicServicesKit';
|
||
import { AuthStore } from '../../utils/AuthStore';
|
||
import { normalizeError } from '../../common/ApiConstants';
|
||
import { api, RequestError } from '../../utils/Request';
|
||
import { FontScaleLevel, FontScaleOption, FONT_SCALE_LABELS, FONT_SCALE_MAP, loadFontScale, setFontScale } from '../../utils/FontScale';
|
||
|
||
interface ProfileDashboard {
|
||
elderly_id: number | null;
|
||
elderly_name: string;
|
||
service_date: string;
|
||
}
|
||
|
||
interface ProfileMenu {
|
||
key: string;
|
||
title: string;
|
||
desc: string;
|
||
route: string; // 空字符串表示未实现
|
||
}
|
||
|
||
@Component
|
||
export struct ElderlyProfilePanel {
|
||
@State userName: string = '';
|
||
@State userId: number = 0;
|
||
@State elderlyName: string = '';
|
||
@State fontScale: FontScaleLevel = 'normal';
|
||
@StorageProp('fontScale') fontScaleLevel: FontScaleLevel = 'system';
|
||
|
||
private scaleFor(): number {
|
||
return FONT_SCALE_MAP[this.fontScaleLevel] ?? 1.0;
|
||
}
|
||
|
||
menus: Array<ProfileMenu> = [
|
||
{ key: 'meal', title: '餐饮服务', desc: '查看并选择定制餐', route: 'pages/elderly/ElderlyMealOrder' },
|
||
{ key: 'activities', title: '活动安排', desc: '查看今天和本周的社工活动', route: 'pages/elderly/Activities' },
|
||
{ key: 'notifications', title: '消息通知', desc: '查看护理记录和订餐状态消息', route: 'pages/notifications/Notifications' },
|
||
{ key: 'history', title: '历史订餐', desc: '查看过往和近期的订餐记录', route: 'pages/elderly/ElderlyHistory' },
|
||
|
||
];
|
||
|
||
aboutToAppear(): void {
|
||
this.loadAuth();
|
||
this.loadDashboard();
|
||
loadFontScale(getContext(this) as common.UIAbilityContext).then((level: FontScaleLevel) => {
|
||
this.fontScale = level;
|
||
});
|
||
}
|
||
|
||
private async loadDashboard(): Promise<void> {
|
||
try {
|
||
const res = await api.get<ProfileDashboard>('/elderly-portal/dashboard/');
|
||
this.elderlyName = res.elderly_name || '';
|
||
} catch (err) {
|
||
console.warn('[ElderlyProfile] load dashboard failed:', normalizeError(err as BusinessError | Error));
|
||
}
|
||
}
|
||
|
||
private changeFontScale(level: FontScaleLevel): void {
|
||
this.fontScale = level;
|
||
setFontScale(getContext(this) as common.UIAbilityContext, level);
|
||
promptAction.showToast({ message: `字体已调整为${FONT_SCALE_LABELS.find((item) => item.level === level)?.label ?? ''}` });
|
||
}
|
||
|
||
private async loadAuth(): Promise<void> {
|
||
const state = await AuthStore.getState();
|
||
this.userName = state.userName;
|
||
this.userId = state.userId;
|
||
}
|
||
|
||
private onMenuClick(menu: ProfileMenu): void {
|
||
if (menu.route.length === 0) {
|
||
promptAction.showToast({ message: '功能开发中' });
|
||
return;
|
||
}
|
||
router.pushUrl({ url: menu.route }).catch(() => {});
|
||
}
|
||
|
||
private async logout(): Promise<void> {
|
||
await AuthStore.logout();
|
||
promptAction.showToast({ message: '已退出登录' });
|
||
router.replaceUrl({ url: 'pages/Login' }).catch(() => {});
|
||
}
|
||
|
||
@Builder
|
||
MenuRow(menu: ProfileMenu) {
|
||
Row({ space: 12 }) {
|
||
Column({ space: 6 }) {
|
||
Text(menu.title)
|
||
.fontSize(Math.round(17 * this.scaleFor()))
|
||
.fontWeight(FontWeight.Medium)
|
||
.fontColor($r('app.color.text_primary'))
|
||
Text(menu.desc)
|
||
.fontSize(Math.round(15 * this.scaleFor()))
|
||
.fontColor($r('app.color.text_secondary'))
|
||
}
|
||
.layoutWeight(1)
|
||
.alignItems(HorizontalAlign.Start)
|
||
|
||
Text('›')
|
||
.fontSize(Math.round(22 * this.scaleFor()))
|
||
.fontColor($r('app.color.inactive_tab'))
|
||
}
|
||
.width('100%')
|
||
.padding(14)
|
||
.backgroundColor($r('app.color.background_card'))
|
||
.borderRadius(14)
|
||
.onClick(() => {
|
||
this.onMenuClick(menu);
|
||
})
|
||
}
|
||
|
||
build() {
|
||
Scroll() {
|
||
Column({ space: 12 }) {
|
||
// 用户信息卡
|
||
Column({ space: 8 }) {
|
||
Stack() {
|
||
Circle()
|
||
.width(64)
|
||
.height(64)
|
||
.fill($r('app.color.accent_blue'))
|
||
Text((this.elderlyName || this.userName || '客').substring(0, 1))
|
||
.fontSize(Math.round(26 * this.scaleFor()))
|
||
.fontWeight(FontWeight.Bold)
|
||
.fontColor('#FFFFFF')
|
||
}
|
||
.width(64)
|
||
.height(64)
|
||
|
||
Text(this.elderlyName || this.userName || '用户')
|
||
.fontSize(Math.round(22 * this.scaleFor()))
|
||
.fontWeight(FontWeight.Bold)
|
||
.fontColor($r('app.color.text_primary'))
|
||
|
||
Text(this.elderlyName.length > 0 ? '长者账号' : '账号')
|
||
.fontSize(Math.round(13 * this.scaleFor()))
|
||
.fontColor($r('app.color.text_secondary'))
|
||
}
|
||
.width('92%')
|
||
.padding({ top: 16, bottom: 14 })
|
||
.backgroundColor($r('app.color.background_card'))
|
||
.borderRadius(16)
|
||
.margin({ top: 16 })
|
||
|
||
// 账号编号
|
||
Row() {
|
||
Text('账号编号')
|
||
.fontSize(Math.round(15 * this.scaleFor()))
|
||
.fontColor($r('app.color.text_secondary'))
|
||
Blank()
|
||
Text(this.userId > 0 ? String(this.userId) : '--')
|
||
.fontSize(Math.round(15 * this.scaleFor()))
|
||
.fontColor($r('app.color.text_primary'))
|
||
}
|
||
.width('92%')
|
||
.padding(14)
|
||
.backgroundColor($r('app.color.background_card'))
|
||
.borderRadius(14)
|
||
|
||
// 字体大小
|
||
Column({ space: 8 }) {
|
||
Text('字体大小')
|
||
.fontSize(Math.round(15 * this.scaleFor()))
|
||
.fontColor($r('app.color.text_primary'))
|
||
.width('100%')
|
||
Flex({ wrap: FlexWrap.Wrap, alignItems: ItemAlign.Center }) {
|
||
ForEach(FONT_SCALE_LABELS, (item: FontScaleOption) => {
|
||
Text(item.label)
|
||
.fontSize(Math.round(15 * this.scaleFor()))
|
||
.fontColor(this.fontScale === item.level ? '#FFFFFF' : $r('app.color.text_primary'))
|
||
.padding({ left: 18, right: 18, top: 10, bottom: 10 })
|
||
.backgroundColor(this.fontScale === item.level ? $r('app.color.accent_blue') : $r('app.color.background_card'))
|
||
.borderRadius(10)
|
||
.margin({ right: 10, bottom: 10 })
|
||
.onClick(() => {
|
||
this.changeFontScale(item.level);
|
||
})
|
||
}, (item: FontScaleOption) => item.level)
|
||
}
|
||
.width('100%')
|
||
}
|
||
.width('92%')
|
||
.padding(14)
|
||
.backgroundColor($r('app.color.background_card'))
|
||
.borderRadius(14)
|
||
.alignItems(HorizontalAlign.Start)
|
||
|
||
// 菜单
|
||
Column({ space: 8 }) {
|
||
ForEach(this.menus, (menu: ProfileMenu) => {
|
||
this.MenuRow(menu)
|
||
}, (menu: ProfileMenu) => menu.key)
|
||
}
|
||
.width('92%')
|
||
|
||
// 退出登录
|
||
Text('退出登录')
|
||
.fontSize(Math.round(17 * this.scaleFor()))
|
||
.fontWeight(FontWeight.Medium)
|
||
.fontColor($r('app.color.accent_red'))
|
||
.textAlign(TextAlign.Center)
|
||
.width('92%')
|
||
.padding(14)
|
||
.backgroundColor($r('app.color.background_card'))
|
||
.borderRadius(14)
|
||
// 避让底部悬浮 Tab
|
||
.margin({ bottom: 130 })
|
||
|
||
.onClick(() => {
|
||
this.logout();
|
||
})
|
||
}
|
||
.width('100%')
|
||
.alignItems(HorizontalAlign.Center)
|
||
}
|
||
.scrollBar(BarState.Auto)
|
||
.edgeEffect(EdgeEffect.Spring)
|
||
.width('100%')
|
||
.height('100%')
|
||
}
|
||
}
|