refactor(mp): 迁移报告列表页 — 使用统一组件库

- PageShell 替代手写 ScrollView + min-height/bg/padding
- SearchSection 替代搜索栏
- ContentCard 替代 report-card 手写样式
- StatusTag 替代 report-card__reviewed 手写标签
- LoadingCard 替代 Loading 组件
- 精简 SCSS:删除 page/search-bar/card 通用样式,保留业务特有样式
This commit is contained in:
iven
2026-05-16 00:56:18 +08:00
parent 3e88dcaba5
commit ae23baeece
2 changed files with 84 additions and 115 deletions

View File

@@ -1,26 +1,9 @@
@import '../../../styles/variables.scss'; @import '../../../styles/variables.scss';
@import '../../../styles/mixins.scss';
.report-page { // PageShell 已接管min-height, background, padding
min-height: 100vh; // SearchSection 已接管search-bar
background: $bg; // ContentCard 已接管report-card 背景/圆角/阴影/触摸反馈
padding: 24px; // StatusTag 已接管reviewed 标签样式
padding-bottom: 120px;
}
.search-bar {
margin-bottom: 20px;
.search-input {
background: $card;
border-radius: $r;
padding: 20px 24px;
font-size: var(--tk-font-body-lg);
width: 100%;
box-sizing: border-box;
box-shadow: $shadow-sm;
}
}
.report-count { .report-count {
margin-bottom: 16px; margin-bottom: 16px;
@@ -31,59 +14,44 @@
} }
} }
.report-list { .report-cards {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: var(--tk-gap-md);
}
.report-card__header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
}
.report-card__type {
font-family: 'Georgia', 'Times New Roman', serif;
font-size: var(--tk-font-body-lg);
font-weight: 600;
color: $tx;
}
.report-card__date {
font-size: var(--tk-font-h2);
color: $tx3;
}
.report-card__indicators {
display: flex;
align-items: center;
gap: 16px; gap: 16px;
} }
.report-card { .report-card__abnormal {
background: $card; font-size: var(--tk-font-h1);
border-radius: $r-lg; color: $dan;
padding: 28px; font-weight: 600;
box-shadow: $shadow-sm; }
&:active { .report-card__normal {
background: $bd-l; font-size: var(--tk-font-h1);
} color: $acc;
&__header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
}
&__type {
font-family: 'Georgia', 'Times New Roman', serif;
font-size: var(--tk-font-body-lg);
font-weight: 600;
color: $tx;
}
&__date {
font-size: var(--tk-font-h2);
color: $tx3;
}
&__indicators {
display: flex;
align-items: center;
gap: 16px;
}
&__abnormal {
font-size: var(--tk-font-h1);
color: $dan;
font-weight: 600;
}
&__normal {
font-size: var(--tk-font-h1);
color: $acc;
}
&__reviewed {
@include tag($acc-l, $acc);
}
} }

View File

@@ -1,10 +1,14 @@
import { useState, useEffect, useCallback, useRef } from 'react'; import { useState, useEffect, useCallback, useRef } from 'react';
import { View, Text, Input, ScrollView } from '@tarojs/components'; import { View, Text } from '@tarojs/components';
import Taro, { useRouter } from '@tarojs/taro'; import Taro, { useRouter } from '@tarojs/taro';
import { usePageData } from '@/hooks/usePageData'; import { usePageData } from '@/hooks/usePageData';
import { listLabReports, type LabReportItem } from '@/services/doctor/labReport'; import { listLabReports, type LabReportItem } from '@/services/doctor/labReport';
import { listPatients } from '@/services/doctor/patient'; import { listPatients } from '@/services/doctor/patient';
import Loading from '@/components/Loading'; 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 ErrorState from '@/components/ErrorState'; import ErrorState from '@/components/ErrorState';
import EmptyState from '@/components/EmptyState'; import EmptyState from '@/components/EmptyState';
import { useElderClass } from '../../../hooks/useElderClass'; import { useElderClass } from '../../../hooks/useElderClass';
@@ -68,59 +72,56 @@ export default function ReportList() {
const formatDate = (d: string) => new Date(d).toLocaleDateString('zh-CN'); const formatDate = (d: string) => new Date(d).toLocaleDateString('zh-CN');
if (loading && reports.length === 0) return <Loading />; if (loading && reports.length === 0) return <LoadingCard count={3} />;
if (error) return <ErrorState onRetry={loadReports} />; if (error) return <ErrorState onRetry={loadReports} />;
return ( return (
<ScrollView scrollY className={`report-page ${modeClass}`}> <PageShell safeBottom className={modeClass}>
{!patientId && ( {!patientId && (
<View className='search-bar'> <SearchSection
<Input value={searchPatient}
className='search-input' onChange={setSearchPatient}
placeholder='搜索患者姓名' onSearch={handleSearch}
value={searchPatient} placeholder="搜索患者姓名"
onInput={(e) => setSearchPatient(e.detail.value)} />
confirmType='search'
onConfirm={handleSearch}
/>
</View>
)} )}
{!currentPatientId ? ( {!currentPatientId ? (
<EmptyState text='请搜索并选择患者' /> <EmptyState text="请搜索并选择患者" />
) : reports.length === 0 ? ( ) : reports.length === 0 ? (
<EmptyState text='暂无化验报告' /> <EmptyState text="暂无化验报告" />
) : ( ) : (
<View className='report-list'> <>
<View className='report-count'> <View className="report-count">
<Text> {total} </Text> <Text> {total} </Text>
</View> </View>
{reports.map((r) => ( <View className="report-cards">
<View {reports.map((r) => (
key={r.id} <ContentCard
className='report-card' key={r.id}
onClick={() => Taro.navigateTo({ onPress={() => Taro.navigateTo({
url: `/pages/pkg-doctor-clinical/report/detail/index?patientId=${currentPatientId}&id=${r.id}`, url: `/pages/pkg-doctor-clinical/report/detail/index?patientId=${currentPatientId}&id=${r.id}`,
})} })}
> >
<View className='report-card__header'> <View className="report-card__header">
<Text className='report-card__type'>{r.report_type}</Text> <Text className="report-card__type">{r.report_type}</Text>
<Text className='report-card__date'>{formatDate(r.report_date)}</Text> <Text className="report-card__date">{formatDate(r.report_date)}</Text>
</View> </View>
<View className='report-card__indicators'> <View className="report-card__indicators">
{(r.abnormal_count ?? 0) > 0 ? ( {(r.abnormal_count ?? 0) > 0 ? (
<Text className='report-card__abnormal'>{r.abnormal_count} </Text> <Text className="report-card__abnormal">{r.abnormal_count} </Text>
) : ( ) : (
<Text className='report-card__normal'></Text> <Text className="report-card__normal"></Text>
)} )}
{r.status === 'reviewed' && ( {r.status === 'reviewed' && (
<Text className='report-card__reviewed'></Text> <StatusTag status="reviewed" size="sm"></StatusTag>
)} )}
</View> </View>
</View> </ContentCard>
))} ))}
</View> </View>
</>
)} )}
</ScrollView> </PageShell>
); );
} }