|
|
|
@ -1,26 +1,36 @@
|
|
|
|
|
<template>
|
|
|
|
|
<!-- 最外层的 div 作为整个登录页面内容的容器 -->
|
|
|
|
|
<div>
|
|
|
|
|
<!-- 使用 el-card 组件创建一个卡片式的布局容器,用于包裹登录表单相关内容,并设置了特定的类名 -->
|
|
|
|
|
<el-card class="login-form-layout">
|
|
|
|
|
<!-- el-form 组件用于创建表单,以下是对其属性的设置说明 -->
|
|
|
|
|
<el-form autoComplete="on"
|
|
|
|
|
:model="loginForm"
|
|
|
|
|
:rules="loginRules"
|
|
|
|
|
ref="loginForm"
|
|
|
|
|
label-position="left">
|
|
|
|
|
<!-- div 元素用于将 SVG 图标在水平方向上居中显示 -->
|
|
|
|
|
<div style="text-align: center">
|
|
|
|
|
<!-- svg-icon 组件用于展示 SVG 图标,这里展示的图标类名为 "login-mall",并设置了宽度、高度和颜色 -->
|
|
|
|
|
<svg-icon icon-class="login-mall" style="width: 56px;height: 56px;color: #409EFF"></svg-icon>
|
|
|
|
|
</div>
|
|
|
|
|
<!-- h2 标题元素,展示登录页面的标题 "mall-admin-web",并设置了类名用于样式控制 -->
|
|
|
|
|
<h2 class="login-title color-main">mall-admin-web</h2>
|
|
|
|
|
<!-- el-form-item 组件表示表单中的一个项目,这里对应 "用户名" 输入项,通过 prop 属性关联验证规则 -->
|
|
|
|
|
<el-form-item prop="username">
|
|
|
|
|
<!-- el-input 组件用于创建输入框,以下是对其属性和插槽的详细说明 -->
|
|
|
|
|
<el-input name="username"
|
|
|
|
|
type="text"
|
|
|
|
|
v-model="loginForm.username"
|
|
|
|
|
autoComplete="on"
|
|
|
|
|
placeholder="请输入用户名">
|
|
|
|
|
<span slot="prefix">
|
|
|
|
|
<svg-icon icon-class="user" class="color-main"></svg-icon>
|
|
|
|
|
</span>
|
|
|
|
|
<!-- 使用插槽 "prefix" 在输入框前面添加一个 SVG 图标,图标类名为 "user",并设置了类名用于样式控制 -->
|
|
|
|
|
<span slot="prefix">
|
|
|
|
|
<svg-icon icon-class="user" class="color-main"></svg-icon>
|
|
|
|
|
</span>
|
|
|
|
|
</el-input>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<!-- 另一个 el-form-item 组件,对应 "密码" 输入项,同样通过 prop 属性关联验证规则 -->
|
|
|
|
|
<el-form-item prop="password">
|
|
|
|
|
<el-input name="password"
|
|
|
|
|
:type="pwdType"
|
|
|
|
@ -28,15 +38,19 @@
|
|
|
|
|
v-model="loginForm.password"
|
|
|
|
|
autoComplete="on"
|
|
|
|
|
placeholder="请输入密码">
|
|
|
|
|
<span slot="prefix">
|
|
|
|
|
<svg-icon icon-class="password" class="color-main"></svg-icon>
|
|
|
|
|
</span>
|
|
|
|
|
<!-- 同样使用插槽 "prefix" 在输入框前面添加表示密码的 SVG 图标,图标类名为 "password",并设置类名用于样式控制 -->
|
|
|
|
|
<span slot="prefix">
|
|
|
|
|
<svg-icon icon-class="password" class="color-main"></svg-icon>
|
|
|
|
|
</span>
|
|
|
|
|
<!-- 使用插槽 "suffix" 在输入框后面添加一个可点击的 SVG 图标,点击这个图标可以切换密码的显示隐藏状态,图标类名为 "eye",并设置类名用于样式控制 -->
|
|
|
|
|
<span slot="suffix" @click="showPwd">
|
|
|
|
|
<svg-icon icon-class="eye" class="color-main"></svg-icon>
|
|
|
|
|
</span>
|
|
|
|
|
<svg-icon icon-class="eye" class="color-main"></svg-icon>
|
|
|
|
|
</span>
|
|
|
|
|
</el-input>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<!-- 又是一个 el-form-item 组件,用于放置登录和获取体验账号的按钮,并设置了底部外边距和文本居中样式 -->
|
|
|
|
|
<el-form-item style="margin-bottom: 60px;text-align: center">
|
|
|
|
|
<!-- el-button 组件用于创建按钮,以下是按钮的相关属性设置说明 -->
|
|
|
|
|
<el-button style="width: 45%" type="primary" :loading="loading" @click.native.prevent="handleLogin">
|
|
|
|
|
登录
|
|
|
|
|
</el-button>
|
|
|
|
@ -46,139 +60,202 @@
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-form>
|
|
|
|
|
</el-card>
|
|
|
|
|
<!-- img 标签用于展示一张背景图片,图片的源地址通过绑定的变量 login_center_bg 来动态设置,并设置了类名用于样式控制 -->
|
|
|
|
|
<img :src="login_center_bg" class="login-center-layout">
|
|
|
|
|
<!-- el-dialog 组件用于创建一个对话框,以下是对其属性的详细说明 -->
|
|
|
|
|
<el-dialog
|
|
|
|
|
title="公众号二维码"
|
|
|
|
|
:visible.sync="dialogVisible"
|
|
|
|
|
:show-close="false"
|
|
|
|
|
:center="true"
|
|
|
|
|
width="30%">
|
|
|
|
|
<!-- div 元素用于在对话框内放置相关内容,并将文本居中显示 -->
|
|
|
|
|
<div style="text-align: center">
|
|
|
|
|
<!-- span 元素用于展示提示文字,通过设置不同的类名来控制文字的样式,如字体大小、颜色等,提示用户关注公众号获取体验账号的操作流程 -->
|
|
|
|
|
<span class="font-title-large"><span class="color-main font-extra-large">关注公众号</span>回复<span class="color-main font-extra-large">体验</span>获取体验账号</span>
|
|
|
|
|
<br>
|
|
|
|
|
<!-- 再次使用 img 标签在对话框内展示公众号的二维码图片,设置了图片的宽度、高度以及顶部外边距 -->
|
|
|
|
|
<img src="http://macro-oss.oss-cn-shenzhen.aliyuncs.com/mall/banner/qrcode_for_macrozheng_258.jpg" width="160" height="160" style="margin-top: 10px">
|
|
|
|
|
</div>
|
|
|
|
|
<!-- 使用插槽 "footer" 在对话框底部定义按钮区域,这里只有一个确定按钮 -->
|
|
|
|
|
<span slot="footer" class="dialog-footer">
|
|
|
|
|
<el-button type="primary" @click="dialogConfirm">确定</el-button>
|
|
|
|
|
<el-button type="primary" @click="dialogConfirm">确定</el-button>
|
|
|
|
|
</span>
|
|
|
|
|
</el-dialog>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
import {isvalidUsername} from '@/utils/validate';
|
|
|
|
|
import {setSupport,getSupport,setCookie,getCookie} from '@/utils/support';
|
|
|
|
|
import login_center_bg from '@/assets/images/login_center_bg.png'
|
|
|
|
|
// 从 @/utils/validate 文件中导入 isvalidUsername 函数,该函数可能用于验证用户名是否符合特定规则
|
|
|
|
|
import {isvalidUsername} from '@/utils/validate';
|
|
|
|
|
// 从 @/utils/support 文件中导入多个函数,分别用于设置和获取支持相关的状态以及设置和获取 Cookie
|
|
|
|
|
import {setSupport, getSupport, setCookie, getCookie} from '@/utils/support';
|
|
|
|
|
// 导入登录页面中心背景图片资源,用于在页面中展示
|
|
|
|
|
import login_center_bg from '@/assets/images/login_center_bg.png'
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
name: 'login',
|
|
|
|
|
data() {
|
|
|
|
|
const validateUsername = (rule, value, callback) => {
|
|
|
|
|
if (!isvalidUsername(value)) {
|
|
|
|
|
callback(new Error('请输入正确的用户名'))
|
|
|
|
|
} else {
|
|
|
|
|
callback()
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
const validatePass = (rule, value, callback) => {
|
|
|
|
|
if (value.length < 3) {
|
|
|
|
|
callback(new Error('密码不能小于3位'))
|
|
|
|
|
} else {
|
|
|
|
|
callback()
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
return {
|
|
|
|
|
loginForm: {
|
|
|
|
|
username: '',
|
|
|
|
|
password: '',
|
|
|
|
|
},
|
|
|
|
|
loginRules: {
|
|
|
|
|
username: [{required: true, trigger: 'blur', validator: validateUsername}],
|
|
|
|
|
password: [{required: true, trigger: 'blur', validator: validatePass}]
|
|
|
|
|
},
|
|
|
|
|
loading: false,
|
|
|
|
|
pwdType: 'password',
|
|
|
|
|
login_center_bg,
|
|
|
|
|
dialogVisible:false,
|
|
|
|
|
supportDialogVisible:false
|
|
|
|
|
export default {
|
|
|
|
|
name: 'login',
|
|
|
|
|
data() {
|
|
|
|
|
// 定义一个名为 validateUsername 的函数,作为用户名输入框的验证规则函数
|
|
|
|
|
const validateUsername = (rule, value, callback) => {
|
|
|
|
|
// 如果传入的用户名不符合验证规则(通过调用 isvalidUsername 函数判断)
|
|
|
|
|
if (!isvalidUsername(value)) {
|
|
|
|
|
// 则通过回调函数 callback 返回一个 Error 对象,提示用户输入正确的用户名,这样在表单验证时会显示相应错误提示
|
|
|
|
|
callback(new Error('请输入正确的用户名'))
|
|
|
|
|
} else {
|
|
|
|
|
// 如果用户名验证通过,则直接调用回调函数,不传递错误信息,表示验证成功
|
|
|
|
|
callback()
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
created() {
|
|
|
|
|
this.loginForm.username = getCookie("username");
|
|
|
|
|
this.loginForm.password = getCookie("password");
|
|
|
|
|
if(this.loginForm.username === undefined||this.loginForm.username==null||this.loginForm.username===''){
|
|
|
|
|
this.loginForm.username = 'admin';
|
|
|
|
|
};
|
|
|
|
|
// 定义一个名为 validatePass 的函数,作为密码输入框的验证规则函数
|
|
|
|
|
const validatePass = (rule, value, callback) => {
|
|
|
|
|
// 如果密码长度小于 3 位
|
|
|
|
|
if (value.length < 3) {
|
|
|
|
|
// 通过回调函数 callback 返回一个 Error 对象,提示密码不能小于 3 位,在表单验证时会显示此错误提示
|
|
|
|
|
callback(new Error('密码不能小于3位'))
|
|
|
|
|
} else {
|
|
|
|
|
// 如果密码长度符合要求,则调用回调函数,表示验证成功
|
|
|
|
|
callback()
|
|
|
|
|
}
|
|
|
|
|
if(this.loginForm.password === undefined||this.loginForm.password==null){
|
|
|
|
|
this.loginForm.password = '';
|
|
|
|
|
};
|
|
|
|
|
return {
|
|
|
|
|
// loginForm 对象用于双向绑定表单中的输入数据,包含用户名和密码两个属性,初始值都为空字符串
|
|
|
|
|
loginForm: {
|
|
|
|
|
username: '',
|
|
|
|
|
password: '',
|
|
|
|
|
},
|
|
|
|
|
// loginRules 对象用于定义表单中各个输入项的验证规则
|
|
|
|
|
loginRules: {
|
|
|
|
|
// 用户名输入项的验证规则数组,这里只有一条规则,要求该输入项必填,触发验证的时机是失去焦点(blur),验证函数为 validateUsername
|
|
|
|
|
username: [{required: true, trigger: 'blur', validator: validateUsername}],
|
|
|
|
|
// 密码输入项的验证规则数组,同样只有一条规则,要求必填,触发验证时机是失去焦点,验证函数为 validatePass
|
|
|
|
|
password: [{required: true, trigger: 'blur', validator: validatePass}]
|
|
|
|
|
},
|
|
|
|
|
// loading 变量用于控制登录按钮的加载状态(比如显示加载动画等),初始值为 false,表示未处于加载状态
|
|
|
|
|
loading: false,
|
|
|
|
|
// pwdType 变量用于控制密码输入框的类型(显示为密码形式还是明文形式),初始值为 'password',表示密码隐藏
|
|
|
|
|
pwdType: 'password',
|
|
|
|
|
// 绑定导入的登录中心背景图片资源,用于在页面中正确显示背景图片
|
|
|
|
|
login_center_bg,
|
|
|
|
|
// dialogVisible 变量用于控制公众号二维码对话框的显示与隐藏,初始值为 false,表示对话框默认不显示
|
|
|
|
|
dialogVisible: false,
|
|
|
|
|
// supportDialogVisible 变量(在当前代码中未看到使用,但可能用于控制其他相关对话框的显示隐藏),初始值为 false
|
|
|
|
|
supportDialogVisible: false
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
created() {
|
|
|
|
|
// 在组件创建时,尝试从 Cookie 中获取用户名信息,并赋值给 loginForm.username
|
|
|
|
|
this.loginForm.username = getCookie("username");
|
|
|
|
|
// 同样尝试从 Cookie 中获取密码信息,并赋值给 loginForm.password
|
|
|
|
|
this.loginForm.password = getCookie("password");
|
|
|
|
|
// 如果获取到的用户名信息是 undefined、null 或者空字符串
|
|
|
|
|
if (this.loginForm.username === undefined || this.loginForm.username == null || this.loginForm.username === '') {
|
|
|
|
|
// 则将用户名默认设置为 'admin'
|
|
|
|
|
this.loginForm.username = 'admin';
|
|
|
|
|
}
|
|
|
|
|
// 如果获取到的密码信息是 undefined 或者 null
|
|
|
|
|
if (this.loginForm.password === undefined || this.loginForm.password == null) {
|
|
|
|
|
// 则将密码默认设置为空字符串
|
|
|
|
|
this.loginForm.password = '';
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
showPwd() {
|
|
|
|
|
// 切换密码输入框的显示类型,如果当前是密码形式(pwdType 为 'password')
|
|
|
|
|
if (this.pwdType === 'password') {
|
|
|
|
|
// 则将其设置为空字符串,即显示明文
|
|
|
|
|
this.pwdType = ''
|
|
|
|
|
} else {
|
|
|
|
|
// 否则将其设置回 'password',恢复为密码隐藏形式
|
|
|
|
|
this.pwdType = 'password'
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
showPwd() {
|
|
|
|
|
if (this.pwdType === 'password') {
|
|
|
|
|
this.pwdType = ''
|
|
|
|
|
handleLogin() {
|
|
|
|
|
// 通过引用 loginForm 调用表单的验证方法,传入一个回调函数,根据验证结果进行后续操作
|
|
|
|
|
this.$refs.loginForm.validate(valid => {
|
|
|
|
|
if (valid) {
|
|
|
|
|
// let isSupport = getSupport();
|
|
|
|
|
// if (isSupport === undefined || isSupport == null) {
|
|
|
|
|
// this.dialogVisible = true;
|
|
|
|
|
// return;
|
|
|
|
|
// }
|
|
|
|
|
// 如果表单验证通过,将 loading 状态设置为 true,表示登录操作正在进行,可能会显示加载动画等提示
|
|
|
|
|
this.loading = true;
|
|
|
|
|
// 通过 $store.dispatch 方法触发名为 'Login' 的 action,并传入 loginForm 数据(包含用户名和密码),处理登录相关逻辑
|
|
|
|
|
this.$store.dispatch('Login', this.loginForm).then(() => {
|
|
|
|
|
// 登录成功后,将 loading 状态设置回 false,隐藏加载动画
|
|
|
|
|
this.loading = false;
|
|
|
|
|
// 将用户名信息保存到 Cookie 中,设置有效期为 15 天(这里的 15 具体含义可能与业务相关的时间单位对应)
|
|
|
|
|
setCookie("username", this.loginForm.username, 15);
|
|
|
|
|
// 同样将密码信息保存到 Cookie 中,有效期也是 15 天
|
|
|
|
|
setCookie("password", this.loginForm.password, 15);
|
|
|
|
|
// 通过 $router.push 方法进行页面跳转,跳转到应用的首页(路径为 '/')
|
|
|
|
|
this.$router.push({path: '/'})
|
|
|
|
|
}).catch(() => {
|
|
|
|
|
// 如果登录过程出现错误,将 loading 状态设置回 false,隐藏加载动画
|
|
|
|
|
this.loading = false
|
|
|
|
|
})
|
|
|
|
|
} else {
|
|
|
|
|
this.pwdType = 'password'
|
|
|
|
|
// 如果表单验证不通过,在控制台打印提示信息,并返回 false,阻止后续操作
|
|
|
|
|
console.log('参数验证不合法!');
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
handleLogin() {
|
|
|
|
|
this.$refs.loginForm.validate(valid => {
|
|
|
|
|
if (valid) {
|
|
|
|
|
// let isSupport = getSupport();
|
|
|
|
|
// if(isSupport===undefined||isSupport==null){
|
|
|
|
|
// this.dialogVisible =true;
|
|
|
|
|
// return;
|
|
|
|
|
// }
|
|
|
|
|
this.loading = true;
|
|
|
|
|
this.$store.dispatch('Login', this.loginForm).then(() => {
|
|
|
|
|
this.loading = false;
|
|
|
|
|
setCookie("username",this.loginForm.username,15);
|
|
|
|
|
setCookie("password",this.loginForm.password,15);
|
|
|
|
|
this.$router.push({path: '/'})
|
|
|
|
|
}).catch(() => {
|
|
|
|
|
this.loading = false
|
|
|
|
|
})
|
|
|
|
|
} else {
|
|
|
|
|
console.log('参数验证不合法!');
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
handleTry(){
|
|
|
|
|
this.dialogVisible =true
|
|
|
|
|
},
|
|
|
|
|
dialogConfirm(){
|
|
|
|
|
this.dialogVisible =false;
|
|
|
|
|
setSupport(true);
|
|
|
|
|
},
|
|
|
|
|
dialogCancel(){
|
|
|
|
|
this.dialogVisible = false;
|
|
|
|
|
setSupport(false);
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
handleTry() {
|
|
|
|
|
// 点击获取体验账号按钮时,将 dialogVisible 设置为 true,显示公众号二维码对话框
|
|
|
|
|
this.dialogVisible = true
|
|
|
|
|
},
|
|
|
|
|
dialogConfirm() {
|
|
|
|
|
// 点击对话框中的确定按钮时,将 dialogVisible 设置为 false,隐藏对话框
|
|
|
|
|
this.dialogVisible = false;
|
|
|
|
|
// 调用 setSupport 函数,传入 true,可能用于设置某种支持相关的状态(具体功能需看 setSupport 函数实现)
|
|
|
|
|
setSupport(true);
|
|
|
|
|
},
|
|
|
|
|
dialogCancel() {
|
|
|
|
|
// 点击对话框中的取消按钮(当前代码中未看到调用此方法的地方,但功能应该是隐藏对话框)时,将 dialogVisible 设置为 false,隐藏对话框
|
|
|
|
|
this.dialogVisible = false;
|
|
|
|
|
// 调用 setSupport 函数,传入 false,可能用于设置某种支持相关的状态(具体功能需看 setSupport 函数实现)
|
|
|
|
|
setSupport(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
.login-form-layout {
|
|
|
|
|
position: absolute;
|
|
|
|
|
left: 0;
|
|
|
|
|
right: 0;
|
|
|
|
|
width: 360px;
|
|
|
|
|
margin: 140px auto;
|
|
|
|
|
border-top: 10px solid #409EFF;
|
|
|
|
|
}
|
|
|
|
|
/* 为类名为 "login-form-layout" 的元素设置样式,以下是具体样式属性的说明 */
|
|
|
|
|
.login-form-layout {
|
|
|
|
|
/* 将元素定位设置为绝对定位,使其可以相对于最近的已定位祖先元素进行定位 */
|
|
|
|
|
position: absolute;
|
|
|
|
|
/* 使其在水平方向上相对于父元素左对齐 */
|
|
|
|
|
left: 0;
|
|
|
|
|
/* 使其在水平方向上相对于父元素右对齐 */
|
|
|
|
|
right: 0;
|
|
|
|
|
/* 设置元素的宽度为 360px */
|
|
|
|
|
width: 360px;
|
|
|
|
|
/* 设置元素在垂直方向上居中,通过上下外边距 auto 实现 */
|
|
|
|
|
margin: 140px auto;
|
|
|
|
|
/* 设置元素的上边框样式,宽度为 10px,颜色为 #409EFF */
|
|
|
|
|
border-top: 10px solid #409EFF;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.login-title {
|
|
|
|
|
text-align: center;
|
|
|
|
|
}
|
|
|
|
|
/* 为类名为 "login-title" 的元素设置样式,这里只是简单地将文本在元素内居中显示 */
|
|
|
|
|
.login-title {
|
|
|
|
|
text-align: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.login-center-layout {
|
|
|
|
|
background: #409EFF;
|
|
|
|
|
width: auto;
|
|
|
|
|
height: auto;
|
|
|
|
|
max-width: 100%;
|
|
|
|
|
max-height: 100%;
|
|
|
|
|
margin-top: 200px;
|
|
|
|
|
}
|
|
|
|
|
/* 为类名为 "login-center-layout" 的元素设置样式,以下是具体样式属性的说明 */
|
|
|
|
|
.login-center-layout {
|
|
|
|
|
/* 设置元素的背景颜色为 #409EFF */
|
|
|
|
|
background: #409EFF;
|
|
|
|
|
/* 设置元素的宽度自动适应内容,不会超出父元素宽度 */
|
|
|
|
|
width: auto;
|
|
|
|
|
/* 设置元素的高度自动适应内容,不会超出父元素高度 */
|
|
|
|
|
height: auto;
|
|
|
|
|
/* 设置元素的最大宽度为 100%,即不会超过父元素的宽度 */
|
|
|
|
|
max-width: 100%;
|
|
|
|
|
/* 设置元素的最大高度为 100%,即不会超过父元素的高度 */
|
|
|
|
|
max-height: 100%;
|
|
|
|
|
/* 设置元素的顶部外边距为 200px */
|
|
|
|
|
margin-top: 200px;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|