From e2d717204f1d958c801f4665bafff6d364b08c1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=88=90?= Date: Mon, 8 Sep 2025 11:39:59 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E4=B8=8A=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + src/components/Auth/index.tsx | 16 ++--- src/config/api.ts | 3 +- src/config/env.ts | 4 +- src/mod_user/pages/edit/index.tsx | 82 +++++++++++++++++-------- src/services/httpService.ts | 28 ++++++++- src/services/uploadFiles.ts | 58 ++++++++++++++++-- src/services/userService.ts | 99 ++++++++++++++++++++----------- src/utils/genderUtils.ts | 70 ++++++++++++++++++++++ src/utils/index.ts | 1 + 10 files changed, 284 insertions(+), 78 deletions(-) create mode 100644 src/utils/genderUtils.ts diff --git a/.gitignore b/.gitignore index b7dd2d1..fdc3298 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ deploy_versions/ node_modules/ .DS_Store .swc +src/config/env.ts diff --git a/src/components/Auth/index.tsx b/src/components/Auth/index.tsx index 137e358..2ec4f42 100644 --- a/src/components/Auth/index.tsx +++ b/src/components/Auth/index.tsx @@ -32,17 +32,17 @@ export default function withAuth

(WrappedComponent: React.Compo if (!is_login) { const currentPage = getCurrentFullPath() - Taro.redirectTo({ - url: `/pages/login/index/index${ - currentPage ? `?redirect=${encodeURIComponent(currentPage)}` : '' - }`, - }) + // Taro.redirectTo({ + // url: `/pages/login/index/index${ + // currentPage ? `?redirect=${encodeURIComponent(currentPage)}` : '' + // }`, + // }) } }, []) - if (!authed) { - return // 空壳,避免 children 渲染出错 - } + // if (!authed) { + // return // 空壳,避免 children 渲染出错 + // } return } diff --git a/src/config/api.ts b/src/config/api.ts index d09d2be..0ab74ab 100644 --- a/src/config/api.ts +++ b/src/config/api.ts @@ -17,7 +17,8 @@ export const API_CONFIG = { // 文件上传接口 UPLOAD: { AVATAR: '/gallery/upload', - IMAGE: '/gallery/upload' + IMAGE: '/gallery/upload', + OSS_IMG: '/gallery/upload_oss_img' }, // 球局相关接口 diff --git a/src/config/env.ts b/src/config/env.ts index e8b805e..8904ea7 100644 --- a/src/config/env.ts +++ b/src/config/env.ts @@ -17,8 +17,8 @@ const envConfigs: Record = { // 开发环境 development: { name: '开发环境', - apiBaseURL: 'https://sit.light120.com', - // apiBaseURL: 'http://localhost:9098', + // apiBaseURL: 'https://sit.light120.com', + apiBaseURL: 'http://localhost:9098', timeout: 15000, enableLog: true, enableMock: true diff --git a/src/mod_user/pages/edit/index.tsx b/src/mod_user/pages/edit/index.tsx index 16550ec..6256785 100644 --- a/src/mod_user/pages/edit/index.tsx +++ b/src/mod_user/pages/edit/index.tsx @@ -4,7 +4,8 @@ import Taro from '@tarojs/taro'; import './index.scss'; import { UserInfo } from '@/components/UserInfo'; import { UserService } from '@/services/userService'; -import {clear_login_state} from '@/services/loginService'; +import { clear_login_state } from '@/services/loginService'; +import { convert_db_gender_to_display } from '@/utils/genderUtils'; import { EditModal } from '@/components'; const EditProfilePage: React.FC = () => { @@ -123,15 +124,15 @@ const EditProfilePage: React.FC = () => { // 调用更新用户信息接口,只传递修改的字段 const update_data = { [editing_field]: value }; await UserService.update_user_info(update_data); - + // 更新本地状态 setFormData(prev => ({ ...prev, [editing_field]: value })); setUserInfo(prev => ({ ...prev, [editing_field]: value })); - + // 关闭弹窗 setEditModalVisible(false); setEditingField(''); - + // 显示成功提示 Taro.showToast({ title: '保存成功', @@ -157,11 +158,11 @@ const EditProfilePage: React.FC = () => { // 调用更新用户信息接口,只传递修改的字段 const update_data = { [field]: value }; await UserService.update_user_info(update_data); - + // 更新本地状态 setFormData(prev => ({ ...prev, [field]: value })); setUserInfo(prev => ({ ...prev, [field]: value })); - + // 显示成功提示 Taro.showToast({ title: '保存成功', @@ -179,8 +180,9 @@ const EditProfilePage: React.FC = () => { // 处理性别选择 const handle_gender_change = (e: any) => { const gender_value = e.detail.value; - const gender_text = gender_value === 'male' ? '男' : '女'; - handle_field_edit('gender', gender_text); + // 使用工具函数转换:页面选择器值(0/1) -> 数据库值('0'/'1') + const gender_db_value = gender_value === 0 ? '0' : '1'; + handle_field_edit('gender', gender_db_value); }; // 处理生日选择 @@ -189,19 +191,42 @@ const EditProfilePage: React.FC = () => { handle_field_edit('birthday', birthday_value); }; - // 处理职业输入 - const handle_occupation_change = (e: any) => { + // 处理职业输入 - 实时更新本地状态 + const handle_occupation_input = (e: any) => { + const occupation_value = e.detail.value; + setFormData(prev => ({ ...prev, occupation: occupation_value })); + }; + + // 处理职业输入 - 失去焦点时保存到服务器 + const handle_occupation_blur = (e: any) => { const occupation_value = e.detail.value; handle_field_edit('occupation', occupation_value); }; + // 处理地区输入 - 实时更新本地状态 + const handle_location_input = (e: any) => { + const location_value = e.detail.value; + setFormData(prev => ({ ...prev, location: location_value })); + }; - // 处理地区输入 - const handle_location_change = (e: any) => { + // 处理地区输入 - 失去焦点时保存到服务器 + const handle_location_blur = (e: any) => { const location_value = e.detail.value; handle_field_edit('location', location_value); }; + // 处理手机号输入 - 实时更新本地状态 + const handle_phone_input = (e: any) => { + const phone_value = e.detail.value; + setFormData(prev => ({ ...prev, phone: phone_value })); + }; + + // 处理手机号输入 - 失去焦点时保存到服务器 + const handle_phone_blur = (e: any) => { + const phone_value = e.detail.value; + handle_field_edit('phone', phone_value); + }; + // 处理退出登录 const handle_logout = () => { @@ -212,7 +237,7 @@ const EditProfilePage: React.FC = () => { if (res.confirm) { // 清除用户数据 clear_login_state(); - + Taro.reLaunch({ url: '/pages/login/index/index' }); @@ -267,10 +292,10 @@ const EditProfilePage: React.FC = () => { {/* 性别 */} - @@ -279,7 +304,9 @@ const EditProfilePage: React.FC = () => { 性别 - {form_data.gender || '请选择'} + + {convert_db_gender_to_display(form_data.gender)} + @@ -289,8 +316,8 @@ const EditProfilePage: React.FC = () => { {/* 生日 */} - @@ -336,11 +363,12 @@ const EditProfilePage: React.FC = () => { 地区 - handle_location_change(e)} + onInput={handle_location_input} + onBlur={handle_location_blur} /> @@ -366,11 +394,12 @@ const EditProfilePage: React.FC = () => { 职业 - handle_occupation_change(e)} + onInput={handle_occupation_input} + onBlur={handle_occupation_blur} /> @@ -386,12 +415,13 @@ const EditProfilePage: React.FC = () => { 手机 - handle_field_edit('phone', e.detail.value)} + onInput={handle_phone_input} + onBlur={handle_phone_blur} /> diff --git a/src/services/httpService.ts b/src/services/httpService.ts index 223617e..19c1c4a 100644 --- a/src/services/httpService.ts +++ b/src/services/httpService.ts @@ -176,6 +176,13 @@ class HttpService { }) } + getHashParam(key) { + const hash = window.location.hash; + const queryString = hash.split('?')[1] || ''; + const params = new URLSearchParams(queryString); + return params.get(key); + } + // 统一请求方法 async request(config: RequestConfig): Promise> { const { @@ -187,7 +194,20 @@ class HttpService { loadingText = '请求中...' } = config - const fullUrl = this.buildUrl(url, method === 'GET' ? params : undefined) + let fullUrl = this.buildUrl(url, method === 'GET' ? params : undefined) + + + // 后门id,用于调试 + let userid = this.getHashParam("userIdTest") + if (userid) { + if (fullUrl.indexOf("?") > -1) { + fullUrl += `&userIdTest45=${userid}` + } + else { + fullUrl += `?userIdTest45=${userid}` + } + } + this.log('info', `发起请求: ${method} ${fullUrl}`, { data: method !== 'GET' ? data : undefined, @@ -283,6 +303,12 @@ class HttpService { }) } + + uploadFile(){ + + + } + // PUT请求 put(url: string, data?: any, config?: Partial): Promise> { return this.request({ diff --git a/src/services/uploadFiles.ts b/src/services/uploadFiles.ts index ba5a2eb..0a53bf5 100644 --- a/src/services/uploadFiles.ts +++ b/src/services/uploadFiles.ts @@ -1,7 +1,7 @@ -import httpService from './httpService' -import type { ApiResponse } from './httpService' import Taro from '@tarojs/taro' import envConfig from '@/config/env' +import { API_CONFIG } from '@/config/api' +import httpService from './httpService' // 用户接口 export interface UploadFilesData { @@ -39,18 +39,28 @@ export interface uploadFileResponseData { updated_at: string, } -function delay(ms: number) { - return new Promise(resolve => setTimeout(resolve, ms)) -} // 发布球局类 class UploadApi { async upload(req: UploadFilesData): Promise<{ id: string, data: uploadFileResponseData }> { // return httpService.post('/files/upload', req, { // showLoading: true, // }) + + let fullUrl = `${envConfig.apiBaseURL}/api/gallery/upload` + // 后门id,用于调试 + let userid = httpService.getHashParam("userIdTest") + if (userid) { + if (fullUrl.indexOf("?") > -1) { + fullUrl += `&userIdTest45=${userid}` + } + else { + fullUrl += `?userIdTest45=${userid}` + } + } + const { id, ...rest } = req return Taro.uploadFile({ - url: `${envConfig.apiBaseURL}/api/gallery/upload`, + url: fullUrl, filePath: rest.filePath, name: 'file', formData: { @@ -69,6 +79,42 @@ class UploadApi { async batchUpload(req: UploadFilesData[]): Promise<{ id: string, data: uploadFileResponseData }[]> { return Promise.all(req.map(item => this.upload(item))) } + + // 上传单张图片到OSS + async upload_oss_img(file_path: string): Promise { + try { + let fullUrl = `${envConfig.apiBaseURL}/api${API_CONFIG.UPLOAD.OSS_IMG}` + // 后门id,用于调试 + let userid = httpService.getHashParam("userIdTest") + if (userid) { + if (fullUrl.indexOf("?") > -1) { + fullUrl += `&userIdTest45=${userid}` + } + else { + fullUrl += `?userIdTest45=${userid}` + } + } + + const response = await Taro.uploadFile({ + url: fullUrl, + filePath: file_path, + name: 'file', + }); + + const result = JSON.parse(response.data); + + if (result.code === 0) { + return result.data; + } else { + throw new Error(result.message || '上传失败'); + } + } catch (error) { + console.error('上传图片失败:', error); + throw error; + } + } + + } // 导出认证服务实例 diff --git a/src/services/userService.ts b/src/services/userService.ts index 459c8cb..31fb90b 100644 --- a/src/services/userService.ts +++ b/src/services/userService.ts @@ -2,6 +2,7 @@ import { UserInfo } from '@/components/UserInfo'; import Taro from '@tarojs/taro'; import { API_CONFIG } from '@/config/api'; import httpService from './httpService'; +import uploadFiles from './uploadFiles'; // 用户详情接口 @@ -158,8 +159,8 @@ export class UserService { } // 处理距离 - 优先使用venue_dtl中的坐标,其次使用game中的坐标 - let latitude = game.latitude || 0; - let longitude = game.longitude || 0; + let latitude: number = typeof game.latitude === 'number' ? game.latitude : parseFloat(game.latitude || '0') || 0; + let longitude: number = typeof game.longitude === 'number' ? game.longitude : parseFloat(game.longitude || '0') || 0; if (game.venue_dtl) { latitude = parseFloat(game.venue_dtl.latitude) || latitude; longitude = parseFloat(game.venue_dtl.longitude) || longitude; @@ -265,9 +266,9 @@ export class UserService { hosted: userData.stats?.hosted_games_count || 0, participated: userData.stats?.participated_games_count || 0 }, - + personal_profile: '', - location:userData.province + userData.city || '', + location: userData.province + userData.city || '', occupation: '', ntrp_level: '', phone: userData.phone || '', @@ -286,7 +287,28 @@ export class UserService { // 更新用户信息 static async update_user_info(update_data: Partial): Promise { try { - const response = await httpService.post(API_CONFIG.USER.UPDATE, update_data, { + // 过滤掉空字段 + const filtered_data: Record = {}; + + Object.keys(update_data).forEach(key => { + const value = update_data[key as keyof UserInfo]; + // 只添加非空且非空字符串的字段 + if (value !== null && value !== undefined && value !== '') { + if (typeof value === 'string' && value.trim() !== '') { + filtered_data[key] = value.trim(); + } else if (typeof value !== 'string') { + filtered_data[key] = value; + } + } + }); + + // 如果没有需要更新的字段,直接返回 + if (Object.keys(filtered_data).length === 0) { + console.log('没有需要更新的字段'); + return; + } + + const response = await httpService.post(API_CONFIG.USER.UPDATE, filtered_data, { showLoading: true }); @@ -342,7 +364,7 @@ export class UserService { console.error('获取参与球局失败:', error); // 返回符合ListContainer data格式的模拟数据 return []; - + } } @@ -379,25 +401,41 @@ export class UserService { // 保存用户信息 static async save_user_info(user_info: Partial & { phone?: string; gender?: string }): Promise { try { - // 获取当前位置信息 - // const location = await Taro.getLocation({ - // type: 'wgs84' - // }); - - const updateParams: UpdateUserParams = { - nickname: user_info.nickname || '', - avatar_url: user_info.avatar || '', - gender: user_info.gender || '', - phone: user_info.phone || '', - latitude: user_info.latitude||'', - longitude: user_info.longitude||'', - city: user_info.location || '', - province: '', // 需要从用户信息中获取 - country: '' // 需要从用户信息中获取 + // 字段映射配置 + const field_mapping: Record = { + nickname: 'nickname', + avatar: 'avatar_url', + gender: 'gender', + phone: 'phone', + latitude: 'latitude', + longitude: 'longitude', + province: 'province', + country:"country", + city:"city", + personal_profile: 'personal_profile', + occupation: 'occupation', + ntrp_level: 'ntrp_level' }; - const response = await httpService.post(API_CONFIG.USER.UPDATE, updateParams, { + // 构建更新参数,只包含非空字段 + const updateParams: Record = {}; + // 循环处理所有字段 + Object.keys(field_mapping).forEach(key => { + const value = user_info[key as keyof typeof user_info]; + if (value && typeof value === 'string' && value.trim() !== '') { + updateParams[field_mapping[key]] = value.trim(); + } + }); + + + // 如果没有需要更新的字段,直接返回成功 + if (Object.keys(updateParams).length === 0) { + console.log('没有需要更新的字段'); + return true; + } + + const response = await httpService.post(API_CONFIG.USER.UPDATE, updateParams, { showLoading: true, loadingText: '保存中...' }); @@ -440,19 +478,12 @@ export class UserService { static async upload_avatar(file_path: string): Promise { try { // 先上传文件到服务器 - const uploadResponse = await Taro.uploadFile({ - url: `${API_CONFIG.BASE_URL}${API_CONFIG.UPLOAD.AVATAR}`, - filePath: file_path, - name: 'file' - }); + const result = await uploadFiles.upload_oss_img(file_path) - const result = JSON.parse(uploadResponse.data) as { code: number; message: string; data: UploadResponseData }; - if (result.code === 0) { - // 使用新的响应格式中的file_url字段 - return result.data.file_url; - } else { - throw new Error(result.message || '头像上传失败'); - } + await this.save_user_info({ avatar: result.ossPath }) + + // 使用新的响应格式中的file_url字段 + return result.ossPath; } catch (error) { console.error('头像上传失败:', error); // 如果上传失败,返回默认头像 diff --git a/src/utils/genderUtils.ts b/src/utils/genderUtils.ts new file mode 100644 index 0000000..9d1e376 --- /dev/null +++ b/src/utils/genderUtils.ts @@ -0,0 +1,70 @@ +/** + * 性别字段转换工具函数 + * 数据库存储:'0' = 男,'1' = 女 + * 页面显示:'男' = 男,'女' = 女 + * 微信返回:0 = 未知,1 = 男,2 = 女 + */ + +/** + * 将数据库性别值转换为页面显示文本 + * @param db_gender 数据库性别值 ('0' | '1') + * @returns 页面显示文本 ('男' | '女' | '未知') + */ +export const convert_db_gender_to_display = (db_gender: string): string => { + switch (db_gender) { + case '0': + return '男'; + case '1': + return '女'; + default: + return '未知'; + } +}; + +/** + * 将页面显示文本转换为数据库性别值 + * @param display_gender 页面显示文本 ('男' | '女') + * @returns 数据库性别值 ('0' | '1') + */ +export const convert_display_gender_to_db = (display_gender: string): string => { + switch (display_gender) { + case '男': + return '0'; + case '女': + return '1'; + default: + return '0'; // 默认返回男性 + } +}; + +/** + * 将微信性别值转换为数据库性别值 + * @param wechat_gender 微信性别值 (0 | 1 | 2) + * @returns 数据库性别值 ('0' | '1') + */ +export const convert_wechat_gender_to_db = (wechat_gender: number): string => { + switch (wechat_gender) { + case 1: // 微信:1 = 男 + return '0'; // 数据库:'0' = 男 + case 2: // 微信:2 = 女 + return '1'; // 数据库:'1' = 女 + default: // 微信:0 = 未知 + return '0'; // 默认返回男性 + } +}; + +/** + * 将数据库性别值转换为微信性别值 + * @param db_gender 数据库性别值 ('0' | '1') + * @returns 微信性别值 (1 | 2) + */ +export const convert_db_gender_to_wechat = (db_gender: string): number => { + switch (db_gender) { + case '0': + return 1; // 微信:1 = 男 + case '1': + return 2; // 微信:2 = 女 + default: + return 1; // 默认返回男性 + } +}; diff --git a/src/utils/index.ts b/src/utils/index.ts index 1192161..044bd88 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,4 +1,5 @@ export * from './getNavbarHeight' +export * from './genderUtils' export * from './locationUtils' export * from './processImage' export * from './timeUtils' From 6f2e7deb34380be54d7ad6783277c522cdf468e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=88=90?= Date: Mon, 8 Sep 2025 13:00:20 +0800 Subject: [PATCH 2/4] 1 --- src/config/env.ts | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/src/config/env.ts b/src/config/env.ts index 8904ea7..2830e77 100644 --- a/src/config/env.ts +++ b/src/config/env.ts @@ -1,7 +1,7 @@ import Taro from '@tarojs/taro' // 环境类型 -export type EnvType = 'development' | 'test' | 'production' +export type EnvType = 'development' | 'production' // 环境配置接口 export interface EnvConfig { @@ -17,22 +17,14 @@ const envConfigs: Record = { // 开发环境 development: { name: '开发环境', - // apiBaseURL: 'https://sit.light120.com', - apiBaseURL: 'http://localhost:9098', + apiBaseURL: 'https://sit.light120.com', + // apiBaseURL: 'http://localhost:9098', timeout: 15000, enableLog: true, enableMock: true }, - // 测试环境 - test: { - name: '测试环境', - apiBaseURL: 'https://sit.light120.com', - // apiBaseURL: 'http://localhost:9098', - timeout: 12000, - enableLog: true, - enableMock: false - }, + // 生产环境 production: { @@ -85,10 +77,7 @@ export const isProduction = (): boolean => { return getCurrentEnv() === 'production' } -// 是否为测试环境 -export const isTest = (): boolean => { - return getCurrentEnv() === 'test' -} + // 环境配置调试信息 export const getEnvInfo = () => { From 7724314530f084f2e9769cfe4c3ed0ca68c0ccd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=88=90?= Date: Mon, 8 Sep 2025 13:20:44 +0800 Subject: [PATCH 3/4] 1 --- src/pages/list/index.tsx | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/pages/list/index.tsx b/src/pages/list/index.tsx index 46f7c5e..58caa2f 100644 --- a/src/pages/list/index.tsx +++ b/src/pages/list/index.tsx @@ -13,11 +13,20 @@ import DistanceQuickFilter from "@/components/DistanceQuickFilter"; import { withAuth } from "@/components"; // import img from "@/config/images"; + + + const ListPage = () => { + // 从 store 获取数据和方法 const store = useListStore() || {}; - const { statusNavbarHeightInfo, location = {} } = useGlobalState() || {}; + const { statusNavbarHeightInfo, location = {}, getCurrentLocationInfo } = useGlobalState() || {}; + + useEffect(() => { + getCurrentLocationInfo?.(); + }, [getCurrentLocationInfo]); + const { totalHeight } = statusNavbarHeightInfo || {}; const { isShowFilterPopup, @@ -53,6 +62,7 @@ const ListPage = () => { }); useEffect(() => { + if (location?.address) { // 保存位置 updateState({ location }); @@ -111,7 +121,7 @@ const ListPage = () => { updateFilterOptions(params); }; - const handleSearchChange = () => {}; + const handleSearchChange = () => { }; // 距离筛选 const handleDistanceOrQuickChange = (name, value) => { @@ -135,9 +145,8 @@ const ListPage = () => { Date: Mon, 8 Sep 2025 13:23:28 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20=E5=8F=91=E5=B8=83=20?= =?UTF-8?q?=E4=B8=8D=E5=8F=AF=E7=94=A8=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/publishBall/publishForm.tsx | 35 +++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/src/pages/publishBall/publishForm.tsx b/src/pages/publishBall/publishForm.tsx index c53f6e0..5c59563 100644 --- a/src/pages/publishBall/publishForm.tsx +++ b/src/pages/publishBall/publishForm.tsx @@ -91,8 +91,21 @@ const PublishForm: React.FC<{ }) } - const getNTRPText = (ntrp: [number, number]) => { - const [min, max] = ntrp + const getNTRPText = (ntrp: [number, number] | any) => { + // 检查 ntrp 是否为数组 + if (!Array.isArray(ntrp) || ntrp.length !== 2) { + console.warn('getNTRPText: ntrp 不是有效的数组格式:', ntrp); + return '未设置'; + } + + const [min, max] = ntrp; + + // 检查 min 和 max 是否为有效数字 + if (typeof min !== 'number' || typeof max !== 'number') { + console.warn('getNTRPText: min 或 max 不是有效数字:', { min, max }); + return '未设置'; + } + if (min === 1.0 && max === 5.0) { return '不限' } @@ -112,12 +125,24 @@ const PublishForm: React.FC<{ return `${min.toFixed(1)} - ${max.toFixed(1)}之间` } - return ''; } - const getPlayersText = (players: [number, number]) => { - const [min, max] = players + const getPlayersText = (players: [number, number] | any) => { + // 检查 players 是否为数组 + if (!Array.isArray(players) || players.length !== 2) { + console.warn('getPlayersText: players 不是有效的数组格式:', players); + return '未设置'; + } + + const [min, max] = players; + + // 检查 min 和 max 是否为有效数字 + if (typeof min !== 'number' || typeof max !== 'number') { + console.warn('getPlayersText: min 或 max 不是有效数字:', { min, max }); + return '未设置'; + } + return `最少${min}人,最多${max}人` }