石广澎
2023-12-29 5d745c2c8854d2c1e94e5ee9004d5219681f6d7c
增加图片验证码和登录日志
1个文件已添加
3个文件已修改
250 ■■■■ 已修改文件
admin-web/public/static/config.js 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin-web/src/utils/auth.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin-web/src/views/login/index.vue 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin-web/src/views/systemSetting/logs/loginLogs.vue 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin-web/public/static/config.js
@@ -4,12 +4,12 @@
const SettingIplatform = {
  // 服务器地址
  // 上传路径
  ftpUrl: 'https://yqzx.jinmingyuan.com/lowConsum',//测试
  // ftpUrl: protocol + '//'+ host + '/file',// 正式,
  /*ftpUrl: 'https://yqzx.jinmingyuan.com/lowConsum',//测试
  apiBaseURL: 'https://yqzx.jinmingyuan.com/lowConsum',//测试*/
  // 接口请求地址
  // apiBaseURL: 'https://yqzx.jinmingyuan.com/lowConsum',//测试
  // apiBaseURL: 'http://127.0.0.1:8083/lowConsum',//开发
  // apiBaseURL: 'http://172.16.60.155:8083/lowConsum',//开发
  /*ftpUrl: 'http://172.16.20.6:8083/lowConsum',//开发
  apiBaseURL: 'http://172.16.20.6:8083/lowConsum',//开发*/
  ftpUrl: protocol + '//'+ host + '/file',// 正式,
  apiBaseURL: protocol + '//'+ host + '/lowapi',// 正式,
  debug: false //调试开关  true时会输出请求日志
};
admin-web/src/utils/auth.js
@@ -1,6 +1,6 @@
import storage from 'store';
const TokenKey = 'iplatform_token';
const TokenKey = 'low_consum_iplatform_token';
const userKey = 'user'
const userInfo = 'userInfo'
export function getToken() {
admin-web/src/views/login/index.vue
@@ -52,24 +52,20 @@
                      :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'"
                    /></span>
                  </el-form-item>
<!--                  <el-form-item prop="code" class="captcha" v-if="loginForm.verifyType==='code' && captchaEnabled">-->
<!--                    <div class="captcha">-->
<!--                      <el-input-->
<!--                        v-model.trim="loginForm.code"-->
<!--                        style="width: 218px"-->
<!--                        prefix-icon="el-icon-message"-->
<!--                        placeholder="验证码"-->
<!--                        type="text"-->
<!--                        tabindex="3"-->
<!--                        autocomplete="off"-->
<!--                      />-->
<!--                      <div class="imgs" @click="getCode()">-->
<!--                        &lt;!&ndash;                <img :src="captchatImg" />&ndash;&gt;-->
<!--                        <img :src="codeUrl"/>-->
<!--                        <span v-show="showCaptchatImg">已失效</span>-->
<!--                      </div>-->
<!--                    </div>-->
<!--                  </el-form-item>-->
                  <el-form-item prop="code" class="captcha" v-if="loginForm.verifyType==='code' && captchaEnabled">
                    <el-input
                      v-model.trim="loginForm.code"
                      style="width: 218px"
                      placeholder="验证码"
                      type="text"
                      tabindex="3"
                      autocomplete="off"
                    />
                    <div class="imgs" @click="getCode()">
                      <img :src="codeUrl"/>
                      <span v-show="showCaptchatImg">已失效</span>
                    </div>
                  </el-form-item>
                  <el-button
                    id="loginBtn"
                    :loading="loading"
@@ -127,18 +123,13 @@
        },
      },
      loginForm: {
        account: 'jmy123456', // admin
        password: 'Adu_8097',
        account: '', // admin
        password: '',
        // key: '',
        uuid: '',
        code: '',
        loginType: 'user_pass',  // 用户名、密码方式登录
        verifyType: 'code'     //  'code': 验证码  'slide':滑块  'jigsaw':拼图
        // captcha: {
        //   captchaVerification: '',
        //   secretKey: '',
        //   token: '',
        // },
      },
      loginRules: {
        account: [{required: true, trigger: 'blur', message: '请输入用户名'}], // validator: validateUsername
@@ -154,7 +145,7 @@
      disabled: false,
      isWeixin: this.$wechat.isWeixin(),
      // 验证码开关
      captchaEnabled: true
      captchaEnabled: false
    };
  },
  components: {},
