diff --git a/apps/miniprogram/src/app.config.ts b/apps/miniprogram/src/app.config.ts index 792171a..0c8b797 100644 --- a/apps/miniprogram/src/app.config.ts +++ b/apps/miniprogram/src/app.config.ts @@ -74,7 +74,7 @@ export default defineAppConfig({ list: [ { pagePath: 'pages/index/index', text: '首页', iconPath: 'assets/tabbar/home.png', selectedIconPath: 'assets/tabbar/home-active.png' }, { pagePath: 'pages/health/index', text: '健康', iconPath: 'assets/tabbar/health.png', selectedIconPath: 'assets/tabbar/health-active.png' }, - { pagePath: 'pages/messages/index', text: '消息', iconPath: 'assets/tabbar/message.png', selectedIconPath: 'assets/tabbar/message-active.png' }, + { pagePath: 'pages/messages/index', text: '助手', iconPath: 'assets/tabbar/message.png', selectedIconPath: 'assets/tabbar/message-active.png' }, { pagePath: 'pages/profile/index', text: '我的', iconPath: 'assets/tabbar/profile.png', selectedIconPath: 'assets/tabbar/profile-active.png' }, ], }, diff --git a/apps/miniprogram/src/components/ui/DoctorTabBar/index.scss b/apps/miniprogram/src/components/ui/DoctorTabBar/index.scss index e8af20b..dd15f7a 100644 --- a/apps/miniprogram/src/components/ui/DoctorTabBar/index.scss +++ b/apps/miniprogram/src/components/ui/DoctorTabBar/index.scss @@ -44,7 +44,7 @@ } &__label { - font-size: 10px; + font-size: var(--tk-font-micro); color: $tx3; line-height: 1.2; transition: color 0.15s ease; diff --git a/apps/miniprogram/src/components/ui/ShortcutButton/index.scss b/apps/miniprogram/src/components/ui/ShortcutButton/index.scss index f09b446..8b08bad 100644 --- a/apps/miniprogram/src/components/ui/ShortcutButton/index.scss +++ b/apps/miniprogram/src/components/ui/ShortcutButton/index.scss @@ -37,14 +37,14 @@ text-align: center; background: $dan; color: $white; - font-size: 11px; + font-size: var(--tk-font-micro); font-weight: 700; border-radius: $r-pill; padding: 0 4px; } &__label { - font-size: 12px; + font-size: var(--tk-font-cap); color: $tx2; } diff --git a/apps/miniprogram/src/components/ui/TodoAlert/index.scss b/apps/miniprogram/src/components/ui/TodoAlert/index.scss index 8b938d5..530578b 100644 --- a/apps/miniprogram/src/components/ui/TodoAlert/index.scss +++ b/apps/miniprogram/src/components/ui/TodoAlert/index.scss @@ -44,7 +44,7 @@ &__subtitle { display: block; - font-size: 12px; + font-size: var(--tk-font-cap); color: $tx3; margin-top: 2px; overflow: hidden; diff --git a/apps/miniprogram/src/pages/appointment/create/index.scss b/apps/miniprogram/src/pages/appointment/create/index.scss index 0fca6cf..48707b5 100644 --- a/apps/miniprogram/src/pages/appointment/create/index.scss +++ b/apps/miniprogram/src/pages/appointment/create/index.scss @@ -308,7 +308,7 @@ gap: var(--tk-gap-md); padding: var(--tk-section-gap) var(--tk-gap-lg); padding-bottom: constant(safe-area-inset-bottom); - padding-bottom: env(safe-area-inset-bottom); + padding-bottom: calc(var(--tk-page-padding) + env(safe-area-inset-bottom, 0px)); background: $card; box-shadow: $shadow-md; } diff --git a/apps/miniprogram/src/pages/appointment/detail/index.scss b/apps/miniprogram/src/pages/appointment/detail/index.scss index 2ef62a6..2e9e00a 100644 --- a/apps/miniprogram/src/pages/appointment/detail/index.scss +++ b/apps/miniprogram/src/pages/appointment/detail/index.scss @@ -153,7 +153,7 @@ right: 0; padding: var(--tk-section-gap) var(--tk-gap-lg); padding-bottom: constant(safe-area-inset-bottom); - padding-bottom: env(safe-area-inset-bottom); + padding-bottom: calc(var(--tk-page-padding) + env(safe-area-inset-bottom, 0px)); background: $card; box-shadow: $shadow-md; } diff --git a/apps/miniprogram/src/pages/health/index.scss b/apps/miniprogram/src/pages/health/index.scss index 557d053..01b12e1 100644 --- a/apps/miniprogram/src/pages/health/index.scss +++ b/apps/miniprogram/src/pages/health/index.scss @@ -341,7 +341,8 @@ } .ai-feedback-btn { - height: 32px; + height: 44px; + min-height: 44px; border-radius: $r-xs; @include flex-center; padding: 0 var(--tk-gap-sm); diff --git a/apps/miniprogram/src/pages/login/index.scss b/apps/miniprogram/src/pages/login/index.scss index 46f9679..102da3f 100644 --- a/apps/miniprogram/src/pages/login/index.scss +++ b/apps/miniprogram/src/pages/login/index.scss @@ -189,6 +189,17 @@ @include flex-center; flex-shrink: 0; margin-top: 1px; + position: relative; + + // 扩大点击区域至 44x44(24px 视觉 + 10px 每侧 padding via 伪元素) + &::before { + content: ''; + position: absolute; + top: -10px; + right: -10px; + bottom: -10px; + left: -10px; + } &.checked { background: var(--tk-pri); diff --git a/apps/miniprogram/src/pages/mall/index.scss b/apps/miniprogram/src/pages/mall/index.scss index ba95e76..37987c4 100644 --- a/apps/miniprogram/src/pages/mall/index.scss +++ b/apps/miniprogram/src/pages/mall/index.scss @@ -308,7 +308,7 @@ position: absolute; top: 8px; left: 8px; - font-size: 10px; + font-size: var(--tk-font-micro); font-weight: 600; padding: 2px 8px; border-radius: 6px; diff --git a/apps/miniprogram/src/pages/messages/index.scss b/apps/miniprogram/src/pages/messages/index.scss index c6a248e..d617f99 100644 --- a/apps/miniprogram/src/pages/messages/index.scss +++ b/apps/miniprogram/src/pages/messages/index.scss @@ -252,7 +252,7 @@ align-items: center; gap: 10px; padding: 10px 16px; - padding-bottom: calc(10px + env(safe-area-inset-bottom)); + padding-bottom: calc(var(--tk-tabbar-space) + env(safe-area-inset-bottom, 0px)); background: $card; border-top: 1px solid $bd-l; flex-shrink: 0; @@ -275,9 +275,9 @@ } .ai-chat-bar__send { - width: 40px; - height: 40px; - border-radius: 20px; + width: 44px; + height: 44px; + border-radius: 22px; background: $pri; display: flex; align-items: center; diff --git a/apps/miniprogram/src/pages/pkg-consultation/detail/index.scss b/apps/miniprogram/src/pages/pkg-consultation/detail/index.scss index bd9d6bd..f7d6af5 100644 --- a/apps/miniprogram/src/pages/pkg-consultation/detail/index.scss +++ b/apps/miniprogram/src/pages/pkg-consultation/detail/index.scss @@ -197,7 +197,7 @@ align-items: center; gap: 10px; padding: 10px 16px; - padding-bottom: calc(10px + env(safe-area-inset-bottom)); + padding-bottom: calc(var(--tk-page-padding) + env(safe-area-inset-bottom, 0px)); background: $card; border-top: 1px solid $bd-l; flex-shrink: 0; diff --git a/apps/miniprogram/src/pages/pkg-doctor-core/consultation/detail/index.scss b/apps/miniprogram/src/pages/pkg-doctor-core/consultation/detail/index.scss index 9d8df0c..0ea5618 100644 --- a/apps/miniprogram/src/pages/pkg-doctor-core/consultation/detail/index.scss +++ b/apps/miniprogram/src/pages/pkg-doctor-core/consultation/detail/index.scss @@ -117,7 +117,7 @@ padding: var(--tk-gap-md) var(--tk-gap-lg); background: $card; border-top: 1px solid $bd; - padding-bottom: calc(16px + env(safe-area-inset-bottom)); + padding-bottom: calc(var(--tk-page-padding) + env(safe-area-inset-bottom, 0px)); } .chat-input { diff --git a/apps/miniprogram/src/pages/pkg-mall/orders/index.scss b/apps/miniprogram/src/pages/pkg-mall/orders/index.scss index d182bdb..df1c4f7 100644 --- a/apps/miniprogram/src/pages/pkg-mall/orders/index.scss +++ b/apps/miniprogram/src/pages/pkg-mall/orders/index.scss @@ -4,7 +4,7 @@ // 订单列表 — 对齐原型 docs/design/mp-10-mall-pkg.html → 屏幕3 .orders-page { - padding-bottom: env(safe-area-inset-bottom); + padding-bottom: calc(var(--tk-page-padding) + env(safe-area-inset-bottom, 0px)); } // 状态筛选 Tab diff --git a/apps/miniprogram/src/services/ai-chat.ts b/apps/miniprogram/src/services/ai-chat.ts index 11ba8f4..6408813 100644 --- a/apps/miniprogram/src/services/ai-chat.ts +++ b/apps/miniprogram/src/services/ai-chat.ts @@ -1,4 +1,5 @@ import { api } from './request'; +import { secureGet, secureSet } from '@/utils/secure-storage'; export interface AiChatMessage { id: string; @@ -74,10 +75,10 @@ export async function closeSession(sessionId: string): Promise { await api.post(`/ai/chat/sessions/${sessionId}/close`, {}); } -/** 获取聊天历史(本地缓存) */ +/** 获取聊天历史(本地加密缓存) */ export function getLocalHistory(): AiChatMessage[] { try { - const raw = wx.getStorageSync('ai_chat_history'); + const raw = secureGet('ai_chat_history'); return raw ? JSON.parse(raw) : []; } catch (err) { console.warn('[ai-chat] 读取本地聊天历史失败:', err); @@ -85,9 +86,9 @@ export function getLocalHistory(): AiChatMessage[] { } } -/** 保存聊天历史到本地 */ +/** 保存聊天历史到本地(加密存储) */ export function saveLocalHistory(messages: AiChatMessage[]): void { try { - wx.setStorageSync('ai_chat_history', JSON.stringify(messages.slice(-100))); + secureSet('ai_chat_history', JSON.stringify(messages.slice(-100))); } catch (err) { console.warn('[ai-chat] 保存本地聊天历史失败:', err); } } diff --git a/apps/miniprogram/src/stores/auth.ts b/apps/miniprogram/src/stores/auth.ts index 37ac420..09f9d8b 100644 --- a/apps/miniprogram/src/stores/auth.ts +++ b/apps/miniprogram/src/stores/auth.ts @@ -93,11 +93,8 @@ export const useAuthStore = create((set, get) => ({ } } catch { /* secure storage 不可用时保持默认值 */ } try { - let patientRaw = Taro.getStorageSync('current_patient'); - // 防御双重序列化:如果 Storage 写入了 JSON 字符串而非对象,尝试解析 - if (typeof patientRaw === 'string') { - try { patientRaw = JSON.parse(patientRaw); } catch { patientRaw = null; } - } + const patientStr = secureGet('current_patient'); + let patientRaw = patientStr ? JSON.parse(patientStr) : null; const patientJson = patientRaw ? JSON.stringify(patientRaw) : ''; if (patientJson !== cachedPatientJson) { cachedPatientJson = patientJson; @@ -227,8 +224,8 @@ export const useAuthStore = create((set, get) => ({ }, setCurrentPatient: (patient) => { - Taro.setStorageSync('current_patient_id', patient.id); - Taro.setStorageSync('current_patient', patient); + secureSet('current_patient_id', patient.id); + secureSet('current_patient', JSON.stringify(patient)); setCachedPatientId(patient.id); clearRequestCache(); set({ currentPatient: patient }); @@ -264,11 +261,11 @@ export const useAuthStore = create((set, get) => ({ secureRemove('user_roles'); secureRemove('tenant_id'); secureRemove('wechat_openid'); - Taro.removeStorageSync('current_patient'); - Taro.removeStorageSync('current_patient_id'); - Taro.removeStorageSync('analytics_queue'); - Taro.removeStorageSync('edit_patient'); - Taro.removeStorageSync('ai_chat_history'); + secureRemove('current_patient'); + secureRemove('current_patient_id'); + secureRemove('analytics_queue'); + secureRemove('edit_patient'); + secureRemove('ai_chat_history'); // 清理 BLE DataBuffer 缓存(key 格式:ble_buffer_{patientId}_{bucket}) const storageInfo = Taro.getStorageInfoSync(); storageInfo.keys.forEach((key) => { diff --git a/apps/miniprogram/src/styles/mixins.scss b/apps/miniprogram/src/styles/mixins.scss index bc337b5..0133f40 100644 --- a/apps/miniprogram/src/styles/mixins.scss +++ b/apps/miniprogram/src/styles/mixins.scss @@ -16,7 +16,15 @@ @mixin safe-bottom { padding-bottom: constant(safe-area-inset-bottom); - padding-bottom: env(safe-area-inset-bottom); + padding-bottom: env(safe-area-inset-bottom, 0px); +} + +@mixin safe-bottom-padded { + padding-bottom: calc(var(--tk-page-padding) + env(safe-area-inset-bottom, 0px)); +} + +@mixin safe-bottom-tabbar { + padding-bottom: calc(var(--tk-tabbar-space) + env(safe-area-inset-bottom, 0px)); } @mixin serif-number {