Prechádzať zdrojové kódy

登录日志删除和清空

xusl 2 rokov pred
rodič
commit
f1ad6869b3

+ 107 - 0
backend/src/main/java/com/jiayue/ssi/controller/SysLogininforController.java

@@ -0,0 +1,107 @@
+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.entity.SysLogininfor;
+import com.jiayue.ssi.service.SysLogininforService;
+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.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 系统访问记录
+ *
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/sysLogininforController")
+@Slf4j
+public class SysLogininforController {
+    @Autowired
+    SysLogininforService sysLogininforService;
+
+    /**
+     * 获取列表分页信息
+     *
+     * @return 列表信息
+     */
+    @GetMapping(value = "/getAll")
+    @InterfaceLimit
+    public ResponseVO getAll(Integer currentPage, Integer pageSize, String ipaddr, String userName,
+                             String status,String startLoginTime,String endLoginTime) {
+        try {
+            QueryWrapper<SysLogininfor> wrapper = new QueryWrapper<>();
+            if (StringUtils.isNotEmpty(ipaddr)) {
+                wrapper.eq("ipaddr", ipaddr);
+            }
+            if (StringUtils.isNotEmpty(userName)) {
+                wrapper.eq("user_name", userName);
+            }
+            if (StringUtils.isNotEmpty(status)) {
+                wrapper.eq("status", status);
+            }
+            if (StringUtils.isNotEmpty(startLoginTime)) {
+                wrapper.ge("login_time", DateUtils.getDayStartTime(DateUtil.parseDate(startLoginTime)));
+            }
+            if (StringUtils.isNotEmpty(endLoginTime)) {
+                wrapper.le("login_time", DateUtils.getDayLastTime(DateUtil.parseDate(endLoginTime)));
+            }
+            Page<SysLogininfor> result = sysLogininforService.page(new Page<>(currentPage, pageSize), wrapper);
+            return ResponseVO.success(result);
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("获取登录日志列表异常");
+            return ResponseVO.error(null);
+        }
+    }
+
+    /**
+     * 删除登录信息
+     */
+    @PostMapping(value = "/delLoginInfo")
+    @InterfaceLimit
+    public ResponseVO delLoginInfo(String infoId) {
+        if (StringUtils.isEmpty(infoId)) {
+            return ResponseVO.fail("id不能为空!");
+        }
+        try {
+            boolean bo = sysLogininforService.removeLoginInfoById(Long.parseLong(infoId));
+            if (bo) {
+                return ResponseVO.success("删除登录信息成功");
+            } else {
+                log.error("删除用户信息失败");
+                return ResponseVO.fail("删除登录信息失败");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("删除登录信息异常");
+            return ResponseVO.error(e);
+        }
+    }
+    /**
+     * 清空登录信息
+     */
+    @PostMapping("/cleanLogininfor")
+    @InterfaceLimit
+    public ResponseVO cleanLogininfor() {
+        try {
+            boolean bo = sysLogininforService.cleanLogininfor();
+            if (bo) {
+                return ResponseVO.success("清空成功");
+            } else {
+                log.error("清空失败");
+                return ResponseVO.fail("清空失败");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("清空异常");
+            return ResponseVO.error(e);
+        }
+    }
+}

+ 2 - 1
backend/src/main/java/com/jiayue/ssi/factory/LoginFactory.java

@@ -47,6 +47,7 @@ public class LoginFactory {
         logininfor.setOs(os);
         logininfor.setMsg(message);
         logininfor.setLoginTime(new Date());
+        logininfor.setCreateBy(username);
         // 日志状态
         if (RyStringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER))
         {
@@ -57,7 +58,7 @@ public class LoginFactory {
             logininfor.setStatus(Constants.FAIL);
         }
         // 插入数据
-        SpringUtils.getBean(SysLogininforService.class).save(logininfor);
+        SpringUtils.getBean(SysLogininforService.class).insertLogininfor(logininfor);
     }
 
     public static String getBlock(Object msg)

+ 0 - 1
backend/src/main/java/com/jiayue/ssi/mapper/SysLogininforMapper.java

@@ -3,7 +3,6 @@ package com.jiayue.ssi.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.jiayue.ssi.entity.SysLogininfor;
-import com.jiayue.ssi.entity.SysMenu;
 import org.apache.ibatis.annotations.Mapper;
 
 import java.util.List;

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

@@ -2,41 +2,28 @@ package com.jiayue.ssi.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.jiayue.ssi.entity.SysLogininfor;
-import com.jiayue.ssi.entity.SysMenu;
 
-import java.util.List;
 
 /**
- * 系统访问日志情况信息 服务层
- *
- * @author ruoyi
+ * 系统访问日志服务类
+ * @author xsl
+ * @date 2023/2/16
  */
 public interface SysLogininforService extends IService<SysLogininfor> {
-//    /**
-//     * 新增系统登录日志
-//     *
-//     * @param logininfor 访问日志对象
-//     */
-//    public void insertLogininfor(SysLogininfor logininfor);
-//
-//    /**
-//     * 查询系统登录日志集合
-//     *
-//     * @param logininfor 访问日志对象
-//     * @return 登录记录集合
-//     */
-//    public List<SysLogininfor> selectLogininforList(SysLogininfor logininfor);
-//
-//    /**
-//     * 批量删除系统登录日志
-//     *
-//     * @param infoIds 需要删除的登录日志ID
-//     * @return 结果
-//     */
-//    public int deleteLogininforByIds(Long[] infoIds);
-//
-//    /**
-//     * 清空系统登录日志
-//     */
-//    public void cleanLogininfor();
+    /**
+     * 新增系统登录日志
+     *
+     * @param logininfor 访问日志对象
+     */
+    void insertLogininfor(SysLogininfor logininfor);
+    /**
+     * 删除用户
+     * @param infoId
+     * @return
+     */
+    boolean removeLoginInfoById(Long infoId);
+    /**
+     * 清空系统登录日志
+     */
+    boolean cleanLogininfor();
 }

+ 43 - 0
backend/src/main/java/com/jiayue/ssi/service/impl/SysLogininforServiceImpl.java

@@ -1,12 +1,16 @@
 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.SysLogininfor;
 import com.jiayue.ssi.entity.SysMenu;
+import com.jiayue.ssi.entity.SysUser;
 import com.jiayue.ssi.mapper.SysLogininforMapper;
 import com.jiayue.ssi.mapper.SysMenuMapper;
 import com.jiayue.ssi.service.SysLogininforService;
 import com.jiayue.ssi.service.SysMenuService;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 /**
@@ -17,5 +21,44 @@ import org.springframework.stereotype.Service;
 */
 @Service
 public class SysLogininforServiceImpl  extends ServiceImpl<SysLogininforMapper, SysLogininfor> implements SysLogininforService {
+    @Autowired
+    private SysLogininforMapper logininforMapper;
 
+    /**
+     * 新增系统登录日志
+     *
+     * @param logininfor 访问日志对象
+     */
+    @Override
+    public void insertLogininfor(SysLogininfor logininfor) {
+        logininforMapper.insertLogininfor(logininfor);
+    }
+    /**
+     * 删除登录信息
+     * @param infoId
+     * @return
+     */
+    @Override
+    public boolean removeLoginInfoById(Long infoId) {
+        LambdaUpdateWrapper<SysLogininfor> updateWrapper = new UpdateWrapper<SysLogininfor>().lambda();
+        updateWrapper.eq(SysLogininfor::getInfoId, infoId).set(SysLogininfor::getDelFlag, 1);
+        int count = logininforMapper.update(new SysLogininfor(), updateWrapper);
+        if (count > 0) {
+            return true;
+        }
+        return false;
+    }
+    /**
+     * 清空系统登录日志
+     */
+    @Override
+    public boolean cleanLogininfor() {
+        LambdaUpdateWrapper<SysLogininfor> updateWrapper = new UpdateWrapper<SysLogininfor>().lambda();
+        updateWrapper.eq(SysLogininfor::getDelFlag,0).set(SysLogininfor::getDelFlag, 1);
+        int count = logininforMapper.update(new SysLogininfor(), updateWrapper);
+        if (count > 0) {
+            return true;
+        }
+        return false;
+    }
 }

+ 34 - 0
backend/src/main/java/com/jiayue/ssi/util/DateUtils.java

@@ -4,8 +4,10 @@ import java.lang.management.ManagementFactory;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.time.*;
+import java.util.Calendar;
 import java.util.Date;
 
+import com.sun.istack.internal.NotNull;
 import org.apache.commons.lang3.time.DateFormatUtils;
 
 /**
@@ -181,4 +183,36 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
         ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
         return Date.from(zdt.toInstant());
     }
+
+    /**
+     * 获取指定时间所在天的0点0分
+     *
+     * @param dateTime 时间毫秒
+     * @return 0点0分的毫秒
+     */
+    public static Date getDayStartTime(Date dateTime) {
+        Calendar date = Calendar.getInstance();
+        date.setTime(dateTime);
+        date.set(Calendar.HOUR_OF_DAY, 0);
+        date.set(Calendar.MINUTE, 0);
+        date.set(Calendar.SECOND, 0);
+        date.set(Calendar.MILLISECOND, 0);
+        return date.getTime();
+    }
+
+    /**
+     * 获取指定时间所在天的23点59分59秒
+     *
+     * @param dateTime 时间毫秒
+     * @return 23点59分59秒的毫秒
+     */
+    public static Date getDayLastTime(Date dateTime) {
+        Calendar date = Calendar.getInstance();
+        date.setTime(dateTime);
+        date.set(Calendar.HOUR_OF_DAY, 23);
+        date.set(Calendar.MINUTE, 59);
+        date.set(Calendar.SECOND, 59);
+        date.set(Calendar.MILLISECOND, 999);
+        return date.getTime();
+    }
 }

+ 63 - 0
backend/src/main/resources/mapper/system/SysLogininforMapper.xml

@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.jiayue.ssi.mapper.SysLogininforMapper">
+
+	<resultMap type="SysLogininfor" id="SysLogininforResult">
+		<id     property="infoId"        column="info_id"           />
+		<result property="userName"      column="user_name"         />
+		<result property="status"        column="status"            />
+		<result property="ipaddr"        column="ipaddr"            />
+		<result property="loginLocation" column="login_location"    />
+		<result property="browser"       column="browser"           />
+		<result property="os"            column="os"                />
+		<result property="msg"           column="msg"               />
+		<result property="loginTime"     column="login_time"        />
+		<result property="createBy"       column="create_by"      />
+		<result property="createTime"     column="create_time"    />
+		<result property="updateTime"     column="update_time"    />
+		<result property="updateBy"       column="update_by"      />
+		<result property="remark"         column="remark"         />
+		<result property="delFlag"         column="del_flag"         />
+	</resultMap>
+
+	<insert id="insertLogininfor" parameterType="SysLogininfor">
+		insert into sys_logininfor (user_name, status, ipaddr, login_location, browser, os, msg, login_time,create_by,create_time,del_flag)
+		values (#{userName}, #{status}, #{ipaddr}, #{loginLocation}, #{browser}, #{os}, #{msg}, sysdate(),#{createBy},sysdate(),0)
+	</insert>
+
+	<select id="selectLogininforList" parameterType="SysLogininfor" resultMap="SysLogininforResult">
+		select info_id, user_name, ipaddr, login_location, browser, os, status, msg, login_time from sys_logininfor
+		<where>
+			<if test="ipaddr != null and ipaddr != ''">
+				AND ipaddr like concat('%', #{ipaddr}, '%')
+			</if>
+			<if test="status != null and status != ''">
+				AND status = #{status}
+			</if>
+			<if test="userName != null and userName != ''">
+				AND user_name like concat('%', #{userName}, '%')
+			</if>
+			<if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
+				and date_format(login_time,'%y%m%d') &gt;= date_format(#{params.beginTime},'%y%m%d')
+			</if>
+			<if test="params.endTime != null and params.endTime != ''"><!-- 结束时间检索 -->
+				and date_format(login_time,'%y%m%d') &lt;= date_format(#{params.endTime},'%y%m%d')
+			</if>
+		</where>
+		order by info_id desc
+	</select>
+
+	<delete id="deleteLogininforByIds" parameterType="Long">
+ 		delete from sys_logininfor where info_id in
+ 		<foreach collection="array" item="infoId" open="(" separator="," close=")">
+ 			#{infoId}
+        </foreach>
+ 	</delete>
+
+    <update id="cleanLogininfor">
+        truncate table sys_logininfor
+    </update>
+
+</mapper>

+ 310 - 0
ui/src/views/auditManager/logininfo/index.vue

@@ -0,0 +1,310 @@
+<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="ipaddr">
+        <el-input
+          v-model="queryParams.ipaddr"
+          placeholder="请输入登录地址"
+          clearable
+          style="width: 240px;"
+        />
+      </el-form-item>
+      <el-form-item label="用户名称" prop="userName">
+        <el-input
+          v-model="queryParams.userName"
+          placeholder="请输入用户名称"
+          clearable
+          style="width: 240px;"
+        />
+      </el-form-item>
+      <el-form-item label="状态" prop="status">
+        <el-select
+          v-model="queryParams.status"
+          placeholder="登录状态"
+          clearable
+          style="width: 240px"
+        >
+          <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: 240px"
+          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="infoId" title="访问编号"/>
+        <vxe-table-column field="userName" title="用户账号"/>
+        <vxe-table-column field="ipaddr" title="登录地址" width="130"/>
+        <vxe-table-column field="loginLocation" title="登录地点"/>
+        <vxe-table-column field="browser" title="浏览器"/>
+        <vxe-table-column field="os" title="操作系统"/>
+        <vxe-table-column field="status" title="登录状态" :formatter="statusFormat"/>
+        <vxe-table-column field="msg" title="操作信息"/>
+        <vxe-table-column field="loginTime" title="登录日期"/>
+      </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>
+  </div>
+</template>
+
+<script>
+
+import {debounce} from "lodash";
+
+export default {
+  name: "Logininfor",
+  data() {
+    return {
+      showTable: true,
+      currentPage: 1,
+      pageSize: 10,
+      // 总条数
+      total: 0,
+      statusOptions: [
+        {value: '0', label: '成功'},
+        {value: '1', label: '失败'}
+      ],
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 选择用户名
+      selectName: "",
+      // 显示搜索条件
+      showSearch: true,
+      // 表格数据
+      list: [],
+      // 日期范围
+      dateRange: [],
+      // 默认排序
+      defaultSort: {prop: 'loginTime', order: 'descending'},
+      // 查询参数
+      queryParams: {
+        ipaddr: undefined,
+        userName: 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
+    },
+    /** 查询登录日志列表 */
+    getList:debounce(function(){
+      this.loading = true;
+      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]
+      }
+      this.$axios.get('/sysLogininforController/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),
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.dateRange = [];
+      this.resetForm("queryForm");
+    },
+    /** 删除按钮操作 */
+    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 = {
+        infoId: _selectData.infoId
+      }
+      this.$axios.post('/sysLogininforController/delLoginInfo', 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.cleanLogininfor();
+      }).catch(() => {
+      })
+    },
+    /**
+     * 清空提交
+     */
+    cleanLogininfor:debounce(function(){
+      this.$axios.post('/sysLogininforController/cleanLogininfor',{}).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>
+

+ 2 - 2
ui/src/views/monitor/server/index.vue

@@ -314,14 +314,14 @@ export default {
   },
   created() {
     this.getList();
-    this.openLoading();
+    // this.openLoading();
   },
   methods: {
     /** 查询服务器信息 */
     getList() {
       getServer().then(response => {
         this.server = response.data;
-        this.$modal.closeLoading();
+        // this.$modal.closeLoading();
       });
     },
     // 打开加载层

+ 0 - 2
ui/src/views/sysManager/userManager/index.vue

@@ -42,7 +42,6 @@
             <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
@@ -285,7 +284,6 @@ export default {
     },
     /** 查询用户列表 */
     getList:debounce(function(){
-      console.log("==============查询用户列表===================")
       this.loading = true;
       var searchParams = {
         currentPage: this.currentPage,