55 个文件中 82 处空 catch 块添加模块前缀日志输出: - stores: auth/health/points (7 处) - services: request/ai-chat/health/ble/* (10 处) - hooks: useLongPolling/usePagination (3 处) - pages: 核心+子包共 35 个页面 (62 处) 保留静默的 catch: secure-storage fallback、Storage 恢复、 analytics 防洪、BLE 断连清理、用户拒绝订阅等合理忽略场景
109 lines
3.6 KiB
TypeScript
109 lines
3.6 KiB
TypeScript
import React, { useState, useCallback } from 'react';
|
|
import { View, Text } from '@tarojs/components';
|
|
import Taro, { useReachBottom } from '@tarojs/taro';
|
|
import { safeNavigateTo } from '@/utils/navigate';
|
|
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';
|
|
import { useElderClass } from '../../../hooks/useElderClass';
|
|
import PageShell from '@/components/ui/PageShell';
|
|
import './index.scss';
|
|
|
|
export default function MyReports() {
|
|
const modeClass = useElderClass();
|
|
const [reports, setReports] = useState<LabReport[]>([]);
|
|
const [page, setPage] = useState(1);
|
|
const [total, setTotal] = useState(0);
|
|
const [loading, setLoading] = useState(false);
|
|
const [hasPatient, setHasPatient] = useState(true);
|
|
|
|
const fetchData = useCallback(async (p: number, append = false) => {
|
|
const patientId = getCachedPatientId();
|
|
if (!patientId) {
|
|
setReports([]);
|
|
setHasPatient(false);
|
|
return;
|
|
}
|
|
setHasPatient(true);
|
|
setLoading(true);
|
|
try {
|
|
const res = await listReports(patientId, p);
|
|
const list = res.data || [];
|
|
setReports(append ? (prev) => [...prev, ...list] : list);
|
|
setTotal(res.total);
|
|
setPage(p);
|
|
} catch (err) {
|
|
console.warn('[reports] 加载报告列表失败:', err);
|
|
Taro.showToast({ title: '加载失败', icon: 'none' });
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
usePageData(async () => { await fetchData(1); }, { throttleMs: 10000, enablePullDown: true });
|
|
|
|
useReachBottom(() => {
|
|
if (!loading && reports.length < total) {
|
|
fetchData(page + 1, true);
|
|
}
|
|
});
|
|
|
|
const goToDetail = (id: string) => {
|
|
safeNavigateTo(`/pages/pkg-profile/reports/detail/index?id=${id}`);
|
|
};
|
|
|
|
const formatStatus = (report: LabReport) => {
|
|
const items = report.items;
|
|
if (!items || !Array.isArray(items)) return 'unknown';
|
|
const vals = items as Array<{ is_abnormal?: boolean }>;
|
|
const hasAbnormal = vals.some((v) => v.is_abnormal);
|
|
return hasAbnormal ? 'abnormal' : 'normal';
|
|
};
|
|
|
|
const typeInitial = (type: string) => {
|
|
return type ? type.charAt(0) : '报';
|
|
};
|
|
|
|
return (
|
|
<PageShell className={modeClass}>
|
|
<Text className='page-title'>检查报告</Text>
|
|
|
|
<View className='report-list'>
|
|
{reports.map((r) => {
|
|
const status = formatStatus(r);
|
|
return (
|
|
<View
|
|
className='report-card'
|
|
key={r.id}
|
|
onClick={() => goToDetail(r.id)}
|
|
>
|
|
<View className='report-card-top'>
|
|
<View className='report-type-row'>
|
|
<View className='report-avatar'>
|
|
<Text className='report-avatar-text'>{typeInitial(r.report_type)}</Text>
|
|
</View>
|
|
<Text className='report-type'>{r.report_type}</Text>
|
|
</View>
|
|
<Text className={`report-status ${status}`}>
|
|
{status === 'normal' ? '正常' : status === 'abnormal' ? '异常' : '未知'}
|
|
</Text>
|
|
</View>
|
|
<Text className='report-date'>{r.report_date}</Text>
|
|
</View>
|
|
);
|
|
})}
|
|
</View>
|
|
|
|
{reports.length === 0 && !loading && (
|
|
<EmptyState text={hasPatient ? '暂无报告记录' : '请先在就诊人管理中选择就诊人'} />
|
|
)}
|
|
|
|
{loading && (
|
|
<Loading />
|
|
)}
|
|
</PageShell>
|
|
);
|
|
}
|