This commit is contained in:
张成
2026-02-09 13:25:13 +08:00
parent 632da5112d
commit cab90aa1cb
6 changed files with 164 additions and 41 deletions

128
config/env.ts Normal file
View File

@@ -0,0 +1,128 @@
import Taro from '@tarojs/taro'
// 环境类型
export type EnvType = 'development' | 'production'
// 环境配置接口
export interface EnvConfig {
name: string
apiBaseURL: string
timeout: number
enableLog: boolean
enableMock: boolean
// 客服配置
customerService: {
corpId: string
serviceUrl: string
phoneNumber?: string
email?: string
}
}
// 各环境配置
const envConfigs: Record<EnvType, EnvConfig> = {
// 开发环境
development: {
name: '开发环境',
// apiBaseURL: 'https://tennis.bimwe.com',
apiBaseURL: 'http://localhost:9098',
timeout: 15000,
enableLog: true,
enableMock: false,
// 客服配置
customerService: {
corpId: 'ww51fc969e8b76af82', // 企业ID
serviceUrl: 'https://work.weixin.qq.com/kfid/kfc64085b93243c5c91',
}
},
// 生产环境1
// production: {
// name: '生产环境1',
// apiBaseURL: 'https://tennis.bimwe.com',
// timeout: 10000,
// enableLog: false,
// enableMock: false,
// // 客服配置
// customerService: {
// corpId: 'ww51fc969e8b76af82', // 企业ID
// serviceUrl: 'https://work.weixin.qq.com/kfid/kfc64085b93243c5c91',
// }
// },
// 生产环境2
production: {
name: '生产环境2',
apiBaseURL: 'https://youchang.qiongjingtiyu.com',
timeout: 10000,
enableLog: false,
enableMock: false,
// 客服配置
customerService: {
corpId: 'ww9a2d9a5d9410c664', // 企业ID
serviceUrl: 'https://work.weixin.qq.com/kfid/kfcd355e162e0390684',
}
}
}
// 获取当前环境
export const getCurrentEnv = (): EnvType => {
// 在小程序环境中,使用默认逻辑判断环境
// 可以根据实际需要配置不同的判断逻辑
// 可以根据实际部署情况添加更多判断逻辑
// 比如通过 Taro.getEnv() 获取当前平台环境
const isProd = process.env.NODE_ENV === 'production'
if (isProd) {
return 'production'
} else {
return 'development'
}
}
// 获取当前环境配置
export const getCurrentConfig = (): EnvConfig => {
const env = getCurrentEnv()
return envConfigs[env]
}
// 获取指定环境配置
export const getEnvConfig = (env: EnvType): EnvConfig => {
return envConfigs[env]
}
// 是否为开发环境
export const isDevelopment = (): boolean => {
return getCurrentEnv() === 'development'
}
// 是否为生产环境
export const isProduction = (): boolean => {
return getCurrentEnv() === 'production'
}
// 环境配置调试信息
export const getEnvInfo = () => {
const config = getCurrentConfig()
return {
env: getCurrentEnv(),
config,
taroEnv: Taro.getEnv(),
platform: Taro.getEnv() === Taro.ENV_TYPE.WEAPP ? '微信小程序' :
Taro.getEnv() === Taro.ENV_TYPE.WEB ? 'Web' :
Taro.getEnv() === Taro.ENV_TYPE.RN ? 'React Native' : '未知'
}
}
// 导出当前环境配置(方便直接使用)
export default getCurrentConfig()

View File

@@ -46,4 +46,4 @@
"simulatorType": "wechat", "simulatorType": "wechat",
"simulatorPluginLibVersion": {}, "simulatorPluginLibVersion": {},
"condition": {} "condition": {}
} }

View File

