login.vue 6.65 KB
<template>
	<view class="login-page" :style="{backgroundImage:setLoginBg}">
		<!-- 公共组件-每个页面必须引入 -->
		<public-module></public-module>
		<view class="u-flex login-main">
			<view class="content">
				<view class="hello login-text-muted">您好,</view>
				<view style="width: 587rpx;" class="text-clip hello-welcome login-text-muted">欢迎来到{{setHeadTitle}}!
				</view>
			</view>
		</view>
		<view class="login-body">
			<view class="login-phone">
				<view class="form-row u-flex">
					<u-input :adjust-position="false" v-model="loginForm.username" type="text" placeholder="请输入登录账号"
						border="bottom" />
				</view>
				<view class="form-row u-flex">
					<u-input :adjust-position="false" v-model="loginForm.password" :password="showPassword"
						placeholder="请输入登录密码" border="bottom">
						<template slot="suffix">
							<view @click="showPasswordMode" style="padding: 10rpx">
								<u-icon width="18" height="14" :name="passwordIcon"></u-icon>
							</view>
						</template>
					</u-input>
				</view>
				<button class="submit" size="default" @click="onSubmitFunc">
					<text class="text">登录</text>
				</button>
				<view class="u-flex row-item">
					<view class="row-phone login-text-gray" @click="openCodeFunc">手机验证码登录</view>
					<view class="row-reset login-text-gray" @click="findPassrordFunc">忘记密码</view>
				</view>
				<view class="u-flex link-login">
					<!-- #ifdef MP-WEIXIN -->
					<view class="link-text login-text-gray">第三方账号登录</view>
					<view style="height: 20rpx"></view>
					<button class="link-image" @tap="handleWenxinAuthorization">
						<image class="image" src="/static/weixin.png" mode="aspectFill"></image>
					</button>
					<!-- #endif -->
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	import {mapMutations,mapActions,mapState} from "vuex";
	import api from '@/api'
	import {loginPasswordReg,useReLaunch,useShowToast,useShowModal,useNavigateTo} from '@/plugins/utils.js'

	export default {
		data() {
			return {
				loginForm: {
					username: "",
					password: "",
				},
				showPassword: true,
				code: "",
				openid: "",
				mpOwnConfig: {},
				defaultLogo: "/static/login.png",
			};
		},
		onLoad() {
			//#ifdef MP-WEIXIN
			wx.login({
				success: (res) => {
					if (!res.code) return
					this.code = res.code;
				},
			});
			//#endif
			uni.setStorageSync('getConfiguration', {
				isConfiguration: false
			});
			this.getPlateForm();
		},
		computed: {
			passwordIcon() {
				return this.showPassword ? '/static/eye-hide.png' : '/static/eye.png'
			},
			setHeadTitle() {
				return this.mpOwnConfig.name !== undefined ? this.mpOwnConfig.name : "ThingsKit"
			},
			setLoginBg() {
				return 'url(' + (this.mpOwnConfig.bg !== undefined ? this.mpOwnConfig.bg : `${this.defaultLogo}`) + ')'
			}
		},
		onShow() {
			uni.setStorageSync('getConfiguration', {
				isConfiguration: false
			});
		},
		methods: {
			...mapState(["plateInfo"]),
			...mapMutations(["setUserInfo", "setPlateInfo"]),
			...mapActions(["updateBadgeTotal"]),
			//获取平台定制信息
			async getPlateForm() {
				const res = await api.loginApi.getPlateCustomApi()
				if (!res) return
				this.mpOwnConfig = {
					bg: res.background,
					logo: res.logo,
					name: res.name,
				};
			},
			saveLoginInfo(res, isThirdLoginAndNoDind, isThirdLogin, toastText) {
				let tokenInfo = {
					refreshToken: res.refreshToken,
					isToken: res.token,
				};
				let userInfo = {
					...tokenInfo,
					token: true, //token用于判断是否登录
					isThirdLoginAndNoDind, //用于判断是否是第三方登录并且不需要绑定账号
					isThirdLogin, //用于判断是否是第三方登录并且需要绑定账号
					thirdUserId: res.thirdUserId,
				};
				//设置全局变量openId
				getApp().globalData.openId = res.thirdUserId;
				if (userInfo.token) {
					this.setUserInfo(userInfo);
				}
				useShowToast(toastText).then(async (res) => {
					this.saveUserInfo();
					await this.getAlarmTotalData();
					useReLaunch("../../pages/index/index")
				});
			},
			//微信授权登录
			//#ifdef MP-WEIXIN
			handleWenxinAuthorization() {
				wx.getUserProfile({
					desc: "微信第三方授权",
					success: async (reswenxin) => {
						if (
							reswenxin.errMsg === "getUserProfile:ok" &&
							reswenxin.encryptedData
						) {
							//获取用户信息
							let wenxinUserInfo = {
								avatarUrl: reswenxin.userInfo.avatarUrl,
								thirdUserId: this.openid,
							};
							const res = await api.loginApi.getThirdLoginApi(this.code)
							if (!res.token && res.thirdUserId) {
								//需要进行三方绑定
								let userInfo = {
									isThirdLogin: true, //用于判断是否是第三方登录并且需要绑定账号
									avatar: wenxinUserInfo.avatarUrl,
									thirdUserId: res.thirdUserId,
								};
								this.setUserInfo(userInfo);
								//设置全局变量openId
								getApp().globalData.openId = res.thirdUserId;
								useReLaunch("/pages/index/index")
							} else {
								// 不需要绑定,直接第三方登录使用
								this.saveLoginInfo(res, true, null, "第三方账号登录成功")
							}
						}
					},
					fail: (res) => {
						//拒绝授权
						return;
					},
				});
			},
			//#endif
			async saveUserInfo() {
				const userInfoRes = await api.loginApi.setUserInfoApi()
				const plateInfoRes = await api.loginApi.setPlateInfoApi()
				Promise.all([userInfoRes, plateInfoRes]).then(res => {
					this.setUserInfo(res[0])
					this.setPlateInfo(res[1])
				})
			},
			async getAlarmTotalData() {
				const res = await api.loginApi.getAlarmTotalApi()
				if (!res) return
				this.updateBadgeTotal(res.totalAlarm?.activedAlarm);
			},
			async onSubmitFunc() {
				const validateValue = Object.values(this.loginForm)
				if (!validateValue[0]) return uni.$u.toast("请输入登录账号~");
				if (!validateValue[1]) return uni.$u.toast("请输入登录密码~");
				if (!loginPasswordReg.test(validateValue[1])) return useShowModal(
					"密码格式不正确(至少一个大写英文字母、至少一个小写英文字母、至少一位数字、至少一个特殊字符、最少八个字符)~", )
				const res = await api.loginApi.postLoginApi(this.loginForm)
				if (res) {
					// 储存登录信息
					this.saveLoginInfo(res, false, false, "登录成功~")
				}
			},
			openCodeFunc() {
				useNavigateTo("../other/code")
			},
			findPassrordFunc() {
				useNavigateTo("../other/find-password")
			},
			showPasswordMode() {
				this.showPassword = !this.showPassword;
			},
		},
	};
</script>

<style lang="scss" scoped>
	@import "./static/login.scss";

	/deep/ button {
		background: rgba(0, 0, 0, 0);
	}
</style>