Files
hms/apps/miniprogram/src/pages/pkg-health/alerts/index.tsx
iven 1fd2c7a533 refactor(mp): 架构重构 — usePageData 统一数据加载 + Store 解耦 + 大页面拆分
新增 usePageData hook(useDidShow 节流 + usePullDownRefresh + loadingRef 防重入 + enabled 条件守卫),
44/58 页面迁移接入,消灭 4 种数据加载模式并存。

- 新增 hooks/usePageData.ts — 统一页面数据加载生命周期
- 新增 stores/index.ts — resetAllStores() 解耦 auth↔health store 依赖
- 新增 pages/index/useHomeData.ts — 首页数据 hook(424→282 行)
- 新增 pages/health/useHealthData.ts — 健康页数据 hook(422→254 行)
- 44 个页面迁移到 usePageData(9 患者端 + 15 医生端 + 20 子包)
- auth store logout 不再直接导入 health store

构建通过,测试 74/75(1 个预存失败)。
2026-05-15 01:13:01 +08:00

133 lines
4.3 KiB
TypeScript

import React, { useState, useCallback } from 'react';
import { View, Text } from '@tarojs/components';
import Taro from '@tarojs/taro';
import { usePageData } from '@/hooks/usePageData';
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 }> = {
info: { label: '提示', className: 'sev-info' },
warning: { label: '警告', className: 'sev-warning' },
critical: { label: '严重', className: 'sev-critical' },
urgent: { label: '紧急', className: 'sev-urgent' },
};
const STATUS_TABS = [
{ key: '', label: '全部' },
{ key: 'pending', label: '待处理' },
{ key: 'acknowledged', label: '已确认' },
{ key: 'resolved', label: '已恢复' },
];
export default function PatientAlerts() {
const modeClass = useElderClass();
const currentPatient = useAuthStore((s) => s.currentPatient);
const [alerts, setAlerts] = useState<Alert[]>([]);
const [total, setTotal] = useState(0);
const [page, setPage] = useState(1);
const [status, setStatus] = useState('');
const [loading, setLoading] = useState(false);
const fetchAlerts = useCallback(
async (pageNum: number, s: string, isRefresh = false) => {
if (!currentPatient) return;
setLoading(true);
try {
const res = await listPatientAlerts(currentPatient.id, {
page: pageNum,
page_size: 20,
status: s || undefined,
});
const list = res.data || [];
if (isRefresh) {
setAlerts(list);
} else {
setAlerts((prev) => [...prev, ...list]);
}
setTotal(res.total);
setPage(pageNum);
} catch {
Taro.showToast({ title: '加载失败', icon: 'none' });
} finally {
setLoading(false);
}
},
[currentPatient],
);
usePageData(
async () => {
Taro.setNavigationBarTitle({ title: '健康告警' });
await fetchAlerts(1, status, true);
},
{ throttleMs: 10000, enablePullDown: true },
);
const handleTabChange = (key: string) => {
setStatus(key);
fetchAlerts(1, key, true);
};
if (!currentPatient) {
return (
<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' })}>
<Text className='alerts-empty-action-text'></Text>
</View>
</View>
</View>
);
}
return (
<View className={`alerts-page ${modeClass}`}>
<View className='alerts-tabs'>
{STATUS_TABS.map((tab) => (
<View
key={tab.key}
className={`alerts-tab ${status === tab.key ? 'active' : ''}`}
onClick={() => handleTabChange(tab.key)}
>
<Text className={`alerts-tab-text ${status === tab.key ? 'active' : ''}`}>{tab.label}</Text>
</View>
))}
</View>
{alerts.length === 0 && !loading ? (
<View className='alerts-empty'>
<Text className='alerts-empty-text'></Text>
<Text className='alerts-empty-hint'></Text>
</View>
) : (
<View className='alerts-list'>
{alerts.map((item) => {
const sev = SEVERITY_MAP[item.severity] || SEVERITY_MAP.warning;
return (
<View className='alert-card' key={item.id}>
<View className='alert-header'>
<View className={`alert-badge ${sev.className}`}>
<Text className='alert-badge-text'>{sev.label}</Text>
</View>
<Text className='alert-time'>
{new Date(item.created_at).toLocaleDateString()}
</Text>
</View>
<Text className='alert-title'>{item.title}</Text>
</View>
);
})}
{loading && <Loading />}
{!loading && alerts.length >= total && total > 0 && (
<Loading text='没有更多了' />
)}
</View>
)}
</View>
);
}