Files
hms/apps/miniprogram/src/pages/pkg-doctor-clinical/prescription/index.tsx
iven d576b8ba8f fix(mp): 空 catch 块添加 console.warn 日志(82 处)
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 断连清理、用户拒绝订阅等合理忽略场景
2026-05-21 13:44:13 +08:00

178 lines
6.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useState, useEffect, useCallback, useRef } from 'react';
import { View, Text } from '@tarojs/components';
import Taro, { useRouter } from '@tarojs/taro';
import { usePageData } from '@/hooks/usePageData';
import { listDialysisPrescriptions, type DialysisPrescription } from '@/services/doctor/dialysis';
import { listPatients } from '@/services/doctor/patient';
import PageShell from '@/components/ui/PageShell';
import ContentCard from '@/components/ui/ContentCard';
import StatusTag from '@/components/ui/StatusTag';
import LoadingCard from '@/components/ui/LoadingCard';
import SearchSection from '@/components/patterns/SearchSection';
import PaginationBar from '@/components/patterns/PaginationBar';
import SegmentTabs from '@/components/SegmentTabs';
import ErrorState from '@/components/ErrorState';
import EmptyState from '@/components/EmptyState';
import { useDoctorClass } from '@/hooks/useDoctorClass';
import { safeNavigateTo } from '@/utils/navigate';
import './index.scss';
const TABS = [
{ key: '', label: '全部' },
{ key: 'active', label: '生效中' },
{ key: 'inactive', label: '已停用' },
];
const STATUS_LABEL: Record<string, string> = {
active: '生效中',
inactive: '已停用',
};
export default function PrescriptionList() {
const router = useRouter();
const patientId = router.params.patientId || '';
const modeClass = useDoctorClass();
const [searchPatient, setSearchPatient] = useState('');
const [currentPatientId, setCurrentPatientId] = useState(patientId);
const [activeTab, setActiveTab] = useState('');
const [prescriptions, setPrescriptions] = useState<DialysisPrescription[]>([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(false);
const [total, setTotal] = useState(0);
const [page, setPage] = useState(1);
const mountedRef = useRef(false);
const loadData = useCallback(async (p: number) => {
setLoading(true);
setError(false);
try {
const res = await listDialysisPrescriptions({
patient_id: currentPatientId || undefined,
status: activeTab || undefined,
page: p,
page_size: 20,
});
setPrescriptions(res.data || []);
setTotal(res.total || 0);
setPage(p);
} catch (err) {
console.warn('[doctor-prescription] 加载数据失败:', err);
setError(true);
Taro.showToast({ title: '加载失败', icon: 'none' });
} finally {
setLoading(false);
}
}, [currentPatientId, activeTab]);
usePageData(
useCallback(() => loadData(1), [loadData]),
);
// tab/patientId 变化时重新加载(跳过首次 mount由 usePageData 的 useDidShow 处理)
useEffect(() => {
if (mountedRef.current) {
loadData(1);
}
mountedRef.current = true;
}, [currentPatientId, activeTab, loadData]);
const handleSearch = async () => {
if (!searchPatient.trim()) return;
setLoading(true);
try {
const res = await listPatients({ search: searchPatient.trim(), page: 1, page_size: 1 });
if (res.data && res.data.length > 0) {
setCurrentPatientId(res.data[0].id);
} else {
Taro.showToast({ title: '未找到患者', icon: 'none' });
}
} catch (err) {
console.warn('[doctor-prescription] 搜索失败:', err);
Taro.showToast({ title: '搜索失败', icon: 'none' });
} finally {
setLoading(false);
}
};
const handleTab = (key: string) => {
setActiveTab(key);
setPage(1);
};
if (loading && prescriptions.length === 0) return <LoadingCard count={3} />;
if (error) return <ErrorState onRetry={() => loadData(1)} />;
return (
<PageShell safeBottom className={modeClass}>
{!patientId ? (
<SearchSection
value={searchPatient}
onChange={setSearchPatient}
onSearch={handleSearch}
placeholder="搜索患者姓名"
filters={TABS}
activeFilter={activeTab}
onFilterChange={handleTab}
/>
) : (
<SegmentTabs tabs={TABS} activeKey={activeTab} onChange={handleTab} variant="underline" />
)}
{prescriptions.length === 0 ? (
<EmptyState text="暂无透析处方" />
) : (
<>
<View className="prescription-count">
<Text> {total} </Text>
</View>
<View className="prescription-cards">
{prescriptions.map((p) => (
<ContentCard
key={p.id}
onPress={() => safeNavigateTo(`/pages/pkg-doctor-clinical/prescription/detail/index?id=${p.id}`)}
>
<View className="prescription-card__header">
<Text className="prescription-card__model">{p.dialyzer_model || '透析处方'}</Text>
<StatusTag status={p.status} size="sm">{STATUS_LABEL[p.status] || p.status}</StatusTag>
</View>
<View className="prescription-card__body">
{p.frequency_per_week != null && (
<Text className="prescription-card__meta">{p.frequency_per_week}/</Text>
)}
{p.duration_minutes != null && (
<Text className="prescription-card__meta">{p.duration_minutes}</Text>
)}
</View>
{(p.effective_from || p.effective_to) && (
<Text className="prescription-card__date">
{p.effective_from || '...'} ~ {p.effective_to || '...'}
</Text>
)}
</ContentCard>
))}
</View>
<PaginationBar
current={page}
total={total}
pageSize={20}
onChange={(p) => loadData(p)}
/>
</>
)}
<View
className="fab"
onClick={() => {
if (!currentPatientId) {
Taro.showToast({ title: '请先选择患者', icon: 'none' });
return;
}
safeNavigateTo(`/pages/pkg-doctor-clinical/prescription/create/index?patientId=${currentPatientId}`);
}}
>
<Text className="fab-text">+</Text>
</View>
</PageShell>
);
}