refactor(mp): 迁移患者端详情页 — 使用统一组件库 (10/12)
报告详情、随访详情、透析记录详情、透析处方详情页: - View.detail-page → PageShell 替代手写 page 容器 - .detail-card → ContentCard 替代手写卡片样式 - 删除通用 page 容器和 card 样式,保留业务布局样式
This commit is contained in:
@@ -1,28 +1,11 @@
|
||||
@import '../../../../styles/variables.scss';
|
||||
@import '../../../../styles/mixins.scss';
|
||||
|
||||
.detail-page {
|
||||
min-height: 100vh;
|
||||
background: $bg;
|
||||
padding: 24px;
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
|
||||
.detail-card {
|
||||
background: $card;
|
||||
border-radius: $r;
|
||||
padding: 28px;
|
||||
margin-bottom: 20px;
|
||||
box-shadow: $shadow-sm;
|
||||
}
|
||||
|
||||
.header-card {
|
||||
.header-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.header-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.detail-title {
|
||||
|
||||
@@ -5,6 +5,8 @@ import { usePageData } from '@/hooks/usePageData';
|
||||
import { getDialysisPrescription } from '@/services/dialysis';
|
||||
import type { DialysisPrescription } from '@/services/dialysis';
|
||||
import Loading from '@/components/Loading';
|
||||
import PageShell from '@/components/ui/PageShell';
|
||||
import ContentCard from '@/components/ui/ContentCard';
|
||||
import { useElderClass } from '../../../../hooks/useElderClass';
|
||||
import './index.scss';
|
||||
|
||||
@@ -36,8 +38,8 @@ export default function DialysisPrescriptionDetail() {
|
||||
|
||||
usePageData(fetchDetail, { throttleMs: 60000 });
|
||||
|
||||
if (loading) return <View className={`detail-page ${modeClass}`}><Loading /></View>;
|
||||
if (!rx) return <View className={`detail-page ${modeClass}`}><View className='empty-state'><Text className='empty-text'>处方不存在</Text></View></View>;
|
||||
if (loading) return <PageShell className={modeClass}><Loading /></PageShell>;
|
||||
if (!rx) return <PageShell className={modeClass}><View className='empty-state'><Text className='empty-text'>处方不存在</Text></View></PageShell>;
|
||||
|
||||
const si = STATUS_MAP[rx.status] || { label: rx.status, cls: '' };
|
||||
|
||||
@@ -52,9 +54,9 @@ export default function DialysisPrescriptionDetail() {
|
||||
};
|
||||
|
||||
return (
|
||||
<View className={`detail-page ${modeClass}`}>
|
||||
<PageShell className={modeClass}>
|
||||
{/* 状态头部 */}
|
||||
<View className='detail-card header-card'>
|
||||
<ContentCard>
|
||||
<View className='header-row'>
|
||||
<Text className='detail-title'>{rx.dialyzer_model || '透析处方'}</Text>
|
||||
<Text className={`status-tag ${si.cls}`}>{si.label}</Text>
|
||||
@@ -62,10 +64,10 @@ export default function DialysisPrescriptionDetail() {
|
||||
{(rx.effective_from || rx.effective_to) && (
|
||||
<Text className='header-sub'>{rx.effective_from || '...'} ~ {rx.effective_to || '...'}</Text>
|
||||
)}
|
||||
</View>
|
||||
</ContentCard>
|
||||
|
||||
{/* 基本参数 */}
|
||||
<View className='detail-card'>
|
||||
<ContentCard>
|
||||
<Text className='section-title'>基本参数</Text>
|
||||
<Row label='透析器型号' value={rx.dialyzer_model} />
|
||||
<Row label='膜面积' value={rx.membrane_area != null ? `${rx.membrane_area} m²` : null} />
|
||||
@@ -73,48 +75,48 @@ export default function DialysisPrescriptionDetail() {
|
||||
<Row label='透析液流量' value={rx.dialysate_flow_rate != null ? `${rx.dialysate_flow_rate} ml/min` : null} />
|
||||
<Row label='频率' value={rx.frequency_per_week != null ? `${rx.frequency_per_week} 次/周` : null} />
|
||||
<Row label='每次时长' value={rx.duration_minutes != null ? `${rx.duration_minutes} 分钟` : null} />
|
||||
</View>
|
||||
</ContentCard>
|
||||
|
||||
{/* 透析液配比 */}
|
||||
<View className='detail-card'>
|
||||
<ContentCard>
|
||||
<Text className='section-title'>透析液配比</Text>
|
||||
<Row label='钾浓度' value={rx.dialysate_potassium != null ? `${rx.dialysate_potassium} mmol/L` : null} />
|
||||
<Row label='钙浓度' value={rx.dialysate_calcium != null ? `${rx.dialysate_calcium} mmol/L` : null} />
|
||||
<Row label='碳酸氢盐浓度' value={rx.dialysate_bicarbonate != null ? `${rx.dialysate_bicarbonate} mmol/L` : null} />
|
||||
</View>
|
||||
</ContentCard>
|
||||
|
||||
{/* 抗凝方案 */}
|
||||
<View className='detail-card'>
|
||||
<ContentCard>
|
||||
<Text className='section-title'>抗凝方案</Text>
|
||||
<Row label='抗凝类型' value={rx.anticoagulation_type} />
|
||||
<Row label='抗凝剂量' value={rx.anticoagulation_dose} />
|
||||
</View>
|
||||
</ContentCard>
|
||||
|
||||
{/* 血管通路 */}
|
||||
{(rx.vascular_access_type || rx.vascular_access_location) && (
|
||||
<View className='detail-card'>
|
||||
<ContentCard>
|
||||
<Text className='section-title'>血管通路</Text>
|
||||
<Row label='通路类型' value={rx.vascular_access_type} />
|
||||
<Row label='通路位置' value={rx.vascular_access_location} />
|
||||
</View>
|
||||
</ContentCard>
|
||||
)}
|
||||
|
||||
{/* 超滤与干体重 */}
|
||||
{(rx.target_ultrafiltration_ml != null || rx.target_dry_weight != null) && (
|
||||
<View className='detail-card'>
|
||||
<ContentCard>
|
||||
<Text className='section-title'>超滤目标</Text>
|
||||
<Row label='目标超滤量' value={rx.target_ultrafiltration_ml != null ? `${rx.target_ultrafiltration_ml} ml` : null} />
|
||||
<Row label='目标干体重' value={rx.target_dry_weight != null ? `${rx.target_dry_weight} kg` : null} />
|
||||
</View>
|
||||
</ContentCard>
|
||||
)}
|
||||
|
||||
{/* 备注 */}
|
||||
{rx.notes && (
|
||||
<View className='detail-card'>
|
||||
<ContentCard>
|
||||
<Text className='section-title'>备注</Text>
|
||||
<Text className='notes-text'>{rx.notes}</Text>
|
||||
</View>
|
||||
</ContentCard>
|
||||
)}
|
||||
</View>
|
||||
</PageShell>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,28 +1,11 @@
|
||||
@import '../../../../styles/variables.scss';
|
||||
@import '../../../../styles/mixins.scss';
|
||||
|
||||
.detail-page {
|
||||
min-height: 100vh;
|
||||
background: $bg;
|
||||
padding: 24px;
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
|
||||
.detail-card {
|
||||
background: $card;
|
||||
border-radius: $r;
|
||||
padding: 28px;
|
||||
margin-bottom: 20px;
|
||||
box-shadow: $shadow-sm;
|
||||
}
|
||||
|
||||
.header-card {
|
||||
.header-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.header-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.detail-title {
|
||||
|
||||
@@ -5,6 +5,8 @@ import { usePageData } from '@/hooks/usePageData';
|
||||
import { getDialysisRecord } from '@/services/dialysis';
|
||||
import type { DialysisRecord } from '@/services/dialysis';
|
||||
import Loading from '@/components/Loading';
|
||||
import PageShell from '@/components/ui/PageShell';
|
||||
import ContentCard from '@/components/ui/ContentCard';
|
||||
import { useElderClass } from '../../../../hooks/useElderClass';
|
||||
import './index.scss';
|
||||
|
||||
@@ -42,25 +44,25 @@ export default function DialysisRecordDetail() {
|
||||
|
||||
usePageData(fetchDetail, { throttleMs: 60000 });
|
||||
|
||||
if (loading) return <View className={`detail-page ${modeClass}`}><Loading /></View>;
|
||||
if (!record) return <View className={`detail-page ${modeClass}`}><View className='empty-state'><Text className='empty-text'>记录不存在</Text></View></View>;
|
||||
if (loading) return <PageShell className={modeClass}><Loading /></PageShell>;
|
||||
if (!record) return <PageShell className={modeClass}><View className='empty-state'><Text className='empty-text'>记录不存在</Text></View></PageShell>;
|
||||
|
||||
const si = STATUS_MAP[record.status] || { label: record.status, cls: '' };
|
||||
|
||||
return (
|
||||
<View className={`detail-page ${modeClass}`}>
|
||||
<PageShell className={modeClass}>
|
||||
{/* 状态头部 */}
|
||||
<View className='detail-card header-card'>
|
||||
<ContentCard>
|
||||
<View className='header-row'>
|
||||
<Text className='detail-title'>{record.dialysis_date}</Text>
|
||||
<Text className={`status-tag ${si.cls}`}>{si.label}</Text>
|
||||
</View>
|
||||
<Text className='header-sub'>{TYPE_MAP[record.dialysis_type] || record.dialysis_type}</Text>
|
||||
{record.reviewed_at && <Text className='review-info'>审核时间 {record.reviewed_at}</Text>}
|
||||
</View>
|
||||
</ContentCard>
|
||||
|
||||
{/* 基本信息 */}
|
||||
<View className='detail-card'>
|
||||
<ContentCard>
|
||||
<Text className='section-title'>基本信息</Text>
|
||||
{record.start_time && (
|
||||
<View className='detail-row'><Text className='detail-label'>开始时间</Text><Text className='detail-value'>{record.start_time}</Text></View>
|
||||
@@ -77,10 +79,10 @@ export default function DialysisRecordDetail() {
|
||||
{record.ultrafiltration_volume != null && (
|
||||
<View className='detail-row'><Text className='detail-label'>超滤量</Text><Text className='detail-value'>{record.ultrafiltration_volume} ml</Text></View>
|
||||
)}
|
||||
</View>
|
||||
</ContentCard>
|
||||
|
||||
{/* 体重与血压 */}
|
||||
<View className='detail-card'>
|
||||
<ContentCard>
|
||||
<Text className='section-title'>体重与血压</Text>
|
||||
{record.dry_weight != null && (
|
||||
<View className='detail-row'><Text className='detail-label'>干体重</Text><Text className='detail-value'>{record.dry_weight} kg</Text></View>
|
||||
@@ -103,11 +105,11 @@ export default function DialysisRecordDetail() {
|
||||
{record.post_heart_rate != null && (
|
||||
<View className='detail-row'><Text className='detail-label'>透后心率</Text><Text className='detail-value'>{record.post_heart_rate} bpm</Text></View>
|
||||
)}
|
||||
</View>
|
||||
</ContentCard>
|
||||
|
||||
{/* 症状与并发症 */}
|
||||
{(record.symptoms || record.complication_notes) && (
|
||||
<View className='detail-card'>
|
||||
<ContentCard>
|
||||
<Text className='section-title'>症状与并发症</Text>
|
||||
{record.symptoms && Object.keys(record.symptoms).length > 0 && (
|
||||
<View className='detail-row'><Text className='detail-label'>症状</Text><Text className='detail-value'>{JSON.stringify(record.symptoms)}</Text></View>
|
||||
@@ -115,8 +117,8 @@ export default function DialysisRecordDetail() {
|
||||
{record.complication_notes && (
|
||||
<View className='detail-row'><Text className='detail-label'>并发症备注</Text><Text className='detail-value'>{record.complication_notes}</Text></View>
|
||||
)}
|
||||
</View>
|
||||
</ContentCard>
|
||||
)}
|
||||
</View>
|
||||
</PageShell>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,21 +1,6 @@
|
||||
@import '../../../../styles/variables.scss';
|
||||
@import '../../../../styles/mixins.scss';
|
||||
|
||||
.detail-page {
|
||||
min-height: 100vh;
|
||||
background: $bg;
|
||||
padding: 24px;
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
|
||||
.detail-card {
|
||||
background: $card;
|
||||
border-radius: $r;
|
||||
padding: 28px;
|
||||
margin-bottom: 20px;
|
||||
box-shadow: $shadow-sm;
|
||||
}
|
||||
|
||||
.detail-title {
|
||||
@include section-title;
|
||||
font-size: var(--tk-font-num-lg);
|
||||
@@ -79,13 +64,6 @@
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.submit-card {
|
||||
background: $card;
|
||||
border-radius: $r;
|
||||
padding: 28px;
|
||||
box-shadow: $shadow-sm;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
@include section-title;
|
||||
margin-bottom: 16px;
|
||||
|
||||
@@ -8,6 +8,8 @@ import { TEMPLATE_IDS } from '@/services/wechat-templates';
|
||||
import { trackEvent } from '@/services/analytics';
|
||||
import Loading from '@/components/Loading';
|
||||
import ErrorState from '@/components/ErrorState';
|
||||
import PageShell from '@/components/ui/PageShell';
|
||||
import ContentCard from '@/components/ui/ContentCard';
|
||||
import { useElderClass } from '@/hooks/useElderClass';
|
||||
import './index.scss';
|
||||
|
||||
@@ -89,25 +91,25 @@ export default function FollowUpDetail() {
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<View className={`detail-page ${modeClass}`}>
|
||||
<PageShell className={modeClass}>
|
||||
<Loading />
|
||||
</View>
|
||||
</PageShell>
|
||||
);
|
||||
}
|
||||
|
||||
if (error || !task) {
|
||||
return (
|
||||
<View className={`detail-page ${modeClass}`}>
|
||||
<PageShell className={modeClass}>
|
||||
<ErrorState text='任务不存在' />
|
||||
</View>
|
||||
</PageShell>
|
||||
);
|
||||
}
|
||||
|
||||
const isCompleted = task.status === 'completed';
|
||||
|
||||
return (
|
||||
<View className={`detail-page ${modeClass}`}>
|
||||
<View className='detail-card'>
|
||||
<PageShell className={modeClass}>
|
||||
<ContentCard>
|
||||
<Text className='detail-title'>{task.follow_up_type}</Text>
|
||||
<View className='detail-row'>
|
||||
<Text className='detail-label'>状态</Text>
|
||||
@@ -132,10 +134,10 @@ export default function FollowUpDetail() {
|
||||
<Text className='detail-desc-text'>{task.content_template}</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
</ContentCard>
|
||||
|
||||
{!isCompleted && (
|
||||
<View className='submit-card'>
|
||||
<ContentCard>
|
||||
<Text className='section-title'>填写随访记录</Text>
|
||||
<Textarea
|
||||
className='submit-textarea'
|
||||
@@ -152,8 +154,8 @@ export default function FollowUpDetail() {
|
||||
{submitting ? '提交中...' : '提交'}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</ContentCard>
|
||||
)}
|
||||
</View>
|
||||
</PageShell>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,21 +1,6 @@
|
||||
@import '../../../../styles/variables.scss';
|
||||
@import '../../../../styles/mixins.scss';
|
||||
|
||||
.detail-page {
|
||||
min-height: 100vh;
|
||||
background: $bg;
|
||||
padding: 24px;
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
|
||||
.detail-card {
|
||||
background: $card;
|
||||
border-radius: $r;
|
||||
padding: 28px;
|
||||
margin-bottom: 20px;
|
||||
box-shadow: $shadow-sm;
|
||||
}
|
||||
|
||||
.detail-title {
|
||||
font-family: 'Georgia', 'Times New Roman', serif;
|
||||
font-size: var(--tk-font-num-lg);
|
||||
@@ -51,13 +36,6 @@
|
||||
margin-left: 24px;
|
||||
}
|
||||
|
||||
.indicators-card {
|
||||
background: $card;
|
||||
border-radius: $r;
|
||||
padding: 28px;
|
||||
box-shadow: $shadow-sm;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-family: 'Georgia', 'Times New Roman', serif;
|
||||
font-size: var(--tk-font-num);
|
||||
|
||||
@@ -4,6 +4,8 @@ import Taro, { useRouter } from '@tarojs/taro';
|
||||
import { usePageData } from '@/hooks/usePageData';
|
||||
import { getReportDetail, LabReport } from '@/services/report';
|
||||
import Loading from '@/components/Loading';
|
||||
import PageShell from '@/components/ui/PageShell';
|
||||
import ContentCard from '@/components/ui/ContentCard';
|
||||
import { useElderClass } from '@/hooks/useElderClass';
|
||||
import { useAuthStore } from '@/stores/auth';
|
||||
import './index.scss';
|
||||
@@ -62,26 +64,26 @@ export default function ReportDetail() {
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<View className={`detail-page ${modeClass}`}>
|
||||
<PageShell className={modeClass}>
|
||||
<Loading />
|
||||
</View>
|
||||
</PageShell>
|
||||
);
|
||||
}
|
||||
|
||||
if (!report) {
|
||||
return (
|
||||
<View className={`detail-page ${modeClass}`}>
|
||||
<PageShell className={modeClass}>
|
||||
<View className='empty-state'>
|
||||
<Text className='empty-text'>报告不存在</Text>
|
||||
</View>
|
||||
</View>
|
||||
</PageShell>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<View className={`detail-page ${modeClass}`}>
|
||||
<PageShell className={modeClass}>
|
||||
{/* 基本信息 */}
|
||||
<View className='detail-card'>
|
||||
<ContentCard>
|
||||
<Text className='detail-title'>{report.report_type}</Text>
|
||||
<View className='detail-row'>
|
||||
<Text className='detail-label'>报告日期</Text>
|
||||
@@ -93,10 +95,10 @@ export default function ReportDetail() {
|
||||
<Text className='detail-value'>{report.doctor_interpretation}</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
</ContentCard>
|
||||
|
||||
{/* 指标列表 */}
|
||||
<View className='indicators-card'>
|
||||
<ContentCard>
|
||||
<Text className='section-title'>检查指标</Text>
|
||||
{indicators.map((item) => {
|
||||
const statusInfo = getStatusInfo(item.status);
|
||||
@@ -122,7 +124,7 @@ export default function ReportDetail() {
|
||||
</View>
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
</View>
|
||||
</ContentCard>
|
||||
</PageShell>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user