From 7958e4ee3e72ccaf787f8377189337bbe633039f Mon Sep 17 00:00:00 2001 From: Ultrame <1019265060@qq.com> Date: Wed, 17 Sep 2025 23:25:32 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=A8=E6=88=B7=E7=94=9F=E6=97=A5=E3=80=81?= =?UTF-8?q?=E6=80=A7=E5=88=AB=E3=80=81=E8=81=8C=E4=B8=9A=E3=80=81=E5=9C=B0?= =?UTF-8?q?=E5=9D=80=E3=80=81ntrp=E6=B0=B4=E5=B9=B3=20Picker=E7=BC=96?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Picker/PickerData.js | 20 ++ src/components/Picker/PopupPicker.tsx | 57 ++++-- src/components/UserInfo/index.tsx | 4 +- src/services/userService.ts | 9 +- src/user_pages/edit/index.tsx | 257 ++++++++++++++------------ src/user_pages/other/index.tsx | 3 +- 6 files changed, 208 insertions(+), 142 deletions(-) diff --git a/src/components/Picker/PickerData.js b/src/components/Picker/PickerData.js index c145e8d..cc5c2e2 100644 --- a/src/components/Picker/PickerData.js +++ b/src/components/Picker/PickerData.js @@ -13,6 +13,26 @@ export const renderYearMonth = (minYear = 2020, maxYear = 2099) => { ] } +export const renderYearMonthDay = (minYear = 2020, maxYear = 2099) => { + return [ + // 年份列 + Array.from({ length: maxYear - minYear + 1 }, (_, index) => ({ + text: `${minYear + index}年`, + value: minYear + index + })), + // 月份列 + Array.from({ length: 12 }, (_, index) => ({ + text: `${index + 1}月`, + value: index + 1 + })), + // 日期列 (默认31天,具体天数需在onChange时动态调整) + Array.from({ length: 31 }, (_, index) => ({ + text: `${index + 1}日`, + value: index + 1 + })) + ] +} + export const renderHourMinute = (minHour = 0, maxHour = 23) => { // 生成小时和分钟的选项数据 return [ diff --git a/src/components/Picker/PopupPicker.tsx b/src/components/Picker/PopupPicker.tsx index 2f2292d..54c2547 100644 --- a/src/components/Picker/PopupPicker.tsx +++ b/src/components/Picker/PopupPicker.tsx @@ -1,7 +1,7 @@ import React, { useState, useEffect, useCallback } from 'react' import CommonPopup from '@/components/CommonPopup' import Picker from './Picker' -import { renderYearMonth, renderHourMinute } from './PickerData' +import { renderYearMonth, renderYearMonthDay, renderHourMinute } from './PickerData' interface PickerOption { text: string | number value: string | number @@ -12,55 +12,74 @@ interface PickerProps { setvisible: (visible: boolean) => void options?: PickerOption[][] value?: (string | number)[] - type?: 'month' | 'hour' | null + type?: 'month' | 'day' | 'hour' | null onConfirm?: (options: PickerOption[], values: (string | number)[]) => void - onChange?: ( value: (string | number)[] ) => void + onChange?: (value: (string | number)[]) => void } -const PopupPicker = ({ - visible, - setvisible, - value = [], - onConfirm, +const PopupPicker = ({ + visible, + setvisible, + value = [], + onConfirm, onChange, options = [], type = null }: PickerProps) => { - + const [defaultValue, setDefaultValue] = useState<(string | number)[]>([]) const [defaultOptions, setDefaultOptions] = useState([]) const changePicker = (options: any[], values: any, columnIndex: number) => { + debugger if (onChange) { - console.log('picker onChange', columnIndex, values, options) + console.log('picker onChange', columnIndex, values, options); - setDefaultValue(values) + if (type === 'day' && JSON.stringify(defaultValue) !== JSON.stringify(values)) { + const [year, month] = values; + const daysInMonth = new Date(Number(year), Number(month), 0).getDate(); + const dayOptions = Array.from({ length: daysInMonth }, (_, i) => ({ + text: i + 1 + '日', + value: i + 1, + })); + const newOptions = [...defaultOptions]; + if (JSON.stringify(newOptions[2]) !== JSON.stringify(dayOptions)) { + newOptions[2] = dayOptions; + setDefaultOptions(newOptions); + } + } + + if (JSON.stringify(defaultValue) !== JSON.stringify(values)) { + setDefaultValue(values); + } } } const handleConfirm = () => { - console.log(defaultValue,'defaultValue'); + console.log(defaultValue, 'defaultValue'); onChange(defaultValue) setvisible(false) } - + const dialogClose = () => { setvisible(false) } useEffect(() => { if (type === 'month') { setDefaultOptions(renderYearMonth()) + } else if (type === 'day') { + setDefaultOptions(renderYearMonthDay()) } else if (type === 'hour') { setDefaultOptions(renderHourMinute()) } else { setDefaultOptions(options) } }, [type]) - -// useEffect(() => { -// if (value.length > 0 && defaultOptions.length > 0) { -// setDefaultValue([...value]) -// } -// }, [value, defaultOptions]) + + // useEffect(() => { + // if (value.length > 0 && defaultOptions.length > 0) { + // setDefaultValue([...value]) + // } + // }, [value, defaultOptions]) return ( <> { participated: 0 }, personal_profile: '加载中...', - location: '加载中...', occupation: '加载中...', ntrp_level: 'NTRP 3.0', phone: '', - gender: '' + gender: '', + country: '', + province: '', + city: '', }); // 表单状态 const [form_data, setFormData] = useState({ nickname: '', personal_profile: '', - location: '', occupation: '', ntrp_level: '4.0', phone: '', gender: '', - birthday: '2000-01-01' + birthday: '2000-01-01', + country: '', + province: '', + city: '' }); // 加载状态 @@ -48,6 +53,11 @@ const EditProfilePage: React.FC = () => { // 编辑弹窗状态 const [edit_modal_visible, setEditModalVisible] = useState(false); const [editing_field, setEditingField] = useState(''); + const [gender_picker_visible, setGenderPickerVisible] = useState(false); + const [birthday_picker_visible, setBirthdayPickerVisible] = useState(false); + const [location_picker_visible, setLocationPickerVisible] = useState(false); + const [ntrp_picker_visible, setNtrpPickerVisible] = useState(false); + const [occupation_picker_visible, setOccupationPickerVisible] = useState(false); // 页面加载时初始化数据 useEffect(() => { @@ -63,12 +73,14 @@ const EditProfilePage: React.FC = () => { setFormData({ nickname: user_data.nickname || '', personal_profile: user_data.personal_profile || '', - location: user_data.location || '', occupation: user_data.occupation || '', ntrp_level: user_data.ntrp_level || 'NTRP 4.0', phone: user_data.phone || '', gender: user_data.gender || '', - birthday: user_data.birthday || '', // 默认生日,实际应该从用户数据获取 + birthday: user_data.birthday || '', + country: user_data.country || '', + province: user_data.province || '', + city: user_data.city || '' }); } catch (error) { console.error('加载用户信息失败:', error); @@ -110,6 +122,26 @@ const EditProfilePage: React.FC = () => { // 处理编辑弹窗 const handle_open_edit_modal = (field: string) => { + if (field === 'gender') { + setGenderPickerVisible(true); + return; + } + if (field === 'birthday') { + setBirthdayPickerVisible(true); + return; + } + if (field === 'location') { + setLocationPickerVisible(true); + return; + } + if (field === 'ntrp_level') { + setNtrpPickerVisible(true); + return; + } + if (field === 'occupation') { + setOccupationPickerVisible(true); + return; + } if (field === 'nickname') { // 手动输入 setEditingField(field); @@ -154,15 +186,22 @@ const EditProfilePage: React.FC = () => { }; // 处理字段编辑 - const handle_field_edit = async (field: string, value: string) => { + const handle_field_edit = async (field: string | { [key: string]: string }, value?: string) => { try { - // 调用更新用户信息接口,只传递修改的字段 - const update_data = { [field]: value }; - await UserService.update_user_info(update_data); + if (typeof field === 'object' && field !== null && !Array.isArray(field)) { + await UserService.update_user_info({ ...field }); + // 更新本地状态 + setFormData(prev => ({ ...prev, ...field })); + setUserInfo(prev => ({ ...prev, ...field })); + } else { + // 调用更新用户信息接口,只传递修改的字段 + const update_data = { [field as string]: value }; + await UserService.update_user_info(update_data); - // 更新本地状态 - setFormData(prev => ({ ...prev, [field]: value })); - setUserInfo(prev => ({ ...prev, [field]: value })); + // 更新本地状态 + setFormData(prev => ({ ...prev, [field as string]: value })); + setUserInfo(prev => ({ ...prev, [field as string]: value })); + } // 显示成功提示 Taro.showToast({ @@ -180,64 +219,35 @@ const EditProfilePage: React.FC = () => { // 处理性别选择 const handle_gender_change = (e: any) => { - const gender_value = e.detail.value; + const gender_value = e[0]; handle_field_edit('gender', gender_value); }; // 处理生日选择 const handle_birthday_change = (e: any) => { - const birthday_value = e.detail.value; - handle_field_edit('birthday', birthday_value); + const [year, month, day] = e; + handle_field_edit('birthday', `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`); }; - // NTRP水平输入 - 实时更新本地状态 - const handle_ntrp_level_input = (e: any) => { - const ntrp_level_value = e.detail.value; - setFormData(prev => ({ ...prev, ntrp_level: ntrp_level_value })); - } - // NTRP水平输入 - 失去焦点时保存到服务器 - const handle_ntrp_level_blur = (e: any) => { - const ntrp_level_value = e.detail.value; + // 处理地区选择 + const handle_location_change = (e: any) => { + debugger + const [country, province, city] = e; + handle_field_edit({ country, province, city }); + }; + + // 处理NTRP水平选择 + const handle_ntrp_level_change = (e: any) => { + const ntrp_level_value = e[0]; handle_field_edit('ntrp_level', ntrp_level_value); - } - - // 处理职业输入 - 实时更新本地状态 - 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_occupation_change = (e: any) => { + const [country, province] = e; + handle_field_edit('occupation', `${country} ${province}`); }; - // 处理地区输入 - 实时更新本地状态 - const handle_location_input = (e: any) => { - const location_value = e.detail.value; - setFormData(prev => ({ ...prev, location: location_value })); - }; - - // 处理地区输入 - 失去焦点时保存到服务器 - 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 = () => { Taro.showModal({ @@ -333,46 +343,31 @@ const EditProfilePage: React.FC = () => { {/* 性别 */} - - - - - 性别 - - - - {convert_db_gender_to_display(form_data.gender)} - - - + handle_open_edit_modal('gender')}> + + + 性别 - + + {convert_db_gender_to_display(form_data.gender)} + + + {/* 生日 */} - - - - - 生日 - - - {form_data.birthday} - - + handle_open_edit_modal('birthday')}> + + + 生日 - + + {form_data.birthday} + + + @@ -398,58 +393,39 @@ const EditProfilePage: React.FC = () => { {/* 地区 */} - + handle_open_edit_modal('location')}> 地区 - + {`${form_data.country} ${form_data.province} ${form_data.city}`} {/* NTRP水平 */} - + handle_open_edit_modal('ntrp_level')}> NTRP 水平 - {/* {form_data.ntrp_level} */} - + {form_data.ntrp_level} {/* 职业 */} - + handle_open_edit_modal('occupation')}> 职业 - + {form_data.occupation} @@ -510,6 +486,53 @@ const EditProfilePage: React.FC = () => { onCancel={handle_edit_modal_cancel} validationMessage={editing_field === 'nickname' ? '请填写 1-20 个字符' : '请填写 2-100 个字符'} /> + {/* 性别选择弹窗 */} + {gender_picker_visible && } + {/* 生日选择弹窗 */} + {birthday_picker_visible && } + {/* 地区选择弹窗 */} + {location_picker_visible && } + {/* NTRP水平选择弹窗 */} + {ntrp_picker_visible && } + {/* 职业选择弹窗 */} + {occupation_picker_visible && } ); }; diff --git a/src/user_pages/other/index.tsx b/src/user_pages/other/index.tsx index 98813f2..a2388e4 100644 --- a/src/user_pages/other/index.tsx +++ b/src/user_pages/other/index.tsx @@ -133,9 +133,8 @@ const OtherUserPage: React.FC = () => { active_tab ); const sorted_games = games_data.sort((a, b) => { - return new Date(b.start_time.replace(/\s/, 'T')).getTime() - new Date(a.start_time.replace(/\s/, 'T')).getTime(); + return new Date(a.original_start_time.replace(/\s/, 'T')).getTime() - new Date(b.original_start_time.replace(/\s/, 'T')).getTime(); }); - console.log('xxxxxxxxxxxxxxxxxx', sorted_games) const { notEndGames, finishedGames } = classifyGameRecords(sorted_games); setGameRecords(notEndGames); setEndedGameRecords(finishedGames);