refactor(mp): 迁移预约+AI报告详情页 — 使用统一组件库 (12/12)

预约详情页:
- View.detail-page → PageShell 替代手写 page 容器
- 手写 detail-header → PageHeader 组件
- .status-card / .info-section / .tips-card → ContentCard
- 删除通用 page 容器、header 和 card 样式

AI 报告详情页:
- View.detail-page → PageShell 替代手写 page 容器
- .detail-card / .content-card → ContentCard
- 删除通用 page 容器和 card 样式,保留 RichText 内部样式
This commit is contained in:
iven
2026-05-16 01:17:04 +08:00
parent 61f1061092
commit 900c9babc3
4 changed files with 33 additions and 110 deletions

View File

@@ -1,21 +1,6 @@
@import '../../../styles/variables.scss'; @import '../../../styles/variables.scss';
@import '../../../styles/mixins.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-type { .detail-type {
@include section-title; @include section-title;
margin-bottom: 12px; margin-bottom: 12px;
@@ -31,12 +16,7 @@
color: $tx3; color: $tx3;
} }
.content-card { .content-card-wrap {
background: $card;
border-radius: $r;
padding: 28px;
box-shadow: $shadow-sm;
// RichText 内部样式 // RichText 内部样式
h1, h2, h3 { h1, h2, h3 {
font-weight: bold; font-weight: bold;

View File

@@ -4,6 +4,8 @@ import Taro, { useRouter } from '@tarojs/taro';
import { usePageData } from '@/hooks/usePageData'; import { usePageData } from '@/hooks/usePageData';
import { getAiAnalysisDetail, type AiAnalysisItem } from '@/services/ai-analysis'; import { getAiAnalysisDetail, type AiAnalysisItem } from '@/services/ai-analysis';
import Loading from '@/components/Loading'; import Loading from '@/components/Loading';
import PageShell from '@/components/ui/PageShell';
import ContentCard from '@/components/ui/ContentCard';
import { sanitizeHtml } from '@/utils/sanitize-html'; import { sanitizeHtml } from '@/utils/sanitize-html';
import { useElderClass } from '../../../hooks/useElderClass'; import { useElderClass } from '../../../hooks/useElderClass';
import './index.scss'; import './index.scss';
@@ -54,9 +56,9 @@ export default function AiReportDetail() {
if (!analysis) { if (!analysis) {
return ( return (
<View className={`detail-page ${modeClass}`}> <PageShell className={modeClass}>
<Text className='empty-text'></Text> <Text className='empty-text'></Text>
</View> </PageShell>
); );
} }
@@ -68,8 +70,8 @@ export default function AiReportDetail() {
const isAutoAnalysis = (analysis.result_metadata as Record<string, unknown>)?.auto_analysis === true; const isAutoAnalysis = (analysis.result_metadata as Record<string, unknown>)?.auto_analysis === true;
return ( return (
<View className={`detail-page ${modeClass}`}> <PageShell className={modeClass}>
<View className='detail-card'> <ContentCard>
<Text className='detail-type'>{TYPE_LABELS[analysis.analysis_type] || analysis.analysis_type}</Text> <Text className='detail-type'>{TYPE_LABELS[analysis.analysis_type] || analysis.analysis_type}</Text>
<View className='detail-meta'> <View className='detail-meta'>
<Text className='meta-item'>: {analysis.model_used}</Text> <Text className='meta-item'>: {analysis.model_used}</Text>
@@ -80,7 +82,7 @@ export default function AiReportDetail() {
<Text className='auto-badge-text'></Text> <Text className='auto-badge-text'></Text>
</View> </View>
)} )}
</View> </ContentCard>
{isTrendAnalysis && ( {isTrendAnalysis && (
<View className='trend-tip-card'> <View className='trend-tip-card'>
@@ -90,9 +92,9 @@ export default function AiReportDetail() {
</View> </View>
)} )}
<View className='content-card'> <ContentCard className='content-card-wrap'>
<RichText className='report-content' nodes={htmlContent} /> <RichText className='report-content' nodes={htmlContent} />
</View> </ContentCard>
</View> </PageShell>
); );
} }

View File

@@ -1,55 +1,13 @@
@import '../../../styles/variables.scss'; @import '../../../styles/variables.scss';
@import '../../../styles/mixins.scss'; @import '../../../styles/mixins.scss';
.detail-page {
min-height: 100vh;
background: $bg;
padding-bottom: 160px;
}
/* 顶部导航 */
.detail-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 32px;
padding-top: 48px;
background: $card;
box-shadow: $shadow-sm;
}
.back-btn {
padding: 8px 0;
}
.back-text {
font-size: var(--tk-font-body-lg);
color: $pri;
font-weight: 500;
}
.header-title {
font-family: 'Georgia', 'Times New Roman', serif;
font-size: var(--tk-font-num-lg);
font-weight: bold;
color: $tx;
}
.header-placeholder {
width: 60px;
}
/* 状态卡片 */ /* 状态卡片 */
.status-card { .status-card-wrap {
background: $card;
border-radius: $r-lg;
padding: 40px 32px;
margin: 20px 24px 24px;
box-shadow: $shadow-md;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
gap: 12px; gap: 12px;
margin: 20px 24px 24px;
} }
.status-tag { .status-tag {
@@ -97,12 +55,8 @@
} }
/* 详情信息 */ /* 详情信息 */
.info-section { .info-section-wrap {
margin: 0 24px 24px; margin: 0 24px 24px;
background: $card;
border-radius: $r;
padding: 28px;
box-shadow: $shadow-sm;
} }
.section-title { .section-title {
@@ -171,11 +125,9 @@
} }
/* 温馨提示 */ /* 温馨提示 */
.tips-card { .tips-card-wrap {
margin: 0 24px 24px; margin: 0 24px 24px;
background: $wrn-l; background: $wrn-l;
border-radius: $r;
padding: 24px 28px;
} }
.tips-title { .tips-title {

View File

@@ -5,6 +5,9 @@ import { getAppointment, cancelAppointment } from '../../../services/appointment
import type { Appointment } from '../../../services/appointment'; import type { Appointment } from '../../../services/appointment';
import Loading from '../../../components/Loading'; import Loading from '../../../components/Loading';
import ErrorState from '../../../components/ErrorState'; import ErrorState from '../../../components/ErrorState';
import PageShell from '@/components/ui/PageShell';
import ContentCard from '@/components/ui/ContentCard';
import PageHeader from '@/components/patterns/PageHeader';
import { useElderClass } from '../../../hooks/useElderClass'; import { useElderClass } from '../../../hooks/useElderClass';
import { useSafeTimeout } from '@/hooks/useSafeTimeout'; import { useSafeTimeout } from '@/hooks/useSafeTimeout';
import './index.scss'; import './index.scss';
@@ -65,53 +68,39 @@ export default function AppointmentDetail() {
} }
}; };
const goBack = () => Taro.navigateBack();
if (loading) { if (loading) {
return ( return (
<View className={`detail-page ${modeClass}`}> <PageShell padding='none' scroll={false} className={modeClass}>
<View className='detail-header'> <PageHeader title='预约详情' />
<View className='back-btn' onClick={goBack}><Text className='back-text'></Text></View>
<Text className='header-title'></Text>
<View className='header-placeholder' />
</View>
<Loading /> <Loading />
</View> </PageShell>
); );
} }
if (error || !appointment) { if (error || !appointment) {
return ( return (
<View className={`detail-page ${modeClass}`}> <PageShell padding='none' scroll={false} className={modeClass}>
<View className='detail-header'> <PageHeader title='预约详情' />
<View className='back-btn' onClick={goBack}><Text className='back-text'></Text></View>
<Text className='header-title'></Text>
<View className='header-placeholder' />
</View>
<ErrorState text='未找到预约信息' /> <ErrorState text='未找到预约信息' />
</View> </PageShell>
); );
} }
return ( return (
<View className={`detail-page ${modeClass}`}> <PageShell padding='none' scroll={false} className={modeClass}>
<View className='detail-header'> <PageHeader title='预约详情' />
<View className='back-btn' onClick={goBack}><Text className='back-text'></Text></View>
<Text className='header-title'></Text>
<View className='header-placeholder' />
</View>
{/* 状态卡片 */} {/* 状态卡片 */}
<View className='status-card'> <ContentCard variant='elevated' className='status-card-wrap'>
<View className={`status-tag ${status.className}`}> <View className={`status-tag ${status.className}`}>
<Text className='status-tag-text'>{status.label}</Text> <Text className='status-tag-text'>{status.label}</Text>
</View> </View>
<Text className='status-doctor'>{appointment.doctor_name}</Text> <Text className='status-doctor'>{appointment.doctor_name}</Text>
<Text className='status-dept'>{appointment.department || ''}</Text> <Text className='status-dept'>{appointment.department || ''}</Text>
</View> </ContentCard>
{/* 预约信息 */} {/* 预约信息 */}
<View className='info-section'> <ContentCard className='info-section-wrap'>
<Text className='section-title'></Text> <Text className='section-title'></Text>
<View className='info-item'> <View className='info-item'>
@@ -145,14 +134,14 @@ export default function AppointmentDetail() {
</View> </View>
<Text className='info-value info-id'>{appointment.id}</Text> <Text className='info-value info-id'>{appointment.id}</Text>
</View> </View>
</View> </ContentCard>
{/* 温馨提示 */} {/* 温馨提示 */}
{(appointment.status === 'pending' || appointment.status === 'confirmed') && ( {(appointment.status === 'pending' || appointment.status === 'confirmed') && (
<View className='tips-card'> <ContentCard className='tips-card-wrap'>
<Text className='tips-title'></Text> <Text className='tips-title'></Text>
<Text className='tips-text'>15</Text> <Text className='tips-text'>15</Text>
</View> </ContentCard>
)} )}
{/* 取消按钮 */} {/* 取消按钮 */}
@@ -166,6 +155,6 @@ export default function AppointmentDetail() {
</View> </View>
</View> </View>
)} )}
</View> </PageShell>
); );
} }