From 722ee76d93ebcbbe090106f2ed0ce86a135abdc8 Mon Sep 17 00:00:00 2001 From: MingNian <1281442923@qq.com> Date: Fri, 22 May 2026 17:48:18 +0800 Subject: [PATCH] refactor: patient frontend UI overhaul - Reworked design system (variables, global styles, component CSS) - Updated TabBar with icon-based navigation - Redesigned HomePage, HealthHub, ServicesHub layouts - Improved Exercise/Diet, Medication, Profile pages styling - Simplified constants (removed emoji icons, streamlined data) - Fixed launch.json cwd paths for frontend projects --- .claude/launch.json | 12 +- frontend-patient/src/assets/styles/global.css | 44 +++++ .../src/assets/styles/variables.css | 63 +++--- .../src/components/common/Badge.module.css | 12 +- .../src/components/common/Button.module.css | 28 +-- .../src/components/common/Card.module.css | 8 +- .../src/components/common/Empty.module.css | 17 +- .../src/components/common/Empty.tsx | 15 +- .../src/components/common/Input.module.css | 7 +- .../src/components/common/Toast.module.css | 1 + .../components/layout/AppLayout.module.css | 1 + .../components/layout/PageHeader.module.css | 6 +- .../src/components/layout/TabBar.module.css | 54 +++-- .../src/components/layout/TabBar.tsx | 45 ++++- frontend-patient/src/pages/auth/LoginPage.tsx | 6 +- .../exercise-diet/ExerciseDietPage.module.css | 10 +- .../pages/exercise-diet/ExerciseDietPage.tsx | 6 +- .../src/pages/health/HealthHubPage.module.css | 32 ++- .../src/pages/health/HealthHubPage.tsx | 187 ++++++++++++------ .../health/HealthRecordListPage.module.css | 8 +- .../src/pages/health/HealthRecordListPage.tsx | 4 +- .../src/pages/home/DeviceBindingPage.tsx | 6 +- .../src/pages/home/HomePage.module.css | 163 +++++++++------ frontend-patient/src/pages/home/HomePage.tsx | 154 ++++++++++++--- .../MedicationDetailPage.module.css | 6 +- .../pages/medication/MedicationDetailPage.tsx | 2 +- .../medication/MedicationEditPage.module.css | 2 +- .../pages/medication/MedicationEditPage.tsx | 2 +- .../medication/MedicationListPage.module.css | 5 +- .../pages/medication/MedicationListPage.tsx | 78 +++----- .../notifications/NotificationListPage.tsx | 2 +- .../src/pages/profile/ProfilePage.module.css | 47 +++-- .../src/pages/profile/ProfilePage.tsx | 41 +++- .../src/pages/profile/staticPages.tsx | 6 +- .../pages/services/DoctorListPage.module.css | 15 +- .../src/pages/services/DoctorListPage.tsx | 2 +- .../services/FollowUpListPage.module.css | 4 +- .../src/pages/services/FollowUpListPage.tsx | 2 +- .../pages/services/ReportListPage.module.css | 4 +- .../src/pages/services/ReportListPage.tsx | 2 +- .../src/pages/services/ReportUploadPage.tsx | 8 +- .../pages/services/ServicesHubPage.module.css | 27 ++- .../src/pages/services/ServicesHubPage.tsx | 49 ++++- frontend-patient/src/utils/constants.ts | 54 ++--- 44 files changed, 854 insertions(+), 393 deletions(-) diff --git a/.claude/launch.json b/.claude/launch.json index 1a64841..7e61951 100644 --- a/.claude/launch.json +++ b/.claude/launch.json @@ -2,10 +2,18 @@ "version": "0.0.1", "configurations": [ { - "name": "健康管家 Web Demo", + "name": "健康管家-患者端", "runtimeExecutable": "cmd.exe", "runtimeArgs": ["/c", "D:\\nodejs\\npm.cmd", "run", "dev"], - "port": 5175 + "cwd": "D:\\APP\\frontend-patient", + "port": 5173 + }, + { + "name": "健康管家-医生端", + "runtimeExecutable": "cmd.exe", + "runtimeArgs": ["/c", "D:\\nodejs\\npm.cmd", "run", "dev"], + "cwd": "D:\\APP\\frontend-doctor", + "port": 5174 } ] } diff --git a/frontend-patient/src/assets/styles/global.css b/frontend-patient/src/assets/styles/global.css index 53930b6..f311521 100644 --- a/frontend-patient/src/assets/styles/global.css +++ b/frontend-patient/src/assets/styles/global.css @@ -36,7 +36,51 @@ white-space: nowrap; } +/* Section Title */ +.section-title { + font-size: var(--font-size-md); + font-weight: 700; + color: var(--color-text-primary); + margin-bottom: 12px; + display: flex; + align-items: center; + gap: 8px; +} + +.section-title::before { + content: ''; + width: 4px; + height: 18px; + border-radius: 2px; + background: var(--color-primary); +} + +/* Tag */ +.tag { + display: inline-flex; + align-items: center; + padding: 3px 10px; + border-radius: 20px; + font-size: 11px; + font-weight: 600; +} +.tag-success { background: var(--color-success-bg); color: #0D8A5E; } +.tag-warning { background: var(--color-warning-bg); color: #D67E0B; } +.tag-danger { background: var(--color-danger-bg); color: #D53131; } +.tag-info { background: var(--color-primary-bg); color: var(--color-primary); } +.tag-primary { background: var(--color-primary-bg); color: var(--color-primary); } + /* Transitions */ +@keyframes fadeInUp { + from { opacity: 0; transform: translateY(12px); } + to { opacity: 1; transform: translateY(0); } +} + +@keyframes pulse { + 0%, 100% { transform: scale(1); } + 50% { transform: scale(1.06); } +} + .page-enter { animation: slideInRight 0.3s ease-out; } diff --git a/frontend-patient/src/assets/styles/variables.css b/frontend-patient/src/assets/styles/variables.css index 6bf59dc..c3c245c 100644 --- a/frontend-patient/src/assets/styles/variables.css +++ b/frontend-patient/src/assets/styles/variables.css @@ -1,30 +1,39 @@ :root { - /* Primary - Rich Medical Blue */ - --color-primary: #2563EB; - --color-primary-light: #3B82F6; - --color-primary-dark: #1D4ED8; - --color-primary-bg: #EFF6FF; - --color-primary-gradient: linear-gradient(135deg, #2563EB, #4F8AF8); + /* Primary - Modern Indigo Blue */ + --color-primary: #4F6EF7; + --color-primary-light: #6C8CFF; + --color-primary-dark: #3D56D4; + --color-primary-bg: #EEF1FE; + --color-primary-gradient: linear-gradient(135deg, #4F6EF7, #6C8CFF); + + /* Accent */ + --color-accent-red: #FF6B6B; + --color-accent-orange: #FFA94D; + --color-accent-green: #20C997; + --color-accent-purple: #845EF7; + --color-accent-sky: #339AF0; + --color-accent-pink: #F06595; /* Status */ - --color-success: #10B981; - --color-success-bg: #ECFDF5; + --color-success: #20C997; + --color-success-bg: #E6F9F2; --color-warning: #F59E0B; - --color-warning-bg: #FFFBEB; - --color-danger: #EF4444; - --color-danger-bg: #FEF2F2; + --color-warning-bg: #FFF4E5; + --color-danger: #FF6B6B; + --color-danger-bg: #FEE9E9; /* Neutral */ --color-white: #FFFFFF; - --color-bg: #F4F6FA; - --color-bg-secondary: #EBEEF3; - --color-border: #E4E7EC; - --color-border-light: #F0F1F4; + --color-bg: #F0F4F8; + --color-bg-secondary: #E8ECF2; + --color-border: #E4E8EE; + --color-border-light: #EEF1F6; + --color-divider: #EDF0F5; /* Text */ - --color-text-primary: #1A1E2B; - --color-text-secondary: #6B7280; - --color-text-tertiary: #9CA3AF; + --color-text-primary: #1A1D28; + --color-text-secondary: #5A5F72; + --color-text-tertiary: #9BA0B4; --color-text-inverse: #FFFFFF; /* Spacing */ @@ -37,21 +46,21 @@ --spacing-3xl: 32px; /* Border radius */ - --radius-sm: 8px; - --radius-md: 12px; + --radius-sm: 10px; + --radius-md: 14px; --radius-lg: 16px; --radius-xl: 20px; --radius-2xl: 24px; --radius-full: 9999px; /* Shadows */ - --shadow-xs: 0 1px 2px rgba(0,0,0,0.04); - --shadow-sm: 0 2px 8px rgba(0,0,0,0.05); - --shadow-md: 0 4px 16px rgba(0,0,0,0.07); - --shadow-lg: 0 8px 32px rgba(0,0,0,0.09); + --shadow-xs: 0 1px 3px rgba(0,0,0,0.03); + --shadow-sm: 0 2px 12px rgba(0,0,0,0.04); + --shadow-md: 0 4px 20px rgba(0,0,0,0.06); + --shadow-lg: 0 8px 30px rgba(0,0,0,0.08); /* Font */ - --font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif; + --font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif; --font-size-xs: 11px; --font-size-sm: 12px; --font-size-base: 14px; @@ -62,8 +71,8 @@ --font-size-3xl: 32px; /* Layout */ - --tab-bar-height: 56px; - --header-height: 48px; + --tab-bar-height: 64px; + --header-height: 50px; --max-content-width: 414px; /* Z-index */ diff --git a/frontend-patient/src/components/common/Badge.module.css b/frontend-patient/src/components/common/Badge.module.css index b1389f1..0f1ff32 100644 --- a/frontend-patient/src/components/common/Badge.module.css +++ b/frontend-patient/src/components/common/Badge.module.css @@ -2,14 +2,14 @@ display: inline-flex; align-items: center; justify-content: center; - min-width: 18px; - height: 18px; - padding: 0 5px; + min-width: 20px; + height: 20px; + padding: 0 6px; border-radius: 10px; - background: var(--color-danger); + background: var(--color-accent-red); color: white; font-size: 10px; - font-weight: 600; + font-weight: 700; line-height: 1; } @@ -18,5 +18,5 @@ width: 8px; height: 8px; border-radius: 50%; - background: var(--color-danger); + background: var(--color-accent-red); } diff --git a/frontend-patient/src/components/common/Button.module.css b/frontend-patient/src/components/common/Button.module.css index 4e2a20b..65408f2 100644 --- a/frontend-patient/src/components/common/Button.module.css +++ b/frontend-patient/src/components/common/Button.module.css @@ -4,7 +4,7 @@ justify-content: center; gap: var(--spacing-sm); border-radius: var(--radius-md); - font-weight: 500; + font-weight: 600; transition: all 0.2s; cursor: pointer; -webkit-tap-highlight-color: transparent; @@ -21,11 +21,13 @@ .lg { padding: 12px 24px; font-size: var(--font-size-md); } .primary { - background: var(--color-primary); + background: var(--color-primary-gradient); color: var(--color-text-inverse); + box-shadow: 0 4px 14px rgba(79,110,247,0.3); } .primary:hover:not(:disabled) { - background: var(--color-primary-dark); + box-shadow: 0 6px 20px rgba(79,110,247,0.35); + transform: translateY(-1px); } .secondary { @@ -48,24 +50,4 @@ .text { background: transparent; color: var(--color-primary); - padding-left: 4px; - padding-right: 4px; -} -.text:hover:not(:disabled) { - opacity: 0.8; -} - -.fullWidth { width: 100%; } - -.spinner { - width: 16px; - height: 16px; - border: 2px solid currentColor; - border-top-color: transparent; - border-radius: 50%; - animation: spin 0.6s linear infinite; -} - -@keyframes spin { - to { transform: rotate(360deg); } } diff --git a/frontend-patient/src/components/common/Card.module.css b/frontend-patient/src/components/common/Card.module.css index 37e4675..aa11722 100644 --- a/frontend-patient/src/components/common/Card.module.css +++ b/frontend-patient/src/components/common/Card.module.css @@ -1,17 +1,17 @@ .card { background: var(--color-white); - border-radius: var(--radius-lg); - padding: var(--spacing-lg); + border-radius: var(--radius-xl); + padding: 18px; box-shadow: var(--shadow-sm); + transition: transform 0.2s, box-shadow 0.2s; } .clickable { cursor: pointer; -webkit-tap-highlight-color: transparent; - transition: transform 0.15s, box-shadow 0.15s; } .clickable:active { - transform: scale(0.98); + transform: scale(0.985); box-shadow: var(--shadow-md); } diff --git a/frontend-patient/src/components/common/Empty.module.css b/frontend-patient/src/components/common/Empty.module.css index 4d2e8bd..42f21d3 100644 --- a/frontend-patient/src/components/common/Empty.module.css +++ b/frontend-patient/src/components/common/Empty.module.css @@ -7,11 +7,24 @@ } .icon { - font-size: 48px; - margin-bottom: 12px; + width: 64px; + height: 64px; + border-radius: 20px; + background: var(--color-bg-secondary); + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 14px; +} + +.icon svg { + width: 32px; + height: 32px; + stroke: var(--color-text-tertiary); } .message { font-size: var(--font-size-sm); color: var(--color-text-tertiary); + font-weight: 500; } diff --git a/frontend-patient/src/components/common/Empty.tsx b/frontend-patient/src/components/common/Empty.tsx index 9d32335..5464a73 100644 --- a/frontend-patient/src/components/common/Empty.tsx +++ b/frontend-patient/src/components/common/Empty.tsx @@ -1,14 +1,23 @@ import styles from './Empty.module.css'; interface EmptyProps { - icon?: string; + icon?: React.ReactNode; message?: string; } -export function Empty({ icon = '📭', message = '暂无数据' }: EmptyProps) { +const DEFAULT_ICON = ( + + + + + + +); + +export function Empty({ icon = DEFAULT_ICON, message = '暂无数据' }: EmptyProps) { return (
- {icon} +
{icon}

{message}

); diff --git a/frontend-patient/src/components/common/Input.module.css b/frontend-patient/src/components/common/Input.module.css index 1f8345c..9c46ab8 100644 --- a/frontend-patient/src/components/common/Input.module.css +++ b/frontend-patient/src/components/common/Input.module.css @@ -7,7 +7,7 @@ .label { font-size: var(--font-size-sm); - font-weight: 500; + font-weight: 600; color: var(--color-text-secondary); } @@ -16,15 +16,16 @@ padding: 10px 14px; background: var(--color-bg); border: 1.5px solid var(--color-border); - border-radius: var(--radius-md); + border-radius: var(--radius-sm); font-size: var(--font-size-base); color: var(--color-text-primary); - transition: border-color 0.2s; + transition: border-color 0.2s, box-shadow 0.2s; } .input:focus { border-color: var(--color-primary); background: var(--color-white); + box-shadow: 0 0 0 3px rgba(79,110,247,0.1); } .input::placeholder { diff --git a/frontend-patient/src/components/common/Toast.module.css b/frontend-patient/src/components/common/Toast.module.css index ffaffad..b69605d 100644 --- a/frontend-patient/src/components/common/Toast.module.css +++ b/frontend-patient/src/components/common/Toast.module.css @@ -19,6 +19,7 @@ min-width: 160px; text-align: center; box-shadow: var(--shadow-lg); + font-weight: 500; } .success { background: var(--color-success); } diff --git a/frontend-patient/src/components/layout/AppLayout.module.css b/frontend-patient/src/components/layout/AppLayout.module.css index afb7c80..a58fc95 100644 --- a/frontend-patient/src/components/layout/AppLayout.module.css +++ b/frontend-patient/src/components/layout/AppLayout.module.css @@ -1,5 +1,6 @@ .layout { min-height: 100vh; + background: var(--color-bg); } .main { diff --git a/frontend-patient/src/components/layout/PageHeader.module.css b/frontend-patient/src/components/layout/PageHeader.module.css index d01d574..6b07884 100644 --- a/frontend-patient/src/components/layout/PageHeader.module.css +++ b/frontend-patient/src/components/layout/PageHeader.module.css @@ -7,7 +7,7 @@ max-width: var(--max-content-width); height: var(--header-height); background: var(--color-white); - border-bottom: 1px solid var(--color-border); + border-bottom: 1px solid var(--color-divider); display: flex; align-items: center; justify-content: space-between; @@ -33,13 +33,13 @@ width: 36px; height: 36px; margin-left: -8px; - border-radius: var(--radius-full); + border-radius: var(--radius-sm); color: var(--color-text-primary); -webkit-tap-highlight-color: transparent; } .title { - font-size: var(--font-size-md); + font-size: 17px; font-weight: 600; text-align: center; flex: 1; diff --git a/frontend-patient/src/components/layout/TabBar.module.css b/frontend-patient/src/components/layout/TabBar.module.css index 34be384..dac5472 100644 --- a/frontend-patient/src/components/layout/TabBar.module.css +++ b/frontend-patient/src/components/layout/TabBar.module.css @@ -7,11 +7,12 @@ max-width: var(--max-content-width); height: var(--tab-bar-height); background: var(--color-white); - border-top: 1px solid var(--color-border); + border-top: 1px solid var(--color-divider); display: flex; align-items: center; justify-content: space-around; z-index: var(--z-tab-bar); + padding: 0 8px; padding-bottom: env(safe-area-inset-bottom); } @@ -21,9 +22,8 @@ align-items: center; justify-content: center; gap: 2px; - padding: var(--spacing-xs) var(--spacing-md); + padding: 6px 0; min-width: 56px; - min-height: 44px; color: var(--color-text-tertiary); transition: color 0.2s; -webkit-tap-highlight-color: transparent; @@ -34,33 +34,57 @@ } .tabIcon { - font-size: 22px; - line-height: 1; + width: 44px; + height: 44px; + border-radius: 12px; + display: flex; + align-items: center; + justify-content: center; + position: relative; + transition: all 0.25s; +} + +.tabActive .tabIcon { + background: var(--color-primary-bg); + transform: translateY(-6px); + box-shadow: 0 4px 12px rgba(79,110,247,0.25); +} + +.tabActive .tabIcon::after { + content: ''; + position: absolute; + bottom: -2px; + width: 20px; + height: 3px; + border-radius: 3px; + background: var(--color-primary); } .tabLabel { - font-size: var(--font-size-xs); + font-size: 10px; font-weight: 500; + transition: color 0.2s; } -.tabIcon { - position: relative; +.tabActive .tabLabel { + font-weight: 600; } .badge { position: absolute; - top: -6px; - right: -10px; - min-width: 16px; - height: 16px; - padding: 0 4px; - background: #EF4444; + top: -4px; + right: -6px; + min-width: 18px; + height: 18px; + padding: 0 5px; + background: var(--color-accent-red); color: #fff; border-radius: 10px; font-size: 10px; - font-weight: 600; + font-weight: 700; display: flex; align-items: center; justify-content: center; line-height: 1; + border: 2px solid #fff; } diff --git a/frontend-patient/src/components/layout/TabBar.tsx b/frontend-patient/src/components/layout/TabBar.tsx index 02b4691..a3859fc 100644 --- a/frontend-patient/src/components/layout/TabBar.tsx +++ b/frontend-patient/src/components/layout/TabBar.tsx @@ -1,7 +1,48 @@ import { useNavigate, useLocation } from 'react-router-dom'; -import { NAV_ITEMS } from '@/utils/constants'; import styles from './TabBar.module.css'; +const NAV_ITEMS = [ + { + path: '/home', + label: '首页', + svg: ( + + + + + ), + }, + { + path: '/health', + label: '健康', + svg: ( + + + + ), + }, + { + path: '/services', + label: '服务', + svg: ( + + + + + ), + }, + { + path: '/profile', + label: '我的', + svg: ( + + + + + ), + }, +]; + export function TabBar() { const navigate = useNavigate(); const location = useLocation(); @@ -16,7 +57,7 @@ export function TabBar() { className={`${styles.tab} ${isActive ? styles.tabActive : ''}`} onClick={() => navigate(item.path)} > - {item.icon} + {item.svg} {item.label} ); diff --git a/frontend-patient/src/pages/auth/LoginPage.tsx b/frontend-patient/src/pages/auth/LoginPage.tsx index ad047f8..dede7d5 100644 --- a/frontend-patient/src/pages/auth/LoginPage.tsx +++ b/frontend-patient/src/pages/auth/LoginPage.tsx @@ -48,7 +48,11 @@ export function LoginPage() { return (
-
+
+ + + +

健康管家

心脏健康管理平台

diff --git a/frontend-patient/src/pages/exercise-diet/ExerciseDietPage.module.css b/frontend-patient/src/pages/exercise-diet/ExerciseDietPage.module.css index 67c3a73..8af8093 100644 --- a/frontend-patient/src/pages/exercise-diet/ExerciseDietPage.module.css +++ b/frontend-patient/src/pages/exercise-diet/ExerciseDietPage.module.css @@ -1,17 +1,17 @@ .tabs { display: flex; gap: 8px; margin-bottom: 16px; } -.tab { padding: 6px 14px; border-radius: var(--radius-full); font-size: var(--font-size-sm); background: var(--color-bg-secondary); color: var(--color-text-secondary); } +.tab { padding: 6px 14px; border-radius: var(--radius-full); font-size: var(--font-size-sm); background: var(--color-bg-secondary); color: var(--color-text-secondary); font-weight: 500; } .tabActive { background: var(--color-primary); color: var(--color-text-inverse); } -.sectionTitle { font-size: var(--font-size-base); font-weight: 600; margin: 16px 0 8px; } +.sectionTitle { font-size: var(--font-size-base); font-weight: 700; margin: 16px 0 8px; } .recCard { margin-bottom: 8px; } .recHeader { display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px; font-weight: 600; font-size: var(--font-size-sm); } -.suitBadge { font-size: var(--font-size-xs); padding: 2px 8px; border-radius: var(--radius-sm); } +.suitBadge { font-size: var(--font-size-xs); padding: 2px 8px; border-radius: var(--radius-sm); font-weight: 600; } .suitYes { background: var(--color-success-bg); color: var(--color-success); } .suitNo { background: var(--color-danger-bg); color: var(--color-danger); } .notSuitable { opacity: 0.5; } .recMeta { font-size: var(--font-size-xs); color: var(--color-text-tertiary); } -.recDesc { font-size: var(--font-size-xs); color: var(--color-text-secondary); margin: 6px 0; } +.recDesc { font-size: var(--font-size-xs); color: var(--color-text-secondary); margin: 6px 0; line-height: 1.5; } .foodTags { display: flex; gap: 6px; flex-wrap: wrap; } -.foodTag { padding: 2px 8px; font-size: var(--font-size-xs); background: var(--color-primary-bg); color: var(--color-primary); border-radius: var(--radius-sm); } +.foodTag { padding: 2px 8px; font-size: var(--font-size-xs); background: var(--color-primary-bg); color: var(--color-primary); border-radius: var(--radius-sm); font-weight: 500; } .addCard { margin-bottom: 12px; display: flex; flex-direction: column; gap: 10px; } .addRow { display: flex; gap: 8px; align-items: center; } .select { padding: 10px 12px; border: 1.5px solid var(--color-border); border-radius: var(--radius-md); font-size: var(--font-size-sm); background: var(--color-bg); outline: none; } diff --git a/frontend-patient/src/pages/exercise-diet/ExerciseDietPage.tsx b/frontend-patient/src/pages/exercise-diet/ExerciseDietPage.tsx index 7eb7a32..0096697 100644 --- a/frontend-patient/src/pages/exercise-diet/ExerciseDietPage.tsx +++ b/frontend-patient/src/pages/exercise-diet/ExerciseDietPage.tsx @@ -72,7 +72,7 @@ export function ExerciseDietPage() { {recommendations.map((r, i) => (
- {r.icon} {r.name} + {r.name} {r.suitable ? '适合' : '不适合'} @@ -83,7 +83,7 @@ export function ExerciseDietPage() {

饮食推荐

{dietRecommendations.slice(0, 3).map((d, i) => ( -
🍽️ {d.title}
+
{d.title}

{d.description}

{d.recommendedFoods.slice(0, 3).map((f, j) => ( @@ -143,7 +143,7 @@ export function ExerciseDietPage() { {diets.length === 0 ? : diets.slice(0, 10).map((d) => ( -
{d.mealType === 'breakfast' ? '🌅' : d.mealType === 'lunch' ? '🌞' : d.mealType === 'dinner' ? '🌙' : '🍪'} {d.foods.map((f) => f.name).join(', ')}
+
{d.foods.map((f) => f.name).join(', ')}
{d.totalCalories}kcal · {formatDate(d.date, 'MM-DD')}
))} diff --git a/frontend-patient/src/pages/health/HealthHubPage.module.css b/frontend-patient/src/pages/health/HealthHubPage.module.css index bea73f5..1cbce6f 100644 --- a/frontend-patient/src/pages/health/HealthHubPage.module.css +++ b/frontend-patient/src/pages/health/HealthHubPage.module.css @@ -1,7 +1,7 @@ .grid { display: grid; grid-template-columns: repeat(3, 1fr); - gap: 10px; + gap: 12px; margin-bottom: 16px; } @@ -9,20 +9,30 @@ display: flex; flex-direction: column; align-items: center; - gap: 6px; - padding: 20px 12px; + gap: 8px; + padding: 18px 12px; background: var(--color-white); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); - transition: transform 0.15s; + transition: transform 0.2s; -webkit-tap-highlight-color: transparent; + position: relative; + overflow: hidden; } -.card:active { transform: scale(0.96); } +.card:active { transform: scale(0.95); } -.cardIcon { font-size: 32px; line-height: 1; } -.cardTitle { font-size: var(--font-size-base); font-weight: 600; } -.cardDesc { font-size: var(--font-size-xs); color: var(--color-text-tertiary); } +.cardIcon { + width: 50px; + height: 50px; + border-radius: 16px; + display: flex; + align-items: center; + justify-content: center; +} + +.cardTitle { font-size: var(--font-size-base); font-weight: 700; color: var(--color-text-primary); } +.cardDesc { font-size: 11px; color: var(--color-text-tertiary); } .extraLinks { display: flex; @@ -36,10 +46,12 @@ gap: 12px; padding: 14px 16px; background: var(--color-white); - border-radius: var(--radius-md); + border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); font-size: var(--font-size-base); + font-weight: 600; -webkit-tap-highlight-color: transparent; + transition: background 0.15s; } -.linkCard:active { background: var(--color-bg); } +.linkCard:active { background: #FAFBFC; } diff --git a/frontend-patient/src/pages/health/HealthHubPage.tsx b/frontend-patient/src/pages/health/HealthHubPage.tsx index f098cfb..9b6199f 100644 --- a/frontend-patient/src/pages/health/HealthHubPage.tsx +++ b/frontend-patient/src/pages/health/HealthHubPage.tsx @@ -1,8 +1,121 @@ import { useNavigate } from 'react-router-dom'; import { PageHeader } from '@/components/layout/PageHeader'; -import { MEASUREMENT_TYPES } from '@/utils/constants'; import styles from './HealthHubPage.module.css'; +const HEALTH_ITEMS = [ + { + path: '/health/records?type=blood_pressure', + label: '血压', + desc: '记录和趋势', + svg: ( + + + + + ), + bg: '#FEE9E9', + }, + { + path: '/health/records?type=heart_rate', + label: '心率', + desc: '记录和趋势', + svg: ( + + + + ), + bg: '#FFF4E5', + }, + { + path: '/health/records?type=blood_sugar', + label: '血糖', + desc: '记录和趋势', + svg: ( + + + + + ), + bg: '#F3E8FF', + }, + { + path: '/health/records?type=spo2', + label: '血氧', + desc: '记录和趋势', + svg: ( + + + + + + ), + bg: '#E6F0FF', + }, + { + path: '/health/records?type=weight', + label: '体重', + desc: '记录和趋势', + svg: ( + + + + + + ), + bg: '#E6F9F2', + }, + { + path: '/health/records?type=steps', + label: '步数', + desc: '记录和趋势', + svg: ( + + + + + ), + bg: '#EEF2FF', + }, +]; + +const QUICK_LINKS = [ + { + label: '健康日历', + path: '/health/calendar', + svg: ( + + + + + + + ), + bg: '#FFF0E0', + }, + { + label: '服药管理', + path: '/health/medications', + svg: ( + + + + + ), + bg: '#FFF4E5', + }, + { + label: '运动饮食', + path: '/health/exercise-diet', + svg: ( + + + + + ), + bg: '#E6F9F2', + }, +]; + export function HealthHubPage() { const navigate = useNavigate(); @@ -10,66 +123,24 @@ export function HealthHubPage() {
- - - - - - + {HEALTH_ITEMS.map((item) => ( + + ))}
- - - + {QUICK_LINKS.map((link) => ( + + ))}
); diff --git a/frontend-patient/src/pages/health/HealthRecordListPage.module.css b/frontend-patient/src/pages/health/HealthRecordListPage.module.css index 6dc8daa..3dc4922 100644 --- a/frontend-patient/src/pages/health/HealthRecordListPage.module.css +++ b/frontend-patient/src/pages/health/HealthRecordListPage.module.css @@ -3,11 +3,12 @@ width: 100%; padding: 12px; margin-bottom: 10px; - background: var(--color-primary); + background: var(--color-primary-gradient); color: var(--color-text-inverse); border-radius: var(--radius-md); font-size: var(--font-size-base); - font-weight: 500; + font-weight: 600; + box-shadow: 0 4px 14px rgba(79,110,247,0.3); } .chartBtn { @@ -20,6 +21,7 @@ border: 1.5px solid var(--color-primary); border-radius: var(--radius-md); font-size: var(--font-size-sm); + font-weight: 600; } .recordCard { @@ -28,7 +30,7 @@ .recordValue { font-size: var(--font-size-xl); - font-weight: 700; + font-weight: 800; color: var(--color-text-primary); margin-bottom: 6px; } diff --git a/frontend-patient/src/pages/health/HealthRecordListPage.tsx b/frontend-patient/src/pages/health/HealthRecordListPage.tsx index ed15e7b..66c12f9 100644 --- a/frontend-patient/src/pages/health/HealthRecordListPage.tsx +++ b/frontend-patient/src/pages/health/HealthRecordListPage.tsx @@ -38,7 +38,7 @@ export function HealthRecordListPage() { {records.length === 0 ? ( - + ) : ( records.map((r) => ( @@ -51,7 +51,7 @@ export function HealthRecordListPage() {
{formatDate(r.recordedAt, 'MM-DD HH:mm')} - {r.source === 'device' ? '📡 设备' : '✋ 手动'} + {r.source === 'device' ? '设备' : '手动'}
diff --git a/frontend-patient/src/pages/home/DeviceBindingPage.tsx b/frontend-patient/src/pages/home/DeviceBindingPage.tsx index 43c4fee..f4c6be7 100644 --- a/frontend-patient/src/pages/home/DeviceBindingPage.tsx +++ b/frontend-patient/src/pages/home/DeviceBindingPage.tsx @@ -36,11 +36,11 @@ export function DeviceBindingPage() {
{devices.length === 0 ? ( - + ) : ( devices.map((d) => ( @@ -51,7 +51,7 @@ export function DeviceBindingPage() { {d.status === 'connected' ? '已连接' : '未连接'} - 🔋 {d.batteryLevel}% + 电量 {d.batteryLevel}%
- {/* Health Overview */}
健康概览 最新记录
-
+
血压 {systolic ? (
- + {systolic} / - + {diastolic}
- ) : --/--} + ) : --/--} mmHg
-
+
心率 - {hrStats?.latest ? Number(hrStats.latest.value) : '--'} + {hrValue ?? '--'} bpm
-
+
血糖 - {sugarStats?.latest ? Number(sugarStats.latest.value) : '--'} + {sugarValue ?? '--'} mmol/L
-
+
血氧 - {spo2Stats?.latest ? Number(spo2Stats.latest.value) : '--'} + {spo2Value ?? '--'} %
- {/* Quick Actions */}
{QUICK_ACTIONS.map((action) => ( ))} diff --git a/frontend-patient/src/pages/medication/MedicationDetailPage.module.css b/frontend-patient/src/pages/medication/MedicationDetailPage.module.css index 7f99e06..83c094b 100644 --- a/frontend-patient/src/pages/medication/MedicationDetailPage.module.css +++ b/frontend-patient/src/pages/medication/MedicationDetailPage.module.css @@ -7,11 +7,11 @@ justify-content: space-between; padding: 8px 0; font-size: var(--font-size-sm); - border-bottom: 1px solid var(--color-border-light); + border-bottom: 1px solid var(--color-divider); color: var(--color-text-secondary); } -.activeBadge { color: var(--color-success); font-weight: 500; } +.activeBadge { color: var(--color-success); font-weight: 600; } .adherenceCard { text-align: center; } @@ -19,7 +19,7 @@ .adherenceRate { font-size: var(--font-size-3xl); - font-weight: 700; + font-weight: 800; color: var(--color-success); margin-bottom: 4px; } diff --git a/frontend-patient/src/pages/medication/MedicationDetailPage.tsx b/frontend-patient/src/pages/medication/MedicationDetailPage.tsx index d12f572..ba4c788 100644 --- a/frontend-patient/src/pages/medication/MedicationDetailPage.tsx +++ b/frontend-patient/src/pages/medication/MedicationDetailPage.tsx @@ -122,7 +122,7 @@ export function MedicationDetailPage() { })}
- 🟢 全勤🟡 漏服⬜ 未开始 + 全勤 漏服 未开始
diff --git a/frontend-patient/src/pages/medication/MedicationEditPage.module.css b/frontend-patient/src/pages/medication/MedicationEditPage.module.css index 997ef91..e6d00c5 100644 --- a/frontend-patient/src/pages/medication/MedicationEditPage.module.css +++ b/frontend-patient/src/pages/medication/MedicationEditPage.module.css @@ -6,7 +6,7 @@ .sectionLabel { font-size: var(--font-size-sm); - font-weight: 500; + font-weight: 600; color: var(--color-text-secondary); display: block; margin-bottom: 8px; diff --git a/frontend-patient/src/pages/medication/MedicationEditPage.tsx b/frontend-patient/src/pages/medication/MedicationEditPage.tsx index afe3d2a..b9fb348 100644 --- a/frontend-patient/src/pages/medication/MedicationEditPage.tsx +++ b/frontend-patient/src/pages/medication/MedicationEditPage.tsx @@ -70,7 +70,7 @@ export function MedicationEditPage() { updateTimeSlot(i, e.target.value)} style={{ flex: 1, padding: '8px 12px', border: '1px solid #ddd', borderRadius: 8, fontSize: 14, fontFamily: 'inherit' }} /> + style={{ background: 'none', border: 'none', color: '#EF4444', fontSize: 18, cursor: 'pointer', padding: 4, fontWeight: 700 }}>×
))} - +
{filtered.length === 0 ? ( - + ) : ( - filtered.map((med) => { - const allTaken = takenMap[med.id]; - return ( - navigate(`/health/medications/${med.id}`)}> -
- {med.drugName} - {med.status === 'active' && !allTaken && } - {med.status === 'active' && allTaken && } -
-
{med.dosage} · {med.frequency} · {med.timeSlots.join(', ')}
- {med.notes &&
{med.notes}
} - {med.status === 'active' && med.endDate && ( -
- 至 {med.endDate} -
+ filtered.map((med) => ( + navigate(`/health/medications/${med.id}`)}> +
+ {med.drugName} + {med.status === 'active' && allTaken(med) && ( + + + )} - - ); - }) +
+
{med.dosage} · {med.frequency}
+ {med.note &&
{med.note}
} +
+ )) )} - +
); } diff --git a/frontend-patient/src/pages/notifications/NotificationListPage.tsx b/frontend-patient/src/pages/notifications/NotificationListPage.tsx index b0fd448..4f62cf8 100644 --- a/frontend-patient/src/pages/notifications/NotificationListPage.tsx +++ b/frontend-patient/src/pages/notifications/NotificationListPage.tsx @@ -76,7 +76,7 @@ export function NotificationListPage() {
{filtered.length === 0 ? ( - + ) : ( filtered.map((n) => (
diff --git a/frontend-patient/src/pages/profile/staticPages.tsx b/frontend-patient/src/pages/profile/staticPages.tsx index a905750..f155008 100644 --- a/frontend-patient/src/pages/profile/staticPages.tsx +++ b/frontend-patient/src/pages/profile/staticPages.tsx @@ -46,7 +46,11 @@ export function AboutPage() {
-
💙
+
+ + + +
健康管家 Demo
v1.0.0-demo
移动端 H5 Web Demo
diff --git a/frontend-patient/src/pages/services/DoctorListPage.module.css b/frontend-patient/src/pages/services/DoctorListPage.module.css index 0284ae8..9e929c5 100644 --- a/frontend-patient/src/pages/services/DoctorListPage.module.css +++ b/frontend-patient/src/pages/services/DoctorListPage.module.css @@ -17,24 +17,26 @@ font-size: var(--font-size-sm); background: var(--color-bg-secondary); color: var(--color-text-secondary); + font-weight: 500; } -.active { background: var(--color-primary-bg); color: var(--color-primary); } +.active { background: var(--color-primary-bg); color: var(--color-primary); font-weight: 600; } .docCard { margin-bottom: 8px; } .docHeader { display: flex; gap: 12px; margin-bottom: 12px; } .avatar { - width: 48px; height: 48px; - border-radius: 50%; + width: 48px; + height: 48px; + border-radius: 16px; background: var(--color-primary-bg); color: var(--color-primary); display: flex; align-items: center; justify-content: center; font-size: var(--font-size-lg); - font-weight: 600; + font-weight: 700; flex-shrink: 0; } @@ -49,7 +51,8 @@ } .onlineDot { - width: 8px; height: 8px; + width: 8px; + height: 8px; border-radius: 50%; background: var(--color-success); } @@ -63,7 +66,7 @@ align-items: center; justify-content: space-between; padding-top: 12px; - border-top: 1px solid var(--color-border-light); + border-top: 1px solid var(--color-divider); } .fee { font-size: var(--font-size-sm); color: var(--color-danger); font-weight: 600; } diff --git a/frontend-patient/src/pages/services/DoctorListPage.tsx b/frontend-patient/src/pages/services/DoctorListPage.tsx index 92b60f1..7019884 100644 --- a/frontend-patient/src/pages/services/DoctorListPage.tsx +++ b/frontend-patient/src/pages/services/DoctorListPage.tsx @@ -28,7 +28,7 @@ export function DoctorListPage() { ))}
{doctors.length === 0 ? ( - + ) : ( doctors.map((doc) => ( diff --git a/frontend-patient/src/pages/services/FollowUpListPage.module.css b/frontend-patient/src/pages/services/FollowUpListPage.module.css index 0c9ba16..f4f134c 100644 --- a/frontend-patient/src/pages/services/FollowUpListPage.module.css +++ b/frontend-patient/src/pages/services/FollowUpListPage.module.css @@ -1,9 +1,9 @@ .tabs { display: flex; gap: 8px; margin-bottom: 14px; } -.tab { padding: 6px 14px; border-radius: var(--radius-full); font-size: var(--font-size-sm); background: var(--color-bg-secondary); color: var(--color-text-secondary); } +.tab { padding: 6px 14px; border-radius: var(--radius-full); font-size: var(--font-size-sm); background: var(--color-bg-secondary); color: var(--color-text-secondary); font-weight: 500; } .tabActive { background: var(--color-primary); color: var(--color-text-inverse); } .card { margin-bottom: 8px; } .cardHeader { display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px; } .title { font-size: var(--font-size-base); font-weight: 600; } .status { font-size: var(--font-size-xs); font-weight: 500; } .meta { font-size: var(--font-size-xs); color: var(--color-text-tertiary); margin-top: 2px; } -.fab { position: fixed; bottom: 80px; right: max(16px, calc((100vw - var(--max-content-width)) / 2 + 16px)); padding: 12px 20px; background: var(--color-primary); color: var(--color-text-inverse); border-radius: var(--radius-full); font-weight: 600; box-shadow: var(--shadow-lg); z-index: 50; } +.fab { position: fixed; bottom: 80px; right: max(16px, calc((100vw - var(--max-content-width)) / 2 + 16px)); padding: 12px 20px; background: var(--color-primary-gradient); color: var(--color-text-inverse); border-radius: var(--radius-full); font-weight: 600; box-shadow: 0 4px 16px rgba(79,110,247,0.35); z-index: 50; } diff --git a/frontend-patient/src/pages/services/FollowUpListPage.tsx b/frontend-patient/src/pages/services/FollowUpListPage.tsx index 839bd16..bdc5235 100644 --- a/frontend-patient/src/pages/services/FollowUpListPage.tsx +++ b/frontend-patient/src/pages/services/FollowUpListPage.tsx @@ -33,7 +33,7 @@ export function FollowUpListPage() {
{filtered.length === 0 ? ( - + ) : ( filtered.map((f) => ( diff --git a/frontend-patient/src/pages/services/ReportListPage.module.css b/frontend-patient/src/pages/services/ReportListPage.module.css index 215a84c..ad2abcf 100644 --- a/frontend-patient/src/pages/services/ReportListPage.module.css +++ b/frontend-patient/src/pages/services/ReportListPage.module.css @@ -1,8 +1,8 @@ .tabs { display: flex; gap: 8px; margin-bottom: 14px; } -.tab { padding: 6px 14px; border-radius: var(--radius-full); font-size: var(--font-size-sm); background: var(--color-bg-secondary); color: var(--color-text-secondary); } +.tab { padding: 6px 14px; border-radius: var(--radius-full); font-size: var(--font-size-sm); background: var(--color-bg-secondary); color: var(--color-text-secondary); font-weight: 500; } .tabActive { background: var(--color-primary); color: var(--color-text-inverse); } .card { margin-bottom: 8px; } .cardHeader { display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px; } .cardTitle { font-size: var(--font-size-base); font-weight: 600; } .cardMeta { display: flex; justify-content: space-between; font-size: var(--font-size-xs); color: var(--color-text-tertiary); } -.fab { position: fixed; bottom: 80px; right: max(16px, calc((100vw - var(--max-content-width)) / 2 + 16px)); padding: 12px 20px; background: var(--color-primary); color: var(--color-text-inverse); border-radius: var(--radius-full); font-weight: 600; box-shadow: var(--shadow-lg); z-index: 50; } +.fab { position: fixed; bottom: 80px; right: max(16px, calc((100vw - var(--max-content-width)) / 2 + 16px)); padding: 12px 20px; background: var(--color-primary-gradient); color: var(--color-text-inverse); border-radius: var(--radius-full); font-weight: 600; box-shadow: 0 4px 16px rgba(79,110,247,0.35); z-index: 50; } diff --git a/frontend-patient/src/pages/services/ReportListPage.tsx b/frontend-patient/src/pages/services/ReportListPage.tsx index 8e086c5..db4d291 100644 --- a/frontend-patient/src/pages/services/ReportListPage.tsx +++ b/frontend-patient/src/pages/services/ReportListPage.tsx @@ -41,7 +41,7 @@ export function ReportListPage() { ))}
{filtered.length === 0 ? ( - + ) : ( filtered.map((r) => ( navigate(`/services/reports/${r.id}`)}> diff --git a/frontend-patient/src/pages/services/ReportUploadPage.tsx b/frontend-patient/src/pages/services/ReportUploadPage.tsx index a9cf46f..014f7b6 100644 --- a/frontend-patient/src/pages/services/ReportUploadPage.tsx +++ b/frontend-patient/src/pages/services/ReportUploadPage.tsx @@ -74,7 +74,9 @@ export function ReportUploadPage() {
fileRef.current?.click()}> - 📷 +
+ +
点击选择报告图片 {files.length > 0 ? `已选 ${files.length} 个文件` : '支持 jpg、png、pdf,可多选'}
@@ -85,9 +87,9 @@ export function ReportUploadPage() { {files.map((file, i) => (
- {file.type.startsWith('image/') ? '🖼' : '📄'} {file.name} ({(file.size / 1024).toFixed(0)}KB) + {file.name} ({(file.size / 1024).toFixed(0)}KB) - +
))}
diff --git a/frontend-patient/src/pages/services/ServicesHubPage.module.css b/frontend-patient/src/pages/services/ServicesHubPage.module.css index 7088ff5..d49a5cf 100644 --- a/frontend-patient/src/pages/services/ServicesHubPage.module.css +++ b/frontend-patient/src/pages/services/ServicesHubPage.module.css @@ -6,18 +6,27 @@ .card { display: flex; - flex-direction: column; - align-items: flex-start; - gap: 4px; - padding: 20px; + align-items: center; + gap: 16px; + padding: 20px 18px; background: var(--color-white); - border-radius: var(--radius-lg); + border-radius: var(--radius-xl); box-shadow: var(--shadow-sm); - transition: transform 0.15s; + transition: transform 0.2s; -webkit-tap-highlight-color: transparent; } .card:active { transform: scale(0.98); } -.icon { font-size: 36px; } -.label { font-size: var(--font-size-md); font-weight: 600; } -.desc { font-size: var(--font-size-xs); color: var(--color-text-tertiary); } + +.icon { + width: 52px; + height: 52px; + border-radius: 16px; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; +} + +.label { font-size: var(--font-size-md); font-weight: 700; color: var(--color-text-primary); margin-bottom: 4px; } +.desc { font-size: 12px; color: var(--color-text-tertiary); } diff --git a/frontend-patient/src/pages/services/ServicesHubPage.tsx b/frontend-patient/src/pages/services/ServicesHubPage.tsx index 63adf30..139f989 100644 --- a/frontend-patient/src/pages/services/ServicesHubPage.tsx +++ b/frontend-patient/src/pages/services/ServicesHubPage.tsx @@ -3,9 +3,44 @@ import { PageHeader } from '@/components/layout/PageHeader'; import styles from './ServicesHubPage.module.css'; const SERVICES = [ - { label: '在线问诊', icon: '👨‍⚕️', desc: '图文咨询医生', path: '/services/consultation' }, - { label: '报告解读', icon: '📋', desc: '上传检查报告', path: '/services/reports' }, - { label: '复查管理', icon: '🏥', desc: '管理复查计划', path: '/services/follow-ups' }, + { + label: '在线问诊', + desc: '图文咨询医生', + path: '/services/consultation', + svg: ( + + + + + ), + bg: '#E6F0FF', + }, + { + label: '报告解读', + desc: '上传检查报告', + path: '/services/reports', + svg: ( + + + + + + + ), + bg: '#F3E8FF', + }, + { + label: '复查管理', + desc: '管理复查计划', + path: '/services/follow-ups', + svg: ( + + + + + ), + bg: '#FEE9E9', + }, ]; export function ServicesHubPage() { @@ -17,9 +52,11 @@ export function ServicesHubPage() {
{SERVICES.map((s) => ( ))}
diff --git a/frontend-patient/src/utils/constants.ts b/frontend-patient/src/utils/constants.ts index 342e645..8f960c9 100644 --- a/frontend-patient/src/utils/constants.ts +++ b/frontend-patient/src/utils/constants.ts @@ -1,19 +1,19 @@ export const MEASUREMENT_TYPES = { - blood_pressure: { label: '血压', unit: 'mmHg', icon: '💓', color: '#EF4444' }, - heart_rate: { label: '心率', unit: 'bpm', icon: '❤️', color: '#F59E0B' }, - blood_sugar: { label: '血糖', unit: 'mmol/L', icon: '🩸', color: '#8B5CF6' }, - spo2: { label: '血氧', unit: '%', icon: '🫁', color: '#06B6D4' }, - weight: { label: '体重', unit: 'kg', icon: '⚖️', color: '#10B981' }, - steps: { label: '步数', unit: '步', icon: '🚶', color: '#6366F1' }, + blood_pressure: { label: '血压', unit: 'mmHg', color: '#EF4444' }, + heart_rate: { label: '心率', unit: 'bpm', color: '#F59E0B' }, + blood_sugar: { label: '血糖', unit: 'mmol/L', color: '#8B5CF6' }, + spo2: { label: '血氧', unit: '%', color: '#06B6D4' }, + weight: { label: '体重', unit: 'kg', color: '#10B981' }, + steps: { label: '步数', unit: '步', color: '#6366F1' }, } as const; export type MeasurementType = keyof typeof MEASUREMENT_TYPES; export const NAV_ITEMS = [ - { path: '/home', label: '首页', icon: '🏠', activeIcon: '🏠' }, - { path: '/health', label: '健康', icon: '💊', activeIcon: '💊' }, - { path: '/services', label: '服务', icon: '👨‍⚕️', activeIcon: '👨‍⚕️' }, - { path: '/profile', label: '我的', icon: '👤', activeIcon: '👤' }, + { path: '/home', label: '首页' }, + { path: '/health', label: '健康' }, + { path: '/services', label: '服务' }, + { path: '/profile', label: '我的' }, ] as const; export const DEPARTMENT_OPTIONS = [ @@ -64,14 +64,14 @@ export const HEALTH_TIPS = [ ]; export const EXERCISE_RECOMMENDATIONS = [ - { name: '散步', duration: '30-45分钟', frequency: '每天', intensity: '低', suitable: true, caloriesPerHalfHour: 80, icon: '🚶' }, - { name: '太极拳', duration: '20-30分钟', frequency: '每周3-5次', intensity: '低', suitable: true, caloriesPerHalfHour: 120, icon: '🧘' }, - { name: '慢跑', duration: '20-30分钟', frequency: '每周3-4次', intensity: '中', suitable: true, caloriesPerHalfHour: 250, icon: '🏃' }, - { name: '游泳', duration: '30分钟', frequency: '每周2-3次', intensity: '中', suitable: true, caloriesPerHalfHour: 300, icon: '🏊' }, - { name: '骑自行车', duration: '30-60分钟', frequency: '每周3-5次', intensity: '中低', suitable: true, caloriesPerHalfHour: 200, icon: '🚴' }, - { name: '八段锦', duration: '15-20分钟', frequency: '每天', intensity: '低', suitable: true, caloriesPerHalfHour: 90, icon: '🙆' }, - { name: '剧烈跑步', duration: '30分钟', frequency: '每周3次', intensity: '高', suitable: false, caloriesPerHalfHour: 400, icon: '🏃' }, - { name: '举重训练', duration: '45分钟', frequency: '每周3次', intensity: '高', suitable: false, caloriesPerHalfHour: 350, icon: '🏋️' }, + { name: '散步', duration: '30-45分钟', frequency: '每天', intensity: '低', suitable: true, caloriesPerHalfHour: 80 }, + { name: '太极拳', duration: '20-30分钟', frequency: '每周3-5次', intensity: '低', suitable: true, caloriesPerHalfHour: 120 }, + { name: '慢跑', duration: '20-30分钟', frequency: '每周3-4次', intensity: '中', suitable: true, caloriesPerHalfHour: 250 }, + { name: '游泳', duration: '30分钟', frequency: '每周2-3次', intensity: '中', suitable: true, caloriesPerHalfHour: 300 }, + { name: '骑自行车', duration: '30-60分钟', frequency: '每周3-5次', intensity: '中低', suitable: true, caloriesPerHalfHour: 200 }, + { name: '八段锦', duration: '15-20分钟', frequency: '每天', intensity: '低', suitable: true, caloriesPerHalfHour: 90 }, + { name: '剧烈跑步', duration: '30分钟', frequency: '每周3次', intensity: '高', suitable: false, caloriesPerHalfHour: 400 }, + { name: '举重训练', duration: '45分钟', frequency: '每周3次', intensity: '高', suitable: false, caloriesPerHalfHour: 350 }, ]; export const DIET_RECOMMENDATIONS = [ @@ -100,11 +100,19 @@ export const DIET_RECOMMENDATIONS = [ suitable: true, }, { - category: '地中海饮食', - title: '富含蔬果和优质脂肪的饮食模式', - description: '被多项研究证实对心血管健康有益,降低心血管事件风险。', - recommendedFoods: ['橄榄油', '坚果', '深海鱼', '蔬菜', '水果', '全谷物'], - avoidFoods: ['红肉', '加工食品', '含糖饮料'], + category: '优质蛋白', + title: '优先选择优质蛋白来源', + description: '优质蛋白有助于维持肌肉力量和心血管修复,每日蛋白摄入约1.0-1.2g/kg体重。', + recommendedFoods: ['鱼肉', '去皮禽肉', '豆制品', '蛋清'], + avoidFoods: ['红肉', '加工肉制品'], + suitable: true, + }, + { + category: '限制饮酒', + title: '戒烟限酒,保护心血管', + description: '酒精会升高血压、增加心率,加重心脏负担。PCI术后患者建议完全戒酒。', + recommendedFoods: ['白开水', '淡茶', '无糖饮品'], + avoidFoods: ['白酒', '啤酒', '红酒', '含酒精饮料'], suitable: true, }, ];