# 07-个人中心页面 ## 目标 实现 APP 端个人中心和健康档案管理页面。 --- ## UI 设计参考 > 参考设计稿:`files/ui/我的.png` ### 页面布局 | 区域 | 设计要点 | |------|----------| | 顶部 | 绿色背景 `#10B981` + "我的" 标题(白色) | | 用户卡片 | 头像(64px 圆形)+ 姓名 + 基本信息 + 用户ID | | 编辑按钮 | 白色半透明背景,编辑图标 | | 健康管理 | "用药情况" 入口(带角标 "12条") | | 设置列表 | 消息通知、隐私设置、通用设置 | ### 用户卡片样式 ```typescript const userCardStyles = { container: { backgroundColor: '#10B981', padding: 20, borderRadius: 16, }, avatar: { width: 64, height: 64, borderRadius: 32, backgroundColor: 'rgba(255,255,255,0.2)', }, nickname: { color: '#FFFFFF', fontSize: 20, fontWeight: '600', }, basicInfo: { color: '#FFFFFF', fontSize: 14, }, userId: { color: 'rgba(255,255,255,0.7)', fontSize: 12, }, } ``` ### 列表项样式 | 元素 | 样式 | |------|------| | 图标背景 | 40px 圆形 | | 用药情况 | `#DCFCE7` 背景,`#10B981` 图标 | | 消息通知 | `#DCFCE7` 背景,铃铛图标 | | 隐私设置 | `#DCFCE7` 背景,盾牌图标 | | 通用设置 | `#DCFCE7` 背景,齿轮图标 | | 角标 | 灰色文字 `#6B7280` | | 右箭头 | 灰色 `#9CA3AF` | ```typescript const listItemStyles = { container: { backgroundColor: '#FFFFFF', paddingVertical: 16, paddingHorizontal: 16, borderRadius: 12, }, iconContainer: { width: 40, height: 40, borderRadius: 20, backgroundColor: '#DCFCE7', justifyContent: 'center', alignItems: 'center', }, iconColor: '#10B981', title: { fontSize: 16, color: '#1F2937', }, description: { fontSize: 13, color: '#6B7280', }, badge: { fontSize: 13, color: '#6B7280', }, } ``` --- ## 实现要点 1. **用户信息卡片**:显示头像、昵称、手机号 2. **功能菜单列表**:使用 List 组件展示菜单项 3. **健康档案**:展示基础信息、体质、病史等 --- ## 关键代码示例 ### 个人中心页面 ```typescript // src/screens/profile/ProfileHomeScreen.tsx import React from 'react' import { View, ScrollView, StyleSheet, Alert } from 'react-native' import { Text, Avatar, Card, List, Button, Divider } from 'react-native-paper' import { useNavigation } from '@react-navigation/native' import { useUserStore } from '../../stores/userStore' import type { ProfileStackParamList } from '../../navigation/types' import type { NativeStackNavigationProp } from '@react-navigation/native-stack' type NavigationProp = NativeStackNavigationProp const ProfileHomeScreen = () => { const navigation = useNavigation() const { user, logout } = useUserStore() const handleLogout = () => { Alert.alert('提示', '确定要退出登录吗?', [ { text: '取消', style: 'cancel' }, { text: '确定', style: 'destructive', onPress: () => logout(), }, ]) } return ( {/* 用户信息卡片 */} {user?.nickname || '用户'} {user?.phone} {/* 功能菜单 */} } right={(props) => } onPress={() => navigation.navigate('HealthRecord')} /> } right={(props) => } onPress={() => navigation.getParent()?.navigate('ConstitutionTab')} /> } right={(props) => } onPress={() => navigation.getParent()?.navigate('ConstitutionTab', { screen: 'ConstitutionQuestions', })} /> } right={(props) => } onPress={() => Alert.alert( '关于我们', '健康AI助手是一款智能健康咨询应用,结合中医体质辨识理论,为您提供个性化的健康建议。\n\n版本:1.0.0' ) } /> {/* 退出登录 */} ) } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#f5f5f5', }, userCard: { margin: 16, }, userContent: { flexDirection: 'row', alignItems: 'center', }, avatar: { backgroundColor: '#667eea', }, userInfo: { marginLeft: 16, }, nickname: { fontSize: 20, fontWeight: 'bold', }, phone: { color: '#999', marginTop: 4, }, menuCard: { marginHorizontal: 16, }, logoutContainer: { padding: 24, alignItems: 'center', }, }) export default ProfileHomeScreen ``` ### 健康档案页面 ```typescript // src/screens/profile/HealthRecordScreen.tsx import React, { useState, useEffect } from 'react' import { View, ScrollView, StyleSheet } from 'react-native' import { Text, Card, Chip, ActivityIndicator } from 'react-native-paper' import { getHealthProfile } from '../../api/user' const genderMap: Record = { male: '男', female: '女', } const HealthRecordScreen = () => { const [profile, setProfile] = useState(null) const [loading, setLoading] = useState(true) useEffect(() => { loadProfile() }, []) const loadProfile = async () => { try { const data = await getHealthProfile() setProfile(data) } finally { setLoading(false) } } if (loading) { return ( ) } return ( {/* 基础信息 */} {profile?.basic_info ? ( ) : ( 暂无基础信息 )} {/* 体质信息 */} {profile?.constitution ? ( {profile.constitution.primary_name} {profile.constitution.primary_description} 测评时间:{profile.constitution.assessed_at} ) : ( 暂无体质测评记录 )} {/* 既往病史 */} {profile?.medical_history?.length > 0 ? ( {profile.medical_history.map((item: any) => ( {item.disease_name} ))} ) : ( 暂无病史记录 )} {/* 过敏信息 */} {profile?.allergy_records?.length > 0 ? ( {profile.allergy_records.map((item: any) => ( {item.allergen} ))} ) : ( 暂无过敏信息 )} ) } const InfoItem = ({ label, value }: { label: string; value?: string }) => ( {label} {value || '-'} ) const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#f5f5f5', padding: 16, }, loadingContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', }, card: { marginBottom: 16, }, infoGrid: { flexDirection: 'row', flexWrap: 'wrap', }, infoItem: { width: '50%', marginBottom: 12, }, infoLabel: { fontSize: 13, color: '#999', marginBottom: 4, }, infoValue: { fontSize: 15, }, emptyText: { color: '#999', textAlign: 'center', padding: 16, }, constitutionInfo: { alignItems: 'center', }, constitutionChip: { backgroundColor: '#667eea', marginBottom: 12, }, constitutionDesc: { color: '#666', textAlign: 'center', lineHeight: 22, }, assessedTime: { marginTop: 12, fontSize: 12, color: '#999', }, tagList: { flexDirection: 'row', flexWrap: 'wrap', gap: 8, }, tag: { marginBottom: 8, }, allergyTag: { backgroundColor: '#fef0f0', }, }) export default HealthRecordScreen ``` --- ## 需要创建的文件 | 文件路径 | 说明 | |----------|------| | `src/api/user.ts` | 用户 API | | `src/screens/profile/ProfileHomeScreen.tsx` | 个人中心 | | `src/screens/profile/HealthRecordScreen.tsx` | 健康档案 | --- ## 验收标准 - [ ] 用户信息正确显示 - [ ] 菜单导航正常 - [ ] 健康档案数据完整 - [ ] 退出登录功能正常 --- ## 预计耗时 25-30 分钟 --- ## 完成 恭喜!APP 端开发任务全部完成! --- ## 后续工作 1. **测试**:在真机和模拟器上进行完整功能测试 2. **优化**:性能优化、动画效果、错误处理 3. **打包**: - Android: `cd android && ./gradlew assembleRelease` - iOS: 使用 Xcode Archive 4. **发布**:提交到应用商店审核