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,205 +1,308 @@
 | 
			
		|||
<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 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-model-item>
 | 
			
		||||
        <a-checkbox @change="handleRememberMeChange" default-checked>自动登录</a-checkbox>
 | 
			
		||||
      </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>
 | 
			
		||||
 | 
			
		||||
    </a-form-model>
 | 
			
		||||
    <login-select-tenant ref="loginSelect" @success="loginSelectOk"></login-select-tenant>
 | 
			
		||||
        <!-- 验证码结束 -->
 | 
			
		||||
        <!-- 记住密码 -->
 | 
			
		||||
        <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>
 | 
			
		||||
    </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:"",
 | 
			
		||||
        },
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    created() {
 | 
			
		||||
      Vue.ls.remove(ACCESS_TOKEN)
 | 
			
		||||
      this.getRouterData();
 | 
			
		||||
      this.rememberMe = true
 | 
			
		||||
    },
 | 
			
		||||
    methods:{
 | 
			
		||||
      handleTabClick(key){
 | 
			
		||||
        this.customActiveKey = key
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      isSubmitting: false,
 | 
			
		||||
      randCodeImage: '',
 | 
			
		||||
      requestCodeSuccess: false,
 | 
			
		||||
      model: {
 | 
			
		||||
        username: '',
 | 
			
		||||
        password: '',
 | 
			
		||||
        inputCode: '',
 | 
			
		||||
        rememberPwd: true
 | 
			
		||||
      },
 | 
			
		||||
      handleRememberMeChange(e){
 | 
			
		||||
        this.rememberMe = e.target.checked
 | 
			
		||||
      rules: {
 | 
			
		||||
        username: [{ required: true, message: 'Username Required' }],
 | 
			
		||||
        password: [
 | 
			
		||||
          {
 | 
			
		||||
            required: true,
 | 
			
		||||
            message: 'Password Required'
 | 
			
		||||
          },
 | 
			
		||||
        ],
 | 
			
		||||
        inputCode: [
 | 
			
		||||
          {
 | 
			
		||||
            required: true,
 | 
			
		||||
            message: 'Captchar Required',
 | 
			
		||||
          },
 | 
			
		||||
        ],
 | 
			
		||||
      },
 | 
			
		||||
      /**跳转到登录页面的参数-账号获取*/
 | 
			
		||||
      getRouterData(){
 | 
			
		||||
        this.$nextTick(() => {
 | 
			
		||||
          let temp = this.$route.params.username || this.$route.query.username || ''
 | 
			
		||||
          if (temp) {
 | 
			
		||||
            this.$refs.alogin.acceptUsername(temp)
 | 
			
		||||
      currdatetime: '',
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  created() {
 | 
			
		||||
    Vue.ls.remove(ACCESS_TOKEN)
 | 
			
		||||
    this.getRouterData()
 | 
			
		||||
    this.handleChangeCheckCode()
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    ...mapActions(['Login']),
 | 
			
		||||
 | 
			
		||||
    /**跳转到登录页面的参数-账号获取*/
 | 
			
		||||
    getRouterData() {
 | 
			
		||||
      this.$nextTick(() => {
 | 
			
		||||
        let temp = this.$route.params.username || this.$route.query.username || ''
 | 
			
		||||
        if (temp) {
 | 
			
		||||
          this.$refs.alogin.acceptUsername(temp)
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /**刷新验证码*/
 | 
			
		||||
    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.$message.error(res.message)
 | 
			
		||||
            this.requestCodeSuccess = false
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
      },
 | 
			
		||||
 | 
			
		||||
      //登录
 | 
			
		||||
      handleSubmit () {
 | 
			
		||||
        this.loginBtn = true;
 | 
			
		||||
        if (this.customActiveKey === 'tab1') {
 | 
			
		||||
          // 使用账户密码登录
 | 
			
		||||
          this.$refs.alogin.handleLogin(this.rememberMe)
 | 
			
		||||
        } else {
 | 
			
		||||
          //手机号码登录
 | 
			
		||||
          this.$refs.plogin.handleLogin(this.rememberMe)
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      // 校验失败
 | 
			
		||||
      validateFail(){
 | 
			
		||||
        this.loginBtn = false;
 | 
			
		||||
      },
 | 
			
		||||
      // 登录后台成功
 | 
			
		||||
      requestSuccess(loginResult){
 | 
			
		||||
        this.$refs.loginSelect.show(loginResult)
 | 
			
		||||
      },
 | 
			
		||||
      //登录后台失败
 | 
			
		||||
      requestFailed (err) {
 | 
			
		||||
        let description = ((err.response || {}).data || {}).message || err.message || "请求出现错误,请稍后再试"
 | 
			
		||||
        this.$notification[ 'error' ]({
 | 
			
		||||
          message: '登录失败',
 | 
			
		||||
          description: description,
 | 
			
		||||
          duration: 4,
 | 
			
		||||
        });
 | 
			
		||||
        //账户密码登录错误后更新验证码
 | 
			
		||||
        if(this.customActiveKey === 'tab1' && description.indexOf('密码错误')>0){
 | 
			
		||||
          this.$refs.alogin.handleChangeCheckCode()
 | 
			
		||||
        }
 | 
			
		||||
        this.loginBtn = false;
 | 
			
		||||
      },
 | 
			
		||||
      loginSelectOk(){
 | 
			
		||||
        this.loginSuccess()
 | 
			
		||||
      },
 | 
			
		||||
      //登录成功
 | 
			
		||||
      loginSuccess () {
 | 
			
		||||
        this.$router.push({ path: "/station-operation" }).catch(()=>{
 | 
			
		||||
          console.log('登录跳转首页出错,这个错误从哪里来的')
 | 
			
		||||
        .catch(() => {
 | 
			
		||||
          this.requestCodeSuccess = false
 | 
			
		||||
        })
 | 
			
		||||
        this.$notification.success({
 | 
			
		||||
          message: '欢迎',
 | 
			
		||||
          description: `${timeFix()},欢迎回来`,
 | 
			
		||||
        });
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
      stepCaptchaSuccess () {
 | 
			
		||||
        this.loginSuccess()
 | 
			
		||||
      },
 | 
			
		||||
      stepCaptchaCancel () {
 | 
			
		||||
        this.Logout().then(() => {
 | 
			
		||||
          this.loginBtn = false
 | 
			
		||||
          this.stepCaptchaVisible = false
 | 
			
		||||
        })
 | 
			
		||||
      },
 | 
			
		||||
      //获取密码加密规则
 | 
			
		||||
      getEncrypte(){
 | 
			
		||||
        var encryptedString = Vue.ls.get(ENCRYPTED_STRING);
 | 
			
		||||
        if(encryptedString == null){
 | 
			
		||||
          getEncryptedString().then((data) => {
 | 
			
		||||
            this.encryptedString = data
 | 
			
		||||
          });
 | 
			
		||||
        }else{
 | 
			
		||||
          this.encryptedString = encryptedString;
 | 
			
		||||
        }
 | 
			
		||||
    //登录
 | 
			
		||||
    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)
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
    //登录失败
 | 
			
		||||
    requestFailed(err) {
 | 
			
		||||
      let description = ((err.response || {}).data || {}).message || err.message || 'Request Error'
 | 
			
		||||
      this.$notification['error']({
 | 
			
		||||
        message: 'Login Failed',
 | 
			
		||||
        description: description,
 | 
			
		||||
        duration: 4,
 | 
			
		||||
      })
 | 
			
		||||
      //账户密码登录错误后更新验证码
 | 
			
		||||
      this.handleChangeCheckCode()
 | 
			
		||||
      this.isSubmitting = false
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
    //登录成功
 | 
			
		||||
    loginSuccess() {
 | 
			
		||||
      this.$router.push({ path: '/station-operation' }).catch(() => {
 | 
			
		||||
        console.log('登录跳转首页出错,这个错误从哪里来的')
 | 
			
		||||
      })
 | 
			
		||||
      this.$notification.success({
 | 
			
		||||
        message: 'Welcome',
 | 
			
		||||
        description: `${timeFix()},Welcome Back`,
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
}
 | 
			
		||||
</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;
 | 
			
		||||
 | 
			
		||||
  .login-form {
 | 
			
		||||
    position: fixed;
 | 
			
		||||
    top: 50%;
 | 
			
		||||
    right: 295px;
 | 
			
		||||
    transform: translateY(-50%);
 | 
			
		||||
 | 
			
		||||
    .logo {
 | 
			
		||||
      img {
 | 
			
		||||
        width: 578px;
 | 
			
		||||
        height: 233px;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  .forge-password {
 | 
			
		||||
      font-size: 14px;
 | 
			
		||||
    }
 | 
			
		||||
    .ant-form {
 | 
			
		||||
      margin-right: 24px;
 | 
			
		||||
      float: right;
 | 
			
		||||
 | 
			
		||||
    button.login-button {
 | 
			
		||||
      padding: 0 15px;
 | 
			
		||||
      font-size: 16px;
 | 
			
		||||
      height: 40px;
 | 
			
		||||
      width: 100%;
 | 
			
		||||
    }
 | 
			
		||||
      &-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;
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
  .user-login-other {
 | 
			
		||||
      text-align: left;
 | 
			
		||||
      margin-top: 24px;
 | 
			
		||||
      line-height: 22px;
 | 
			
		||||
          .ant-form-explain {
 | 
			
		||||
            position: absolute;
 | 
			
		||||
            right: 0;
 | 
			
		||||
            top: -36px;
 | 
			
		||||
            font-size: 18px;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
    .item-icon {
 | 
			
		||||
        font-size: 24px;
 | 
			
		||||
        color: rgba(0,0,0,.2);
 | 
			
		||||
        margin-left: 16px;
 | 
			
		||||
        vertical-align: middle;
 | 
			
		||||
        cursor: pointer;
 | 
			
		||||
        transition: color .3s;
 | 
			
		||||
          .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;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      &:hover {
 | 
			
		||||
          color: #1890ff;
 | 
			
		||||
        &.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%;
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    .register {
 | 
			
		||||
        float: right;
 | 
			
		||||
      .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>
 | 
			
		||||