Bläddra i källkod

1. 优化代码生成器的模板
2. 增加 API 正常日志的 API 接口

YunaiV 4 år sedan
förälder
incheckning
0678fb7ca0
19 ändrade filer med 485 tillägg och 22 borttagningar
  1. 3 1
      src/main/java/cn/iocoder/dashboard/framework/logger/apilog/config/ApiLogConfiguration.java
  2. 11 13
      src/main/java/cn/iocoder/dashboard/framework/logger/apilog/core/filter/ApiAccessLogFilter.java
  3. 1 1
      src/main/java/cn/iocoder/dashboard/framework/logger/apilog/core/service/dto/ApiAccessLogCreateDTO.java
  4. 71 0
      src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/SysApiAccessLogController.java
  5. 75 0
      src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/apiaccesslog/SysApiAccessLogBaseVO.java
  6. 66 0
      src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/apiaccesslog/SysApiAccessLogExcelVO.java
  7. 42 0
      src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/apiaccesslog/SysApiAccessLogExportReqVO.java
  8. 47 0
      src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/apiaccesslog/SysApiAccessLogPageReqVO.java
  9. 23 0
      src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/apiaccesslog/SysApiAccessLogRespVO.java
  10. 33 0
      src/main/java/cn/iocoder/dashboard/modules/system/convert/logger/SysApiAccessLogConvert.java
  11. 1 1
      src/main/java/cn/iocoder/dashboard/modules/system/dal/dataobject/logger/SysApiAccessLogDO.java
  12. 45 0
      src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/logger/SysApiAccessLogMapper.java
  13. 2 0
      src/main/java/cn/iocoder/dashboard/modules/system/enums/dict/SysDictTypeEnum.java
  14. 31 0
      src/main/java/cn/iocoder/dashboard/modules/system/service/logger/SysApiAccessLogService.java
  15. 29 1
      src/main/java/cn/iocoder/dashboard/modules/system/service/logger/impl/SysApiAccessLogServiceImpl.java
  16. 1 1
      src/main/resources/application-dev.yaml
  17. 1 1
      src/main/resources/application-local.yaml
  18. 1 1
      src/main/resources/codegen/java/controller/controller.vm
  19. 2 2
      src/main/resources/codegen/java/service/serviceImpl.vm

+ 3 - 1
src/main/java/cn/iocoder/dashboard/framework/logger/apilog/config/ApiLogConfiguration.java

