Xazn-app/pagesB/login/smsLogin.vue

510 lines
13 KiB
Vue
Raw Normal View History

2025-05-22 16:37:43 +08:00
<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>
2025-07-03 08:57:13 +08:00
<image class="img" src="https://xaznkj.cn/app/fastbee1_blue.png" mode="widthFix"></image>
2025-05-22 16:37:43 +08:00
</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">
2025-07-03 08:57:13 +08:00
<u--image :showLoading="true" src="https://xaznkj.cn/app/fastbee1_blue.png" width="260rpx"
2025-05-22 16:37:43 +08:00
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>