fix(mp): 行业标准第二轮审计修复 — 安全存储+UX+合规

- 安全:AI聊天历史、患者档案、设备同步数据统一走 secureSet/secureGet 加密存储
- 合规:TabBar "消息" 改为 "助手" 消除命名误导
- 合规:新增 .env.production 模板配置 HTTPS API URL
- UX:AI发送按钮 40→44px、反馈按钮 32→44px、协议勾选框 44px 点击热区
- UX:5处硬编码 10-12px 字号替换为 design token(DoctorTabBar/ShortcutButton/TodoAlert/mall)
- UX:6处安全区域写法统一(全部使用 --tk-page-padding/--tk-tabbar-space + env fallback)
- 新增 safe-bottom-padded / safe-bottom-tabbar 两个 mixin

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
iven
2026-05-21 14:06:29 +08:00
parent d576b8ba8f
commit 345e46002a
16 changed files with 51 additions and 33 deletions

View File

@@ -93,11 +93,8 @@ export const useAuthStore = create<AuthState>((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<AuthState>((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<AuthState>((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) => {