Files
mini-programs/src/pages/userInfo/edit/index.tsx
张成 24b957fad4 11
2025-09-06 23:16:42 +08:00

240 lines
7.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { useState, useEffect } from 'react';
import { View, Text, Image, ScrollView, Button, Input, Textarea } from '@tarojs/components';
import Taro from '@tarojs/taro';
import './index.scss';
import GuideBar from '@/components/GuideBar';
import { UserInfo } from '@/components/UserInfo';
import { UserService } from '@/services/userService';
const EditProfilePage: React.FC = () => {
// 用户信息状态
const [user_info, setUserInfo] = useState<UserInfo>({
id: '1',
nickname: '188的王晨',
avatar: require('../../../static/userInfo/default_avatar.svg'),
bio: '网球入坑两年,偏好双打,正手进攻型选手\n平时在张江、世纪公园附近活动欢迎约球\n不卷分数但认真对待每一拍每一场球都想打得开心。有时候也会带相机来拍点照片📸',
location: '上海黄浦',
occupation: '互联网从业者',
ntrp_level: 'NTRP 4.0'
});
// 表单状态
const [form_data, setFormData] = useState({
nickname: user_info.nickname,
bio: user_info.bio,
location: user_info.location,
occupation: user_info.occupation,
ntrp_level: user_info.ntrp_level,
phone: '', // 新增手机号字段
gender: '' // 新增性别字段
});
// 页面加载时初始化数据
useEffect(() => {
// 这里应该从store或API获取当前用户信息
// const currentUser = getUserInfo();
// setUserInfo(currentUser);
// setFormData(currentUser);
}, []);
// 处理输入变化
const handle_input_change = (field: string, value: string) => {
setFormData(prev => ({
...prev,
[field]: value
}));
};
// 处理头像上传
const handle_avatar_upload = () => {
Taro.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success: async (res) => {
const tempFilePath = res.tempFilePaths[0];
try {
const avatar_url = await UserService.upload_avatar(tempFilePath);
setUserInfo(prev => ({ ...prev, avatar: avatar_url }));
Taro.showToast({
title: '头像上传成功',
icon: 'success'
});
} catch (error) {
console.error('头像上传失败:', error);
Taro.showToast({
title: '头像上传失败',
icon: 'none'
});
}
}
});
};
// 处理保存
const handle_save = async () => {
// 验证表单
if (!form_data.nickname.trim()) {
Taro.showToast({
title: '请输入昵称',
icon: 'none'
});
return;
}
try {
await UserService.save_user_info(form_data);
Taro.showToast({
title: '保存成功',
icon: 'success'
});
Taro.navigateBack();
} catch (error) {
console.error('保存失败:', error);
Taro.showToast({
title: '保存失败',
icon: 'none'
});
}
};
// 处理返回
const handle_back = () => {
Taro.navigateBack();
};
return (
<View className="edit_profile_page">
{/* 主要内容 */}
<ScrollView className="main_content" scrollY>
{/* 头部操作栏 */}
<View className="header_section">
<Button className="back_button" onClick={handle_back}>
<Image
className="back_icon"
src={require('../../../static/detail/icon-arrow-left.svg')}
/>
</Button>
<Text className="page_title"></Text>
<Button className="save_button" onClick={handle_save}>
<Text className="save_text"></Text>
</Button>
</View>
{/* 头像编辑区域 */}
<View className="avatar_section">
<View className="avatar_container" onClick={handle_avatar_upload}>
<Image className="avatar" src={user_info.avatar} />
<View className="avatar_overlay">
<Image
className="upload_icon"
src={require('../../../static/publishBall/icon-upload.svg')}
/>
</View>
</View>
<Text className="avatar_tip"></Text>
</View>
{/* 基本信息编辑 */}
<View className="form_section">
{/* 昵称 */}
<View className="form_item">
<Text className="form_label"></Text>
<Input
className="form_input"
value={form_data.nickname}
placeholder="请输入昵称"
onInput={(e) => handle_input_change('nickname', e.detail.value)}
/>
</View>
{/* 个人简介 */}
<View className="form_item">
<Text className="form_label"></Text>
<Textarea
className="form_textarea"
value={form_data.bio}
placeholder="介绍一下自己吧..."
maxlength={200}
onInput={(e) => handle_input_change('bio', e.detail.value)}
/>
<Text className="char_count">{form_data.bio.length}/200</Text>
</View>
{/* 所在地区 */}
<View className="form_item">
<Text className="form_label"></Text>
<Input
className="form_input"
value={form_data.location}
placeholder="请输入所在地区"
onInput={(e) => handle_input_change('location', e.detail.value)}
/>
</View>
{/* 职业 */}
<View className="form_item">
<Text className="form_label"></Text>
<Input
className="form_input"
value={form_data.occupation}
placeholder="请输入职业"
onInput={(e) => handle_input_change('occupation', e.detail.value)}
/>
</View>
{/* 手机号 */}
<View className="form_item">
<Text className="form_label"></Text>
<Input
className="form_input"
value={form_data.phone}
placeholder="请输入手机号"
type="number"
maxlength={11}
onInput={(e) => handle_input_change('phone', e.detail.value)}
/>
</View>
{/* NTRP等级 */}
<View className="form_item">
<Text className="form_label">NTRP等级</Text>
<View className="level_selector">
{['1.0', '1.5', '2.0', '2.5', '3.0', '3.5', '4.0', '4.5', '5.0'].map((level) => (
<View
key={level}
className={`level_item ${form_data.ntrp_level.includes(level) ? 'selected' : ''}`}
onClick={() => handle_input_change('ntrp_level', `NTRP ${level}`)}
>
<Text className="level_text">{level}</Text>
</View>
))}
</View>
</View>
{/* 性别 */}
<View className="form_item">
<Text className="form_label"></Text>
<View className="gender_selector">
<View
className={`gender_item ${form_data.gender === '男' ? 'selected' : ''}`}
onClick={() => handle_input_change('gender', '男')}
>
<Text className="gender_text"></Text>
</View>
<View
className={`gender_item ${form_data.gender === '女' ? 'selected' : ''}`}
onClick={() => handle_input_change('gender', '女')}
>
<Text className="gender_text"></Text>
</View>
</View>
</View>
</View>
</ScrollView>
<GuideBar currentPage='personal' />
</View>
);
};
export default EditProfilePage;