JuHua-app/pages/login/index.vue
2024-12-09 14:16:57 +08:00

561 lines
14 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="login-wrap">
<view class="top-wrap">
<image src="../../static/538.png" mode="widthFix" style="width: 500rpx;"></image>
</view>
<view class="main-wrap">
<u--form :model="loginForm" :rules="rules" ref="form" labelWidth="31">
<u-form-item prop="username" borderBottom>
<uni-easyinput v-model="loginForm.username" clearable :inputBorder="false"
:placeholder="$tt('login.inputUserName')" prefixIcon="person"
prefixIconStyle="font-size: 44rpx; margin-right: 10rpx"></uni-easyinput>
</u-form-item>
<u-form-item prop="password" borderBottom>
<uni-easyinput prefixIcon="locked" prefixIconStyle="font-size: 44rpx; margin-right: 10rpx"
type="password" :inputBorder="false" v-model="loginForm.password"
:placeholder="$tt('login.inputPassword')"></uni-easyinput>
</u-form-item>
<u-form-item prop="code" borderBottom>
<!-- 注意由于兼容性差异如果需要使用前后插槽nvue下需使用u--input非nvue下需使用u-input -->
<!-- 验证码 -->
<uni-easyinput :placeholder="$tt('login.inputCode')" v-model="loginForm.code" :inputBorder="false"
prefixIcon="checkbox" prefixIconStyle="font-size: 44rpx; margin-right: 10rpx">
<template slot="right">
<u--image :src="codeUrl" width="240rpx" height="60rpx" @click="getCode"></u--image>
</template>
</uni-easyinput>
</u-form-item>
<!-- 记住密码 -->
<view prop="rememberMe" style="display: flex; justify-content:flex-end; padding: 20rpx;">
<view style="font-size: 13px;">
<u-checkbox-group @change="handleRememberCheckbox">
<label>
<u-checkbox :checked="loginForm.rememberMe" style="transform:scale(0.8)" />
</label>
<text>
{{$tt('login.remember')}}
</text>
</u-checkbox-group>
</view>
</view>
<view style="margin-top: 50rpx;">
<u-button style="height: 90rpx; width: 650rpx;" shape="circle" type="primary"
:text="$tt('login.login')" @click="handleLogin()"></u-button>
</view>
</u--form>
<view class="footer-wrap">
<view class="tipbox">
<!-- #ifdef APP-PLUS || MP-WEIXIN -->
<view class="txt">
{{$tt('login.other')}}
</view>
<!-- #endif -->
<view class="otherUser">
<!-- #ifdef APP-PLUS -->
<uni-icons style="background-color: #e7e7e7; padding: 10rpx; border-radius: 50%; margin: 20rpx;"
type="weixin"  size="24"  color="#3c9cff" @click="handleWeChatLogin()"></uni-icons>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<uni-icons style="background-color: #e7e7e7; padding: 10rpx; border-radius: 50%; margin: 20rpx;"
type="phone-filled"  size="24"  color="#3c9cff"
@click="handleWeChatOneClickLogin"></uni-icons>
<!-- #endif -->
</view>
</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="/static/logo_title.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>
</template>
<script>
import { mapState, mapMutations } from 'vuex';
import projectConfig from '@/env.config.js';
import { getProfile } from '@/apis/modules/common.js'
import { encrypt, decrypt } from '@/utils/jsencrypt.js'
export default {
data () {
return {
token: '',
codeUrl: '',
isClause: false,
show: false,
systemLocale: '',
applicationLocale: '',
columns: [
[{
text: this.$tt('locale.en-US'),
code: 'en-US'
},
{
text: this.$tt('locale.zh-CN'),
code: 'zh-CN'
},
]
],
value: 'English',
loginForm: {
username: '',
password: '',
rememberMe: false,
code: '',
uuid: '',
},
rules: {
username: {
type: 'string',
min: 2,
max: 20,
required: true,
message: this.$tt('login.inputUserName'),
trigger: ['blur', 'change']
},
password: {
type: 'string',
required: true,
min: 5,
max: 20,
message: this.$tt('login.inputPassword'),
trigger: ['blur', 'change']
},
code: {
type: 'integer',
required: true,
message: this.$tt('login.inputCode'),
trigger: ['blur', 'change']
}
},
isShowPop: false,
};
},
onLoad () {
this.loadSelectedLanguage();
},
mounted () {
this.getToken();
if (this.token != '' && this.token != null) {
// 跳转主页
uni.switchTab({
url: '/pages/tabBar/home/index'
});
} else {
this.getCode();
this.getAccount();
}
},
methods: {
loadSelectedLanguage () {
// 获取之前保存的语言设置
const selectedLanguage = wx.getStorageSync('language');
// 如果获取到了,使用该语言设置
if (selectedLanguage === 'zh-CN') {
this.applicationLocale = 'zh-CN';
this.value = '简体中文';
} else if (selectedLanguage === 'en-US') {
this.applicationLocale = 'en-US';
this.value = 'English';
} else {
// 如果没有获取到,使用默认设置
this.applicationLocale = 'zh-CN'; // 默认设置为中文
this.$i18n.locale = this.applicationLocale;
this.value = '简体中文';
}
},
onLocaleChange () {
this.show = true;
},
close () {
this.show = false
},
cancel () {
this.show = false
},
confirm (e) {
this.show = false;
this.value = e.value[0].text;
this.$i18n.locale = e.value[0].code;
uni.setLocale(e.value[0].code);
wx.setStorageSync('language', e.value[0].code)
},
change (e) {
// console.log('change', e)
},
handleLogin () {
this.$refs.form.validate().then(res => {
// if (!this.isClause) {
// uni.showToast({
// icon: 'none',
// title: this.$tt('login.readAndCheckTheAgreement'),
// });
// return;
// }
// 调用登录
this.$api.common.login(this.loginForm).then(async res => {
if (res.code == 200) {
// 存储token和账号
this.saveToken(res.token);
this.saveAccount();
// 获取用户信息
let profile = await this.getProfile();
uni.$u.vuex('profile', profile);
// 跳转主页
uni.reLaunch({
url: '/pages/tabBar/home/index'
});
} else {
if (res.msg) {
uni.showToast({
icon: "none",
title: res.msg,
complete: (res) => {
setTimeout(() => {
this.getCode();
}, 1500);
}
})
}
}
})
}).catch(errors => {
uni.$u.toast(this.$tt('login.accontMsg'));
});
},
handletestLogin () {
this.loginForm.username = "fastbee"
this.loginForm.password = "123456"
},
// 微信登录
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,
},
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;
},
// 获取验证码
getCode () {
this.$api.common.captchaImage(true).then(res => {
this.codeUrl = 'data:image/gif;base64,' + res.img;
this.loginForm.uuid = res.uuid;
this.loginForm.code = '';
})
.catch(err => {
this.$u.toast(err.msg);
});
},
// 用户注册
handleRegister () {
uni.$u.route('/pagesB/login/register');
},
//短信登录
gotoSmsLogin () {
uni.$u.route('/pagesB/login/smsLogin');
},
// 获取用户信息
getProfile () {
return new Promise((resolve, reject) => {
getProfile().then(res => {
resolve(res.data);
}).catch(err => {
this.$u.toast(err.msg);
})
});
},
saveToken (token) {
// 本地缓存存储token
uni.setStorageSync('token', token);
// vuex存储token
uni.$u.vuex('vuex_token', token);
},
getToken () {
// 本地缓存获取token
this.token = uni.getStorageSync('token');
// vuex存储token
uni.$u.vuex('vuex_token', this.token);
},
// 本地缓存存储
saveAccount () {
if (this.loginForm.rememberMe) {
uni.setStorageSync('username', this.loginForm.username);
uni.setStorageSync('password', encrypt(this.loginForm.password));
uni.setStorageSync('rememberMe', this.loginForm.rememberMe)
} else {
uni.removeStorageSync('username');
uni.removeStorageSync('password');
uni.removeStorageSync('rememberMe');
}
},
// 本地缓存获取
getAccount () {
let username = uni.getStorageSync('username');
let password = uni.getStorageSync('password');
let rememberMe = uni.getStorageSync('rememberMe');
if (username && username != '') {
this.loginForm.username = username;
}
if (password && password != '') {
this.loginForm.password = decrypt(password);
}
if (rememberMe != '') {
this.loginForm.rememberMe = rememberMe;
}
},
//微信小程序登录获取手机号
getPhoneNumber (e) {
let that = this;
wx.login({
success (res) {
if (e.detail.code && res.code) {
console.log('用户授权成功');
//发起网络请求
wx.request({
url: projectConfig.baseUrl + '/wechat/miniLogin',
data: {
code: res.code,
phoneCode: e.detail.code,
},
method: 'post',
success: async res => {
if (res.data.code == 200) {
// 存储token和账号
const token = wx.setStorageSync('token', res.data.data.token)
that.saveToken(res.data.data.token);
// 获取用户信息
let profile = await that.getProfile();
uni.$u.vuex('profile', profile);
// 跳转主页
wx.switchTab({
url: '/pages/tabBar/home/index'
});
} else {
wx.showToast({
icon: "none",
mask: true,
title: res.data.msg,
duration: 3000,
})
}
},
})
} else {
console.log('用户拒绝授权');
}
}
})
},
// 服务协议
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}`
});
},
//记住密码
handleRememberCheckbox (e) {
this.loginForm.rememberMe = !this.loginForm.rememberMe
},
// 勾选协议
handleClauseCheckbox (e) {
this.isClause = !this.isClause;
},
openhpLink () {
uni.navigateTo({
url: '/pages/common/webview/index?url=http://www.hpiot.cn/'
});
}
}
};
</script>
<style lang="scss" scoped>
page {
height: 100%;
}
.copyright {
font-size: 16rpx;
margin-top: 20rpx;
}
.login-wrap {
height: 100%;
.top-wrap {
height: 510rpx;
display: flex;
align-items: center;
justify-content: center;
}
.main-wrap {
padding: 0 40rpx;
.register-wrap {
margin-top: 40rpx;
display: flex;
justify-content: center;
text-align: center;
.now-btn {
margin-left: 20rpx;
}
}
.footer-wrap {
position: fixed;
bottom: 60rpx;
left: 0;
right: 0;
.tipbox {
text-align: center;
}
.otherUser {
margin-top: 40rpx;
display: flex;
justify-content: center;
}
.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;
.check_text {}
.service,
.privacy {
color: #3c9cff;
}
}
}
}
.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
}
}
}
}
}
</style>