feat: 重构用户认证和个人资料功能
- 更新用户认证流程,启用未授权跳转 - 重构个人资料页面,使用真实API数据 - 修改注册和编辑资料表单,适配新API - 移除旧订单相关API,添加用户资料API - 优化验证码发送和手机号绑定逻辑 - 调整样式和代码结构,提高可维护性
Showing
12 changed files
with
292 additions
and
272 deletions
| 1 | /* | 1 | /* |
| 2 | * @Date: 2023-12-22 10:29:37 | 2 | * @Date: 2023-12-22 10:29:37 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2024-06-06 09:31:34 | 4 | + * @LastEditTime: 2025-07-08 20:22:08 |
| 5 | - * @FilePath: /meihuaApp/src/api/index.js | 5 | + * @FilePath: /jgdl/src/api/index.js |
| 6 | * @Description: 文件描述 | 6 | * @Description: 文件描述 |
| 7 | */ | 7 | */ |
| 8 | import { fn, fetch } from './fn'; | 8 | import { fn, fetch } from './fn'; |
| 9 | 9 | ||
| 10 | const Api = { | 10 | const Api = { |
| 11 | - BIND_PHONE: '/srv/?a=room_order&t=bind_phone', | ||
| 12 | - SEND_SMS_CODE: '/srv/?a=room_order&t=send_sms_code', | ||
| 13 | - SHOW_SESSION: '/srv/?a=room_order&t=show_session', | ||
| 14 | - SAVE_CUSTOMER_INFO: '/srv/?a=room_order&t=save_customer_info', | ||
| 15 | - SYS_PARAM: '/srv/?a=room_order&t=sys_param', | ||
| 16 | - GET_LIST: '/srv/?a=room_data&t=get_list', | ||
| 17 | - GET_ROOM: '/srv/?a=room_data&t=get_room', | ||
| 18 | - ADD_ORDER: '/srv/?a=room_data&t=add_order', | ||
| 19 | - MY_ORDER: '/srv/?a=room_data&t=my_order', | ||
| 20 | - ORDER_CANCEL: '/srv/?a=room_data&t=order_cancel', | ||
| 21 | PAY: '/srv/?a=pay', | 11 | PAY: '/srv/?a=pay', |
| 22 | PAY_CHECK: '/srv/?a=pay_check', | 12 | PAY_CHECK: '/srv/?a=pay_check', |
| 23 | - ORDER_SUCCESS: '/srv/?a=room_data&t=order_success', | 13 | + UPDATE_PROFILE: '/srv/?a=user&t=update_profile', |
| 24 | - TMP_SYS_PARAM: '/srv/?a=get_item', | 14 | + SEND_SMS_CODE: '/srv/?a=sms_code', |
| 15 | + GET_PROFILE: '/srv/?a=user&t=get_profile', | ||
| 25 | } | 16 | } |
| 26 | - | ||
| 27 | -/** | ||
| 28 | - * @description: 绑定手机号(手机号登录) | ||
| 29 | - * @param phone 手机号 | ||
| 30 | - * @param sms_code 验证码 | ||
| 31 | - * @returns | ||
| 32 | - */ | ||
| 33 | -export const bindPhoneAPI = (params) => fn(fetch.post(Api.BIND_PHONE, params)); | ||
| 34 | - | ||
| 35 | -/** | ||
| 36 | - * @description: 发送验证码 | ||
| 37 | - * @param phone 手机号 | ||
| 38 | - * @returns | ||
| 39 | - */ | ||
| 40 | -export const sendSmsCodeAPI = (params) => fn(fetch.post(Api.SEND_SMS_CODE, params)); | ||
| 41 | - | ||
| 42 | -/** | ||
| 43 | - * @description: 获取我的信息 | ||
| 44 | - * @returns | ||
| 45 | - */ | ||
| 46 | -export const showMyInfoAPI = (params) => fn(fetch.get(Api.SHOW_SESSION, params)); | ||
| 47 | - | ||
| 48 | -/** | ||
| 49 | - * @description: 保存我的信息 | ||
| 50 | - * @param params | ||
| 51 | - * @returns | ||
| 52 | - */ | ||
| 53 | -export const saveCustomerInfoAPI = (params) => fn(fetch.post(Api.SAVE_CUSTOMER_INFO, params)); | ||
| 54 | - | ||
| 55 | -/** | ||
| 56 | - * @description: 获取系统参数 | ||
| 57 | - * @returns | ||
| 58 | - */ | ||
| 59 | -export const sysParamAPI = (params) => fn(fetch.get(Api.SYS_PARAM, params)); | ||
| 60 | - | ||
| 61 | -/** | ||
| 62 | - * @description: 获取房间列表 | ||
| 63 | - * @param start_date 入住时间 | ||
| 64 | - * @param end_date 离店时间 | ||
| 65 | - * @param offset 偏移量 | ||
| 66 | - * @param limit 条数 | ||
| 67 | - * @returns | ||
| 68 | - */ | ||
| 69 | -export const getListAPI = (params) => fn(fetch.get(Api.GET_LIST, params)); | ||
| 70 | - | ||
| 71 | -/** | ||
| 72 | - * @description: 获取房间详情 | ||
| 73 | - * @param start_date 入住时间 | ||
| 74 | - * @param end_date 离店时间 | ||
| 75 | - * @param room_type floor/room | ||
| 76 | - * @returns | ||
| 77 | - */ | ||
| 78 | -export const getRoomAPI = (params) => fn(fetch.get(Api.GET_ROOM, params)); | ||
| 79 | - | ||
| 80 | -/** | ||
| 81 | - * @description: 预定房间 | ||
| 82 | - * @param id ID | ||
| 83 | - * @param num 预定房间数量 | ||
| 84 | - * @param plan_in 入住时间 | ||
| 85 | - * @param plan_out 离店时间 | ||
| 86 | - * @param contact_name 联系人 | ||
| 87 | - * @param contact_phone 联系电话 | ||
| 88 | - * @param order_remark 备注 | ||
| 89 | - * @param room_type floor/room | ||
| 90 | - * @returns | ||
| 91 | - */ | ||
| 92 | -export const addOrderAPI = (params) => fn(fetch.post(Api.ADD_ORDER, params)); | ||
| 93 | - | ||
| 94 | /** | 17 | /** |
| 95 | * @description: 支付 | 18 | * @description: 支付 |
| 96 | * @param order_id 订单ID | 19 | * @param order_id 订单ID |
| ... | @@ -106,31 +29,26 @@ export const payAPI = (params) => fn(fetch.post(Api.PAY, params)); | ... | @@ -106,31 +29,26 @@ export const payAPI = (params) => fn(fetch.post(Api.PAY, params)); |
| 106 | export const payCheckAPI = (params) => fn(fetch.post(Api.PAY_CHECK, params)); | 29 | export const payCheckAPI = (params) => fn(fetch.post(Api.PAY_CHECK, params)); |
| 107 | 30 | ||
| 108 | /** | 31 | /** |
| 109 | - * @description: 获取我的订单列表 | 32 | + * @description: 注册/编辑用户 |
| 110 | - * @param pay_type | 33 | + * @param nickname 昵称 |
| 111 | - * @param page | 34 | + * @param avatar_url 头像 |
| 112 | - * @param limit | 35 | + * @param gender 性别 0=女, 1=男 |
| 113 | - * @returns | 36 | + * @param phone 手机号 |
| 114 | - */ | 37 | + * @param sms_code 短信验证码 |
| 115 | -export const myOrderAPI = (params) => fn(fetch.get(Api.MY_ORDER, params)); | 38 | + * @param school_id 学校id |
| 116 | - | ||
| 117 | -/** | ||
| 118 | - * @description: 取消订单 | ||
| 119 | - * @param id | ||
| 120 | * @returns | 39 | * @returns |
| 121 | */ | 40 | */ |
| 122 | -export const orderCancelAPI = (params) => fn(fetch.post(Api.ORDER_CANCEL, params)); | 41 | +export const updateProfileAPI = (params) => fn(fetch.post(Api.UPDATE_PROFILE, params)); |
| 123 | 42 | ||
| 124 | /** | 43 | /** |
| 125 | - * @description: 订单成功 | 44 | + * @description: 发送验证码 |
| 126 | - * @param id | 45 | + * @param mobile 手机号 |
| 127 | * @returns | 46 | * @returns |
| 128 | */ | 47 | */ |
| 129 | -export const orderSuccessAPI = (params) => fn(fetch.post(Api.ORDER_SUCCESS, params)); | 48 | +export const sendSmsCodeAPI = (params) => fn(fetch.get(Api.SEND_SMS_CODE, params)); |
| 130 | 49 | ||
| 131 | /** | 50 | /** |
| 132 | - * @description: | 51 | + * @description: 获取用户资料 |
| 133 | - * @param id | 52 | + * @returns data[{ id,nickname,avatar_url,gender,phone,wechat_id,school_id,real_name_verified,favorite_count,order_count,follower_count }] |
| 134 | - * @returns | ||
| 135 | */ | 53 | */ |
| 136 | -export const tmpSysParamAPI = (params) => fn(fetch.get(Api.TMP_SYS_PARAM, params)); | 54 | +export const getProfileAPI = (params) => fn(fetch.get(Api.GET_PROFILE, params)); | ... | ... |
| 1 | /* | 1 | /* |
| 2 | * @Date: 2025-06-28 10:33:00 | 2 | * @Date: 2025-06-28 10:33:00 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-06-28 11:04:17 | 4 | + * @LastEditTime: 2025-07-08 17:49:20 |
| 5 | - * @FilePath: /myApp/src/app.js | 5 | + * @FilePath: /jgdl/src/app.js |
| 6 | * @Description: 文件描述 | 6 | * @Description: 文件描述 |
| 7 | */ | 7 | */ |
| 8 | import { createApp } from 'vue' | 8 | import { createApp } from 'vue' |
| ... | @@ -23,15 +23,15 @@ const App = createApp({ | ... | @@ -23,15 +23,15 @@ const App = createApp({ |
| 23 | // if (path !== 'pages/index/index' && !wx.getStorageSync("sessionid")) { | 23 | // if (path !== 'pages/index/index' && !wx.getStorageSync("sessionid")) { |
| 24 | if (!wx.getStorageSync("sessionid")) { | 24 | if (!wx.getStorageSync("sessionid")) { |
| 25 | console.warn("没有权限"); | 25 | console.warn("没有权限"); |
| 26 | - // if (path === 'pages/detail/index') { | 26 | + if (path === 'pages/detail/index') { |
| 27 | - // Taro.navigateTo({ | 27 | + Taro.navigateTo({ |
| 28 | - // url: `./pages/auth/index?url=${path}&id=${query.id}&start_date=${query.start_date}&end_date=${query.end_date}`, | 28 | + url: `./pages/auth/index?url=${path}&id=${query.id}`, |
| 29 | - // }) | 29 | + }) |
| 30 | - // } else { | 30 | + } else { |
| 31 | - // Taro.navigateTo({ | 31 | + Taro.navigateTo({ |
| 32 | - // url: './pages/auth/index?url=' + path, | 32 | + url: './pages/auth/index?url=' + path, |
| 33 | - // }) | 33 | + }) |
| 34 | - // } | 34 | + } |
| 35 | } | 35 | } |
| 36 | }, | 36 | }, |
| 37 | onShow(options) { | 37 | onShow(options) { | ... | ... |
| ... | @@ -56,6 +56,7 @@ | ... | @@ -56,6 +56,7 @@ |
| 56 | import { ref, onMounted } from 'vue' | 56 | import { ref, onMounted } from 'vue' |
| 57 | import Taro from '@tarojs/taro' | 57 | import Taro from '@tarojs/taro' |
| 58 | import { Home, Category, Comment, My } from '@nutui/icons-vue-taro' | 58 | import { Home, Category, Comment, My } from '@nutui/icons-vue-taro' |
| 59 | +import { getProfileAPI } from '@/api/index'; | ||
| 59 | 60 | ||
| 60 | // 当前激活的tab | 61 | // 当前激活的tab |
| 61 | const activeTab = ref('') | 62 | const activeTab = ref('') |
| ... | @@ -88,24 +89,23 @@ const getCurrentPage = () => { | ... | @@ -88,24 +89,23 @@ const getCurrentPage = () => { |
| 88 | * @param {string} url - 页面路径 | 89 | * @param {string} url - 页面路径 |
| 89 | */ | 90 | */ |
| 90 | const navigateTo = (url) => { | 91 | const navigateTo = (url) => { |
| 91 | - // TODO: 等待正式接口 | 92 | + if ((url === '/pages/profile/index' || url === '/pages/sell/index') && !is_auth.value) { |
| 92 | - // if ((url === '/pages/profile/index' || url === '/pages/sell/index') && !is_auth.value) { | 93 | + Taro.showToast({ |
| 93 | - // Taro.showToast({ | 94 | + title: '请先完善个人信息', |
| 94 | - // title: '请先完善个人信息', | 95 | + icon: 'none', |
| 95 | - // icon: 'none', | 96 | + duration: 2000, |
| 96 | - // duration: 2000, | 97 | + success: () => { |
| 97 | - // success: (res) => { | 98 | + setTimeout(() => { |
| 98 | - // setTimeout(() => { | 99 | + Taro.navigateTo({ |
| 99 | - // Taro.navigateTo({ | 100 | + url: '/pages/register/index' |
| 100 | - // url: '/pages/register/index' | 101 | + }) |
| 101 | - // }) | 102 | + }, 2000); |
| 102 | - // }, 2000); | 103 | + } |
| 103 | - // } | 104 | + }) |
| 104 | - // }) | 105 | + return |
| 105 | - // return | 106 | + } |
| 106 | - // } | 107 | + Taro.reLaunch({ |
| 107 | - Taro.redirectTo({ | 108 | + url |
| 108 | - url: url | ||
| 109 | }) | 109 | }) |
| 110 | } | 110 | } |
| 111 | 111 | ||
| ... | @@ -132,7 +132,7 @@ const getIconColor = (tab) => { | ... | @@ -132,7 +132,7 @@ const getIconColor = (tab) => { |
| 132 | const userInfo = ref({ | 132 | const userInfo = ref({ |
| 133 | avatar: '', | 133 | avatar: '', |
| 134 | nickname: '', | 134 | nickname: '', |
| 135 | - phone: '1', | 135 | + phone: '', |
| 136 | gender: '', | 136 | gender: '', |
| 137 | school: '', | 137 | school: '', |
| 138 | birthday: '', | 138 | birthday: '', |
| ... | @@ -140,13 +140,16 @@ const userInfo = ref({ | ... | @@ -140,13 +140,16 @@ const userInfo = ref({ |
| 140 | 140 | ||
| 141 | const is_auth = ref(false); | 141 | const is_auth = ref(false); |
| 142 | 142 | ||
| 143 | -onMounted(() => { | 143 | +onMounted(async () => { |
| 144 | getCurrentPage() | 144 | getCurrentPage() |
| 145 | // 获取当前用户的信息 | 145 | // 获取当前用户的信息 |
| 146 | - // if (userInfo.value && userInfo.value.phone) { | 146 | + const user = await getProfileAPI(); |
| 147 | - // is_auth.value = true | 147 | + if (user.code) { |
| 148 | - // } | 148 | + userInfo.value = user.data |
| 149 | - is_auth.value = false | 149 | + if (userInfo.value && userInfo.value.phone) { |
| 150 | + is_auth.value = true | ||
| 151 | + } | ||
| 152 | + } | ||
| 150 | }) | 153 | }) |
| 151 | </script> | 154 | </script> |
| 152 | 155 | ... | ... |
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2023-12-20 14:11:11 | 2 | * @Date: 2023-12-20 14:11:11 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-07-03 11:43:29 | 4 | + * @LastEditTime: 2025-07-08 20:22:50 |
| 5 | * @FilePath: /jgdl/src/components/payCard.vue | 5 | * @FilePath: /jgdl/src/components/payCard.vue |
| 6 | * @Description: 文件描述 | 6 | * @Description: 文件描述 |
| 7 | --> | 7 | --> |
| ... | @@ -22,7 +22,7 @@ | ... | @@ -22,7 +22,7 @@ |
| 22 | import Taro from '@tarojs/taro' | 22 | import Taro from '@tarojs/taro' |
| 23 | import { ref, watch, onMounted, onUnmounted } from 'vue' | 23 | import { ref, watch, onMounted, onUnmounted } from 'vue' |
| 24 | import { getCurrentPageUrl } from "@/utils/weapp"; | 24 | import { getCurrentPageUrl } from "@/utils/weapp"; |
| 25 | -import { payAPI, payCheckAPI, orderSuccessAPI } from '@/api/index' | 25 | +import { payAPI, payCheckAPI } from '@/api/index' |
| 26 | 26 | ||
| 27 | /** | 27 | /** |
| 28 | * 格式化时间 | 28 | * 格式化时间 | ... | ... |
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2022-09-19 14:11:06 | 2 | * @Date: 2022-09-19 14:11:06 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2024-05-26 10:17:04 | 4 | + * @LastEditTime: 2025-07-08 17:46:08 |
| 5 | - * @FilePath: /meihuaApp/src/pages/auth/index.vue | 5 | + * @FilePath: /jgdl/src/pages/auth/index.vue |
| 6 | * @Description: 文件描述 | 6 | * @Description: 文件描述 |
| 7 | --> | 7 | --> |
| 8 | <template> | 8 | <template> |
| ... | @@ -35,8 +35,8 @@ export default { | ... | @@ -35,8 +35,8 @@ export default { |
| 35 | title: '授权中', | 35 | title: '授权中', |
| 36 | }) | 36 | }) |
| 37 | request.post('/srv/?a=openid', { | 37 | request.post('/srv/?a=openid', { |
| 38 | - code: res.code | 38 | + code: res.code, |
| 39 | - // openid: '0002' | 39 | + openid: 'h-001' |
| 40 | // openid: 'o5NFZ5cFQtLRy3aVHaZMLkjHFusI' | 40 | // openid: 'o5NFZ5cFQtLRy3aVHaZMLkjHFusI' |
| 41 | // openid: 'o5NFZ5TpgG4FwYursGCLjcUJH2ak' | 41 | // openid: 'o5NFZ5TpgG4FwYursGCLjcUJH2ak' |
| 42 | // openid: 'o5NFZ5cqroPYwawCp8FEOxewtgnw' | 42 | // openid: 'o5NFZ5cqroPYwawCp8FEOxewtgnw' |
| ... | @@ -62,7 +62,7 @@ export default { | ... | @@ -62,7 +62,7 @@ export default { |
| 62 | const params = getCurrentPageParam(); | 62 | const params = getCurrentPageParam(); |
| 63 | if (getCurrentPageParam().url === 'pages/detail/index') { // 详情页的分享跳转处理 | 63 | if (getCurrentPageParam().url === 'pages/detail/index') { // 详情页的分享跳转处理 |
| 64 | Taro.reLaunch({ | 64 | Taro.reLaunch({ |
| 65 | - url: `../../${params.url}?id=${params.id}&start_date=${params.start_date}&end_date=${params.end_date}` | 65 | + url: `../../${params.url}?id=${params.id}` |
| 66 | }) | 66 | }) |
| 67 | } else { // 其他页面分享跳首页 | 67 | } else { // 其他页面分享跳首页 |
| 68 | Taro.reLaunch({ | 68 | Taro.reLaunch({ |
| ... | @@ -81,7 +81,7 @@ export default { | ... | @@ -81,7 +81,7 @@ export default { |
| 81 | Taro.hideLoading(); | 81 | Taro.hideLoading(); |
| 82 | }); | 82 | }); |
| 83 | } else { | 83 | } else { |
| 84 | - console.log('登录失败!' + res.errMsg) | 84 | + console.error('登录失败!' + res.errMsg) |
| 85 | } | 85 | } |
| 86 | } | 86 | } |
| 87 | }) | 87 | }) | ... | ... |
| ... | @@ -77,7 +77,7 @@ | ... | @@ -77,7 +77,7 @@ |
| 77 | 77 | ||
| 78 | .nut-input { | 78 | .nut-input { |
| 79 | text-align: right; | 79 | text-align: right; |
| 80 | - | 80 | + |
| 81 | .nut-input__inner { | 81 | .nut-input__inner { |
| 82 | color: #666; | 82 | color: #666; |
| 83 | font-size: 32rpx; | 83 | font-size: 32rpx; |
| ... | @@ -94,7 +94,7 @@ | ... | @@ -94,7 +94,7 @@ |
| 94 | 94 | ||
| 95 | .phone-value { | 95 | .phone-value { |
| 96 | color: #666; | 96 | color: #666; |
| 97 | - font-size: 32rpx; | 97 | + // font-size: 32rpx; |
| 98 | margin-right: 16rpx; | 98 | margin-right: 16rpx; |
| 99 | } | 99 | } |
| 100 | 100 | ||
| ... | @@ -134,7 +134,7 @@ | ... | @@ -134,7 +134,7 @@ |
| 134 | 134 | ||
| 135 | .school-value { | 135 | .school-value { |
| 136 | color: #666; | 136 | color: #666; |
| 137 | - font-size: 32rpx; | 137 | + // font-size: 32rpx; |
| 138 | margin-right: 16rpx; | 138 | margin-right: 16rpx; |
| 139 | } | 139 | } |
| 140 | 140 | ||
| ... | @@ -161,7 +161,7 @@ | ... | @@ -161,7 +161,7 @@ |
| 161 | .nut-radio__icon { | 161 | .nut-radio__icon { |
| 162 | color: #f97316; | 162 | color: #f97316; |
| 163 | } | 163 | } |
| 164 | - | 164 | + |
| 165 | .nut-radio__label { | 165 | .nut-radio__label { |
| 166 | color: #333; | 166 | color: #333; |
| 167 | } | 167 | } | ... | ... |
| ... | @@ -4,10 +4,10 @@ | ... | @@ -4,10 +4,10 @@ |
| 4 | <view class="avatar-section"> | 4 | <view class="avatar-section"> |
| 5 | <view class="avatar-container"> | 5 | <view class="avatar-container"> |
| 6 | <image | 6 | <image |
| 7 | - :src="formData.avatar || defaultAvatar" | 7 | + :src="formData.avatar_url || defaultAvatar" |
| 8 | class="avatar-image" | 8 | class="avatar-image" |
| 9 | mode="aspectFill" | 9 | mode="aspectFill" |
| 10 | - @tap="previewAvatar(formData.avatar || defaultAvatar)" | 10 | + @tap="previewAvatar(formData.avatar_url || defaultAvatar)" |
| 11 | /> | 11 | /> |
| 12 | </view> | 12 | </view> |
| 13 | <view class="change-avatar-btn" @click="changeAvatar"> | 13 | <view class="change-avatar-btn" @click="changeAvatar"> |
| ... | @@ -39,19 +39,19 @@ | ... | @@ -39,19 +39,19 @@ |
| 39 | <nut-config-provider :theme-vars="themeVars"> | 39 | <nut-config-provider :theme-vars="themeVars"> |
| 40 | <nut-form-item label="性别" prop="gender" body-align="right"> | 40 | <nut-form-item label="性别" prop="gender" body-align="right"> |
| 41 | <nut-radio-group v-model="formData.gender" direction="horizontal"> | 41 | <nut-radio-group v-model="formData.gender" direction="horizontal"> |
| 42 | - <nut-radio label="男">男</nut-radio> | 42 | + <nut-radio :label="0">男</nut-radio> |
| 43 | - <nut-radio label="女">女</nut-radio> | 43 | + <nut-radio :label="1">女</nut-radio> |
| 44 | </nut-radio-group> | 44 | </nut-radio-group> |
| 45 | </nut-form-item> | 45 | </nut-form-item> |
| 46 | </nut-config-provider> | 46 | </nut-config-provider> |
| 47 | 47 | ||
| 48 | <!-- 生日 --> | 48 | <!-- 生日 --> |
| 49 | - <nut-form-item label="生日" prop="birthday"> | 49 | + <!-- <nut-form-item label="生日" prop="birthday"> |
| 50 | <view class="birthday-item" @click="showDatePicker"> | 50 | <view class="birthday-item" @click="showDatePicker"> |
| 51 | <text class="birthday-value">{{ formData.birthday || '未设置' }}</text> | 51 | <text class="birthday-value">{{ formData.birthday || '未设置' }}</text> |
| 52 | <Right class="arrow-icon" /> | 52 | <Right class="arrow-icon" /> |
| 53 | </view> | 53 | </view> |
| 54 | - </nut-form-item> | 54 | + </nut-form-item> --> |
| 55 | 55 | ||
| 56 | <!-- 所在学校 --> | 56 | <!-- 所在学校 --> |
| 57 | <nut-form-item label="所在学校" prop="school"> | 57 | <nut-form-item label="所在学校" prop="school"> |
| ... | @@ -64,7 +64,7 @@ | ... | @@ -64,7 +64,7 @@ |
| 64 | <!-- 微信号 --> | 64 | <!-- 微信号 --> |
| 65 | <nut-form-item label="微信号" prop="wechat"> | 65 | <nut-form-item label="微信号" prop="wechat"> |
| 66 | <nut-input | 66 | <nut-input |
| 67 | - v-model="formData.wechat" | 67 | + v-model="formData.wechat_id" |
| 68 | placeholder="请输入微信号" | 68 | placeholder="请输入微信号" |
| 69 | input-align="right" | 69 | input-align="right" |
| 70 | > | 70 | > |
| ... | @@ -100,7 +100,7 @@ | ... | @@ -100,7 +100,7 @@ |
| 100 | /> | 100 | /> |
| 101 | <view class="code-row"> | 101 | <view class="code-row"> |
| 102 | <nut-input | 102 | <nut-input |
| 103 | - v-model="verifyCode" | 103 | + v-model="sms_code" |
| 104 | placeholder="验证码" | 104 | placeholder="验证码" |
| 105 | class="code-input" | 105 | class="code-input" |
| 106 | maxlength="6" | 106 | maxlength="6" |
| ... | @@ -138,14 +138,14 @@ | ... | @@ -138,14 +138,14 @@ |
| 138 | </nut-popup> | 138 | </nut-popup> |
| 139 | 139 | ||
| 140 | <!-- 日期选择器 --> | 140 | <!-- 日期选择器 --> |
| 141 | - <nut-popup v-model:visible="datePickerVisible" position="bottom"> | 141 | + <!-- <nut-popup v-model:visible="datePickerVisible" position="bottom"> |
| 142 | <nut-date-picker | 142 | <nut-date-picker |
| 143 | v-model="dateValue" | 143 | v-model="dateValue" |
| 144 | title="选择生日" | 144 | title="选择生日" |
| 145 | @confirm="onDateConfirm" | 145 | @confirm="onDateConfirm" |
| 146 | @cancel="datePickerVisible = false" | 146 | @cancel="datePickerVisible = false" |
| 147 | /> | 147 | /> |
| 148 | - </nut-popup> | 148 | + </nut-popup> --> |
| 149 | 149 | ||
| 150 | <!-- 学校选择器 --> | 150 | <!-- 学校选择器 --> |
| 151 | <nut-popup v-model:visible="schoolPickerVisible" position="bottom"> | 151 | <nut-popup v-model:visible="schoolPickerVisible" position="bottom"> |
| ... | @@ -162,20 +162,21 @@ | ... | @@ -162,20 +162,21 @@ |
| 162 | <nut-image-preview v-model:show="previewVisible" :images="previewImages" :init-no="previewIndex" @close="closePreview" /> | 162 | <nut-image-preview v-model:show="previewVisible" :images="previewImages" :init-no="previewIndex" @close="closePreview" /> |
| 163 | 163 | ||
| 164 | <!-- 成功提示 --> | 164 | <!-- 成功提示 --> |
| 165 | - <nut-toast | 165 | + <!-- <nut-toast |
| 166 | v-model:visible="toastVisible" | 166 | v-model:visible="toastVisible" |
| 167 | msg="保存成功" | 167 | msg="保存成功" |
| 168 | type="success" | 168 | type="success" |
| 169 | - /> | 169 | + /> --> |
| 170 | </view> | 170 | </view> |
| 171 | </template> | 171 | </template> |
| 172 | 172 | ||
| 173 | <script setup> | 173 | <script setup> |
| 174 | import { ref, reactive, onMounted } from 'vue' | 174 | import { ref, reactive, onMounted } from 'vue' |
| 175 | -import Taro from '@tarojs/taro' | 175 | +import Taro, { useDidShow } from '@tarojs/taro' |
| 176 | import './index.less' | 176 | import './index.less' |
| 177 | import { Right } from '@nutui/icons-vue-taro' | 177 | import { Right } from '@nutui/icons-vue-taro' |
| 178 | import BASE_URL from '@/utils/config'; | 178 | import BASE_URL from '@/utils/config'; |
| 179 | +import { updateProfileAPI, sendSmsCodeAPI, getProfileAPI } from '@/api/index'; | ||
| 179 | 180 | ||
| 180 | // 主题配置 | 181 | // 主题配置 |
| 181 | const themeVars = { | 182 | const themeVars = { |
| ... | @@ -187,20 +188,22 @@ const defaultAvatar = 'https://cdn.ipadbiz.cn/mlaj/images/icon_1.jpeg' | ... | @@ -187,20 +188,22 @@ const defaultAvatar = 'https://cdn.ipadbiz.cn/mlaj/images/icon_1.jpeg' |
| 187 | 188 | ||
| 188 | // 表单数据 | 189 | // 表单数据 |
| 189 | const formData = reactive({ | 190 | const formData = reactive({ |
| 190 | - avatar: '', | 191 | + avatar_url: '', |
| 191 | - nickname: '张先生', | 192 | + nickname: '', |
| 192 | - phone: '139 2233 8888', | 193 | + phone: '', |
| 193 | - gender: '男', | 194 | + sms_code: '', |
| 194 | - birthday: '', | 195 | + gender: '', |
| 195 | - school: '上海理工大学', | 196 | + // birthday: '', |
| 196 | - wechat: '' | 197 | + school: '', |
| 198 | + school_id: '', | ||
| 199 | + wechat_id: '' | ||
| 197 | }) | 200 | }) |
| 198 | 201 | ||
| 199 | // 弹框控制 | 202 | // 弹框控制 |
| 200 | const phoneDialogVisible = ref(false) | 203 | const phoneDialogVisible = ref(false) |
| 201 | -const datePickerVisible = ref(false) | 204 | +// const datePickerVisible = ref(false) |
| 202 | const schoolPickerVisible = ref(false) | 205 | const schoolPickerVisible = ref(false) |
| 203 | -const toastVisible = ref(false) | 206 | +// const toastVisible = ref(false) |
| 204 | 207 | ||
| 205 | // 图片预览相关 | 208 | // 图片预览相关 |
| 206 | const previewVisible = ref(false) | 209 | const previewVisible = ref(false) |
| ... | @@ -213,11 +216,11 @@ const closePreview = () => { | ... | @@ -213,11 +216,11 @@ const closePreview = () => { |
| 213 | 216 | ||
| 214 | // 手机号相关 | 217 | // 手机号相关 |
| 215 | const newPhone = ref('') | 218 | const newPhone = ref('') |
| 216 | -const verifyCode = ref('') | 219 | +const sms_code = ref('') |
| 217 | const codeCountdown = ref(0) | 220 | const codeCountdown = ref(0) |
| 218 | 221 | ||
| 219 | // 日期选择 | 222 | // 日期选择 |
| 220 | -const dateValue = ref(new Date()) | 223 | +// const dateValue = ref(new Date()) |
| 221 | 224 | ||
| 222 | // 学校选择 | 225 | // 学校选择 |
| 223 | const schoolValue = ref([]) | 226 | const schoolValue = ref([]) |
| ... | @@ -282,7 +285,7 @@ const uploadImage = (filePath) => { | ... | @@ -282,7 +285,7 @@ const uploadImage = (filePath) => { |
| 282 | Taro.hideLoading({ | 285 | Taro.hideLoading({ |
| 283 | success: () => { | 286 | success: () => { |
| 284 | if (res.statusCode === 200) { | 287 | if (res.statusCode === 200) { |
| 285 | - formData.avatar = upload_data.data.src; | 288 | + formData.avatar_url = upload_data.data.src; |
| 286 | Taro.showToast({ | 289 | Taro.showToast({ |
| 287 | title: '上传成功', | 290 | title: '上传成功', |
| 288 | icon: 'success' | 291 | icon: 'success' |
| ... | @@ -332,7 +335,7 @@ const previewAvatar = (imageUrl) => { | ... | @@ -332,7 +335,7 @@ const previewAvatar = (imageUrl) => { |
| 332 | const showPhoneDialog = () => { | 335 | const showPhoneDialog = () => { |
| 333 | phoneDialogVisible.value = true | 336 | phoneDialogVisible.value = true |
| 334 | newPhone.value = '' | 337 | newPhone.value = '' |
| 335 | - verifyCode.value = '' | 338 | + sms_code.value = '' |
| 336 | } | 339 | } |
| 337 | 340 | ||
| 338 | /** | 341 | /** |
| ... | @@ -350,7 +353,7 @@ const onPhoneInput = ({ detail }) => { | ... | @@ -350,7 +353,7 @@ const onPhoneInput = ({ detail }) => { |
| 350 | */ | 353 | */ |
| 351 | const onCodeInput = ({ detail }) => { | 354 | const onCodeInput = ({ detail }) => { |
| 352 | // 只保留数字 | 355 | // 只保留数字 |
| 353 | - verifyCode.value = detail.value.replace(/\D/g, '') | 356 | + sms_code.value = detail.value.replace(/\D/g, '') |
| 354 | } | 357 | } |
| 355 | 358 | ||
| 356 | /** | 359 | /** |
| ... | @@ -364,7 +367,7 @@ const validatePhone = (phone) => { | ... | @@ -364,7 +367,7 @@ const validatePhone = (phone) => { |
| 364 | } | 367 | } |
| 365 | 368 | ||
| 366 | // 发送验证码 | 369 | // 发送验证码 |
| 367 | -const sendCode = () => { | 370 | +const sendCode = async () => { |
| 368 | if (!newPhone.value) { | 371 | if (!newPhone.value) { |
| 369 | Taro.showToast({ | 372 | Taro.showToast({ |
| 370 | title: '请输入手机号', | 373 | title: '请输入手机号', |
| ... | @@ -381,23 +384,39 @@ const sendCode = () => { | ... | @@ -381,23 +384,39 @@ const sendCode = () => { |
| 381 | return | 384 | return |
| 382 | } | 385 | } |
| 383 | 386 | ||
| 384 | - codeCountdown.value = 60 | 387 | + // 如果正在倒计时,不允许重复发送 |
| 385 | - const timer = setInterval(() => { | 388 | + if (codeCountdown.value > 0) { |
| 386 | - codeCountdown.value-- | 389 | + return |
| 387 | - if (codeCountdown.value <= 0) { | 390 | + } |
| 388 | - clearInterval(timer) | 391 | + |
| 389 | - } | 392 | + try { |
| 390 | - }, 1000) | 393 | + // 发送验证码API请求 |
| 391 | - | 394 | + await sendSmsCodeAPI({ mobile: newPhone.value }) |
| 392 | - Taro.showToast({ | 395 | + Taro.showToast({ |
| 393 | - title: '验证码已发送', | 396 | + title: '验证码已发送', |
| 394 | - icon: 'success' | 397 | + icon: 'success' |
| 395 | - }) | 398 | + }) |
| 399 | + | ||
| 400 | + // 开始倒计时 | ||
| 401 | + codeCountdown.value = 60 | ||
| 402 | + const timer = setInterval(() => { | ||
| 403 | + codeCountdown.value-- | ||
| 404 | + if (codeCountdown.value <= 0) { | ||
| 405 | + clearInterval(timer) | ||
| 406 | + } | ||
| 407 | + }, 1000) | ||
| 408 | + | ||
| 409 | + } catch (error) { | ||
| 410 | + Taro.showToast({ | ||
| 411 | + title: error.message || '发送验证码失败,请重试', | ||
| 412 | + icon: 'error' | ||
| 413 | + }) | ||
| 414 | + } | ||
| 396 | } | 415 | } |
| 397 | 416 | ||
| 398 | // 确认手机号更改 | 417 | // 确认手机号更改 |
| 399 | -const confirmPhoneChange = () => { | 418 | +const confirmPhoneChange = async () => { |
| 400 | - if (!newPhone.value || !verifyCode.value) { | 419 | + if (!newPhone.value || !sms_code.value) { |
| 401 | Taro.showToast({ | 420 | Taro.showToast({ |
| 402 | title: '请填写完整信息', | 421 | title: '请填写完整信息', |
| 403 | icon: 'none' | 422 | icon: 'none' |
| ... | @@ -413,7 +432,7 @@ const confirmPhoneChange = () => { | ... | @@ -413,7 +432,7 @@ const confirmPhoneChange = () => { |
| 413 | return | 432 | return |
| 414 | } | 433 | } |
| 415 | 434 | ||
| 416 | - if (verifyCode.value.length !== 6) { | 435 | + if (sms_code.value.length !== 6) { |
| 417 | Taro.showToast({ | 436 | Taro.showToast({ |
| 418 | title: '请输入6位验证码', | 437 | title: '请输入6位验证码', |
| 419 | icon: 'none' | 438 | icon: 'none' |
| ... | @@ -421,26 +440,37 @@ const confirmPhoneChange = () => { | ... | @@ -421,26 +440,37 @@ const confirmPhoneChange = () => { |
| 421 | return | 440 | return |
| 422 | } | 441 | } |
| 423 | 442 | ||
| 424 | - formData.phone = newPhone.value | 443 | + try { |
| 425 | - phoneDialogVisible.value = false | 444 | + // 验证验证码API请求 |
| 426 | - newPhone.value = '' | 445 | + await updateProfileAPI({ mobile: newPhone.value, sms_code: sms_code.value }) |
| 427 | - verifyCode.value = '' | 446 | + Taro.showToast({ |
| 428 | - Taro.showToast({ | 447 | + title: '手机号绑定成功', |
| 429 | - title: '手机号绑定成功', | 448 | + icon: 'success' |
| 430 | - icon: 'success' | 449 | + }) |
| 431 | - }) | 450 | + |
| 451 | + // 绑定手机号 | ||
| 452 | + formData.phone = newPhone.value | ||
| 453 | + phoneDialogVisible.value = false | ||
| 454 | + newPhone.value = '' | ||
| 455 | + sms_code.value = '' | ||
| 456 | + } catch (error) { | ||
| 457 | + Taro.showToast({ | ||
| 458 | + title: error.message || '手机号绑定失败,请重试', | ||
| 459 | + icon: 'error' | ||
| 460 | + }) | ||
| 461 | + } | ||
| 432 | } | 462 | } |
| 433 | 463 | ||
| 434 | // 显示日期选择器 | 464 | // 显示日期选择器 |
| 435 | -const showDatePicker = () => { | 465 | +// const showDatePicker = () => { |
| 436 | - datePickerVisible.value = true | 466 | +// datePickerVisible.value = true |
| 437 | -} | 467 | +// } |
| 438 | 468 | ||
| 439 | // 确认日期选择 | 469 | // 确认日期选择 |
| 440 | -const onDateConfirm = ({ selectedValue }) => { | 470 | +// const onDateConfirm = ({ selectedValue }) => { |
| 441 | - formData.birthday = `${selectedValue[0]}-${String(selectedValue[1]).padStart(2, '0')}-${String(selectedValue[2]).padStart(2, '0')}` | 471 | +// formData.birthday = `${selectedValue[0]}-${String(selectedValue[1]).padStart(2, '0')}-${String(selectedValue[2]).padStart(2, '0')}` |
| 442 | - datePickerVisible.value = false | 472 | +// datePickerVisible.value = false |
| 443 | -} | 473 | +// } |
| 444 | 474 | ||
| 445 | // 显示学校选择器 | 475 | // 显示学校选择器 |
| 446 | const showSchoolPicker = () => { | 476 | const showSchoolPicker = () => { |
| ... | @@ -454,18 +484,44 @@ const onSchoolConfirm = ({ selectedOptions }) => { | ... | @@ -454,18 +484,44 @@ const onSchoolConfirm = ({ selectedOptions }) => { |
| 454 | } | 484 | } |
| 455 | 485 | ||
| 456 | // 保存 | 486 | // 保存 |
| 457 | -const handleSave = () => { | 487 | +const handleSave = async () => { |
| 458 | // 这里可以添加表单验证 | 488 | // 这里可以添加表单验证 |
| 459 | - toastVisible.value = true | 489 | + // toastVisible.value = true |
| 460 | 490 | ||
| 461 | - setTimeout(() => { | 491 | + try { |
| 462 | - toastVisible.value = false | 492 | + // 保存用户信息API请求 |
| 463 | - goBack() | 493 | + await updateProfileAPI(formData) |
| 464 | - }, 1500) | 494 | + Taro.showToast({ |
| 495 | + title: '保存成功', | ||
| 496 | + icon: 'success', | ||
| 497 | + complete: () => { | ||
| 498 | + goBack() | ||
| 499 | + } | ||
| 500 | + }) | ||
| 501 | + // setTimeout(() => { | ||
| 502 | + // toastVisible.value = false | ||
| 503 | + // }, 1500) | ||
| 504 | + // goBack() | ||
| 505 | + } catch (error) { | ||
| 506 | + Taro.showToast({ | ||
| 507 | + title: error.message || '保存失败,请重试', | ||
| 508 | + icon: 'error' | ||
| 509 | + }) | ||
| 510 | + } | ||
| 465 | } | 511 | } |
| 466 | 512 | ||
| 467 | // 初始化 | 513 | // 初始化 |
| 468 | -onMounted(() => { | 514 | +useDidShow(async () => { |
| 469 | - | 515 | + // 获取用户信息 |
| 516 | + const user = await getProfileAPI() | ||
| 517 | + if (user.code) { | ||
| 518 | + formData.avatar_url = user.data.avatar_url | ||
| 519 | + formData.nickname = user.data.nickname | ||
| 520 | + formData.phone = user.data.phone | ||
| 521 | + formData.gender = user.data.gender | ||
| 522 | + formData.school = user.data.school | ||
| 523 | + formData.school_id = user.data.school_id | ||
| 524 | + formData.wechat_id = user.data.wechat_id | ||
| 525 | + } | ||
| 470 | }) | 526 | }) |
| 471 | </script> | 527 | </script> | ... | ... |
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2022-09-19 14:11:06 | 2 | * @Date: 2022-09-19 14:11:06 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-07-08 14:15:15 | 4 | + * @LastEditTime: 2025-07-08 15:51:46 |
| 5 | * @FilePath: /jgdl/src/pages/productDetail/index.vue | 5 | * @FilePath: /jgdl/src/pages/productDetail/index.vue |
| 6 | * @Description: 商品详情页 | 6 | * @Description: 商品详情页 |
| 7 | --> | 7 | --> | ... | ... |
| ... | @@ -2,8 +2,8 @@ | ... | @@ -2,8 +2,8 @@ |
| 2 | <view class="profile-page"> | 2 | <view class="profile-page"> |
| 3 | <!-- User Profile Section --> | 3 | <!-- User Profile Section --> |
| 4 | <view class="user-profile-section"> | 4 | <view class="user-profile-section"> |
| 5 | - <image :src="userInfo.avatar || defaultAvatar" class="user-avatar" mode="aspectFill" /> | 5 | + <image :src="userInfo.avatar_url || defaultAvatar" class="user-avatar" mode="aspectFill" /> |
| 6 | - <text class="user-name">{{ userInfo.name }}</text> | 6 | + <text class="user-name">{{ userInfo.nickname }}</text> |
| 7 | <text class="user-phone">{{ userInfo.phone }}</text> | 7 | <text class="user-phone">{{ userInfo.phone }}</text> |
| 8 | <nut-button class="edit-profile-btn" @click="onEditProfile"> | 8 | <nut-button class="edit-profile-btn" @click="onEditProfile"> |
| 9 | 编辑资料 | 9 | 编辑资料 |
| ... | @@ -12,15 +12,15 @@ | ... | @@ -12,15 +12,15 @@ |
| 12 | <!-- Stats Row --> | 12 | <!-- Stats Row --> |
| 13 | <view class="stats-row"> | 13 | <view class="stats-row"> |
| 14 | <view class="stat-item"> | 14 | <view class="stat-item"> |
| 15 | - <text class="stat-number">{{ userStats.following }}</text> | 15 | + <text class="stat-number">{{ userInfo.follower_count }}</text> |
| 16 | <text class="stat-label">关注</text> | 16 | <text class="stat-label">关注</text> |
| 17 | </view> | 17 | </view> |
| 18 | <view class="stat-item" @click="onOrderManagement"> | 18 | <view class="stat-item" @click="onOrderManagement"> |
| 19 | - <text class="stat-number">{{ userStats.orders }}</text> | 19 | + <text class="stat-number">{{ userInfo.order_count }}</text> |
| 20 | <text class="stat-label">订单</text> | 20 | <text class="stat-label">订单</text> |
| 21 | </view> | 21 | </view> |
| 22 | <view class="stat-item"> | 22 | <view class="stat-item"> |
| 23 | - <text class="stat-number">{{ userStats.followers }}</text> | 23 | + <text class="stat-number">{{ userInfo.favorite_count }}</text> |
| 24 | <text class="stat-label">被关注</text> | 24 | <text class="stat-label">被关注</text> |
| 25 | </view> | 25 | </view> |
| 26 | </view> | 26 | </view> |
| ... | @@ -78,10 +78,9 @@ | ... | @@ -78,10 +78,9 @@ |
| 78 | </template> | 78 | </template> |
| 79 | 79 | ||
| 80 | <script setup> | 80 | <script setup> |
| 81 | -import { ref } from 'vue' | 81 | +import { ref, onMounted } from 'vue' |
| 82 | -import { | 82 | +import { getProfileAPI } from '@/api/index' |
| 83 | - Heart, Clock, Notice, Cart, Message, Tips, Setting, Right, StarN | 83 | +import { Heart, Clock, Notice, Cart, Message, Tips, Right, StarN } from '@nutui/icons-vue-taro' |
| 84 | -} from '@nutui/icons-vue-taro' | ||
| 85 | import Taro from '@tarojs/taro' | 84 | import Taro from '@tarojs/taro' |
| 86 | import TabBar from '@/components/TabBar.vue' | 85 | import TabBar from '@/components/TabBar.vue' |
| 87 | 86 | ||
| ... | @@ -90,16 +89,19 @@ const defaultAvatar = 'https://cdn.ipadbiz.cn/mlaj/images/icon_1.jpeg' | ... | @@ -90,16 +89,19 @@ const defaultAvatar = 'https://cdn.ipadbiz.cn/mlaj/images/icon_1.jpeg' |
| 90 | 89 | ||
| 91 | // 用户信息 | 90 | // 用户信息 |
| 92 | const userInfo = ref({ | 91 | const userInfo = ref({ |
| 93 | - name: '张同学', | 92 | + nickname: '张同学', |
| 94 | phone: '138****8888', | 93 | phone: '138****8888', |
| 95 | - avatar: '' | 94 | + avatar_url: '', |
| 95 | + follower_count: 0, | ||
| 96 | + order_count: 0, | ||
| 97 | + favorite_count: 0 | ||
| 96 | }) | 98 | }) |
| 97 | 99 | ||
| 98 | -// 用户统计 | 100 | +onMounted(async () => { |
| 99 | -const userStats = ref({ | 101 | + const user = await getProfileAPI() |
| 100 | - following: 12, | 102 | + if (user.code) { |
| 101 | - orders: 8, | 103 | + userInfo.value = user.data |
| 102 | - followers: 24 | 104 | + } |
| 103 | }) | 105 | }) |
| 104 | 106 | ||
| 105 | /** | 107 | /** | ... | ... |
| ... | @@ -4,10 +4,10 @@ | ... | @@ -4,10 +4,10 @@ |
| 4 | <view class="avatar-section"> | 4 | <view class="avatar-section"> |
| 5 | <view class="avatar-container"> | 5 | <view class="avatar-container"> |
| 6 | <image | 6 | <image |
| 7 | - :src="formData.avatar || defaultAvatar" | 7 | + :src="formData.avatar_url || defaultAvatar" |
| 8 | class="avatar-image" | 8 | class="avatar-image" |
| 9 | mode="aspectFill" | 9 | mode="aspectFill" |
| 10 | - @tap="previewAvatar(formData.avatar || defaultAvatar)" | 10 | + @tap="previewAvatar(formData.avatar_url || defaultAvatar)" |
| 11 | /> | 11 | /> |
| 12 | </view> | 12 | </view> |
| 13 | <view class="change-avatar-btn" @click="changeAvatar"> | 13 | <view class="change-avatar-btn" @click="changeAvatar"> |
| ... | @@ -52,9 +52,9 @@ | ... | @@ -52,9 +52,9 @@ |
| 52 | </nut-form-item> | 52 | </nut-form-item> |
| 53 | 53 | ||
| 54 | <!-- 验证码 --> | 54 | <!-- 验证码 --> |
| 55 | - <nut-form-item label="验证码" prop="verifyCode" required :rules="[{ required: true, message: '请输入验证码' }]"> | 55 | + <nut-form-item label="验证码" prop="sms_code" required :rules="[{ required: true, message: '请输入验证码' }]"> |
| 56 | <nut-input | 56 | <nut-input |
| 57 | - v-model="formData.verifyCode" | 57 | + v-model="formData.sms_code" |
| 58 | placeholder="请输入验证码" | 58 | placeholder="请输入验证码" |
| 59 | type="number" | 59 | type="number" |
| 60 | maxlength="6" | 60 | maxlength="6" |
| ... | @@ -67,19 +67,19 @@ | ... | @@ -67,19 +67,19 @@ |
| 67 | <nut-config-provider :theme-vars="themeVars"> | 67 | <nut-config-provider :theme-vars="themeVars"> |
| 68 | <nut-form-item label="性别" prop="gender" body-align="right" required :rules="[{ required: true, message: '请选择性别' }]"> | 68 | <nut-form-item label="性别" prop="gender" body-align="right" required :rules="[{ required: true, message: '请选择性别' }]"> |
| 69 | <nut-radio-group v-model="formData.gender" direction="horizontal"> | 69 | <nut-radio-group v-model="formData.gender" direction="horizontal"> |
| 70 | - <nut-radio label="男">男</nut-radio> | 70 | + <nut-radio :label="0">男</nut-radio> |
| 71 | - <nut-radio label="女">女</nut-radio> | 71 | + <nut-radio :label="1">女</nut-radio> |
| 72 | </nut-radio-group> | 72 | </nut-radio-group> |
| 73 | </nut-form-item> | 73 | </nut-form-item> |
| 74 | </nut-config-provider> | 74 | </nut-config-provider> |
| 75 | 75 | ||
| 76 | <!-- 生日 --> | 76 | <!-- 生日 --> |
| 77 | - <nut-form-item label="生日" prop="birthday" label-position="top"> | 77 | + <!-- <nut-form-item label="生日" prop="birthday" label-position="top"> |
| 78 | <view class="birthday-item" @click="showDatePicker"> | 78 | <view class="birthday-item" @click="showDatePicker"> |
| 79 | <text class="birthday-value">{{ formData.birthday || '请选择生日' }}</text> | 79 | <text class="birthday-value">{{ formData.birthday || '请选择生日' }}</text> |
| 80 | <Right class="arrow-icon" /> | 80 | <Right class="arrow-icon" /> |
| 81 | </view> | 81 | </view> |
| 82 | - </nut-form-item> | 82 | + </nut-form-item> --> |
| 83 | 83 | ||
| 84 | <!-- 所在学校 --> | 84 | <!-- 所在学校 --> |
| 85 | <nut-form-item label="所在学校" prop="school" required :rules="[{ required: true, message: '请选择学校' }]" label-position="top"> | 85 | <nut-form-item label="所在学校" prop="school" required :rules="[{ required: true, message: '请选择学校' }]" label-position="top"> |
| ... | @@ -88,6 +88,16 @@ | ... | @@ -88,6 +88,16 @@ |
| 88 | <Right class="arrow-icon" /> | 88 | <Right class="arrow-icon" /> |
| 89 | </view> | 89 | </view> |
| 90 | </nut-form-item> | 90 | </nut-form-item> |
| 91 | + | ||
| 92 | + <!-- 微信号 --> | ||
| 93 | + <nut-form-item label="微信号" prop="wechat_id" required :rules="[{ required: true, message: '请输入微信号' }]"> | ||
| 94 | + <nut-input | ||
| 95 | + v-model="formData.wechat_id" | ||
| 96 | + placeholder="请输入微信号" | ||
| 97 | + input-align="right" | ||
| 98 | + clearable | ||
| 99 | + /> | ||
| 100 | + </nut-form-item> | ||
| 91 | </view> | 101 | </view> |
| 92 | </nut-form> | 102 | </nut-form> |
| 93 | 103 | ||
| ... | @@ -143,6 +153,7 @@ import Taro from '@tarojs/taro' | ... | @@ -143,6 +153,7 @@ import Taro from '@tarojs/taro' |
| 143 | import { Right } from '@nutui/icons-vue-taro' | 153 | import { Right } from '@nutui/icons-vue-taro' |
| 144 | import './index.less' | 154 | import './index.less' |
| 145 | import BASE_URL from '@/utils/config'; | 155 | import BASE_URL from '@/utils/config'; |
| 156 | +import { updateProfileAPI, sendSmsCodeAPI } from '@/api/index'; | ||
| 146 | 157 | ||
| 147 | // 主题配置 | 158 | // 主题配置 |
| 148 | const themeVars = { | 159 | const themeVars = { |
| ... | @@ -154,13 +165,15 @@ const defaultAvatar = 'https://cdn.ipadbiz.cn/mlaj/images/icon_1.jpeg' | ... | @@ -154,13 +165,15 @@ const defaultAvatar = 'https://cdn.ipadbiz.cn/mlaj/images/icon_1.jpeg' |
| 154 | 165 | ||
| 155 | // 表单数据 | 166 | // 表单数据 |
| 156 | const formData = reactive({ | 167 | const formData = reactive({ |
| 157 | - avatar: '', | 168 | + avatar_url: '', |
| 158 | nickname: '', | 169 | nickname: '', |
| 159 | phone: '', | 170 | phone: '', |
| 160 | - verifyCode: '', | 171 | + sms_code: '', |
| 161 | gender: '', | 172 | gender: '', |
| 162 | - birthday: '', | 173 | + // birthday: '', |
| 163 | - school: '' | 174 | + school: '', |
| 175 | + school_id: '', | ||
| 176 | + wechat_id: '' | ||
| 164 | }) | 177 | }) |
| 165 | 178 | ||
| 166 | // 弹框控制 | 179 | // 弹框控制 |
| ... | @@ -260,7 +273,7 @@ const uploadImage = (filePath) => { | ... | @@ -260,7 +273,7 @@ const uploadImage = (filePath) => { |
| 260 | Taro.hideLoading({ | 273 | Taro.hideLoading({ |
| 261 | success: () => { | 274 | success: () => { |
| 262 | if (res.statusCode === 200) { | 275 | if (res.statusCode === 200) { |
| 263 | - formData.avatar = upload_data.data.src; | 276 | + formData.avatar_url = upload_data.data.src; |
| 264 | Taro.showToast({ | 277 | Taro.showToast({ |
| 265 | title: '上传成功', | 278 | title: '上传成功', |
| 266 | icon: 'success' | 279 | icon: 'success' |
| ... | @@ -308,30 +321,51 @@ const previewAvatar = (imageUrl) => { | ... | @@ -308,30 +321,51 @@ const previewAvatar = (imageUrl) => { |
| 308 | /** | 321 | /** |
| 309 | * 发送验证码 | 322 | * 发送验证码 |
| 310 | */ | 323 | */ |
| 311 | -const sendCode = () => { | 324 | +const sendCode = async () => { |
| 312 | if (!isPhoneValid.value) { | 325 | if (!isPhoneValid.value) { |
| 313 | - showToast('请输入正确的手机号', 'error') | 326 | + Taro.showToast({ |
| 327 | + title: '请输入正确的手机号', | ||
| 328 | + icon: 'error' | ||
| 329 | + }) | ||
| 314 | return | 330 | return |
| 315 | } | 331 | } |
| 316 | 332 | ||
| 317 | - // 模拟发送验证码 | 333 | + // 如果正在倒计时,不允许重复发送 |
| 318 | - codeCountdown.value = 60 | 334 | + if (codeCountdown.value > 0) { |
| 319 | - const timer = setInterval(() => { | 335 | + return |
| 320 | - codeCountdown.value-- | 336 | + } |
| 321 | - if (codeCountdown.value <= 0) { | 337 | + |
| 322 | - clearInterval(timer) | 338 | + try { |
| 323 | - } | 339 | + // 发送验证码API请求 |
| 324 | - }, 1000) | 340 | + await sendSmsCodeAPI({ mobile: formData.phone }) |
| 341 | + Taro.showToast({ | ||
| 342 | + title: '验证码已发送', | ||
| 343 | + icon: 'success' | ||
| 344 | + }) | ||
| 345 | + | ||
| 346 | + // 开始倒计时 | ||
| 347 | + codeCountdown.value = 60 | ||
| 348 | + const timer = setInterval(() => { | ||
| 349 | + codeCountdown.value-- | ||
| 350 | + if (codeCountdown.value <= 0) { | ||
| 351 | + clearInterval(timer) | ||
| 352 | + } | ||
| 353 | + }, 1000) | ||
| 325 | 354 | ||
| 326 | - showToast('验证码已发送', 'success') | 355 | + } catch (error) { |
| 356 | + Taro.showToast({ | ||
| 357 | + title: error.message || '发送验证码失败,请重试', | ||
| 358 | + icon: 'error' | ||
| 359 | + }) | ||
| 360 | + } | ||
| 327 | } | 361 | } |
| 328 | 362 | ||
| 329 | /** | 363 | /** |
| 330 | * 显示日期选择器 | 364 | * 显示日期选择器 |
| 331 | */ | 365 | */ |
| 332 | -const showDatePicker = () => { | 366 | +// const showDatePicker = () => { |
| 333 | - datePickerVisible.value = true | 367 | +// datePickerVisible.value = true |
| 334 | -} | 368 | +// } |
| 335 | 369 | ||
| 336 | /** | 370 | /** |
| 337 | * 确认日期选择 | 371 | * 确认日期选择 |
| ... | @@ -353,6 +387,7 @@ const showSchoolPicker = () => { | ... | @@ -353,6 +387,7 @@ const showSchoolPicker = () => { |
| 353 | */ | 387 | */ |
| 354 | const onSchoolConfirm = ({ selectedOptions }) => { | 388 | const onSchoolConfirm = ({ selectedOptions }) => { |
| 355 | formData.school = selectedOptions[0].text | 389 | formData.school = selectedOptions[0].text |
| 390 | + formData.school_id = selectedOptions[0].value | ||
| 356 | schoolPickerVisible.value = false | 391 | schoolPickerVisible.value = false |
| 357 | } | 392 | } |
| 358 | 393 | ||
| ... | @@ -379,7 +414,7 @@ const validateForm = () => { | ... | @@ -379,7 +414,7 @@ const validateForm = () => { |
| 379 | return false | 414 | return false |
| 380 | } | 415 | } |
| 381 | 416 | ||
| 382 | - if (!formData.verifyCode.trim()) { | 417 | + if (!formData.sms_code.trim()) { |
| 383 | showToast('请输入验证码', 'error') | 418 | showToast('请输入验证码', 'error') |
| 384 | return false | 419 | return false |
| 385 | } | 420 | } |
| ... | @@ -389,11 +424,16 @@ const validateForm = () => { | ... | @@ -389,11 +424,16 @@ const validateForm = () => { |
| 389 | return false | 424 | return false |
| 390 | } | 425 | } |
| 391 | 426 | ||
| 392 | - if (!formData.school) { | 427 | + if (!formData.school_id) { |
| 393 | showToast('请选择学校', 'error') | 428 | showToast('请选择学校', 'error') |
| 394 | return false | 429 | return false |
| 395 | } | 430 | } |
| 396 | 431 | ||
| 432 | + if (!formData.wechat_id) { | ||
| 433 | + showToast('请输入微信号', 'error') | ||
| 434 | + return false | ||
| 435 | + } | ||
| 436 | + | ||
| 397 | return true | 437 | return true |
| 398 | } | 438 | } |
| 399 | 439 | ||
| ... | @@ -408,11 +448,13 @@ const handleRegister = async () => { | ... | @@ -408,11 +448,13 @@ const handleRegister = async () => { |
| 408 | isRegistering.value = true | 448 | isRegistering.value = true |
| 409 | 449 | ||
| 410 | try { | 450 | try { |
| 411 | - // 模拟注册API调用 | ||
| 412 | - await new Promise(resolve => setTimeout(resolve, 2000)) | ||
| 413 | 451 | ||
| 414 | - // TODO: 这里应该调用实际的注册API | 452 | + const result = await updateProfileAPI(formData) |
| 415 | - // const result = await registerAPI(formData) | 453 | + |
| 454 | + if (result.code !== 0) { | ||
| 455 | + showToast(result.msg || '注册失败', 'error') | ||
| 456 | + return | ||
| 457 | + } | ||
| 416 | 458 | ||
| 417 | showToast('注册成功', 'success') | 459 | showToast('注册成功', 'success') |
| 418 | 460 | ... | ... |
| 1 | /* | 1 | /* |
| 2 | * @Date: 2022-09-19 14:11:06 | 2 | * @Date: 2022-09-19 14:11:06 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2024-01-15 17:07:14 | 4 | + * @LastEditTime: 2025-07-08 17:44:47 |
| 5 | - * @FilePath: /meihuaApp/src/utils/config.js | 5 | + * @FilePath: /jgdl/src/utils/config.js |
| 6 | * @Description: 文件描述 | 6 | * @Description: 文件描述 |
| 7 | */ | 7 | */ |
| 8 | // TAG:服务器环境配置 | 8 | // TAG:服务器环境配置 |
| 9 | -// const BASE_URL = "https://oa-dev.onwall.cn"; // 测试服务器 | 9 | +const BASE_URL = "https://oa-dev.onwall.cn"; // 测试服务器 |
| 10 | -const BASE_URL = "https://oa.onwall.cn"; // 正式服务器 | 10 | +// const BASE_URL = "https://oa.onwall.cn"; // 正式服务器 |
| 11 | 11 | ||
| 12 | export default BASE_URL | 12 | export default BASE_URL | ... | ... |
| 1 | /* | 1 | /* |
| 2 | * @Date: 2022-09-19 14:11:06 | 2 | * @Date: 2022-09-19 14:11:06 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-07-01 11:17:49 | 4 | + * @LastEditTime: 2025-07-08 17:42:15 |
| 5 | - * @FilePath: /myApp/src/utils/request.js | 5 | + * @FilePath: /jgdl/src/utils/request.js |
| 6 | * @Description: 简单axios封装,后续按实际处理 | 6 | * @Description: 简单axios封装,后续按实际处理 |
| 7 | */ | 7 | */ |
| 8 | // import axios from 'axios' | 8 | // import axios from 'axios' |
| ... | @@ -60,8 +60,7 @@ const service = axios.create({ | ... | @@ -60,8 +60,7 @@ const service = axios.create({ |
| 60 | }) | 60 | }) |
| 61 | 61 | ||
| 62 | service.defaults.params = { | 62 | service.defaults.params = { |
| 63 | - f: 'room', | 63 | + f: 'jiangedianlv', |
| 64 | - client_id: '772428', | ||
| 65 | }; | 64 | }; |
| 66 | 65 | ||
| 67 | // request interceptor | 66 | // request interceptor | ... | ... |
-
Please register or login to post a comment