fix(mp): 小程序页面优化 + E2E 测试报告更新

- 小程序各页面优化和修复
- 更新联调报告和 E2E 测试报告
- 更新 miniprogram wiki
This commit is contained in:
iven
2026-05-15 23:03:21 +08:00
parent ced1c0ad0c
commit c06e986090
24 changed files with 905 additions and 441 deletions

View File

@@ -4,7 +4,9 @@ import Taro from '@tarojs/taro';
import { usePageData } from '@/hooks/usePageData';
import { listAlerts, type Alert } from '@/services/doctor/alerts';
import Loading from '@/components/Loading';
import ErrorState from '@/components/ErrorState';
import EmptyState from '@/components/EmptyState';
import SegmentTabs from '@/components/SegmentTabs';
import { useElderClass } from '../../../hooks/useElderClass';
import { safeNavigateTo } from '@/utils/navigate';
import './index.scss';
@@ -34,6 +36,7 @@ export default function AlertList() {
const modeClass = useElderClass();
const [alerts, setAlerts] = useState<Alert[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(false);
const [activeTab, setActiveTab] = useState('');
const [total, setTotal] = useState(0);
const [page, setPage] = useState(1);
@@ -43,6 +46,7 @@ export default function AlertList() {
const loadAlerts = useCallback(async () => {
setLoading(true);
setError(false);
try {
const res = await listAlerts({
status: activeTab || undefined,
@@ -52,6 +56,7 @@ export default function AlertList() {
setAlerts(res.data || []);
setTotal(res.total || 0);
} catch {
setError(true);
Taro.showToast({ title: '加载失败', icon: 'none' });
} finally {
setLoading(false);
@@ -91,6 +96,28 @@ export default function AlertList() {
if (loading && alerts.length === 0) return <Loading />;
if (error) {
return (
<ScrollView scrollY className={`alert-list-page ${modeClass}`}>
<View className='alert-list-header'>
<Text className='alert-list-title'></Text>
</View>
<View className='alert-tabs'>
{STATUS_TABS.map((tab) => (
<Text
key={tab.value}
className={`alert-tab ${activeTab === tab.value ? 'alert-tab--active' : ''}`}
onClick={() => handleTabChange(tab.value)}
>
{tab.label}
</Text>
))}
</View>
<ErrorState onRetry={loadAlerts} />
</ScrollView>
);
}
return (
<ScrollView scrollY className={`alert-list-page ${modeClass}`}>
<View className='alert-list-header'>
@@ -98,17 +125,7 @@ export default function AlertList() {
<Text className='alert-list-count'> {total} </Text>
</View>
<View className='alert-tabs'>
{STATUS_TABS.map((tab) => (
<Text
key={tab.value}
className={`alert-tab ${activeTab === tab.value ? 'alert-tab--active' : ''}`}
onClick={() => handleTabChange(tab.value)}
>
{tab.label}
</Text>
))}
</View>
<SegmentTabs tabs={STATUS_TABS.map(t => ({ key: t.value, label: t.label }))} activeKey={activeTab} onChange={handleTabChange} variant="pill" />
{alerts.length === 0 ? (
<EmptyState description='暂无告警' />

View File

@@ -5,10 +5,12 @@ import { usePageData } from '@/hooks/usePageData';
import { listDialysisRecords, type DialysisRecord } from '@/services/doctor/dialysis';
import { listPatients } from '@/services/doctor/patient';
import Loading from '@/components/Loading';
import ErrorState from '@/components/ErrorState';
import EmptyState from '@/components/EmptyState';
import { useElderClass } from '../../../hooks/useElderClass';
import { safeNavigateTo } from '@/utils/navigate';
import './index.scss';
import SegmentTabs from '@/components/SegmentTabs';
import './index.scss';;
const TABS = [
{ key: '', label: '全部' },
@@ -28,6 +30,7 @@ export default function DialysisList() {
const [activeTab, setActiveTab] = useState('');
const [records, setRecords] = useState<DialysisRecord[]>([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(false);
const [total, setTotal] = useState(0);
const [page, setPage] = useState(1);
const mountedRef = useRef(false);
@@ -35,6 +38,7 @@ export default function DialysisList() {
const loadRecords = useCallback(async (p: number) => {
if (!currentPatientId) return;
setLoading(true);
setError(false);
try {
const params: { page: number; page_size: number; status?: string } = { page: p, page_size: 20 };
if (activeTab) params.status = activeTab;
@@ -43,6 +47,7 @@ export default function DialysisList() {
setTotal(res.total || 0);
setPage(p);
} catch {
setError(true);
Taro.showToast({ title: '加载失败', icon: 'none' });
} finally {
setLoading(false);
@@ -88,6 +93,7 @@ export default function DialysisList() {
// 服务端已按 activeTab 过滤,无需客户端二次筛选
if (loading && records.length === 0) return <Loading />;
if (error) return <ErrorState onRetry={() => loadRecords(1)} />;
return (
<ScrollView scrollY className={`dialysis-page ${modeClass}`}>
@@ -104,17 +110,7 @@ export default function DialysisList() {
</View>
)}
<View className='tabs'>
{TABS.map((t) => (
<View
key={t.key}
className={`tab ${activeTab === t.key ? 'tab--active' : ''}`}
onClick={() => handleTab(t.key)}
>
<Text className='tab-text'>{t.label}</Text>
</View>
))}
</View>
<SegmentTabs tabs={TABS} activeKey={activeTab} onChange={handleTab} variant="underline" />
{!currentPatientId ? (
<EmptyState text='请搜索并选择患者' />

View File

@@ -5,9 +5,11 @@ import { usePageData } from '@/hooks/usePageData';
import { listDialysisPrescriptions, type DialysisPrescription } from '@/services/doctor/dialysis';
import { listPatients } from '@/services/doctor/patient';
import Loading from '@/components/Loading';
import ErrorState from '@/components/ErrorState';
import EmptyState from '@/components/EmptyState';
import { useElderClass } from '../../../hooks/useElderClass';
import { safeNavigateTo } from '@/utils/navigate';
import SegmentTabs from '@/components/SegmentTabs';
import './index.scss';
const TABS = [
@@ -25,12 +27,14 @@ export default function PrescriptionList() {
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,
@@ -42,6 +46,7 @@ export default function PrescriptionList() {
setTotal(res.total || 0);
setPage(p);
} catch {
setError(true);
Taro.showToast({ title: '加载失败', icon: 'none' });
} finally {
setLoading(false);
@@ -78,6 +83,7 @@ export default function PrescriptionList() {
};
if (loading && prescriptions.length === 0) return <Loading />;
if (error) return <ErrorState onRetry={() => loadData(1)} />;
return (
<ScrollView scrollY className={`prescription-page ${modeClass}`}>
@@ -94,17 +100,7 @@ export default function PrescriptionList() {
</View>
)}
<View className='tabs'>
{TABS.map((t) => (
<View
key={t.key}
className={`tab ${activeTab === t.key ? 'tab--active' : ''}`}
onClick={() => { setActiveTab(t.key); setPage(1); }}
>
<Text className='tab-text'>{t.label}</Text>
</View>
))}
</View>
<SegmentTabs tabs={TABS} activeKey={activeTab} onChange={(key) => { setActiveTab(key); setPage(1); }} variant="underline" />
{prescriptions.length === 0 ? (
<EmptyState text='暂无透析处方' />

View File

@@ -5,6 +5,7 @@ import { usePageData } from '@/hooks/usePageData';
import { listLabReports, type LabReportItem } from '@/services/doctor/labReport';
import { listPatients } from '@/services/doctor/patient';
import Loading from '@/components/Loading';
import ErrorState from '@/components/ErrorState';
import EmptyState from '@/components/EmptyState';
import { useElderClass } from '../../../hooks/useElderClass';
import './index.scss';
@@ -17,17 +18,20 @@ export default function ReportList() {
const [currentPatientId, setCurrentPatientId] = useState(patientId);
const [reports, setReports] = useState<LabReportItem[]>([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(false);
const [total, setTotal] = useState(0);
const mountedRef = useRef(false);
const loadReports = useCallback(async () => {
if (!currentPatientId) return;
setLoading(true);
setError(false);
try {
const res = await listLabReports(currentPatientId, { page: 1, page_size: 50 });
setReports(res.data || []);
setTotal(res.total || 0);
} catch {
setError(true);
Taro.showToast({ title: '加载失败', icon: 'none' });
} finally {
setLoading(false);
@@ -65,6 +69,7 @@ export default function ReportList() {
const formatDate = (d: string) => new Date(d).toLocaleDateString('zh-CN');
if (loading && reports.length === 0) return <Loading />;
if (error) return <ErrorState onRetry={loadReports} />;
return (
<ScrollView scrollY className={`report-page ${modeClass}`}>