diff --git a/pom.xml b/pom.xml
index 20ede4f7e..cc04724b0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,7 +22,7 @@
${java.version}
3.8.0
- 2.4.1
+ 2.4.2
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java
index 276442289..99f9f7648 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java
@@ -23,28 +23,12 @@ import com.ruoyi.system.service.ISysOperLogService;
*
* @author ruoyi
*/
-@RestController
-@RequestMapping("/monitor/operlog")
+
public class SysOperlogController extends BaseController {
@Autowired
private ISysOperLogService operLogService;
- @PreAuthorize("@ss.hasPermi('monitor:operlog:list')")
- @GetMapping("/list")
- public TableDataInfo list(SysOperLog operLog) {
- startPage();
- List list = operLogService.selectOperLogList(operLog);
- return getDataTable(list);
- }
- @Log(title = "操作日志", businessType = BusinessType.EXPORT)
- @PreAuthorize("@ss.hasPermi('monitor:operlog:export')")
- @GetMapping("/export")
- public AjaxResult export(SysOperLog operLog) {
- List list = operLogService.selectOperLogList(operLog);
- ExcelUtil util = new ExcelUtil(SysOperLog.class);
- return util.exportExcel(list, "操作日志");
- }
}
diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml
deleted file mode 100644
index ab7f11b1b..000000000
--- a/ruoyi-common/pom.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
- ruoyi
- com.ruoyi
- 3.3.0
-
- 4.0.0
-
- ruoyi-common
-
-
- common通用工具
-
-
-
-
-
-
- org.yaml
- snakeyaml
-
-
-
-
- eu.bitwalker
- UserAgentUtils
-
-
-
-
-
-
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/Log.java b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/Log.java
deleted file mode 100644
index 3458c882d..000000000
--- a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/Log.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.ruoyi.common.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import com.ruoyi.common.enums.BusinessType;
-import com.ruoyi.common.enums.OperatorType;
-
-/**
- * 自定义操作日志记录注解
- *
- * @author ruoyi
- *
- */
-@Target({ ElementType.PARAMETER, ElementType.METHOD })
-@Retention(RetentionPolicy.RUNTIME)
-@Documented
-public @interface Log
-{
- /**
- * 模块
- */
- public String title() default "";
-
- /**
- * 功能
- */
- public BusinessType businessType() default BusinessType.OTHER;
-
- /**
- * 操作人类别
- */
- public OperatorType operatorType() default OperatorType.MANAGE;
-
- /**
- * 是否保存请求的参数
- */
- public boolean isSaveRequestData() default true;
-}
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java
deleted file mode 100644
index 2c58eb9be..000000000
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java
+++ /dev/null
@@ -1,160 +0,0 @@
-package com.ruoyi.framework.aspectj;
-
-import java.lang.reflect.Method;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Map;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.aspectj.lang.JoinPoint;
-import org.aspectj.lang.Signature;
-import org.aspectj.lang.annotation.AfterReturning;
-import org.aspectj.lang.annotation.AfterThrowing;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Pointcut;
-import org.aspectj.lang.reflect.MethodSignature;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Component;
-import org.springframework.web.multipart.MultipartFile;
-import org.springframework.web.servlet.HandlerMapping;
-import com.alibaba.fastjson.JSON;
-import com.ruoyi.common.annotation.Log;
-import com.ruoyi.common.core.domain.model.LoginUser;
-import com.ruoyi.common.enums.BusinessStatus;
-import com.ruoyi.common.enums.HttpMethod;
-import com.ruoyi.common.utils.ServletUtils;
-import com.ruoyi.common.utils.StringUtils;
-import com.ruoyi.common.utils.ip.IpUtils;
-import com.ruoyi.common.utils.spring.SpringUtils;
-import com.ruoyi.framework.manager.AsyncManager;
-import com.ruoyi.framework.manager.factory.AsyncFactory;
-import com.ruoyi.framework.web.service.TokenService;
-import com.ruoyi.system.domain.SysOperLog;
-
-/**
- * 操作日志记录处理
- *
- * @author ruoyi
- */
-@Aspect
-@Component
-public class LogAspect {
- private static final Logger log = LoggerFactory.getLogger(LogAspect.class);
-
- // 配置织入点
- @Pointcut("@annotation(com.ruoyi.common.annotation.Log)")
- public void logPointCut() {
- }
-
- /**
- * 处理完请求后执行
- *
- * @param joinPoint 切点
- */
- @AfterReturning(pointcut = "logPointCut()", returning = "jsonResult")
- public void doAfterReturning(JoinPoint joinPoint, Object jsonResult) {
- handleLog(joinPoint, null, jsonResult);
- }
-
- /**
- * 拦截异常操作
- *
- * @param joinPoint 切点
- * @param e 异常
- */
- @AfterThrowing(value = "logPointCut()", throwing = "e")
- public void doAfterThrowing(JoinPoint joinPoint, Exception e) {
- handleLog(joinPoint, e, null);
- }
-
- protected void handleLog(final JoinPoint joinPoint, final Exception e, Object jsonResult) {
- try {
- // 获得注解
- Log controllerLog = getAnnotationLog(joinPoint);
- if (controllerLog == null) {
- return;
- }
-
- // 获取当前的用户
- LoginUser loginUser = SpringUtils.getBean(TokenService.class).getLoginUser(ServletUtils.getRequest());
-
- // *========数据库日志=========*//
- SysOperLog operLog = new SysOperLog();
- operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
- // 请求的地址
- String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
- operLog.setOperIp(ip);
- // 返回参数
- operLog.setJsonResult(JSON.toJSONString(jsonResult));
-
- operLog.setOperUrl(ServletUtils.getRequest().getRequestURI());
- if (loginUser != null) {
- operLog.setOperName(loginUser.getUsername());
- }
-
- if (e != null) {
- operLog.setStatus(BusinessStatus.FAIL.ordinal());
- operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));
- }
- // 设置方法名称
- String className = joinPoint.getTarget().getClass().getName();
- String methodName = joinPoint.getSignature().getName();
- operLog.setMethod(className + "." + methodName + "()");
- // 设置请求方式
- operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
- // 处理设置注解上的参数
- getControllerMethodDescription(joinPoint, controllerLog, operLog);
- // 保存数据库
- AsyncManager.me().execute(AsyncFactory.recordOper(operLog));
- } catch (Exception exp) {
- // 记录本地异常日志
- log.error("==前置通知异常==");
- log.error("异常信息:{}", exp.getMessage());
- exp.printStackTrace();
- }
- }
-
- /**
- * 参数拼装
- */
- private String argsArrayToString(Object[] paramsArray) {
- String params = "";
- if (paramsArray != null && paramsArray.length > 0) {
- for (int i = 0; i < paramsArray.length; i++) {
- if (!isFilterObject(paramsArray[i])) {
- Object jsonObj = JSON.toJSON(paramsArray[i]);
- params += jsonObj.toString() + " ";
- }
- }
- }
- return params.trim();
- }
-
- /**
- * 判断是否需要过滤的对象。
- *
- * @param o 对象信息。
- * @return 如果是需要过滤的对象,则返回true;否则返回false。
- */
- @SuppressWarnings("rawtypes")
- public boolean isFilterObject(final Object o) {
- Class> clazz = o.getClass();
- if (clazz.isArray()) {
- return clazz.getComponentType().isAssignableFrom(MultipartFile.class);
- } else if (Collection.class.isAssignableFrom(clazz)) {
- Collection collection = (Collection) o;
- for (Iterator iter = collection.iterator(); iter.hasNext(); ) {
- return iter.next() instanceof MultipartFile;
- }
- } else if (Map.class.isAssignableFrom(clazz)) {
- Map map = (Map) o;
- for (Iterator iter = map.entrySet().iterator(); iter.hasNext(); ) {
- Map.Entry entry = (Map.Entry) iter.next();
- return entry.getValue() instanceof MultipartFile;
- }
- }
- return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse;
- }
-}
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ApplicationConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ApplicationConfig.java
deleted file mode 100644
index eab1ee0e6..000000000
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ApplicationConfig.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.ruoyi.framework.config;
-
-import java.util.TimeZone;
-
-import org.mybatis.spring.annotation.MapperScan;
-import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.EnableAspectJAutoProxy;
-
-/**
- * 程序注解配置
- *
- * @author ruoyi
- */
-@Configuration
-// 表示通过aop框架暴露该代理对象,AopContext能够访问
-@EnableAspectJAutoProxy(exposeProxy = true)
-// 指定要扫描的Mapper类的包的路径
-@MapperScan("com.ruoyi.**.mapper")
-public class ApplicationConfig {
- /**
- * 时区配置
- */
- @Bean
- public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() {
- return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault());
- }
-}
diff --git a/ruoyi-ui/src/api/monitor/operlog.js b/ruoyi-ui/src/api/monitor/operlog.js
deleted file mode 100644
index c519355ef..000000000
--- a/ruoyi-ui/src/api/monitor/operlog.js
+++ /dev/null
@@ -1,35 +0,0 @@
-import request from '@/utils/request'
-
-// 查询操作日志列表
-export function list(query) {
- return request({
- url: '/monitor/operlog/list',
- method: 'get',
- params: query
- })
-}
-
-// 删除操作日志
-export function delOperlog(operId) {
- return request({
- url: '/monitor/operlog/' + operId,
- method: 'delete'
- })
-}
-
-// 清空操作日志
-export function cleanOperlog() {
- return request({
- url: '/monitor/operlog/clean',
- method: 'delete'
- })
-}
-
-// 导出操作日志
-export function exportOperlog(query) {
- return request({
- url: '/monitor/operlog/export',
- method: 'get',
- params: query
- })
-}
\ No newline at end of file
diff --git a/ruoyi-ui/src/api/system/operatelog.js b/ruoyi-ui/src/api/system/operatelog.js
new file mode 100644
index 000000000..c089975d4
--- /dev/null
+++ b/ruoyi-ui/src/api/system/operatelog.js
@@ -0,0 +1,19 @@
+import request from '@/utils/request'
+
+// 查询操作日志列表
+export function listOperateLog(query) {
+ return request({
+ url: '/system/operate-log/page',
+ method: 'get',
+ params: query
+ })
+}
+
+// 导出操作日志
+export function exportOperateLog(query) {
+ return request({
+ url: '/system/operate-log/export',
+ method: 'get',
+ params: query
+ })
+}
diff --git a/ruoyi-ui/src/main.js b/ruoyi-ui/src/main.js
index c7fafc017..f337ab78a 100644
--- a/ruoyi-ui/src/main.js
+++ b/ruoyi-ui/src/main.js
@@ -23,6 +23,7 @@ import RightToolbar from "@/components/RightToolbar"
// 代码高亮插件
import hljs from 'highlight.js'
import 'highlight.js/styles/github-gist.css'
+import {DICT_TYPE, getDictDataLabel, getDictDatas} from "@/utils/dict";
// 全局方法挂载
Vue.prototype.getDicts = getDicts
@@ -32,6 +33,9 @@ Vue.prototype.resetForm = resetForm
Vue.prototype.addDateRange = addDateRange
Vue.prototype.selectDictLabel = selectDictLabel
Vue.prototype.selectDictLabels = selectDictLabels
+Vue.prototype.getDictDatas = getDictDatas
+Vue.prototype.getDictDataLabel = getDictDataLabel
+Vue.prototype.DICT_TYPE = DICT_TYPE
Vue.prototype.download = download
Vue.prototype.downloadExcel = downloadExcel
Vue.prototype.handleTree = handleTree
diff --git a/ruoyi-ui/src/utils/dict.js b/ruoyi-ui/src/utils/dict.js
index 07df5fd8c..00f74aefe 100644
--- a/ruoyi-ui/src/utils/dict.js
+++ b/ruoyi-ui/src/utils/dict.js
@@ -12,6 +12,7 @@ export const DICT_TYPE = {
SYS_DATA_SCOPE: 'sys_data_scope',
SYS_USER_SEX: 'sys_user_sex',
SYS_NOTICE_TYPE: 'sys_notice_type',
+ SYS_OPERATE_TYPE: 'sys_operate_type'
}
/**
diff --git a/ruoyi-ui/src/views/monitor/operlog/index.vue b/ruoyi-ui/src/views/system/operatelog/index.vue
similarity index 63%
rename from ruoyi-ui/src/views/monitor/operlog/index.vue
rename to ruoyi-ui/src/views/system/operatelog/index.vue
index 3a44cfcd3..f038dc51f 100644
--- a/ruoyi-ui/src/views/monitor/operlog/index.vue
+++ b/ruoyi-ui/src/views/system/operatelog/index.vue
@@ -1,318 +1,275 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 搜索
- 重置
-
-
-
-
-
- 删除
-
-
- 清空
-
-
- 导出
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ parseTime(scope.row.operTime) }}
-
-
-
-
- 详细
-
-
-
-
-
-
-
-
-
-
-
- {{ form.title }} / {{ typeFormat(form) }}
- {{ form.operName }} / {{ form.operIp }} / {{ form.operLocation }}
-
-
- {{ form.operUrl }}
- {{ form.requestMethod }}
-
-
- {{ form.method }}
-
-
- {{ form.operParam }}
-
-
- {{ form.jsonResult }}
-
-
-
- 正常
- 失败
-
-
-
- {{ parseTime(form.operTime) }}
-
-
- {{ form.errorMsg }}
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+ {{ getDictDataLabel(DICT_TYPE.SYS_OPERATE_TYPE, scope.row.type) }}
+
+
+
+
+
+ {{ scope.row.resultCode === 0 ? '成功' : '失败' }}
+
+
+
+
+ {{ parseTime(scope.row.startTime) }}
+
+
+
+
+ {{ scope.row.duration }} ms
+
+
+
+
+ 详细
+
+
+
+
+
+
+
+
+
+
+
+ {{ form.title }} / {{ typeFormat(form) }}
+ {{ form.operName }} / {{ form.operIp }} / {{ form.operLocation }}
+
+
+ {{ form.operUrl }}
+ {{ form.requestMethod }}
+
+
+ {{ form.method }}
+
+
+ {{ form.operParam }}
+
+
+ {{ form.jsonResult }}
+
+
+
+ 正常
+ 失败
+
+
+
+ {{ parseTime(form.operTime) }}
+
+
+ {{ form.errorMsg }}
+
+
+
+
+
+
+
+
+
+
diff --git a/sql/ruoyi-vue-pro-data.sql b/sql/ruoyi-vue-pro-data.sql
new file mode 100644
index 000000000..a1ee1b82a
--- /dev/null
+++ b/sql/ruoyi-vue-pro-data.sql
@@ -0,0 +1,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 (1, 1, '男', '1', 'sys_user_sex', 0, '性别男', 'admin', '2021-01-05 17:03:48', '', '2021-01-06 05:48:53', b'0');
+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');
+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');
+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');
+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');
+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');
+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');
+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');
+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');
+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');
+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');
+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');
+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');
+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');
+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');
+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');
+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');
+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');
+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');
+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');
+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');
+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');
+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');
+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');
+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');
+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');
+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');
+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');
+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');
diff --git a/src/main/java/cn/iocoder/dashboard/common/pojo/PageResult.java b/src/main/java/cn/iocoder/dashboard/common/pojo/PageResult.java
index fa7d109d9..092677d0c 100644
--- a/src/main/java/cn/iocoder/dashboard/common/pojo/PageResult.java
+++ b/src/main/java/cn/iocoder/dashboard/common/pojo/PageResult.java
@@ -31,4 +31,8 @@ public final class PageResult implements Serializable {
this.total = total;
}
+ public static PageResult empty() {
+ return new PageResult<>(0L);
+ }
+
}
diff --git a/src/main/java/cn/iocoder/dashboard/framework/async/config/AsyncConfiguration.java b/src/main/java/cn/iocoder/dashboard/framework/async/config/AsyncConfiguration.java
index b2c126c28..58096d5da 100644
--- a/src/main/java/cn/iocoder/dashboard/framework/async/config/AsyncConfiguration.java
+++ b/src/main/java/cn/iocoder/dashboard/framework/async/config/AsyncConfiguration.java
@@ -4,6 +4,6 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
@Configuration
-@EnableAsync(proxyTargetClass = true)
+@EnableAsync
public class AsyncConfiguration {
}
diff --git a/src/main/java/cn/iocoder/dashboard/framework/logger/operatelog/core/annotations/OperateLog.java b/src/main/java/cn/iocoder/dashboard/framework/logger/operatelog/core/annotations/OperateLog.java
index ce61c77a0..494f04158 100644
--- a/src/main/java/cn/iocoder/dashboard/framework/logger/operatelog/core/annotations/OperateLog.java
+++ b/src/main/java/cn/iocoder/dashboard/framework/logger/operatelog/core/annotations/OperateLog.java
@@ -1,6 +1,6 @@
package cn.iocoder.dashboard.framework.logger.operatelog.core.annotations;
-import cn.iocoder.dashboard.modules.system.enums.logger.SysOperateLogTypeEnum;
+import cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateLogTypeEnum;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@@ -32,7 +32,7 @@ public @interface OperateLog {
*
* 实际并不是数组,因为枚举不能设置 null 作为默认值
*/
- SysOperateLogTypeEnum[] type() default {};
+ OperateLogTypeEnum[] type() default {};
// ========== 开关字段 ==========
diff --git a/src/main/java/cn/iocoder/dashboard/framework/logger/operatelog/core/aop/OperateLogAspect.java b/src/main/java/cn/iocoder/dashboard/framework/logger/operatelog/core/aop/OperateLogAspect.java
index beb654210..a5afe95e1 100644
--- a/src/main/java/cn/iocoder/dashboard/framework/logger/operatelog/core/aop/OperateLogAspect.java
+++ b/src/main/java/cn/iocoder/dashboard/framework/logger/operatelog/core/aop/OperateLogAspect.java
@@ -6,11 +6,11 @@ import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.iocoder.dashboard.common.pojo.CommonResult;
import cn.iocoder.dashboard.framework.logger.operatelog.core.annotations.OperateLog;
+import cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateLogTypeEnum;
import cn.iocoder.dashboard.framework.logger.operatelog.core.service.OperateLogFrameworkService;
import cn.iocoder.dashboard.framework.security.core.util.SecurityUtils;
import cn.iocoder.dashboard.framework.tracer.core.util.TracerUtils;
import cn.iocoder.dashboard.modules.system.controller.logger.vo.SysOperateLogCreateReqVO;
-import cn.iocoder.dashboard.modules.system.enums.logger.SysOperateLogTypeEnum;
import cn.iocoder.dashboard.util.servlet.ServletUtils;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
@@ -180,7 +180,7 @@ public class OperateLogAspect {
}
if (operateLogVO.getType() == null) {
RequestMethod requestMethod = obtainFirstMatchRequestMethod(obtainRequestMethod(joinPoint));
- SysOperateLogTypeEnum operateLogType = convertOperateLogType(requestMethod);
+ OperateLogTypeEnum operateLogType = convertOperateLogType(requestMethod);
operateLogVO.setType(operateLogType != null ? operateLogType.getType() : null);
}
// content 和 exts 属性
@@ -275,21 +275,21 @@ public class OperateLogAspect {
return requestMethods[0];
}
- private static SysOperateLogTypeEnum convertOperateLogType(RequestMethod requestMethod) {
+ private static OperateLogTypeEnum convertOperateLogType(RequestMethod requestMethod) {
if (requestMethod == null) {
return null;
}
switch (requestMethod) {
case GET:
- return SysOperateLogTypeEnum.GET;
+ return OperateLogTypeEnum.GET;
case POST:
- return SysOperateLogTypeEnum.CREATE;
+ return OperateLogTypeEnum.CREATE;
case PUT:
- return SysOperateLogTypeEnum.UPDATE;
+ return OperateLogTypeEnum.UPDATE;
case DELETE:
- return SysOperateLogTypeEnum.DELETE;
+ return OperateLogTypeEnum.DELETE;
default:
- return SysOperateLogTypeEnum.OTHER;
+ return OperateLogTypeEnum.OTHER;
}
}
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/enums/logger/SysOperateLogTypeEnum.java b/src/main/java/cn/iocoder/dashboard/framework/logger/operatelog/core/enums/OperateLogTypeEnum.java
similarity index 89%
rename from src/main/java/cn/iocoder/dashboard/modules/system/enums/logger/SysOperateLogTypeEnum.java
rename to src/main/java/cn/iocoder/dashboard/framework/logger/operatelog/core/enums/OperateLogTypeEnum.java
index ab1f8546d..5e3552455 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/enums/logger/SysOperateLogTypeEnum.java
+++ b/src/main/java/cn/iocoder/dashboard/framework/logger/operatelog/core/enums/OperateLogTypeEnum.java
@@ -1,4 +1,4 @@
-package cn.iocoder.dashboard.modules.system.enums.logger;
+package cn.iocoder.dashboard.framework.logger.operatelog.core.enums;
import cn.iocoder.dashboard.framework.logger.operatelog.core.annotations.OperateLog;
import lombok.AllArgsConstructor;
@@ -11,7 +11,7 @@ import lombok.Getter;
*/
@Getter
@AllArgsConstructor
-public enum SysOperateLogTypeEnum {
+public enum OperateLogTypeEnum {
/**
* 查询
diff --git a/src/main/java/cn/iocoder/dashboard/framework/mybatis/core/mapper/BaseMapperX.java b/src/main/java/cn/iocoder/dashboard/framework/mybatis/core/mapper/BaseMapperX.java
new file mode 100644
index 000000000..e2f2559d8
--- /dev/null
+++ b/src/main/java/cn/iocoder/dashboard/framework/mybatis/core/mapper/BaseMapperX.java
@@ -0,0 +1,24 @@
+package cn.iocoder.dashboard.framework.mybatis.core.mapper;
+
+import cn.iocoder.dashboard.common.pojo.PageParam;
+import cn.iocoder.dashboard.common.pojo.PageResult;
+import cn.iocoder.dashboard.framework.mybatis.core.util.MyBatisUtils;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * 在 MyBatis Plus 的 BaseMapper 的基础上拓展,提供更多的能力
+ */
+public interface BaseMapperX extends BaseMapper {
+
+ default PageResult selectPage(PageParam pageParam, @Param("ew") Wrapper queryWrapper) {
+ // MyBatis Plus 查询
+ IPage mpPage = MyBatisUtils.buildPage(pageParam);
+ selectPage(mpPage, queryWrapper);
+ // 转换返回
+ return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
+ }
+
+}
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/auth/SysAuthController.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/auth/SysAuthController.java
index 3db8ed8ef..3669652e8 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/controller/auth/SysAuthController.java
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/auth/SysAuthController.java
@@ -54,7 +54,6 @@ public class SysAuthController {
@ApiOperation("获取登陆用户的权限信息")
@GetMapping("/get-permission-info")
- @OperateLog
public CommonResult getPermissionInfo() {
// 获得用户信息
SysUserDO user = userService.getUser(getLoginUserId());
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/common/SysCaptchaController.http b/src/main/java/cn/iocoder/dashboard/modules/system/controller/common/SysCaptchaController.http
index 90859ca70..0b1cf854b 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/controller/common/SysCaptchaController.http
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/common/SysCaptchaController.http
@@ -1,2 +1,2 @@
### 请求 /captcha/get-image 接口 => 成功
-GET {{baseUrl}}/captcha/get-image
+GET {{baseUrl}}/system/captcha/get-image
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/common/SysCaptchaController.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/common/SysCaptchaController.java
index 3faa96db3..f29e835ad 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/controller/common/SysCaptchaController.java
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/common/SysCaptchaController.java
@@ -23,7 +23,7 @@ public class SysCaptchaController {
@ApiOperation("生成图片验证码")
@GetMapping("/get-image")
- private CommonResult getCaptchaImage() {
+ public CommonResult getCaptchaImage() {
return success(captchaService.getCaptchaImage());
}
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/SysOperateLogController.http b/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/SysOperateLogController.http
new file mode 100644
index 000000000..3b8871996
--- /dev/null
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/SysOperateLogController.http
@@ -0,0 +1,3 @@
+### 请求 /system/operate-log/demo 接口 => 成功
+GET {{baseUrl}}/system/operate-log/demo
+Authorization: Bearer {{token}}
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/SysOperateLogController.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/SysOperateLogController.java
new file mode 100644
index 000000000..2b569e193
--- /dev/null
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/SysOperateLogController.java
@@ -0,0 +1,86 @@
+package cn.iocoder.dashboard.modules.system.controller.logger;
+
+import cn.iocoder.dashboard.common.pojo.CommonResult;
+import cn.iocoder.dashboard.common.pojo.PageResult;
+import cn.iocoder.dashboard.framework.logger.operatelog.core.annotations.OperateLog;
+import cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateLogTypeEnum;
+import cn.iocoder.dashboard.framework.logger.operatelog.core.util.OperateLogUtils;
+import cn.iocoder.dashboard.modules.system.controller.logger.vo.SysOperateLogPageReqVO;
+import cn.iocoder.dashboard.modules.system.controller.logger.vo.SysOperateLogRespVO;
+import cn.iocoder.dashboard.modules.system.convert.logger.SysOperateLogConvert;
+import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger.SysOperateLogDO;
+import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO;
+import cn.iocoder.dashboard.modules.system.service.logger.SysOperateLogService;
+import cn.iocoder.dashboard.modules.system.service.user.SysUserService;
+import cn.iocoder.dashboard.util.collection.CollectionUtils;
+import cn.iocoder.dashboard.util.collection.MapUtils;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
+
+@Api(tags = "操作日志 API")
+@RestController
+@RequestMapping("/system/operate-log")
+public class SysOperateLogController {
+
+ @Resource
+ private SysOperateLogService operateLogService;
+
+ @Resource
+ private SysUserService userService;
+
+ @ApiOperation("示例")
+ @OperateLog(type = OperateLogTypeEnum.OTHER)
+ @GetMapping("/demo")
+ public CommonResult demo() {
+ // 这里可以调用业务逻辑
+
+ // 补全操作日志的明细
+ OperateLogUtils.setContent("将编号 1 的数据,xxx 字段修改成了 yyyy");
+ OperateLogUtils.addExt("orderId", 1);
+
+ // 响应
+ return success(true);
+ }
+
+ @ApiOperation("查看操作日志分页列表")
+ @GetMapping("/page")
+// @PreAuthorize("@ss.hasPermi('system:operate-log:query')")
+ public CommonResult> pageOperateLog(@Validated SysOperateLogPageReqVO reqVO) {
+ PageResult pageResult = operateLogService.pageOperateLog(reqVO);
+
+ // 获得拼接需要的数据
+ Collection userIds = CollectionUtils.convertList(pageResult.getList(), SysOperateLogDO::getUserId);
+ Map userMap = userService.getUserMap(userIds);
+ // 拼接数据
+ List list = new ArrayList<>(pageResult.getList().size());
+ pageResult.getList().forEach(operateLog -> {
+ SysOperateLogRespVO respVO = SysOperateLogConvert.INSTANCE.convert(operateLog);
+ list.add(respVO);
+ // 拼接用户信息
+ MapUtils.findAndThen(userMap, operateLog.getUserId(), user -> respVO.setUserNickname(user.getNickname()));
+ });
+ return success(new PageResult<>(list, pageResult.getTotal()));
+ }
+
+// @Log(title = "操作日志", businessType = BusinessType.EXPORT)
+// @PreAuthorize("@ss.hasPermi('system:operate-log:export')")
+// @GetMapping("/export")
+// public AjaxResult export(SysOperLog operLog) {
+// List list = operLogService.selectOperLogList(operLog);
+// ExcelUtil util = new ExcelUtil(SysOperLog.class);
+// return util.exportExcel(list, "操作日志");
+// }
+
+}
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/package-info.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/package-info.java
deleted file mode 100644
index d682a7365..000000000
--- a/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/package-info.java
+++ /dev/null
@@ -1 +0,0 @@
-package cn.iocoder.dashboard.modules.system.controller.logger;
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/SysOperateLogBaseVO.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/SysOperateLogBaseVO.java
index 31d734461..35bc57f28 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/SysOperateLogBaseVO.java
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/SysOperateLogBaseVO.java
@@ -6,6 +6,7 @@ import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Date;
+import java.util.Map;
/**
* 操作日志 Base VO,提供给添加、修改、详细的子 VO 使用
@@ -30,10 +31,16 @@ public class SysOperateLogBaseVO {
@NotEmpty(message = "操作名")
private String name;
- @ApiModelProperty(value = "操作分类", required = true, example = "操作分类", notes = "参见 SysOperateLogTypeEnum 枚举类")
+ @ApiModelProperty(value = "操作分类", required = true, example = "1", notes = "参见 SysOperateLogTypeEnum 枚举类")
@NotNull(message = "操作分类不能为空")
private Integer type;
+ @ApiModelProperty(value = "操作明细", example = "修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。")
+ private String content;
+
+ @ApiModelProperty(value = "拓展字段", example = "{'orderId': 1}")
+ private Map exts;
+
@ApiModelProperty(value = "请求方法名", required = true, example = "GET")
@NotEmpty(message = "请求方法名不能为空")
private String requestMethod;
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/SysOperateLogPageReqVO.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/SysOperateLogPageReqVO.java
new file mode 100644
index 000000000..7602063f9
--- /dev/null
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/SysOperateLogPageReqVO.java
@@ -0,0 +1,39 @@
+package cn.iocoder.dashboard.modules.system.controller.logger.vo;
+
+import cn.iocoder.dashboard.common.pojo.PageParam;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+import static cn.iocoder.dashboard.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@ApiModel("操作日志分页列表 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class SysOperateLogPageReqVO extends PageParam {
+
+ @ApiModelProperty(value = "操作模块", example = "订单", notes = "模拟匹配")
+ private String module;
+
+ @ApiModelProperty(value = "用户昵称", example = "芋道", notes = "模拟匹配")
+ private String userNickname;
+
+ @ApiModelProperty(value = "操作分类", example = "1", notes = "参见 SysOperateLogTypeEnum 枚举类")
+ private Integer type;
+
+ @ApiModelProperty(value = "操作状态", example = "true")
+ private Boolean success;
+
+ @ApiModelProperty(value = "开始时间", example = "2020-10-24")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date beginTime;
+
+ @ApiModelProperty(value = "结束时间", example = "2020-10-24")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date endTime;
+
+}
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/SysOperateLogRespVO.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/SysOperateLogRespVO.java
new file mode 100644
index 000000000..34b78b6cc
--- /dev/null
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/SysOperateLogRespVO.java
@@ -0,0 +1,21 @@
+package cn.iocoder.dashboard.modules.system.controller.logger.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+@ApiModel("操作日志 Response VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class SysOperateLogRespVO extends SysOperateLogBaseVO {
+
+ @ApiModelProperty(value = "日志编号", required = true, example = "1024")
+ private Long id;
+
+ @ApiModelProperty(value = "用户昵称", required = true, example = "芋艿")
+ private String userNickname;
+
+}
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/convert/logger/SysOperateLogConvert.java b/src/main/java/cn/iocoder/dashboard/modules/system/convert/logger/SysOperateLogConvert.java
index 734c82c31..2f46788e4 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/convert/logger/SysOperateLogConvert.java
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/convert/logger/SysOperateLogConvert.java
@@ -1,6 +1,8 @@
package cn.iocoder.dashboard.modules.system.convert.logger;
+import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.modules.system.controller.logger.vo.SysOperateLogCreateReqVO;
+import cn.iocoder.dashboard.modules.system.controller.logger.vo.SysOperateLogRespVO;
import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger.SysOperateLogDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@@ -12,4 +14,8 @@ public interface SysOperateLogConvert {
SysOperateLogDO convert(SysOperateLogCreateReqVO bean);
+ PageResult convertPage(PageResult page);
+
+ SysOperateLogRespVO convert(SysOperateLogDO bean);
+
}
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/logger/SysOperateLogMapper.java b/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/logger/SysOperateLogMapper.java
index b15bd6d0c..99667ec78 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/logger/SysOperateLogMapper.java
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/logger/SysOperateLogMapper.java
@@ -1,9 +1,30 @@
package cn.iocoder.dashboard.modules.system.dal.mysql.dao.logger;
+import cn.iocoder.dashboard.common.exception.enums.GlobalErrorCodeConstants;
+import cn.iocoder.dashboard.common.pojo.PageResult;
+import cn.iocoder.dashboard.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.dashboard.framework.mybatis.core.query.QueryWrapperX;
+import cn.iocoder.dashboard.modules.system.controller.logger.vo.SysOperateLogPageReqVO;
import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger.SysOperateLogDO;
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
+import java.util.Collection;
+
@Mapper
-public interface SysOperateLogMapper extends BaseMapper {
+public interface SysOperateLogMapper extends BaseMapperX {
+
+ default PageResult selectPage(SysOperateLogPageReqVO reqVO, Collection userIds) {
+ QueryWrapperX query = new QueryWrapperX()
+ .likeIfPresent("module", reqVO.getModule())
+ .inIfPresent("user_id", userIds)
+ .eqIfPresent("operate_type", reqVO.getType())
+ .betweenIfPresent("start_time", reqVO.getBeginTime(), reqVO.getEndTime());
+ if (Boolean.TRUE.equals(reqVO.getSuccess())) {
+ query.eq("result_code", GlobalErrorCodeConstants.SUCCESS.getCode());
+ } else if (Boolean.FALSE.equals(reqVO.getSuccess())) {
+ query.gt("result_code", GlobalErrorCodeConstants.SUCCESS.getCode());
+ }
+ return selectPage(reqVO, query);
+ }
+
}
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/user/SysUserMapper.java b/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/user/SysUserMapper.java
index 225195f12..5103fc00e 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/user/SysUserMapper.java
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/user/SysUserMapper.java
@@ -45,5 +45,9 @@ public interface SysUserMapper extends BaseMapper {
.inIfPresent("dept_id", deptIds));
}
+ default List selectListByNickname(String nickname) {
+ return selectList(new QueryWrapperX().like("nickname", nickname));
+ }
+
}
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/logger/SysOperateLogDO.java b/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/logger/SysOperateLogDO.java
index be835d006..709b486ab 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/logger/SysOperateLogDO.java
+++ b/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;
import cn.iocoder.dashboard.common.pojo.CommonResult;
import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO;
-import cn.iocoder.dashboard.modules.system.enums.logger.SysOperateLogTypeEnum;
+import cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateLogTypeEnum;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
@@ -62,22 +62,18 @@ public class SysOperateLogDO extends BaseDO {
/**
* 操作分类
*
- * 枚举 {@link SysOperateLogTypeEnum}
+ * 枚举 {@link OperateLogTypeEnum}
*/
@TableField("operate_type")
private Integer type;
/**
* 操作内容,记录整个操作的明细
* 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。
- *
- * TODO 预留字段
*/
private String content;
/**
* 拓展字段,有些复杂的业务,需要记录一些字段
* 例如说,记录订单编号,则可以添加 key 为 "orderId",value 为订单编号
- *
- * TODO 预留字段
*/
@TableField(typeHandler = FastjsonTypeHandler.class)
private Map exts;
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/logger/SysOperateLogService.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/logger/SysOperateLogService.java
index 8cf65d209..89d87720a 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/service/logger/SysOperateLogService.java
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/logger/SysOperateLogService.java
@@ -1,9 +1,21 @@
package cn.iocoder.dashboard.modules.system.service.logger;
+import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.framework.logger.operatelog.core.service.OperateLogFrameworkService;
+import cn.iocoder.dashboard.modules.system.controller.logger.vo.SysOperateLogPageReqVO;
+import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger.SysOperateLogDO;
/**
* 操作日志 Service 接口
*/
public interface SysOperateLogService extends OperateLogFrameworkService {
+
+ /**
+ * 获得操作日志分页列表
+ *
+ * @param reqVO 分页条件
+ * @return 操作日志分页列表
+ */
+ PageResult pageOperateLog(SysOperateLogPageReqVO reqVO);
+
}
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/logger/impl/SysOperateLogServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/logger/impl/SysOperateLogServiceImpl.java
index 4c7905da2..0e8953c70 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/service/logger/impl/SysOperateLogServiceImpl.java
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/logger/impl/SysOperateLogServiceImpl.java
@@ -1,18 +1,27 @@
package cn.iocoder.dashboard.modules.system.service.logger.impl;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.modules.system.controller.logger.vo.SysOperateLogCreateReqVO;
+import cn.iocoder.dashboard.modules.system.controller.logger.vo.SysOperateLogPageReqVO;
import cn.iocoder.dashboard.modules.system.convert.logger.SysOperateLogConvert;
import cn.iocoder.dashboard.modules.system.dal.mysql.dao.logger.SysOperateLogMapper;
import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger.SysOperateLogDO;
+import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO;
import cn.iocoder.dashboard.modules.system.service.logger.SysOperateLogService;
+import cn.iocoder.dashboard.modules.system.service.user.SysUserService;
import cn.iocoder.dashboard.util.string.StrUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
+import java.util.Collection;
-import static cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger.SysOperateLogDO.*;
+import static cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger.SysOperateLogDO.JAVA_METHOD_ARGS_MAX_LENGTH;
+import static cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.logger.SysOperateLogDO.RESULT_MAX_LENGTH;
+import static cn.iocoder.dashboard.util.collection.CollectionUtils.convertSet;
@Service
@Slf4j
@@ -21,6 +30,9 @@ public class SysOperateLogServiceImpl implements SysOperateLogService {
@Resource
private SysOperateLogMapper operateLogMapper;
+ @Resource
+ private SysUserService userService;
+
@Override
@Async
public void createOperateLogAsync(SysOperateLogCreateReqVO reqVO) {
@@ -35,4 +47,18 @@ public class SysOperateLogServiceImpl implements SysOperateLogService {
}
}
+ @Override
+ public PageResult pageOperateLog(SysOperateLogPageReqVO reqVO) {
+ // 处理基于用户昵称的查询
+ Collection userIds = null;
+ if (StrUtil.isNotEmpty(reqVO.getUserNickname())) {
+ userIds = convertSet(userService.listUsersByNickname(reqVO.getUserNickname()), SysUserDO::getId);
+ if (CollUtil.isEmpty(userIds)) {
+ return PageResult.empty();
+ }
+ }
+ // 查询分页
+ return operateLogMapper.selectPage(reqVO, userIds);
+ }
+
}
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/user/SysUserService.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/user/SysUserService.java
index 771ffeb9f..288c14dee 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/service/user/SysUserService.java
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/user/SysUserService.java
@@ -1,10 +1,15 @@
package cn.iocoder.dashboard.modules.system.service.user;
+import cn.hutool.core.collection.CollUtil;
import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.*;
import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO;
+import cn.iocoder.dashboard.util.collection.CollectionUtils;
+import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
* 用户 Service 接口
@@ -45,6 +50,35 @@ public interface SysUserService {
*/
List listUsers(SysUserExportReqVO reqVO);
+ /**
+ * 获得用户列表
+ *
+ * @param ids 用户编号数组
+ * @return 用户列表
+ */
+ List listUsers(Collection ids);
+
+ /**
+ * 获得用户 Map
+ *
+ * @param ids 用户编号数组
+ * @return 用户 Map
+ */
+ default Map getUserMap(Collection ids) {
+ if (CollUtil.isEmpty(ids)) {
+ return new HashMap<>();
+ }
+ return CollectionUtils.convertMap(listUsers(ids), SysUserDO::getId);
+ }
+
+ /**
+ * 获得用户列表,基于昵称模糊匹配
+ *
+ * @param nickname 昵称
+ * @return 用户列表
+ */
+ List listUsersByNickname(String nickname);
+
/**
* 创建用户
*
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/user/SysUserServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/user/SysUserServiceImpl.java
index 11b541177..b71e634cf 100644
--- a/src/main/java/cn/iocoder/dashboard/modules/system/service/user/SysUserServiceImpl.java
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/user/SysUserServiceImpl.java
@@ -83,6 +83,16 @@ public class SysUserServiceImpl implements SysUserService {
return userMapper.selectList(reqVO, this.getDeptCondition(reqVO.getDeptId()));
}
+ @Override
+ public List listUsers(Collection ids) {
+ return userMapper.selectBatchIds(ids);
+ }
+
+ @Override
+ public List listUsersByNickname(String nickname) {
+ return userMapper.selectListByNickname(nickname);
+ }
+
/**
* 获得部门条件:查询指定部门的子部门编号们,包括自身
*