243 lines
6.5 KiB
Vue
243 lines
6.5 KiB
Vue
<template>
|
||
<view class="login-wrap">
|
||
<view class="top-wrap">
|
||
<image src="/static/yack.png" mode="widthFix" style="width: 500rpx;"></image>
|
||
<view class="logo-text">{{$tt('common.fastbee')}}</view>
|
||
</view>
|
||
<view class="main-wrap">
|
||
<u--text size="18" type="info" bold margin="20rpx 0" :text="$tt('smsLogin.smsLogin')"></u--text>
|
||
<u--form :model="loginForm" :rules="rules" ref="form">
|
||
<u-form-item prop="phonenumber" labelWidth="0" borderBottom>
|
||
<u--input v-model="loginForm.phonenumber" :placeholder="$tt('register.inputPhone')" clearable
|
||
border="none" prefixIcon="phone"
|
||
prefixIconStyle="font-size: 44rpx; color: rgb(192, 196, 204); margin-right: 10rpx"
|
||
placeholderStyle="font-size: 24rpx;"></u--input>
|
||
</u-form-item>
|
||
<u-form-item prop="code" labelWidth="0" borderBottom>
|
||
<u-input :placeholder="$tt('register.inputCode')" v-model="loginForm.code" clearable border="none"
|
||
prefixIcon="integral-fill"
|
||
prefixIconStyle="font-size: 44rpx; color: rgb(192, 196, 204); margin-right: 10rpx"
|
||
placeholderStyle="font-size: 24rpx;">
|
||
<template slot="suffix">
|
||
<u-code ref="uCode" @change="codeChange" seconds="60"></u-code>
|
||
<u-button @click="getCode" :text="tips" type="primary" size="small"
|
||
:disabled="this.loginForm.phonenumber == ''" style="border:none;"></u-button>
|
||
</template>
|
||
</u-input>
|
||
</u-form-item>
|
||
</u--form>
|
||
<view style="margin-top: 50rpx;">
|
||
<u-button style="height: 90rpx; width: 650rpx;" shape="circle" type="primary"
|
||
:text="$tt('smsLogin.login')" @click="handleLogin()"></u-button>
|
||
</view>
|
||
<view class="register-wrap">
|
||
<view class="now-btn">
|
||
<u--text :text="$tt('smsLogin.accountLogin')" size="13px" @click="handleAccountLogin"></u--text>
|
||
</view>
|
||
<view class="now-btn">
|
||
<u--text text="|" size="13px"></u--text>
|
||
</view>
|
||
<view style="margin:0 0 0 20rpx;">
|
||
<u--text :text="$tt('login.HuapuIoT')" size="13px" color="#000" @click="openhpLink"></u--text>
|
||
</view>
|
||
</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']
|
||
}]
|
||
},
|
||
};
|
||
},
|
||
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'));
|
||
}
|
||
},
|
||
//登录
|
||
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: `/pagesA/common/webview/index?title=${title}&url=${url}`
|
||
});
|
||
},
|
||
// 隐私政策
|
||
handlePrivacy () {
|
||
let title = this.$tt('login.privacyPolicy');
|
||
let url = projectConfig.officialWebUrl + 'privacy-policy.html';
|
||
uni.navigateTo({
|
||
url: `/pagesA/common/webview/index?title=${title}&url=${url}`
|
||
});
|
||
},
|
||
openhpLink () {
|
||
uni.navigateTo({
|
||
url: '/pagesA/common/webview/index?url=https://ycdat.cn/'
|
||
});
|
||
}
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
page {
|
||
height: 100%;
|
||
}
|
||
|
||
.login-wrap {
|
||
height: 100%;
|
||
|
||
.top-wrap {
|
||
height: 510rpx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
.logo-text {
|
||
margin-top: 16rpx;
|
||
font-size: 32rpx;
|
||
color: #333;
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
|
||
.main-wrap {
|
||
padding: 0 40rpx;
|
||
|
||
.register-wrap {
|
||
margin-top: 40rpx;
|
||
display: flex;
|
||
justify-content: center;
|
||
text-align: center;
|
||
|
||
.now-btn {
|
||
margin-left: 20rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style> |