feat: 登录页,及Log页接口对接
5
public/index.html
vendored
|
@ -139,7 +139,7 @@
|
|||
top: 0;
|
||||
width: 51%;
|
||||
height: 100%;
|
||||
background: #49a9ee;
|
||||
background: #051314;
|
||||
/* Old browsers */
|
||||
z-index: 1000;
|
||||
-webkit-transform: translateX(0);
|
||||
|
@ -249,9 +249,6 @@
|
|||
<div id="loader"></div>
|
||||
<div class="loader-section section-left"></div>
|
||||
<div class="loader-section section-right"></div>
|
||||
<div class="load_title">正在加载 核素监测数据自动处理与交互分析系统,请耐心等待
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -152,8 +152,8 @@ export function downFile(url,parameter, method='get'){
|
|||
* @param parameter
|
||||
* @returns {*}
|
||||
*/
|
||||
export function downloadFile(url, fileName, parameter) {
|
||||
return downFile(url, parameter).then((data) => {
|
||||
export function downloadFile(url, fileName, parameter, method) {
|
||||
return downFile(url, parameter, method).then((data) => {
|
||||
if (!data || data.size === 0) {
|
||||
Vue.prototype['$message'].warning('文件下载失败')
|
||||
return
|
||||
|
|
BIN
src/assets/images/login/bg.jpg
Normal file
After Width: | Height: | Size: 572 KiB |
BIN
src/assets/images/login/login-btn-active.png
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
src/assets/images/login/login-btn.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
src/assets/images/login/logo.png
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
src/assets/images/login/pwd-bg.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
src/assets/images/login/username-bg.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
src/assets/images/login/validate-bg.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="search-form">
|
||||
<a-form-model ref="form" :model="formModel" v-bind="$attrs" @keyup.enter.native="onSearch">
|
||||
<a-form-model ref="form" :colon="false" :model="formModel" v-bind="$attrs" @keyup.enter.native="onSearch">
|
||||
<a-row v-if="type == 'single-line'" :gutter="20" style="margin-right: 0 !important;">
|
||||
<a-col
|
||||
class="search-form-item"
|
||||
|
@ -101,6 +101,13 @@ export default {
|
|||
}
|
||||
.ant-form-item-label {
|
||||
flex-shrink: 0;
|
||||
margin-right: 10px;
|
||||
label {
|
||||
font-size: 16px;
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.ant-form-item-control-wrapper {
|
||||
width: 100%;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="tree-with-line">
|
||||
<a-tree v-bind="$attrs" :defaultExpandedKeys="defaultExpandedKeys" :selected-keys="selectedKeys" @select="onSelect">
|
||||
<a-tree v-bind="$attrs" :selected-keys="selectedKeys" :expandedKeys="expandedKeys" @select="onSelect" @expand="onExpand">
|
||||
<template slot="switcherIcon">
|
||||
<div></div>
|
||||
</template>
|
||||
|
@ -13,7 +13,7 @@ export default {
|
|||
selectedKeys: {
|
||||
type: Array
|
||||
},
|
||||
defaultExpandedKeys: {
|
||||
expandedKeys: {
|
||||
type: Array
|
||||
}
|
||||
},
|
||||
|
@ -23,6 +23,9 @@ export default {
|
|||
this.$emit('update:selectedKeys', selectedKeys)
|
||||
this.$emit('select')
|
||||
}
|
||||
},
|
||||
onExpand(expandedKeys) {
|
||||
this.$emit('update:expandedKeys', expandedKeys)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -680,7 +680,8 @@
|
|||
margin-right: 10px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
padding: 0 15px;
|
||||
padding: 0 16px;
|
||||
letter-spacing: 2px;
|
||||
position: relative;
|
||||
> a {
|
||||
color: #c9f6f6;
|
||||
|
|
|
@ -23,7 +23,7 @@ export const JeecgListMixin = {
|
|||
pageSizeOptions: ['10', '20', '30'],
|
||||
showTotal: (total, range) => {
|
||||
const { current, pageSize } = this.ipagination
|
||||
return `共 ${total} 条记录 第 ${current} / ${Math.ceil(total / pageSize)} 页`
|
||||
return `Total ${total} items Page ${current} / ${Math.ceil(total / pageSize)}`
|
||||
},
|
||||
showQuickJumper: true,
|
||||
showSizeChanger: true,
|
||||
|
@ -228,12 +228,12 @@ export const JeecgListMixin = {
|
|||
},
|
||||
handleEdit: function (record) {
|
||||
this.$refs.modalForm.edit(record);
|
||||
this.$refs.modalForm.title = "编辑";
|
||||
this.$refs.modalForm.title = "Edit";
|
||||
this.$refs.modalForm.disableSubmit = false;
|
||||
},
|
||||
handleAdd: function () {
|
||||
this.$refs.modalForm.add();
|
||||
this.$refs.modalForm.title = "新增";
|
||||
this.$refs.modalForm.title = "Add";
|
||||
this.$refs.modalForm.disableSubmit = false;
|
||||
},
|
||||
handleTableChange(pagination, filters, sorter) {
|
||||
|
@ -262,7 +262,7 @@ export const JeecgListMixin = {
|
|||
},
|
||||
handleDetail:function(record){
|
||||
this.$refs.modalForm.edit(record);
|
||||
this.$refs.modalForm.title="详情";
|
||||
this.$refs.modalForm.title="Detail";
|
||||
this.$refs.modalForm.disableSubmit = true;
|
||||
},
|
||||
/* 导出 */
|
||||
|
|
|
@ -17,9 +17,18 @@
|
|||
</template>
|
||||
<!-- 标题结束 -->
|
||||
<!-- 内容 -->
|
||||
<tree-with-line :treeData="treeData" :selected-keys.sync="selectedKeys" :expanded-keys.sync="expandedKeys" @select="onSelect"> </tree-with-line>
|
||||
<a-spin :spinning="isGettingTreeData" style="min-height: 200px">
|
||||
<tree-with-line
|
||||
:treeData="treeData"
|
||||
:selected-keys.sync="selectedKeys"
|
||||
:expanded-keys.sync="expandedKeys"
|
||||
@select="onSelect"
|
||||
>
|
||||
</tree-with-line>
|
||||
</a-spin>
|
||||
<!-- 内容结束 -->
|
||||
</a-card>
|
||||
<!-- 日志列表 -->
|
||||
<div class="log-list">
|
||||
<custom-table
|
||||
size="middle"
|
||||
|
@ -27,10 +36,10 @@
|
|||
:columns="columns"
|
||||
:list="dataSource"
|
||||
:pagination="false"
|
||||
:loading="loading"
|
||||
:loading="isGettingTreeData || loading"
|
||||
:can-select="false"
|
||||
@change="handleTableChange"
|
||||
:scroll="{ y: 'calc(100vh - 365px)' }"
|
||||
:scroll="{ y: 'calc(100vh - 175px)' }"
|
||||
>
|
||||
<template slot="operate" slot-scope="{ record }">
|
||||
<a-space :size="20">
|
||||
|
@ -45,37 +54,42 @@
|
|||
</template>
|
||||
</custom-table>
|
||||
</div>
|
||||
|
||||
<!-- 日志列表结束 -->
|
||||
<custom-modal title="Log" v-model="visible" :show-footer="false">
|
||||
这里是Log内容
|
||||
<a-spin :spinning="isGettingDetail" style="min-height: 100px">
|
||||
{{ logInfo }}
|
||||
</a-spin>
|
||||
</custom-modal>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
|
||||
import TreeWithLine from '@/components/TreeWithLine/index.vue'
|
||||
import { downloadFile, getAction } from '../../api/manage'
|
||||
import TreeJson from './tree.json'
|
||||
import { downloadFile, getAction, postAction } from '../../api/manage'
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: 'Name',
|
||||
title: 'NAME',
|
||||
align: 'center',
|
||||
dataIndex: 'name'
|
||||
width: 320,
|
||||
dataIndex: 'fileName'
|
||||
},
|
||||
{
|
||||
title: 'date',
|
||||
title: 'DATE',
|
||||
align: 'center',
|
||||
dataIndex: 'date'
|
||||
width: 200,
|
||||
dataIndex: 'fileDate'
|
||||
},
|
||||
{
|
||||
title: 'size',
|
||||
title: 'SIZE',
|
||||
align: 'center',
|
||||
dataIndex: 'size'
|
||||
width: 220,
|
||||
dataIndex: 'fileSize'
|
||||
},
|
||||
{
|
||||
title: 'Operate',
|
||||
title: 'OPERATE',
|
||||
align: 'center',
|
||||
width: 200,
|
||||
scopedSlots: {
|
||||
customRender: 'operate'
|
||||
}
|
||||
|
@ -92,22 +106,17 @@ export default {
|
|||
return {
|
||||
disableMixinCreated: true,
|
||||
url: {
|
||||
list: '/test'
|
||||
list: '/logManage/findFiles'
|
||||
},
|
||||
isGettingTreeData: false, // 正在获取左侧树信息
|
||||
treeData: [],
|
||||
selectedKeys: [],
|
||||
expandedKeys: [],
|
||||
dataSource: [
|
||||
{
|
||||
id: 1,
|
||||
name: 'DEX33_002-20220512_0723_S_FULL_9011.9.log',
|
||||
date: '2022-05-13',
|
||||
size: '105KB',
|
||||
fileName: 'test.txt'
|
||||
}
|
||||
],
|
||||
visible: false
|
||||
dataSource: [],
|
||||
|
||||
visible: false,
|
||||
isGettingDetail: false,
|
||||
logInfo: ''
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
@ -117,17 +126,15 @@ export default {
|
|||
async getTreeData() {
|
||||
try {
|
||||
this.isGettingTreeData = true
|
||||
const res = await getAction('/logManage/findFtpFolders')
|
||||
console.log('%c [ res ]-159', 'font-size:13px; background:pink; color:#bf2c9f;', res)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
this.$message.error('Get Tree Data Failed')
|
||||
this.treeData = this.buildTreeData(TreeJson)
|
||||
console.log('%c [ this.treeData ]-125', 'font-size:13px; background:pink; color:#bf2c9f;', this.treeData)
|
||||
const res = await getAction('/logManage/findFtpFolders', { workPath: 'log' })
|
||||
this.treeData = this.buildTreeData(res)
|
||||
const firstNode = this.treeData[0]
|
||||
this.selectedKeys = [firstNode.key]
|
||||
this.expandedKeys = [firstNode.key]
|
||||
this.onSelect()
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
this.$message.error('Get Tree Data Failed')
|
||||
} finally {
|
||||
this.isGettingTreeData = false
|
||||
}
|
||||
|
@ -152,15 +159,60 @@ export default {
|
|||
return tree
|
||||
},
|
||||
onSelect() {
|
||||
this.queryParam.query = this.selectedKeys[0]
|
||||
this.queryParam.path = this.selectedKeys[0]
|
||||
this.loadData()
|
||||
},
|
||||
onOperate(record) {
|
||||
console.log('%c [ ]-147', 'font-size:13px; background:pink; color:#bf2c9f;', record)
|
||||
this.visible = true
|
||||
|
||||
loadData(arg) {
|
||||
if (!this.url.list) {
|
||||
this.$message.error('请设置url.list属性!')
|
||||
return
|
||||
}
|
||||
//加载数据 若传入参数1则加载第一页的内容
|
||||
if (arg === 1) {
|
||||
this.ipagination.current = 1
|
||||
}
|
||||
this.onClearSelected()
|
||||
|
||||
var params = this.getQueryParams() //查询条件
|
||||
this.loading = true
|
||||
getAction(this.url.list, params)
|
||||
.then(res => {
|
||||
this.dataSource = res
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
onDownload({ fileName }) {
|
||||
downloadFile('/logManage/downloadFile', fileName, { fileName })
|
||||
|
||||
async onOperate({ fileName, filePath, fileSize }) {
|
||||
if (parseFloat(fileSize) == 0) {
|
||||
this.$message.warn('This Log Is Empty')
|
||||
return
|
||||
}
|
||||
this.visible = true
|
||||
const formData = new FormData()
|
||||
formData.append('fileName', fileName)
|
||||
formData.append('localPath', filePath)
|
||||
try {
|
||||
this.isGettingDetail = true
|
||||
const res = await postAction('/logManage/downloadFile', formData)
|
||||
this.logInfo = res
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
} finally {
|
||||
this.isGettingDetail = false
|
||||
}
|
||||
},
|
||||
onDownload({ fileName, filePath, fileSize }) {
|
||||
if (parseFloat(fileSize) == 0) {
|
||||
this.$message.warn('This Log Is Empty')
|
||||
return
|
||||
}
|
||||
const formData = new FormData()
|
||||
formData.append('fileName', fileName)
|
||||
formData.append('localPath', filePath)
|
||||
downloadFile('/logManage/downloadFile', fileName, formData, 'post')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,75 +1,83 @@
|
|||
<template>
|
||||
<div class="main">
|
||||
<a-form-model class="user-layout-login" @keyup.enter.native="handleSubmit">
|
||||
<a-tabs :activeKey="customActiveKey" :tabBarStyle="{ textAlign: 'center', borderBottom: 'unset' }" @change="handleTabClick">
|
||||
<a-tab-pane key="tab1" tab="账号密码登录">
|
||||
<login-account ref="alogin" @validateFail="validateFail" @success="requestSuccess" @fail="requestFailed"></login-account>
|
||||
</a-tab-pane>
|
||||
<div class="login-page">
|
||||
<div class="login-form">
|
||||
<div class="logo">
|
||||
<img src="@/assets/images/login/logo.png" alt="" />
|
||||
</div>
|
||||
<a-form-model layout="vertical" ref="formRef" :model="model" :rules="rules" @keyup.enter.native="handleSubmit">
|
||||
<a-form-model-item class="username" label="Username" prop="username">
|
||||
<a-input v-model="model.username"></a-input>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item class="password" label="Password" prop="password">
|
||||
<a-input type="password" v-model="model.password"></a-input>
|
||||
</a-form-model-item>
|
||||
<!-- 验证码 -->
|
||||
|
||||
<a-tab-pane key="tab2" tab="手机号登录">
|
||||
<login-phone ref="plogin" @validateFail="validateFail" @success="requestSuccess" @fail="requestFailed"></login-phone>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
|
||||
<a-form-model-item>
|
||||
<a-checkbox @change="handleRememberMeChange" default-checked>自动登录</a-checkbox>
|
||||
<a-form-model-item class="validate-code" label="Captcha" prop="inputCode">
|
||||
<a-input v-model="model.inputCode"> </a-input>
|
||||
<div class="validate-image">
|
||||
<img v-if="requestCodeSuccess" :src="randCodeImage" @click="handleChangeCheckCode" />
|
||||
<img v-else src="@/assets/checkcode.png" @click="handleChangeCheckCode" />
|
||||
</div>
|
||||
</a-form-model-item>
|
||||
|
||||
<a-form-item style="margin-top:24px">
|
||||
<a-button size="large" type="primary" htmlType="submit" class="login-button" :loading="loginBtn" @click.stop.prevent="handleSubmit" :disabled="loginBtn">确定
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
|
||||
<!-- 验证码结束 -->
|
||||
<!-- 记住密码 -->
|
||||
<div class="remember-pwd">
|
||||
<a-checkbox v-model="model.rememberPwd">Remember password</a-checkbox>
|
||||
</div>
|
||||
<!-- 记住密码结束 -->
|
||||
<a-button class="login-button" :loading="isSubmitting" @click="handleSubmit"> SIGN IN </a-button>
|
||||
</a-form-model>
|
||||
<login-select-tenant ref="loginSelect" @success="loginSelectOk"></login-select-tenant>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from 'vue'
|
||||
import { ACCESS_TOKEN, ENCRYPTED_STRING } from '@/store/mutation-types'
|
||||
import ThirdLogin from './third/ThirdLogin'
|
||||
import LoginSelectTenant from './LoginSelectTenant'
|
||||
import TwoStepCaptcha from '@/components/tools/TwoStepCaptcha'
|
||||
import { getEncryptedString } from '@/utils/encryption/aesEncrypt'
|
||||
import { ACCESS_TOKEN } from '@/store/mutation-types'
|
||||
import { timeFix } from '@/utils/util'
|
||||
|
||||
import LoginAccount from './LoginAccount'
|
||||
import LoginPhone from './LoginPhone'
|
||||
import { getAction } from '@/api/manage'
|
||||
import { mapActions } from 'vuex'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LoginSelectTenant,
|
||||
TwoStepCaptcha,
|
||||
ThirdLogin,
|
||||
LoginAccount,
|
||||
LoginPhone
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
customActiveKey: 'tab1',
|
||||
rememberMe: true,
|
||||
loginBtn: false,
|
||||
requiredTwoStepCaptcha: false,
|
||||
stepCaptchaVisible: false,
|
||||
encryptedString:{
|
||||
key:"",
|
||||
iv:"",
|
||||
isSubmitting: false,
|
||||
randCodeImage: '',
|
||||
requestCodeSuccess: false,
|
||||
model: {
|
||||
username: '',
|
||||
password: '',
|
||||
inputCode: '',
|
||||
rememberPwd: true
|
||||
},
|
||||
rules: {
|
||||
username: [{ required: true, message: 'Username Required' }],
|
||||
password: [
|
||||
{
|
||||
required: true,
|
||||
message: 'Password Required'
|
||||
},
|
||||
],
|
||||
inputCode: [
|
||||
{
|
||||
required: true,
|
||||
message: 'Captchar Required',
|
||||
},
|
||||
],
|
||||
},
|
||||
currdatetime: '',
|
||||
}
|
||||
},
|
||||
created() {
|
||||
Vue.ls.remove(ACCESS_TOKEN)
|
||||
this.getRouterData();
|
||||
this.rememberMe = true
|
||||
this.getRouterData()
|
||||
this.handleChangeCheckCode()
|
||||
},
|
||||
methods: {
|
||||
handleTabClick(key){
|
||||
this.customActiveKey = key
|
||||
},
|
||||
handleRememberMeChange(e){
|
||||
this.rememberMe = e.target.checked
|
||||
},
|
||||
...mapActions(['Login']),
|
||||
|
||||
/**跳转到登录页面的参数-账号获取*/
|
||||
getRouterData() {
|
||||
this.$nextTick(() => {
|
||||
|
@ -80,126 +88,221 @@ export default {
|
|||
})
|
||||
},
|
||||
|
||||
//登录
|
||||
handleSubmit () {
|
||||
this.loginBtn = true;
|
||||
if (this.customActiveKey === 'tab1') {
|
||||
// 使用账户密码登录
|
||||
this.$refs.alogin.handleLogin(this.rememberMe)
|
||||
/**刷新验证码*/
|
||||
handleChangeCheckCode() {
|
||||
this.currdatetime = new Date().getTime()
|
||||
this.model.inputCode = ''
|
||||
getAction(`/sys/randomImage/${this.currdatetime}`)
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
this.randCodeImage = res.result
|
||||
this.requestCodeSuccess = true
|
||||
} else {
|
||||
//手机号码登录
|
||||
this.$refs.plogin.handleLogin(this.rememberMe)
|
||||
this.$message.error(res.message)
|
||||
this.requestCodeSuccess = false
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.requestCodeSuccess = false
|
||||
})
|
||||
},
|
||||
|
||||
//登录
|
||||
async handleSubmit() {
|
||||
if (this.isSubmitting) {
|
||||
return
|
||||
}
|
||||
try {
|
||||
await this.$refs.formRef.validate()
|
||||
try {
|
||||
const loginParams = {
|
||||
username: this.model.username,
|
||||
password: this.model.password,
|
||||
captcha: this.model.inputCode,
|
||||
checkKey: this.currdatetime,
|
||||
}
|
||||
this.isSubmitting = true
|
||||
const res = await this.Login(loginParams)
|
||||
this.loginSuccess()
|
||||
} catch (error) {
|
||||
if (error && error.code === 412) {
|
||||
this.handleChangeCheckCode()
|
||||
}
|
||||
this.requestFailed(error)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
},
|
||||
// 校验失败
|
||||
validateFail(){
|
||||
this.loginBtn = false;
|
||||
},
|
||||
// 登录后台成功
|
||||
requestSuccess(loginResult){
|
||||
this.$refs.loginSelect.show(loginResult)
|
||||
},
|
||||
//登录后台失败
|
||||
|
||||
//登录失败
|
||||
requestFailed(err) {
|
||||
let description = ((err.response || {}).data || {}).message || err.message || "请求出现错误,请稍后再试"
|
||||
let description = ((err.response || {}).data || {}).message || err.message || 'Request Error'
|
||||
this.$notification['error']({
|
||||
message: '登录失败',
|
||||
message: 'Login Failed',
|
||||
description: description,
|
||||
duration: 4,
|
||||
});
|
||||
})
|
||||
//账户密码登录错误后更新验证码
|
||||
if(this.customActiveKey === 'tab1' && description.indexOf('密码错误')>0){
|
||||
this.$refs.alogin.handleChangeCheckCode()
|
||||
}
|
||||
this.loginBtn = false;
|
||||
},
|
||||
loginSelectOk(){
|
||||
this.loginSuccess()
|
||||
this.handleChangeCheckCode()
|
||||
this.isSubmitting = false
|
||||
},
|
||||
|
||||
//登录成功
|
||||
loginSuccess() {
|
||||
this.$router.push({ path: "/station-operation" }).catch(()=>{
|
||||
this.$router.push({ path: '/station-operation' }).catch(() => {
|
||||
console.log('登录跳转首页出错,这个错误从哪里来的')
|
||||
})
|
||||
this.$notification.success({
|
||||
message: '欢迎',
|
||||
description: `${timeFix()},欢迎回来`,
|
||||
});
|
||||
},
|
||||
|
||||
stepCaptchaSuccess () {
|
||||
this.loginSuccess()
|
||||
},
|
||||
stepCaptchaCancel () {
|
||||
this.Logout().then(() => {
|
||||
this.loginBtn = false
|
||||
this.stepCaptchaVisible = false
|
||||
message: 'Welcome',
|
||||
description: `${timeFix()},Welcome Back`,
|
||||
})
|
||||
},
|
||||
//获取密码加密规则
|
||||
getEncrypte(){
|
||||
var encryptedString = Vue.ls.get(ENCRYPTED_STRING);
|
||||
if(encryptedString == null){
|
||||
getEncryptedString().then((data) => {
|
||||
this.encryptedString = data
|
||||
});
|
||||
}else{
|
||||
this.encryptedString = encryptedString;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.user-layout-login {
|
||||
label {
|
||||
font-size: 14px;
|
||||
}
|
||||
.getCaptcha {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
}
|
||||
.login-page {
|
||||
height: 100%;
|
||||
background: url(~@/assets/images/login/bg.jpg) center no-repeat;
|
||||
background-size: cover;
|
||||
|
||||
.forge-password {
|
||||
font-size: 14px;
|
||||
}
|
||||
.login-form {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
right: 295px;
|
||||
transform: translateY(-50%);
|
||||
|
||||
button.login-button {
|
||||
padding: 0 15px;
|
||||
font-size: 16px;
|
||||
height: 40px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.user-login-other {
|
||||
text-align: left;
|
||||
margin-top: 24px;
|
||||
line-height: 22px;
|
||||
|
||||
.item-icon {
|
||||
font-size: 24px;
|
||||
color: rgba(0,0,0,.2);
|
||||
margin-left: 16px;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
transition: color .3s;
|
||||
|
||||
&:hover {
|
||||
color: #1890ff;
|
||||
.logo {
|
||||
img {
|
||||
width: 578px;
|
||||
height: 233px;
|
||||
}
|
||||
}
|
||||
|
||||
.register {
|
||||
.ant-form {
|
||||
margin-right: 24px;
|
||||
float: right;
|
||||
|
||||
&-item {
|
||||
margin-bottom: 20px !important;
|
||||
::v-deep {
|
||||
.ant-form-item-label {
|
||||
line-height: 17px;
|
||||
label {
|
||||
font-size: 22px;
|
||||
color: #fff;
|
||||
padding-left: 6px;
|
||||
&::before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-form-explain {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: -36px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.ant-form-item-children {
|
||||
width: 444px;
|
||||
height: 60px;
|
||||
.ant-input {
|
||||
padding-left: 70px;
|
||||
padding-right: 15px;
|
||||
height: 100%;
|
||||
font-size: 26px;
|
||||
background-color: transparent !important;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.username {
|
||||
::v-deep {
|
||||
.ant-form-item-children {
|
||||
background: url(~@/assets/images/login/username-bg.png) center no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.password {
|
||||
::v-deep {
|
||||
.ant-form-item-children {
|
||||
background: url(~@/assets/images/login/pwd-bg.png) center no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.validate-code {
|
||||
width: 444px;
|
||||
::v-deep {
|
||||
.ant-form-item-children {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.ant-input {
|
||||
width: 294px;
|
||||
background: url(~@/assets/images/login/validate-bg.png) center no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
.validate-image {
|
||||
width: 135px;
|
||||
height: 60px;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.remember-pwd {
|
||||
user-select: none;
|
||||
margin-top: -20px;
|
||||
margin-left: 5px;
|
||||
.ant-checkbox-wrapper {
|
||||
color: #6ebad0;
|
||||
}
|
||||
}
|
||||
|
||||
.login-button {
|
||||
width: 444px;
|
||||
height: 76px;
|
||||
margin-top: 44px;
|
||||
background: url(~@/assets/images/login/login-btn.png) center no-repeat;
|
||||
border: 0;
|
||||
padding-bottom: 15px;
|
||||
::v-deep {
|
||||
.anticon-loading {
|
||||
font-size: 22px;
|
||||
}
|
||||
span {
|
||||
font-family: MicrogrammaD-MediExte;
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
text-shadow: 0px 2px 4px rgba(0, 0, 0, 0.61);
|
||||
}
|
||||
}
|
||||
&:focus,
|
||||
&.ant-btn-loading {
|
||||
background-image: url(~@/assets/images/login/login-btn-active.png);
|
||||
}
|
||||
&::before,
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.valid-error .ant-select-selection__placeholder{
|
||||
color: #f5222d;
|
||||
}
|
||||
</style>
|