# Conflicts:
#	yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/biz/infra/logger/ApiAccessLogCommonApi.java
#	yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/biz/infra/logger/ApiErrorLogCommonApi.java
#	yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/biz/infra/logger/dto/ApiAccessLogCreateReqDTO.java
#	yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoSecurityAutoConfiguration.java
#	yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/filter/TokenAuthenticationFilter.java
#	yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/apilog/config/YudaoApiLogAutoConfiguration.java
#	yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/YudaoWebAutoConfiguration.java
#	yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/api/logger/ApiAccessLogApiImpl.java
#	yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/logger/ApiAccessLogServiceImplTest.java
#	yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/OperateLogApi.java
This commit is contained in:
YunaiV
2025-05-14 21:04:37 +08:00
91 changed files with 338 additions and 365 deletions

View File

@@ -1,32 +0,0 @@
package cn.iocoder.yudao.module.infra.api.logger;
import cn.iocoder.yudao.module.infra.api.logger.dto.ApiAccessLogCreateReqDTO;
import org.springframework.scheduling.annotation.Async;
import javax.validation.Valid;
/**
* API 访问日志的 API 接口
*
* @author 芋道源码
*/
public interface ApiAccessLogApi {
/**
* 创建 API 访问日志
*
* @param createDTO 创建信息
*/
void createApiAccessLog(@Valid ApiAccessLogCreateReqDTO createDTO);
/**
* 【异步】创建 API 访问日志
*
* @param createDTO 访问日志 DTO
*/
@Async
default void createApiAccessLogAsync(ApiAccessLogCreateReqDTO createDTO) {
createApiAccessLog(createDTO);
}
}

View File

@@ -1,32 +0,0 @@
package cn.iocoder.yudao.module.infra.api.logger;
import cn.iocoder.yudao.module.infra.api.logger.dto.ApiErrorLogCreateReqDTO;
import org.springframework.scheduling.annotation.Async;
import javax.validation.Valid;
/**
* API 错误日志的 API 接口
*
* @author 芋道源码
*/
public interface ApiErrorLogApi {
/**
* 创建 API 错误日志
*
* @param createDTO 创建信息
*/
void createApiErrorLog(@Valid ApiErrorLogCreateReqDTO createDTO);
/**
* 【异步】创建 API 异常日志
*
* @param createDTO 异常日志 DTO
*/
@Async
default void createApiErrorLogAsync(ApiErrorLogCreateReqDTO createDTO) {
createApiErrorLog(createDTO);
}
}

View File

@@ -1,103 +0,0 @@
package cn.iocoder.yudao.module.infra.api.logger.dto;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
/**
* API 访问日志
*
* @author 芋道源码
*/
@Data
public class ApiAccessLogCreateReqDTO {
/**
* 链路追踪编号
*/
private String traceId;
/**
* 用户编号
*/
private Long userId;
/**
* 用户类型
*/
private Integer userType;
/**
* 应用名
*/
@NotNull(message = "应用名不能为空")
private String applicationName;
/**
* 请求方法名
*/
@NotNull(message = "http 请求方法不能为空")
private String requestMethod;
/**
* 访问地址
*/
@NotNull(message = "访问地址不能为空")
private String requestUrl;
/**
* 请求参数
*/
private String requestParams;
/**
* 响应结果
*/
private String responseBody;
/**
* 用户 IP
*/
@NotNull(message = "ip 不能为空")
private String userIp;
/**
* 浏览器 UA
*/
@NotNull(message = "User-Agent 不能为空")
private String userAgent;
/**
* 操作模块
*/
private String operateModule;
/**
* 操作名
*/
private String operateName;
/**
* 操作分类
*
* 枚举,参见 OperateTypeEnum 类
*/
private Integer operateType;
/**
* 开始请求时间
*/
@NotNull(message = "开始请求时间不能为空")
private LocalDateTime beginTime;
/**
* 结束请求时间
*/
@NotNull(message = "结束请求时间不能为空")
private LocalDateTime endTime;
/**
* 执行时长,单位:毫秒
*/
@NotNull(message = "执行时长不能为空")
private Integer duration;
/**
* 结果码
*/
@NotNull(message = "错误码不能为空")
private Integer resultCode;
/**
* 结果提示
*/
private String resultMsg;
}

View File

