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..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 {
@@ -18,21 +18,13 @@ const envConfigs: Record = {
development: {
name: '开发环境',
apiBaseURL: 'https://sit.light120.com',
- // apiBaseURL: 'http://localhost:9098',
+ // 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 = () => {
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/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 = () => {
{
- 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}人`
}
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'