510 lines
13 KiB
Vue
510 lines
13 KiB
Vue
<template>
|
||
<view class="sms-login">
|
||
<view class="top-wrap">
|
||
<view class="back-btn">
|
||
<u-icon name="arrow-left" color="#333333" size="18" @click="handleBack()"></u-icon>
|
||
</view>
|
||
<view class="register" @click="handleRegister()">{{$tt('register.registration')}}</view>
|
||
<image class="img" src="https://xaznkj.cn/app/fastbee1_blue.png" mode="widthFix"></image>
|
||
</view>
|
||
<view class="main-wrap">
|
||
<view>
|
||
<text class="title">{{$tt('smsLogin.smsLogin')}}</text>
|
||
</view>
|
||
<view class="form">
|
||
<u--form :model="loginForm" :rules="rules" ref="form">
|
||
<u-form-item prop="phonenumber" labelWidth="0">
|
||
<u-input v-model="loginForm.phonenumber" clearable :inputBorder="false" border="none"
|
||
:maxlength="11" :placeholder="$tt('register.inputPhone')" prefixIcon="phone"
|
||
prefixIconStyle="font-size: 42rpx;color: rgb(192, 196, 204); margin-left:10rpx"
|
||
placeholderStyle="font-size: 22rpx;"
|
||
:customStyle="{padding:'20rpx 0',backgroundColor:' #fff', borderRradius:' 18rpx'}"></u-input>
|
||
</u-form-item>
|
||
<u-form-item prop="code" labelWidth="0">
|
||
<u-input :placeholder="$tt('register.inputCode')" v-model="loginForm.code" clearable
|
||
border="none"
|
||
:customStyle="{padding:'20rpx 0',backgroundColor:' #fff', borderRradius:' 18rpx'}"
|
||
prefixIcon="integral-fill"
|
||
prefixIconStyle="font-size: 42rpx;color: rgb(192, 196, 204); margin-left:10rpx"
|
||
placeholderStyle="font-size: 22rpx;">
|
||
<template slot="suffix">
|
||
<view style="margin-right: 15rpx;">
|
||
<u-code ref="uCode" @change="codeChange" seconds="60"></u-code>
|
||
<u-button @click="getCode" :text="tips" type="primary" size="small"
|
||
:disabled="loginForm.phonenumber == ''" style="border:none;"></u-button>
|
||
</view>
|
||
</template>
|
||
</u-input>
|
||
</u-form-item>
|
||
</u--form>
|
||
</view>
|
||
|
||
<view style="margin-top: 120rpx;">
|
||
<button class="Login-button" @click="handleLogin()">{{$tt('login.login')}}</button>
|
||
</view>
|
||
<view class="footer-wrap">
|
||
<view class="tipbox">
|
||
<view class="divider-wrap">
|
||
<u-divider class="divider" text="第三方登录" textColor="#999999" lineColor="#D8D8D8"></u-divider>
|
||
</view>
|
||
<view class="otherUser">
|
||
<view class="item">
|
||
<uni-icons style="background-color: #E3EDFF; padding: 18rpx; border-radius: 12rpx;"
|
||
type="chat-filled" size="24" color="#045FFA" @click="gotoSmsLogin()"></uni-icons>
|
||
<text class="text">{{$tt('login.smsLogin')}}</text>
|
||
</view>
|
||
<!-- #ifdef APP-PLUS -->
|
||
<view class="item">
|
||
<uni-icons style="background-color: #E3EDFF; padding: 18rpx; border-radius: 12rpx;"
|
||
type="weixin" size="24" color="#045FFA" @click="handleWeChatLogin()"></uni-icons>
|
||
<text class="text">{{$tt('login.weChat')}}</text>
|
||
</view>
|
||
<!-- #endif -->
|
||
<!-- #ifdef MP-WEIXIN -->
|
||
<view class="item">
|
||
<uni-icons style="background-color: #E3EDFF; padding: 18rpx; border-radius: 12rpx;"
|
||
type="phone-filled" size="24" color="#486FF2"
|
||
@click="handleWeChatOneClickLogin"></uni-icons>
|
||
<text class="text">{{$tt('login.mobileLogin')}}</text>
|
||
</view>
|
||
<!-- #endif -->
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="other-wrap">
|
||
<!-- 微信授权弹出框 -->
|
||
<!-- #ifdef MP-WEIXIN -->
|
||
<view class="one-click-login-pop-wrap">
|
||
<u-popup :show="isShowPop" mode="bottom" :round="10" closeable="true" @close="isShowPop = false">
|
||
<view class="content-wrap">
|
||
<u--image :showLoading="true" src="https://xaznkj.cn/app/fastbee1_blue.png" width="260rpx"
|
||
height="90rpx" customStyle="float:left"></u--image>
|
||
<text class="title">{{$tt("login.welcomeToLogin")}}</text>
|
||
<view class="btn-login">
|
||
<u-button open-type="getPhoneNumber" @getphonenumber="getPhoneNumber"
|
||
@click="isShowPop = false;"
|
||
type="success">{{$tt("login.phoneAuthorization")}}</u-button>
|
||
</view>
|
||
</view>
|
||
</u-popup>
|
||
</view>
|
||
<!-- #endif -->
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import projectConfig from '@/env.config.js';
|
||
import {
|
||
getProfile,
|
||
getSmsCode,
|
||
smsLogin
|
||
} from '@/apis/modules/common.js'
|
||
|
||
export default {
|
||
data() {
|
||
return {
|
||
token: '',
|
||
tips: '',
|
||
codeUrl: '',
|
||
loginForm: {
|
||
phonenumber: '',
|
||
code: '',
|
||
},
|
||
rules: {
|
||
phonenumber: [{
|
||
required: true,
|
||
message: this.$tt('register.inputPhone'),
|
||
trigger: "blur"
|
||
},
|
||
{
|
||
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
|
||
message: this.$tt('smsLogin.correctPhone'),
|
||
trigger: "blur"
|
||
}
|
||
],
|
||
code: [{
|
||
type: 'integer',
|
||
required: true,
|
||
message: this.$tt('login.inputCode'),
|
||
trigger: ['blur', 'change']
|
||
}]
|
||
},
|
||
isShowPop: false,
|
||
};
|
||
},
|
||
methods: {
|
||
//获取短信验证码
|
||
getCode() {
|
||
if (this.$refs.uCode.canGetCode) {
|
||
if (this.validatePhoneNumber(this.loginForm.phonenumber)) {
|
||
if (this.loginForm.phonenumber) {
|
||
uni.showLoading({
|
||
title: this.$tt('smsLogin.obtainSmsCode')
|
||
});
|
||
getSmsCode(this.loginForm.phonenumber).then(res => {
|
||
if (res.code == 200) {
|
||
uni.$u.toast(this.$tt('smsLogin.codeSent'));
|
||
// 通知验证码组件内部开始倒计时
|
||
this.$refs.uCode.start();
|
||
} else {
|
||
uni.$u.toast(res.msg);
|
||
}
|
||
})
|
||
.catch(err => {
|
||
console.log("err catch", err);
|
||
})
|
||
} else {
|
||
uni.$u.toast(this.$tt('register.inputPhone'));
|
||
}
|
||
}
|
||
} else {
|
||
uni.$u.toast(this.$tt('smsLogin.sending'));
|
||
}
|
||
},
|
||
handleBack() {
|
||
uni.navigateBack()
|
||
},
|
||
//登录
|
||
handleLogin() {
|
||
this.$refs.form.validate().then(res => {
|
||
const params = {
|
||
phonenumber: this.loginForm.phonenumber,
|
||
smsCode: this.loginForm.code,
|
||
}
|
||
// 调用短信登录
|
||
smsLogin(params).then(async res => {
|
||
if (res.code == 200) {
|
||
// 存储token和账号
|
||
this.saveToken(res.data);
|
||
this.saveAccount();
|
||
// 获取用户信息
|
||
let profile = await this.getProfile();
|
||
uni.$u.vuex('profile', profile);
|
||
// 跳转主页
|
||
uni.switchTab({
|
||
url: '/pages/tabBar/home/index'
|
||
});
|
||
} else {
|
||
if (res.msg) {
|
||
uni.showToast({
|
||
icon: "none",
|
||
title: res.msg,
|
||
})
|
||
}
|
||
}
|
||
})
|
||
}).catch(errors => {
|
||
uni.$u.toast(this.$tt('login.accontMsg'));
|
||
});
|
||
},
|
||
// 定义校验函数
|
||
validatePhoneNumber(phone) {
|
||
// 正则表达式规则:1开头的10位或者13、14、15、16、17、18、19开头的11位数字
|
||
const regExp =
|
||
/^((1[3-9]\d{9})|((\+?\d{2,3}-)?(13\d{9}|14[57]|15[0-35-9]|16[6]|17[0135678]|18[\d]{9}|\d{3}-\d{8})))$/;
|
||
return regExp.test(phone);
|
||
},
|
||
// 账号登录
|
||
handleAccountLogin() {
|
||
uni.$u.route('/pages/login/index');
|
||
},
|
||
// 获取用户信息
|
||
getProfile() {
|
||
return new Promise((resolve, reject) => {
|
||
getProfile().then(res => {
|
||
resolve(res.data);
|
||
}).catch(err => {
|
||
this.$u.toast(err.msg);
|
||
})
|
||
}).catch((e) => {});
|
||
},
|
||
codeChange(text) {
|
||
this.tips = text;
|
||
text = this.$tt('smsLogin.obtainCode');
|
||
},
|
||
saveToken(token) {
|
||
// 本地缓存存储token
|
||
uni.setStorageSync('token', token);
|
||
// vuex存储token
|
||
uni.$u.vuex('vuex_token', token);
|
||
},
|
||
saveAccount() {
|
||
// 本地缓存存储
|
||
uni.setStorageSync('phonenumber', this.loginForm.phonenumber);
|
||
},
|
||
// 服务协议
|
||
handleService() {
|
||
let title = this.$tt('login.serviceAgreement');
|
||
let url = projectConfig.officialWebUrl + 'service-agreement.html';
|
||
uni.navigateTo({
|
||
url: `/pages/common/webview/index?title=${title}&url=${url}`
|
||
});
|
||
},
|
||
// 隐私政策
|
||
handlePrivacy() {
|
||
let title = this.$tt('login.privacyPolicy');
|
||
let url = projectConfig.officialWebUrl + 'privacy-policy.html';
|
||
uni.navigateTo({
|
||
url: `/pages/common/webview/index?title=${title}&url=${url}`
|
||
});
|
||
},
|
||
openhpLink() {
|
||
uni.navigateTo({
|
||
url: '/pages/common/webview/index?url=http://www.hpiot.cn/'
|
||
});
|
||
},
|
||
// 用户注册
|
||
handleRegister() {
|
||
uni.$u.route('/pagesB/login/register');
|
||
},
|
||
//短信登录
|
||
gotoSmsLogin() {
|
||
uni.$u.route('/pagesB/login/smsLogin');
|
||
},
|
||
// 微信登录
|
||
handleWeChatLogin() {
|
||
let that = this;
|
||
uni.login({
|
||
provider: 'weixin',
|
||
onlyAuthorize: false,
|
||
success: function(loginRes) {
|
||
if (loginRes) {
|
||
console.log('用户授权成功');
|
||
uni.request({
|
||
url: projectConfig.baseUrl + '/wechat/mobileLogin',
|
||
data: {
|
||
//业务服务器通过code + 仅保存在服务器的appsecret参数,向:微信开放平台接口发起网络请求
|
||
code: loginRes.code,
|
||
accessToken: loginRes.authResult.access_token,
|
||
expiresIn: loginRes.authResult.expires_in,
|
||
refreshToken: loginRes.authResult.refresh_token,
|
||
openId: loginRes.authResult.openid,
|
||
unionId: loginRes.authResult.unionid,
|
||
},
|
||
header: {
|
||
language: wx.getStorageSync('language') || 'zh-CN'
|
||
},
|
||
method: 'post',
|
||
success: async res => {
|
||
if (res.data.code == 200) {
|
||
if (res.data.data.token != null) {
|
||
that.saveToken(res.data.data.token);
|
||
// 获取用户信息
|
||
let profile = await that.getProfile();
|
||
uni.$u.vuex('profile', profile);
|
||
// 跳转主页面
|
||
wx.switchTab({
|
||
url: '/pages/tabBar/home/index'
|
||
})
|
||
} else {
|
||
//跳转绑定页面
|
||
uni.navigateTo({
|
||
url: '/pagesB/login/bindLogin?bindId=' +
|
||
res
|
||
.data.data.bindId,
|
||
})
|
||
}
|
||
} else {
|
||
uni.showToast({
|
||
icon: "none",
|
||
mask: true,
|
||
title: res.data.msg,
|
||
duration: 3000,
|
||
})
|
||
}
|
||
},
|
||
fail(err) {
|
||
console.log(err)
|
||
}
|
||
});
|
||
}
|
||
},
|
||
fail(err) {
|
||
console.log(err)
|
||
}
|
||
})
|
||
},
|
||
// 微信一键登录
|
||
handleWeChatOneClickLogin() {
|
||
this.isShowPop = true;
|
||
},
|
||
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
page {
|
||
height: 100%;
|
||
}
|
||
|
||
.sms-login {
|
||
display: flex;
|
||
flex-direction: column;
|
||
padding-top: var(--status-bar-height);
|
||
height: 100vh;
|
||
background-image: linear-gradient(45deg,
|
||
rgba(216, 216, 216, 0.3) 0,
|
||
rgba(225, 225, 225, 0) 100%);
|
||
|
||
.top-wrap {
|
||
position: relative;
|
||
display: flex;
|
||
|
||
.back-btn {
|
||
position: absolute;
|
||
top: 70rpx;
|
||
left: 46rpx;
|
||
}
|
||
|
||
.register {
|
||
position: absolute;
|
||
// #ifdef MP-WEIXIN
|
||
top: 140rpx;
|
||
// #endif
|
||
// #ifndef MP-WEIXIN
|
||
top: 70rpx;
|
||
// #endif
|
||
right: 46rpx;
|
||
line-height: 36rpx;
|
||
font-size: 28rpx;
|
||
font-weight: 400;
|
||
}
|
||
|
||
.img {
|
||
margin: 0 auto;
|
||
width: 338rpx;
|
||
margin-top: 236rpx;
|
||
}
|
||
}
|
||
|
||
.main-wrap {
|
||
padding-left: 80rpx;
|
||
padding-right: 80rpx;
|
||
margin-top: 142rpx;
|
||
flex: 1 auto;
|
||
overflow-y: auto;
|
||
display: flex;
|
||
flex-direction: column;
|
||
|
||
.title {
|
||
font-size: 40rpx;
|
||
letter-spacing: 0.6rpx;
|
||
font-family: PingFang SC-Heavy;
|
||
font-weight: 400;
|
||
}
|
||
|
||
.form {
|
||
margin-top: 64rpx;
|
||
}
|
||
|
||
.Login-button {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
height: 98rpx;
|
||
border-radius: 18rpx;
|
||
color: #fff;
|
||
background-color: #486FF2;
|
||
font-weight: 400;
|
||
font-size: 32rpx;
|
||
letter-spacing: 0.6rpx;
|
||
}
|
||
|
||
.footer-wrap {
|
||
margin-top: auto;
|
||
margin-bottom: 38px;
|
||
|
||
.tipbox {
|
||
text-align: center;
|
||
|
||
.divider-wrap {
|
||
margin-bottom: 38rpx;
|
||
padding: 0 112rpx;
|
||
}
|
||
}
|
||
|
||
.otherUser {
|
||
display: flex;
|
||
flex-direction: row;
|
||
justify-content: center;
|
||
align-items: center;
|
||
gap: 10px;
|
||
|
||
.item {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
width: 134rpx;
|
||
|
||
.text {
|
||
margin-top: 10rpx;
|
||
letter-spacing: 0.6rpx;
|
||
font-size: 20rpx;
|
||
font-weight: 400;
|
||
}
|
||
}
|
||
}
|
||
|
||
.txt {
|
||
font-size: 28rpx;
|
||
color: #cbcbcb;
|
||
}
|
||
|
||
.item-wrap {
|
||
background-color: #eaeaea;
|
||
width: 50px;
|
||
height: 50px;
|
||
border-radius: 50%;
|
||
display: flex;
|
||
flex-direction: row;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin: 10rpx 20rpx;
|
||
}
|
||
|
||
.clause {
|
||
font-size: 28rpx;
|
||
display: inline-block;
|
||
vertical-align: middle;
|
||
|
||
.service,
|
||
.privacy {
|
||
color: #486FF2;
|
||
}
|
||
}
|
||
}
|
||
|
||
.other-wrap {
|
||
.one-click-login-pop-wrap {
|
||
.content-wrap {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
margin-top: 90rpx;
|
||
|
||
.title {
|
||
margin-top: 30rpx;
|
||
font-size: 36rpx;
|
||
}
|
||
|
||
.btn-login {
|
||
margin-top: 100rpx;
|
||
margin-bottom: 60rpx;
|
||
width: 320rpx;
|
||
border-radius: 20rpx
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
::v-deep .u-form-item__body__right__message[data-v-067e4733] {
|
||
width: 280rpx;
|
||
display: flex;
|
||
margin-left: auto;
|
||
}
|
||
}
|
||
}
|
||
</style> |