@@ -1,107 +0,0 @@
package cn.iocoder.yudao.module.infra.api.logger.dto;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
/**
* API 错误日志
*
* @author 芋道源码
*/
@Data
public class ApiErrorLogCreateReqDTO {
/**
* 链路编号
*/
private String traceId;
/**
* 账号编号
*/
private Long userId;
/**
* 用户类型
*/
private Integer userType;
/**
* 应用名
*/
@NotNull(message = "应用名不能为空")
private String applicationName;
/**
* 请求方法名
*/
@NotNull(message = "http 请求方法不能为空")
private String requestMethod;
/**
* 访问地址
*/
@NotNull(message = "访问地址不能为空")
private String requestUrl;
/**
* 请求参数
*/
@NotNull(message = "请求参数不能为空")
private String requestParams;
/**
* 用户 IP
*/
@NotNull(message = "ip 不能为空")
private String userIp;
/**
* 浏览器 UA
*/
@NotNull(message = "User-Agent 不能为空")
private String userAgent;
/**
* 异常时间
*/
@NotNull(message = "异常时间不能为空")
private LocalDateTime exceptionTime;
/**
* 异常名
*/
@NotNull(message = "异常名不能为空")
private String exceptionName;
/**
* 异常发生的类全名
*/
@NotNull(message = "异常发生的类全名不能为空")
private String exceptionClassName;
/**
* 异常发生的类文件
*/
@NotNull(message = "异常发生的类文件不能为空")
private String exceptionFileName;
/**
* 异常发生的方法名
*/
@NotNull(message = "异常发生的方法名不能为空")
private String exceptionMethodName;
/**
* 异常发生的方法所在行
*/
@NotNull(message = "异常发生的方法所在行不能为空")
private Integer exceptionLineNumber;
/**
* 异常的栈轨迹异常的栈轨迹
*/
@NotNull(message = "异常的栈轨迹不能为空")
private String exceptionStackTrace;
/**
* 异常导致的根消息
*/
@NotNull(message = "异常导致的根消息不能为空")
private String exceptionRootCauseMessage;
/**
* 异常导致的消息
*/
@NotNull(message = "异常导致的消息不能为空")
private String exceptionMessage;
}

View File