@@ -1,6 +1,7 @@
import React, { useState } from "react"; import React, { useState } from "react";
import { View, Text, Button, Image } from "@tarojs/components"; import { View, Text, Button, Image } from "@tarojs/components";
import Taro, { useRouter } from "@tarojs/taro"; import Taro, { useRouter } from "@tarojs/taro";
import { GeneralNavbar } from "@/components";
import { import {
wechat_auth_login, wechat_auth_login,
save_login_state, save_login_state,
@@ -171,6 +172,8 @@ const LoginPage: React.FC = () => {
<View className="bg_overlay"></View> <View className="bg_overlay"></View>
</View> </View>
<GeneralNavbar title="" showBack={true} showAvatar={false} onBack={handle_return_home} />
{/* 主要内容 */} {/* 主要内容 */}
<View className="login_main_content"> <View className="login_main_content">
{/* 品牌区域 */} {/* 品牌区域 */}
@@ -216,9 +219,9 @@ const LoginPage: React.FC = () => {
<Text className="button_text"></Text> <Text className="button_text"></Text>
</Button> </Button>
<View className="return_home_button link_button" onClick={handle_return_home}> {/* <View className="return_home_button link_button" onClick={handle_return_home}>
<Text className="button_text">返回首页</Text> <Text className="button_text">返回首页</Text>
</View> </View> */}
{/* 用户协议复选框 */} {/* 用户协议复选框 */}
<View className="terms_checkbox_section"> <View className="terms_checkbox_section">

View File

@@ -65,20 +65,22 @@ const MyselfPageContent: React.FC<MyselfPageContentProps> = ({ isActive = true }
game_records: TennisMatch[] game_records: TennisMatch[]
): { notEndGames: TennisMatch[]; finishedGames: TennisMatch[] } => { ): { notEndGames: TennisMatch[]; finishedGames: TennisMatch[] } => {
const now = new Date().getTime(); const now = new Date().getTime();
return game_records.reduce(
(result, cur) => { // 使用for
let { end_time } = cur; const notEndGames: TennisMatch[] = [];
end_time = end_time.replace(/\s/, "T"); const finishedGames: TennisMatch[] = [];
new Date(end_time).getTime() > now for (const game of game_records) {
? result.notEndGames.push(cur) const { end_time } = game;
: result.finishedGames.push(cur); const end_time_str = end_time.replace(/\s/, "T");
return result; new Date(end_time_str).getTime() > now
}, ? notEndGames.push(game)
{ : finishedGames.push(game);
notEndGames: [] as TennisMatch[], }
finishedGames: [] as TennisMatch[],
} console.log("notEndGames", notEndGames);
);
return { notEndGames, finishedGames };
}, },
[] []
); );
@@ -95,6 +97,8 @@ const MyselfPageContent: React.FC<MyselfPageContentProps> = ({ isActive = true }
} else { } else {
games_data = await UserService.get_participated_games(user_info.id); games_data = await UserService.get_participated_games(user_info.id);
} }
const sorted_games = games_data.sort((a, b) => { const sorted_games = games_data.sort((a, b) => {
return ( return (
new Date(a.original_start_time.replace(/\s/, "T")).getTime() - new Date(a.original_start_time.replace(/\s/, "T")).getTime() -
@@ -102,6 +106,8 @@ const MyselfPageContent: React.FC<MyselfPageContentProps> = ({ isActive = true }
); );
}); });
const { notEndGames, finishedGames } = classifyGameRecords(sorted_games); const { notEndGames, finishedGames } = classifyGameRecords(sorted_games);
console.log("notEndGames", notEndGames);
set_game_records(notEndGames); set_game_records(notEndGames);
setEndedGameRecords(finishedGames); setEndedGameRecords(finishedGames);
} catch (error) { } catch (error) {
@@ -250,17 +256,15 @@ const MyselfPageContent: React.FC<MyselfPageContentProps> = ({ isActive = true }
<View className={styles.gameTabsSection}> <View className={styles.gameTabsSection}>
<View className={styles.tabContainer}> <View className={styles.tabContainer}>
<View <View
className={`${styles.tabItem} ${ className={`${styles.tabItem} ${active_tab === "hosted" ? styles.active : ""
active_tab === "hosted" ? styles.active : "" }`}
}`}
onClick={() => setActiveTab("hosted")} onClick={() => setActiveTab("hosted")}
> >
<Text className={styles.tabText}></Text> <Text className={styles.tabText}></Text>
</View> </View>
<View <View
className={`${styles.tabItem} ${ className={`${styles.tabItem} ${active_tab === "participated" ? styles.active : ""
active_tab === "participated" ? styles.active : "" }`}
}`}
onClick={() => setActiveTab("participated")} onClick={() => setActiveTab("participated")}
> >
<Text className={styles.tabText}></Text> <Text className={styles.tabText}></Text>
@@ -281,7 +285,7 @@ const MyselfPageContent: React.FC<MyselfPageContentProps> = ({ isActive = true }
btnImg="ICON_ADD" btnImg="ICON_ADD"
reload={goPublish} reload={goPublish}
isShowNoData={game_records.length === 0} isShowNoData={game_records.length === 0}
loadMoreMatches={() => {}} loadMoreMatches={() => { }}
collapse={true} collapse={true}
style={{ style={{
paddingBottom: ended_game_records.length ? 0 : "90px", paddingBottom: ended_game_records.length ? 0 : "90px",
@@ -308,7 +312,7 @@ const MyselfPageContent: React.FC<MyselfPageContentProps> = ({ isActive = true }
error={null} error={null}
errorImg="ICON_LIST_EMPTY_CARD" errorImg="ICON_LIST_EMPTY_CARD"
isShowNoData={ended_game_records.length === 0} isShowNoData={ended_game_records.length === 0}
loadMoreMatches={() => {}} loadMoreMatches={() => { }}
collapse={true} collapse={true}
style={{ paddingBottom: "90px", overflow: "hidden" }} style={{ paddingBottom: "90px", overflow: "hidden" }}
listLoadErrorWrapperHeight="fit-content" listLoadErrorWrapperHeight="fit-content"

View File

@@ -249,7 +249,7 @@ const CommentReply = () => {
<View className="comment-left"> <View className="comment-left">
<Image <Image
className="user-avatar" className="user-avatar"
src={item.user_avatar || "https://img.yzcdn.cn/vant/cat.jpeg"} src={item.user_avatar }
mode="aspectFill" mode="aspectFill"
onClick={(e) => handleUserClick(e, item.user_id)} onClick={(e) => handleUserClick(e, item.user_id)}
/> />

View File

@@ -151,6 +151,7 @@ interface BackendGameData {
longitude: string; longitude: string;
venue_type: string; venue_type: string;
surface_type: string; surface_type: string;
distance_km: string;
}; };
participants: { participants: {
user: { user: {
@@ -206,7 +207,7 @@ export class UserService {
latitude = parseFloat(game.venue_dtl.latitude) || latitude; latitude = parseFloat(game.venue_dtl.latitude) || latitude;
longitude = parseFloat(game.venue_dtl.longitude) || longitude; longitude = parseFloat(game.venue_dtl.longitude) || longitude;
} }
const distance = this.calculate_distance(latitude, longitude);
// 处理地点信息 - 优先使用venue_dtl中的信息 // 处理地点信息 - 优先使用venue_dtl中的信息
let location = game.location_name || game.location || "未知地点"; let location = game.location_name || game.location || "未知地点";
@@ -227,7 +228,7 @@ export class UserService {
original_start_time: game.start_time, original_start_time: game.start_time,
end_time: game.end_time || "", end_time: game.end_time || "",
location: location, location: location,
distance_km: parseFloat(distance.replace("km", "")) || 0, distance_km: game.venue_dtl?.distance_km ,
current_players: registered_count, current_players: registered_count,
max_players: max_count, max_players: max_count,
skill_level_min: parseInt(game.skill_level_min) || 0, skill_level_min: parseInt(game.skill_level_min) || 0,
@@ -303,20 +304,7 @@ export class UserService {
return `${date_str} ${time_str}`; return `${date_str} ${time_str}`;
} }
// 计算距离(模拟实现,实际需要根据用户位置计算)
private static calculate_distance(
latitude: number,
longitude: number
): string {
if (latitude === 0 && longitude === 0) {
return "未知距离";
}
// 这里应该根据用户当前位置计算实际距离
// 暂时返回模拟距离
const distances = ["1.2km", "2.5km", "3.8km", "5.1km", "7.3km"];
return distances[Math.floor(Math.random() * distances.length)];
}
// 获取用户信息 // 获取用户信息
static async get_user_info(user_id?: string): Promise<UserInfo> { static async get_user_info(user_id?: string): Promise<UserInfo> {
try { try {