@@ -4,6 +4,7 @@ import cn.iocoder.dashboard.framework.logger.apilog.core.filter.ApiAccessLogFilt
 import cn.iocoder.dashboard.framework.logger.apilog.core.service.ApiAccessLogFrameworkService;
 import cn.iocoder.dashboard.framework.web.config.WebProperties;
 import cn.iocoder.dashboard.framework.web.core.enums.FilterOrderEnum;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.boot.web.servlet.FilterRegistrationBean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -18,8 +19,9 @@ public class ApiLogConfiguration {
      */
     @Bean
     public FilterRegistrationBean<ApiAccessLogFilter> apiAccessLogFilter(WebProperties webProperties,
+                                                                         @Value("${spring.application.name}") String applicationName,
                                                                          ApiAccessLogFrameworkService apiAccessLogFrameworkService) {
-        ApiAccessLogFilter filter = new ApiAccessLogFilter(webProperties, apiAccessLogFrameworkService);
+        ApiAccessLogFilter filter = new ApiAccessLogFilter(webProperties, applicationName, apiAccessLogFrameworkService);
         return createFilterBean(filter, FilterOrderEnum.API_ACCESS_LOG_FILTER);
     }
 

+ 11 - 13
src/main/java/cn/iocoder/dashboard/framework/logger/apilog/core/filter/ApiAccessLogFilter.java

@@ -15,7 +15,6 @@ import cn.iocoder.dashboard.util.json.JsonUtils;
 import cn.iocoder.dashboard.util.servlet.ServletUtils;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.web.filter.OncePerRequestFilter;
 
 import javax.servlet.FilterChain;
@@ -36,10 +35,9 @@ import java.util.Map;
 public class ApiAccessLogFilter extends OncePerRequestFilter {
 
     private final WebProperties webProperties;
-    private final ApiAccessLogFrameworkService apiAccessLogFrameworkService;
+    private final String applicationName;
 
-    @Value("${spring.application.name}")
-    private String applicationName;
+    private final ApiAccessLogFrameworkService apiAccessLogFrameworkService;
 
     @Override
     protected boolean shouldNotFilter(HttpServletRequest request) {
@@ -51,7 +49,7 @@ public class ApiAccessLogFilter extends OncePerRequestFilter {
     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
             throws ServletException, IOException {
         // 获得开始时间
-        Date startTime = new Date();
+        Date beginTim = new Date();
         // 提前获得参数,避免 XssFilter 过滤处理
         Map<String, String> queryString = ServletUtil.getParamMap(request);
         String requestBody = ServletUtils.isJsonRequest(request) ? ServletUtil.getBody(request) : null;
@@ -60,25 +58,25 @@ public class ApiAccessLogFilter extends OncePerRequestFilter {
             // 继续过滤器
             filterChain.doFilter(request, response);
             // 正常执行,记录日志
-            createApiAccessLog(request, startTime, queryString, requestBody, null);
+            createApiAccessLog(request, beginTim, queryString, requestBody, null);
         } catch (Exception ex) {
             // 异常执行,记录日志
-            createApiAccessLog(request, startTime, queryString, requestBody, ex);
+            createApiAccessLog(request, beginTim, queryString, requestBody, ex);
             throw ex;
         }
     }
 
-    private void createApiAccessLog(HttpServletRequest request, Date startTime,
+    private void createApiAccessLog(HttpServletRequest request, Date beginTime,
                                     Map<String, String> queryString, String requestBody, Exception ex) {
         try {
-            ApiAccessLogCreateDTO accessLog = this.buildApiAccessLogDTO(request, startTime, queryString, requestBody, ex);
+            ApiAccessLogCreateDTO accessLog = this.buildApiAccessLogDTO(request, beginTime, queryString, requestBody, ex);
             apiAccessLogFrameworkService.createApiAccessLogAsync(accessLog);
         } catch (Exception e) {
-            log.error("[createApiAccessLog][url({}) 发生异常]", request.getRequestURI(), ex);
+            log.error("[createApiAccessLog][url({}) 发生异常]", request.getRequestURI(), e);
         }
     }
 
-    private ApiAccessLogCreateDTO buildApiAccessLogDTO(HttpServletRequest request, Date startTime,
+    private ApiAccessLogCreateDTO buildApiAccessLogDTO(HttpServletRequest request, Date beginTime,
                                                        Map<String, String> queryString, String requestBody, Exception ex) {
         ApiAccessLogCreateDTO accessLog = new ApiAccessLogCreateDTO();
         // 处理用户信息
@@ -106,9 +104,9 @@ public class ApiAccessLogFilter extends OncePerRequestFilter {
         accessLog.setUserAgent(ServletUtils.getUserAgent(request));
         accessLog.setUserIp(ServletUtil.getClientIP(request));
         // 持续时间
-        accessLog.setStartTime(startTime);
+        accessLog.setBeginTime(beginTime);
         accessLog.setEndTime(new Date());
-        accessLog.setDuration((int) DateUtils.diff(accessLog.getEndTime(), accessLog.getStartTime()));
+        accessLog.setDuration((int) DateUtils.diff(accessLog.getEndTime(), accessLog.getBeginTime()));
         return accessLog;
     }
 

+ 1 - 1
src/main/java/cn/iocoder/dashboard/framework/logger/apilog/core/service/dto/ApiAccessLogCreateDTO.java

@@ -61,7 +61,7 @@ public class ApiAccessLogCreateDTO {
      * 开始请求时间
      */
     @NotNull(message = "开始请求时间不能为空")
-    private Date startTime;
+    private Date beginTime;
     /**
      * 结束请求时间
      */

+ 71 - 0
src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/SysApiAccessLogController.java

@@ -0,0 +1,71 @@
+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.excel.core.util.ExcelUtils;
+import cn.iocoder.dashboard.framework.logger.operatelog.core.annotations.OperateLog;
+import cn.iocoder.dashboard.modules.system.controller.logger.vo.apiaccesslog.SysApiAccessLogExcelVO;
+import cn.iocoder.dashboard.modules.system.controller.logger.vo.apiaccesslog.SysApiAccessLogExportReqVO;
+import cn.iocoder.dashboard.modules.system.controller.logger.vo.apiaccesslog.SysApiAccessLogPageReqVO;
+import cn.iocoder.dashboard.modules.system.controller.logger.vo.apiaccesslog.SysApiAccessLogRespVO;
+import cn.iocoder.dashboard.modules.system.convert.logger.SysApiAccessLogConvert;
+import cn.iocoder.dashboard.modules.system.dal.dataobject.logger.SysApiAccessLogDO;
+import cn.iocoder.dashboard.modules.system.service.logger.SysApiAccessLogService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.security.access.prepost.PreAuthorize;
+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.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+import java.io.IOException;
+import java.util.List;
+
+import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
+import static cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateTypeEnum.EXPORT;
+
+@Api(tags = "API 访问日志")
+@RestController
+@RequestMapping("/system/api-access-log")
+@Validated
+public class SysApiAccessLogController {
+
+    @Resource
+    private SysApiAccessLogService apiAccessLogService;
+
+    @GetMapping("/get")
+    @ApiOperation("获得API 访问日志")
+    @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
+    @PreAuthorize("@ss.hasPermission('system:api-access-log:query')")
+    public CommonResult<SysApiAccessLogRespVO> getApiAccessLog(@RequestParam("id") Long id) {
+        SysApiAccessLogDO apiAccessLog = apiAccessLogService.getApiAccessLog(id);
+        return success(SysApiAccessLogConvert.INSTANCE.convert(apiAccessLog));
+    }
+
+    @GetMapping("/page")
+    @ApiOperation("获得API 访问日志分页")
+    @PreAuthorize("@ss.hasPermission('system:api-access-log:query')")
+    public CommonResult<PageResult<SysApiAccessLogRespVO>> getApiAccessLogPage(@Valid SysApiAccessLogPageReqVO pageVO) {
+        PageResult<SysApiAccessLogDO> pageResult = apiAccessLogService.getApiAccessLogPage(pageVO);
+        return success(SysApiAccessLogConvert.INSTANCE.convertPage(pageResult));
+    }
+
+    @GetMapping("/export-excel")
+    @ApiOperation("导出API 访问日志 Excel")
+    @PreAuthorize("@ss.hasPermission('system:api-access-log:export')")
+    @OperateLog(type = EXPORT)
+    public void exportApiAccessLogExcel(@Valid SysApiAccessLogExportReqVO exportReqVO,
+                                        HttpServletResponse response) throws IOException {
+        List<SysApiAccessLogDO> list = apiAccessLogService.getApiAccessLogList(exportReqVO);
+        // 导出 Excel
+        List<SysApiAccessLogExcelVO> datas = SysApiAccessLogConvert.INSTANCE.convertList02(list);
+        ExcelUtils.write(response, "API 访问日志.xls", "数据", SysApiAccessLogExcelVO.class, datas);
+    }
+
+}

+ 75 - 0
src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/apiaccesslog/SysApiAccessLogBaseVO.java

@@ -0,0 +1,75 @@
+package cn.iocoder.dashboard.modules.system.controller.logger.vo.apiaccesslog;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+
+import static cn.iocoder.dashboard.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+/**
+* API 访问日志 Base VO,提供给添加、修改、详细的子 VO 使用
+* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
+*/
+@Data
+public class SysApiAccessLogBaseVO {
+
+    @ApiModelProperty(value = "链路追踪编号", required = true, example = "66600cb6-7852-11eb-9439-0242ac130002")
+    @NotNull(message = "链路追踪编号不能为空")
+    private String traceId;
+
+    @ApiModelProperty(value = "用户编号", required = true, example = "666")
+    @NotNull(message = "用户编号不能为空")
+    private Long userId;
+
+    @ApiModelProperty(value = "用户类型", required = true, example = "2", notes = "参见 UserTypeEnum 枚举")
+    @NotNull(message = "用户类型不能为空")
+    private Integer userType;
+
+    @ApiModelProperty(value = "应用名", required = true, example = "dashboard")
+    @NotNull(message = "应用名不能为空")
+    private String applicationName;
+
+    @ApiModelProperty(value = "请求方法名", required = true, example = "GET")
+    @NotNull(message = "请求方法名不能为空")
+    private String requestMethod;
+
+    @ApiModelProperty(value = "请求地址", required = true, example = "/xxx/yyy")
+    @NotNull(message = "请求地址不能为空")
+    private String requestUrl;
+
+    @ApiModelProperty(value = "Java 方法的参数")
+    private String requestParams;
+
+    @ApiModelProperty(value = "用户 IP", required = true, example = "127.0.0.1")
+    @NotNull(message = "用户 IP不能为空")
+    private String userIp;
+
+    @ApiModelProperty(value = "浏览器 UA", required = true, example = "Mozilla/5.0")
+    @NotNull(message = "浏览器 UA不能为空")
+    private String userAgent;
+
+    @ApiModelProperty(value = "开始请求时间", required = true)
+    @NotNull(message = "开始请求时间不能为空")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private Date beginTime;
+
+    @ApiModelProperty(value = "结束请求时间", required = true)
+    @NotNull(message = "结束请求时间不能为空")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private Date endTime;
+
+    @ApiModelProperty(value = "执行时长", required = true, example = "100")
+    @NotNull(message = "执行时长不能为空")
+    private Integer duration;
+
+    @ApiModelProperty(value = "结果码", required = true, example = "0")
+    @NotNull(message = "结果码不能为空")
+    private Integer resultCode;
+
+    @ApiModelProperty(value = "结果提示", example = "芋道源码,牛逼!")
+    private String resultMsg;
+
+}

+ 66 - 0
src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/apiaccesslog/SysApiAccessLogExcelVO.java

@@ -0,0 +1,66 @@
+package cn.iocoder.dashboard.modules.system.controller.logger.vo.apiaccesslog;
+
+import cn.iocoder.dashboard.framework.excel.core.annotations.DictFormat;
+import cn.iocoder.dashboard.framework.excel.core.convert.DictConvert;
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+import static cn.iocoder.dashboard.modules.system.enums.dict.SysDictTypeEnum.USER_TYPE;
+
+/**
+ * API 访问日志 Excel VO
+ *
+ * @author 芋道源码
+ */
+@Data
+public class SysApiAccessLogExcelVO {
+
+    @ExcelProperty("日志主键")
+    private Long id;
+
+    @ExcelProperty("链路追踪编号")
+    private String traceId;
+
+    @ExcelProperty("用户编号")
+    private Long userId;
+
+    @ExcelProperty(value = "用户类型", converter = DictConvert.class)
+    @DictFormat(USER_TYPE)
+    private Integer userType;
+
+    @ExcelProperty("应用名")
+    private String applicationName;
+
+    @ExcelProperty("请求方法名")
+    private String requestMethod;
+
+    @ExcelProperty("请求地址")
+    private String requestUrl;
+
+    @ExcelProperty("Java 方法的参数")
+    private String requestParams;
+
+    @ExcelProperty("用户 IP")
+    private String userIp;
+
+    @ExcelProperty("浏览器 UA")
+    private String userAgent;
+
+    @ExcelProperty("开始请求时间")
+    private Date beginTime;
+
+    @ExcelProperty("结束请求时间")
+    private Date endTime;
+
+    @ExcelProperty("执行时长")
+    private Integer duration;
+
+    @ExcelProperty("结果码")
+    private Integer resultCode;
+
+    @ExcelProperty("结果提示")
+    private String resultMsg;
+
+}

+ 42 - 0
src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/apiaccesslog/SysApiAccessLogExportReqVO.java

@@ -0,0 +1,42 @@
+package cn.iocoder.dashboard.modules.system.controller.logger.vo.apiaccesslog;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+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(value = "API 访问日志 Excel 导出 Request VO", description = "参数和 SysApiAccessLogPageReqVO 是一致的")
+@Data
+public class SysApiAccessLogExportReqVO {
+
+    @ApiModelProperty(value = "用户编号", example = "666")
+    private Long userId;
+
+    @ApiModelProperty(value = "用户类型", example = "2")
+    private Integer userType;
+
+    @ApiModelProperty(value = "应用名", example = "dashboard")
+    private String applicationName;
+
+    @ApiModelProperty(value = "请求地址", example = "/xxx/yyy", notes = "模糊匹配")
+    private String requestUrl;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "开始开始请求时间")
+    private Date beginBeginTime;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "结束开始请求时间")
+    private Date endBeginTime;
+
+    @ApiModelProperty(value = "执行时长", example = "100", notes = "大于等于,单位:毫秒")
+    private Integer duration;
+
+    @ApiModelProperty(value = "结果码", example = "0")
+    private Integer resultCode;
+
+}

+ 47 - 0
src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/apiaccesslog/SysApiAccessLogPageReqVO.java

@@ -0,0 +1,47 @@
+package cn.iocoder.dashboard.modules.system.controller.logger.vo.apiaccesslog;
+
+import cn.iocoder.dashboard.common.pojo.PageParam;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+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("API 访问日志分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class SysApiAccessLogPageReqVO extends PageParam {
+
+    @ApiModelProperty(value = "用户编号", example = "666")
+    private Long userId;
+
+    @ApiModelProperty(value = "用户类型", example = "2")
+    private Integer userType;
+
+    @ApiModelProperty(value = "应用名", example = "dashboard")
+    private String applicationName;
+
+    @ApiModelProperty(value = "请求地址", example = "/xxx/yyy", notes = "模糊匹配")
+    private String requestUrl;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "开始开始请求时间")
+    private Date beginBeginTime;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "结束开始请求时间")
+    private Date endBeginTime;
+
+    @ApiModelProperty(value = "执行时长", example = "100", notes = "大于等于,单位:毫秒")
+    private Integer duration;
+
+    @ApiModelProperty(value = "结果码", example = "0")
+    private Integer resultCode;
+
+}

+ 23 - 0
src/main/java/cn/iocoder/dashboard/modules/system/controller/logger/vo/apiaccesslog/SysApiAccessLogRespVO.java

@@ -0,0 +1,23 @@
+package cn.iocoder.dashboard.modules.system.controller.logger.vo.apiaccesslog;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import java.util.Date;
+
+@ApiModel("API 访问日志 Response VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class SysApiAccessLogRespVO extends SysApiAccessLogBaseVO {
+
+    @ApiModelProperty(value = "日志主键", required = true, example = "1024")
+    private Long id;
+
+    @ApiModelProperty(value = "创建时间", required = true)
+    private Date createTime;
+
+}

+ 33 - 0
src/main/java/cn/iocoder/dashboard/modules/system/convert/logger/SysApiAccessLogConvert.java

@@ -0,0 +1,33 @@
+package cn.iocoder.dashboard.modules.system.convert.logger;
+
+import cn.iocoder.dashboard.common.pojo.PageResult;
+import cn.iocoder.dashboard.framework.logger.apilog.core.service.dto.ApiAccessLogCreateDTO;
+import cn.iocoder.dashboard.modules.system.controller.logger.vo.apiaccesslog.SysApiAccessLogExcelVO;
+import cn.iocoder.dashboard.modules.system.controller.logger.vo.apiaccesslog.SysApiAccessLogRespVO;
+import cn.iocoder.dashboard.modules.system.dal.dataobject.logger.SysApiAccessLogDO;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+
+/**
+ * API 访问日志 Convert
+ *
+ * @author 芋道源码
+ */
+@Mapper
+public interface SysApiAccessLogConvert {
+
+    SysApiAccessLogConvert INSTANCE = Mappers.getMapper(SysApiAccessLogConvert.class);
+
+    SysApiAccessLogDO convert(ApiAccessLogCreateDTO bean);
+
+    SysApiAccessLogRespVO convert(SysApiAccessLogDO bean);
+
+    List<SysApiAccessLogRespVO> convertList(List<SysApiAccessLogDO> list);
+
+    PageResult<SysApiAccessLogRespVO> convertPage(PageResult<SysApiAccessLogDO> page);
+
+    List<SysApiAccessLogExcelVO> convertList02(List<SysApiAccessLogDO> list);
+
+}

+ 1 - 1
src/main/java/cn/iocoder/dashboard/modules/system/dal/dataobject/logger/SysApiAccessLogDO.java

@@ -78,7 +78,7 @@ public class SysApiAccessLogDO extends BaseDO {
     /**
      * 开始请求时间
      */
-    private Date startTime;
+    private Date beginTime;
     /**
      * 结束请求时间
      */

+ 45 - 0
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/logger/SysApiAccessLogMapper.java

@@ -0,0 +1,45 @@
+package cn.iocoder.dashboard.modules.system.dal.mysql.logger;
+
+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.apiaccesslog.SysApiAccessLogExportReqVO;
+import cn.iocoder.dashboard.modules.system.controller.logger.vo.apiaccesslog.SysApiAccessLogPageReqVO;
+import cn.iocoder.dashboard.modules.system.dal.dataobject.logger.SysApiAccessLogDO;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * API 访问日志 Mapper
+ *
+ * @author 芋道源码
+ */
+@Mapper
+public interface SysApiAccessLogMapper extends BaseMapperX<SysApiAccessLogDO> {
+
+    default PageResult<SysApiAccessLogDO> selectPage(SysApiAccessLogPageReqVO reqVO) {
+        return selectPage(reqVO, new QueryWrapperX<SysApiAccessLogDO>()
+                .eqIfPresent("user_id", reqVO.getUserId())
+                .eqIfPresent("user_type", reqVO.getUserType())
+                .eqIfPresent("application_name", reqVO.getApplicationName())
+                .likeIfPresent("request_url", reqVO.getRequestUrl())
+                .betweenIfPresent("begin_time", reqVO.getBeginBeginTime(), reqVO.getEndBeginTime())
+                .geIfPresent("duration", reqVO.getDuration())
+                .eqIfPresent("result_code", reqVO.getResultCode())
+        );
+    }
+
+    default List<SysApiAccessLogDO> selectList(SysApiAccessLogExportReqVO reqVO) {
+        return selectList(new QueryWrapperX<SysApiAccessLogDO>()
+                .eqIfPresent("user_id", reqVO.getUserId())
+                .eqIfPresent("user_type", reqVO.getUserType())
+                .eqIfPresent("application_name", reqVO.getApplicationName())
+                .likeIfPresent("request_url", reqVO.getRequestUrl())
+                .betweenIfPresent("begin_time", reqVO.getBeginBeginTime(), reqVO.getEndBeginTime())
+                .geIfPresent("duration", reqVO.getDuration())
+                .eqIfPresent("result_code", reqVO.getResultCode())
+        );
+    }
+
+}

+ 2 - 0
src/main/java/cn/iocoder/dashboard/modules/system/enums/dict/SysDictTypeEnum.java

@@ -10,6 +10,8 @@ import lombok.Getter;
 @AllArgsConstructor
 public enum SysDictTypeEnum {
 
+    USER_TYPE("user_type"), // 用户类型
+
     SYS_USER_SEX("sys_user_sex"), // 用户性别
     SYS_COMMON_STATUS("sys_common_status"), // 系统状态
     SYS_OPERATE_TYPE("sys_operate_type"), // 操作类型

+ 31 - 0
src/main/java/cn/iocoder/dashboard/modules/system/service/logger/SysApiAccessLogService.java

@@ -1,6 +1,12 @@
 package cn.iocoder.dashboard.modules.system.service.logger;
 
+import cn.iocoder.dashboard.common.pojo.PageResult;
 import cn.iocoder.dashboard.framework.logger.apilog.core.service.ApiAccessLogFrameworkService;
+import cn.iocoder.dashboard.modules.system.controller.logger.vo.apiaccesslog.SysApiAccessLogExportReqVO;
+import cn.iocoder.dashboard.modules.system.controller.logger.vo.apiaccesslog.SysApiAccessLogPageReqVO;
+import cn.iocoder.dashboard.modules.system.dal.dataobject.logger.SysApiAccessLogDO;
+
+import java.util.List;
 
 /**
  * API 访问日志 Service 接口
@@ -8,4 +14,29 @@ import cn.iocoder.dashboard.framework.logger.apilog.core.service.ApiAccessLogFra
  * @author 芋道源码
  */
 public interface SysApiAccessLogService extends ApiAccessLogFrameworkService {
+
+    /**
+     * 获得 API 访问日志
+     *
+     * @param id 编号
+     * @return API 访问日志
+     */
+    SysApiAccessLogDO getApiAccessLog(Long id);
+
+    /**
+     * 获得 API 访问日志分页
+     *
+     * @param pageReqVO 分页查询
+     * @return API 访问日志分页
+     */
+    PageResult<SysApiAccessLogDO> getApiAccessLogPage(SysApiAccessLogPageReqVO pageReqVO);
+
+    /**
+     * 获得 API 访问日志列表, 用于 Excel 导出
+     *
+     * @param exportReqVO 查询条件
+     * @return API 访问日志分页
+     */
+    List<SysApiAccessLogDO> getApiAccessLogList(SysApiAccessLogExportReqVO exportReqVO);
+
 }

+ 29 - 1
src/main/java/cn/iocoder/dashboard/modules/system/service/logger/impl/SysApiAccessLogServiceImpl.java

@@ -1,11 +1,20 @@
 package cn.iocoder.dashboard.modules.system.service.logger.impl;
 
+import cn.iocoder.dashboard.common.pojo.PageResult;
 import cn.iocoder.dashboard.framework.logger.apilog.core.service.dto.ApiAccessLogCreateDTO;
+import cn.iocoder.dashboard.modules.system.controller.logger.vo.apiaccesslog.SysApiAccessLogExportReqVO;
+import cn.iocoder.dashboard.modules.system.controller.logger.vo.apiaccesslog.SysApiAccessLogPageReqVO;
+import cn.iocoder.dashboard.modules.system.convert.logger.SysApiAccessLogConvert;
+import cn.iocoder.dashboard.modules.system.dal.dataobject.logger.SysApiAccessLogDO;
+import cn.iocoder.dashboard.modules.system.dal.mysql.logger.SysApiAccessLogMapper;
 import cn.iocoder.dashboard.modules.system.service.logger.SysApiAccessLogService;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
+import javax.annotation.Resource;
 import javax.validation.Valid;
+import java.util.List;
 
 /**
  * API 访问日志 Service 实现类
@@ -16,11 +25,30 @@ import javax.validation.Valid;
 @Validated
 public class SysApiAccessLogServiceImpl implements SysApiAccessLogService {
 
-
+    @Resource
+    private SysApiAccessLogMapper apiAccessLogMapper;
 
     @Override
+    @Async
     public void createApiAccessLogAsync(@Valid ApiAccessLogCreateDTO createDTO) {
+        // 插入
+        SysApiAccessLogDO apiAccessLog = SysApiAccessLogConvert.INSTANCE.convert(createDTO);
+        apiAccessLogMapper.insert(apiAccessLog);
+    }
+
+    @Override
+    public SysApiAccessLogDO getApiAccessLog(Long id) {
+        return apiAccessLogMapper.selectById(id);
+    }
 
+    @Override
+    public PageResult<SysApiAccessLogDO> getApiAccessLogPage(SysApiAccessLogPageReqVO pageReqVO) {
+        return apiAccessLogMapper.selectPage(pageReqVO);
+    }
+
+    @Override
+    public List<SysApiAccessLogDO> getApiAccessLogList(SysApiAccessLogExportReqVO exportReqVO) {
+        return apiAccessLogMapper.selectList(exportReqVO);
     }
 
 }

+ 1 - 1
src/main/resources/application-dev.yaml

@@ -157,7 +157,7 @@ yudao:
     base-package: ${yudao.info.base-package}.modules
     db-schemas: ${spring.datasource.name}
   xss:
-    enable: true
+    enable: false
     exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系
       - ${spring.boot.admin.context-path}/** # 不处理 Spring Boot Admin 的请求
       - ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求

+ 1 - 1
src/main/resources/application-local.yaml

@@ -157,7 +157,7 @@ yudao:
     base-package: ${yudao.info.base-package}.modules
     db-schemas: ${spring.datasource.name}
   xss:
-    enable: true
+    enable: false
     exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系
       - ${spring.boot.admin.context-path}/** # 不处理 Spring Boot Admin 的请求
       - ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求

+ 1 - 1
src/main/resources/codegen/java/controller/controller.vm

@@ -52,7 +52,7 @@ public class ${table.className}Controller {
         return success(true);
     }
 
-	@DeleteMapping("/delete")
+    @DeleteMapping("/delete")
     @ApiOperation("删除${table.classComment}")
     @ApiImplicitParam(name = "id", value = "编号", required = true)
 	@PreAuthorize("@ss.hasPermission('${permissionPrefix}:delete')")

+ 2 - 2
src/main/resources/codegen/java/service/serviceImpl.vm

@@ -74,12 +74,12 @@ public class ${table.className}ServiceImpl implements ${table.className}Service
 
     @Override
     public PageResult<${table.className}DO> get${simpleClassName}Page(${table.className}PageReqVO pageReqVO) {
-		return ${classNameVar}Mapper.selectPage(pageReqVO);
+        return ${classNameVar}Mapper.selectPage(pageReqVO);
     }
 
     @Override
     public List<${table.className}DO> get${simpleClassName}List(${table.className}ExportReqVO exportReqVO) {
-		return ${classNameVar}Mapper.selectList(exportReqVO);
+        return ${classNameVar}Mapper.selectList(exportReqVO);
     }
 
 }