From 184bd0ea03cfbb958747f90caf43615d184a4c23 Mon Sep 17 00:00:00 2001 From: iven Date: Sat, 16 May 2026 01:55:28 +0800 Subject: [PATCH] =?UTF-8?q?refactor(mp):=20=E8=BF=81=E7=A7=BB=E5=89=A9?= =?UTF-8?q?=E4=BD=99=208=20=E7=89=B9=E6=AE=8A=E9=A1=B5=E9=9D=A2=E5=88=B0?= =?UTF-8?q?=E7=BB=9F=E4=B8=80=E7=BB=84=E4=BB=B6=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 首页/健康/我的/商城/消息 TabBar 页面使用 PageShell 替代手写容器 - 登录/法律条款/关怀模式设置页使用 PageShell 替代手写容器 - 各页面卡片统一使用 ContentCard 组件 - 清理页面 SCSS 中的 min-height/background/padding 样板代码 - 66 个小程序页面全部完成统一组件迁移 --- apps/miniprogram/src/pages/health/index.scss | 23 ------- apps/miniprogram/src/pages/health/index.tsx | 29 +++++---- apps/miniprogram/src/pages/index/index.scss | 21 ------ apps/miniprogram/src/pages/index/index.tsx | 65 +++++++++++-------- apps/miniprogram/src/pages/legal/index.scss | 2 - .../src/pages/legal/privacy-policy.tsx | 5 +- .../src/pages/legal/user-agreement.tsx | 5 +- apps/miniprogram/src/pages/login/index.scss | 7 +- apps/miniprogram/src/pages/login/index.tsx | 9 ++- apps/miniprogram/src/pages/mall/index.scss | 5 -- apps/miniprogram/src/pages/mall/index.tsx | 14 ++-- .../miniprogram/src/pages/messages/index.scss | 17 +---- apps/miniprogram/src/pages/messages/index.tsx | 17 +++-- .../pages/pkg-profile/elder-mode/index.scss | 15 +---- .../pages/pkg-profile/elder-mode/index.tsx | 14 ++-- apps/miniprogram/src/pages/profile/index.scss | 14 ---- apps/miniprogram/src/pages/profile/index.tsx | 26 ++++---- 17 files changed, 109 insertions(+), 179 deletions(-) diff --git a/apps/miniprogram/src/pages/health/index.scss b/apps/miniprogram/src/pages/health/index.scss index 081f24a..52992da 100644 --- a/apps/miniprogram/src/pages/health/index.scss +++ b/apps/miniprogram/src/pages/health/index.scss @@ -2,9 +2,6 @@ @import '../../styles/mixins.scss'; .health-page { - min-height: 100vh; - background: $bg; - padding: 20px 24px 100px; padding-bottom: calc(100px + env(safe-area-inset-bottom)); } @@ -23,10 +20,6 @@ /* ─── 录入区 ─── */ .input-section { margin-bottom: 20px; - background: $card; - border-radius: $r; - padding: 20px; - box-shadow: $shadow-md; } .input-group { @@ -130,11 +123,7 @@ } .trend-empty { - background: $card; - border-radius: $r; - padding: 24px; text-align: center; - box-shadow: $shadow-sm; } .trend-empty-text { @@ -143,10 +132,7 @@ } .trend-chart { - background: $card; - border-radius: $r; padding: 16px; - box-shadow: $shadow-sm; } .trend-bars { @@ -217,10 +203,6 @@ display: flex; align-items: center; gap: 12px; - background: $card; - border-radius: $r; - padding: 16px; - box-shadow: $shadow-sm; &:active { opacity: 0.85; @@ -266,11 +248,6 @@ /* ─── 健康资讯入口 ─── */ .article-entry { - background: $card; - border-radius: $r; - padding: 16px; - box-shadow: $shadow-sm; - &:active { opacity: 0.85; } diff --git a/apps/miniprogram/src/pages/health/index.tsx b/apps/miniprogram/src/pages/health/index.tsx index af6de1b..a4f3a0f 100644 --- a/apps/miniprogram/src/pages/health/index.tsx +++ b/apps/miniprogram/src/pages/health/index.tsx @@ -8,6 +8,8 @@ import Loading from '../../components/Loading'; import ErrorState from '../../components/ErrorState'; import GuestGuard from '../../components/GuestGuard'; import SegmentTabs from '../../components/SegmentTabs'; +import PageShell from '@/components/ui/PageShell'; +import ContentCard from '@/components/ui/ContentCard'; import { useHealthData, VITAL_TABS, type VitalType } from './useHealthData'; import './index.scss'; @@ -48,12 +50,12 @@ export default function Health() { if (error) { return ( - + 健康数据 - + ); } @@ -162,7 +164,7 @@ export default function Health() { const dayLabels = ['日', '一', '二', '三', '四', '五', '六']; return ( - + 健康数据 @@ -199,7 +201,7 @@ export default function Health() { - + {activeTab === 'blood_pressure' && ( 收缩压(高压) @@ -281,18 +283,18 @@ export default function Health() { {saving ? '保存中...' : '保存'} - + 近 7 天趋势 {trendLoading ? ( ) : trendData.length === 0 ? ( - + 暂无趋势数据 - + ) : ( - + {getThresholdValue(activeTab, thresholds) && (() => { const tv = getThresholdValue(activeTab, thresholds)!; @@ -319,16 +321,15 @@ export default function Health() { ); })} - + )} - Taro.navigateTo({ url: '/pages/article/index' })} + Taro.navigateTo({ url: '/pages/article/index' })} > 最新健康资讯 › - - + + ); } diff --git a/apps/miniprogram/src/pages/index/index.scss b/apps/miniprogram/src/pages/index/index.scss index 604056f..c7f1d32 100644 --- a/apps/miniprogram/src/pages/index/index.scss +++ b/apps/miniprogram/src/pages/index/index.scss @@ -6,9 +6,6 @@ ═══════════════════════════════════════ */ .home-page { - min-height: 100vh; - background: $bg; - padding: 20px 24px 100px; padding-bottom: calc(100px + env(safe-area-inset-bottom)); } @@ -69,10 +66,6 @@ /* ─── 今日体征进度 ─── */ .checkin-card { - background: $card; - border-radius: $r; - box-shadow: $shadow-md; - padding: 20px; margin-bottom: 16px; display: flex; align-items: center; @@ -140,11 +133,6 @@ } .vital-card { - background: $card; - border-radius: $r; - padding: 14px 16px; - box-shadow: $shadow-sm; - &:active { opacity: 0.7; } @@ -314,8 +302,6 @@ ═══════════════════════════════════════ */ .guest-page { - min-height: 100vh; - background: $bg; padding-bottom: calc(120px + env(safe-area-inset-bottom)); } @@ -393,10 +379,7 @@ } .guest-article-card { - background: $card; - border-radius: $r; overflow: hidden; - box-shadow: $shadow-sm; display: flex; &:active { @@ -449,10 +432,6 @@ /* ─── 底部登录引导 ─── */ .guest-login-prompt { margin: 24px 24px 0; - background: $card; - border-radius: $r; - padding: 20px; - box-shadow: $shadow-md; display: flex; align-items: center; gap: 16px; diff --git a/apps/miniprogram/src/pages/index/index.tsx b/apps/miniprogram/src/pages/index/index.tsx index f99dc9f..cd4b836 100644 --- a/apps/miniprogram/src/pages/index/index.tsx +++ b/apps/miniprogram/src/pages/index/index.tsx @@ -10,6 +10,8 @@ import { api } from '@/services/request'; import type { Article } from '@/services/article'; import ProgressRing from '../../components/ProgressRing'; import Loading from '../../components/Loading'; +import PageShell from '@/components/ui/PageShell'; +import ContentCard from '@/components/ui/ContentCard'; import { useHomeData, type ReminderItem } from './useHomeData'; import './index.scss'; @@ -83,7 +85,7 @@ function GuestHome({ modeClass }: { modeClass: string }) { const slides = banners.length > 0 ? banners : FALLBACK_SLIDES; return ( - + 0 ? ( {articles.map((article) => ( - Taro.navigateTo({ url: `/pages/article/detail/index?id=${article.id}` })} + onPress={() => Taro.navigateTo({ url: `/pages/article/detail/index?id=${article.id}` })} + activeFeedback="opacity" + padding="none" > {article.cover_image && ( @@ -130,34 +133,40 @@ function GuestHome({ modeClass }: { modeClass: string }) { {article.summary || '点击查看详情'} - + ))} ) : ( - - 健康数据管理 - 记录并追踪您的体征数据 - - - 智能预约排班 - 在线预约透析和治疗 - - - AI 健康分析 - 个性化健康趋势解读 - + + + 健康数据管理 + 记录并追踪您的体征数据 + + + + + 智能预约排班 + 在线预约透析和治疗 + + + + + AI 健康分析 + 个性化健康趋势解读 + + )} - + 登录后即可使用完整健康管理服务 立即登录 - - + + ); } @@ -177,7 +186,7 @@ function HomeDashboard({ modeClass }: { modeClass: string }) { }; return ( - + {greeting},{displayName} @@ -191,7 +200,7 @@ function HomeDashboard({ modeClass }: { modeClass: string }) { - Taro.switchTab({ url: '/pages/health/index' })}> + Taro.switchTab({ url: '/pages/health/index' })}> @@ -207,7 +216,7 @@ function HomeDashboard({ modeClass }: { modeClass: string }) { ))} - + 今日体征 @@ -218,10 +227,10 @@ function HomeDashboard({ modeClass }: { modeClass: string }) { {healthItems.map((item) => { const tag = getStatusTag(item.status); return ( - Taro.navigateTo({ url: `/pages/pkg-health/trend/index?indicator=${item.indicator}` })} + onPress={() => Taro.navigateTo({ url: `/pages/pkg-health/trend/index?indicator=${item.indicator}` })} + activeFeedback="opacity" > {item.label} @@ -232,7 +241,7 @@ function HomeDashboard({ modeClass }: { modeClass: string }) { {tag && {tag.label}} {!item.status && 未记录} - + ); })} @@ -270,7 +279,7 @@ function HomeDashboard({ modeClass }: { modeClass: string }) { 预约挂号 - + ); } diff --git a/apps/miniprogram/src/pages/legal/index.scss b/apps/miniprogram/src/pages/legal/index.scss index 306743d..72f31c6 100644 --- a/apps/miniprogram/src/pages/legal/index.scss +++ b/apps/miniprogram/src/pages/legal/index.scss @@ -1,9 +1,7 @@ @import '../../styles/variables.scss'; .legal-page { - min-height: 100vh; background: $card; - padding: 32px 24px; padding-bottom: 60px; } diff --git a/apps/miniprogram/src/pages/legal/privacy-policy.tsx b/apps/miniprogram/src/pages/legal/privacy-policy.tsx index 81b0e87..45c3671 100644 --- a/apps/miniprogram/src/pages/legal/privacy-policy.tsx +++ b/apps/miniprogram/src/pages/legal/privacy-policy.tsx @@ -1,4 +1,5 @@ import { View, Text, RichText } from '@tarojs/components'; +import PageShell from '@/components/ui/PageShell'; import './index.scss'; const PRIVACY_CONTENT = ` @@ -48,11 +49,11 @@ const PRIVACY_CONTENT = ` export default function PrivacyPolicy() { return ( - + 如有疑问,请联系客服 - + ); } diff --git a/apps/miniprogram/src/pages/legal/user-agreement.tsx b/apps/miniprogram/src/pages/legal/user-agreement.tsx index 439289f..8417d64 100644 --- a/apps/miniprogram/src/pages/legal/user-agreement.tsx +++ b/apps/miniprogram/src/pages/legal/user-agreement.tsx @@ -1,4 +1,5 @@ import { View, Text, RichText } from '@tarojs/components'; +import PageShell from '@/components/ui/PageShell'; import './index.scss'; const AGREEMENT_CONTENT = ` @@ -34,11 +35,11 @@ const AGREEMENT_CONTENT = ` export default function UserAgreement() { return ( - + 如有疑问,请联系客服 - + ); } diff --git a/apps/miniprogram/src/pages/login/index.scss b/apps/miniprogram/src/pages/login/index.scss index 92b22bd..127a80a 100644 --- a/apps/miniprogram/src/pages/login/index.scss +++ b/apps/miniprogram/src/pages/login/index.scss @@ -1,13 +1,8 @@ @import '../../styles/variables.scss'; @import '../../styles/mixins.scss'; -.login-scroll { - height: 100vh; -} - .login-page { - min-height: 100vh; - background: $bg; + // PageShell 接管 min-height, background, scroll display: flex; flex-direction: column; align-items: center; diff --git a/apps/miniprogram/src/pages/login/index.tsx b/apps/miniprogram/src/pages/login/index.tsx index 54b2326..8b1e3a7 100644 --- a/apps/miniprogram/src/pages/login/index.tsx +++ b/apps/miniprogram/src/pages/login/index.tsx @@ -1,8 +1,9 @@ import { useState } from 'react'; -import { View, Text, Button, ScrollView } from '@tarojs/components'; +import { View, Text, Button } from '@tarojs/components'; import Taro from '@tarojs/taro'; import { useAuthStore } from '../../stores/auth'; import { useElderClass } from '../../hooks/useElderClass'; +import PageShell from '@/components/ui/PageShell'; import './index.scss'; const IS_DEV = process.env.NODE_ENV !== 'production'; @@ -95,8 +96,7 @@ export default function Login() { }; return ( - - + {/* 品牌区 */} @@ -155,7 +155,6 @@ export default function Login() { 暂不登录,先看看 - - + ); } diff --git a/apps/miniprogram/src/pages/mall/index.scss b/apps/miniprogram/src/pages/mall/index.scss index b1eef69..3658a84 100644 --- a/apps/miniprogram/src/pages/mall/index.scss +++ b/apps/miniprogram/src/pages/mall/index.scss @@ -2,8 +2,6 @@ @import '../../styles/mixins.scss'; .mall-page { - min-height: 100vh; - background: $bg; padding-bottom: calc(120px + env(safe-area-inset-bottom)); } @@ -121,10 +119,7 @@ } .product-card { - background: $card; - border-radius: $r; overflow: hidden; - box-shadow: $shadow-sm; &:active { opacity: 0.7; diff --git a/apps/miniprogram/src/pages/mall/index.tsx b/apps/miniprogram/src/pages/mall/index.tsx index 35c9214..85c2245 100644 --- a/apps/miniprogram/src/pages/mall/index.tsx +++ b/apps/miniprogram/src/pages/mall/index.tsx @@ -10,6 +10,8 @@ import Loading from '../../components/Loading'; import ErrorState from '../../components/ErrorState'; import EmptyState from '../../components/EmptyState'; import { useElderClass } from '../../hooks/useElderClass'; +import PageShell from '@/components/ui/PageShell'; +import ContentCard from '@/components/ui/ContentCard'; import './index.scss'; const PRODUCT_TYPE_TABS = [ @@ -137,7 +139,7 @@ export default function Mall() { if (noProfile) { return ( - + Taro.navigateTo({ url: '/pages/pkg-profile/family-add/index' })} /> - + ); } return ( - + {/* 积分余额卡片 */} @@ -197,7 +199,7 @@ export default function Mall() { ) : ( {products.map((item) => ( - handleProductClick(item)}> + handleProductClick(item)} activeFeedback="opacity" padding="none"> {item.product_type === 'physical' ? '物' : item.product_type === 'service' ? '券' : '权'} @@ -217,7 +219,7 @@ export default function Mall() { ) : null} - + ))} {loading && } {!loading && products.length >= total && total > 0 && ( @@ -225,6 +227,6 @@ export default function Mall() { )} )} - + ); } diff --git a/apps/miniprogram/src/pages/messages/index.scss b/apps/miniprogram/src/pages/messages/index.scss index 884aa0b..e901355 100644 --- a/apps/miniprogram/src/pages/messages/index.scss +++ b/apps/miniprogram/src/pages/messages/index.scss @@ -2,8 +2,7 @@ @import '../../styles/mixins.scss'; .messages-page { - min-height: 100vh; - background: $bg; + // PageShell 接管 min-height, background padding: 20px 24px 100px; padding-bottom: calc(100px + env(safe-area-inset-bottom)); } @@ -91,14 +90,7 @@ display: flex; gap: 12px; align-items: center; - background: $card; - border-radius: $r; - padding: 16px; - box-shadow: $shadow-sm; - - &:active { - opacity: 0.85; - } + // ContentCard 接管 background, border-radius, padding, box-shadow, active feedback } .consult-card-muted { @@ -188,10 +180,7 @@ display: flex; gap: 12px; align-items: flex-start; - background: $card; - border-radius: $r; - padding: 16px; - box-shadow: $shadow-sm; + // ContentCard 接管 background, border-radius, padding, box-shadow } .notify-card-muted { diff --git a/apps/miniprogram/src/pages/messages/index.tsx b/apps/miniprogram/src/pages/messages/index.tsx index f949694..e10cf25 100644 --- a/apps/miniprogram/src/pages/messages/index.tsx +++ b/apps/miniprogram/src/pages/messages/index.tsx @@ -10,6 +10,8 @@ import GuestGuard from '../../components/GuestGuard'; import { useAuthStore } from '../../stores/auth'; import { useElderClass } from '../../hooks/useElderClass'; import { usePageData } from '@/hooks/usePageData'; +import PageShell from '@/components/ui/PageShell'; +import ContentCard from '@/components/ui/ContentCard'; import './index.scss'; type MsgTab = 'consultation' | 'notification'; @@ -116,7 +118,7 @@ export default function Messages() { const unreadConsultCount = sessions.filter((s) => s.unread_count_patient > 0).length; return ( - + {/* 页头 */} 消息 @@ -160,10 +162,11 @@ export default function Messages() { const doctorName = session.last_message?.slice(0, 1) || '医'; const hasUnread = session.unread_count_patient > 0; return ( - Taro.navigateTo({ url: `/pages/pkg-consultation/detail/index?id=${session.id}` })} + padding="sm" className={`consult-card ${hasUnread ? '' : 'consult-card-muted'}`} - onClick={() => Taro.navigateTo({ url: `/pages/pkg-consultation/detail/index?id=${session.id}` })} > {doctorName} @@ -188,7 +191,7 @@ export default function Messages() { )} - + ); })} @@ -207,7 +210,7 @@ export default function Messages() { const cfg = NOTIFY_ICONS[n.type] || NOTIFY_ICONS.report; const isUnread = !n.read; return ( - + {cfg.icon} @@ -219,7 +222,7 @@ export default function Messages() { {n.desc} {isUnread && } - + ); })} @@ -228,6 +231,6 @@ export default function Messages() { )} - + ); } diff --git a/apps/miniprogram/src/pages/pkg-profile/elder-mode/index.scss b/apps/miniprogram/src/pages/pkg-profile/elder-mode/index.scss index f168e0a..e103d21 100644 --- a/apps/miniprogram/src/pages/pkg-profile/elder-mode/index.scss +++ b/apps/miniprogram/src/pages/pkg-profile/elder-mode/index.scss @@ -2,17 +2,11 @@ @import '../../../styles/mixins.scss'; .elder-mode-page { - min-height: 100vh; - background: $bg; - padding: 24px; + // PageShell 接管 min-height, background, padding } .elder-mode-card { - background: $card; - border-radius: $r; - padding: 24px; - box-shadow: $shadow-md; - margin-bottom: 20px; + // ContentCard 接管 background, border-radius, padding, box-shadow, margin-bottom } .elder-mode-header { @@ -108,10 +102,7 @@ } .elder-mode-preview-card { - background: $card; - border-radius: $r; - padding: 20px; - box-shadow: $shadow-sm; + // ContentCard 接管 background, border-radius, padding, box-shadow } .elder-mode-preview-sample { diff --git a/apps/miniprogram/src/pages/pkg-profile/elder-mode/index.tsx b/apps/miniprogram/src/pages/pkg-profile/elder-mode/index.tsx index 98d69d1..cc540da 100644 --- a/apps/miniprogram/src/pages/pkg-profile/elder-mode/index.tsx +++ b/apps/miniprogram/src/pages/pkg-profile/elder-mode/index.tsx @@ -2,6 +2,8 @@ import { View, Text } from '@tarojs/components'; import Taro from '@tarojs/taro'; import { useUIStore } from '../../../stores/ui'; import { useElderClass } from '../../../hooks/useElderClass'; +import PageShell from '@/components/ui/PageShell'; +import ContentCard from '@/components/ui/ContentCard'; import './index.scss'; export default function ElderMode() { @@ -21,8 +23,8 @@ export default function ElderMode() { }; return ( - - + + @@ -42,19 +44,19 @@ export default function ElderMode() { - + 效果预览 - + {isElder ? '长辈模式字体示例' : '标准模式字体示例'} {isElder ? '字号放大 1.3 倍,间距放大 1.2 倍' : '正常字号和间距'} - + - + ); } diff --git a/apps/miniprogram/src/pages/profile/index.scss b/apps/miniprogram/src/pages/profile/index.scss index 0832ee9..d87a6d3 100644 --- a/apps/miniprogram/src/pages/profile/index.scss +++ b/apps/miniprogram/src/pages/profile/index.scss @@ -2,21 +2,14 @@ @import '../../styles/mixins.scss'; .profile-page { - min-height: 100vh; - background: $bg; - padding: 20px 24px 100px; padding-bottom: calc(100px + env(safe-area-inset-bottom)); } /* ─── 用户信息卡片 ─── */ .profile-user-card { - background: $card; - border-radius: $r; - padding: 20px; display: flex; align-items: center; gap: 16px; - box-shadow: $shadow-md; margin-bottom: 16px; } @@ -70,11 +63,7 @@ .stat-card { flex: 1; - background: $card; - border-radius: $r; - padding: 16px; text-align: center; - box-shadow: $shadow-sm; } .stat-value { @@ -118,10 +107,7 @@ } .menu-group-card { - background: $card; - border-radius: $r; overflow: hidden; - box-shadow: $shadow-sm; } .menu-item { diff --git a/apps/miniprogram/src/pages/profile/index.tsx b/apps/miniprogram/src/pages/profile/index.tsx index d60c9a9..735f279 100644 --- a/apps/miniprogram/src/pages/profile/index.tsx +++ b/apps/miniprogram/src/pages/profile/index.tsx @@ -7,6 +7,8 @@ import { useUIStore } from '../../stores/ui'; import { navigateToLogin } from '../../utils/navigate'; import { usePageData } from '@/hooks/usePageData'; import Loading from '../../components/Loading'; +import PageShell from '@/components/ui/PageShell'; +import ContentCard from '@/components/ui/ContentCard'; import './index.scss'; interface MenuItem { @@ -123,10 +125,10 @@ export default function Profile() { const displayInitial = (user?.display_name || user?.username || '用').charAt(0); return ( - + {/* 用户信息卡片 */} {isGuest ? ( - + ? @@ -135,10 +137,10 @@ export default function Profile() { 点击登录,开启健康管理之旅 - + ) : ( <> - + {displayInitial} @@ -149,21 +151,21 @@ export default function Profile() { - + {/* 积分 + 打卡 */} {pointsLoading ? ( ) : ( - + {(pointsAccount?.balance ?? 0).toLocaleString()} 健康积分 - - + + {checkinInfo?.consecutive_days ?? 0} 连续打卡 - + )} @@ -173,7 +175,7 @@ export default function Profile() { {groups.map((group) => ( {group.title} - + {group.items.map((item, idx) => ( ))} - + ))} @@ -202,6 +204,6 @@ export default function Profile() { 退出登录 )} - + ); }