Commit 1768d27e1154c1d5486f0c6e4cd3107ddbeda4ac
1 parent
2fccaa2b
完善新操作日志的页面修改
Showing
34 changed files
with
649 additions
and
664 deletions
pom.xml
| @@ -22,7 +22,7 @@ | @@ -22,7 +22,7 @@ | ||
| 22 | <maven.compiler.target>${java.version}</maven.compiler.target> | 22 | <maven.compiler.target>${java.version}</maven.compiler.target> |
| 23 | <maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version> | 23 | <maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version> |
| 24 | <!-- 统一依赖管理 --> | 24 | <!-- 统一依赖管理 --> |
| 25 | - <spring.boot.version>2.4.1</spring.boot.version> | 25 | + <spring.boot.version>2.4.2</spring.boot.version> |
| 26 | 26 | ||
| 27 | <!-- <ruoyi.version>3.3.0</ruoyi.version>--> | 27 | <!-- <ruoyi.version>3.3.0</ruoyi.version>--> |
| 28 | <!-- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>--> | 28 | <!-- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>--> |
ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java
| @@ -23,28 +23,12 @@ import com.ruoyi.system.service.ISysOperLogService; | @@ -23,28 +23,12 @@ import com.ruoyi.system.service.ISysOperLogService; | ||
| 23 | * | 23 | * |
| 24 | * @author ruoyi | 24 | * @author ruoyi |
| 25 | */ | 25 | */ |
| 26 | -@RestController | ||
| 27 | -@RequestMapping("/monitor/operlog") | 26 | + |
| 28 | public class SysOperlogController extends BaseController { | 27 | public class SysOperlogController extends BaseController { |
| 29 | 28 | ||
| 30 | @Autowired | 29 | @Autowired |
| 31 | private ISysOperLogService operLogService; | 30 | private ISysOperLogService operLogService; |
| 32 | 31 | ||
| 33 | - @PreAuthorize("@ss.hasPermi('monitor:operlog:list')") | ||
| 34 | - @GetMapping("/list") | ||
| 35 | - public TableDataInfo list(SysOperLog operLog) { | ||
| 36 | - startPage(); | ||
| 37 | - List<SysOperLog> list = operLogService.selectOperLogList(operLog); | ||
| 38 | - return getDataTable(list); | ||
| 39 | - } | ||
| 40 | - | ||
| 41 | - @Log(title = "操作日志", businessType = BusinessType.EXPORT) | ||
| 42 | - @PreAuthorize("@ss.hasPermi('monitor:operlog:export')") | ||
| 43 | - @GetMapping("/export") | ||
| 44 | - public AjaxResult export(SysOperLog operLog) { | ||
| 45 | - List<SysOperLog> list = operLogService.selectOperLogList(operLog); | ||
| 46 | - ExcelUtil<SysOperLog> util = new ExcelUtil<SysOperLog>(SysOperLog.class); | ||
| 47 | - return util.exportExcel(list, "操作日志"); | ||
| 48 | - } | 32 | + |
| 49 | 33 | ||
| 50 | } | 34 | } |
ruoyi-common/pom.xml deleted
| 1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | -<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| 3 | - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| 4 | - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| 5 | - <parent> | ||
| 6 | - <artifactId>ruoyi</artifactId> | ||
| 7 | - <groupId>com.ruoyi</groupId> | ||
| 8 | - <version>3.3.0</version> | ||
| 9 | - </parent> | ||
| 10 | - <modelVersion>4.0.0</modelVersion> | ||
| 11 | - | ||
| 12 | - <artifactId>ruoyi-common</artifactId> | ||
| 13 | - | ||
| 14 | - <description> | ||
| 15 | - common通用工具 | ||
| 16 | - </description> | ||
| 17 | - | ||
| 18 | - <dependencies> | ||
| 19 | - | ||
| 20 | - <!-- yml解析器 --> | ||
| 21 | - <dependency> | ||
| 22 | - <groupId>org.yaml</groupId> | ||
| 23 | - <artifactId>snakeyaml</artifactId> | ||
| 24 | - </dependency> | ||
| 25 | - | ||
| 26 | - <!-- 解析客户端操作系统、浏览器等 --> | ||
| 27 | - <dependency> | ||
| 28 | - <groupId>eu.bitwalker</groupId> | ||
| 29 | - <artifactId>UserAgentUtils</artifactId> | ||
| 30 | - </dependency> | ||
| 31 | - | ||
| 32 | - | ||
| 33 | - </dependencies> | ||
| 34 | - | ||
| 35 | -</project> |
ruoyi-common/src/main/java/com/ruoyi/common/annotation/Log.java deleted
| 1 | -package com.ruoyi.common.annotation; | ||
| 2 | - | ||
| 3 | -import java.lang.annotation.Documented; | ||
| 4 | -import java.lang.annotation.ElementType; | ||
| 5 | -import java.lang.annotation.Retention; | ||
| 6 | -import java.lang.annotation.RetentionPolicy; | ||
| 7 | -import java.lang.annotation.Target; | ||
| 8 | -import com.ruoyi.common.enums.BusinessType; | ||
| 9 | -import com.ruoyi.common.enums.OperatorType; | ||
| 10 | - | ||
| 11 | -/** | ||
| 12 | - * 自定义操作日志记录注解 | ||
| 13 | - * | ||
| 14 | - * @author ruoyi | ||
| 15 | - * | ||
| 16 | - */ | ||
| 17 | -@Target({ ElementType.PARAMETER, ElementType.METHOD }) | ||
| 18 | -@Retention(RetentionPolicy.RUNTIME) | ||
| 19 | -@Documented | ||
| 20 | -public @interface Log | ||
| 21 | -{ | ||
| 22 | - /** | ||
| 23 | - * 模块 | ||
| 24 | - */ | ||
| 25 | - public String title() default ""; | ||
| 26 | - | ||
| 27 | - /** | ||
| 28 | - * 功能 | ||
| 29 | - */ | ||
| 30 | - public BusinessType businessType() default BusinessType.OTHER; | ||
| 31 | - | ||
| 32 | - /** | ||
| 33 | - * 操作人类别 | ||
| 34 | - */ | ||
| 35 | - public OperatorType operatorType() default OperatorType.MANAGE; | ||
| 36 | - | ||
| 37 | - /** | ||
| 38 | - * 是否保存请求的参数 | ||
| 39 | - */ | ||
| 40 | - public boolean isSaveRequestData() default true; | ||
| 41 | -} |
ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java deleted
| 1 | -package com.ruoyi.framework.aspectj; | ||
| 2 | - | ||
| 3 | -import java.lang.reflect.Method; | ||
| 4 | -import java.util.Collection; | ||
| 5 | -import java.util.Iterator; | ||
| 6 | -import java.util.Map; | ||
| 7 | -import javax.servlet.http.HttpServletRequest; | ||
| 8 | -import javax.servlet.http.HttpServletResponse; | ||
| 9 | - | ||
| 10 | -import org.aspectj.lang.JoinPoint; | ||
| 11 | -import org.aspectj.lang.Signature; | ||
| 12 | -import org.aspectj.lang.annotation.AfterReturning; | ||
| 13 | -import org.aspectj.lang.annotation.AfterThrowing; | ||
| 14 | -import org.aspectj.lang.annotation.Aspect; | ||
| 15 | -import org.aspectj.lang.annotation.Pointcut; | ||
| 16 | -import org.aspectj.lang.reflect.MethodSignature; | ||
| 17 | -import org.slf4j.Logger; | ||
| 18 | -import org.slf4j.LoggerFactory; | ||
| 19 | -import org.springframework.stereotype.Component; | ||
| 20 | -import org.springframework.web.multipart.MultipartFile; | ||
| 21 | -import org.springframework.web.servlet.HandlerMapping; | ||
| 22 | -import com.alibaba.fastjson.JSON; | ||
| 23 | -import com.ruoyi.common.annotation.Log; | ||
| 24 | -import com.ruoyi.common.core.domain.model.LoginUser; | ||
| 25 | -import com.ruoyi.common.enums.BusinessStatus; | ||
| 26 | -import com.ruoyi.common.enums.HttpMethod; | ||
| 27 | -import com.ruoyi.common.utils.ServletUtils; | ||
| 28 | -import com.ruoyi.common.utils.StringUtils; | ||
| 29 | -import com.ruoyi.common.utils.ip.IpUtils; | ||
| 30 | -import com.ruoyi.common.utils.spring.SpringUtils; | ||
| 31 | -import com.ruoyi.framework.manager.AsyncManager; | ||
| 32 | -import com.ruoyi.framework.manager.factory.AsyncFactory; | ||
| 33 | -import com.ruoyi.framework.web.service.TokenService; | ||
| 34 | -import com.ruoyi.system.domain.SysOperLog; | ||
| 35 | - | ||
| 36 | -/** | ||
| 37 | - * 操作日志记录处理 | ||
| 38 | - * | ||
| 39 | - * @author ruoyi | ||
| 40 | - */ | ||
| 41 | -@Aspect | ||
| 42 | -@Component | ||
| 43 | -public class LogAspect { | ||
| 44 | - private static final Logger log = LoggerFactory.getLogger(LogAspect.class); | ||
| 45 | - | ||
| 46 | - // 配置织入点 | ||
| 47 | - @Pointcut("@annotation(com.ruoyi.common.annotation.Log)") | ||
| 48 | - public void logPointCut() { | ||
| 49 | - } | ||
| 50 | - | ||
| 51 | - /** | ||
| 52 | - * 处理完请求后执行 | ||
| 53 | - * | ||
| 54 | - * @param joinPoint 切点 | ||
| 55 | - */ | ||
| 56 | - @AfterReturning(pointcut = "logPointCut()", returning = "jsonResult") | ||
| 57 | - public void doAfterReturning(JoinPoint joinPoint, Object jsonResult) { | ||
| 58 | - handleLog(joinPoint, null, jsonResult); | ||
| 59 | - } | ||
| 60 | - | ||
| 61 | - /** | ||
| 62 | - * 拦截异常操作 | ||
| 63 | - * | ||
| 64 | - * @param joinPoint 切点 | ||
| 65 | - * @param e 异常 | ||
| 66 | - */ | ||
| 67 | - @AfterThrowing(value = "logPointCut()", throwing = "e") | ||
| 68 | - public void doAfterThrowing(JoinPoint joinPoint, Exception e) { | ||
| 69 | - handleLog(joinPoint, e, null); | ||
| 70 | - } | ||
| 71 | - | ||
| 72 | - protected void handleLog(final JoinPoint joinPoint, final Exception e, Object jsonResult) { | ||
| 73 | - try { | ||
| 74 | - // 获得注解 | ||
| 75 | - Log controllerLog = getAnnotationLog(joinPoint); | ||
| 76 | - if (controllerLog == null) { | ||
| 77 | - return; | ||
| 78 | - } | ||
| 79 | - | ||
| 80 | - // 获取当前的用户 | ||
| 81 | - LoginUser loginUser = SpringUtils.getBean(TokenService.class).getLoginUser(ServletUtils.getRequest()); | ||
| 82 | - | ||
| 83 | - // *========数据库日志=========*// | ||
| 84 | - SysOperLog operLog = new SysOperLog(); | ||
| 85 | - operLog.setStatus(BusinessStatus.SUCCESS.ordinal()); | ||
| 86 | - // 请求的地址 | ||
| 87 | - String ip = IpUtils.getIpAddr(ServletUtils.getRequest()); | ||
| 88 | - operLog.setOperIp(ip); | ||
| 89 | - // 返回参数 | ||
| 90 | - operLog.setJsonResult(JSON.toJSONString(jsonResult)); | ||
| 91 | - | ||
| 92 | - operLog.setOperUrl(ServletUtils.getRequest().getRequestURI()); | ||
| 93 | - if (loginUser != null) { | ||
| 94 | - operLog.setOperName(loginUser.getUsername()); | ||
| 95 | - } | ||
| 96 | - | ||
| 97 | - if (e != null) { | ||
| 98 | - operLog.setStatus(BusinessStatus.FAIL.ordinal()); | ||
| 99 | - operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000)); | ||
| 100 | - } | ||
| 101 | - // 设置方法名称 | ||
| 102 | - String className = joinPoint.getTarget().getClass().getName(); | ||
| 103 | - String methodName = joinPoint.getSignature().getName(); | ||
| 104 | - operLog.setMethod(className + "." + methodName + "()"); | ||
| 105 | - // 设置请求方式 | ||
| 106 | - operLog.setRequestMethod(ServletUtils.getRequest().getMethod()); | ||
| 107 | - // 处理设置注解上的参数 | ||
| 108 | - getControllerMethodDescription(joinPoint, controllerLog, operLog); | ||
| 109 | - // 保存数据库 | ||
| 110 | - AsyncManager.me().execute(AsyncFactory.recordOper(operLog)); | ||
| 111 | - } catch (Exception exp) { | ||
| 112 | - // 记录本地异常日志 | ||
| 113 | - log.error("==前置通知异常=="); | ||
| 114 | - log.error("异常信息:{}", exp.getMessage()); | ||
| 115 | - exp.printStackTrace(); | ||
| 116 | - } | ||
| 117 | - } | ||
| 118 | - | ||
| 119 | - /** | ||
| 120 | - * 参数拼装 | ||
| 121 | - */ | ||
| 122 | - private String argsArrayToString(Object[] paramsArray) { | ||
| 123 | - String params = ""; | ||
| 124 | - if (paramsArray != null && paramsArray.length > 0) { | ||
| 125 | - for (int i = 0; i < paramsArray.length; i++) { | ||
| 126 | - if (!isFilterObject(paramsArray[i])) { | ||
| 127 | - Object jsonObj = JSON.toJSON(paramsArray[i]); | ||
| 128 | - params += jsonObj.toString() + " "; | ||
| 129 | - } | ||
| 130 | - } | ||
| 131 | - } | ||
| 132 | - return params.trim(); | ||
| 133 | - } | ||
| 134 | - | ||
| 135 | - /** | ||
| 136 | - * 判断是否需要过滤的对象。 | ||
| 137 | - * | ||
| 138 | - * @param o 对象信息。 | ||
| 139 | - * @return 如果是需要过滤的对象,则返回true;否则返回false。 | ||
| 140 | - */ | ||
| 141 | - @SuppressWarnings("rawtypes") | ||
| 142 | - public boolean isFilterObject(final Object o) { | ||
| 143 | - Class<?> clazz = o.getClass(); | ||
| 144 | - if (clazz.isArray()) { | ||
| 145 | - return clazz.getComponentType().isAssignableFrom(MultipartFile.class); | ||
| 146 | - } else if (Collection.class.isAssignableFrom(clazz)) { | ||
| 147 | - Collection collection = (Collection) o; | ||
| 148 | - for (Iterator iter = collection.iterator(); iter.hasNext(); ) { | ||
| 149 | - return iter.next() instanceof MultipartFile; | ||
| 150 | - } | ||
| 151 | - } else if (Map.class.isAssignableFrom(clazz)) { | ||
| 152 | - Map map = (Map) o; | ||
| 153 | - for (Iterator iter = map.entrySet().iterator(); iter.hasNext(); ) { | ||
| 154 | - Map.Entry entry = (Map.Entry) iter.next(); | ||
| 155 | - return entry.getValue() instanceof MultipartFile; | ||
| 156 | - } | ||
| 157 | - } | ||
| 158 | - return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse; | ||
| 159 | - } | ||
| 160 | -} |
ruoyi-framework/src/main/java/com/ruoyi/framework/config/ApplicationConfig.java deleted
| 1 | -package com.ruoyi.framework.config; | ||
| 2 | - | ||
| 3 | -import java.util.TimeZone; | ||
| 4 | - | ||
| 5 | -import org.mybatis.spring.annotation.MapperScan; | ||
| 6 | -import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; | ||
| 7 | -import org.springframework.context.annotation.Bean; | ||
| 8 | -import org.springframework.context.annotation.Configuration; | ||
| 9 | -import org.springframework.context.annotation.EnableAspectJAutoProxy; | ||
| 10 | - | ||
| 11 | -/** | ||
| 12 | - * 程序注解配置 | ||
| 13 | - * | ||
| 14 | - * @author ruoyi | ||
| 15 | - */ | ||
| 16 | -@Configuration | ||
| 17 | -// 表示通过aop框架暴露该代理对象,AopContext能够访问 | ||
| 18 | -@EnableAspectJAutoProxy(exposeProxy = true) | ||
| 19 | -// 指定要扫描的Mapper类的包的路径 | ||
| 20 | -@MapperScan("com.ruoyi.**.mapper") | ||
| 21 | -public class ApplicationConfig { | ||
| 22 | - /** | ||
| 23 | - * 时区配置 | ||
| 24 | - */ | ||
| 25 | - @Bean | ||
| 26 | - public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() { | ||
| 27 | - return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault()); | ||
| 28 | - } | ||
| 29 | -} |
ruoyi-ui/src/api/monitor/operlog.js renamed to ruoyi-ui/src/api/system/operatelog.js
| 1 | -import request from '@/utils/request' | ||
| 2 | - | ||
| 3 | -// 查询操作日志列表 | ||
| 4 | -export function list(query) { | ||
| 5 | - return request({ | ||
| 6 | - url: '/monitor/operlog/list', | ||
| 7 | - method: 'get', | ||
| 8 | - params: query | ||
| 9 | - }) | ||
| 10 | -} | ||
| 11 | - | ||
| 12 | -// 删除操作日志 | ||
| 13 | -export function delOperlog(operId) { | ||
| 14 | - return request({ | ||
| 15 | - url: '/monitor/operlog/' + operId, | ||
| 16 | - method: 'delete' | ||
| 17 | - }) | ||
| 18 | -} | ||
| 19 | - | ||
| 20 | -// 清空操作日志 | ||
| 21 | -export function cleanOperlog() { | ||
| 22 | - return request({ | ||
| 23 | - url: '/monitor/operlog/clean', | ||
| 24 | - method: 'delete' | ||
| 25 | - }) | ||
| 26 | -} | ||
| 27 | - | ||
| 28 | -// 导出操作日志 | ||
| 29 | -export function exportOperlog(query) { | ||
| 30 | - return request({ | ||
| 31 | - url: '/monitor/operlog/export', | ||
| 32 | - method: 'get', | ||
| 33 | - params: query | ||
| 34 | - }) | ||
| 35 | -} | ||
| 36 | \ No newline at end of file | 1 | \ No newline at end of file |
| 2 | +import request from '@/utils/request' | ||
| 3 | + | ||
| 4 | +// 查询操作日志列表 | ||
| 5 | +export function listOperateLog(query) { | ||
| 6 | + return request({ | ||
| 7 | + url: '/system/operate-log/page', | ||
| 8 | + method: 'get', | ||
| 9 | + params: query | ||
| 10 | + }) | ||
| 11 | +} | ||
| 12 | + | ||
| 13 | +// 导出操作日志 | ||
| 14 | +export function exportOperateLog(query) { | ||
| 15 | + return request({ | ||
| 16 | + url: '/system/operate-log/export', | ||
| 17 | + method: 'get', | ||
| 18 | + params: query | ||
| 19 | + }) | ||
| 20 | +} |
ruoyi-ui/src/main.js
| @@ -23,6 +23,7 @@ import RightToolbar from "@/components/RightToolbar" | @@ -23,6 +23,7 @@ import RightToolbar from "@/components/RightToolbar" | ||
| 23 | // 代码高亮插件 | 23 | // 代码高亮插件 |
| 24 | import hljs from 'highlight.js' | 24 | import hljs from 'highlight.js' |
| 25 | import 'highlight.js/styles/github-gist.css' | 25 | import 'highlight.js/styles/github-gist.css' |
| 26 | +import {DICT_TYPE, getDictDataLabel, getDictDatas} from "@/utils/dict"; | ||
| 26 | 27 | ||
| 27 | // 全局方法挂载 | 28 | // 全局方法挂载 |
| 28 | Vue.prototype.getDicts = getDicts | 29 | Vue.prototype.getDicts = getDicts |
| @@ -32,6 +33,9 @@ Vue.prototype.resetForm = resetForm | @@ -32,6 +33,9 @@ Vue.prototype.resetForm = resetForm | ||
| 32 | Vue.prototype.addDateRange = addDateRange | 33 | Vue.prototype.addDateRange = addDateRange |
| 33 | Vue.prototype.selectDictLabel = selectDictLabel | 34 | Vue.prototype.selectDictLabel = selectDictLabel |
| 34 | Vue.prototype.selectDictLabels = selectDictLabels | 35 | Vue.prototype.selectDictLabels = selectDictLabels |
| 36 | +Vue.prototype.getDictDatas = getDictDatas | ||
| 37 | +Vue.prototype.getDictDataLabel = getDictDataLabel | ||
| 38 | +Vue.prototype.DICT_TYPE = DICT_TYPE | ||
| 35 | Vue.prototype.download = download | 39 | Vue.prototype.download = download |
| 36 | Vue.prototype.downloadExcel = downloadExcel | 40 | Vue.prototype.downloadExcel = downloadExcel |
| 37 | Vue.prototype.handleTree = handleTree | 41 | Vue.prototype.handleTree = handleTree |
ruoyi-ui/src/utils/dict.js
| @@ -12,6 +12,7 @@ export const DICT_TYPE = { | @@ -12,6 +12,7 @@ export const DICT_TYPE = { | ||
| 12 | SYS_DATA_SCOPE: 'sys_data_scope', | 12 | SYS_DATA_SCOPE: 'sys_data_scope', |
| 13 | SYS_USER_SEX: 'sys_user_sex', | 13 | SYS_USER_SEX: 'sys_user_sex', |
| 14 | SYS_NOTICE_TYPE: 'sys_notice_type', | 14 | SYS_NOTICE_TYPE: 'sys_notice_type', |
| 15 | + SYS_OPERATE_TYPE: 'sys_operate_type' | ||
| 15 | } | 16 | } |
| 16 | 17 | ||
| 17 | /** | 18 | /** |
ruoyi-ui/src/views/monitor/operlog/index.vue renamed to ruoyi-ui/src/views/system/operatelog/index.vue
| 1 | -<template> | ||
| 2 | - <div class="app-container"> | ||
| 3 | - <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"> | ||
| 4 | - <el-form-item label="系统模块" prop="title"> | ||
| 5 | - <el-input | ||
| 6 | - v-model="queryParams.title" | ||
| 7 | - placeholder="请输入系统模块" | ||
| 8 | - clearable | ||
| 9 | - style="width: 240px;" | ||
| 10 | - size="small" | ||
| 11 | - @keyup.enter.native="handleQuery" | ||
| 12 | - /> | ||
| 13 | - </el-form-item> | ||
| 14 | - <el-form-item label="操作人员" prop="operName"> | ||
| 15 | - <el-input | ||
| 16 | - v-model="queryParams.operName" | ||
| 17 | - placeholder="请输入操作人员" | ||
| 18 | - clearable | ||
| 19 | - style="width: 240px;" | ||
| 20 | - size="small" | ||
| 21 | - @keyup.enter.native="handleQuery" | ||
| 22 | - /> | ||
| 23 | - </el-form-item> | ||
| 24 | - <el-form-item label="类型" prop="businessType"> | ||
| 25 | - <el-select | ||
| 26 | - v-model="queryParams.businessType" | ||
| 27 | - placeholder="操作类型" | ||
| 28 | - clearable | ||
| 29 | - size="small" | ||
| 30 | - style="width: 240px" | ||
| 31 | - > | ||
| 32 | - <el-option | ||
| 33 | - v-for="dict in typeOptions" | ||
| 34 | - :key="dict.dictValue" | ||
| 35 | - :label="dict.dictLabel" | ||
| 36 | - :value="dict.dictValue" | ||
| 37 | - /> | ||
| 38 | - </el-select> | ||
| 39 | - </el-form-item> | ||
| 40 | - <el-form-item label="状态" prop="status"> | ||
| 41 | - <el-select | ||
| 42 | - v-model="queryParams.status" | ||
| 43 | - placeholder="操作状态" | ||
| 44 | - clearable | ||
| 45 | - size="small" | ||
| 46 | - style="width: 240px" | ||
| 47 | - > | ||
| 48 | - <el-option | ||
| 49 | - v-for="dict in statusOptions" | ||
| 50 | - :key="dict.dictValue" | ||
| 51 | - :label="dict.dictLabel" | ||
| 52 | - :value="dict.dictValue" | ||
| 53 | - /> | ||
| 54 | - </el-select> | ||
| 55 | - </el-form-item> | ||
| 56 | - <el-form-item label="操作时间"> | ||
| 57 | - <el-date-picker | ||
| 58 | - v-model="dateRange" | ||
| 59 | - size="small" | ||
| 60 | - style="width: 240px" | ||
| 61 | - value-format="yyyy-MM-dd" | ||
| 62 | - type="daterange" | ||
| 63 | - range-separator="-" | ||
| 64 | - start-placeholder="开始日期" | ||
| 65 | - end-placeholder="结束日期" | ||
| 66 | - ></el-date-picker> | ||
| 67 | - </el-form-item> | ||
| 68 | - <el-form-item> | ||
| 69 | - <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> | ||
| 70 | - <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> | ||
| 71 | - </el-form-item> | ||
| 72 | - </el-form> | ||
| 73 | - | ||
| 74 | - <el-row :gutter="10" class="mb8"> | ||
| 75 | - <el-col :span="1.5"> | ||
| 76 | - <el-button | ||
| 77 | - type="danger" | ||
| 78 | - icon="el-icon-delete" | ||
| 79 | - size="mini" | ||
| 80 | - :disabled="multiple" | ||
| 81 | - @click="handleDelete" | ||
| 82 | - v-hasPermi="['monitor:operlog:remove']" | ||
| 83 | - >删除</el-button> | ||
| 84 | - </el-col> | ||
| 85 | - <el-col :span="1.5"> | ||
| 86 | - <el-button | ||
| 87 | - type="danger" | ||
| 88 | - icon="el-icon-delete" | ||
| 89 | - size="mini" | ||
| 90 | - @click="handleClean" | ||
| 91 | - v-hasPermi="['monitor:operlog:remove']" | ||
| 92 | - >清空</el-button> | ||
| 93 | - </el-col> | ||
| 94 | - <el-col :span="1.5"> | ||
| 95 | - <el-button | ||
| 96 | - type="warning" | ||
| 97 | - icon="el-icon-download" | ||
| 98 | - size="mini" | ||
| 99 | - @click="handleExport" | ||
| 100 | - v-hasPermi="['system:config:export']" | ||
| 101 | - >导出</el-button> | ||
| 102 | - </el-col> | ||
| 103 | - <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> | ||
| 104 | - </el-row> | ||
| 105 | - | ||
| 106 | - <el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange"> | ||
| 107 | - <el-table-column type="selection" width="55" align="center" /> | ||
| 108 | - <el-table-column label="日志编号" align="center" prop="operId" /> | ||
| 109 | - <el-table-column label="系统模块" align="center" prop="title" /> | ||
| 110 | - <el-table-column label="操作类型" align="center" prop="businessType" :formatter="typeFormat" /> | ||
| 111 | - <el-table-column label="请求方式" align="center" prop="requestMethod" /> | ||
| 112 | - <el-table-column label="操作人员" align="center" prop="operName" /> | ||
| 113 | - <el-table-column label="主机" align="center" prop="operIp" width="130" :show-overflow-tooltip="true" /> | ||
| 114 | - <el-table-column label="操作地点" align="center" prop="operLocation" :show-overflow-tooltip="true" /> | ||
| 115 | - <el-table-column label="操作状态" align="center" prop="status" :formatter="statusFormat" /> | ||
| 116 | - <el-table-column label="操作日期" align="center" prop="operTime" width="180"> | ||
| 117 | - <template slot-scope="scope"> | ||
| 118 | - <span>{{ parseTime(scope.row.operTime) }}</span> | ||
| 119 | - </template> | ||
| 120 | - </el-table-column> | ||
| 121 | - <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | ||
| 122 | - <template slot-scope="scope"> | ||
| 123 | - <el-button | ||
| 124 | - size="mini" | ||
| 125 | - type="text" | ||
| 126 | - icon="el-icon-view" | ||
| 127 | - @click="handleView(scope.row,scope.index)" | ||
| 128 | - v-hasPermi="['monitor:operlog:query']" | ||
| 129 | - >详细</el-button> | ||
| 130 | - </template> | ||
| 131 | - </el-table-column> | ||
| 132 | - </el-table> | ||
| 133 | - | ||
| 134 | - <pagination | ||
| 135 | - v-show="total>0" | ||
| 136 | - :total="total" | ||
| 137 | - :page.sync="queryParams.pageNum" | ||
| 138 | - :limit.sync="queryParams.pageSize" | ||
| 139 | - @pagination="getList" | ||
| 140 | - /> | ||
| 141 | - | ||
| 142 | - <!-- 操作日志详细 --> | ||
| 143 | - <el-dialog title="操作日志详细" :visible.sync="open" width="700px" append-to-body> | ||
| 144 | - <el-form ref="form" :model="form" label-width="100px" size="mini"> | ||
| 145 | - <el-row> | ||
| 146 | - <el-col :span="12"> | ||
| 147 | - <el-form-item label="操作模块:">{{ form.title }} / {{ typeFormat(form) }}</el-form-item> | ||
| 148 | - <el-form-item | ||
| 149 | - label="登录信息:" | ||
| 150 | - >{{ form.operName }} / {{ form.operIp }} / {{ form.operLocation }}</el-form-item> | ||
| 151 | - </el-col> | ||
| 152 | - <el-col :span="12"> | ||
| 153 | - <el-form-item label="请求地址:">{{ form.operUrl }}</el-form-item> | ||
| 154 | - <el-form-item label="请求方式:">{{ form.requestMethod }}</el-form-item> | ||
| 155 | - </el-col> | ||
| 156 | - <el-col :span="24"> | ||
| 157 | - <el-form-item label="操作方法:">{{ form.method }}</el-form-item> | ||
| 158 | - </el-col> | ||
| 159 | - <el-col :span="24"> | ||
| 160 | - <el-form-item label="请求参数:">{{ form.operParam }}</el-form-item> | ||
| 161 | - </el-col> | ||
| 162 | - <el-col :span="24"> | ||
| 163 | - <el-form-item label="返回参数:">{{ form.jsonResult }}</el-form-item> | ||
| 164 | - </el-col> | ||
| 165 | - <el-col :span="12"> | ||
| 166 | - <el-form-item label="操作状态:"> | ||
| 167 | - <div v-if="form.status === 0">正常</div> | ||
| 168 | - <div v-else-if="form.status === 1">失败</div> | ||
| 169 | - </el-form-item> | ||
| 170 | - </el-col> | ||
| 171 | - <el-col :span="12"> | ||
| 172 | - <el-form-item label="操作时间:">{{ parseTime(form.operTime) }}</el-form-item> | ||
| 173 | - </el-col> | ||
| 174 | - <el-col :span="24"> | ||
| 175 | - <el-form-item label="异常信息:" v-if="form.status === 1">{{ form.errorMsg }}</el-form-item> | ||
| 176 | - </el-col> | ||
| 177 | - </el-row> | ||
| 178 | - </el-form> | ||
| 179 | - <div slot="footer" class="dialog-footer"> | ||
| 180 | - <el-button @click="open = false">关 闭</el-button> | ||
| 181 | - </div> | ||
| 182 | - </el-dialog> | ||
| 183 | - </div> | ||
| 184 | -</template> | ||
| 185 | - | ||
| 186 | -<script> | ||
| 187 | -import { list, delOperlog, cleanOperlog, exportOperlog } from "@/api/monitor/operlog"; | ||
| 188 | - | ||
| 189 | -export default { | ||
| 190 | - name: "Operlog", | ||
| 191 | - data() { | ||
| 192 | - return { | ||
| 193 | - // 遮罩层 | ||
| 194 | - loading: true, | ||
| 195 | - // 选中数组 | ||
| 196 | - ids: [], | ||
| 197 | - // 非多个禁用 | ||
| 198 | - multiple: true, | ||
| 199 | - // 显示搜索条件 | ||
| 200 | - showSearch: true, | ||
| 201 | - // 总条数 | ||
| 202 | - total: 0, | ||
| 203 | - // 表格数据 | ||
| 204 | - list: [], | ||
| 205 | - // 是否显示弹出层 | ||
| 206 | - open: false, | ||
| 207 | - // 类型数据字典 | ||
| 208 | - typeOptions: [], | ||
| 209 | - // 类型数据字典 | ||
| 210 | - statusOptions: [], | ||
| 211 | - // 日期范围 | ||
| 212 | - dateRange: [], | ||
| 213 | - // 表单参数 | ||
| 214 | - form: {}, | ||
| 215 | - // 查询参数 | ||
| 216 | - queryParams: { | ||
| 217 | - pageNum: 1, | ||
| 218 | - pageSize: 10, | ||
| 219 | - title: undefined, | ||
| 220 | - operName: undefined, | ||
| 221 | - businessType: undefined, | ||
| 222 | - status: undefined | ||
| 223 | - } | ||
| 224 | - }; | ||
| 225 | - }, | ||
| 226 | - created() { | ||
| 227 | - this.getList(); | ||
| 228 | - this.getDicts("sys_oper_type").then(response => { | ||
| 229 | - this.typeOptions = response.data; | ||
| 230 | - }); | ||
| 231 | - this.getDicts("sys_common_status").then(response => { | ||
| 232 | - this.statusOptions = response.data; | ||
| 233 | - }); | ||
| 234 | - }, | ||
| 235 | - methods: { | ||
| 236 | - /** 查询登录日志 */ | ||
| 237 | - getList() { | ||
| 238 | - this.loading = true; | ||
| 239 | - list(this.addDateRange(this.queryParams, this.dateRange)).then( response => { | ||
| 240 | - this.list = response.rows; | ||
| 241 | - this.total = response.total; | ||
| 242 | - this.loading = false; | ||
| 243 | - } | ||
| 244 | - ); | ||
| 245 | - }, | ||
| 246 | - // 操作日志状态字典翻译 | ||
| 247 | - statusFormat(row, column) { | ||
| 248 | - return this.selectDictLabel(this.statusOptions, row.status); | ||
| 249 | - }, | ||
| 250 | - // 操作日志类型字典翻译 | ||
| 251 | - typeFormat(row, column) { | ||
| 252 | - return this.selectDictLabel(this.typeOptions, row.businessType); | ||
| 253 | - }, | ||
| 254 | - /** 搜索按钮操作 */ | ||
| 255 | - handleQuery() { | ||
| 256 | - this.queryParams.pageNum = 1; | ||
| 257 | - this.getList(); | ||
| 258 | - }, | ||
| 259 | - /** 重置按钮操作 */ | ||
| 260 | - resetQuery() { | ||
| 261 | - this.dateRange = []; | ||
| 262 | - this.resetForm("queryForm"); | ||
| 263 | - this.handleQuery(); | ||
| 264 | - }, | ||
| 265 | - // 多选框选中数据 | ||
| 266 | - handleSelectionChange(selection) { | ||
| 267 | - this.ids = selection.map(item => item.operId) | ||
| 268 | - this.multiple = !selection.length | ||
| 269 | - }, | ||
| 270 | - /** 详细按钮操作 */ | ||
| 271 | - handleView(row) { | ||
| 272 | - this.open = true; | ||
| 273 | - this.form = row; | ||
| 274 | - }, | ||
| 275 | - /** 删除按钮操作 */ | ||
| 276 | - handleDelete(row) { | ||
| 277 | - const operIds = row.operId || this.ids; | ||
| 278 | - this.$confirm('是否确认删除日志编号为"' + operIds + '"的数据项?', "警告", { | ||
| 279 | - confirmButtonText: "确定", | ||
| 280 | - cancelButtonText: "取消", | ||
| 281 | - type: "warning" | ||
| 282 | - }).then(function() { | ||
| 283 | - return delOperlog(operIds); | ||
| 284 | - }).then(() => { | ||
| 285 | - this.getList(); | ||
| 286 | - this.msgSuccess("删除成功"); | ||
| 287 | - }) | ||
| 288 | - }, | ||
| 289 | - /** 清空按钮操作 */ | ||
| 290 | - handleClean() { | ||
| 291 | - this.$confirm('是否确认清空所有操作日志数据项?', "警告", { | ||
| 292 | - confirmButtonText: "确定", | ||
| 293 | - cancelButtonText: "取消", | ||
| 294 | - type: "warning" | ||
| 295 | - }).then(function() { | ||
| 296 | - return cleanOperlog(); | ||
| 297 | - }).then(() => { | ||
| 298 | - this.getList(); | ||
| 299 | - this.msgSuccess("清空成功"); | ||
| 300 | - }) | ||
| 301 | - }, | ||
| 302 | - /** 导出按钮操作 */ | ||
| 303 | - handleExport() { | ||
| 304 | - const queryParams = this.queryParams; | ||
| 305 | - this.$confirm('是否确认导出所有操作日志数据项?', "警告", { | ||
| 306 | - confirmButtonText: "确定", | ||
| 307 | - cancelButtonText: "取消", | ||
| 308 | - type: "warning" | ||
| 309 | - }).then(function() { | ||
| 310 | - return exportOperlog(queryParams); | ||
| 311 | - }).then(response => { | ||
| 312 | - this.download(response.msg); | ||
| 313 | - }) | ||
| 314 | - } | ||
| 315 | - } | ||
| 316 | -}; | ||
| 317 | -</script> | ||
| 318 | - | 1 | +<template> |
| 2 | + <div class="app-container"> | ||
| 3 | + <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"> | ||
| 4 | + <el-form-item label="系统模块" prop="title"> | ||
| 5 | + <el-input | ||
| 6 | + v-model="queryParams.title" | ||
| 7 | + placeholder="请输入系统模块" | ||
| 8 | + clearable | ||
| 9 | + style="width: 240px;" | ||
| 10 | + size="small" | ||
| 11 | + @keyup.enter.native="handleQuery" | ||
| 12 | + /> | ||
| 13 | + </el-form-item> | ||
| 14 | + <el-form-item label="操作人员" prop="operName"> | ||
| 15 | + <el-input | ||
| 16 | + v-model="queryParams.operName" | ||
| 17 | + placeholder="请输入操作人员" | ||
| 18 | + clearable | ||
| 19 | + style="width: 240px;" | ||
| 20 | + size="small" | ||
| 21 | + @keyup.enter.native="handleQuery" | ||
| 22 | + /> | ||
| 23 | + </el-form-item> | ||
| 24 | + <el-form-item label="类型" prop="type"> | ||
| 25 | + <el-select | ||
| 26 | + v-model="queryParams.type" | ||
| 27 | + placeholder="操作类型" | ||
| 28 | + clearable | ||
| 29 | + size="small" | ||
| 30 | + style="width: 240px" | ||
| 31 | + > | ||
| 32 | + <el-option | ||
| 33 | + v-for="dict in this.getDictDatas(DICT_TYPE.SYS_OPERATE_TYPE)" | ||
| 34 | + :key="parseInt(dict.value)" | ||
| 35 | + :label="dict.label" | ||
| 36 | + :value="parseInt(dict.value)" | ||
| 37 | + /> | ||
| 38 | + </el-select> | ||
| 39 | + </el-form-item> | ||
| 40 | + <el-form-item label="状态" prop="status"> | ||
| 41 | + <el-select | ||
| 42 | + v-model="queryParams.success" | ||
| 43 | + placeholder="操作状态" | ||
| 44 | + clearable | ||
| 45 | + size="small" | ||
| 46 | + style="width: 240px" | ||
| 47 | + > | ||
| 48 | + <el-option | ||
| 49 | + :key="true" | ||
| 50 | + label="成功" | ||
| 51 | + :value="true" | ||
| 52 | + /> | ||
| 53 | + <el-option | ||
| 54 | + :key="false" | ||
| 55 | + label="失败" | ||
| 56 | + :value="false" | ||
| 57 | + /> | ||
| 58 | + </el-select> | ||
| 59 | + </el-form-item> | ||
| 60 | + <el-form-item label="操作时间"> | ||
| 61 | + <el-date-picker | ||
| 62 | + v-model="dateRange" | ||
| 63 | + size="small" | ||
| 64 | + style="width: 240px" | ||
| 65 | + value-format="yyyy-MM-dd" | ||
| 66 | + type="daterange" | ||
| 67 | + range-separator="-" | ||
| 68 | + start-placeholder="开始日期" | ||
| 69 | + end-placeholder="结束日期" | ||
| 70 | + ></el-date-picker> | ||
| 71 | + </el-form-item> | ||
| 72 | + <el-form-item> | ||
| 73 | + <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> | ||
| 74 | + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> | ||
| 75 | + </el-form-item> | ||
| 76 | + </el-form> | ||
| 77 | + | ||
| 78 | + <el-row :gutter="10" class="mb8"> | ||
| 79 | + <el-col :span="1.5"> | ||
| 80 | + <el-button | ||
| 81 | + type="warning" | ||
| 82 | + icon="el-icon-download" | ||
| 83 | + size="mini" | ||
| 84 | + @click="handleExport" | ||
| 85 | + v-hasPermi="['system:config:export']" | ||
| 86 | + >导出</el-button> | ||
| 87 | + </el-col> | ||
| 88 | + <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> | ||
| 89 | + </el-row> | ||
| 90 | + | ||
| 91 | + <el-table v-loading="loading" :data="list"> | ||
| 92 | + <el-table-column label="日志编号" align="center" prop="id" /> | ||
| 93 | + <el-table-column label="操作模块" align="center" prop="module" /> | ||
| 94 | + <el-table-column label="操作名" align="center" prop="name" width="180" /> | ||
| 95 | + <el-table-column label="操作类型" align="center" prop="type"> | ||
| 96 | + <template slot-scope="scope"> | ||
| 97 | + <span>{{ getDictDataLabel(DICT_TYPE.SYS_OPERATE_TYPE, scope.row.type) }}</span> | ||
| 98 | + </template> | ||
| 99 | + </el-table-column> | ||
| 100 | + <el-table-column label="操作人" align="center" prop="userNickname" /> | ||
| 101 | + <el-table-column label="操作结果" align="center" prop="status"> | ||
| 102 | + <template slot-scope="scope"> | ||
| 103 | + <span>{{ scope.row.resultCode === 0 ? '成功' : '失败' }}</span> | ||
| 104 | + </template> | ||
| 105 | + </el-table-column> | ||
| 106 | + <el-table-column label="操作日期" align="center" prop="startTime" width="180"> | ||
| 107 | + <template slot-scope="scope"> | ||
| 108 | + <span>{{ parseTime(scope.row.startTime) }}</span> | ||
| 109 | + </template> | ||
| 110 | + </el-table-column> | ||
| 111 | + <el-table-column label="执行时长" align="center" prop="startTime"> | ||
| 112 | + <template slot-scope="scope"> | ||
| 113 | + <span>{{ scope.row.duration }} ms</span> | ||
| 114 | + </template> | ||
| 115 | + </el-table-column> | ||
| 116 | + <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | ||
| 117 | + <template slot-scope="scope"> | ||
| 118 | + <el-button | ||
| 119 | + size="mini" | ||
| 120 | + type="text" | ||
| 121 | + icon="el-icon-view" | ||
| 122 | + @click="handleView(scope.row,scope.index)" | ||
| 123 | + v-hasPermi="['system:operate-log:query']" | ||
| 124 | + >详细</el-button> | ||
| 125 | + </template> | ||
| 126 | + </el-table-column> | ||
| 127 | + </el-table> | ||
| 128 | + | ||
| 129 | + <pagination | ||
| 130 | + v-show="total>0" | ||
| 131 | + :total="total" | ||
| 132 | + :page.sync="queryParams.pageNo" | ||
| 133 | + :limit.sync="queryParams.pageSize" | ||
| 134 | + @pagination="getList" | ||
| 135 | + /> | ||
| 136 | + | ||
| 137 | + <!-- 操作日志详细 --> | ||
| 138 | + <el-dialog title="操作日志详细" :visible.sync="open" width="700px" append-to-body> | ||
| 139 | + <el-form ref="form" :model="form" label-width="100px" size="mini"> | ||
| 140 | + <el-row> | ||
| 141 | + <el-col :span="12"> | ||
| 142 | + <el-form-item label="操作模块:">{{ form.title }} / {{ typeFormat(form) }}</el-form-item> | ||
| 143 | + <el-form-item | ||
| 144 | + label="登录信息:" | ||
| 145 | + >{{ form.operName }} / {{ form.operIp }} / {{ form.operLocation }}</el-form-item> | ||
| 146 | + </el-col> | ||
| 147 | + <el-col :span="12"> | ||
| 148 | + <el-form-item label="请求地址:">{{ form.operUrl }}</el-form-item> | ||
| 149 | + <el-form-item label="请求方式:">{{ form.requestMethod }}</el-form-item> | ||
| 150 | + </el-col> | ||
| 151 | + <el-col :span="24"> | ||
| 152 | + <el-form-item label="操作方法:">{{ form.method }}</el-form-item> | ||
| 153 | + </el-col> | ||
| 154 | + <el-col :span="24"> | ||
| 155 | + <el-form-item label="请求参数:">{{ form.operParam }}</el-form-item> | ||
| 156 | + </el-col> | ||
| 157 | + <el-col :span="24"> | ||
| 158 | + <el-form-item label="返回参数:">{{ form.jsonResult }}</el-form-item> | ||
| 159 | + </el-col> | ||
| 160 | + <el-col :span="12"> | ||
| 161 | + <el-form-item label="操作状态:"> | ||
| 162 | + <div v-if="form.status === 0">正常</div> | ||
| 163 | + <div v-else-if="form.status === 1">失败</div> | ||
| 164 | + </el-form-item> | ||
| 165 | + </el-col> | ||
| 166 | + <el-col :span="12"> | ||
| 167 | + <el-form-item label="操作时间:">{{ parseTime(form.operTime) }}</el-form-item> | ||
| 168 | + </el-col> | ||
| 169 | + <el-col :span="24"> | ||
| 170 | + <el-form-item label="异常信息:" v-if="form.status === 1">{{ form.errorMsg }}</el-form-item> | ||
| 171 | + </el-col> | ||
| 172 | + </el-row> | ||
| 173 | + </el-form> | ||
| 174 | + <div slot="footer" class="dialog-footer"> | ||
| 175 | + <el-button @click="open = false">关 闭</el-button> | ||
| 176 | + </div> | ||
| 177 | + </el-dialog> | ||
| 178 | + </div> | ||
| 179 | +</template> | ||
| 180 | + | ||
| 181 | +<script> | ||
| 182 | +import { listOperateLog, exportOperateLog } from "@/api/system/operatelog"; | ||
| 183 | + | ||
| 184 | +export default { | ||
| 185 | + name: "Operlog", | ||
| 186 | + data() { | ||
| 187 | + return { | ||
| 188 | + // 遮罩层 | ||
| 189 | + loading: true, | ||
| 190 | + // 显示搜索条件 | ||
| 191 | + showSearch: true, | ||
| 192 | + // 总条数 | ||
| 193 | + total: 0, | ||
| 194 | + // 表格数据 | ||
| 195 | + list: [], | ||
| 196 | + // 是否显示弹出层 | ||
| 197 | + open: false, | ||
| 198 | + // 类型数据字典 | ||
| 199 | + typeOptions: [], | ||
| 200 | + // 类型数据字典 | ||
| 201 | + statusOptions: [], | ||
| 202 | + // 日期范围 | ||
| 203 | + dateRange: [], | ||
| 204 | + // 表单参数 | ||
| 205 | + form: {}, | ||
| 206 | + // 查询参数 | ||
| 207 | + queryParams: { | ||
| 208 | + pageNo: 1, | ||
| 209 | + pageSize: 10, | ||
| 210 | + title: undefined, | ||
| 211 | + operName: undefined, | ||
| 212 | + businessType: undefined, | ||
| 213 | + status: undefined | ||
| 214 | + }, | ||
| 215 | + | ||
| 216 | + }; | ||
| 217 | + }, | ||
| 218 | + created() { | ||
| 219 | + this.getList(); | ||
| 220 | + }, | ||
| 221 | + methods: { | ||
| 222 | + /** 查询登录日志 */ | ||
| 223 | + getList() { | ||
| 224 | + this.loading = true; | ||
| 225 | + listOperateLog(this.addDateRange(this.queryParams, [ | ||
| 226 | + this.dateRange[0] ? this.dateRange[0] + ' 00:00:00' : undefined, | ||
| 227 | + this.dateRange[1] ? this.dateRange[1] + ' 23:59:59' : undefined, | ||
| 228 | + ])).then( response => { | ||
| 229 | + this.list = response.data.list; | ||
| 230 | + this.total = response.data.total; | ||
| 231 | + this.loading = false; | ||
| 232 | + } | ||
| 233 | + ); | ||
| 234 | + }, | ||
| 235 | + // 操作日志状态字典翻译 | ||
| 236 | + statusFormat(row, column) { | ||
| 237 | + return this.selectDictLabel(this.statusOptions, row.status); | ||
| 238 | + }, | ||
| 239 | + // 操作日志类型字典翻译 | ||
| 240 | + typeFormat(row, column) { | ||
| 241 | + return this.selectDictLabel(this.typeOptions, row.businessType); | ||
| 242 | + }, | ||
| 243 | + /** 搜索按钮操作 */ | ||
| 244 | + handleQuery() { | ||
| 245 | + this.queryParams.pageNo = 1; | ||
| 246 | + this.getList(); | ||
| 247 | + }, | ||
| 248 | + /** 重置按钮操作 */ | ||
| 249 | + resetQuery() { | ||
| 250 | + this.dateRange = []; | ||
| 251 | + this.resetForm("queryForm"); | ||
| 252 | + this.handleQuery(); | ||
| 253 | + }, | ||
| 254 | + /** 详细按钮操作 */ | ||
| 255 | + handleView(row) { | ||
| 256 | + this.open = true; | ||
| 257 | + this.form = row; | ||
| 258 | + }, | ||
| 259 | + /** 导出按钮操作 */ | ||
| 260 | + handleExport() { | ||
| 261 | + const queryParams = this.queryParams; | ||
| 262 | + this.$confirm('是否确认导出所有操作日志数据项?', "警告", { | ||
| 263 | + confirmButtonText: "确定", | ||
| 264 | + cancelButtonText: "取消", | ||
| 265 | + type: "warning" | ||
| 266 | + }).then(function() { | ||
| 267 | + return exportOperateLog(queryParams); | ||
| 268 | + }).then(response => { | ||
| 269 | + this.download(response.msg); | ||
| 270 | + }) | ||
| 271 | + } | ||
| 272 | + } | ||
| 273 | +}; | ||
| 274 | +</script> | ||
| 275 | + |
sql/ruoyi-vue-pro-data.sql
0 → 100644
| 1 | +INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`, `deleted`) VALUES (1, 1, '男', '1', 'sys_user_sex', 0, '性别男', 'admin', '2021-01-05 17:03:48', '', '2021-01-06 05:48:53', b'0'); | ||
| 2 | +INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`, `deleted`) VALUES (2, 2, '女', '2', 'sys_user_sex', 0, '性别女', 'admin', '2021-01-05 17:03:48', '', '2021-01-06 05:48:55', b'0'); | ||
| 3 | +INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`, `deleted`) VALUES (8, 1, '正常', '0', 'sys_job_status', 0, '正常状态', 'admin', '2021-01-05 17:03:48', '', '2021-01-06 00:02:28', b'0'); | ||
| 4 | +INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`, `deleted`) VALUES (9, 2, '暂停', '1', 'sys_job_status', 0, '停用状态', 'admin', '2021-01-05 17:03:48', '', '2021-01-06 00:02:28', b'0'); | ||
| 5 | +INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`, `deleted`) VALUES (10, 1, '默认', 'DEFAULT', 'sys_job_group', 0, '默认分组', 'admin', '2021-01-05 17:03:48', '', '2021-01-06 00:02:28', b'0'); | ||
| 6 | +INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`, `deleted`) VALUES (11, 2, '系统', 'SYSTEM', 'sys_job_group', 0, '系统分组', 'admin', '2021-01-05 17:03:48', '', '2021-01-06 00:02:28', b'0'); | ||
| 7 | +INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`, `deleted`) VALUES (12, 1, '是', 'Y', 'sys_yes_no', 0, '系统默认是', 'admin', '2021-01-05 17:03:48', '', '2021-01-06 00:02:28', b'0'); | ||
| 8 | +INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`, `deleted`) VALUES (13, 2, '否', 'N', 'sys_yes_no', 0, '系统默认否', 'admin', '2021-01-05 17:03:48', '', '2021-01-06 00:02:28', b'0'); | ||
| 9 | +INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`, `deleted`) VALUES (14, 1, '通知', '1', 'sys_notice_type', 0, '通知', 'admin', '2021-01-05 17:03:48', '', '2021-01-06 00:02:28', b'0'); | ||
| 10 | +INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`, `deleted`) VALUES (15, 2, '公告', '2', 'sys_notice_type', 0, '公告', 'admin', '2021-01-05 17:03:48', '', '2021-01-06 00:02:28', b'0'); | ||
| 11 | +INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`, `deleted`) VALUES (16, 0, '其它', '0', 'sys_operate_type', 0, '其它操作', 'admin', '2021-01-05 17:03:48', '', '2021-01-16 13:51:12', b'0'); | ||
| 12 | +INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`, `deleted`) VALUES (17, 1, '查询', '1', 'sys_operate_type', 0, '查询操作', 'admin', '2021-01-05 17:03:48', '', '2021-01-16 13:51:10', b'0'); | ||
| 13 | +INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`, `deleted`) VALUES (18, 2, '新增', '2', 'sys_operate_type', 0, '新增操作', 'admin', '2021-01-05 17:03:48', '', '2021-01-16 13:51:17', b'0'); | ||
| 14 | +INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`, `deleted`) VALUES (19, 3, '修改', '3', 'sys_operate_type', 0, '修改操作', 'admin', '2021-01-05 17:03:48', '', '2021-01-16 13:51:20', b'0'); | ||
| 15 | +INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`, `deleted`) VALUES (20, 4, '删除', '4', 'sys_operate_type', 0, '删除操作', 'admin', '2021-01-05 17:03:48', '', '2021-01-16 13:51:24', b'0'); | ||
| 16 | +INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`, `deleted`) VALUES (22, 5, '导出', '5', 'sys_operate_type', 0, '导出操作', 'admin', '2021-01-05 17:03:48', '', '2021-01-16 13:49:20', b'0'); | ||
| 17 | +INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`, `deleted`) VALUES (23, 6, '导入', '6', 'sys_operate_type', 0, '导入操作', 'admin', '2021-01-05 17:03:48', '', '2021-01-16 13:49:24', b'0'); | ||
| 18 | +INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`, `deleted`) VALUES (27, 1, '开启', '0', 'sys_common_status', 0, '开启状态', 'admin', '2021-01-05 17:03:48', '', '2021-01-06 02:57:12', b'0'); | ||
| 19 | +INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`, `deleted`) VALUES (28, 2, '关闭', '1', 'sys_common_status', 0, '关闭状态', 'admin', '2021-01-05 17:03:48', '', '2021-01-06 05:48:32', b'0'); | ||
| 20 | +INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`, `deleted`) VALUES (29, 1, '目录', '1', 'sys_menu_type', 0, '目录', 'admin', '2021-01-05 17:03:48', '', '2021-01-06 13:33:30', b'0'); | ||
| 21 | +INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`, `deleted`) VALUES (30, 2, '菜单', '2', 'sys_menu_type', 0, '菜单', 'admin', '2021-01-05 17:03:48', '', '2021-01-06 13:33:35', b'0'); | ||
| 22 | +INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`, `deleted`) VALUES (31, 3, '按钮', '3', 'sys_menu_type', 0, '按钮', 'admin', '2021-01-05 17:03:48', '', '2021-01-06 13:33:38', b'0'); | ||
| 23 | +INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`, `deleted`) VALUES (32, 1, '内置', '1', 'sys_role_type', 0, '内置角色', 'admin', '2021-01-05 17:03:48', '', '2021-01-06 13:34:22', b'0'); | ||
| 24 | +INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`, `deleted`) VALUES (33, 2, '自定义', '2', 'sys_role_type', 0, '自定义角色', 'admin', '2021-01-05 17:03:48', '', '2021-01-06 13:34:26', b'0'); | ||
| 25 | +INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`, `deleted`) VALUES (34, 1, '全部数据权限', '1', 'sys_data_scope', 0, '全部数据权限', 'admin', '2021-01-05 17:03:48', '', '2021-01-06 19:38:02', b'0'); | ||
| 26 | +INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`, `deleted`) VALUES (35, 2, '指定部门数据权限', '2', 'sys_data_scope', 0, '指定部门数据权限', 'admin', '2021-01-05 17:03:48', '', '2021-01-06 19:38:20', b'0'); | ||
| 27 | +INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`, `deleted`) VALUES (36, 3, '本部门数据权限', '3', 'sys_data_scope', 0, '本部门数据权限', 'admin', '2021-01-05 17:03:48', '', '2021-01-06 19:38:29', b'0'); | ||
| 28 | +INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`, `deleted`) VALUES (37, 4, '本部门及以下数据权限', '4', 'sys_data_scope', 0, '本部门及以下数据权限', 'admin', '2021-01-05 17:03:48', '', '2021-01-06 19:38:32', b'0'); | ||
| 29 | +INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `create_by`, `create_time`, `update_by`, `update_time`, `deleted`) VALUES (38, 5, '仅本人数据权限', '5', 'sys_data_scope', 0, '仅本人数据权限', 'admin', '2021-01-05 17:03:48', '', '2021-01-06 19:38:38', b'0'); |
src/main/java/cn/iocoder/dashboard/common/pojo/PageResult.java
| @@ -31,4 +31,8 @@ public final class PageResult<T> implements Serializable { | @@ -31,4 +31,8 @@ public final class PageResult<T> implements Serializable { | ||
| 31 | this.total = total; | 31 | this.total = total; |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | + public static <T> PageResult<T> empty() { | ||
| 35 | + return new PageResult<>(0L); | ||
| 36 | + } | ||
| 37 | + | ||
| 34 | } | 38 | } |
src/main/java/cn/iocoder/dashboard/framework/async/config/AsyncConfiguration.java
| @@ -4,6 +4,6 @@ import org.springframework.context.annotation.Configuration; | @@ -4,6 +4,6 @@ import org.springframework.context.annotation.Configuration; | ||
| 4 | import org.springframework.scheduling.annotation.EnableAsync; | 4 | import org.springframework.scheduling.annotation.EnableAsync; |
| 5 | 5 | ||
| 6 | @Configuration | 6 | @Configuration |
| 7 | -@EnableAsync(proxyTargetClass = true) | 7 | +@EnableAsync |
| 8 | public class AsyncConfiguration { | 8 | public class AsyncConfiguration { |
| 9 | } | 9 | } |
src/main/java/cn/iocoder/dashboard/framework/logger/operatelog/core/annotations/OperateLog.java
| 1 | package cn.iocoder.dashboard.framework.logger.operatelog.core.annotations; | 1 | package cn.iocoder.dashboard.framework.logger.operatelog.core.annotations; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.dashboard.modules.system.enums.logger.SysOperateLogTypeEnum; | 3 | +import cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateLogTypeEnum; |
| 4 | import io.swagger.annotations.Api; | 4 | import io.swagger.annotations.Api; |
| 5 | import io.swagger.annotations.ApiOperation; | 5 | import io.swagger.annotations.ApiOperation; |
| 6 | 6 | ||
| @@ -32,7 +32,7 @@ public @interface OperateLog { | @@ -32,7 +32,7 @@ public @interface OperateLog { | ||
| 32 | * | 32 | * |
| 33 | * 实际并不是数组,因为枚举不能设置 null 作为默认值 | 33 | * 实际并不是数组,因为枚举不能设置 null 作为默认值 |
| 34 | */ | 34 | */ |
| 35 | - SysOperateLogTypeEnum[] type() default {}; | 35 | + OperateLogTypeEnum[] type() default {}; |
| 36 | 36 | ||
| 37 | // ========== 开关字段 ========== | 37 | // ========== 开关字段 ========== |
| 38 | 38 |
src/main/java/cn/iocoder/dashboard/framework/logger/operatelog/core/aop/OperateLogAspect.java
| @@ -6,11 +6,11 @@ import cn.hutool.core.util.StrUtil; | @@ -6,11 +6,11 @@ import cn.hutool.core.util.StrUtil; | ||
| 6 | import cn.hutool.extra.servlet.ServletUtil; | 6 | import cn.hutool.extra.servlet.ServletUtil; |
| 7 | import cn.iocoder.dashboard.common.pojo.CommonResult; | 7 | import cn.iocoder.dashboard.common.pojo.CommonResult; |
| 8 | import cn.iocoder.dashboard.framework.logger.operatelog.core.annotations.OperateLog; | 8 | import cn.iocoder.dashboard.framework.logger.operatelog.core.annotations.OperateLog; |
| 9 | +import cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateLogTypeEnum; | ||
| 9 | import cn.iocoder.dashboard.framework.logger.operatelog.core.service.OperateLogFrameworkService; | 10 | import cn.iocoder.dashboard.framework.logger.operatelog.core.service.OperateLogFrameworkService; |
| 10 | import cn.iocoder.dashboard.framework.security.core.util.SecurityUtils; | 11 | import cn.iocoder.dashboard.framework.security.core.util.SecurityUtils; |
| 11 | import cn.iocoder.dashboard.framework.tracer.core.util.TracerUtils; | 12 | import cn.iocoder.dashboard.framework.tracer.core.util.TracerUtils; |
| 12 | import cn.iocoder.dashboard.modules.system.controller.logger.vo.SysOperateLogCreateReqVO; | 13 | import cn.iocoder.dashboard.modules.system.controller.logger.vo.SysOperateLogCreateReqVO; |
| 13 | -import cn.iocoder.dashboard.modules.system.enums.logger.SysOperateLogTypeEnum; | ||
| 14 | import cn.iocoder.dashboard.util.servlet.ServletUtils; | 14 | import cn.iocoder.dashboard.util.servlet.ServletUtils; |
| 15 | import com.alibaba.fastjson.JSON; | 15 | import com.alibaba.fastjson.JSON; |
| 16 | import com.google.common.collect.Maps; | 16 | import com.google.common.collect.Maps; |
| @@ -180,7 +180,7 @@ public class OperateLogAspect { | @@ -180,7 +180,7 @@ public class OperateLogAspect { | ||
| 180 | } | 180 | } |
| 181 | if (operateLogVO.getType() == null) { | 181 | if (operateLogVO.getType() == null) { |
| 182 | RequestMethod requestMethod = obtainFirstMatchRequestMethod(obtainRequestMethod(joinPoint)); | 182 | RequestMethod requestMethod = obtainFirstMatchRequestMethod(obtainRequestMethod(joinPoint)); |
| 183 | - SysOperateLogTypeEnum operateLogType = convertOperateLogType(requestMethod); | 183 | + OperateLogTypeEnum operateLogType = convertOperateLogType(requestMethod); |
| 184 | operateLogVO.setType(operateLogType != null ? operateLogType.getType() : null); | 184 | operateLogVO.setType(operateLogType != null ? operateLogType.getType() : null); |
| 185 | } | 185 | } |
| 186 | // content 和 exts 属性 | 186 | // content 和 exts 属性 |
| @@ -275,21 +275,21 @@ public class OperateLogAspect { | @@ -275,21 +275,21 @@ public class OperateLogAspect { | ||
| 275 | return requestMethods[0]; | 275 | return requestMethods[0]; |
| 276 | } | 276 | } |
| 277 | 277 | ||
| 278 | - private static SysOperateLogTypeEnum convertOperateLogType(RequestMethod requestMethod) { | 278 | + private static OperateLogTypeEnum convertOperateLogType(RequestMethod requestMethod) { |
| 279 | if (requestMethod == null) { | 279 | if (requestMethod == null) { |
| 280 | return null; | 280 | return null; |
| 281 | } | 281 | } |
| 282 | switch (requestMethod) { | 282 | switch (requestMethod) { |
| 283 | case GET: | 283 | case GET: |
| 284 | - return SysOperateLogTypeEnum.GET; | 284 | + return OperateLogTypeEnum.GET; |
| 285 | case POST: | 285 | case POST: |
| 286 | - return SysOperateLogTypeEnum.CREATE; | 286 | + return OperateLogTypeEnum.CREATE; |
| 287 | case PUT: | 287 | case PUT: |
| 288 | - return SysOperateLogTypeEnum.UPDATE; | 288 | + return OperateLogTypeEnum.UPDATE; |
| 289 | case DELETE: | 289 | case DELETE: |
| 290 | - return SysOperateLogTypeEnum.DELETE; | 290 | + return OperateLogTypeEnum.DELETE; |
| 291 | default: | 291 | default: |
| 292 | - return SysOperateLogTypeEnum.OTHER; | 292 | + return OperateLogTypeEnum.OTHER; |
| 293 | } | 293 | } |
| 294 | } | 294 | } |
| 295 | 295 |
src/main/java/cn/iocoder/dashboard/modules/system/enums/logger/SysOperateLogTypeEnum.java renamed to src/main/java/cn/iocoder/dashboard/framework/logger/operatelog/core/enums/OperateLogTypeEnum.java
| 1 | -package cn.iocoder.dashboard.modules.system.enums.logger; | 1 | +package cn.iocoder.dashboard.framework.logger.operatelog.core.enums; |
| 2 | 2 | ||
| 3 | import cn.iocoder.dashboard.framework.logger.operatelog.core.annotations.OperateLog; | 3 | import cn.iocoder.dashboard.framework.logger.operatelog.core.annotations.OperateLog; |
| 4 | import lombok.AllArgsConstructor; | 4 | import lombok.AllArgsConstructor; |
| @@ -11,7 +11,7 @@ import lombok.Getter; | @@ -11,7 +11,7 @@ import lombok.Getter; | ||
| 11 | */ | 11 | */ |
| 12 | @Getter | 12 | @Getter |
| 13 | @AllArgsConstructor | 13 | @AllArgsConstructor |
| 14 | -public enum SysOperateLogTypeEnum { | 14 | +public enum OperateLogTypeEnum { |
| 15 | 15 | ||
| 16 | /** | 16 | /** |
| 17 | * 查询 | 17 | * 查询 |
src/main/java/cn/iocoder/dashboard/framework/mybatis/core/mapper/BaseMapperX.java
0 → 100644
| 1 | +package cn.iocoder.dashboard.framework.mybatis.core.mapper; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.dashboard.common.pojo.PageParam; | ||
| 4 | +import cn.iocoder.dashboard.common.pojo.PageResult; | ||
| 5 | +import cn.iocoder.dashboard.framework.mybatis.core.util.MyBatisUtils; | ||
| 6 | +import com.baomidou.mybatisplus.core.conditions.Wrapper; | ||
| 7 | +import com.baomidou.mybatisplus.core.mapper.BaseMapper; | ||
| 8 | +import com.baomidou.mybatisplus.core.metadata.IPage; | ||
| 9 | +import org.apache.ibatis.annotations.Param; | ||
| 10 | + | ||
| 11 | +/** | ||
| 12 | + * 在 MyBatis Plus 的 BaseMapper 的基础上拓展,提供更多的能力 | ||
| 13 | + */ | ||
| 14 | +public interface BaseMapperX<T> extends BaseMapper<T> { | ||
| 15 | + | ||
| 16 | + default PageResult<T> selectPage(PageParam pageParam, @Param("ew") Wrapper<T> queryWrapper) { | ||
| 17 | + // MyBatis Plus 查询 | ||
| 18 | + IPage<T> mpPage = MyBatisUtils.buildPage(pageParam); | ||
| 19 | + selectPage(mpPage, queryWrapper); | ||
| 20 | + // 转换返回 | ||
| 21 | + return new PageResult<>(mpPage.getRecords(), mpPage.getTotal()); | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | +} |
src/main/java/cn/iocoder/dashboard/modules/system/controller/auth/SysAuthController.java
| @@ -54,7 +54,6 @@ public class SysAuthController { | @@ -54,7 +54,6 @@ public class SysAuthController { | ||
| 54 | 54 | ||
| 55 | @ApiOperation("获取登陆用户的权限信息") | 55 | @ApiOperation("获取登陆用户的权限信息") |
| 56 | @GetMapping("/get-permission-info") | 56 | @GetMapping("/get-permission-info") |
| 57 | - @OperateLog | ||
| 58 | public CommonResult<SysAuthPermissionInfoRespVO> getPermissionInfo() { | 57 | public CommonResult<SysAuthPermissionInfoRespVO> getPermissionInfo() { |
| 59 | // 获得用户信息 | 58 | // 获得用户信息 |
| 60 | SysUserDO user = userService.getUser(getLoginUserId()); | 59 | SysUserDO user = userService.getUser(getLoginUserId()); |
src/main/java/cn/iocoder/dashboard/modules/system/controller/common/SysCaptchaController.http
src/main/java/cn/iocoder/dashboard/modules/system/controller/common/SysCaptchaController.java
| @@ -23,7 +23,7 @@ public class SysCaptchaController { | @@ -23,7 +23,7 @@ public class SysCaptchaController { | ||
| 23 | 23 | ||
| 24 | @ApiOperation("生成图片验证码") | 24 | @ApiOperation("生成图片验证码") |
| 25 | @GetMapping("/get-image") | 25 | @GetMapping("/get-image") |
| 26 | - private CommonResult<SysCaptchaImageRespVO> getCaptchaImage() { | 26 | + public CommonResult<SysCaptchaImageRespVO> getCaptchaImage() { |
| 27 | return success(captchaService.getCaptchaImage()); | 27 | return success(captchaService.getCaptchaImage()); |
| 28 | } | 28 | } |
| 29 | 29 |
src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/SysOperateLogController.http
0 → 100644
src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/SysOperateLogController.java
0 → 100644
| 1 | +package cn.iocoder.dashboard.modules.system.controller.logger; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.dashboard.common.pojo.CommonResult; | ||
| 4 | +import cn.iocoder.dashboard.common.pojo.PageResult; | ||
| 5 | +import cn.iocoder.dashboard.framework.logger.operatelog.core.annotations.OperateLog; | ||
| 6 | +import cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateLogTypeEnum; | ||
| 7 | +import cn.iocoder.dashboard.framework.logger.operatelog.core.util.OperateLogUtils; | ||
| 8 | +import cn.iocoder.dashboard.modules.system.controller.logger.vo.SysOperateLogPageReqVO; | ||
| 9 | +import cn.iocoder.dashboard.modules.system.controller.logger.vo.SysOperateLogRespVO; | ||
| 10 | +import cn.iocoder.dashboard.modules.system.convert.logger.SysOperateLogConvert; | ||
| 11 | +import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger.SysOperateLogDO; | ||
| 12 | +import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO; | ||
| 13 | +import cn.iocoder.dashboard.modules.system.service.logger.SysOperateLogService; | ||
| 14 | +import cn.iocoder.dashboard.modules.system.service.user.SysUserService; | ||
| 15 | +import cn.iocoder.dashboard.util.collection.CollectionUtils; | ||
| 16 | +import cn.iocoder.dashboard.util.collection.MapUtils; | ||
| 17 | +import io.swagger.annotations.Api; | ||
| 18 | +import io.swagger.annotations.ApiOperation; | ||
| 19 | +import org.springframework.validation.annotation.Validated; | ||
| 20 | +import org.springframework.web.bind.annotation.GetMapping; | ||
| 21 | +import org.springframework.web.bind.annotation.RequestMapping; | ||
| 22 | +import org.springframework.web.bind.annotation.RestController; | ||
| 23 | + | ||
| 24 | +import javax.annotation.Resource; | ||
| 25 | +import java.util.ArrayList; | ||
| 26 | +import java.util.Collection; | ||
| 27 | +import java.util.List; | ||
| 28 | +import java.util.Map; | ||
| 29 | + | ||
| 30 | +import static cn.iocoder.dashboard.common.pojo.CommonResult.success; | ||
| 31 | + | ||
| 32 | +@Api(tags = "操作日志 API") | ||
| 33 | +@RestController | ||
| 34 | +@RequestMapping("/system/operate-log") | ||
| 35 | +public class SysOperateLogController { | ||
| 36 | + | ||
| 37 | + @Resource | ||
| 38 | + private SysOperateLogService operateLogService; | ||
| 39 | + | ||
| 40 | + @Resource | ||
| 41 | + private SysUserService userService; | ||
| 42 | + | ||
| 43 | + @ApiOperation("示例") | ||
| 44 | + @OperateLog(type = OperateLogTypeEnum.OTHER) | ||
| 45 | + @GetMapping("/demo") | ||
| 46 | + public CommonResult<Boolean> demo() { | ||
| 47 | + // 这里可以调用业务逻辑 | ||
| 48 | + | ||
| 49 | + // 补全操作日志的明细 | ||
| 50 | + OperateLogUtils.setContent("将编号 1 的数据,xxx 字段修改成了 yyyy"); | ||
| 51 | + OperateLogUtils.addExt("orderId", 1); | ||
| 52 | + | ||
| 53 | + // 响应 | ||
| 54 | + return success(true); | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + @ApiOperation("查看操作日志分页列表") | ||
| 58 | + @GetMapping("/page") | ||
| 59 | +// @PreAuthorize("@ss.hasPermi('system:operate-log:query')") | ||
| 60 | + public CommonResult<PageResult<SysOperateLogRespVO>> pageOperateLog(@Validated SysOperateLogPageReqVO reqVO) { | ||
| 61 | + PageResult<SysOperateLogDO> pageResult = operateLogService.pageOperateLog(reqVO); | ||
| 62 | + | ||
| 63 | + // 获得拼接需要的数据 | ||
| 64 | + Collection<Long> userIds = CollectionUtils.convertList(pageResult.getList(), SysOperateLogDO::getUserId); | ||
| 65 | + Map<Long, SysUserDO> userMap = userService.getUserMap(userIds); | ||
| 66 | + // 拼接数据 | ||
| 67 | + List<SysOperateLogRespVO> list = new ArrayList<>(pageResult.getList().size()); | ||
| 68 | + pageResult.getList().forEach(operateLog -> { | ||
| 69 | + SysOperateLogRespVO respVO = SysOperateLogConvert.INSTANCE.convert(operateLog); | ||
| 70 | + list.add(respVO); | ||
| 71 | + // 拼接用户信息 | ||
| 72 | + MapUtils.findAndThen(userMap, operateLog.getUserId(), user -> respVO.setUserNickname(user.getNickname())); | ||
| 73 | + }); | ||
| 74 | + return success(new PageResult<>(list, pageResult.getTotal())); | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | +// @Log(title = "操作日志", businessType = BusinessType.EXPORT) | ||
| 78 | +// @PreAuthorize("@ss.hasPermi('system:operate-log:export')") | ||
| 79 | +// @GetMapping("/export") | ||
| 80 | +// public AjaxResult export(SysOperLog operLog) { | ||
| 81 | +// List<SysOperLog> list = operLogService.selectOperLogList(operLog); | ||
| 82 | +// ExcelUtil<SysOperLog> util = new ExcelUtil<SysOperLog>(SysOperLog.class); | ||
| 83 | +// return util.exportExcel(list, "操作日志"); | ||
| 84 | +// } | ||
| 85 | + | ||
| 86 | +} |
src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/package-info.java deleted
| 1 | -package cn.iocoder.dashboard.modules.system.controller.logger; |
src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/SysOperateLogBaseVO.java
| @@ -6,6 +6,7 @@ import lombok.Data; | @@ -6,6 +6,7 @@ import lombok.Data; | ||
| 6 | import javax.validation.constraints.NotEmpty; | 6 | import javax.validation.constraints.NotEmpty; |
| 7 | import javax.validation.constraints.NotNull; | 7 | import javax.validation.constraints.NotNull; |
| 8 | import java.util.Date; | 8 | import java.util.Date; |
| 9 | +import java.util.Map; | ||
| 9 | 10 | ||
| 10 | /** | 11 | /** |
| 11 | * 操作日志 Base VO,提供给添加、修改、详细的子 VO 使用 | 12 | * 操作日志 Base VO,提供给添加、修改、详细的子 VO 使用 |
| @@ -30,10 +31,16 @@ public class SysOperateLogBaseVO { | @@ -30,10 +31,16 @@ public class SysOperateLogBaseVO { | ||
| 30 | @NotEmpty(message = "操作名") | 31 | @NotEmpty(message = "操作名") |
| 31 | private String name; | 32 | private String name; |
| 32 | 33 | ||
| 33 | - @ApiModelProperty(value = "操作分类", required = true, example = "操作分类", notes = "参见 SysOperateLogTypeEnum 枚举类") | 34 | + @ApiModelProperty(value = "操作分类", required = true, example = "1", notes = "参见 SysOperateLogTypeEnum 枚举类") |
| 34 | @NotNull(message = "操作分类不能为空") | 35 | @NotNull(message = "操作分类不能为空") |
| 35 | private Integer type; | 36 | private Integer type; |
| 36 | 37 | ||
| 38 | + @ApiModelProperty(value = "操作明细", example = "修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。") | ||
| 39 | + private String content; | ||
| 40 | + | ||
| 41 | + @ApiModelProperty(value = "拓展字段", example = "{'orderId': 1}") | ||
| 42 | + private Map<String, Object> exts; | ||
| 43 | + | ||
| 37 | @ApiModelProperty(value = "请求方法名", required = true, example = "GET") | 44 | @ApiModelProperty(value = "请求方法名", required = true, example = "GET") |
| 38 | @NotEmpty(message = "请求方法名不能为空") | 45 | @NotEmpty(message = "请求方法名不能为空") |
| 39 | private String requestMethod; | 46 | private String requestMethod; |
src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/SysOperateLogPageReqVO.java
0 → 100644
| 1 | +package cn.iocoder.dashboard.modules.system.controller.logger.vo; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.dashboard.common.pojo.PageParam; | ||
| 4 | +import io.swagger.annotations.ApiModel; | ||
| 5 | +import io.swagger.annotations.ApiModelProperty; | ||
| 6 | +import lombok.Data; | ||
| 7 | +import lombok.EqualsAndHashCode; | ||
| 8 | +import org.springframework.format.annotation.DateTimeFormat; | ||
| 9 | + | ||
| 10 | +import java.util.Date; | ||
| 11 | + | ||
| 12 | +import static cn.iocoder.dashboard.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | ||
| 13 | + | ||
| 14 | +@ApiModel("操作日志分页列表 Request VO") | ||
| 15 | +@Data | ||
| 16 | +@EqualsAndHashCode(callSuper = true) | ||
| 17 | +public class SysOperateLogPageReqVO extends PageParam { | ||
| 18 | + | ||
| 19 | + @ApiModelProperty(value = "操作模块", example = "订单", notes = "模拟匹配") | ||
| 20 | + private String module; | ||
| 21 | + | ||
| 22 | + @ApiModelProperty(value = "用户昵称", example = "芋道", notes = "模拟匹配") | ||
| 23 | + private String userNickname; | ||
| 24 | + | ||
| 25 | + @ApiModelProperty(value = "操作分类", example = "1", notes = "参见 SysOperateLogTypeEnum 枚举类") | ||
| 26 | + private Integer type; | ||
| 27 | + | ||
| 28 | + @ApiModelProperty(value = "操作状态", example = "true") | ||
| 29 | + private Boolean success; | ||
| 30 | + | ||
| 31 | + @ApiModelProperty(value = "开始时间", example = "2020-10-24") | ||
| 32 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | ||
| 33 | + private Date beginTime; | ||
| 34 | + | ||
| 35 | + @ApiModelProperty(value = "结束时间", example = "2020-10-24") | ||
| 36 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | ||
| 37 | + private Date endTime; | ||
| 38 | + | ||
| 39 | +} |
src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/SysOperateLogRespVO.java
0 → 100644
| 1 | +package cn.iocoder.dashboard.modules.system.controller.logger.vo; | ||
| 2 | + | ||
| 3 | +import io.swagger.annotations.ApiModel; | ||
| 4 | +import io.swagger.annotations.ApiModelProperty; | ||
| 5 | +import lombok.Data; | ||
| 6 | +import lombok.EqualsAndHashCode; | ||
| 7 | +import lombok.ToString; | ||
| 8 | + | ||
| 9 | +@ApiModel("操作日志 Response VO") | ||
| 10 | +@Data | ||
| 11 | +@EqualsAndHashCode(callSuper = true) | ||
| 12 | +@ToString(callSuper = true) | ||
| 13 | +public class SysOperateLogRespVO extends SysOperateLogBaseVO { | ||
| 14 | + | ||
| 15 | + @ApiModelProperty(value = "日志编号", required = true, example = "1024") | ||
| 16 | + private Long id; | ||
| 17 | + | ||
| 18 | + @ApiModelProperty(value = "用户昵称", required = true, example = "芋艿") | ||
| 19 | + private String userNickname; | ||
| 20 | + | ||
| 21 | +} |
src/main/java/cn/iocoder/dashboard/modules/system/convert/logger/SysOperateLogConvert.java
| 1 | package cn.iocoder.dashboard.modules.system.convert.logger; | 1 | package cn.iocoder.dashboard.modules.system.convert.logger; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.dashboard.common.pojo.PageResult; | ||
| 3 | import cn.iocoder.dashboard.modules.system.controller.logger.vo.SysOperateLogCreateReqVO; | 4 | import cn.iocoder.dashboard.modules.system.controller.logger.vo.SysOperateLogCreateReqVO; |
| 5 | +import cn.iocoder.dashboard.modules.system.controller.logger.vo.SysOperateLogRespVO; | ||
| 4 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger.SysOperateLogDO; | 6 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger.SysOperateLogDO; |
| 5 | import org.mapstruct.Mapper; | 7 | import org.mapstruct.Mapper; |
| 6 | import org.mapstruct.factory.Mappers; | 8 | import org.mapstruct.factory.Mappers; |
| @@ -12,4 +14,8 @@ public interface SysOperateLogConvert { | @@ -12,4 +14,8 @@ public interface SysOperateLogConvert { | ||
| 12 | 14 | ||
| 13 | SysOperateLogDO convert(SysOperateLogCreateReqVO bean); | 15 | SysOperateLogDO convert(SysOperateLogCreateReqVO bean); |
| 14 | 16 | ||
| 17 | + PageResult<SysOperateLogRespVO> convertPage(PageResult<SysOperateLogDO> page); | ||
| 18 | + | ||
| 19 | + SysOperateLogRespVO convert(SysOperateLogDO bean); | ||
| 20 | + | ||
| 15 | } | 21 | } |
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/logger/SysOperateLogMapper.java
| 1 | package cn.iocoder.dashboard.modules.system.dal.mysql.dao.logger; | 1 | package cn.iocoder.dashboard.modules.system.dal.mysql.dao.logger; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.dashboard.common.exception.enums.GlobalErrorCodeConstants; | ||
| 4 | +import cn.iocoder.dashboard.common.pojo.PageResult; | ||
| 5 | +import cn.iocoder.dashboard.framework.mybatis.core.mapper.BaseMapperX; | ||
| 6 | +import cn.iocoder.dashboard.framework.mybatis.core.query.QueryWrapperX; | ||
| 7 | +import cn.iocoder.dashboard.modules.system.controller.logger.vo.SysOperateLogPageReqVO; | ||
| 3 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger.SysOperateLogDO; | 8 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger.SysOperateLogDO; |
| 4 | -import com.baomidou.mybatisplus.core.mapper.BaseMapper; | ||
| 5 | import org.apache.ibatis.annotations.Mapper; | 9 | import org.apache.ibatis.annotations.Mapper; |
| 6 | 10 | ||
| 11 | +import java.util.Collection; | ||
| 12 | + | ||
| 7 | @Mapper | 13 | @Mapper |
| 8 | -public interface SysOperateLogMapper extends BaseMapper<SysOperateLogDO> { | 14 | +public interface SysOperateLogMapper extends BaseMapperX<SysOperateLogDO> { |
| 15 | + | ||
| 16 | + default PageResult<SysOperateLogDO> selectPage(SysOperateLogPageReqVO reqVO, Collection<Long> userIds) { | ||
| 17 | + QueryWrapperX<SysOperateLogDO> query = new QueryWrapperX<SysOperateLogDO>() | ||
| 18 | + .likeIfPresent("module", reqVO.getModule()) | ||
| 19 | + .inIfPresent("user_id", userIds) | ||
| 20 | + .eqIfPresent("operate_type", reqVO.getType()) | ||
| 21 | + .betweenIfPresent("start_time", reqVO.getBeginTime(), reqVO.getEndTime()); | ||
| 22 | + if (Boolean.TRUE.equals(reqVO.getSuccess())) { | ||
| 23 | + query.eq("result_code", GlobalErrorCodeConstants.SUCCESS.getCode()); | ||
| 24 | + } else if (Boolean.FALSE.equals(reqVO.getSuccess())) { | ||
| 25 | + query.gt("result_code", GlobalErrorCodeConstants.SUCCESS.getCode()); | ||
| 26 | + } | ||
| 27 | + return selectPage(reqVO, query); | ||
| 28 | + } | ||
| 29 | + | ||
| 9 | } | 30 | } |
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/user/SysUserMapper.java
| @@ -45,5 +45,9 @@ public interface SysUserMapper extends BaseMapper<SysUserDO> { | @@ -45,5 +45,9 @@ public interface SysUserMapper extends BaseMapper<SysUserDO> { | ||
| 45 | .inIfPresent("dept_id", deptIds)); | 45 | .inIfPresent("dept_id", deptIds)); |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | + default List<SysUserDO> selectListByNickname(String nickname) { | ||
| 49 | + return selectList(new QueryWrapperX<SysUserDO>().like("nickname", nickname)); | ||
| 50 | + } | ||
| 51 | + | ||
| 48 | } | 52 | } |
| 49 | 53 |
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/logger/SysOperateLogDO.java
| @@ -3,7 +3,7 @@ package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger; | @@ -3,7 +3,7 @@ package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger; | ||
| 3 | import cn.iocoder.dashboard.common.pojo.CommonResult; | 3 | import cn.iocoder.dashboard.common.pojo.CommonResult; |
| 4 | import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO; | 4 | import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO; |
| 5 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO; | 5 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO; |
| 6 | -import cn.iocoder.dashboard.modules.system.enums.logger.SysOperateLogTypeEnum; | 6 | +import cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateLogTypeEnum; |
| 7 | import com.baomidou.mybatisplus.annotation.TableField; | 7 | import com.baomidou.mybatisplus.annotation.TableField; |
| 8 | import com.baomidou.mybatisplus.annotation.TableId; | 8 | import com.baomidou.mybatisplus.annotation.TableId; |
| 9 | import com.baomidou.mybatisplus.annotation.TableName; | 9 | import com.baomidou.mybatisplus.annotation.TableName; |
| @@ -62,22 +62,18 @@ public class SysOperateLogDO extends BaseDO { | @@ -62,22 +62,18 @@ public class SysOperateLogDO extends BaseDO { | ||
| 62 | /** | 62 | /** |
| 63 | * 操作分类 | 63 | * 操作分类 |
| 64 | * | 64 | * |
| 65 | - * 枚举 {@link SysOperateLogTypeEnum} | 65 | + * 枚举 {@link OperateLogTypeEnum} |
| 66 | */ | 66 | */ |
| 67 | @TableField("operate_type") | 67 | @TableField("operate_type") |
| 68 | private Integer type; | 68 | private Integer type; |
| 69 | /** | 69 | /** |
| 70 | * 操作内容,记录整个操作的明细 | 70 | * 操作内容,记录整个操作的明细 |
| 71 | * 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。 | 71 | * 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。 |
| 72 | - * | ||
| 73 | - * TODO 预留字段 | ||
| 74 | */ | 72 | */ |
| 75 | private String content; | 73 | private String content; |
| 76 | /** | 74 | /** |
| 77 | * 拓展字段,有些复杂的业务,需要记录一些字段 | 75 | * 拓展字段,有些复杂的业务,需要记录一些字段 |
| 78 | * 例如说,记录订单编号,则可以添加 key 为 "orderId",value 为订单编号 | 76 | * 例如说,记录订单编号,则可以添加 key 为 "orderId",value 为订单编号 |
| 79 | - * | ||
| 80 | - * TODO 预留字段 | ||
| 81 | */ | 77 | */ |
| 82 | @TableField(typeHandler = FastjsonTypeHandler.class) | 78 | @TableField(typeHandler = FastjsonTypeHandler.class) |
| 83 | private Map<String, Object> exts; | 79 | private Map<String, Object> exts; |
src/main/java/cn/iocoder/dashboard/modules/system/service/logger/SysOperateLogService.java
| 1 | package cn.iocoder.dashboard.modules.system.service.logger; | 1 | package cn.iocoder.dashboard.modules.system.service.logger; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.dashboard.common.pojo.PageResult; | ||
| 3 | import cn.iocoder.dashboard.framework.logger.operatelog.core.service.OperateLogFrameworkService; | 4 | import cn.iocoder.dashboard.framework.logger.operatelog.core.service.OperateLogFrameworkService; |
| 5 | +import cn.iocoder.dashboard.modules.system.controller.logger.vo.SysOperateLogPageReqVO; | ||
| 6 | +import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger.SysOperateLogDO; | ||
| 4 | 7 | ||
| 5 | /** | 8 | /** |
| 6 | * 操作日志 Service 接口 | 9 | * 操作日志 Service 接口 |
| 7 | */ | 10 | */ |
| 8 | public interface SysOperateLogService extends OperateLogFrameworkService { | 11 | public interface SysOperateLogService extends OperateLogFrameworkService { |
| 12 | + | ||
| 13 | + /** | ||
| 14 | + * 获得操作日志分页列表 | ||
| 15 | + * | ||
| 16 | + * @param reqVO 分页条件 | ||
| 17 | + * @return 操作日志分页列表 | ||
| 18 | + */ | ||
| 19 | + PageResult<SysOperateLogDO> pageOperateLog(SysOperateLogPageReqVO reqVO); | ||
| 20 | + | ||
| 9 | } | 21 | } |
src/main/java/cn/iocoder/dashboard/modules/system/service/logger/impl/SysOperateLogServiceImpl.java
| 1 | package cn.iocoder.dashboard.modules.system.service.logger.impl; | 1 | package cn.iocoder.dashboard.modules.system.service.logger.impl; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.collection.CollUtil; | ||
| 4 | +import cn.hutool.core.util.StrUtil; | ||
| 5 | +import cn.iocoder.dashboard.common.pojo.PageResult; | ||
| 3 | import cn.iocoder.dashboard.modules.system.controller.logger.vo.SysOperateLogCreateReqVO; | 6 | import cn.iocoder.dashboard.modules.system.controller.logger.vo.SysOperateLogCreateReqVO; |
| 7 | +import cn.iocoder.dashboard.modules.system.controller.logger.vo.SysOperateLogPageReqVO; | ||
| 4 | import cn.iocoder.dashboard.modules.system.convert.logger.SysOperateLogConvert; | 8 | import cn.iocoder.dashboard.modules.system.convert.logger.SysOperateLogConvert; |
| 5 | import cn.iocoder.dashboard.modules.system.dal.mysql.dao.logger.SysOperateLogMapper; | 9 | import cn.iocoder.dashboard.modules.system.dal.mysql.dao.logger.SysOperateLogMapper; |
| 6 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger.SysOperateLogDO; | 10 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger.SysOperateLogDO; |
| 11 | +import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO; | ||
| 7 | import cn.iocoder.dashboard.modules.system.service.logger.SysOperateLogService; | 12 | import cn.iocoder.dashboard.modules.system.service.logger.SysOperateLogService; |
| 13 | +import cn.iocoder.dashboard.modules.system.service.user.SysUserService; | ||
| 8 | import cn.iocoder.dashboard.util.string.StrUtils; | 14 | import cn.iocoder.dashboard.util.string.StrUtils; |
| 9 | import lombok.extern.slf4j.Slf4j; | 15 | import lombok.extern.slf4j.Slf4j; |
| 10 | import org.springframework.scheduling.annotation.Async; | 16 | import org.springframework.scheduling.annotation.Async; |
| 11 | import org.springframework.stereotype.Service; | 17 | import org.springframework.stereotype.Service; |
| 12 | 18 | ||
| 13 | import javax.annotation.Resource; | 19 | import javax.annotation.Resource; |
| 20 | +import java.util.Collection; | ||
| 14 | 21 | ||
| 15 | -import static cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger.SysOperateLogDO.*; | 22 | +import static cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger.SysOperateLogDO.JAVA_METHOD_ARGS_MAX_LENGTH; |
| 23 | +import static cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger.SysOperateLogDO.RESULT_MAX_LENGTH; | ||
| 24 | +import static cn.iocoder.dashboard.util.collection.CollectionUtils.convertSet; | ||
| 16 | 25 | ||
| 17 | @Service | 26 | @Service |
| 18 | @Slf4j | 27 | @Slf4j |
| @@ -21,6 +30,9 @@ public class SysOperateLogServiceImpl implements SysOperateLogService { | @@ -21,6 +30,9 @@ public class SysOperateLogServiceImpl implements SysOperateLogService { | ||
| 21 | @Resource | 30 | @Resource |
| 22 | private SysOperateLogMapper operateLogMapper; | 31 | private SysOperateLogMapper operateLogMapper; |
| 23 | 32 | ||
| 33 | + @Resource | ||
| 34 | + private SysUserService userService; | ||
| 35 | + | ||
| 24 | @Override | 36 | @Override |
| 25 | @Async | 37 | @Async |
| 26 | public void createOperateLogAsync(SysOperateLogCreateReqVO reqVO) { | 38 | public void createOperateLogAsync(SysOperateLogCreateReqVO reqVO) { |
| @@ -35,4 +47,18 @@ public class SysOperateLogServiceImpl implements SysOperateLogService { | @@ -35,4 +47,18 @@ public class SysOperateLogServiceImpl implements SysOperateLogService { | ||
| 35 | } | 47 | } |
| 36 | } | 48 | } |
| 37 | 49 | ||
| 50 | + @Override | ||
| 51 | + public PageResult<SysOperateLogDO> pageOperateLog(SysOperateLogPageReqVO reqVO) { | ||
| 52 | + // 处理基于用户昵称的查询 | ||
| 53 | + Collection<Long> userIds = null; | ||
| 54 | + if (StrUtil.isNotEmpty(reqVO.getUserNickname())) { | ||
| 55 | + userIds = convertSet(userService.listUsersByNickname(reqVO.getUserNickname()), SysUserDO::getId); | ||
| 56 | + if (CollUtil.isEmpty(userIds)) { | ||
| 57 | + return PageResult.empty(); | ||
| 58 | + } | ||
| 59 | + } | ||
| 60 | + // 查询分页 | ||
| 61 | + return operateLogMapper.selectPage(reqVO, userIds); | ||
| 62 | + } | ||
| 63 | + | ||
| 38 | } | 64 | } |
src/main/java/cn/iocoder/dashboard/modules/system/service/user/SysUserService.java
| 1 | package cn.iocoder.dashboard.modules.system.service.user; | 1 | package cn.iocoder.dashboard.modules.system.service.user; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.collection.CollUtil; | ||
| 3 | import cn.iocoder.dashboard.common.pojo.PageResult; | 4 | import cn.iocoder.dashboard.common.pojo.PageResult; |
| 4 | import cn.iocoder.dashboard.modules.system.controller.user.vo.user.*; | 5 | import cn.iocoder.dashboard.modules.system.controller.user.vo.user.*; |
| 5 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO; | 6 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO; |
| 7 | +import cn.iocoder.dashboard.util.collection.CollectionUtils; | ||
| 6 | 8 | ||
| 9 | +import java.util.Collection; | ||
| 10 | +import java.util.HashMap; | ||
| 7 | import java.util.List; | 11 | import java.util.List; |
| 12 | +import java.util.Map; | ||
| 8 | 13 | ||
| 9 | /** | 14 | /** |
| 10 | * 用户 Service 接口 | 15 | * 用户 Service 接口 |
| @@ -46,6 +51,35 @@ public interface SysUserService { | @@ -46,6 +51,35 @@ public interface SysUserService { | ||
| 46 | List<SysUserDO> listUsers(SysUserExportReqVO reqVO); | 51 | List<SysUserDO> listUsers(SysUserExportReqVO reqVO); |
| 47 | 52 | ||
| 48 | /** | 53 | /** |
| 54 | + * 获得用户列表 | ||
| 55 | + * | ||
| 56 | + * @param ids 用户编号数组 | ||
| 57 | + * @return 用户列表 | ||
| 58 | + */ | ||
| 59 | + List<SysUserDO> listUsers(Collection<Long> ids); | ||
| 60 | + | ||
| 61 | + /** | ||
| 62 | + * 获得用户 Map | ||
| 63 | + * | ||
| 64 | + * @param ids 用户编号数组 | ||
| 65 | + * @return 用户 Map | ||
| 66 | + */ | ||
| 67 | + default Map<Long, SysUserDO> getUserMap(Collection<Long> ids) { | ||
| 68 | + if (CollUtil.isEmpty(ids)) { | ||
| 69 | + return new HashMap<>(); | ||
| 70 | + } | ||
| 71 | + return CollectionUtils.convertMap(listUsers(ids), SysUserDO::getId); | ||
| 72 | + } | ||
| 73 | + | ||
| 74 | + /** | ||
| 75 | + * 获得用户列表,基于昵称模糊匹配 | ||
| 76 | + * | ||
| 77 | + * @param nickname 昵称 | ||
| 78 | + * @return 用户列表 | ||
| 79 | + */ | ||
| 80 | + List<SysUserDO> listUsersByNickname(String nickname); | ||
| 81 | + | ||
| 82 | + /** | ||
| 49 | * 创建用户 | 83 | * 创建用户 |
| 50 | * | 84 | * |
| 51 | * @param reqVO 用户信息 | 85 | * @param reqVO 用户信息 |
src/main/java/cn/iocoder/dashboard/modules/system/service/user/SysUserServiceImpl.java
| @@ -83,6 +83,16 @@ public class SysUserServiceImpl implements SysUserService { | @@ -83,6 +83,16 @@ public class SysUserServiceImpl implements SysUserService { | ||
| 83 | return userMapper.selectList(reqVO, this.getDeptCondition(reqVO.getDeptId())); | 83 | return userMapper.selectList(reqVO, this.getDeptCondition(reqVO.getDeptId())); |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | + @Override | ||
| 87 | + public List<SysUserDO> listUsers(Collection<Long> ids) { | ||
| 88 | + return userMapper.selectBatchIds(ids); | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + @Override | ||
| 92 | + public List<SysUserDO> listUsersByNickname(String nickname) { | ||
| 93 | + return userMapper.selectListByNickname(nickname); | ||
| 94 | + } | ||
| 95 | + | ||
| 86 | /** | 96 | /** |
| 87 | * 获得部门条件:查询指定部门的子部门编号们,包括自身 | 97 | * 获得部门条件:查询指定部门的子部门编号们,包括自身 |
| 88 | * | 98 | * |