Xazn-app/pagesB/login/smsLogin.vue
2025-05-22 16:37:43 +08:00

510 lines
13 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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://iot-xcwl.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://iot-xcwl.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>