他人页

This commit is contained in:
2025-09-15 17:30:48 +08:00
parent 91636855aa
commit 7a0bc71f9f
10 changed files with 227 additions and 167 deletions

View File

@@ -137,6 +137,7 @@
.message_button { .message_button {
width: 40px; width: 40px;
height: 40px; height: 40px;
padding: unset;
background: #FFFFFF; background: #FFFFFF;
border: 0.5px solid rgba(0, 0, 0, 0.12); border: 0.5px solid rgba(0, 0, 0, 0.12);
border-radius: 999px; border-radius: 999px;
@@ -147,8 +148,8 @@
transition: all 0.3s ease; transition: all 0.3s ease;
.button_icon { .button_icon {
width: 18px; width: 20px;
height: 18px; height: 20px;
} }
} }

View File

@@ -1,10 +1,10 @@
import React, { useState } from 'react'; import React, { useState } from "react";
import Taro from '@tarojs/taro'; import Taro from "@tarojs/taro";
import { View, Text, Image, Button } from '@tarojs/components'; import { View, Text, Image, Button } from "@tarojs/components";
import './index.scss'; import "./index.scss";
import { EditModal } from '@/components'; import { EditModal } from "@/components";
import { UserService } from '@/services/userService'; import { UserService } from "@/services/userService";
// 用户信息接口 // 用户信息接口
export interface UserInfo { export interface UserInfo {
@@ -33,7 +33,6 @@ export interface UserInfo {
ongoing_games?: string[]; ongoing_games?: string[];
} }
// 用户信息卡片组件属性 // 用户信息卡片组件属性
interface UserInfoCardProps { interface UserInfoCardProps {
user_info: UserInfo; user_info: UserInfo;
@@ -45,11 +44,10 @@ interface UserInfoCardProps {
set_user_info?: (info: UserInfo) => void; set_user_info?: (info: UserInfo) => void;
} }
// 处理编辑用户信息 // 处理编辑用户信息
const on_edit = () => { const on_edit = () => {
Taro.navigateTo({ Taro.navigateTo({
url: '/user_pages/edit/index' url: "/user_pages/edit/index",
}); });
}; };
// 用户信息卡片组件 // 用户信息卡片组件
@@ -62,17 +60,17 @@ export const UserInfoCard: React.FC<UserInfoCardProps> = ({
on_share, on_share,
set_user_info, set_user_info,
}) => { }) => {
console.log("用户信息:", user_info); console.log("UserInfoCard 用户信息:", user_info);
// 编辑个人简介弹窗状态 // 编辑个人简介弹窗状态
const [edit_modal_visible, setEditModalVisible] = useState(false); const [edit_modal_visible, setEditModalVisible] = useState(false);
const [editing_field, setEditingField] = useState<string>(''); const [editing_field, setEditingField] = useState<string>("");
// 表单状态 // 表单状态
const [form_data, setFormData] = useState<UserInfo>({...user_info}); const [form_data, setFormData] = useState<UserInfo>({ ...user_info });
// 处理编辑弹窗 // 处理编辑弹窗
const handle_open_edit_modal = (field: string) => { const handle_open_edit_modal = (field: string) => {
if (field === 'nickname') { if (field === "nickname") {
// 手动输入 // 手动输入
setEditingField(field); setEditingField(field);
setEditModalVisible(true); setEditModalVisible(true);
@@ -88,33 +86,33 @@ export const UserInfoCard: React.FC<UserInfoCardProps> = ({
await UserService.update_user_info(update_data); await UserService.update_user_info(update_data);
// 更新本地状态 // 更新本地状态
setFormData(prev => { setFormData((prev) => {
const updated = { ...prev, [editing_field]: value }; 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; return updated;
}); });
// 关闭弹窗 // 关闭弹窗
setEditModalVisible(false); setEditModalVisible(false);
setEditingField(''); setEditingField("");
// 显示成功提示 // 显示成功提示
Taro.showToast({ Taro.showToast({
title: '保存成功', title: "保存成功",
icon: 'success' icon: "success",
}); });
} catch (error) { } catch (error) {
console.error('保存失败:', error); console.error("保存失败:", error);
Taro.showToast({ Taro.showToast({
title: '保存失败', title: "保存失败",
icon: 'error' icon: "error",
}); });
} }
}; };
const handle_edit_modal_cancel = () => { const handle_edit_modal_cancel = () => {
setEditModalVisible(false); setEditModalVisible(false);
setEditingField(''); setEditingField("");
}; };
return ( return (
@@ -128,11 +126,14 @@ export const UserInfoCard: React.FC<UserInfoCardProps> = ({
<Text className="nickname">{user_info.nickname}</Text> <Text className="nickname">{user_info.nickname}</Text>
<Text className="join_date">{user_info.join_date}</Text> <Text className="join_date">{user_info.join_date}</Text>
</View> </View>
<View className='tag_item' onClick={on_edit}> {is_current_user && (
<Image <View className="tag_item" onClick={on_edit}>
className="tag_icon" <Image
src={require('../../static/userInfo/edit.svg')} className="tag_icon"
/> </View> src={require("../../static/userInfo/edit.svg")}
/>
</View>
)}
</View> </View>
{/* 统计数据 */} {/* 统计数据 */}
@@ -159,15 +160,17 @@ export const UserInfoCard: React.FC<UserInfoCardProps> = ({
{/* 只有非当前用户才显示关注按钮 */} {/* 只有非当前用户才显示关注按钮 */}
{!is_current_user && on_follow && ( {!is_current_user && on_follow && (
<Button <Button
className={`follow_button ${is_following ? 'following' : ''}`} className={`follow_button ${is_following ? "following" : ""}`}
onClick={on_follow} onClick={on_follow}
> >
<Image <Image
className="button_icon" className="button_icon"
src={require('../../static/userInfo/plus.svg')} src={require(is_following
? "@/static/userInfo/following.svg"
: "@/static/userInfo/unfollow.svg")}
/> />
<Text className="button_text"> <Text className="button_text">
{is_following ? '已关注' : '关注'} {is_following ? "已关注" : "关注"}
</Text> </Text>
</Button> </Button>
)} )}
@@ -176,7 +179,7 @@ export const UserInfoCard: React.FC<UserInfoCardProps> = ({
<Button className="message_button" onClick={on_message}> <Button className="message_button" onClick={on_message}>
<Image <Image
className="button_icon" className="button_icon"
src={require('../../static/userInfo/message.svg')} src={require("@/static/userInfo/chat.svg")}
/> />
</Button> </Button>
)} )}
@@ -193,74 +196,69 @@ export const UserInfoCard: React.FC<UserInfoCardProps> = ({
{/* 标签和简介 */} {/* 标签和简介 */}
<View className="tags_bio_section"> <View className="tags_bio_section">
<View className="tags_container"> <View className="tags_container">
<View className="tag_item"> {user_info.gender ? (
{user_info.gender === "0" && ( <View className="tag_item">
<Image {user_info.gender === "0" && (
className="tag_icon" <Image
src={require('../../static/userInfo/male.svg')} className="tag_icon"
/> src={require("../../static/userInfo/male.svg")}
)} />
{user_info.gender === "1" && ( )}
<Image {user_info.gender === "1" && (
className="tag_icon" <Image
src={require('../../static/userInfo/female.svg')} className="tag_icon"
/> src={require("../../static/userInfo/female.svg")}
)} />
{ )}
!user_info.gender && ( </View>
<View className='button_edit'> ) : is_current_user ? (
<Text></Text> <View className="button_edit">
</View> <Text></Text>
) </View>
} ) : null}
</View> {user_info.ntrp_level ? (
{user_info.ntrp_level ?
<View className="tag_item"> <View className="tag_item">
{/* <Image
className="tag_icon"
src={require('../../static/userInfo/level.svg')}
/> */}
<Text className="tag_text">{user_info.ntrp_level}</Text> <Text className="tag_text">{user_info.ntrp_level}</Text>
</View> : </View>
) : is_current_user ? (
<View className="button_edit"> <View className="button_edit">
<Text>NTRP水平</Text> <Text>NTRP水平</Text>
</View> </View>
} ) : null}
{user_info.occupation ? {user_info.occupation ? (
<View className="tag_item"> <View className="tag_item">
<Text className="tag_text">{user_info.occupation}</Text> <Text className="tag_text">{user_info.occupation}</Text>
</View> : </View>
) : is_current_user ? (
<View className="button_edit"> <View className="button_edit">
<Text></Text> <Text></Text>
</View> </View>
} ) : null}
{user_info.location ? {user_info.location ? (
<View className="tag_item"> <View className="tag_item">
{/* <Image
className="tag_icon"
src={require('../../static/userInfo/location.svg')}
/> */}
<Text className="tag_text">{user_info.location}</Text> <Text className="tag_text">{user_info.location}</Text>
</View> : </View>
) : is_current_user ? (
<View className="button_edit"> <View className="button_edit">
<Text></Text> <Text></Text>
</View> </View>
} ) : null}
</View> </View>
<View className="personal_profile"> <View className="personal_profile">
{ {user_info.personal_profile ? (
user_info.personal_profile ? ( <Text className="bio_text">{user_info.personal_profile}</Text>
<Text className="bio_text">{user_info.personal_profile}</Text> ) : is_current_user ? (
) : ( <View
<View className='personal_profile_edit' onClick={() => handle_open_edit_modal('personal_profile')}> className="personal_profile_edit"
<Image onClick={() => handle_open_edit_modal("personal_profile")}
className="edit_icon" >
src={require('../../static/userInfo/info_edit.svg')} <Image
/> className="edit_icon"
<Text className="bio_text"></Text> src={require("../../static/userInfo/info_edit.svg")}
</View> />
) <Text className="bio_text"></Text>
} </View>
) : null}
</View> </View>
</View> </View>
@@ -268,13 +266,13 @@ export const UserInfoCard: React.FC<UserInfoCardProps> = ({
<EditModal <EditModal
visible={edit_modal_visible} visible={edit_modal_visible}
type={editing_field} type={editing_field}
title='编辑简介' title="编辑简介"
placeholder='介绍一下你的喜好,或者训练习惯' placeholder="介绍一下你的喜好,或者训练习惯"
initialValue={form_data['personal_profile'] || ''} initialValue={form_data["personal_profile"] || ""}
maxLength={100} maxLength={100}
onSave={handle_edit_modal_save} onSave={handle_edit_modal_save}
onCancel={handle_edit_modal_cancel} onCancel={handle_edit_modal_cancel}
validationMessage='请填写 2-100 个字符' validationMessage="请填写 2-100 个字符"
/> />
</View> </View>
); );
@@ -298,7 +296,7 @@ export interface GameRecord {
current_participants: number; current_participants: number;
level_range: string; level_range: string;
game_type: string; game_type: string;
images: string[]; image_list: string[];
} }
// 球局卡片组件属性 // 球局卡片组件属性
@@ -312,20 +310,17 @@ interface GameCardProps {
export const GameCard: React.FC<GameCardProps> = ({ export const GameCard: React.FC<GameCardProps> = ({
game, game,
on_click, on_click,
on_participant_click on_participant_click,
}) => { }) => {
return ( return (
<View <View className="game_card" onClick={() => on_click(game.id)}>
className="game_card"
onClick={() => on_click(game.id)}
>
{/* 球局标题和类型 */} {/* 球局标题和类型 */}
<View className="game_header"> <View className="game_header">
<Text className="game_title">{game.title}</Text> <Text className="game_title">{game.title}</Text>
<View className="game_type_icon"> <View className="game_type_icon">
<Image <Image
className="type_icon" className="type_icon"
src={require('../../static/userInfo/tennis.svg')} src={require("../../static/userInfo/tennis.svg")}
/> />
</View> </View>
</View> </View>
@@ -348,12 +343,8 @@ export const GameCard: React.FC<GameCardProps> = ({
{/* 球局图片 */} {/* 球局图片 */}
<View className="game_images"> <View className="game_images">
{game.images.map((image, index) => ( {game.image_list.map((image, index) => (
<Image <Image key={index} className="game_image" src={image} />
key={index}
className="game_image"
src={image}
/>
))} ))}
</View> </View>
@@ -361,7 +352,7 @@ export const GameCard: React.FC<GameCardProps> = ({
<View className="game_tags"> <View className="game_tags">
<View className="participants_info"> <View className="participants_info">
<View className="avatars"> <View className="avatars">
{game.participants.map((participant, index) => ( {game.participants?.map((participant, index) => (
<Image <Image
key={index} key={index}
className="participant_avatar" className="participant_avatar"
@@ -394,8 +385,8 @@ export const GameCard: React.FC<GameCardProps> = ({
// 球局标签页组件属性 // 球局标签页组件属性
interface GameTabsProps { interface GameTabsProps {
active_tab: 'hosted' | 'participated'; active_tab: "hosted" | "participated";
on_tab_change: (tab: 'hosted' | 'participated') => void; on_tab_change: (tab: "hosted" | "participated") => void;
is_current_user: boolean; is_current_user: boolean;
} }
@@ -403,18 +394,26 @@ interface GameTabsProps {
export const GameTabs: React.FC<GameTabsProps> = ({ export const GameTabs: React.FC<GameTabsProps> = ({
active_tab, active_tab,
on_tab_change, on_tab_change,
is_current_user is_current_user,
}) => { }) => {
const hosted_text = is_current_user ? '我主办的' : '他主办的'; const hosted_text = is_current_user ? "我主办的" : "主办球局";
const participated_text = is_current_user ? '我参与的' : '他参与的'; const participated_text = is_current_user ? "我参与的" : "参与球局";
return ( return (
<View className="game_tabs_section"> <View className="game_tabs_section">
<View className="tab_container"> <View className="tab_container">
<View className={`tab_item ${active_tab === 'hosted' ? 'active' : ''}`} onClick={() => on_tab_change('hosted')}> <View
className={`tab_item ${active_tab === "hosted" ? "active" : ""}`}
onClick={() => on_tab_change("hosted")}
>
<Text className="tab_text">{hosted_text}</Text> <Text className="tab_text">{hosted_text}</Text>
</View> </View>
<View className={`tab_item ${active_tab === 'participated' ? 'active' : ''}`} onClick={() => on_tab_change('participated')}> <View
className={`tab_item ${
active_tab === "participated" ? "active" : ""
}`}
onClick={() => on_tab_change("participated")}
>
<Text className="tab_text">{participated_text}</Text> <Text className="tab_text">{participated_text}</Text>
</View> </View>
</View> </View>

View File

@@ -8,8 +8,8 @@ export const API_CONFIG = {
USER: { USER: {
DETAIL: '/user/detail', DETAIL: '/user/detail',
UPDATE: '/user/update', UPDATE: '/user/update',
FOLLOW: '/user/follow', FOLLOW: '/wch_users/follow',
UNFOLLOW: '/user/unfollow', UNFOLLOW: '/wch_users/unfollow',
HOSTED_GAMES: '/user/games', HOSTED_GAMES: '/user/games',
PARTICIPATED_GAMES: '/user/participated', PARTICIPATED_GAMES: '/user/participated',
PARSE_PHONE: '/user/parse_phone', PARSE_PHONE: '/user/parse_phone',

View File

@@ -285,10 +285,10 @@ export class UserService {
} }
// 获取用户主办的球局 // 获取用户主办的球局
static async get_hosted_games(user_id: string): Promise<any[]> { static async get_hosted_games(userId: string): Promise<any[]> {
try { try {
const response = await httpService.post<any>(API_CONFIG.USER.HOSTED_GAMES, { const response = await httpService.post<any>(API_CONFIG.USER.HOSTED_GAMES, {
user_id userId
}, { }, {
showLoading: false showLoading: false
@@ -308,10 +308,10 @@ export class UserService {
} }
// 获取用户参与的球局 // 获取用户参与的球局
static async get_participated_games(user_id: string): Promise<any[]> { static async get_participated_games(userId: string): Promise<any[]> {
try { try {
const response = await httpService.post<any>(API_CONFIG.USER.PARTICIPATED_GAMES, { const response = await httpService.post<any>(API_CONFIG.USER.PARTICIPATED_GAMES, {
user_id userId
}, { }, {
showLoading: false showLoading: false

View File

@@ -0,0 +1,7 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.75 15.8333H9.16663V12.5H15V9.16666H18.3333V15.8333H16.25L15 17.0833L13.75 15.8333Z" stroke="black" stroke-opacity="0.85" stroke-width="1.66667" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M1.66663 2.5H15V12.5H7.08329L5.41663 14.1667L3.74996 12.5H1.66663V2.5Z" stroke="black" stroke-opacity="0.85" stroke-width="1.66667" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M7.91663 7.5H8.33329" stroke="black" stroke-opacity="0.85" stroke-width="1.66667" stroke-linecap="round"/>
<path d="M10.8334 7.5H11.25" stroke="black" stroke-opacity="0.85" stroke-width="1.66667" stroke-linecap="round"/>
<path d="M5 7.5H5.41667" stroke="black" stroke-opacity="0.85" stroke-width="1.66667" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 839 B

View File

@@ -0,0 +1,5 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.99998 7.49999C11.6108 7.49999 12.9166 6.19415 12.9166 4.58332C12.9166 2.97249 11.6108 1.66666 9.99998 1.66666C8.38915 1.66666 7.08331 2.97249 7.08331 4.58332C7.08331 6.19415 8.38915 7.49999 9.99998 7.49999Z" stroke="black" stroke-width="1.66667" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M1.66669 17.0833C1.66669 13.4014 5.02456 10.4167 9.16669 10.4167" stroke="black" stroke-width="1.66667" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M13.2709 11.6667C12.3849 11.6667 11.6667 12.5036 11.6667 13.536C11.6667 15.4053 13.5625 17.1047 14.5834 17.5C15.6042 17.1047 17.5 15.4053 17.5 13.536C17.5 12.5036 16.7818 11.6667 15.8959 11.6667C15.3533 11.6667 14.8736 11.9805 14.5834 12.4609C14.2931 11.9805 13.8134 11.6667 13.2709 11.6667Z" stroke="black" stroke-width="1.66667" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 961 B

View File

@@ -0,0 +1,5 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.91667 8.33333C9.5275 8.33333 10.8333 7.0275 10.8333 5.41667C10.8333 3.80584 9.5275 2.5 7.91667 2.5C6.30583 2.5 5 3.80584 5 5.41667C5 7.0275 6.30583 8.33333 7.91667 8.33333Z" stroke="white" stroke-width="1.66667" stroke-linejoin="round"/>
<path d="M15 12.0833V17.0833M12.5 14.5833H17.5" stroke="white" stroke-width="1.66667" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M11.25 11.6667H7.83333C5.9665 11.6667 5.03308 11.6667 4.32004 12.0299C3.69283 12.3495 3.18289 12.8595 2.86331 13.4867C2.5 14.1997 2.5 15.1332 2.5 17V17.5H11.25" stroke="white" stroke-width="1.66667" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 745 B

View File

@@ -58,13 +58,14 @@ const MyselfPage: React.FC = () => {
set_user_info(user_data); set_user_info(user_data);
// 获取球局记录 // 获取球局记录
let games_data; load_game_data();
if (active_tab === "hosted") { // let games_data;
games_data = await UserService.get_hosted_games(user_id); // if (active_tab === "hosted") {
} else { // games_data = await UserService.get_hosted_games(user_id);
games_data = await UserService.get_participated_games(user_id); // } else {
} // games_data = await UserService.get_participated_games(user_id);
set_game_records(games_data); // }
// set_game_records(games_data);
} catch (error) { } catch (error) {
console.error("加载用户数据失败:", error); console.error("加载用户数据失败:", error);
Taro.showToast({ Taro.showToast({
@@ -98,9 +99,9 @@ const MyselfPage: React.FC = () => {
try { try {
let games_data; let games_data;
if (active_tab === "hosted") { if (active_tab === "hosted") {
games_data = await UserService.get_hosted_games(user_id); games_data = await UserService.get_hosted_games(user_info.id);
} else { } 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); set_game_records(games_data);
} catch (error) { } catch (error) {

View File

@@ -1,7 +1,11 @@
// 他人用户页面样式 // 他人用户页面样式
.other_user_page { .other_user_page {
min-height: 100vh; 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; position: relative;
overflow: hidden; overflow: hidden;
box-sizing: border-box; box-sizing: border-box;
@@ -36,7 +40,8 @@
height: 64px; height: 64px;
border-radius: 50%; border-radius: 50%;
overflow: hidden; 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 { .avatar {
width: 100%; width: 100%;
@@ -52,7 +57,7 @@
gap: 4px; gap: 4px;
.nickname { .nickname {
font-family: 'PingFang SC'; font-family: "PingFang SC";
font-weight: 600; font-weight: 600;
font-size: 20px; font-size: 20px;
line-height: 1.4em; line-height: 1.4em;
@@ -61,7 +66,7 @@
} }
.join_date { .join_date {
font-family: 'PingFang SC'; font-family: "PingFang SC";
font-weight: 400; font-weight: 400;
font-size: 14px; font-size: 14px;
line-height: 1.4em; line-height: 1.4em;
@@ -89,7 +94,7 @@
align-items: center; align-items: center;
.stat_number { .stat_number {
font-family: 'PingFang SC'; font-family: "PingFang SC";
font-weight: 600; font-weight: 600;
font-size: 18px; font-size: 18px;
line-height: 1.4em; line-height: 1.4em;
@@ -98,7 +103,7 @@
} }
.stat_label { .stat_label {
font-family: 'PingFang SC'; font-family: "PingFang SC";
font-weight: 500; font-weight: 500;
font-size: 12px; font-size: 12px;
line-height: 1.4em; line-height: 1.4em;
@@ -126,7 +131,7 @@
transition: all 0.3s ease; transition: all 0.3s ease;
&.following { &.following {
background: #FFFFFF; background: #ffffff;
color: #000000; color: #000000;
} }
@@ -136,11 +141,11 @@
} }
.button_text { .button_text {
font-family: 'PingFang SC'; font-family: "PingFang SC";
font-weight: 600; font-weight: 600;
font-size: 14px; font-size: 14px;
line-height: 1.4em; line-height: 1.4em;
color: #FFFFFF; color: #ffffff;
.following & { .following & {
color: #000000; color: #000000;
@@ -151,7 +156,7 @@
.message_button { .message_button {
width: 40px; width: 40px;
height: 40px; height: 40px;
background: #FFFFFF; background: #ffffff;
border: 0.5px solid rgba(0, 0, 0, 0.12); border: 0.5px solid rgba(0, 0, 0, 0.12);
border-radius: 999px; border-radius: 999px;
display: flex; display: flex;
@@ -185,7 +190,7 @@
gap: 4px; gap: 4px;
padding: 6px 8px; padding: 6px 8px;
height: 20px; height: 20px;
background: #FFFFFF; background: #ffffff;
border: 0.5px solid rgba(0, 0, 0, 0.16); border: 0.5px solid rgba(0, 0, 0, 0.16);
border-radius: 999px; border-radius: 999px;
@@ -195,7 +200,7 @@
} }
.tag_text { .tag_text {
font-family: 'PingFang SC'; font-family: "PingFang SC";
font-weight: 500; font-weight: 500;
font-size: 11px; font-size: 11px;
line-height: 1.8em; line-height: 1.8em;
@@ -206,7 +211,7 @@
} }
.bio_text { .bio_text {
font-family: 'PingFang SC'; font-family: "PingFang SC";
font-weight: 400; font-weight: 400;
font-size: 14px; font-size: 14px;
line-height: 1.571em; 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 { .game_tabs_section {
margin-bottom: 16px; margin-bottom: 16px;
@@ -231,7 +247,7 @@
transition: all 0.3s ease; transition: all 0.3s ease;
.tab_text { .tab_text {
font-family: 'PingFang SC'; font-family: "PingFang SC";
font-weight: 600; font-weight: 600;
font-size: 20px; font-size: 20px;
line-height: 1.4em; line-height: 1.4em;
@@ -265,7 +281,7 @@
margin-bottom: 16px; margin-bottom: 16px;
.date_text { .date_text {
font-family: 'PingFang SC'; font-family: "PingFang SC";
font-weight: 600; font-weight: 600;
font-size: 14px; font-size: 14px;
line-height: 1.4em; line-height: 1.4em;
@@ -274,7 +290,7 @@
} }
.separator { .separator {
font-family: 'PingFang SC'; font-family: "PingFang SC";
font-weight: 400; font-weight: 400;
font-size: 18px; font-size: 18px;
line-height: 1.4em; line-height: 1.4em;
@@ -283,7 +299,7 @@
} }
.weekday_text { .weekday_text {
font-family: 'PingFang SC'; font-family: "PingFang SC";
font-weight: 600; font-weight: 600;
font-size: 14px; font-size: 14px;
line-height: 1.4em; line-height: 1.4em;
@@ -300,7 +316,7 @@
padding: 0 5px 15px; padding: 0 5px 15px;
.game_card { .game_card {
background: #FFFFFF; background: #ffffff;
border: 0.5px solid rgba(0, 0, 0, 0.08); border: 0.5px solid rgba(0, 0, 0, 0.08);
border-radius: 20px; border-radius: 20px;
padding: 0 0 12px; padding: 0 0 12px;
@@ -321,7 +337,7 @@
padding: 12px 15px 0; padding: 12px 15px 0;
.game_title { .game_title {
font-family: 'PingFang SC'; font-family: "PingFang SC";
font-weight: 600; font-weight: 600;
font-size: 16px; font-size: 16px;
line-height: 1.5em; line-height: 1.5em;
@@ -344,7 +360,7 @@
padding: 6px 15px 0; padding: 6px 15px 0;
.time_text { .time_text {
font-family: 'PingFang SC'; font-family: "PingFang SC";
font-weight: 400; font-weight: 400;
font-size: 12px; font-size: 12px;
line-height: 1.5em; line-height: 1.5em;
@@ -362,7 +378,7 @@
.location_text, .location_text,
.type_text, .type_text,
.distance_text { .distance_text {
font-family: 'PingFang SC'; font-family: "PingFang SC";
font-weight: 400; font-weight: 400;
font-size: 12px; font-size: 12px;
line-height: 1.5em; line-height: 1.5em;
@@ -370,7 +386,7 @@
} }
.separator { .separator {
font-family: 'PingFang SC'; font-family: "PingFang SC";
font-weight: 400; font-weight: 400;
font-size: 14px; font-size: 14px;
line-height: 1.3em; line-height: 1.3em;
@@ -392,7 +408,7 @@
width: 56.44px; width: 56.44px;
height: 56.44px; height: 56.44px;
border-radius: 9px; border-radius: 9px;
border: 1.5px solid #FFFFFF; border: 1.5px solid #ffffff;
&:nth-child(1) { &:nth-child(1) {
top: 4.18px; top: 4.18px;
@@ -435,12 +451,12 @@
width: 20px; width: 20px;
height: 20px; height: 20px;
border-radius: 50%; border-radius: 50%;
border: 1px solid #FFFFFF; border: 1px solid #ffffff;
} }
} }
.participants_count { .participants_count {
background: #FFFFFF; background: #ffffff;
border: 0.5px solid rgba(0, 0, 0, 0.16); border: 0.5px solid rgba(0, 0, 0, 0.16);
border-radius: 999px; border-radius: 999px;
padding: 6px; padding: 6px;
@@ -450,7 +466,7 @@
justify-content: center; justify-content: center;
.count_text { .count_text {
font-family: 'PingFang SC'; font-family: "PingFang SC";
font-weight: 500; font-weight: 500;
font-size: 11px; font-size: 11px;
line-height: 1.8em; line-height: 1.8em;
@@ -465,7 +481,7 @@
gap: 4px; gap: 4px;
.info_tag { .info_tag {
background: #FFFFFF; background: #ffffff;
border: 0.5px solid rgba(0, 0, 0, 0.16); border: 0.5px solid rgba(0, 0, 0, 0.16);
border-radius: 999px; border-radius: 999px;
padding: 6px 8px; padding: 6px 8px;
@@ -475,7 +491,7 @@
justify-content: center; justify-content: center;
.tag_text { .tag_text {
font-family: 'PingFang SC'; font-family: "PingFang SC";
font-weight: 500; font-weight: 500;
font-size: 11px; font-size: 11px;
line-height: 1.8em; line-height: 1.8em;

View File

@@ -2,7 +2,7 @@ import React, { useState, useEffect } from "react";
import { View, Text, ScrollView } from "@tarojs/components"; import { View, Text, ScrollView } from "@tarojs/components";
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
import "./index.scss"; import "./index.scss";
import GuideBar from "@/components/GuideBar"; // import GuideBar from "@/components/GuideBar";
import { import {
UserInfoCard, UserInfoCard,
GameCard, GameCard,
@@ -21,6 +21,7 @@ const OtherUserPage: React.FC = () => {
// 模拟用户数据 // 模拟用户数据
const [user_info, setUserInfo] = useState<UserInfo>({ const [user_info, setUserInfo] = useState<UserInfo>({
id: user_id || "1", id: user_id || "1",
gender:"",
nickname: "网球爱好者", nickname: "网球爱好者",
avatar: require("@/static/userInfo/default_avatar.svg"), avatar: require("@/static/userInfo/default_avatar.svg"),
join_date: "2024年3月加入", join_date: "2024年3月加入",
@@ -37,7 +38,7 @@ const OtherUserPage: React.FC = () => {
ntrp_level: "NTRP 3.5", ntrp_level: "NTRP 3.5",
is_following: false, is_following: false,
ongoing_games: [], ongoing_games: [],
personal_profile: '', personal_profile: "",
}); });
// 模拟球局数据 // 模拟球局数据
@@ -48,7 +49,7 @@ const OtherUserPage: React.FC = () => {
// 当前激活的标签页 // 当前激活的标签页
const [active_tab, setActiveTab] = useState<"hosted" | "participated">( const [active_tab, setActiveTab] = useState<"hosted" | "participated">(
"hosted", "hosted"
); );
// 页面加载时获取用户信息 // 页面加载时获取用户信息
@@ -58,11 +59,36 @@ const OtherUserPage: React.FC = () => {
try { try {
// const user_data = await UserService.get_user_info(user_id); // const user_data = await UserService.get_user_info(user_id);
const res = await LoginService.getUserInfoById(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( const games_data = await UserService.get_user_games(
user_id, user_id,
active_tab, active_tab
); );
setGameRecords(games_data); setGameRecords(games_data);
} catch (error) { } catch (error) {
@@ -83,7 +109,7 @@ const OtherUserPage: React.FC = () => {
try { try {
const new_follow_status = await UserService.toggle_follow( const new_follow_status = await UserService.toggle_follow(
user_info.id, user_info.id,
is_following, is_following
); );
setIsFollowing(new_follow_status); setIsFollowing(new_follow_status);
Taro.showToast({ Taro.showToast({