diff --git a/src/components/FollowUserCard/index.tsx b/src/components/FollowUserCard/index.tsx index 97b9dcd..cf4c077 100644 --- a/src/components/FollowUserCard/index.tsx +++ b/src/components/FollowUserCard/index.tsx @@ -4,12 +4,17 @@ import Taro from '@tarojs/taro'; import { FollowUser } from '@/services/followService'; import './index.scss'; + +// 标签页类型 +type TabType = 'mutual_follow' | 'following' | 'follower' | 'recommend'; + interface FollowUserCardProps { user: FollowUser; + tabKey: TabType; onFollowChange?: (userId: number, isFollowing: boolean) => void; } -const FollowUserCard: React.FC = ({ user, onFollowChange }) => { +const FollowUserCard: React.FC = ({ user, tabKey, onFollowChange }) => { const [isProcessing, setIsProcessing] = useState(false); // 防御性检查 @@ -23,7 +28,7 @@ const FollowUserCard: React.FC = ({ user, onFollowChange }) try { setIsProcessing(true); - + // 根据当前状态决定操作 let new_status = false; if (user.follow_status === 'follower' || user.follow_status === 'recommend') { @@ -53,7 +58,7 @@ const FollowUserCard: React.FC = ({ user, onFollowChange }) try { setIsProcessing(true); // TODO: 加入黑名单逻辑 - Taro.showToast({ + Taro.showToast({ title: '不会再为您推荐该用户', icon: 'none' }); @@ -107,8 +112,8 @@ const FollowUserCard: React.FC = ({ user, onFollowChange }) return ( - @@ -118,8 +123,8 @@ const FollowUserCard: React.FC = ({ user, onFollowChange }) - - @@ -128,7 +133,7 @@ const FollowUserCard: React.FC = ({ user, onFollowChange }) { - user.follow_status === 'recommend' && ( + tabKey === 'recommend' && ( ) } diff --git a/src/static/userInfo/female.svg b/src/static/userInfo/female.svg index b6e6f14..f74adb8 100644 --- a/src/static/userInfo/female.svg +++ b/src/static/userInfo/female.svg @@ -1,5 +1,17 @@ - - - - + + + + + + + + + + + + + + + + diff --git a/src/static/userInfo/male.svg b/src/static/userInfo/male.svg index 127367e..772015b 100644 --- a/src/static/userInfo/male.svg +++ b/src/static/userInfo/male.svg @@ -1,5 +1,5 @@ - - - - + + + + diff --git a/src/user_pages/follow/index.tsx b/src/user_pages/follow/index.tsx index e5bfd0d..59fd76b 100644 --- a/src/user_pages/follow/index.tsx +++ b/src/user_pages/follow/index.tsx @@ -6,6 +6,7 @@ import FollowUserCard from '@/components/FollowUserCard'; import { FollowService, FollowUser } from '@/services/followService'; import { withAuth } from '@/components'; import './index.scss'; +import CommonDialog from '@/components/CommonDialog' // 标签页类型 type TabType = 'mutual_follow' | 'following' | 'follower' | 'recommend'; @@ -22,7 +23,7 @@ const FollowPage: React.FC = () => { // 获取页面参数,支持指定默认标签页 const instance = Taro.getCurrentInstance(); const default_tab = (instance.router?.params?.tab as TabType) || 'mutual_follow'; - + // 当前激活的标签页 - 根据设计稿默认显示互相关注 const [active_tab, set_active_tab] = useState(default_tab); @@ -101,58 +102,62 @@ const FollowPage: React.FC = () => { load_user_list(tab, true); }; + const updateFollowStatus = (user_id: number, is_following: boolean) => { + // 更新用户列表中的关注状态 + set_user_lists(prev => { + const new_lists = { ...prev }; + + // 更新所有标签页中的用户状态 + Object.keys(new_lists).forEach(tab_key => { + const tab = tab_key as TabType; + if (new_lists[tab] && Array.isArray(new_lists[tab])) { + new_lists[tab] = new_lists[tab].map(user => { + if (user.id === user_id) { + // 根据操作结果更新状态 + let new_status = user.follow_status; + if (is_following) { + if (user.follow_status === 'follower') { + new_status = 'mutual_follow'; + } else if (user.follow_status === 'recommend') { + new_status = 'following'; + } + } else { + if (user.follow_status === 'mutual_follow') { + new_status = 'follower'; + } else if (user.follow_status === 'following') { + new_status = 'recommend'; + } + } + return { ...user, follow_status: new_status }; + } + return user; + }); + } + }); + + return new_lists; + }); + }; + // 处理关注状态变化 const handle_follow_change = async (user_id: number, is_following: boolean) => { try { if (is_following) { await FollowService.follow_user(user_id); + updateFollowStatus(user_id, is_following); // Taro.showToast({ // title: '关注成功', // icon: 'success' // }); } else { - await FollowService.unfollow_user(user_id); + showDeleteConfirm(user_id); + return; // Taro.showToast({ // title: '取消关注成功', // icon: 'success' // }); } - // 更新用户列表中的关注状态 - set_user_lists(prev => { - const new_lists = { ...prev }; - - // 更新所有标签页中的用户状态 - Object.keys(new_lists).forEach(tab_key => { - const tab = tab_key as TabType; - if (new_lists[tab] && Array.isArray(new_lists[tab])) { - new_lists[tab] = new_lists[tab].map(user => { - if (user.id === user_id) { - // 根据操作结果更新状态 - let new_status = user.follow_status; - if (is_following) { - if (user.follow_status === 'follower') { - new_status = 'mutual_follow'; - } else if (user.follow_status === 'recommend') { - new_status = 'following'; - } - } else { - if (user.follow_status === 'mutual_follow') { - new_status = 'follower'; - } else if (user.follow_status === 'following') { - new_status = 'recommend'; - } - } - return { ...user, follow_status: new_status }; - } - return user; - }); - } - }); - - return new_lists; - }); - } catch (error) { console.error('关注操作失败:', error); Taro.showToast({ @@ -186,6 +191,46 @@ const FollowPage: React.FC = () => { }); } }, [default_tab]); + // 取消关注确认弹窗状态 + const [deleteConfirm, setDeleteConfirm] = useState<{ + visible: boolean; + userId: number | null; + }>({ + visible: false, + userId: null + }) + // 取消关注确认弹窗 + const showDeleteConfirm = (userId: number | null) => { + setDeleteConfirm({ + visible: true, + userId: userId + }) + } + // 关闭取消关注确认弹窗 + const closeDeleteConfirm = () => { + setDeleteConfirm({ + visible: false, + userId: null + }) + } + // 确认取消关注 + const confirmUnfollow = async () => { + try { + await FollowService.unfollow_user(deleteConfirm.userId!); + closeDeleteConfirm(); + updateFollowStatus(deleteConfirm.userId!, false); + // Taro.showToast({ + // title: '取消关注成功', + // icon: 'success' + // }); + } catch (error) { + console.error('取消关注失败:', error); + Taro.showToast({ + title: '操作失败', + icon: 'none' + }); + } + } return ( @@ -216,7 +261,7 @@ const FollowPage: React.FC = () => { {/* 推荐图标 SVG */} - + )} @@ -238,6 +283,7 @@ const FollowPage: React.FC = () => { )) || []} @@ -263,6 +309,17 @@ const FollowPage: React.FC = () => { )} + + {/* 取消关注确认弹窗 */} + ); }; diff --git a/src/user_pages/myself/index.scss b/src/user_pages/myself/index.scss index b84a546..92faf61 100644 --- a/src/user_pages/myself/index.scss +++ b/src/user_pages/myself/index.scss @@ -365,4 +365,15 @@ } } } +} + +.ended_game_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); + transition: color 0.3s ease; + padding: 24px 15px; } \ No newline at end of file diff --git a/src/user_pages/myself/index.tsx b/src/user_pages/myself/index.tsx index 034980b..e952215 100644 --- a/src/user_pages/myself/index.tsx +++ b/src/user_pages/myself/index.tsx @@ -41,6 +41,8 @@ const MyselfPage: React.FC = () => { // 球局记录状态 const [game_records, set_game_records] = useState([]); + // 往期球局 + const [ended_game_records, setEndedGameRecords] = useState([]); const [loading, set_loading] = useState(true); // 关注状态 @@ -99,7 +101,26 @@ const MyselfPage: React.FC = () => { load_game_data(); } }, [active_tab]); - + // 分类球局数据 + const classifyGameRecords = ( + game_records: TennisMatch[] + ): { notEndGames: TennisMatch[]; finishedGames: TennisMatch[] } => { + const now = new Date().getTime(); + return game_records.reduce( + (result, cur) => { + let { end_time } = cur; + end_time = end_time.replace(/\s/, "T"); + new Date(end_time).getTime() > now + ? result.notEndGames.push(cur) + : result.finishedGames.push(cur); + return result; + }, + { + notEndGames: [] as TennisMatch[], + finishedGames: [] as TennisMatch[], + } + ); + }; // 加载球局数据 const load_game_data = async () => { try { @@ -109,7 +130,13 @@ const MyselfPage: React.FC = () => { } else { games_data = await UserService.get_participated_games(user_info.id); } - set_game_records(games_data); + 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(); + }); + const { notEndGames, finishedGames } = classifyGameRecords(sorted_games); + set_game_records(notEndGames); + setEndedGameRecords(finishedGames); + // set_game_records(games_data); } catch (error) { console.error("加载球局数据失败:", error); } @@ -225,6 +252,41 @@ const MyselfPage: React.FC = () => { /> + + {/* 往期球局 */} + 往期球局 + + {/* + 5月29日 + / + 星期六 + */} + + {/* 球局列表 */} + {/* */} + + { }} + /> + + {/* */} + + {/* 球局卡片 */} + {/* + {game_records.map((game) => ( + + ))} + */} + diff --git a/src/user_pages/other/index.scss b/src/user_pages/other/index.scss index 1059e52..395c18c 100644 --- a/src/user_pages/other/index.scss +++ b/src/user_pages/other/index.scss @@ -554,5 +554,5 @@ letter-spacing: 1.9%; color: rgba(0, 0, 0, 0.85); transition: color 0.3s ease; - padding: 12px 15px; + padding: 24px 15px; } diff --git a/types/list/types.ts b/types/list/types.ts index c038980..67e924f 100644 --- a/types/list/types.ts +++ b/types/list/types.ts @@ -10,7 +10,8 @@ export interface TennisMatch { skillLevel: string matchType: string images: string[] - shinei: string + shinei: string, + end_time: string, } export interface IFilterOptions { dateRange: [string, string], // 日期区间