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,