@@ -1,12 +1,12 @@
package cn.iocoder.yudao.module.infra.api.logger;
import cn.iocoder.yudao.module.infra.api.logger.dto.ApiAccessLogCreateReqDTO;
import cn.iocoder.yudao.framework.common.biz.infra.logger.ApiAccessLogCommonApi;
import cn.iocoder.yudao.framework.common.biz.infra.logger.dto.ApiAccessLogCreateReqDTO;
import cn.iocoder.yudao.module.infra.service.logger.ApiAccessLogService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
/**
* API 访问日志的 API 实现类
*
@@ -14,7 +14,7 @@ import javax.annotation.Resource;
*/
@Service
@Validated
public class ApiAccessLogApiImpl implements ApiAccessLogApi {
public class ApiAccessLogApiImpl implements ApiAccessLogCommonApi {
@Resource
private ApiAccessLogService apiAccessLogService;

View File

@@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.infra.api.logger;
import cn.iocoder.yudao.module.infra.api.logger.dto.ApiErrorLogCreateReqDTO;
import cn.iocoder.yudao.framework.common.biz.infra.logger.ApiErrorLogCommonApi;
import cn.iocoder.yudao.framework.common.biz.infra.logger.dto.ApiErrorLogCreateReqDTO;
import cn.iocoder.yudao.module.infra.service.logger.ApiErrorLogService;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
@@ -14,7 +15,7 @@ import javax.annotation.Resource;
*/
@Service
@Validated
public class ApiErrorLogApiImpl implements ApiErrorLogApi {
public class ApiErrorLogApiImpl implements ApiErrorLogCommonApi {
@Resource
private ApiErrorLogService apiErrorLogService;

View File

@@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.infra.service.logger;
import cn.iocoder.yudao.framework.common.biz.infra.logger.dto.ApiAccessLogCreateReqDTO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.infra.api.logger.dto.ApiAccessLogCreateReqDTO;
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog.ApiAccessLogPageReqVO;
import cn.iocoder.yudao.module.infra.dal.dataobject.logger.ApiAccessLogDO;

View File

@@ -1,11 +1,11 @@
package cn.iocoder.yudao.module.infra.service.logger;
import cn.iocoder.yudao.framework.common.biz.infra.logger.dto.ApiAccessLogCreateReqDTO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
import cn.iocoder.yudao.module.infra.api.logger.dto.ApiAccessLogCreateReqDTO;
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog.ApiAccessLogPageReqVO;
import cn.iocoder.yudao.module.infra.dal.dataobject.logger.ApiAccessLogDO;
import cn.iocoder.yudao.module.infra.dal.mysql.logger.ApiAccessLogMapper;

View File

@@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.infra.service.logger;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.infra.api.logger.dto.ApiErrorLogCreateReqDTO;
import cn.iocoder.yudao.framework.common.biz.infra.logger.dto.ApiErrorLogCreateReqDTO;
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog.ApiErrorLogPageReqVO;
import cn.iocoder.yudao.module.infra.dal.dataobject.logger.ApiErrorLogDO;

View File

@@ -5,7 +5,7 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
import cn.iocoder.yudao.module.infra.api.logger.dto.ApiErrorLogCreateReqDTO;
import cn.iocoder.yudao.framework.common.biz.infra.logger.dto.ApiErrorLogCreateReqDTO;
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog.ApiErrorLogPageReqVO;
import cn.iocoder.yudao.module.infra.dal.dataobject.logger.ApiErrorLogDO;
import cn.iocoder.yudao.module.infra.dal.mysql.logger.ApiErrorLogMapper;

View File

@@ -8,7 +8,7 @@ import { ImageUpload, FileUpload } from "#/components/upload";
import { message, Tabs, Form, Input, Textarea, Select, RadioGroup, Radio, CheckboxGroup, Checkbox, DatePicker, TreeSelect } from 'ant-design-vue';
import { DICT_TYPE, getDictOptions } from '#/utils';
#if($table.templateType == 2)## 树表需要导入这些
import { get${simpleClassName}List } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
import { get${simpleClassName}List } from '#/api/${table.moduleName}/${table.businessName}';
import { handleTree } from '@vben/utils'
#end
## 特殊:主子表专属逻辑
@@ -22,7 +22,7 @@ import { handleTree } from '@vben/utils'
import { computed, ref } from 'vue';
import { $t } from '#/locales';
import { get${simpleClassName}, create${simpleClassName}, update${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
import { get${simpleClassName}, create${simpleClassName}, update${simpleClassName} } from '#/api/${table.moduleName}/${table.businessName}';
const emit = defineEmits(['success']);

View File

@@ -1,13 +1,15 @@
import type { VbenFormSchema } from '#/adapter/form';
import type { OnActionClickFn, VxeTableGridOptions } from '#/adapter/vxe-table';
import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${table.businessName}';
import { z } from '#/adapter/form';
import { getRangePickerDefaultProps } from '#/utils/date';
import { DICT_TYPE, getDictOptions } from '#/utils/dict';
#if(${table.templateType} == 2)## 树表需要导入这些
import { get${simpleClassName}List } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
import { get${simpleClassName}List } from '#/api/${table.moduleName}/${table.businessName}';
import { handleTree } from '@vben/utils';
#end
import { DICT_TYPE, getDictOptions, getRangePickerDefaultProps } from '#/utils';
import { useAccess } from '@vben/access';
const { hasAccessByCodes } = useAccess();

View File

@@ -1,5 +1,5 @@
<script lang="ts" setup>
import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${table.businessName}';
import { useVbenModal } from '@vben/common-ui';
import { message, Tabs, Checkbox, Input, Textarea, Select,RadioGroup,CheckboxGroup, DatePicker } from 'ant-design-vue';
@@ -15,7 +15,7 @@ import { message, Tabs, Checkbox, Input, Textarea, Select,RadioGroup,CheckboxGro
import { computed, ref } from 'vue';
import { $t } from '#/locales';
import { useVbenForm } from '#/adapter/form';
import { get${simpleClassName}, create${simpleClassName}, update${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
import { get${simpleClassName}, create${simpleClassName}, update${simpleClassName} } from '#/api/${table.moduleName}/${table.businessName}';
import { useFormSchema } from '../data';

View File

@@ -1,6 +1,6 @@
<script lang="ts" setup>
import type { OnActionClickParams, VxeTableGridOptions } from '#/adapter/vxe-table';
import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${table.businessName}';
import { Page, useVbenModal } from '@vben/common-ui';
import { Button, message,Tabs } from 'ant-design-vue';
@@ -20,9 +20,9 @@ import { ref, h } from 'vue';
import { $t } from '#/locales';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
#if (${table.templateType} == 2)## 树表接口
import { get${simpleClassName}List, delete${simpleClassName}, export${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
import { get${simpleClassName}List, delete${simpleClassName}, export${simpleClassName} } from '#/api/${table.moduleName}/${table.businessName}';
#else## 标准表接口
import { get${simpleClassName}Page, delete${simpleClassName}, export${simpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
import { get${simpleClassName}Page, delete${simpleClassName}, export${simpleClassName} } from '#/api/${table.moduleName}/${table.businessName}';
#end
import { downloadFileFromBlobPart } from '@vben/utils';

View File

@@ -3,7 +3,7 @@
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
<script lang="ts" setup>
import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${table.businessName}';
import { useVbenModal } from '@vben/common-ui';
import { message } from 'ant-design-vue';
@@ -11,7 +11,7 @@
import { computed, ref } from 'vue';
import { $t } from '#/locales';
import { useVbenForm } from '#/adapter/form';
import { get${subSimpleClassName}, create${subSimpleClassName}, update${subSimpleClassName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
import { get${subSimpleClassName}, create${subSimpleClassName}, update${subSimpleClassName} } from '#/api/${table.moduleName}/${table.businessName}';
import { use${subSimpleClassName}FormSchema } from '../data';

View File

@@ -5,7 +5,7 @@
#set ($subClassNameVar = $subClassNameVars.get($subIndex))
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
<script lang="ts" setup>
import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${table.businessName}';
import { computed, ref, h, onMounted,watch,nextTick } from 'vue';
import { $t } from '#/locales';
@@ -17,11 +17,11 @@ import { ImageUpload, FileUpload } from "#/components/upload";
import type { OnActionClickParams } from '#/adapter/vxe-table';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { use${subSimpleClassName}GridEditColumns } from '../data';
import { get${subSimpleClassName}ListBy${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
import { get${subSimpleClassName}ListBy${SubJoinColumnName} } from '#/api/${table.moduleName}/${table.businessName}';
#else
import { useVbenForm } from '#/adapter/form';
import { use${subSimpleClassName}FormSchema } from '../data';
import { get${subSimpleClassName}By${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
import { get${subSimpleClassName}By${SubJoinColumnName} } from '#/api/${table.moduleName}/${table.businessName}';
#end
const props = defineProps<{

View File

@@ -7,7 +7,7 @@
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
<script lang="ts" setup>
import type { OnActionClickParams, VxeTableGridOptions } from '#/adapter/vxe-table';
import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${table.businessName}';
#if ($table.templateType == 11) ## erp
import ${subSimpleClassName}Form from './${subSimpleClassName_strikeCase}-form.vue'
@@ -21,13 +21,13 @@
#if ($table.templateType == 11) ## erp
import { delete${subSimpleClassName}, get${subSimpleClassName}Page } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
import { delete${subSimpleClassName}, get${subSimpleClassName}Page } from '#/api/${table.moduleName}/${table.businessName}';
import { use${subSimpleClassName}GridFormSchema, use${subSimpleClassName}GridColumns } from '../data';
#else
#if ($subTable.subJoinMany) ## 一对多
import { get${subSimpleClassName}ListBy${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
import { get${subSimpleClassName}ListBy${SubJoinColumnName} } from '#/api/${table.moduleName}/${table.businessName}';
#else
import { get${subSimpleClassName}By${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
import { get${subSimpleClassName}By${SubJoinColumnName} } from '#/api/${table.moduleName}/${table.businessName}';
#end
import { use${subSimpleClassName}GridColumns } from '../data';
#end

View File

@@ -1,17 +1,17 @@
package cn.iocoder.yudao.module.infra.service.logger;
import cn.iocoder.yudao.framework.common.biz.infra.logger.dto.ApiAccessLogCreateReqDTO;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
import cn.iocoder.yudao.module.infra.api.logger.dto.ApiAccessLogCreateReqDTO;
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog.ApiAccessLogPageReqVO;
import cn.iocoder.yudao.module.infra.dal.dataobject.logger.ApiAccessLogDO;
import cn.iocoder.yudao.module.infra.dal.mysql.logger.ApiAccessLogMapper;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.Import;
import javax.annotation.Resource;
import java.time.Duration;
import java.util.List;

View File

@@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.infra.service.logger;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
import cn.iocoder.yudao.module.infra.api.logger.dto.ApiErrorLogCreateReqDTO;
import cn.iocoder.yudao.framework.common.biz.infra.logger.dto.ApiErrorLogCreateReqDTO;
import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog.ApiErrorLogPageReqVO;
import cn.iocoder.yudao.module.infra.dal.dataobject.logger.ApiErrorLogDO;
import cn.iocoder.yudao.module.infra.dal.mysql.logger.ApiErrorLogMapper;