import { Image } from 'expo-image'; import * as ImagePicker from 'expo-image-picker'; import { useRouter } from 'expo-router'; import React, { useEffect, useState } from 'react'; import { Alert, ImageBackground, ScrollView, StatusBar, StyleSheet, Text, TextInput, TouchableOpacity, View, } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { Images } from '@/constants/images'; import { useAuth } from '@/contexts/AuthContext'; import { uploadFile } from '@/services/base'; import { getUserInfo, updateAvatar, updateNickname, updateUserInfo } from '@/services/user'; interface FormData { nickname: string; avatar: string; sex: number; // 1-男 2-女 3-保密 } export default function ProfileScreen() { const router = useRouter(); const insets = useSafeAreaInsets(); const { refreshUser } = useAuth(); const [formData, setFormData] = useState({ nickname: '', avatar: '', sex: 3, }); const [loading, setLoading] = useState(false); useEffect(() => { loadUserInfo(); }, []); const loadUserInfo = async () => { try { const res = await getUserInfo(); if (res) { setFormData({ nickname: res.nickname || '', avatar: res.avatar || '', sex: (res as any).sex || 3, }); } } catch (error) { console.error('获取用户信息失败:', error); } }; const handleBack = () => { router.back(); }; const handleChooseAvatar = async () => { try { const permissionResult = await ImagePicker.requestMediaLibraryPermissionsAsync(); if (!permissionResult.granted) { Alert.alert('提示', '需要相册权限才能选择头像'); return; } const result = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ['images'], allowsEditing: true, aspect: [1, 1], quality: 0.8, }); if (!result.canceled && result.assets[0]) { const imageUri = result.assets[0].uri; setFormData(prev => ({ ...prev, avatar: imageUri })); } } catch (error) { console.error('选择头像失败:', error); Alert.alert('提示', '选择头像失败'); } }; const handleSexChange = (sex: number) => { setFormData(prev => ({ ...prev, sex })); }; const handleSave = async () => { if (!formData.nickname?.trim()) { Alert.alert('提示', '请输入昵称'); return; } try { setLoading(true); // 如果头像是本地文件(file://开头),需要先上传 let avatarUrl = formData.avatar; if (formData.avatar && formData.avatar.startsWith('file://')) { const uploadedUrl = await uploadFile(formData.avatar, 'avatar'); if (uploadedUrl) { avatarUrl = uploadedUrl; // 更新头像 await updateAvatar(avatarUrl); } else { Alert.alert('提示', '头像上传失败'); setLoading(false); return; } } // 更新昵称 const nicknameRes = await updateNickname(formData.nickname); // 更新其他信息(性别等) const infoRes = await updateUserInfo({ sex: formData.sex } as any); if (nicknameRes || infoRes) { Alert.alert('提示', '保存成功', [ { text: '确定', onPress: () => { refreshUser?.(); router.back(); } } ]); } else { Alert.alert('提示', '保存失败'); } } catch (error) { console.error('保存失败:', error); Alert.alert('提示', '保存失败'); } finally { setLoading(false); } }; return ( {/* 顶部导航 */} 个人资料 {/* 头像 */} 点击更换头像 {/* 表单 */} {/* 昵称 */} 昵称 setFormData(prev => ({ ...prev, nickname: text }))} placeholder="请输入昵称" placeholderTextColor="#999" maxLength={20} /> {/* 性别 */} 性别 handleSexChange(1)} > {formData.sex === 1 && } handleSexChange(2)} > {formData.sex === 2 && } handleSexChange(3)} > {formData.sex === 3 && } 保密 {/* 保存按钮 */} {loading ? '保存中...' : '确定'} ); } const styles = StyleSheet.create({ container: { flex: 1, }, header: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingHorizontal: 10, height: 80, }, backBtn: { width: 40, height: 40, justifyContent: 'center', alignItems: 'center', }, backIcon: { fontSize: 32, color: '#fff', fontWeight: 'bold', }, headerTitle: { fontSize: 16, fontWeight: 'bold', color: '#fff', }, placeholder: { width: 40, }, scrollView: { flex: 1, paddingHorizontal: 20, }, avatarSection: { alignItems: 'center', paddingVertical: 30, }, avatarWrapper: { width: 80, height: 80, borderRadius: 40, borderWidth: 3, borderColor: '#FFE996', overflow: 'hidden', }, avatar: { width: '100%', height: '100%', }, avatarTip: { marginTop: 10, fontSize: 12, color: 'rgba(255,255,255,0.7)', }, formSection: { backgroundColor: 'rgba(255,255,255,0.1)', borderRadius: 10, padding: 15, }, formItem: { flexDirection: 'row', alignItems: 'center', paddingVertical: 15, borderBottomWidth: 1, borderBottomColor: 'rgba(255,255,255,0.2)', }, formLabel: { width: 60, fontSize: 14, color: '#fff', }, formInput: { flex: 1, fontSize: 14, color: '#fff', padding: 0, }, sexOptions: { flex: 1, flexDirection: 'row', alignItems: 'center', }, sexOption: { flexDirection: 'row', alignItems: 'center', marginRight: 20, }, sexOptionActive: {}, radioOuter: { width: 18, height: 18, borderRadius: 9, borderWidth: 2, borderColor: 'rgba(255,255,255,0.5)', justifyContent: 'center', alignItems: 'center', marginRight: 6, }, radioOuterActive: { borderColor: '#FC7D2E', }, radioInner: { width: 10, height: 10, borderRadius: 5, backgroundColor: '#FC7D2E', }, sexText: { fontSize: 14, color: 'rgba(255,255,255,0.7)', }, sexTextActive: { color: '#fff', }, saveBtn: { marginTop: 50, alignItems: 'center', }, saveBtnDisabled: { opacity: 0.6, }, saveBtnBg: { width: 280, height: 60, justifyContent: 'center', alignItems: 'center', }, saveBtnText: { fontSize: 16, fontWeight: 'bold', color: '#fff', textShadowColor: '#000', textShadowOffset: { width: 1, height: 1 }, textShadowRadius: 2, }, });