|
|
@@ -0,0 +1,403 @@
|
|
|
+<template>
|
|
|
+ <div class="login-container">
|
|
|
+ <div class="shadow">
|
|
|
+ <div class="img">
|
|
|
+ <img src="../../assets/images/iconbg.png" alt="" />
|
|
|
+ </div>
|
|
|
+ <div class="form">
|
|
|
+ <img src="../../assets/images/1ogo.png" alt="" />
|
|
|
+ <div class="title">车辆大屏管理系统</div>
|
|
|
+ <div class="login">登录</div>
|
|
|
+ <div class="name">
|
|
|
+ <el-form
|
|
|
+ ref="loginForm"
|
|
|
+ :model="loginForm"
|
|
|
+ :rules="loginRules"
|
|
|
+ class="login-form"
|
|
|
+ >
|
|
|
+ <el-form-item prop="username">
|
|
|
+ <span class="svg-container">
|
|
|
+ <div class="user"></div>
|
|
|
+ </span>
|
|
|
+ <el-input
|
|
|
+ v-model="loginForm.username"
|
|
|
+ placeholder="请输入账号"
|
|
|
+ type="text"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item prop="password">
|
|
|
+ <span class="svg-container">
|
|
|
+ <div class="password"></div>
|
|
|
+ </span>
|
|
|
+ <el-input
|
|
|
+ ref="password"
|
|
|
+ v-model="loginForm.password"
|
|
|
+ :type="passwordType"
|
|
|
+ placeholder="请输入密码"
|
|
|
+ @keyup.enter.native="handleLogin"
|
|
|
+ />
|
|
|
+ <span class="show-pwd" @click="showPwd">
|
|
|
+ <div
|
|
|
+ :class="passwordType === 'password' ? 'eye_close' : 'eye'"
|
|
|
+ ></div>
|
|
|
+ </span>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-button
|
|
|
+ :loading="loading"
|
|
|
+ type="primary"
|
|
|
+ style="width: 100%; margin-bottom: 30px"
|
|
|
+ @click="handleLogin"
|
|
|
+ >登录</el-button
|
|
|
+ >
|
|
|
+ </el-form>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { JSEncrypt } from "jsencrypt";
|
|
|
+export default {
|
|
|
+ name: "Login",
|
|
|
+ data() {
|
|
|
+ // 自定义校验规则
|
|
|
+ const validateUsername = (rule, value, callback) => {
|
|
|
+ if (!value) {
|
|
|
+ callback(new Error("请输入用户名"));
|
|
|
+ } else {
|
|
|
+ callback();
|
|
|
+ }
|
|
|
+ };
|
|
|
+ const validatePassword = (rule, value, callback) => {
|
|
|
+ if (value.length < 1) {
|
|
|
+ callback(new Error("密码不少于1位"));
|
|
|
+ } else {
|
|
|
+ callback();
|
|
|
+ }
|
|
|
+ };
|
|
|
+ return {
|
|
|
+ // 表格绑定数据
|
|
|
+ loginForm: {
|
|
|
+ username: "",
|
|
|
+ password: "",
|
|
|
+ token: "",
|
|
|
+ },
|
|
|
+ // 校验规则
|
|
|
+ loginRules: {
|
|
|
+ username: [
|
|
|
+ { required: true, trigger: "blur", validator: validateUsername },
|
|
|
+ ],
|
|
|
+ password: [
|
|
|
+ { required: true, trigger: "blur", validator: validatePassword },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ // 加载中效果
|
|
|
+ loading: false,
|
|
|
+ // 密码显示隐藏控制
|
|
|
+ passwordType: "password",
|
|
|
+ redirect: undefined,
|
|
|
+ };
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ // 监听路由地址变化
|
|
|
+ $route: {
|
|
|
+ handler: function (route) {
|
|
|
+ this.redirect = route.query && route.query.redirect;
|
|
|
+ },
|
|
|
+ immediate: true,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ // 密码显示隐藏控制函数
|
|
|
+ showPwd() {
|
|
|
+ if (this.passwordType === "password") {
|
|
|
+ this.passwordType = "";
|
|
|
+ } else {
|
|
|
+ this.passwordType = "password";
|
|
|
+ }
|
|
|
+ // 重新渲染后使密码框聚焦
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.$refs.password.focus();
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 登录函数
|
|
|
+ handleLogin() {
|
|
|
+ // 校验用户名密码是否符合验证规则
|
|
|
+ this.$refs.loginForm.validate((valid) => {
|
|
|
+ // 符合验证规则
|
|
|
+ if (valid) {
|
|
|
+ this.loading = true;
|
|
|
+ this.loginForm.token = this.getPassword(8);
|
|
|
+ // this.API.role
|
|
|
+ // .adminlogin({
|
|
|
+ // admin_account: this.loginForm.username,
|
|
|
+ // admin_password: this.loginForm.password,
|
|
|
+ // })
|
|
|
+ // .then((res) => {
|
|
|
+ // console.log(res);
|
|
|
+ // });
|
|
|
+ this.$store
|
|
|
+ .dispatch("user/login", this.loginForm)
|
|
|
+ .then(() => {
|
|
|
+ this.$message({
|
|
|
+ message: "登录成功",
|
|
|
+ type: "success",
|
|
|
+ });
|
|
|
+ this.$router.push({ path: this.redirect || "/car" });
|
|
|
+ this.loading = false;
|
|
|
+ })
|
|
|
+ .catch(() => {
|
|
|
+ this.$message.error("登录失败,用户名或密码错误");
|
|
|
+ this.loading = false;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ // 不符合验证规则
|
|
|
+ else {
|
|
|
+ console.log("提交失败!!");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ getPassword(num) {
|
|
|
+ // 定义一个空数组保存我们的密码
|
|
|
+ let passArrItem = [];
|
|
|
+
|
|
|
+ // 定义获取密码成员的方法
|
|
|
+ const getNumber = () => Math.floor(Math.random() * 10); // 0~9的数字
|
|
|
+ const getUpLetter = () =>
|
|
|
+ String.fromCharCode(Math.floor(Math.random() * 26) + 65); // A-Z
|
|
|
+ const getLowLetter = () =>
|
|
|
+ String.fromCharCode(Math.floor(Math.random() * 26) + 97); // a-z
|
|
|
+
|
|
|
+ // 将获取成员的方法保存在一个数组中方便用后面生成的随机index取用
|
|
|
+ const passMethodArr = [getNumber, getUpLetter, getLowLetter];
|
|
|
+
|
|
|
+ // 随机index
|
|
|
+ const getIndex = () => Math.floor(Math.random() * 3);
|
|
|
+
|
|
|
+ // 从0-9,a-z,A-Z中随机获取一项
|
|
|
+ const getPassItem = () => passMethodArr[getIndex()]();
|
|
|
+
|
|
|
+ // 不多解释
|
|
|
+ Array(num - 3)
|
|
|
+ .fill("")
|
|
|
+ .forEach(() => {
|
|
|
+ passArrItem.push(getPassItem());
|
|
|
+ });
|
|
|
+
|
|
|
+ const confirmItem = [getNumber(), getUpLetter(), getLowLetter()];
|
|
|
+
|
|
|
+ // 加上我们确认的三项,从而使生成的密码,大写字母、小写字母和数字至少各包含一个
|
|
|
+ passArrItem.push(...confirmItem);
|
|
|
+
|
|
|
+ // 转为字符串返回
|
|
|
+ return passArrItem.join("");
|
|
|
+ },
|
|
|
+ },
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss">
|
|
|
+/* 修复input 背景不协调 和光标变色 */
|
|
|
+
|
|
|
+$bg: #283443;
|
|
|
+$light_gray: #fff;
|
|
|
+$cursor: #fff;
|
|
|
+
|
|
|
+@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
|
|
|
+ .login-container .el-input input {
|
|
|
+ color: $bg;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* 重置 element-ui css */
|
|
|
+.login-container {
|
|
|
+ .el-input {
|
|
|
+ display: inline-block;
|
|
|
+ height: 47px;
|
|
|
+ width: 85%;
|
|
|
+
|
|
|
+ input {
|
|
|
+ background: transparent;
|
|
|
+ border: 0px;
|
|
|
+ -webkit-appearance: none;
|
|
|
+ border-radius: 0px;
|
|
|
+ padding: 12px 5px 12px 15px;
|
|
|
+ color: $bg;
|
|
|
+ height: 47px;
|
|
|
+ caret-color: $bg;
|
|
|
+
|
|
|
+ &:-webkit-autofill {
|
|
|
+ box-shadow: 0 0 0px 1000px #e5e5e5 inset !important;
|
|
|
+ -webkit-text-fill-color: $bg !important;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-form-item {
|
|
|
+ border: 1px solid rgba(255, 255, 255, 0.1);
|
|
|
+ background: rgba(0, 0, 0, 0.1);
|
|
|
+ border-radius: 5px;
|
|
|
+ color: #454545;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+$bg: #2d3a4b;
|
|
|
+$dark_gray: #889aa4;
|
|
|
+
|
|
|
+.login-container {
|
|
|
+ width: 100vw;
|
|
|
+ height: 100vh;
|
|
|
+ min-width: 1280px;
|
|
|
+ min-height: 800px;
|
|
|
+ background: url(../../assets/images/bg.jpg);
|
|
|
+ background-size: 100% 100%;
|
|
|
+ overflow: hidden;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ .shadow {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ box-shadow: 0px 10px 30px 0px rgba(60, 108, 254, 0.36);
|
|
|
+
|
|
|
+ .img {
|
|
|
+ width: 666px;
|
|
|
+ height: 848px;
|
|
|
+ background: linear-gradient(
|
|
|
+ -40deg,
|
|
|
+ rgba(83, 94, 240, 0.5),
|
|
|
+ rgba(67, 147, 248, 0.5)
|
|
|
+ );
|
|
|
+ border-radius: 20px 0px 0px 20px;
|
|
|
+ img {
|
|
|
+ width: 586px;
|
|
|
+ height: 531px;
|
|
|
+ margin: 136px 0 0 37px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .form {
|
|
|
+ width: 740px;
|
|
|
+ height: 848px;
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 0 20px 20px 0;
|
|
|
+ position: relative;
|
|
|
+ img {
|
|
|
+ position: absolute;
|
|
|
+ top: 61px;
|
|
|
+ left: 53px;
|
|
|
+ // margin: 61px 0 0 53px;
|
|
|
+ }
|
|
|
+ .title {
|
|
|
+ position: absolute;
|
|
|
+ top: 217px;
|
|
|
+ left: 141px;
|
|
|
+ font-size: 50px;
|
|
|
+ font-family: Microsoft YaHei;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #132949;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .login {
|
|
|
+ height: 36px;
|
|
|
+ font-size: 30px;
|
|
|
+ font-family: Adobe Heiti Std;
|
|
|
+ font-weight: normal;
|
|
|
+ color: #132949;
|
|
|
+ position: absolute;
|
|
|
+ top: 334px;
|
|
|
+ left: 345px;
|
|
|
+ border-bottom: 4px solid rgba(0, 118, 254, 0.3);
|
|
|
+ }
|
|
|
+ .name {
|
|
|
+ position: absolute;
|
|
|
+ top: 406px;
|
|
|
+ left: 139px;
|
|
|
+ // z-index: 99;
|
|
|
+
|
|
|
+ .login-form {
|
|
|
+ width: 480px;
|
|
|
+ position: absolute;
|
|
|
+ .el-input {
|
|
|
+ font-size: 20px;
|
|
|
+ }
|
|
|
+ .el-form-item {
|
|
|
+ margin-bottom: 29px;
|
|
|
+ }
|
|
|
+ /deep/ .el-form-item__content {
|
|
|
+ border: 1px solid #d9d9d9;
|
|
|
+ background-color: #fff;
|
|
|
+ width: 481px;
|
|
|
+ height: 64px;
|
|
|
+ border-radius: 6px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ .el-form-item__error {
|
|
|
+ font-size: 18px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /deep/ .el-button {
|
|
|
+ width: 485px !important;
|
|
|
+ height: 74px;
|
|
|
+ background: #2b4cfe;
|
|
|
+ box-shadow: 0px 3px 16px 0px rgba(43, 71, 224, 0.58);
|
|
|
+ border-radius: 6px;
|
|
|
+ font-size: 22px;
|
|
|
+ font-family: Microsoft YaHei-3970(82674968);
|
|
|
+ font-weight: 400;
|
|
|
+ color: #ffffff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .svg-container {
|
|
|
+ padding: 6px 5px 6px 15px;
|
|
|
+ color: $bg;
|
|
|
+ vertical-align: middle;
|
|
|
+ width: 30px;
|
|
|
+ display: inline-block;
|
|
|
+
|
|
|
+ .user {
|
|
|
+ width: 25px;
|
|
|
+ height: 25px;
|
|
|
+ background: url(../../assets/images/name.png);
|
|
|
+ background-size: 100% 100%;
|
|
|
+ }
|
|
|
+ .password {
|
|
|
+ width: 25px;
|
|
|
+ height: 25px;
|
|
|
+ background: url(../../assets/images/code.png);
|
|
|
+ background-size: 100% 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .show-pwd {
|
|
|
+ right: 10px;
|
|
|
+ font-size: 16px;
|
|
|
+ color: $bg;
|
|
|
+ cursor: pointer;
|
|
|
+ user-select: none;
|
|
|
+ .eye_close {
|
|
|
+ margin-right: 15px;
|
|
|
+ width: 25px;
|
|
|
+ height: 25px;
|
|
|
+ background: url(../../assets/images/eye_close.png);
|
|
|
+ background-size: 100% 100%;
|
|
|
+ }
|
|
|
+ .eye {
|
|
|
+ margin-right: 15px;
|
|
|
+ width: 25px;
|
|
|
+ height: 25px;
|
|
|
+ background: url(../../assets/images/eye.png);
|
|
|
+ background-size: 100% 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|