feat(miniprogram): 关怀模式 Phase 2 — Design Token + 15 页面批量接入
Some checks failed
CI / rust-check (push) Has been cancelled
CI / rust-test (push) Has been cancelled
CI / frontend-build (push) Has been cancelled
CI / security-audit (push) Has been cancelled

- 新建 useElderClass hook,替代每页 3 行样板代码
- 新建 CSS 自定义属性 Design Token 系统(tokens.scss)
  正常/关怀两套值:字号、间距、触控、布局参数
- 15 个页面批量接入关怀模式 class:
  TabBar: 商城页
  主流程: 预约列表/详情/创建、咨询详情
  子包: 体征录入/趋势/日常监测/告警、用药/档案/随访/报告/家庭/设置
- 新建 elder-toast 工具(关怀模式 3s + 触觉反馈)
- 页面覆盖率:4/59 → 22/59 (37%)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
iven
2026-05-09 22:17:58 +08:00
parent 4335f7e144
commit e8ccee02d5
22 changed files with 209 additions and 63 deletions

View File

@@ -4,6 +4,7 @@ import Taro, { useDidShow, usePullDownRefresh } from '@tarojs/taro';
import { listPatientAlerts, type Alert } from '@/services/alert';
import { useAuthStore } from '@/stores/auth';
import Loading from '@/components/Loading';
import { useElderClass } from '../../../hooks/useElderClass';
import './index.scss';
const SEVERITY_MAP: Record<string, { label: string; className: string }> = {
@@ -21,6 +22,7 @@ const STATUS_TABS = [
];
export default function PatientAlerts() {
const modeClass = useElderClass();
const { currentPatient } = useAuthStore();
const [alerts, setAlerts] = useState<Alert[]>([]);
const [total, setTotal] = useState(0);
@@ -74,7 +76,7 @@ export default function PatientAlerts() {
if (!currentPatient) {
return (
<View className='alerts-page'>
<View className={`alerts-page ${modeClass}`}>
<View className='alerts-empty'>
<Text className='alerts-empty-text'></Text>
<View className='alerts-empty-action' onClick={() => Taro.navigateTo({ url: '/pages/pkg-profile/family-add/index' })}>
@@ -86,7 +88,7 @@ export default function PatientAlerts() {
}
return (
<View className='alerts-page'>
<View className={`alerts-page ${modeClass}`}>
<View className='alerts-tabs'>
{STATUS_TABS.map((tab) => (
<View

View File

@@ -8,6 +8,7 @@ import { useHealthStore } from '@/stores/health';
import { usePointsStore } from '@/stores/points';
import { clearRequestCache } from '@/services/request';
import { trackEvent } from '@/services/analytics';
import { useElderClass } from '../../../hooks/useElderClass';
import './index.scss';
const bpSchema = z.number().min(30, '血压值不能低于30').max(300, '血压值不能高于300').optional();
@@ -58,6 +59,7 @@ const FIELD_LABELS: Record<string, string> = {
};
export default function DailyMonitoring() {
const modeClass = useElderClass();
const { currentPatient } = useAuthStore();
const today = formatDate(new Date());
@@ -258,7 +260,7 @@ export default function DailyMonitoring() {
const bloodSugarAbnormal = checkAbnormal(bloodSugar, 'bloodSugar');
return (
<View className='dm-page'>
<View className={`dm-page ${modeClass}`}>
{/* 页面标题 */}
<View className='dm-hero'>
<View className='dm-hero-icon'>

View File

@@ -8,6 +8,7 @@ import { useHealthStore } from '@/stores/health';
import { usePointsStore } from '@/stores/points';
import { clearRequestCache } from '@/services/request';
import { trackEvent } from '@/services/analytics';
import { useElderClass } from '../../../hooks/useElderClass';
import './index.scss';
const INDICATORS = [
@@ -56,6 +57,7 @@ function getWarnForIndicator(
}
export default function HealthInput() {
const modeClass = useElderClass();
const [indicatorIdx, setIndicatorIdx] = useState(0);
const [thresholds, setThresholds] = useState<HealthThreshold[]>(DEFAULT_THRESHOLDS);
const [value, setValue] = useState('');
@@ -155,7 +157,7 @@ export default function HealthInput() {
const indicatorInitial = INDICATORS[indicatorIdx].label.charAt(0);
return (
<View className='input-page'>
<View className={`input-page ${modeClass}`}>
{/* 页面标题 */}
<View className='input-hero'>
<View className='input-hero-icon'>

View File

@@ -3,6 +3,7 @@ import { View, Text } from '@tarojs/components';
import { useRouter } from '@tarojs/taro';
import { useHealthStore } from '@/stores/health';
import TrendChart from '@/components/TrendChart';
import { useElderClass } from '../../../hooks/useElderClass';
import './index.scss';
const RANGE_OPTIONS = [
@@ -22,6 +23,7 @@ const INDICATOR_META: Record<string, { label: string; unit: string; refMin?: num
};
export default function Trend() {
const modeClass = useElderClass();
const router = useRouter();
const indicator = router.params.indicator || 'heart_rate';
const [range, setRange] = useState('7d');
@@ -41,7 +43,7 @@ export default function Trend() {
};
return (
<View className='trend-page'>
<View className={`trend-page ${modeClass}`}>
{/* 页面标题 */}
<View className='trend-hero'>
<View className='trend-hero-icon'>