优化个人页

This commit is contained in:
2025-10-17 16:24:07 +08:00
parent 8f688378e1
commit f3ab0020d3
7 changed files with 549 additions and 429 deletions

View File

@@ -3,53 +3,36 @@ import { View, Text, Image, ScrollView, Button } from "@tarojs/components";
import { PopupPicker } from "@/components/Picker/index";
import Taro from "@tarojs/taro";
import "./index.scss";
import { UserInfo } from "@/components/UserInfo";
import { UserService, PickerOption } from "@/services/userService";
import { clear_login_state } from "@/services/loginService";
import { convert_db_gender_to_display } from "@/utils/genderUtils";
import { EditModal } from "@/components";
import img from "@/config/images";
import CommonDialog from "@/components/CommonDialog";
import { useUserActions, useUserInfo } from "@/store/userStore";
import { UserInfoType } from "@/services/userService";
const EditProfilePage: React.FC = () => {
// 用户信息状态
const [user_info, setUserInfo] = useState<UserInfo>({
id: "1",
nickname: "加载中...",
avatar: require("@/static/userInfo/default_avatar.svg"),
join_date: "加载中...",
stats: {
following: 0,
friends: 0,
hosted: 0,
participated: 0,
},
personal_profile: "加载中...",
occupation: "加载中...",
ntrp_level: "NTRP 3.0",
phone: "",
gender: "",
country: "",
province: "",
city: "",
});
const { updateUserInfo } = useUserActions();
// 直接从store获取用户信息确保响应式更新
const user_info = useUserInfo();
// 表单状态
// 表单状态基于store中的用户信息初始化
const [form_data, setFormData] = useState({
nickname: "",
personal_profile: "",
occupation: "",
ntrp_level: "4.0",
phone: "",
gender: "",
birthday: "2000-01-01",
country: "",
province: "",
city: "",
nickname: (user_info as UserInfoType)?.nickname || "",
personal_profile: (user_info as UserInfoType)?.personal_profile || "",
occupation: (user_info as UserInfoType)?.occupation || "",
ntrp_level: (user_info as UserInfoType)?.ntrp_level || "4.0",
phone: (user_info as UserInfoType)?.phone || "",
gender: (user_info as UserInfoType)?.gender || "",
birthday: (user_info as UserInfoType)?.birthday || "2000-01-01",
country: (user_info as UserInfoType)?.country || "",
province: (user_info as UserInfoType)?.province || "",
city: (user_info as UserInfoType)?.city || "",
});
// 加载状态
const [loading, setLoading] = useState(true);
const [loading, setLoading] = useState(false);
const [showLogoutDialog, setShowLogoutDialog] = useState(false);
// 编辑弹窗状态
@@ -68,11 +51,28 @@ const EditProfilePage: React.FC = () => {
// 城市数据
const [cities, setCities] = useState<PickerOption[]>([]);
// 监听store中的用户信息变化同步到表单状态
useEffect(() => {
if (user_info && Object.keys(user_info).length > 0) {
setFormData({
nickname: (user_info as UserInfoType)?.nickname || "",
personal_profile: (user_info as UserInfoType)?.personal_profile || "",
occupation: (user_info as UserInfoType)?.occupation || "",
ntrp_level: (user_info as UserInfoType)?.ntrp_level || "4.0",
phone: (user_info as UserInfoType)?.phone || "",
gender: (user_info as UserInfoType)?.gender || "",
birthday: (user_info as UserInfoType)?.birthday || "2000-01-01",
country: (user_info as UserInfoType)?.country || "",
province: (user_info as UserInfoType)?.province || "",
city: (user_info as UserInfoType)?.city || "",
});
}
}, [user_info]);
// 页面加载时初始化数据
useEffect(() => {
load_user_info();
getProfessions();
getCities();
getProfessions();
}, []);
const getProfessions = async () => {
@@ -93,34 +93,34 @@ const EditProfilePage: React.FC = () => {
};
// 加载用户信息
const load_user_info = async () => {
try {
setLoading(true);
const user_data = await UserService.get_user_info();
setUserInfo(user_data);
setFormData({
nickname: user_data.nickname || "",
personal_profile: user_data.personal_profile || "",
occupation: user_data.occupation || "",
ntrp_level: user_data.ntrp_level || "NTRP 4.0",
phone: user_data.phone || "",
gender: user_data.gender || "",
birthday: user_data.birthday || "",
country: user_data.country || "",
province: user_data.province || "",
city: user_data.city || "",
});
} catch (error) {
console.error("加载用户信息失败:", error);
Taro.showToast({
title: "加载用户信息失败",
icon: "error",
duration: 2000,
});
} finally {
setLoading(false);
}
};
// const load_user_info = async () => {
// try {
// setLoading(true);
// const user_data = await UserService.get_user_info();
// setUserInfo(user_data);
// setFormData({
// nickname: user_data.nickname || "",
// personal_profile: user_data.personal_profile || "",
// occupation: user_data.occupation || "",
// ntrp_level: user_data.ntrp_level || "NTRP 4.0",
// phone: user_data.phone || "",
// gender: user_data.gender || "",
// birthday: user_data.birthday || "",
// country: user_data.country || "",
// province: user_data.province || "",
// city: user_data.city || "",
// });
// } catch (error) {
// console.error("加载用户信息失败:", error);
// Taro.showToast({
// title: "加载用户信息失败",
// icon: "error",
// duration: 2000,
// });
// } finally {
// setLoading(false);
// }
// };
// 处理头像上传
const handle_avatar_upload = () => {
@@ -184,11 +184,10 @@ const EditProfilePage: React.FC = () => {
try {
// 调用更新用户信息接口,只传递修改的字段
const update_data = { [editing_field]: value };
await UserService.update_user_info(update_data);
await updateUserInfo(update_data);
// 更新本地状态
// 更新表单状态store会自动更新
setFormData((prev) => ({ ...prev, [editing_field]: value }));
setUserInfo((prev) => ({ ...prev, [editing_field]: value }));
// 关闭弹窗
setEditModalVisible(false);
@@ -224,20 +223,18 @@ const EditProfilePage: React.FC = () => {
field !== null &&
!Array.isArray(field)
) {
await UserService.update_user_info({ ...field });
// 更新本地状态
await updateUserInfo({ ...field });
// 更新表单状态store会自动更新
setFormData((prev) => ({ ...prev, ...field }));
setUserInfo((prev) => ({ ...prev, ...field }));
} else {
// 调用更新用户信息接口,只传递修改的字段
const update_data = { [field as string]: value };
await UserService.update_user_info(update_data);
await updateUserInfo(update_data);
// 更新本地状态
// 更新表单状态store会自动更新
setFormData((prev) => ({ ...prev, [field as string]: value }));
setUserInfo((prev) => ({ ...prev, [field as string]: value }));
}
// 显示成功提示
Taro.showToast({
title: "保存成功",
@@ -364,7 +361,7 @@ const EditProfilePage: React.FC = () => {
<View className="avatar_container" onClick={handle_avatar_upload}>
<Image
className="avatar"
src={user_info.avatar}
src={(user_info as UserInfoType)?.avatar_url || ""}
mode="aspectFill"
/>
<View className="avatar_overlay">
@@ -393,7 +390,7 @@ const EditProfilePage: React.FC = () => {
</View>
<View className="item_right">
<Text className="item_value">
{form_data.nickname || "188的王晨"}
{form_data.nickname || ""}
</Text>
<Image
className="arrow_icon"
@@ -648,6 +645,8 @@ const EditProfilePage: React.FC = () => {
{/* 生日选择弹窗 */}
{birthday_picker_visible && (
<PopupPicker
minYear={1970}
maxYear={new Date().getFullYear()}
showHeader={true}
title="选择生日"
confirmText="保存"
@@ -693,7 +692,7 @@ const EditProfilePage: React.FC = () => {
],
]}
type="ntrp"
img={user_info.avatar}
img={(user_info as UserInfoType)?.avatar_url}
visible={ntrp_picker_visible}
setvisible={setNtrpPickerVisible}
value={[form_data.ntrp_level]}

View File

@@ -3,12 +3,14 @@ import { View, Text, Image, ScrollView } from "@tarojs/components";
import Taro, { useDidShow } from "@tarojs/taro";
import "./index.scss";
import GuideBar from "@/components/GuideBar";
import { UserInfoCard, UserInfo } from "@/components/UserInfo/index";
import { UserService } from "@/services/userService";
import { UserInfoCard } from "@/components/UserInfo/index";
import { UserService, UserInfo } from "@/services/userService";
import ListContainer from "@/container/listContainer";
import { TennisMatch } from "@/../types/list/types";
import { withAuth, NTRPTestEntryCard } from "@/components";
import { EvaluateScene } from "@/store/evaluateStore";
import { useUserInfo } from "@/store/userStore";
import { UserInfoType } from "@/services/userService";
const MyselfPage: React.FC = () => {
// 获取页面参数
@@ -18,33 +20,14 @@ const MyselfPage: React.FC = () => {
// 判断是否为当前用户
const is_current_user = !user_id;
// 用户信息状态
const [user_info, set_user_info] = useState<UserInfo>({
id: "",
nickname: "加载中...",
avatar: require("@/static/userInfo/default_avatar.svg"),
join_date: "加载中...",
stats: {
following: 0,
friends: 0,
hosted: 0,
participated: 0,
},
bio: "加载中...",
city: "加载中...",
occupation: "加载中...",
ntrp_level: "NTRP 3.0",
personal_profile: "加载中...",
gender: "",
country: "",
province: "",
});
// 直接从store获取用户信息确保响应式更新
const user_info = useUserInfo();
// 球局记录状态
const [game_records, set_game_records] = useState<TennisMatch[]>([]);
// 往期球局
const [ended_game_records, setEndedGameRecords] = useState<TennisMatch[]>([]);
const [loading, set_loading] = useState(true);
const [loading, set_loading] = useState(false);
// 关注状态
const [is_following, setIsFollowing] = useState(false);
@@ -55,37 +38,37 @@ const MyselfPage: React.FC = () => {
);
// 加载用户数据
const load_user_data = async () => {
try {
set_loading(true);
// const load_user_data = async () => {
// try {
// set_loading(true);
// 获取用户信息(包含统计数据)
const user_data = await UserService.get_user_info();
set_user_info(user_data);
// let games_data;
// if (active_tab === "hosted") {
// games_data = await UserService.get_hosted_games(user_id);
// } else {
// games_data = await UserService.get_participated_games(user_id);
// }
// set_game_records(games_data);
} catch (error) {
console.error("加载用户数据失败:", error);
Taro.showToast({
title: "加载失败,请重试",
icon: "error",
duration: 2000,
});
} finally {
set_loading(false);
}
};
// // 获取用户信息(包含统计数据)
// const user_data = await UserService.get_user_info();
// set_user_info(user_data);
// // let games_data;
// // if (active_tab === "hosted") {
// // games_data = await UserService.get_hosted_games(user_id);
// // } else {
// // games_data = await UserService.get_participated_games(user_id);
// // }
// // set_game_records(games_data);
// } catch (error) {
// console.error("加载用户数据失败:", error);
// Taro.showToast({
// title: "加载失败,请重试",
// icon: "error",
// duration: 2000,
// });
// } finally {
// set_loading(false);
// }
// };
useEffect(() => {
if (user_info.id) {
load_game_data(); // 在 user_info 更新后调用
}
}, [user_info]);
// useEffect(() => {
// if (user_info.id) {
// load_game_data(); // 在 user_info 更新后调用
// }
// }, [user_info]);
// 页面加载时获取数据
// useEffect(() => {
@@ -93,7 +76,7 @@ const MyselfPage: React.FC = () => {
// }, [user_id]);
useDidShow(() => {
load_user_data(); // 确保从编辑页面返回时刷新数据
// set_user_info(useUserInfo()); // 确保从编辑页面返回时刷新数据
});
// 切换标签页时重新加载球局数据
@@ -196,19 +179,12 @@ const MyselfPage: React.FC = () => {
<View className="main_content">
{/* 用户信息区域 */}
<View className="user_info_section">
{loading ? (
<View className="loading_container">
<Text className="loading_text">...</Text>
</View>
) : (
<UserInfoCard
user_info={user_info}
is_current_user={is_current_user}
is_following={is_following}
on_follow={handle_follow}
set_user_info={set_user_info}
/>
)}
<UserInfoCard
user_info={user_info}
is_current_user={is_current_user}
is_following={is_following}
on_follow={handle_follow}
/>
{/* 球局订单和收藏功能 */}
<View className="quick_actions_section">
<View className="action_card">

View File

@@ -9,10 +9,10 @@ import {
UserInfoCard,
// GameCard,
GameTabs,
UserInfo,
// UserInfo,
GameRecord,
} from "@/components/UserInfo";
import { UserService } from "@/services/userService";
import { UserService, UserInfoType } from "@/services/userService";
import * as LoginService from "@/services/loginService";
const OtherUserPage: React.FC = () => {
@@ -21,21 +21,22 @@ const OtherUserPage: React.FC = () => {
const user_id = instance.router?.params?.userid;
// 模拟用户数据
const [user_info, setUserInfo] = useState<UserInfo>({
id: user_id || "1",
const [user_info, setUserInfo] = useState<Partial<UserInfoType>>({
id: parseInt(user_id || "1") || 1,
gender: "",
nickname: "网球爱好者",
avatar: require("@/static/userInfo/default_avatar.svg"),
avatar_url: require("@/static/userInfo/default_avatar.svg"),
join_date: "2024年3月加入",
stats: {
following: 0,
friends: 0,
hosted: 0,
participated: 0,
following_count: 0,
followers_count: 0,
hosted_games_count: 0,
participated_games_count: 0,
},
tags: ["北京朝阳", "金融从业者", "NTRP 3.5"],
bio: "热爱网球的金融从业者,周末喜欢约球\n技术还在提升中欢迎一起切磋\n平时在朝阳公园附近活动",
location: "北京朝阳",
city: "北京",
district: "朝阳",
occupation: "金融从业者",
ntrp_level: "NTRP 3.5",
is_following: false,
@@ -68,22 +69,26 @@ const OtherUserPage: React.FC = () => {
const { data: userData } = res;
// setUserInfo({...res.data as UserInfo, avatar: data.avatar_url || require("@/static/userInfo/default_avatar.svg")});
setUserInfo({
id: user_id || "",
id: parseInt(user_id || "") || 0,
nickname: userData.nickname || "",
avatar: userData.avatar_url || "",
avatar_url: userData.avatar_url || "",
join_date: userData.subscribe_time
? `${new Date(userData.subscribe_time).getFullYear()}${new Date(userData.subscribe_time).getMonth() + 1
}月加入`
? `${new Date(userData.subscribe_time).getFullYear()}${
new Date(userData.subscribe_time).getMonth() + 1
}月加入`
: "",
stats: {
following: userData.stats?.following_count || 0,
friends: userData.stats?.followers_count || 0,
hosted: userData.stats?.hosted_games_count || 0,
participated: userData.stats?.participated_games_count || 0,
following_count: userData.stats?.following_count || 0,
followers_count: userData.stats?.followers_count || 0,
hosted_games_count: userData.stats?.hosted_games_count || 0,
participated_games_count:
userData.stats?.participated_games_count || 0,
},
personal_profile: userData.personal_profile || "",
location: userData.city + userData.district || "",
province: userData.province || "",
city: userData.city || "",
district: userData.district || "",
occupation: userData.occupation || "",
ntrp_level: "",
phone: userData.phone || "",
@@ -132,7 +137,10 @@ const OtherUserPage: React.FC = () => {
active_tab
);
const sorted_games = games_data.sort((a, b) => {
return new Date(a.original_start_time.replace(/\s/, 'T')).getTime() - new Date(b.original_start_time.replace(/\s/, 'T')).getTime();
return (
new Date(a.original_start_time.replace(/\s/, "T")).getTime() -
new Date(b.original_start_time.replace(/\s/, "T")).getTime()
);
});
const { notEndGames, finishedGames } = classifyGameRecords(sorted_games);
setGameRecords(notEndGames);
@@ -157,7 +165,7 @@ const OtherUserPage: React.FC = () => {
const handle_follow = async () => {
try {
const new_follow_status = await UserService.toggle_follow(
user_info.id,
user_info.id || "",
is_following
);
setIsFollowing(new_follow_status);
@@ -178,7 +186,9 @@ const OtherUserPage: React.FC = () => {
// 处理发送消息
const handle_send_message = () => {
Taro.navigateTo({
url: `/mode_user/message/chat/index?user_id=${user_info.id}&nickname=${user_info.nickname}`,
url: `/mode_user/message/chat/index?user_id=${
user_info.id || ""
}&nickname=${user_info.nickname || ""}`,
});
};
@@ -244,7 +254,7 @@ const OtherUserPage: React.FC = () => {
error={null}
errorImg="ICON_LIST_EMPTY"
emptyText="暂无消息,去互动看看吧"
loadMoreMatches={() => { }}
loadMoreMatches={() => {}}
/>
</ScrollView>
{/* </View> */}
@@ -280,7 +290,7 @@ const OtherUserPage: React.FC = () => {
error={null}
errorImg="ICON_LIST_EMPTY"
emptyText="暂无消息,去互动看看吧"
loadMoreMatches={() => { }}
loadMoreMatches={() => {}}
/>
</ScrollView>
{/* </View> */}