diff --git a/src/components/UserInfo/index.scss b/src/components/UserInfo/index.scss index d8feca9..7a43528 100644 --- a/src/components/UserInfo/index.scss +++ b/src/components/UserInfo/index.scss @@ -137,6 +137,7 @@ .message_button { width: 40px; height: 40px; + padding: unset; background: #FFFFFF; border: 0.5px solid rgba(0, 0, 0, 0.12); border-radius: 999px; @@ -147,8 +148,8 @@ transition: all 0.3s ease; .button_icon { - width: 18px; - height: 18px; + width: 20px; + height: 20px; } } @@ -527,4 +528,4 @@ } } } -} \ No newline at end of file +} diff --git a/src/components/UserInfo/index.tsx b/src/components/UserInfo/index.tsx index 0201dc4..5ac021f 100644 --- a/src/components/UserInfo/index.tsx +++ b/src/components/UserInfo/index.tsx @@ -1,10 +1,10 @@ -import React, { useState } from 'react'; -import Taro from '@tarojs/taro'; -import { View, Text, Image, Button } from '@tarojs/components'; -import './index.scss'; +import React, { useState } from "react"; +import Taro from "@tarojs/taro"; +import { View, Text, Image, Button } from "@tarojs/components"; +import "./index.scss"; -import { EditModal } from '@/components'; -import { UserService } from '@/services/userService'; +import { EditModal } from "@/components"; +import { UserService } from "@/services/userService"; // 用户信息接口 export interface UserInfo { @@ -33,7 +33,6 @@ export interface UserInfo { ongoing_games?: string[]; } - // 用户信息卡片组件属性 interface UserInfoCardProps { user_info: UserInfo; @@ -45,11 +44,10 @@ interface UserInfoCardProps { set_user_info?: (info: UserInfo) => void; } - // 处理编辑用户信息 const on_edit = () => { Taro.navigateTo({ - url: '/user_pages/edit/index' + url: "/user_pages/edit/index", }); }; // 用户信息卡片组件 @@ -62,17 +60,17 @@ export const UserInfoCard: React.FC = ({ on_share, set_user_info, }) => { - console.log("用户信息:", user_info); + console.log("UserInfoCard 用户信息:", user_info); // 编辑个人简介弹窗状态 const [edit_modal_visible, setEditModalVisible] = useState(false); - const [editing_field, setEditingField] = useState(''); + const [editing_field, setEditingField] = useState(""); // 表单状态 - const [form_data, setFormData] = useState({...user_info}); + const [form_data, setFormData] = useState({ ...user_info }); // 处理编辑弹窗 const handle_open_edit_modal = (field: string) => { - if (field === 'nickname') { + if (field === "nickname") { // 手动输入 setEditingField(field); setEditModalVisible(true); @@ -88,33 +86,33 @@ export const UserInfoCard: React.FC = ({ await UserService.update_user_info(update_data); // 更新本地状态 - setFormData(prev => { + setFormData((prev) => { const updated = { ...prev, [editing_field]: value }; - typeof set_user_info === 'function' && set_user_info(updated); + typeof set_user_info === "function" && set_user_info(updated); return updated; }); // 关闭弹窗 setEditModalVisible(false); - setEditingField(''); + setEditingField(""); // 显示成功提示 Taro.showToast({ - title: '保存成功', - icon: 'success' + title: "保存成功", + icon: "success", }); } catch (error) { - console.error('保存失败:', error); + console.error("保存失败:", error); Taro.showToast({ - title: '保存失败', - icon: 'error' + title: "保存失败", + icon: "error", }); } }; const handle_edit_modal_cancel = () => { setEditModalVisible(false); - setEditingField(''); + setEditingField(""); }; return ( @@ -128,11 +126,14 @@ export const UserInfoCard: React.FC = ({ {user_info.nickname} {user_info.join_date} - - + {is_current_user && ( + + + + )} {/* 统计数据 */} @@ -159,15 +160,17 @@ export const UserInfoCard: React.FC = ({ {/* 只有非当前用户才显示关注按钮 */} {!is_current_user && on_follow && ( )} @@ -176,7 +179,7 @@ export const UserInfoCard: React.FC = ({ )} @@ -193,74 +196,69 @@ export const UserInfoCard: React.FC = ({ {/* 标签和简介 */} - - {user_info.gender === "0" && ( - - )} - {user_info.gender === "1" && ( - - )} - { - !user_info.gender && ( - - 选择性别 - - ) - } - - {user_info.ntrp_level ? + {user_info.gender ? ( + + {user_info.gender === "0" && ( + + )} + {user_info.gender === "1" && ( + + )} + + ) : is_current_user ? ( + + 选择性别 + + ) : null} + {user_info.ntrp_level ? ( - {/* */} {user_info.ntrp_level} - : + + ) : is_current_user ? ( 测测你的NTRP水平 - } - {user_info.occupation ? + ) : null} + {user_info.occupation ? ( {user_info.occupation} - : + + ) : is_current_user ? ( 选择职业 - } - {user_info.location ? + ) : null} + {user_info.location ? ( - {/* */} {user_info.location} - : + + ) : is_current_user ? ( 选择地区 - } + ) : null} - { - user_info.personal_profile ? ( - {user_info.personal_profile} - ) : ( - handle_open_edit_modal('personal_profile')}> - - 点击添加简介,让更多人了解你 - - ) - } + {user_info.personal_profile ? ( + {user_info.personal_profile} + ) : is_current_user ? ( + handle_open_edit_modal("personal_profile")} + > + + 点击添加简介,让更多人了解你 + + ) : null} @@ -268,13 +266,13 @@ export const UserInfoCard: React.FC = ({ ); @@ -298,7 +296,7 @@ export interface GameRecord { current_participants: number; level_range: string; game_type: string; - images: string[]; + image_list: string[]; } // 球局卡片组件属性 @@ -312,20 +310,17 @@ interface GameCardProps { export const GameCard: React.FC = ({ game, on_click, - on_participant_click + on_participant_click, }) => { return ( - on_click(game.id)} - > + on_click(game.id)}> {/* 球局标题和类型 */} {game.title} @@ -348,12 +343,8 @@ export const GameCard: React.FC = ({ {/* 球局图片 */} - {game.images.map((image, index) => ( - + {game.image_list.map((image, index) => ( + ))} @@ -361,7 +352,7 @@ export const GameCard: React.FC = ({ - {game.participants.map((participant, index) => ( + {game.participants?.map((participant, index) => ( = ({ // 球局标签页组件属性 interface GameTabsProps { - active_tab: 'hosted' | 'participated'; - on_tab_change: (tab: 'hosted' | 'participated') => void; + active_tab: "hosted" | "participated"; + on_tab_change: (tab: "hosted" | "participated") => void; is_current_user: boolean; } @@ -403,21 +394,29 @@ interface GameTabsProps { export const GameTabs: React.FC = ({ active_tab, on_tab_change, - is_current_user + is_current_user, }) => { - const hosted_text = is_current_user ? '我主办的' : '他主办的'; - const participated_text = is_current_user ? '我参与的' : '他参与的'; + const hosted_text = is_current_user ? "我主办的" : "主办球局"; + const participated_text = is_current_user ? "我参与的" : "参与球局"; return ( - on_tab_change('hosted')}> + on_tab_change("hosted")} + > {hosted_text} - on_tab_change('participated')}> + on_tab_change("participated")} + > {participated_text} ); -}; \ No newline at end of file +}; diff --git a/src/config/api.ts b/src/config/api.ts index 1be3372..f54531e 100644 --- a/src/config/api.ts +++ b/src/config/api.ts @@ -3,25 +3,25 @@ import envConfig from './env'// API配置 export const API_CONFIG = { // 基础URL BASE_URL: envConfig.apiBaseURL, - + // 用户相关接口 USER: { DETAIL: '/user/detail', UPDATE: '/user/update', - FOLLOW: '/user/follow', - UNFOLLOW: '/user/unfollow', + FOLLOW: '/wch_users/follow', + UNFOLLOW: '/wch_users/unfollow', HOSTED_GAMES: '/user/games', PARTICIPATED_GAMES: '/user/participated', PARSE_PHONE: '/user/parse_phone', }, - + // 文件上传接口 UPLOAD: { AVATAR: '/gallery/upload', IMAGE: '/gallery/upload', OSS_IMG: '/gallery/upload_oss_img' }, - + // 球局相关接口 GAME: { LIST: '/game/list', @@ -38,4 +38,4 @@ export const REQUEST_CONFIG = { header: { 'Content-Type': 'application/json' } -}; \ No newline at end of file +}; diff --git a/src/services/userService.ts b/src/services/userService.ts index cb3aa57..5bc1650 100644 --- a/src/services/userService.ts +++ b/src/services/userService.ts @@ -252,7 +252,7 @@ export class UserService { try { // 过滤掉空字段 const filtered_data: Record = {}; - + Object.keys(update_data).forEach(key => { const value = update_data[key as keyof UserInfo]; // 只添加非空且非空字符串的字段 @@ -285,10 +285,10 @@ export class UserService { } // 获取用户主办的球局 - static async get_hosted_games(user_id: string): Promise { + static async get_hosted_games(userId: string): Promise { try { const response = await httpService.post(API_CONFIG.USER.HOSTED_GAMES, { - user_id + userId }, { showLoading: false @@ -308,10 +308,10 @@ export class UserService { } // 获取用户参与的球局 - static async get_participated_games(user_id: string): Promise { + static async get_participated_games(userId: string): Promise { try { const response = await httpService.post(API_CONFIG.USER.PARTICIPATED_GAMES, { - user_id + userId }, { showLoading: false @@ -522,4 +522,4 @@ export const get_user_info = (): any | null => { } catch (error) { return null; } -}; \ No newline at end of file +}; diff --git a/src/static/userInfo/chat.svg b/src/static/userInfo/chat.svg new file mode 100644 index 0000000..940b3f9 --- /dev/null +++ b/src/static/userInfo/chat.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/static/userInfo/following.svg b/src/static/userInfo/following.svg new file mode 100644 index 0000000..4932907 --- /dev/null +++ b/src/static/userInfo/following.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/static/userInfo/unfollow.svg b/src/static/userInfo/unfollow.svg new file mode 100644 index 0000000..b9517fe --- /dev/null +++ b/src/static/userInfo/unfollow.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/user_pages/myself/index.tsx b/src/user_pages/myself/index.tsx index 319fe74..07e3037 100644 --- a/src/user_pages/myself/index.tsx +++ b/src/user_pages/myself/index.tsx @@ -58,13 +58,14 @@ const MyselfPage: React.FC = () => { 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); + load_game_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({ @@ -98,9 +99,9 @@ const MyselfPage: React.FC = () => { try { let games_data; if (active_tab === "hosted") { - games_data = await UserService.get_hosted_games(user_id); + games_data = await UserService.get_hosted_games(user_info.id); } else { - games_data = await UserService.get_participated_games(user_id); + games_data = await UserService.get_participated_games(user_info.id); } set_game_records(games_data); } catch (error) { diff --git a/src/user_pages/other/index.scss b/src/user_pages/other/index.scss index a1c7fcb..81b1b18 100644 --- a/src/user_pages/other/index.scss +++ b/src/user_pages/other/index.scss @@ -1,7 +1,11 @@ // 他人用户页面样式 .other_user_page { min-height: 100vh; - background: radial-gradient(circle at 50% 0%, rgba(238, 255, 220, 1) 0%, rgba(255, 255, 255, 1) 37%); + background: radial-gradient( + circle at 50% 0%, + rgba(238, 255, 220, 1) 0%, + rgba(255, 255, 255, 1) 37% + ); position: relative; overflow: hidden; box-sizing: border-box; @@ -36,7 +40,8 @@ height: 64px; border-radius: 50%; overflow: hidden; - box-shadow: 0px 8px 20px 0px rgba(0, 0, 0, 0.12), 0px 0px 1px 0px rgba(0, 0, 0, 0.2); + box-shadow: 0px 8px 20px 0px rgba(0, 0, 0, 0.12), + 0px 0px 1px 0px rgba(0, 0, 0, 0.2); .avatar { width: 100%; @@ -52,7 +57,7 @@ gap: 4px; .nickname { - font-family: 'PingFang SC'; + font-family: "PingFang SC"; font-weight: 600; font-size: 20px; line-height: 1.4em; @@ -61,7 +66,7 @@ } .join_date { - font-family: 'PingFang SC'; + font-family: "PingFang SC"; font-weight: 400; font-size: 14px; line-height: 1.4em; @@ -89,7 +94,7 @@ align-items: center; .stat_number { - font-family: 'PingFang SC'; + font-family: "PingFang SC"; font-weight: 600; font-size: 18px; line-height: 1.4em; @@ -98,7 +103,7 @@ } .stat_label { - font-family: 'PingFang SC'; + font-family: "PingFang SC"; font-weight: 500; font-size: 12px; line-height: 1.4em; @@ -126,7 +131,7 @@ transition: all 0.3s ease; &.following { - background: #FFFFFF; + background: #ffffff; color: #000000; } @@ -136,11 +141,11 @@ } .button_text { - font-family: 'PingFang SC'; + font-family: "PingFang SC"; font-weight: 600; font-size: 14px; line-height: 1.4em; - color: #FFFFFF; + color: #ffffff; .following & { color: #000000; @@ -151,7 +156,7 @@ .message_button { width: 40px; height: 40px; - background: #FFFFFF; + background: #ffffff; border: 0.5px solid rgba(0, 0, 0, 0.12); border-radius: 999px; display: flex; @@ -185,7 +190,7 @@ gap: 4px; padding: 6px 8px; height: 20px; - background: #FFFFFF; + background: #ffffff; border: 0.5px solid rgba(0, 0, 0, 0.16); border-radius: 999px; @@ -195,7 +200,7 @@ } .tag_text { - font-family: 'PingFang SC'; + font-family: "PingFang SC"; font-weight: 500; font-size: 11px; line-height: 1.8em; @@ -206,7 +211,7 @@ } .bio_text { - font-family: 'PingFang SC'; + font-family: "PingFang SC"; font-weight: 400; font-size: 14px; line-height: 1.571em; @@ -216,6 +221,17 @@ } } + .game_list_container { + .game_class_text { + font-family: "PingFang SC"; + font-weight: 600; + font-size: 20px; + line-height: 1.4em; + letter-spacing: 1.9%; + color: rgba(0, 0, 0, 0.85); + } + } + // 球局类型标签页 .game_tabs_section { margin-bottom: 16px; @@ -231,7 +247,7 @@ transition: all 0.3s ease; .tab_text { - font-family: 'PingFang SC'; + font-family: "PingFang SC"; font-weight: 600; font-size: 20px; line-height: 1.4em; @@ -265,7 +281,7 @@ margin-bottom: 16px; .date_text { - font-family: 'PingFang SC'; + font-family: "PingFang SC"; font-weight: 600; font-size: 14px; line-height: 1.4em; @@ -274,7 +290,7 @@ } .separator { - font-family: 'PingFang SC'; + font-family: "PingFang SC"; font-weight: 400; font-size: 18px; line-height: 1.4em; @@ -283,7 +299,7 @@ } .weekday_text { - font-family: 'PingFang SC'; + font-family: "PingFang SC"; font-weight: 600; font-size: 14px; line-height: 1.4em; @@ -300,7 +316,7 @@ padding: 0 5px 15px; .game_card { - background: #FFFFFF; + background: #ffffff; border: 0.5px solid rgba(0, 0, 0, 0.08); border-radius: 20px; padding: 0 0 12px; @@ -321,7 +337,7 @@ padding: 12px 15px 0; .game_title { - font-family: 'PingFang SC'; + font-family: "PingFang SC"; font-weight: 600; font-size: 16px; line-height: 1.5em; @@ -344,7 +360,7 @@ padding: 6px 15px 0; .time_text { - font-family: 'PingFang SC'; + font-family: "PingFang SC"; font-weight: 400; font-size: 12px; line-height: 1.5em; @@ -362,7 +378,7 @@ .location_text, .type_text, .distance_text { - font-family: 'PingFang SC'; + font-family: "PingFang SC"; font-weight: 400; font-size: 12px; line-height: 1.5em; @@ -370,7 +386,7 @@ } .separator { - font-family: 'PingFang SC'; + font-family: "PingFang SC"; font-weight: 400; font-size: 14px; line-height: 1.3em; @@ -392,7 +408,7 @@ width: 56.44px; height: 56.44px; border-radius: 9px; - border: 1.5px solid #FFFFFF; + border: 1.5px solid #ffffff; &:nth-child(1) { top: 4.18px; @@ -435,12 +451,12 @@ width: 20px; height: 20px; border-radius: 50%; - border: 1px solid #FFFFFF; + border: 1px solid #ffffff; } } .participants_count { - background: #FFFFFF; + background: #ffffff; border: 0.5px solid rgba(0, 0, 0, 0.16); border-radius: 999px; padding: 6px; @@ -450,7 +466,7 @@ justify-content: center; .count_text { - font-family: 'PingFang SC'; + font-family: "PingFang SC"; font-weight: 500; font-size: 11px; line-height: 1.8em; @@ -465,7 +481,7 @@ gap: 4px; .info_tag { - background: #FFFFFF; + background: #ffffff; border: 0.5px solid rgba(0, 0, 0, 0.16); border-radius: 999px; padding: 6px 8px; @@ -475,7 +491,7 @@ justify-content: center; .tag_text { - font-family: 'PingFang SC'; + font-family: "PingFang SC"; font-weight: 500; font-size: 11px; line-height: 1.8em; @@ -488,4 +504,4 @@ } } } -} \ No newline at end of file +} diff --git a/src/user_pages/other/index.tsx b/src/user_pages/other/index.tsx index 62fbf7e..61d219c 100644 --- a/src/user_pages/other/index.tsx +++ b/src/user_pages/other/index.tsx @@ -2,7 +2,7 @@ import React, { useState, useEffect } from "react"; import { View, Text, ScrollView } from "@tarojs/components"; import Taro from "@tarojs/taro"; import "./index.scss"; -import GuideBar from "@/components/GuideBar"; +// import GuideBar from "@/components/GuideBar"; import { UserInfoCard, GameCard, @@ -21,6 +21,7 @@ const OtherUserPage: React.FC = () => { // 模拟用户数据 const [user_info, setUserInfo] = useState({ id: user_id || "1", + gender:"", nickname: "网球爱好者", avatar: require("@/static/userInfo/default_avatar.svg"), join_date: "2024年3月加入", @@ -37,7 +38,7 @@ const OtherUserPage: React.FC = () => { ntrp_level: "NTRP 3.5", is_following: false, ongoing_games: [], - personal_profile: '', + personal_profile: "", }); // 模拟球局数据 @@ -48,7 +49,7 @@ const OtherUserPage: React.FC = () => { // 当前激活的标签页 const [active_tab, setActiveTab] = useState<"hosted" | "participated">( - "hosted", + "hosted" ); // 页面加载时获取用户信息 @@ -58,11 +59,36 @@ const OtherUserPage: React.FC = () => { try { // const user_data = await UserService.get_user_info(user_id); const res = await LoginService.getUserInfoById(user_id); - setUserInfo(res.data as UserInfo); + const { data: userData } = res; + // setUserInfo({...res.data as UserInfo, avatar: data.avatar_url || require("@/static/userInfo/default_avatar.svg")}); + setUserInfo({ + id: userData.user_code || user_id || "", + nickname: userData.nickname || "", + avatar: userData.avatar_url || "", + join_date: userData.subscribe_time + ? `${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, + }, + + personal_profile: userData.personal_profile || "", + location: userData.city + userData.district || "", + occupation: userData.occupation || "", + ntrp_level: "", + phone: userData.phone || "", + gender: userData.gender || "", + birthday: userData.birthday || "", + }); const games_data = await UserService.get_user_games( user_id, - active_tab, + active_tab ); setGameRecords(games_data); } catch (error) { @@ -83,7 +109,7 @@ const OtherUserPage: React.FC = () => { try { const new_follow_status = await UserService.toggle_follow( user_info.id, - is_following, + is_following ); setIsFollowing(new_follow_status); Taro.showToast({