fix(mp): 五专家组审查 HIGH 级问题修复 — 9 项
- S-1: 隐私政策描述修正("混淆加密" → "HTTPS + 微信沙箱") - A-1: getCachedPatientId 统一导出 + 9 处 Storage 直读替换 - A-2: usePageData loading 改为 useState 响应式 - A-3: health.ts refreshingToday 移入 store state - M-2: prod config 移除 console.error/warn - M-4: clearCache 后同步刷新 request.ts 内存缓存 - Q-3: doctor/appointment.ts any[] → Appointment 类型 - Q-4: daily-monitoring 常量提取到 constants.ts - 清理: 删除空目录 FamilyPicker/HealthCard + 未使用组件 DeviceCard
This commit is contained in:
@@ -23,9 +23,9 @@ const PRIVACY_CONTENT = `
|
||||
|
||||
<h4>三、信息存储与保护</h4>
|
||||
<p>1. 您的信息存储在中华人民共和国境内的安全服务器中</p>
|
||||
<p>2. 我们采用加密传输(HTTPS)和加密存储等安全措施</p>
|
||||
<p>2. 我们采用加密传输(HTTPS)确保数据在传输过程中的安全</p>
|
||||
<p>3. 严格的内部数据访问权限控制</p>
|
||||
<p>4. Token 等敏感凭证采用混淆加密存储</p>
|
||||
<p>4. Token 等敏感凭证通过 HTTPS 加密传输,本地存储依赖微信小程序安全沙箱保护</p>
|
||||
|
||||
<h4>四、信息共享</h4>
|
||||
<p>未经您的同意,我们不会与任何第三方共享您的个人信息,以下情况除外:</p>
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
export const BP_RANGE = { min: 30, minMsg: '血压值不能低于30', max: 300, maxMsg: '血压值不能高于300', optional: true };
|
||||
export const WEIGHT_RANGE = { min: 1, minMsg: '体重不能低于1kg', max: 500, maxMsg: '体重不能高于500kg', optional: true };
|
||||
export const SUGAR_RANGE = { min: 0.1, minMsg: '血糖值不能低于0.1', max: 50, maxMsg: '血糖值不能高于50', optional: true };
|
||||
export const VOLUME_RANGE = { min: 0, minMsg: '数值不能为负', max: 10000, maxMsg: '数值超出合理范围', optional: true };
|
||||
|
||||
export const REFERENCE_RANGES: Record<string, { min: number; max: number } | null> = {
|
||||
systolic: { min: 90, max: 140 },
|
||||
diastolic: { min: 60, max: 90 },
|
||||
bloodSugar: { min: 3.9, max: 6.1 },
|
||||
weight: null,
|
||||
fluidIntake: null,
|
||||
urineOutput: null,
|
||||
};
|
||||
|
||||
export type AbnormalResult = { abnormal: boolean; direction: 'high' | 'low' | null };
|
||||
|
||||
export const checkAbnormal = (value: string, field: string): AbnormalResult => {
|
||||
const ref = REFERENCE_RANGES[field];
|
||||
if (!value || !ref) return { abnormal: false, direction: null };
|
||||
const num = parseFloat(value);
|
||||
if (isNaN(num)) return { abnormal: false, direction: null };
|
||||
if (num > ref.max) return { abnormal: true, direction: 'high' };
|
||||
if (num < ref.min) return { abnormal: true, direction: 'low' };
|
||||
return { abnormal: false, direction: null };
|
||||
};
|
||||
|
||||
export type SectionKey = 'morning' | 'evening' | 'other';
|
||||
|
||||
export const FIELD_LABELS: Record<string, string> = {
|
||||
morningSystolic: '晨间收缩压',
|
||||
morningDiastolic: '晨间舒张压',
|
||||
eveningSystolic: '晚间收缩压',
|
||||
eveningDiastolic: '晚间舒张压',
|
||||
bloodSugar: '血糖',
|
||||
};
|
||||
|
||||
export function formatDate(date: Date): string {
|
||||
const y = date.getFullYear();
|
||||
const m = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const d = String(date.getDate()).padStart(2, '0');
|
||||
return `${y}-${m}-${d}`;
|
||||
}
|
||||
@@ -9,56 +9,14 @@ import { usePointsStore } from '@/stores/points';
|
||||
import { clearRequestCache } from '@/services/request';
|
||||
import { trackEvent } from '@/services/analytics';
|
||||
import { useSafeTimeout } from '@/hooks/useSafeTimeout';
|
||||
import { useElderClass } from '../../../hooks/useElderClass';
|
||||
import { useElderClass } from '@/hooks/useElderClass';
|
||||
import {
|
||||
BP_RANGE, WEIGHT_RANGE, SUGAR_RANGE, VOLUME_RANGE,
|
||||
checkAbnormal, formatDate, FIELD_LABELS,
|
||||
type SectionKey, type AbnormalResult,
|
||||
} from './constants';
|
||||
import './index.scss';
|
||||
|
||||
const BP_RANGE = { min: 30, minMsg: '血压值不能低于30', max: 300, maxMsg: '血压值不能高于300', optional: true };
|
||||
const WEIGHT_RANGE = { min: 1, minMsg: '体重不能低于1kg', max: 500, maxMsg: '体重不能高于500kg', optional: true };
|
||||
const SUGAR_RANGE = { min: 0.1, minMsg: '血糖值不能低于0.1', max: 50, maxMsg: '血糖值不能高于50', optional: true };
|
||||
const VOLUME_RANGE = { min: 0, minMsg: '数值不能为负', max: 10000, maxMsg: '数值超出合理范围', optional: true };
|
||||
|
||||
function formatDate(date: Date): string {
|
||||
const y = date.getFullYear();
|
||||
const m = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const d = String(date.getDate()).padStart(2, '0');
|
||||
return `${y}-${m}-${d}`;
|
||||
}
|
||||
|
||||
// ── Abnormal value detection ──
|
||||
|
||||
const REFERENCE_RANGES: Record<string, { min: number; max: number } | null> = {
|
||||
systolic: { min: 90, max: 140 },
|
||||
diastolic: { min: 60, max: 90 },
|
||||
bloodSugar: { min: 3.9, max: 6.1 },
|
||||
weight: null,
|
||||
fluidIntake: null,
|
||||
urineOutput: null,
|
||||
};
|
||||
|
||||
type AbnormalResult = { abnormal: boolean; direction: 'high' | 'low' | null };
|
||||
|
||||
const checkAbnormal = (value: string, field: string): AbnormalResult => {
|
||||
const ref = REFERENCE_RANGES[field];
|
||||
if (!value || !ref) return { abnormal: false, direction: null };
|
||||
const num = parseFloat(value);
|
||||
if (isNaN(num)) return { abnormal: false, direction: null };
|
||||
if (num > ref.max) return { abnormal: true, direction: 'high' };
|
||||
if (num < ref.min) return { abnormal: true, direction: 'low' };
|
||||
return { abnormal: false, direction: null };
|
||||
};
|
||||
|
||||
// ── Section state type ──
|
||||
|
||||
type SectionKey = 'morning' | 'evening' | 'other';
|
||||
|
||||
const FIELD_LABELS: Record<string, string> = {
|
||||
morningSystolic: '晨间收缩压',
|
||||
morningDiastolic: '晨间舒张压',
|
||||
eveningSystolic: '晚间收缩压',
|
||||
eveningDiastolic: '晚间舒张压',
|
||||
bloodSugar: '血糖',
|
||||
};
|
||||
|
||||
export default function DailyMonitoring() {
|
||||
const modeClass = useElderClass();
|
||||
const currentPatient = useAuthStore((s) => s.currentPatient);
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { useState, useCallback } from 'react';
|
||||
import { View, Text } from '@tarojs/components';
|
||||
import Taro, { useReachBottom } from '@tarojs/taro';
|
||||
import { usePageData } from '@/hooks/usePageData';
|
||||
import { getCachedPatientId } from '@/services/request';
|
||||
import { listConsents, revokeConsent } from '@/services/consent';
|
||||
import type { Consent } from '@/services/consent';
|
||||
import EmptyState from '@/components/EmptyState';
|
||||
@@ -33,7 +34,7 @@ export default function ConsentList() {
|
||||
const [hasPatient, setHasPatient] = useState(true);
|
||||
|
||||
const fetchData = useCallback(async (p: number, append = false) => {
|
||||
const patientId = Taro.getStorageSync('current_patient_id') || '';
|
||||
const patientId = getCachedPatientId();
|
||||
if (!patientId) {
|
||||
setConsents([]);
|
||||
setHasPatient(false);
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { useState, useCallback } from 'react';
|
||||
import { View, Text } from '@tarojs/components';
|
||||
import Taro, { useReachBottom } from '@tarojs/taro';
|
||||
import { usePageData } from '@/hooks/usePageData';
|
||||
import { getCachedPatientId } from '@/services/request';
|
||||
import { listDiagnoses, Diagnosis } from '../../../services/health-record';
|
||||
import EmptyState from '../../../components/EmptyState';
|
||||
import Loading from '../../../components/Loading';
|
||||
@@ -29,7 +30,7 @@ export default function Diagnoses() {
|
||||
const [hasPatient, setHasPatient] = useState(true);
|
||||
|
||||
const fetchData = useCallback(async (p: number, append = false) => {
|
||||
const patientId = Taro.getStorageSync('current_patient_id') || '';
|
||||
const patientId = getCachedPatientId();
|
||||
if (!patientId) {
|
||||
setRecords([]);
|
||||
setHasPatient(false);
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { useState, useCallback } from 'react';
|
||||
import { View, Text } from '@tarojs/components';
|
||||
import Taro, { useReachBottom } from '@tarojs/taro';
|
||||
import { usePageData } from '@/hooks/usePageData';
|
||||
import { getCachedPatientId } from '@/services/request';
|
||||
import { listDialysisPrescriptions } from '@/services/dialysis';
|
||||
import type { DialysisPrescription } from '@/services/dialysis';
|
||||
import EmptyState from '@/components/EmptyState';
|
||||
@@ -24,7 +25,7 @@ export default function DialysisPrescriptionList() {
|
||||
const [hasPatient, setHasPatient] = useState(true);
|
||||
|
||||
const fetchData = useCallback(async (p: number, append = false) => {
|
||||
const patientId = Taro.getStorageSync('current_patient_id') || '';
|
||||
const patientId = getCachedPatientId();
|
||||
if (!patientId) {
|
||||
setPrescriptions([]);
|
||||
setHasPatient(false);
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { useState, useCallback } from 'react';
|
||||
import { View, Text } from '@tarojs/components';
|
||||
import Taro, { useReachBottom } from '@tarojs/taro';
|
||||
import { usePageData } from '@/hooks/usePageData';
|
||||
import { getCachedPatientId } from '@/services/request';
|
||||
import { listDialysisRecords } from '@/services/dialysis';
|
||||
import type { DialysisRecord } from '@/services/dialysis';
|
||||
import EmptyState from '@/components/EmptyState';
|
||||
@@ -30,7 +31,7 @@ export default function DialysisRecordList() {
|
||||
const [hasPatient, setHasPatient] = useState(true);
|
||||
|
||||
const fetchData = useCallback(async (p: number, append = false) => {
|
||||
const patientId = Taro.getStorageSync('current_patient_id') || '';
|
||||
const patientId = getCachedPatientId();
|
||||
if (!patientId) {
|
||||
setRecords([]);
|
||||
setHasPatient(false);
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { useState, useCallback } from 'react';
|
||||
import { View, Text } from '@tarojs/components';
|
||||
import Taro, { useReachBottom } from '@tarojs/taro';
|
||||
import { usePageData } from '@/hooks/usePageData';
|
||||
import { getCachedPatientId } from '@/services/request';
|
||||
import { listHealthRecords, HealthRecord } from '../../../services/health-record';
|
||||
import EmptyState from '../../../components/EmptyState';
|
||||
import Loading from '../../../components/Loading';
|
||||
@@ -23,7 +24,7 @@ export default function HealthRecords() {
|
||||
const [hasPatient, setHasPatient] = useState(true);
|
||||
|
||||
const fetchData = useCallback(async (p: number, append = false) => {
|
||||
const patientId = Taro.getStorageSync('current_patient_id') || '';
|
||||
const patientId = getCachedPatientId();
|
||||
if (!patientId) {
|
||||
setRecords([]);
|
||||
setHasPatient(false);
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { useState, useCallback } from 'react';
|
||||
import { View, Text, Input, Picker } from '@tarojs/components';
|
||||
import Taro from '@tarojs/taro';
|
||||
import { usePageData } from '@/hooks/usePageData';
|
||||
import { getCachedPatientId } from '@/services/request';
|
||||
import EmptyState from '../../../components/EmptyState';
|
||||
import {
|
||||
listReminders,
|
||||
@@ -69,7 +70,7 @@ export default function MedicationReminder() {
|
||||
Taro.showToast({ title: '请输入药品名称', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
const patientId = Taro.getStorageSync('current_patient_id');
|
||||
const patientId = getCachedPatientId();
|
||||
if (!patientId) {
|
||||
Taro.showToast({ title: '请先绑定患者档案', icon: 'none' });
|
||||
return;
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { useState, useCallback } from 'react';
|
||||
import { View, Text } from '@tarojs/components';
|
||||
import Taro, { useReachBottom } from '@tarojs/taro';
|
||||
import { usePageData } from '@/hooks/usePageData';
|
||||
import { getCachedPatientId } from '@/services/request';
|
||||
import { listReports, LabReport } from '../../../services/report';
|
||||
import EmptyState from '../../../components/EmptyState';
|
||||
import Loading from '../../../components/Loading';
|
||||
@@ -17,7 +18,7 @@ export default function MyReports() {
|
||||
const [hasPatient, setHasPatient] = useState(true);
|
||||
|
||||
const fetchData = useCallback(async (p: number, append = false) => {
|
||||
const patientId = Taro.getStorageSync('current_patient_id') || '';
|
||||
const patientId = getCachedPatientId();
|
||||
if (!patientId) {
|
||||
setReports([]);
|
||||
setHasPatient(false);
|
||||
|
||||
@@ -2,6 +2,7 @@ import React from 'react';
|
||||
import { View, Text } from '@tarojs/components';
|
||||
import Taro from '@tarojs/taro';
|
||||
import { useAuthStore } from '../../../stores/auth';
|
||||
import { invalidateHeadersCache, clearRequestCache } from '@/services/request';
|
||||
import { useElderClass } from '../../../hooks/useElderClass';
|
||||
import './index.scss';
|
||||
|
||||
@@ -35,6 +36,8 @@ export default function Settings() {
|
||||
),
|
||||
);
|
||||
|
||||
clearRequestCache();
|
||||
invalidateHeadersCache();
|
||||
Taro.showToast({ title: '缓存已清除', icon: 'success' });
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user