From 71aa31628dda29072d3739279d2efc36a9b4f702 Mon Sep 17 00:00:00 2001 From: wx-jincw Date: Sat, 23 May 2026 17:38:36 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=BE=AE=E4=BF=A1=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E7=BB=91=E5=AE=9A=E8=B4=A6=E5=8F=B7=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/config/app.js | 2 +- app/libs/login.js | 64 ++++++------- app/pages/users/login/index.vue | 68 ++++++++++++- app/pages/users/wechat_login/index.vue | 128 ++++++++++++++++++++----- 4 files changed, 195 insertions(+), 67 deletions(-) diff --git a/app/config/app.js b/app/config/app.js index 6c1f665..9df0501 100644 --- a/app/config/app.js +++ b/app/config/app.js @@ -45,5 +45,5 @@ module.exports = { * false=关闭(跳转账号密码页,走 register/binding/account 绑定已有账号) * 可被后端 wechat/getLogo 返回的 routineLoginRequirePhone 覆盖 */ - MP_WECHAT_REQUIRE_PHONE: true + MP_WECHAT_REQUIRE_PHONE: false }; diff --git a/app/libs/login.js b/app/libs/login.js index 66c50ec..2a56654 100644 --- a/app/libs/login.js +++ b/app/libs/login.js @@ -38,46 +38,36 @@ export function _toLogin(push, pathLogin) { pathLogin = '/page/users/login/index' Cache.set('login_back_url',path); } - - // // #ifdef H5 - // if (isWeixin()) { - // let urlData = location.pathname + location.search - // if (urlData.indexOf('?') !== -1) { - // urlData += '&go_longin=1'; - // } else { - // urlData += '?go_longin=1'; - // } - // if (!Cache.has('snsapiKey')) { - // auth.oAuth('snsapi_base', urlData); - // } else { - // if (['/pages/user/index'].indexOf(login_back_url) == -1) { - // uni.navigateTo({ - // url: '/pages/users/wechat_login/index' - // }) - // } - // } - // } else { - // if (['/pages/user/index'].indexOf(login_back_url) == -1) { - // uni.navigateTo({ - // url: '/pages/users/login/index' - // }) - // } - // } - // // #endif - - // if (['pages/user/index','/pages/user/index'].indexOf(login_back_url) == -1) { - // // #ifdef MP - // uni.navigateTo({ - // url: '/pages/users/wechat_login/index' - // }) - // // #endif - // } - + if (['pages/user/index','/pages/user/index'].indexOf(login_back_url) == -1) { + // #ifdef H5 + if (isWeixin()) { + let urlData = location.pathname + location.search + if (urlData.indexOf('?') !== -1) { + urlData += '&go_longin=1'; + } else { + urlData += '?go_longin=1'; + } + if (!Cache.has('snsapiKey')) { + auth.oAuth('snsapi_base', urlData); + } else { + uni.navigateTo({ + url: '/pages/users/wechat_login/index' + }) + } + } else { + uni.navigateTo({ + url: '/pages/users/login/index' + }) + } + // #endif + + // #ifdef MP uni.navigateTo({ - url: '/pages/users/login/index' + url: '/pages/users/wechat_login/index' }) - } + // #endif + } } diff --git a/app/pages/users/login/index.vue b/app/pages/users/login/index.vue index 4e5458b..5889207 100644 --- a/app/pages/users/login/index.vue +++ b/app/pages/users/login/index.vue @@ -47,9 +47,12 @@
登录
-
登录
+
{{ bindWechatMode ? '绑定微信登录' : '登录' }}
-
微信登录
+
微信登录
+ + +
请使用已有账号密码完成微信绑定,绑定后可直接微信登录
@@ -80,7 +83,7 @@ validatorDefaultCatch } from "@/utils/dialog"; import { - getLogo, appAuth, appleLogin + getLogo, appAuth, appleLogin, bindRoutineAccount } from "@/api/public"; import { VUE_APP_API_URL @@ -116,7 +119,10 @@ appleLoginStatus: false, // 苹果登录强制绑定手机号码状态 appleUserInfo: null, appleShow: false, // 苹果登录版本必须要求ios13以上的 - pendingGzhCode: '' // 公众号授权未绑定时,随账号密码一并提交 + pendingGzhCode: '', // 公众号授权未绑定时,随账号密码一并提交 + // 小程序:微信绑定已有账号模式(来自 wechat_login 页 register 流程) + bindWechatMode: false, + wechatBindAuthKey: '' }; }, watch:{ @@ -132,7 +138,13 @@ this.getCode(); this.getLogoImage(); }, - onLoad() { + onLoad(options) { + // #ifdef MP-WEIXIN + if (options.bindWechat === '1' && options.authKey) { + this.bindWechatMode = true; + this.wechatBindAuthKey = decodeURIComponent(options.authKey); + } + // #endif let self = this uni.getSystemInfo({ success: function(res) { @@ -445,6 +457,43 @@ if (!that.password) return that.$util.Tips({ title: '请填写密码' }); + + // 小程序微信绑定模式:校验账号密码并将微信 openId 关联到该账号 + // #ifdef MP-WEIXIN + if (that.bindWechatMode) { + if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(that.account)) { + return that.$util.Tips({ + title: '请输入正确的手机号码' + }); + } + if (!that.wechatBindAuthKey) { + return that.$util.Tips({ + title: '微信授权已失效,请返回重新授权' + }); + } + uni.showLoading({ title: '绑定中' }); + bindRoutineAccount({ + account: that.account, + password: that.password, + key: that.wechatBindAuthKey + }).then(res => { + uni.hideLoading(); + that.wechatBindAuthKey = ''; + that.bindWechatMode = false; + that.$store.commit('LOGIN', { + token: res.data.token + }); + that.getUserInfo(res.data); + }).catch(e => { + uni.hideLoading(); + that.$util.Tips({ + title: e + }); + }); + return; + } + // #endif + const loginPayload = { account: that.account, password: that.password, @@ -686,6 +735,15 @@ margin-top: 32rpx; background-color: #07c160; } + + .bind-wechat-tip { + margin-top: 24rpx; + padding: 0 20rpx; + text-align: center; + font-size: 24rpx; + color: #999; + line-height: 1.6; + } .tips { margin: 30rpx; diff --git a/app/pages/users/wechat_login/index.vue b/app/pages/users/wechat_login/index.vue index ad56bab..0e35e5b 100644 --- a/app/pages/users/wechat_login/index.vue +++ b/app/pages/users/wechat_login/index.vue @@ -23,7 +23,11 @@ - + + + + + @@ -72,7 +76,11 @@ authKey: '', options: '', userInfo: {}, - codeNum: 0 + codeNum: 0, + // 小程序:是否强制获取微信手机号(true=弹手机号授权,false=跳转账号密码绑定) + requirePhone: false, + // 微信授权后待绑定的 key(关闭手机号时缓存,供「绑定已有账号」使用) + pendingBindAuthKey: '' } }, components: { @@ -80,9 +88,11 @@ routinePhone }, onLoad(options) { - // getLogo().then(res => { - // this.logoUrl = res.data.logoUrl - // }) + // #ifdef MP + // 先用本地配置同步初始化,避免 getLogo 未返回前 requirePhone 被误判 + this.requirePhone = this.parseRequirePhoneFlag(this.$config.MP_WECHAT_REQUIRE_PHONE); + this.loadMpLoginConfig(); + // #endif let that = this // #ifdef H5 document.body.addEventListener("focusout", () => { @@ -131,6 +141,66 @@ }, methods: { + // #ifdef MP + /** + * 是否强制获取微信手机号(仅 "1" / true 为开启,其余均为关闭) + */ + parseRequirePhoneFlag(value) { + return value === true || value === 1 || String(value) === '1'; + }, + /** + * 拉取小程序微信登录配置(是否强制获取手机号) + * 后端 system_config.routine_login_require_phone:1=开启,0=关闭(默认) + * 未配置时使用 app/config/app.js 中的 MP_WECHAT_REQUIRE_PHONE + */ + loadMpLoginConfig() { + const localDefault = this.parseRequirePhoneFlag(this.$config.MP_WECHAT_REQUIRE_PHONE); + return getLogo().then(res => { + const cfg = (res && res.data) ? res.data : {}; + if (cfg.logoUrl) { + this.logoUrl = cfg.logoUrl; + } + // 仅当后端明确返回 routineLoginRequirePhone 时才覆盖本地默认 + if (cfg.routineLoginRequirePhone !== undefined && cfg.routineLoginRequirePhone !== null && cfg.routineLoginRequirePhone !== '') { + this.requirePhone = this.parseRequirePhoneFlag(cfg.routineLoginRequirePhone); + } else { + this.requirePhone = localDefault; + } + return this.requirePhone; + }).catch(() => { + this.requirePhone = localDefault; + return this.requirePhone; + }); + }, + /** + * 关闭强制手机号时:跳转账号密码页进行微信绑定 + * 若尚未微信授权,提示先点「微信登录」 + */ + goBindAccountLogin() { + if (!this.pendingBindAuthKey) { + return this.$util.Tips({ + title: '请先点击上方「微信登录」完成授权' + }); + } + uni.navigateTo({ + url: '/pages/users/login/index?bindWechat=1&authKey=' + encodeURIComponent(this.pendingBindAuthKey) + }); + }, + /** + * 新微信用户且关闭强制手机号:跳转绑定页 + */ + goWechatBindLogin(authKey) { + this.pendingBindAuthKey = authKey; + uni.navigateTo({ + url: '/pages/users/login/index?bindWechat=1&authKey=' + encodeURIComponent(authKey) + }); + }, + // #endif + goAccountLogin() { + uni.navigateTo({ + url: '/pages/users/login/index' + }); + }, back() { uni.navigateBack(); }, @@ -224,19 +294,22 @@ uni.showLoading({ title: '正在登录中' }); - Routine.getUserProfile() - .then(res => { - Routine.getCode() - .then(code => { - self.getWxUser(code, res); - }) - .catch(res => { - uni.hideLoading(); - }); - }) - .catch(res => { - uni.hideLoading(); - }); + // 先确保开关配置已加载,再发起微信登录,避免 requirePhone 竞态导致误弹手机号 + self.loadMpLoginConfig().finally(() => { + Routine.getUserProfile() + .then(res => { + Routine.getCode() + .then(code => { + self.getWxUser(code, res); + }) + .catch(() => { + uni.hideLoading(); + }); + }) + .catch(() => { + uni.hideLoading(); + }); + }); }, getWxUser(code, res) { @@ -254,17 +327,24 @@ userInfo.type = 'routine' Routine.authUserInfo(userInfo.code, userInfo) .then(res => { - self.authKey = res.data.key; - if (res.data.type === 'register') { + const payload = (res && res.data) ? res.data : (res || {}); + self.authKey = payload.key; + if (payload.type === 'register') { uni.hideLoading(); - self.isPhoneBox = true + self.isPhoneBox = false; + // 开关开启:弹出微信手机号授权;关闭:跳转账号密码绑定页 + if (self.requirePhone) { + self.isPhoneBox = true; + } else { + self.goWechatBindLogin(payload.key); + } } - if (res.data.type === 'login') { + if (payload.type === 'login') { uni.hideLoading(); self.$store.commit('LOGIN', { - token: res.data.token + token: payload.token }); - self.$store.commit("SETUID", res.data.uid); + self.$store.commit("SETUID", payload.uid); self.getUserInfo(); self.$util.Tips({ title: res,