From 5cbd30fcb731ea4fa141edd9ed7cce4c5f3c72d0 Mon Sep 17 00:00:00 2001 From: tsui110 Date: Fri, 2 Jan 2026 17:18:29 +0800 Subject: [PATCH] =?UTF-8?q?fix=EF=BC=9A=E7=A7=BB=E9=99=A4=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E7=9A=84=E9=80=BB=E8=BE=91=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages-activity/activity/duiduipeng/index.vue | 4 +- pages-activity/activity/wuxianshang/index.vue | 8 +- pages-user/address/index.vue | 6 +- pages-user/invite/landing.vue | 11 +- pages-user/orders/index.vue | 6 +- pages-user/points/index.vue | 4 +- pages/login/index.vue | 205 +++++++++++++----- utils/checkPhone.js | 16 +- utils/payment.js | 4 +- 9 files changed, 172 insertions(+), 92 deletions(-) diff --git a/pages-activity/activity/duiduipeng/index.vue b/pages-activity/activity/duiduipeng/index.vue index 9371c2a..a5c032e 100644 --- a/pages-activity/activity/duiduipeng/index.vue +++ b/pages-activity/activity/duiduipeng/index.vue @@ -1272,8 +1272,8 @@ async function onParticipate() { const iid = currentIssueId.value || '' if (!aid || !iid) { uni.showToast({ title: '期数未选择', icon: 'none' }); return } const token = uni.getStorageSync('token') - const phoneBound = !!uni.getStorageSync('phone_bound') - if (!token || !phoneBound) { + const phoneNumber = uni.getStorageSync('phone_number') + if (!token || !phoneNumber) { uni.showModal({ title: '提示', content: '请先登录并绑定手机号', diff --git a/pages-activity/activity/wuxianshang/index.vue b/pages-activity/activity/wuxianshang/index.vue index ec5d22d..8a1361d 100644 --- a/pages-activity/activity/wuxianshang/index.vue +++ b/pages-activity/activity/wuxianshang/index.vue @@ -228,8 +228,8 @@ function openPayment(count) { pendingCount.value = times paymentAmount.value = (pricePerDraw.value * times).toFixed(2) const token = uni.getStorageSync('token') - const phoneBound = !!uni.getStorageSync('phone_bound') - if (!token || !phoneBound) { + const phoneNumber = uni.getStorageSync('phone_number') + if (!token || !phoneNumber) { uni.showModal({ title: '提示', content: '请先登录并绑定手机号', @@ -340,8 +340,8 @@ async function onMachineDraw(count) { } const token = uni.getStorageSync('token') - const phoneBound = !!uni.getStorageSync('phone_bound') - if (!token || !phoneBound) { + const phoneNumber = uni.getStorageSync('phone_number') + if (!token || !phoneNumber) { uni.showModal({ title: '提示', content: '请先登录并绑定手机号', diff --git a/pages-user/address/index.vue b/pages-user/address/index.vue index d815e88..a10c053 100644 --- a/pages-user/address/index.vue +++ b/pages-user/address/index.vue @@ -88,14 +88,14 @@ const error = ref('') async function fetchList() { const user_id = uni.getStorageSync('user_id') const token = uni.getStorageSync('token') - const phoneBound = !!uni.getStorageSync('phone_bound') - + const phoneNumber = uni.getStorageSync('phone_number') + // 简单的登录检查,实际逻辑可能需要更严谨 if (!user_id || !token) { // 这里不再强制弹窗,由页面逻辑决定是否跳转 return } - + loading.value = true error.value = '' try { diff --git a/pages-user/invite/landing.vue b/pages-user/invite/landing.vue index 1ab0032..f8bf607 100644 --- a/pages-user/invite/landing.vue +++ b/pages-user/invite/landing.vue @@ -163,18 +163,19 @@ function onGetPhoneNumber(e) { if (user_info.invite_code) uni.setStorageSync('invite_code', user_info.invite_code) const openid = data && (data.openid || data.open_id) if (openid) uni.setStorageSync('openid', openid) - + try { await new Promise(r => setTimeout(r, 600)) const bindRes = await bindPhone(user_id, phoneCode, { 'X-Suppress-Auth-Modal': true }) const phoneNumber = (bindRes && (bindRes.phone || bindRes.phone_number || bindRes.mobile)) || '' - if (phoneNumber) uni.setStorageSync('phone_number', phoneNumber) + if (phoneNumber) { + uni.setStorageSync('phone_number', phoneNumber) + console.log('[Invite Landing] 已缓存手机号:', phoneNumber) + } } catch (bindErr) { console.warn('Bind phone failed', bindErr) } - - uni.setStorageSync('phone_bound', true) - + try { const stats = await getUserStats(user_id) uni.setStorageSync('user_stats', stats) diff --git a/pages-user/orders/index.vue b/pages-user/orders/index.vue index ac0f557..9b60ac2 100644 --- a/pages-user/orders/index.vue +++ b/pages-user/orders/index.vue @@ -310,9 +310,9 @@ function filterOrders(items) { async function fetchOrders(append) { const user_id = uni.getStorageSync('user_id') const token = uni.getStorageSync('token') - const phoneBound = !!uni.getStorageSync('phone_bound') - - if (!user_id || !token || !phoneBound) { + const phoneNumber = uni.getStorageSync('phone_number') + + if (!user_id || !token || !phoneNumber) { uni.showModal({ title: '提示', content: '请先登录并绑定手机号', diff --git a/pages-user/points/index.vue b/pages-user/points/index.vue index 43bde87..6820340 100644 --- a/pages-user/points/index.vue +++ b/pages-user/points/index.vue @@ -106,8 +106,8 @@ function getActionText(action) { async function fetchRecords(append = false) { const user_id = uni.getStorageSync('user_id') const token = uni.getStorageSync('token') - const phoneBound = !!uni.getStorageSync('phone_bound') - if (!user_id || !token || !phoneBound) { + const phoneNumber = uni.getStorageSync('phone_number') + if (!user_id || !token || !phoneNumber) { uni.showModal({ title: '提示', content: '请先登录并绑定手机号', diff --git a/pages/login/index.vue b/pages/login/index.vue index eb5acfc..ce34fa5 100644 --- a/pages/login/index.vue +++ b/pages/login/index.vue @@ -347,30 +347,30 @@ async function handleSmsLogin() { vibrateShort() return } - + if (!canLogin.value) return - + loading.value = true - + try { const inviterCode = uni.getStorageSync('inviter_code') const data = await smsLogin(mobile.value, smsCode.value, inviterCode) - + console.log('[DEBUG] 短信登录响应原始数据:', data) saveUserData(data) - + const isNew = data && data.is_new_user - uni.showToast({ - title: isNew ? '🎉 注册成功!' : '✨ 登录成功!', - icon: 'none', - duration: 1200 + uni.showToast({ + title: isNew ? '🎉 注册成功!' : '✨ 登录成功!', + icon: 'none', + duration: 1200 }) - + // 后台获取数据 if (data && data.user_id) { fetchExtraData(data.user_id) } - + setTimeout(() => uni.reLaunch({ url: '/pages/mine/index' }), 600) } catch (err) { uni.showToast({ title: err.message || '登录失败', icon: 'none' }) @@ -380,7 +380,7 @@ async function handleSmsLogin() { } // 微信登录 -function onGetPhoneNumber(e) { +async function onGetPhoneNumber(e) { if (!agreementChecked.value) { uni.showToast({ title: '请先同意用户协议', icon: 'none' }) vibrateShort() @@ -395,58 +395,145 @@ function onGetPhoneNumber(e) { loading.value = true - uni.login({ - provider: 'weixin', - success: async (res) => { + try { + // 1. 检查是否已登录且未过期 + const token = uni.getStorageSync('token') + const phoneNumber = uni.getStorageSync('phone_number') + + console.log('[DEBUG] 微信登录 - 检查登录状态:', { + hasToken: !!token, + hasPhoneNumber: !!phoneNumber, + phoneNumber: phoneNumber || '未找到' + }) + + let userId = null + + // 2. 如果已有 token 和手机号,说明已登录且已绑定手机号 + if (token && phoneNumber) { + console.log('[DEBUG] 已登录且已绑定手机号,跳过登录流程') + userId = uni.getStorageSync('user_id') + + // 跳转到首页 + uni.showToast({ title: '✨ 已登录!', icon: 'none', duration: 1200 }) + setTimeout(() => uni.reLaunch({ url: '/pages/mine/index' }), 600) + loading.value = false + return + } + + // 3. 如果有 token 但没有手机号,说明已登录但未绑定手机号 + if (token && !phoneNumber) { + console.log('[DEBUG] 已登录但未绑定手机号,开始绑定') + userId = uni.getStorageSync('user_id') + try { - const inviterCode = uni.getStorageSync('inviter_code') - const data = await wechatLogin(res.code, inviterCode) + const bindRes = await bindPhone(userId, phoneCode) + console.log('[DEBUG] 绑定手机号成功:', bindRes) - // 检查后端返回的数据中是否已包含手机号 - const isBound = data.phone || data.phone_number || data.mobile - console.log('[DEBUG] 微信登录返回数据手机号状态:', isBound ? '已绑定' : '未绑定', data) - - // 如果未绑定手机号,则调用绑定接口 - if (!isBound) { - try { - console.log('[DEBUG] 开始绑定手机号') - await bindPhone(data.user_id, phoneCode) - // 绑定成功后,强制从服务器获取最新的用户信息(不读取缓存) - try { - const updatedUserInfo = await authRequest({ url: '/api/app/users/info', method: 'GET' }) - console.log('[DEBUG] 绑定后从服务器获取用户信息:', updatedUserInfo) - // 如果返回了用户信息,合并到 data 对象 - if (updatedUserInfo) { - Object.assign(data, updatedUserInfo) - } - } catch (err) { - console.warn('[DEBUG] 绑定后获取用户信息失败:', err) - } - } catch (e) { - console.error('[DEBUG] 绑定手机号失败:', e) - } - } else { - console.log('[DEBUG] 微信登录已包含手机号,跳过绑定') + // 从绑定响应中获取手机号并缓存 + const boundPhone = bindRes.phone || bindRes.phone_number || bindRes.mobile + if (boundPhone) { + uni.setStorageSync('phone_number', boundPhone) + console.log('[DEBUG] 已缓存手机号到 phone_number:', boundPhone) } - // 保存用户数据(此时应该包含手机号) - saveUserData(data) + // 更新用户信息 + try { + const updatedUserInfo = await authRequest({ url: '/api/app/users/info', method: 'GET' }) + if (updatedUserInfo) { + uni.setStorageSync('user_info', updatedUserInfo) + } + } catch (err) { + console.warn('[DEBUG] 绑定后获取用户信息失败:', err) + } // 后台获取数据 - fetchExtraData(data.user_id) + fetchExtraData(userId) - uni.showToast({ title: '✨ 登录成功!', icon: 'none', duration: 1200 }) + uni.showToast({ title: '✨ 绑定成功!', icon: 'none', duration: 1200 }) setTimeout(() => uni.reLaunch({ url: '/pages/mine/index' }), 600) - } catch (err) { - uni.showToast({ title: err.message || '登录失败', icon: 'none' }) - } finally { - loading.value = false + } catch (bindErr) { + console.error('[DEBUG] 绑定手机号失败:', bindErr) + uni.showToast({ title: bindErr.message || '绑定失败', icon: 'none' }) } - }, - fail: () => { loading.value = false + return } - }) + + // 4. 如果没有 token,说明未登录或已过期,执行完整的登录流程 + console.log('[DEBUG] 未登录或已过期,执行微信登录') + + uni.login({ + provider: 'weixin', + success: async (res) => { + try { + const inviterCode = uni.getStorageSync('inviter_code') + const data = await wechatLogin(res.code, inviterCode) + + console.log('[DEBUG] 微信登录成功:', data) + + // 保存基本用户信息 + saveUserData(data) + userId = data.user_id + + // 检查是否需要绑定手机号 + const hasPhone = data.mobile || data.phone || data.phone_number + + if (!hasPhone) { + // 5. 如果登录返回的数据中没有手机号,调用绑定接口 + console.log('[DEBUG] 登录未返回手机号,开始绑定') + try { + const bindRes = await bindPhone(userId, phoneCode) + console.log('[DEBUG] 绑定手机号成功:', bindRes) + + // 从绑定响应中获取手机号并缓存 + const boundPhone = bindRes.phone || bindRes.phone_number || bindRes.mobile + if (boundPhone) { + uni.setStorageSync('phone_number', boundPhone) + console.log('[DEBUG] 已缓存手机号到 phone_number:', boundPhone) + } + + // 更新用户信息 + try { + const updatedUserInfo = await authRequest({ url: '/api/app/users/info', method: 'GET' }) + if (updatedUserInfo) { + Object.assign(data, updatedUserInfo) + uni.setStorageSync('user_info', updatedUserInfo) + } + } catch (err) { + console.warn('[DEBUG] 绑定后获取用户信息失败:', err) + } + } catch (bindErr) { + console.error('[DEBUG] 绑定手机号失败:', bindErr) + } + } else { + // 6. 如果登录已返回手机号,直接缓存 + const phoneToCache = data.mobile || data.phone || data.phone_number + uni.setStorageSync('phone_number', phoneToCache) + console.log('[DEBUG] 登录已返回手机号,已缓存:', phoneToCache) + } + + // 后台获取数据 + fetchExtraData(userId) + + uni.showToast({ title: '✨ 登录成功!', icon: 'none', duration: 1200 }) + setTimeout(() => uni.reLaunch({ url: '/pages/mine/index' }), 600) + } catch (err) { + console.error('[DEBUG] 微信登录失败:', err) + uni.showToast({ title: err.message || '登录失败', icon: 'none' }) + } finally { + loading.value = false + } + }, + fail: () => { + loading.value = false + uni.showToast({ title: '微信登录失败', icon: 'none' }) + } + }) + } catch (err) { + console.error('[DEBUG] 微信登录流程错误:', err) + uni.showToast({ title: err.message || '登录失败', icon: 'none' }) + loading.value = false + } } // 抖音登录 - 不需要手机号授权 @@ -523,13 +610,11 @@ function saveUserData(data) { hasPhone: hasPhone ? '已绑定' : '未绑定' }) - // 根据实际是否有手机号来设置 phone_bound 状态 + // 如果有手机号,缓存到 phone_number if (hasPhone) { - uni.setStorageSync('phone_bound', true) - console.log('[DEBUG] 已设置 phone_bound = true') - } else { - uni.setStorageSync('phone_bound', false) - console.log('[DEBUG] 已设置 phone_bound = false') + const phoneToCache = data.mobile || data.phone || data.phone_number + uni.setStorageSync('phone_number', phoneToCache) + console.log('[DEBUG] 已缓存手机号到 phone_number:', phoneToCache) } // 如果返回了 openid,则存储 (短信登录现在也会返回已关联的 openid) @@ -541,8 +626,8 @@ function saveUserData(data) { console.warn('[DEBUG] 登录接口未返回 openid, 请检查后端或联系管理员') } + // 如果未绑定手机号,切换到短信登录tab进行绑定 if (!hasPhone) { - // 未绑定手机号,切换到短信登录tab进行绑定 console.log('[DEBUG] 未检测到手机号,切换到短信登录tab') uni.showModal({ title: '绑定手机号', diff --git a/utils/checkPhone.js b/utils/checkPhone.js index 60a969f..c5f78b2 100644 --- a/utils/checkPhone.js +++ b/utils/checkPhone.js @@ -4,20 +4,14 @@ * @returns {boolean} 是否已绑定手机号 */ export function checkPhoneBound() { - // 获取用户信息 - const userInfo = uni.getStorageSync('user_info') || {} - console.log('[checkPhoneBound] 检查用户信息:', { - mobile: userInfo.mobile, - phone: userInfo.phone, - phone_number: userInfo.phone_number, - userInfoKeys: Object.keys(userInfo) - }) + // 直接检查 phone_number 缓存中是否有手机号 + const phoneNumber = uni.getStorageSync('phone_number') || '' - const mobile = userInfo.mobile || userInfo.phone || userInfo.phone_number || '' + console.log('[checkPhoneBound] 检查 phone_number 缓存:', phoneNumber ? phoneNumber : '未找到') // 如果已绑定手机号,直接返回 - if (mobile) { - console.log('[checkPhoneBound] 已检测到手机号,允许通过:', mobile) + if (phoneNumber) { + console.log('[checkPhoneBound] 已检测到手机号,允许通过:', phoneNumber) return true } diff --git a/utils/payment.js b/utils/payment.js index d6e5878..904e3a8 100644 --- a/utils/payment.js +++ b/utils/payment.js @@ -98,10 +98,10 @@ export async function executePaymentFlow({ createOrder, openid, onOrderCreated } */ export function checkLoginStatus() { const token = uni.getStorageSync('token') - const phoneBound = !!uni.getStorageSync('phone_bound') + const phoneNumber = uni.getStorageSync('phone_number') const openid = uni.getStorageSync('openid') - if (!token || !phoneBound) { + if (!token || !phoneNumber) { return { ok: false, message: '请先登录并绑定手机号' } } if (!openid) {