@@ -272,7 +263,7 @@
      if (this.loginForm.verifyType === 'code') {
        getCodeImg().then(data => {
          this.captchaEnabled = data.captchaEnabled === undefined ? true : data.captchaEnabled;
          console.log("captchaEnabled = " + this.captchaEnabled);
          if (this.captchaEnabled) {
            this.codeUrl = "data:image/jpeg;base64," + data.img;
          }
@@ -328,16 +319,20 @@
    color: $cursor;
  }
}
.flex-1 {
  flex: 1;
}
.min-1200 {
  min-width: 1200px;
}
/* reset element-ui css */
.login-container {
  padding:50px;
  padding: 50px;
  line-height: 54px;
  .el-form-item__content {
    display: flex;
    flex: 1;
@@ -347,18 +342,20 @@
    background-color: #F1F3F5;
    border-radius: 4px;
  }
  .el-input {
    flex: 1;
    margin-left: 6px;
    position: relative;
    background-color: #F1F3F5;
    top: 3px;
    input {
      border: none;
      padding: 0;
      font-size: 16px;
      line-height: 54px;
      background: #F1F3F5;
      // background: #F1F3F5;
      color: #333333;
    }
  }
@@ -366,9 +363,34 @@
</style>
<style lang="scss" scoped>
.captcha {
  display: flex;
  align-items: flex-start;
}
$bg: #2d3a4b;
$dark_gray: #889aa4;
$light_gray: #eee;
.imgs {
  position: relative;
  height: 36px;
  cursor: pointer;
  img {
    height: 100%;
  }
  span {
    width: 84px;
    line-height: 36px;
    display: inline-block;
    background: rgba(0, 0, 0, 0.4);
    position: absolute;
    left: 0;
    color: #fff;
  }
}
.login-container {
  height: 100%;
  width: 100%;
@@ -377,45 +399,53 @@
  background-size: cover;
  position: relative;
}
.school-logo{
.school-logo {
  position: absolute;
  top:30px;
  top: 30px;
  left: 40px;
}
.form-main{
.form-main {
  background-color: #FFFFFF;
  overflow: hidden;
  border-radius: 8px;
}
>>>.el-button{
> > > .el-button {
  font-size: 16px;
}
.logo-name{
  width: 336px;
  height: 51px;
.logo-name {
  margin-bottom: 30px;
}
.logo-lf{
  width:100%;
.logo-lf {
  width: 100%;
}
.login-box{
  padding:100px;
  .title{
.login-box {
  padding: 100px;
  .title {
    font-size: 22px;
    font-weight: bold;
  }
  .f-lable{
  .f-lable {
    line-height: 20px;
    margin-bottom: 10px;
    font-size: 14px;
    color: #333333;
  }
}
.w1050 {
  width: 1050px;
  margin: 0 auto;
  overflow: hidden;
}
.login-btn {
  width: 100%;
  height: 45px;
@@ -424,11 +454,13 @@
  color: #FFFFFF;
  background-color: #0d997c;
}
.logo-txt {
  position: absolute;
  top: 5%;
  left: 2%;
}
.txtBox {
  color: #fff;
  opacity: 0.7;
@@ -441,24 +473,27 @@
  line-height: 30px;
  width: 610px;
}
.show-pwd{
.show-pwd {
  position: relative;
  top:5px;
  top: 5px;
  right: 5px;
  cursor: pointer;
}
.td-outer-wrapper {
  width: 1200px !important;
  margin: 0 auto !important;
}
@media screen and(max-width: 1400px) {
  .w1050 {
    width: 850px;
    margin: 0 auto;
    overflow: hidden;
  }
  .login-box{
    padding:40px;
  .login-box {
    padding: 40px;
  }
}
</style>
admin-web/src/views/systemSetting/logs/loginLogs.vue
New file
@@ -0,0 +1,111 @@
<template>
  <div class="app-container">
    <el-card class="box-card" shadow="never" style="width: 100%">
      <!--搜索条件-->
      <div class="filter-container">
        <my-search ref="searchBar" :items="items" @search="fifterForm"></my-search>
      </div>
      <div style="margin-top: 15px">
        <!--列表-->
        <my-table-v2 ref="myTable" :filter="filterFrom" :table="table"/>
      </div>
    </el-card>
  </div>
</template>
<script>
import MyTableV2 from "@/components/myTable/myTableV2";
import SettingIplatform from "@/utils/settingIplatform";
import {LongToDateTime} from "@/utils/DateFormatter";
export default {
  components: {MyTableV2},
  data() {
    return {
      items: [
        {
          type: 'text',
          dataIndex: 'userName',
          label: '登录账号',
          placeholder: '请输入',
          defaultValue: ''
        }
      ],
      // 搜索条件
      filterFrom: {
        userName: null,
      },
      // 表格数据
      table: {
        showIndex: true, // 是否显示序号
        expand: false, // 是否显示详情数据
        url: SettingIplatform.apiBaseURL + '/pc/p/login/info/list', // 请求地址
        // 工具条
        tools: {
          columnsCtrl: {// 列控制按钮
            show: false
          },
          generalExport: {// 通用导出按钮
            show: false
          },
          // 自定义工具条按钮
          custom: []
        },
        // 列信息
        columns: [
          {title: '登录账号', field: 'userName', align: 'left', minWidth: 110},
          {title: '登录IP', field: 'ipaddr', align: 'center'},
          {title: '浏览器类型', field: 'browser', align: 'center'},
          {
            title: '登录状态', field: 'status', align: 'center', formatter: row => {
              return {value: row.status == 1 ? '登录成功' : '登录失败'}
            }
          },
          {title: '提示消息', field: 'msg', align: 'left'},
          {
            title: '访问时间', field: 'login_time', align: 'center', width: 180, formatter: row => {
              return {value: LongToDateTime(row.loginTime)}
            }
          },
        ],
        // 操作信息
        operation: {
          show: false, // 显示操作列
        },
        paging: {
          show: true, // 显示分页
          // 分页信息
          page: {
            small: false,
            pageNumber: 1,
            pageSize: 10,
            total: 0
          }
        }
      },
    }
  },
  mounted() {
  },
  methods: {
    // 查询table列表
    search(pageNumber) {
      if (pageNumber != undefined) {
        this.$refs.myTable.search(pageNumber)
      } else {
        this.$refs.myTable.search()
      }
    },
    fifterForm(params) {
      this.filterFrom = Object.assign(this.filterFrom, params)
      this.search(1)
    },
  }
}
</script>
<style scoped>
</style>