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 { getToken } from "@/services/http"; 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.4, // 服务器限制1MB,降低质量确保不超限 }); 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); // 如果头像是本地文件(非http开头),需要先上传 let avatarUrl = formData.avatar; console.log("[profile] 头像URI:", formData.avatar?.substring(0, 100)); if (formData.avatar && !formData.avatar.startsWith("http")) { const token = getToken(); const uploadResult = await uploadFile(formData.avatar, "avatar", token || undefined); if (typeof uploadResult === "string") { avatarUrl = uploadResult; await updateAvatar(avatarUrl); } else { Alert.alert("头像上传失败", uploadResult.error); 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, }, });