You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
crmeb/app/pages/users/wechat_login/index.vue

489 lines
12 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view class="page">
<view class="system-height" :style="{height:statusBarHeight}"></view>
<!-- #ifdef MP -->
<view class="title-bar" style="height: 43px;">
<view class="icon" @click="back" v-if="!isHome">
<image src="../static/left.png"></image>
</view>
<view class="icon" @click="home" v-else>
<image src="../static/home.png"></image>
</view>
账户登录
</view>
<!-- #endif -->
<view class="wechat_login">
<view class="img">
<image src="../static/wechat_login.png" mode="widthFix"></image>
</view>
<view class="btn-wrapper">
<!-- #ifdef H5 -->
<button hover-class="none" @click="wechatLogin" class="bg-green btn1">微信登录</button>
<!-- #endif -->
<!-- #ifdef MP -->
<button hover-class="none" @tap="getUserProfile" class="bg-green btn1">微信登录</button>
<!-- #endif -->
<!-- 关闭强制手机号时,引导已有账号用户去绑定 -->
<!-- #ifdef MP -->
<button hover-class="none" v-if="!requirePhone" @click="goBindAccountLogin" class="btn2">绑定已有账号</button>
<!-- #endif -->
<button hover-class="none" @click="goAccountLogin" class="btn2">账号密码登录</button>
</view>
</view>
<block v-if="isUp">
<mobileLogin :isUp="isUp" @close="maskClose" :authKey="authKey" @wechatPhone="wechatPhone"></mobileLogin>
</block>
<block v-if="isPhoneBox">
<routinePhone :logoUrl="logoUrl" :isPhoneBox="isPhoneBox" @close="bindPhoneClose" :authKey="authKey">
</routinePhone>
</block>
</view>
</template>
<script>
const app = getApp();
let statusBarHeight = uni.getSystemInfoSync().statusBarHeight + 'px';
import mobileLogin from '@/components/login_mobile/index.vue'
import routinePhone from '@/components/login_mobile/routine_phone.vue'
import {
mapGetters
} from "vuex";
import {
getLogo,
getUserPhone
} from '@/api/public';
import {
LOGO_URL,
EXPIRES_TIME,
USER_INFO,
STATE_R_KEY
} from '@/config/cache';
import {
getUserInfo
} from '@/api/user.js'
import Routine from '@/libs/routine';
import wechat from "@/libs/wechat";
import {
switchLoginPage,
openLoginBindPage
} from '@/libs/login';
export default {
data() {
return {
isUp: false,
phone: '',
statusBarHeight: statusBarHeight,
isHome: false,
isPhoneBox: false,
logoUrl: '/static/images/logo.png',
code: '',
authKey: '',
options: '',
userInfo: {},
codeNum: 0,
// 小程序是否强制获取微信手机号true=弹手机号授权false=跳转账号密码绑定)
requirePhone: false,
// 微信授权后待绑定的 key关闭手机号时缓存供「绑定已有账号」使用
pendingBindAuthKey: ''
}
},
components: {
mobileLogin,
routinePhone
},
onLoad(options) {
// #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", () => {
setTimeout(() => {
const scrollHeight = document.documentElement.scrollTop || document.body.scrollTop ||
0;
window.scrollTo(0, Math.max(scrollHeight - 1, 0));
}, 100);
});
const {
code,
state,
scope
} = options;
this.options = options
// 获取确认授权code
this.code = code || ''
//if(!code) location.replace(decodeURIComponent(decodeURIComponent(option.query.back_url)));
if (code && this.options.scope !== 'snsapi_base') {
let spread = app.globalData.spid ? app.globalData.spid : 0;
//公众号授权登录回调 wechatAuth(code, Cache.get("spread"), loginType)
wechat.auth(code, spread).then(res => {
if (res.type === 'register') {
this.authKey = res.key;
this.isUp = true
}
if (res.type === 'login') {
this.$store.commit('LOGIN', {
token: res.token
});
this.$store.commit("SETUID", res.uid);
this.getUserInfo();
this.wechatPhone();
//location.replace(decodeURIComponent(decodeURIComponent(option.query.back_url)));
}
}).catch(error => {});
}
// #endif
let pages = getCurrentPages();
// let prePage = pages[pages.length - 2];
// if (prePage.route == 'pages/order_addcart/order_addcart') {
// this.isHome = true
// } else {
// this.isHome = false
// }
},
methods: {
// #ifdef MP
/**
* 是否强制获取微信手机号(仅 "1" / true 为开启,其余均为关闭)
*/
parseRequirePhoneFlag(value) {
return value === true || value === 1 || String(value) === '1';
},
/**
* 拉取小程序微信登录配置(是否强制获取手机号)
* 后端 system_config.routine_login_require_phone1=开启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: '请先点击上方「微信登录」完成授权'
});
}
openLoginBindPage(this.pendingBindAuthKey);
},
/**
* 新微信用户且关闭强制手机号:跳转绑定页
*/
goWechatBindLogin(authKey) {
this.pendingBindAuthKey = authKey;
openLoginBindPage(authKey);
},
// #endif
goAccountLogin() {
switchLoginPage('/pages/users/login/index');
},
back() {
uni.navigateBack();
},
home() {
uni.switchTab({
url: '/pages/index/index'
})
},
// 弹窗关闭
maskClose() {
this.isUp = false
},
bindPhoneClose(data) {
if (data.isStatus) {
this.isPhoneBox = false
this.$util.Tips({
title: '登录成功',
icon: 'success'
}, {
tab: 3
})
} else {
this.isPhoneBox = false
}
},
// #ifdef MP
// 小程序获取手机号码
getphonenumber(e) {
uni.showLoading({
title: '正在登录中'
});
Routine.getCode()
.then(code => {
this.getUserPhoneNumber(e.detail.encryptedData, e.detail.iv, code);
})
.catch(error => {
uni.$emit('closePage', false)
uni.hideLoading();
});
},
// 小程序获取手机号码回调
getUserPhoneNumber(encryptedData, iv, code) {
getUserPhone({
encryptedData: encryptedData,
iv: iv,
code: code,
type: 'routine',
key: this.authKey
})
.then(res => {
this.$store.commit('LOGIN', {
token: res.data.token
});
this.$store.commit("SETUID", res.data.uid);
this.getUserInfo();
this.$util.Tips({
title: '登录成功',
icon: 'success'
}, {
tab: 3
})
})
.catch(res => {
uni.hideLoading();
that.$util.Tips({
title: res
});
});
},
/**
* 获取个人用户信息
*/
getUserInfo: function() {
let that = this;
getUserInfo().then(res => {
uni.hideLoading();
that.userInfo = res.data
that.$store.commit("UPDATE_USERINFO", res.data);
that.$util.Tips({
title: '登录成功',
icon: 'success'
}, {
tab: 3
})
});
},
getUserProfile() {
let self = this;
uni.showLoading({
title: '正在登录中'
});
// 先确保开关配置已加载,再发起微信登录,避免 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) {
let self = this
let userInfo = res.userInfo;
userInfo.code = code;
userInfo.spread_spid = app.globalData.spid; //获取推广人ID
userInfo.spread_code = app.globalData.code; //获取推广人分享二维码ID
userInfo.avatar = userInfo.userInfo.avatarUrl;
userInfo.city = userInfo.userInfo.city;
userInfo.country = userInfo.userInfo.country;
userInfo.nickName = userInfo.userInfo.nickName;
userInfo.province = userInfo.userInfo.province;
userInfo.sex = userInfo.userInfo.gender;
userInfo.type = 'routine'
Routine.authUserInfo(userInfo.code, userInfo)
.then(res => {
const payload = (res && res.data) ? res.data : (res || {});
self.authKey = payload.key;
if (payload.type === 'register') {
uni.hideLoading();
self.isPhoneBox = false;
// 开关开启:弹出微信手机号授权;关闭:跳转账号密码绑定页
if (self.requirePhone) {
self.isPhoneBox = true;
} else {
self.goWechatBindLogin(payload.key);
}
}
if (payload.type === 'login') {
uni.hideLoading();
self.$store.commit('LOGIN', {
token: payload.token
});
self.$store.commit("SETUID", payload.uid);
self.getUserInfo();
self.$util.Tips({
title: res,
icon: 'success'
}, {
tab: 3
})
}
})
.catch(res => {
uni.hideLoading();
uni.showToast({
title: res,
icon: 'none',
duration: 2000
});
});
},
// #endif
// #ifdef H5
// 获取url后面的参数
getQueryString(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
var reg_rewrite = new RegExp("(^|/)" + name + "/([^/]*)(/|$)", "i");
var r = window.location.search.substr(1).match(reg);
var q = window.location.pathname.substr(1).match(reg_rewrite);
if (r != null) {
return unescape(r[2]);
} else if (q != null) {
return unescape(q[2]);
} else {
return null;
}
},
// 公众号登录
wechatLogin() {
if (!this.code && this.options.scope !== 'snsapi_base') {
this.$wechat.oAuth('snsapi_userinfo', '/pages/users/wechat_login/index');
} else {
// if (this.authKey) {
// this.isUp = true;
// }
this.isUp = true;
}
},
// 输入手机号后的回调
wechatPhone() {
this.$Cache.clear('snsapiKey');
if (this.options.back_url) {
let url = uni.getStorageSync('snRouter');
url = url.indexOf('/pages/index/index') != -1 ? '/' : url;
if (url.indexOf('/pages/users/wechat_login/index') !== -1) {
url = '/';
}
if (!url) {
url = '/pages/index/index';
}
this.isUp = false
uni.showToast({
title: '登录成功',
icon: 'none'
})
setTimeout(res => {
location.href = url
}, 800)
} else {
uni.navigateBack()
}
}
// #endif
}
}
</script>
<style lang="scss">
page {
background: #fff;
height: 100%;
}
.page {
background: #fff;
height: 100%;
}
.wechat_login {
padding: 72rpx 34rpx;
.img image {
width: 100%;
}
.btn-wrapper {
margin-top: 86rpx;
padding: 0 66rpx;
button {
width: 100%;
height: 86rpx;
line-height: 86rpx;
margin-bottom: 40rpx;
border-radius: 120rpx;
font-size: 30rpx;
&.btn1 {
color: #fff;
}
&.btn2 {
color: #666666;
border: 1px solid #666666;
}
}
}
}
.title-bar {
position: relative;
display: flex;
align-items: center;
justify-content: center;
font-size: 36rpx;
}
.icon {
position: absolute;
left: 30rpx;
top: 0;
display: flex;
align-items: center;
justify-content: center;
width: 86rpx;
height: 86rpx;
image {
width: 50rpx;
height: 50rpx;
}
}
</style>