Browse Source

日志记录删除、清空功能

xusl 2 years ago
parent
commit
cd13d6b107

+ 111 - 0
backend/src/main/java/com/jiayue/ssi/controller/SysOperlogController.java

@@ -0,0 +1,111 @@
+package com.jiayue.ssi.controller;
+
+import cn.hutool.core.date.DateUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.jiayue.ssi.annotation.InterfaceLimit;
+import com.jiayue.ssi.annotation.OperateLog;
+import com.jiayue.ssi.backenum.BusinessType;
+import com.jiayue.ssi.entity.SysOperLog;
+import com.jiayue.ssi.service.SysOperLogService;
+import com.jiayue.ssi.util.DateUtils;
+import com.jiayue.ssi.util.ResponseVO;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 操作日志记录
+ *
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/sysOperlogController")
+@Slf4j
+public class SysOperlogController {
+    @Autowired
+    SysOperLogService sysOperLogService;
+    /**
+     * 获取列表分页信息
+     *
+     * @return 列表信息
+     */
+    @GetMapping(value = "/getAll")
+    @InterfaceLimit
+    public ResponseVO getAll(Integer currentPage, Integer pageSize, String title, String operName,
+                             String businessType, String status,String startOperTime, String endOperTime) {
+        try {
+            QueryWrapper<SysOperLog> wrapper = new QueryWrapper<>();
+            if (StringUtils.isNotEmpty(title)) {
+                wrapper.like("title", title);
+            }
+            if (StringUtils.isNotEmpty(operName)) {
+                wrapper.like("oper_name", operName);
+            }
+            if (StringUtils.isNotEmpty(businessType)) {
+                wrapper.eq("business_type", businessType);
+            }
+            if (StringUtils.isNotEmpty(status)) {
+                wrapper.eq("status", status);
+            }
+            if (StringUtils.isNotEmpty(startOperTime)) {
+                wrapper.ge("oper_time", DateUtils.getDayStartTime(DateUtil.parseDate(startOperTime)));
+            }
+            if (StringUtils.isNotEmpty(endOperTime)) {
+                wrapper.le("oper_time", DateUtils.getDayLastTime(DateUtil.parseDate(endOperTime)));
+            }
+            Page<SysOperLog> result = sysOperLogService.page(new Page<>(currentPage, pageSize), wrapper);
+            return ResponseVO.success(result);
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("获取操作日志列表异常");
+            return ResponseVO.error(null);
+        }
+    }
+    /**
+     * 删除登录信息
+     */
+    @PostMapping(value = "/delOperlog")
+    @InterfaceLimit
+    @OperateLog(title = "操作日志", businessType = BusinessType.DELETE)
+    public ResponseVO delOperlog(String operId) {
+        if (StringUtils.isEmpty(operId)) {
+            return ResponseVO.fail("id不能为空!");
+        }
+        try {
+            boolean bo = sysOperLogService.removeOperlogById(Long.parseLong(operId));
+            if (bo) {
+                return ResponseVO.success("删除操作信息成功");
+            } else {
+                log.error("删除操作信息失败");
+                return ResponseVO.fail("删除操作信息失败");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("删除操作信息异常");
+            return ResponseVO.error(e);
+        }
+    }
+    /**
+     * 清空登录信息
+     */
+    @PostMapping("/cleanOperLog")
+    @InterfaceLimit
+    @OperateLog(title = "操作日志", businessType = BusinessType.CLEAN)
+    public ResponseVO cleanOperLog() {
+        try {
+            boolean bo = sysOperLogService.cleanOperLog();
+            if (bo) {
+                return ResponseVO.success("清空成功");
+            } else {
+                log.error("清空失败");
+                return ResponseVO.fail("清空失败");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("清空异常");
+            return ResponseVO.error(e);
+        }
+    }
+}

+ 2 - 0
backend/src/main/java/com/jiayue/ssi/entity/SysOperLog.java

@@ -1,5 +1,6 @@
 package com.jiayue.ssi.entity;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.fasterxml.jackson.annotation.JsonFormat;
 
 import java.util.Date;
@@ -22,6 +23,7 @@ public class SysOperLog extends BaseEntity {
     private Integer businessType;
 
     /** 业务类型数组 */
+    @TableField(exist = false)
     private Integer[] businessTypes;
 
     /** 请求方法 */

+ 1 - 1
backend/src/main/java/com/jiayue/ssi/service/SysLogininforService.java

@@ -17,7 +17,7 @@ public interface SysLogininforService extends IService<SysLogininfor> {
      */
     void insertLogininfor(SysLogininfor logininfor);
     /**
-     * 删除用户
+     * 删除登录日志
      * @param infoId
      * @return
      */

+ 10 - 29
backend/src/main/java/com/jiayue/ssi/service/SysOperLogService.java

@@ -19,33 +19,14 @@ public interface SysOperLogService extends IService<SysOperLog> {
      * @param operLog 操作日志对象
      */
     void insertOperlog(SysOperLog operLog);
-//
-//    /**
-//     * 查询系统操作日志集合
-//     *
-//     * @param operLog 操作日志对象
-//     * @return 操作日志集合
-//     */
-//    public List<SysOperLog> selectOperLogList(SysOperLog operLog);
-//
-//    /**
-//     * 批量删除系统操作日志
-//     *
-//     * @param operIds 需要删除的操作日志ID
-//     * @return 结果
-//     */
-//    public int deleteOperLogByIds(Long[] operIds);
-//
-//    /**
-//     * 查询操作日志详细
-//     *
-//     * @param operId 操作ID
-//     * @return 操作日志对象
-//     */
-//    public SysOperLog selectOperLogById(Long operId);
-//
-//    /**
-//     * 清空操作日志
-//     */
-//    public void cleanOperLog();
+    /**
+     * 删除操作日志
+     * @param operId
+     * @return
+     */
+    boolean removeOperlogById(Long operId);
+    /**
+     * 清空操作日志
+     */
+    boolean cleanOperLog();
 }

+ 30 - 47
backend/src/main/java/com/jiayue/ssi/service/impl/SysOperLogServiceImpl.java

@@ -1,5 +1,7 @@
 package com.jiayue.ssi.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.jiayue.ssi.entity.SysOperLog;
 import com.jiayue.ssi.mapper.SysOperLogMapper;
@@ -7,8 +9,6 @@ import com.jiayue.ssi.service.SysOperLogService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-
 /**
  * 操作日志 服务层处理
  *
@@ -29,49 +29,32 @@ public class SysOperLogServiceImpl  extends ServiceImpl<SysOperLogMapper, SysOpe
     {
         operLogMapper.insertOperlog(operLog);
     }
-
-//    /**
-//     * 查询系统操作日志集合
-//     *
-//     * @param operLog 操作日志对象
-//     * @return 操作日志集合
-//     */
-//    @Override
-//    public List<SysOperLog> selectOperLogList(SysOperLog operLog)
-//    {
-//        return operLogMapper.selectOperLogList(operLog);
-//    }
-//
-//    /**
-//     * 批量删除系统操作日志
-//     *
-//     * @param operIds 需要删除的操作日志ID
-//     * @return 结果
-//     */
-//    @Override
-//    public int deleteOperLogByIds(Long[] operIds)
-//    {
-//        return operLogMapper.deleteOperLogByIds(operIds);
-//    }
-//
-//    /**
-//     * 查询操作日志详细
-//     *
-//     * @param operId 操作ID
-//     * @return 操作日志对象
-//     */
-//    @Override
-//    public SysOperLog selectOperLogById(Long operId)
-//    {
-//        return operLogMapper.selectOperLogById(operId);
-//    }
-//
-//    /**
-//     * 清空操作日志
-//     */
-//    @Override
-//    public void cleanOperLog()
-//    {
-//        operLogMapper.cleanOperLog();
-//    }
+    /**
+     * 删除操作日志
+     * @param operId
+     * @return
+     */
+    @Override
+    public boolean removeOperlogById(Long operId) {
+        LambdaUpdateWrapper<SysOperLog> updateWrapper = new UpdateWrapper<SysOperLog>().lambda();
+        updateWrapper.eq(SysOperLog::getOperId, operId).set(SysOperLog::getDelFlag, 1);
+        int count = operLogMapper.update(new SysOperLog(), updateWrapper);
+        if (count > 0) {
+            return true;
+        }
+        return false;
+    }
+    /**
+     * 清空操作日志
+     */
+    @Override
+    public boolean cleanOperLog() {
+        LambdaUpdateWrapper<SysOperLog> updateWrapper = new UpdateWrapper<SysOperLog>().lambda();
+        updateWrapper.eq(SysOperLog::getDelFlag,0).set(SysOperLog::getDelFlag, 1);
+        int count = operLogMapper.update(new SysOperLog(), updateWrapper);
+        if (count > 0) {
+            return true;
+        }
+        return false;
+    }
 }

+ 11 - 2
ui/src/views/auditManager/logininfo/index.vue

@@ -179,14 +179,23 @@ export default {
     /** 查询登录日志列表 */
     getList:debounce(function(){
       this.loading = true;
+      let _startOperTime;
+      let _endOperTime;
+      if (this.dateRange == null) {
+        _startOperTime = ''
+        _endOperTime = ''
+      } else {
+        _startOperTime = this.dateRange[0]
+        _endOperTime = this.dateRange[1]
+      }
       var searchParams = {
         currentPage: this.currentPage,
         pageSize: this.pageSize,
         ipaddr: this.queryParams.ipaddr,
         userName: this.queryParams.userName,
         status: this.queryParams.status,
-        startLoginTime:this.dateRange[0],
-        endLoginTime:this.dateRange[1]
+        startLoginTime:_startOperTime,
+        endLoginTime:_endOperTime
       }
       this.$axios.get('/sysLogininforController/getAll',
         {params: searchParams}).then((res) => {

+ 447 - 0
ui/src/views/auditManager/operlog/index.vue

@@ -0,0 +1,447 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="系统模块" prop="title">
+        <el-input
+          v-model="queryParams.title"
+          placeholder="请输入系统模块"
+          clearable
+          style="width: 220px;"
+        />
+      </el-form-item>
+      <el-form-item label="操作人员" prop="operName">
+        <el-input
+          v-model="queryParams.operName"
+          placeholder="请输入操作人员"
+          clearable
+          style="width: 220px;"
+        />
+      </el-form-item>
+      <el-form-item label="类型" prop="businessType">
+        <el-select
+          v-model="queryParams.businessType"
+          placeholder="操作类型"
+          clearable
+          style="width: 220px"
+        >
+          <el-option
+            v-for="dict in operTypeOptions"
+            :key="dict.value"
+            :label="dict.label"
+            :value="dict.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="状态" prop="status">
+        <el-select
+          v-model="queryParams.status"
+          placeholder="操作状态"
+          clearable
+          style="width: 220px"
+        >
+          <el-option
+            v-for="dict in statusOptions"
+            :key="dict.value"
+            :label="dict.label"
+            :value="dict.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="操作时间">
+        <el-date-picker
+          v-model="dateRange"
+          style="width: 230px"
+          value-format="yyyy-MM-dd"
+          type="daterange"
+          range-separator="-"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+        ></el-date-picker>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          @click="handleDelete"
+        >删除
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          @click="handleClean"
+        >清空
+        </el-button>
+      </el-col>
+    </el-row>
+
+    <div style="padding-top: 10px">
+      <vxe-table
+        ref="tables"
+        align="center"
+        :loading="loading"
+        class="mytable-style"
+        auto-resize
+        border
+        resizable
+        export-config
+        highlight-current-row
+        show-overflow
+        max-height="700"
+        :data="list"
+        :radio-config="{trigger: 'row'}"
+      >
+        <vxe-column type="radio" width="60"/>
+        <vxe-table-column field="operId" title="日志编号"/>
+        <vxe-table-column field="title" title="系统模块"/>
+        <vxe-table-column field="businessType" title="操作类型" :formatter="operTypeFormat"/>
+        <vxe-table-column field="operName" title="操作人员"/>
+        <vxe-table-column field="operIp" title="操作地址"/>
+        <vxe-table-column field="operLocation" title="操作地点"/>
+        <vxe-table-column field="status" title="操作状态" :formatter="statusFormat"/>
+        <vxe-table-column field="operTime" title="操作日期"/>
+        <vxe-table-column field="costTime" title="消耗时间(毫秒)"/>
+        <vxe-table-column title="操作">
+          <template slot-scope="scope">
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-view"
+              @click="handleView(scope.row,scope.index)"
+            >详细
+            </el-button>
+          </template>
+        </vxe-table-column>
+      </vxe-table>
+      <vxe-pager
+        v-show="showTable"
+        perfect
+        :current-page.sync="currentPage"
+        :page-size.sync="pageSize"
+        :total="total"
+        :page-sizes="[10,50,100]"
+        :layouts="['PrevJump', 'PrevPage','JumpNumber', 'NextPage', 'NextJump', 'Sizes', 'FullJump', 'Total']"
+        @page-change="handlePageChange"
+      >
+      </vxe-pager>
+    </div>
+
+    <!-- 操作日志详细 -->
+    <el-dialog title="操作日志详细" :visible.sync="open" width="700px" append-to-body>
+      <el-form ref="form" :model="form" label-width="100px" size="mini">
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="操作模块:">{{ form.title }}</el-form-item>
+            <el-form-item
+              label="登录信息:"
+            >{{ form.operName }} / {{ form.operIp }} / {{ form.operLocation }}
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="请求地址:">{{ form.operUrl }}</el-form-item>
+            <el-form-item label="请求方式:">{{ form.requestMethod }}</el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="操作方法:">{{ form.method }}</el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="请求参数:">{{ form.operParam }}</el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="返回参数:">{{ form.jsonResult }}</el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="操作状态:">
+              <div v-if="form.status === 0">正常</div>
+              <div v-else-if="form.status === 1">失败</div>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="消耗时间:">{{ form.costTime }}毫秒</el-form-item>
+          </el-col>
+          <el-col :span="10">
+            <el-form-item label="操作时间:">{{ parseTime(form.operTime) }}</el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="异常信息:" v-if="form.status === 1">{{ form.errorMsg }}</el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="open = false">关 闭</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+// import { list, delOperlog, cleanOperlog } from "@/api/monitor/operlog";
+
+import {debounce} from "lodash";
+
+export default {
+  name: "Operlog",
+  dicts: ['sys_oper_type', 'sys_common_status'],
+  data() {
+    return {
+      showTable: true,
+      currentPage: 1,
+      pageSize: 10,
+      ///** 业务类型(0=其它,1=新增,2=修改,3=删除,4=授权,5=导出,6=导入,7=强退,8=生成代码,9=清空数据) */
+      operTypeOptions: [
+        {value: '1', label: '新增'},
+        {value: '2', label: '修改'},
+        {value: '3', label: '删除'},
+        {value: '4', label: '授权'},
+        {value: '9', label: '清空数据'},
+        {value: '0', label: '其他'}
+      ],
+      statusOptions: [
+        {value: '0', label: '成功'},
+        {value: '1', label: '失败'}
+      ],
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 表格数据
+      list: [],
+      // 是否显示弹出层
+      open: false,
+      // 日期范围
+      dateRange: [],
+      // 默认排序
+      defaultSort: {prop: 'operTime', order: 'descending'},
+      // 表单参数
+      form: {},
+      // 查询参数
+      queryParams: {
+        title: undefined,
+        operName: undefined,
+        businessType: undefined,
+        status: undefined
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    handlePageChange({currentPage, pageSize}) {
+      this.currentPage = currentPage
+      this.pageSize = pageSize
+      this.getList()
+    },
+    // 列表状态格式化
+    statusFormat({cellValue}) {
+      let belongTo = '未知的类型'
+      for (let i = 0; i < this.statusOptions.length; i++) {
+        if (cellValue == "0") {
+          belongTo = "成功"
+        } else if (cellValue == "1") {
+          belongTo = "失败"
+        }
+      }
+      return belongTo
+    },
+    // 列表状态格式化
+    operTypeFormat({cellValue}) {
+      let belongTo = '未知的类型'
+      for (let i = 0; i < this.operTypeOptions.length; i++) {
+        if (cellValue == "1") {
+          belongTo = "新增"
+        } else if (cellValue == "2") {
+          belongTo = "修改"
+        } else if (cellValue == "3") {
+          belongTo = "删除"
+        } else if (cellValue == "4") {
+          belongTo = "授权"
+        } else if (cellValue == "9") {
+          belongTo = "清空数据"
+        } else if (cellValue == "0") {
+          belongTo = "其他"
+        }
+      }
+      return belongTo
+    },
+
+    /** 查询操作日志列表 */
+    getList: debounce(function () {
+      this.loading = true;
+      let _startOperTime;
+      let _endOperTime;
+      if (this.dateRange == null) {
+        _startOperTime = ''
+        _endOperTime = ''
+      } else {
+        _startOperTime = this.dateRange[0]
+        _endOperTime = this.dateRange[1]
+      }
+      var searchParams = {
+        currentPage: this.currentPage,
+        pageSize: this.pageSize,
+        title: this.queryParams.title,
+        operName: this.queryParams.operName,
+        businessType: this.queryParams.businessType,
+        status: this.queryParams.status,
+        startOperTime: _startOperTime,
+        endOperTime: _endOperTime
+      }
+      this.$axios.get('/sysOperlogController/getAll',
+        {params: searchParams}).then((res) => {
+        this.list = res.data.records
+        this.total = res.data.total
+        if (res.data.records == '') {
+          this.showTable = false
+        } else {
+          this.showTable = true
+        }
+        this.loading = false
+      }).catch((error) => {
+        // this.$message.error(error)
+      })
+    }, 1000),
+    // 操作日志类型字典翻译
+    typeFormat(row, column) {
+      // return this.selectDictLabel(this.dict.type.sys_oper_type, row.businessType);
+      return ''
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.dateRange = [];
+      this.resetForm("queryForm");
+    },
+    /** 多选框选中数据 */
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.operId)
+      this.multiple = !selection.length
+    },
+    /** 排序触发事件 */
+    handleSortChange(column, prop, order) {
+      this.queryParams.orderByColumn = column.prop;
+      this.queryParams.isAsc = column.order;
+      this.getList();
+    },
+    /** 详细按钮操作 */
+    handleView(row) {
+      this.open = true;
+      this.form = row;
+    },
+    /** 删除按钮操作 */
+    handleDelete() {
+      const _selectData = this.$refs.tables.getRadioRecord(true)
+      if (_selectData == null) {
+        this.$message({
+          type: 'warning',
+          message: '请选择记录!'
+        });
+        return
+      }
+      this.$confirm('是否确认删除操作日志?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.doDelete(_selectData)
+      }).catch(() => {
+      });
+    },
+    /**
+     * 删除提交
+     */
+    doDelete: debounce(function (_selectData) {
+      const param = {
+        operId: _selectData.operId
+      }
+      this.$axios.post('/sysOperlogController/delOperlog', param).then((res) => {
+        if (res.code == 0) {
+          this.$message({
+            type: 'success',
+            message: '删除成功!'
+          });
+          this.getList();
+        } else {
+          this.$message({
+            type: 'error',
+            message: res.data
+          });
+        }
+      }).catch((error) => {
+        this.$message({
+          type: 'error',
+          message: '删除失败!'
+        });
+        console.log(error)
+        this.loading = false
+      })
+    }, 1000),
+    /** 清空按钮操作 */
+    handleClean() {
+      if (this.list == '') {
+        this.$message({
+          type: 'warning',
+          message: '没有记录不能清空!'
+        });
+        return
+      }
+      this.$confirm('是否确认清空所有操作日志数据项?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.cleanOperLog();
+      }).catch(() => {
+      })
+    },
+    /**
+     * 清空提交
+     */
+    cleanOperLog: debounce(function () {
+      this.$axios.post('/sysOperlogController/cleanOperLog', {}).then((res) => {
+        if (res.code == 0) {
+          this.$message({
+            type: 'success',
+            message: '清空成功!'
+          });
+          this.getList();
+        } else {
+          this.$message({
+            type: 'error',
+            message: res.data
+          });
+        }
+      }).catch((error) => {
+        this.$message({
+          type: 'error',
+          message: '清空失败!'
+        });
+        console.log(error)
+        this.loading = false
+      })
+    }, 1000)
+  }
+};
+</script>
+