fix(mp): T40 UI 审计修复 — 28 项设计系统合规 + 安全加固 + 讨论记录

T40 UI 审计修复(60 页面全覆盖):
- 新增 $acc-d/$wrn-d 渐变中间色变量,修复首页轮播渐变硬编码
- 替换 8 处裸 white 为 $white 设计变量(5 个 SCSS 文件)
- 修复 7 处触摸目标 40/44px → 48px(健康/消息/咨询/预约/首页)
- 3 页面新增 Loading 状态(体征录入/个人中心/就诊人添加)
- statusTag 移除硬编码布局值,改用 SCSS mixin 控制
- 医生端 14 页面架构 Hook 层补充(useThrottledDidShow 替换 useEffect)
- 移除 action-inbox 未使用 import

安全 P0 修复:
- JWT 中间件加固:token 类型校验 + 过期预检 + 类型别名简化
- 速率限制增强:滑动窗口 + 暴力破解防护
- analytics handler 错误处理完善

文档:
- T40 审计报告(24 PASS / 36 PASS_WITH_ISSUES / 0 NEEDS_WORK)
- 5 份 DevTools/性能审计讨论记录
- wiki 症状导航 + 小程序章节更新
This commit is contained in:
iven
2026-05-14 23:12:54 +08:00
parent 447126b6c5
commit 8f353946e1
90 changed files with 2089 additions and 830 deletions

View File

@@ -1,6 +1,7 @@
import { useState } from 'react';
import { View, Text, Input, Picker } from '@tarojs/components';
import Taro, { useDidShow } from '@tarojs/taro';
import Taro from '@tarojs/taro';
import { useThrottledDidShow } from '@/hooks/useThrottledDidShow';
import { num, validateStr } from '@/utils/validate';
import { inputVitalSign, getHealthThresholds, findThreshold, DEFAULT_THRESHOLDS, type HealthThreshold } from '../../../services/health';
import { useAuthStore } from '../../../stores/auth';
@@ -9,6 +10,7 @@ import { usePointsStore } from '@/stores/points';
import { clearRequestCache } from '@/services/request';
import { trackEvent } from '@/services/analytics';
import { useElderClass } from '../../../hooks/useElderClass';
import Loading from '../../../components/Loading';
import './index.scss';
const INDICATORS = [
@@ -59,12 +61,14 @@ export default function HealthInput() {
const [diastolic, setDiastolic] = useState('');
const [note, setNote] = useState('');
const [submitting, setSubmitting] = useState(false);
const { currentPatient } = useAuthStore();
const { clearCache } = useHealthStore();
const [loadingThresholds, setLoadingThresholds] = useState(true);
const currentPatient = useAuthStore((s) => s.currentPatient);
const clearCache = useHealthStore((s) => s.clearCache);
/** 从 storage 中读取设备同步回传的数据并自动填充表单 */
useDidShow(() => {
getHealthThresholds().then((t) => { if (t.length > 0) setThresholds(t); });
useThrottledDidShow(() => {
setLoadingThresholds(true);
getHealthThresholds().then((t) => { if (t.length > 0) setThresholds(t); }).finally(() => setLoadingThresholds(false));
try {
const raw = Taro.getStorageSync('device_sync_result');
if (!raw) return;
@@ -88,7 +92,7 @@ export default function HealthInput() {
} catch {
// 解析失败则忽略,不影响正常使用
}
});
}, 10000);
const handleSubmit = async () => {
if (!currentPatient) {
@@ -164,6 +168,10 @@ export default function HealthInput() {
return (
<View className={`input-page ${modeClass}`}>
{loadingThresholds && <Loading />}
{!loadingThresholds && (
<>
{/* 页面标题 */}
<View className='input-hero'>
<View className='input-hero-icon'>
@@ -267,6 +275,8 @@ export default function HealthInput() {
>
<Text className='input-submit-text'>{submitting ? '提交中...' : '提交录入'}</Text>
</View>
</>
)}
</View>
);
}