Przeglądaj źródła

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	server/yusp-tagging-core/pom.xml
#	server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/controller/AitagTagLogController.java
2507040827 4 dni temu
rodzic
commit
a06ed92ddb
24 zmienionych plików z 814 dodań i 139 usunięć
  1. 15 0
      server/yusp-tagging-core/pom.xml
  2. 21 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/annotation/ApiOperationType.java
  3. 143 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/aop/ApiLogAspect.java
  4. 12 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/config/AopConfig.java
  5. 101 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/controller/AitagApiLogController.java
  6. 9 6
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/controller/AitagAppController.java
  7. 15 8
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/controller/AitagTagCategoryController.java
  8. 24 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagApiLogQueryDto.java
  9. 1 1
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagAppCreateDto.java
  10. 1 1
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagTagCategoryCreateDto.java
  11. 1 1
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagTagCategoryUpdateDto.java
  12. 77 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/entity/AitagApiLog.java
  13. 0 99
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/entity/AitagTagInfo.java
  14. 27 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/vo/AitagApiLogListVo.java
  15. 1 1
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/vo/AitagTagCategoryVo.java
  16. 54 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/mapper/AitagApiLogMapper.java
  17. 43 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/AitagApiLogService.java
  18. 2 2
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/AitagAppService.java
  19. 6 6
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/AitagTagCategoryService.java
  20. 159 0
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/impl/AitagApiLogServiceImpl.java
  21. 2 2
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/impl/AitagAppServiceImpl.java
  22. 23 11
      server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/impl/AitagTagCategoryServiceImpl.java
  23. 76 0
      server/yusp-tagging-core/src/main/resources/mapper/AitagApiLogMapper.xml
  24. 1 1
      server/yusp-tagging-core/src/main/resources/mapper/AitagTagCategoryMapper.xml

+ 15 - 0
server/yusp-tagging-core/pom.xml

@@ -171,6 +171,21 @@
             <scope>compile</scope>
         </dependency>
 
+        <!-- AOP 模块  2.26新增 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-aop</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.aspectj</groupId>
+            <artifactId>aspectjweaver</artifactId>
+            <version>1.9.7</version>
+        </dependency>
+        <dependency>
+            <groupId>org.aspectj</groupId>
+            <artifactId>aspectjrt</artifactId>
+            <version>1.9.7</version>
+        </dependency>
     </dependencies>
 
     <dependencyManagement>

+ 21 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/annotation/ApiOperationType.java

@@ -0,0 +1,21 @@
+package cn.com.yusys.yusp.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * API操作类型注解
+ * 用于标识接口的操作类型
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ApiOperationType {
+    
+    /**
+     * 操作类型名称
+     * @return 操作类型
+     */
+    String value();
+}

+ 143 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/aop/ApiLogAspect.java

@@ -0,0 +1,143 @@
+package cn.com.yusys.yusp.aop;
+
+import cn.com.yusys.yusp.annotation.ApiOperationType;
+import cn.com.yusys.yusp.domain.entity.AitagApiLog;
+import cn.com.yusys.yusp.service.AitagApiLogService;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.lang.reflect.Method;
+import java.util.Date;
+
+@Aspect
+@Component
+public class ApiLogAspect {
+
+    @Autowired
+    private AitagApiLogService apiLogService;
+
+    @Around("@annotation(cn.com.yusys.yusp.annotation.ApiOperationType)")
+    public Object logApiCall(ProceedingJoinPoint joinPoint) throws Throwable {
+        long startTime = System.currentTimeMillis();
+
+        AitagApiLog apiLog = new AitagApiLog();
+        apiLog.setId(apiLogService.generateLogId());
+        apiLog.setCreateDate(new Date());
+
+        // 获取操作类型
+        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+        Method method = signature.getMethod();
+        ApiOperationType annotation = method.getAnnotation(ApiOperationType.class);
+        if (annotation != null) {
+            apiLog.setOperationType(annotation.value());
+        }
+
+        // 记录输入参数(隐藏敏感数据)
+        Object[] args = joinPoint.getArgs();
+        if (args != null && args.length > 0) {
+            try {
+                String inputJson = JSON.toJSONString(args);
+                // 隐藏敏感数据
+                String hiddenInput = hideSensitiveData(inputJson);
+                apiLog.setInputData(hiddenInput);
+            } catch (Exception e) {
+                apiLog.setInputData("参数序列化失败");
+            }
+        }
+
+        // 执行目标方法
+        Object result;
+        try {
+            result = joinPoint.proceed();
+
+            // 记录成功执行
+            long endTime = System.currentTimeMillis();
+            apiLog.setConsumingTime(String.valueOf(endTime - startTime));
+
+            // 记录输出结果(隐藏敏感数据)
+            if (result != null) {
+                try {
+                    String outputJson = JSON.toJSONString(result);
+                    // 隐藏敏感数据
+                    String hiddenOutput = hideSensitiveData(outputJson);
+                    apiLog.setOutputData(hiddenOutput);
+                } catch (Exception e) {
+                    apiLog.setOutputData("返回结果序列化失败");
+                }
+            }
+
+            // 保存日志
+            apiLogService.recordApiLog(apiLog);
+
+            return result;
+        } catch (Exception e) {
+            // 记录异常情况
+            long endTime = System.currentTimeMillis();
+            apiLog.setConsumingTime(String.valueOf(endTime - startTime));
+
+            // 记录异常信息
+            String errorMsg = e.getClass().getSimpleName();
+            if (e.getMessage() != null) {
+                errorMsg += ": " + e.getMessage();
+            }
+            // 限制错误信息长度
+            if (errorMsg.length() > 500) {
+                errorMsg = errorMsg.substring(0, 500) + "...";
+            }
+            apiLog.setOutputData("调用失败 - " + errorMsg);
+
+            // 保存日志
+            apiLogService.recordApiLog(apiLog);
+
+            // 重新抛出异常
+            throw e;
+        }
+    }
+
+    /**
+     * 隐藏敏感数据
+     * @param jsonStr 原始JSON字符串
+     * @return 隐藏敏感数据后的JSON字符串
+     */
+    private String hideSensitiveData(String jsonStr) {
+        try {
+            // 尝试解析为JSONObject
+            Object parsedObj = JSON.parse(jsonStr);
+            if (parsedObj instanceof JSONObject) {
+                JSONObject jsonObj = (JSONObject) parsedObj;
+                hideDataInObject(jsonObj);
+                return jsonObj.toJSONString();
+            } else {
+                // 如果不是JSONObject,可能是数组或其他类型
+                return jsonStr.replaceAll("\"data\"\\s*:\\s*\"[^\"]*\"", "\"data\":\"已隐藏\"")
+                        .replaceAll("\"data\"\\s*:\\s*\\{[^}]*\\}", "\"data\":\"已隐藏\"");
+            }
+        } catch (Exception e) {
+            // 解析失败时使用正则表达式简单替换
+            return jsonStr.replaceAll("\"data\"\\s*:\\s*\"[^\"]*\"", "\"data\":\"已隐藏\"")
+                    .replaceAll("\"data\"\\s*:\\s*\\{[^}]*\\}", "\"data\":\"已隐藏\"");
+        }
+    }
+
+    /**
+     * 递归隐藏JSONObject中的敏感数据
+     */
+    private void hideDataInObject(JSONObject obj) {
+        for (String key : obj.keySet()) {
+            if ("data".equalsIgnoreCase(key)) {
+                obj.put(key, "已隐藏");
+            } else {
+                Object value = obj.get(key);
+                if (value instanceof JSONObject) {
+                    hideDataInObject((JSONObject) value);
+                }
+            }
+        }
+    }
+}

+ 12 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/config/AopConfig.java

@@ -0,0 +1,12 @@
+package cn.com.yusys.yusp.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
+
+@Configuration
+@EnableAspectJAutoProxy(proxyTargetClass = true)
+public class AopConfig {
+    // AOP配置类,启用AspectJ自动代理
+    // proxyTargetClass = true 强制使用CGLIB代理,避免某些情况下JDK动态代理的问题
+
+}

+ 101 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/controller/AitagApiLogController.java

@@ -0,0 +1,101 @@
+package cn.com.yusys.yusp.controller;
+
+import cn.com.yusys.yusp.domain.dto.AitagApiLogQueryDto;
+import cn.com.yusys.yusp.domain.entity.AitagApiLog;
+import cn.com.yusys.yusp.domain.vo.AitagApiLogListVo;
+import cn.com.yusys.yusp.model.Result;
+import cn.com.yusys.yusp.service.AitagApiLogService;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+
+@RestController
+@RequestMapping("/api/aitag-apilog")
+public class AitagApiLogController {
+
+    @Autowired
+    private AitagApiLogService apiLogService;
+
+
+    @GetMapping("/list")
+    public Result<List<AitagApiLogListVo>> listApiLogs(
+            @RequestParam(required = false) String startTime,
+            @RequestParam(required = false) String endTime,
+            @RequestParam(defaultValue = "1") Integer page,
+            @RequestParam(defaultValue = "10") Integer pageSize) {
+        try {
+            // 构建查询条件
+            AitagApiLogQueryDto queryDTO = new AitagApiLogQueryDto();
+            queryDTO.setPage(page);
+            queryDTO.setPageSize(pageSize);
+
+            // 处理时间参数 - 只处理日期粒度
+            if (startTime != null && !startTime.isEmpty()) {
+                queryDTO.setStartTime(parseDateOnly(startTime));
+            }
+
+            if (endTime != null && !endTime.isEmpty()) {
+                queryDTO.setEndTime(parseDateOnly(endTime));
+            }
+
+            Page<AitagApiLogListVo> pageResult = apiLogService.listApiLogs(queryDTO);
+            return Result.pageSuccess(pageResult.getRecords(), pageResult.getTotal());
+        } catch (Exception e) {
+            return Result.error("500", "查询日志列表失败:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 解析日期字符串(只保留日期部分,设置时间为当天00:00:00)
+     */
+    private Date parseDateOnly(String dateStr) {
+        try {
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+            Date date = sdf.parse(dateStr);
+            // 设置时间为当天00:00:00
+            Calendar calendar = Calendar.getInstance();
+            calendar.setTime(date);
+            calendar.set(Calendar.HOUR_OF_DAY, 0);
+            calendar.set(Calendar.MINUTE, 0);
+            calendar.set(Calendar.SECOND, 0);
+            calendar.set(Calendar.MILLISECOND, 0);
+            return calendar.getTime();
+        } catch (ParseException e) {
+            throw new RuntimeException("日期格式错误,请使用 yyyy-MM-dd 格式");
+        }
+    }
+
+    @GetMapping("/refresh")
+    public Result<List<AitagApiLogListVo>> refreshApiLogs(
+            @RequestParam(defaultValue = "1") Integer page,
+            @RequestParam(defaultValue = "10") Integer pageSize) {
+        try {
+            Page<AitagApiLogListVo> pageResult = apiLogService.refreshApiLogs(page, pageSize);
+            // 直接返回Page对象
+            return Result.pageSuccess(pageResult.getRecords(), pageResult.getTotal());
+        } catch (Exception e) {
+            return Result.error("500", "刷新日志列表失败:" + e.getMessage());
+        }
+    }
+
+
+    @GetMapping("/query/{id}")
+    public Result<AitagApiLog> getApiLogDetail(@PathVariable String id) {
+        try {
+            AitagApiLog logDetail = apiLogService.getApiLogDetail(id);
+            if (logDetail == null) {
+                return Result.error("404", "日志记录不存在");
+            }
+            return Result.success(logDetail);
+        } catch (Exception e) {
+            return Result.error("500", "查询日志详情失败:" + e.getMessage());
+        }
+    }
+}

+ 9 - 6
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/controller/AitagAppController.java

@@ -1,13 +1,15 @@
 package cn.com.yusys.yusp.controller;
 
 import cn.com.yusys.yusp.model.Result;
-import cn.com.yusys.yusp.domain.dto.AitagAppCreateDTO;
+import cn.com.yusys.yusp.domain.dto.AitagAppCreateDto;
 import cn.com.yusys.yusp.domain.entity.AitagApp;
 import cn.com.yusys.yusp.service.AitagAppService;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
+import cn.com.yusys.yusp.annotation.ApiOperationType;
+
 
 import java.util.List;
 
@@ -18,6 +20,7 @@ public class AitagAppController {
     @Autowired
     private AitagAppService aiTagAppService;
 
+    @ApiOperationType("应用列表一览")
     @GetMapping("/list")
     public Result<List<AitagApp>> listApps(
             @RequestParam(defaultValue = "1") int page,
@@ -34,9 +37,9 @@ public class AitagAppController {
     }
 
 
-
+    @ApiOperationType("新增应用")
     @PostMapping("/add")
-    public Result<AitagApp> addApp(@Validated @RequestBody AitagAppCreateDTO dto) {
+    public Result<AitagApp> addApp(@Validated @RequestBody AitagAppCreateDto dto) {
         try {
             AitagApp app = aiTagAppService.addApp(dto);
             return Result.success(app); // 成功时返回封装后的数据
@@ -45,7 +48,7 @@ public class AitagAppController {
         }
     }
 
-
+    @ApiOperationType("查询应用")
     @GetMapping("/query")
     public Result<List<AitagApp>> queryByName(
             @RequestParam String appName,
@@ -61,7 +64,7 @@ public class AitagAppController {
 
 
 
-
+    @ApiOperationType("重置密钥")
     @PostMapping("/reset-secret")
     public Result<String> resetSecret(@RequestParam String id) {
         try {
@@ -72,7 +75,7 @@ public class AitagAppController {
         }
     }
 
-
+    @ApiOperationType("禁用应用")
     @PostMapping("/disable")
     public Result<Void> disableApp(@RequestParam String id) {
         try {

+ 15 - 8
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/controller/AitagTagCategoryController.java

@@ -1,15 +1,16 @@
 package cn.com.yusys.yusp.controller;
 
-import cn.com.yusys.yusp.domain.dto.AitagTagCategoryCreateDTO;
-import cn.com.yusys.yusp.domain.dto.AitagTagCategoryUpdateDTO;
+import cn.com.yusys.yusp.domain.dto.AitagTagCategoryCreateDto;
+import cn.com.yusys.yusp.domain.dto.AitagTagCategoryUpdateDto;
 import cn.com.yusys.yusp.domain.entity.AitagTagCategory;
-import cn.com.yusys.yusp.domain.vo.AitagTagCategoryVO;
+import cn.com.yusys.yusp.domain.vo.AitagTagCategoryVo;
 import cn.com.yusys.yusp.model.Result;
 import cn.com.yusys.yusp.service.AitagTagCategoryService;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
+import cn.com.yusys.yusp.annotation.ApiOperationType;
 
 import java.util.List;
 
@@ -20,21 +21,22 @@ public class AitagTagCategoryController {
     @Autowired
     private AitagTagCategoryService aiTagCategoryService;
 
+    @ApiOperationType("标签体系列表")
     @GetMapping("/list")
-    public Result<List<AitagTagCategoryVO>> listCategories(
+    public Result<List<AitagTagCategoryVo>> listCategories(
             @RequestParam(defaultValue = "1") int page,
             @RequestParam(defaultValue = "5") int size) {
         try {
-            Page<AitagTagCategoryVO> pageResult = aiTagCategoryService.listCategories(page, size);
+            Page<AitagTagCategoryVo> pageResult = aiTagCategoryService.listCategories(page, size);
             return Result.pageSuccess(pageResult.getRecords(), pageResult.getTotal());
         } catch (Exception e) {
             return Result.error("500", "分页查询失败:" + e.getMessage());
         }
     }
 
-
+    @ApiOperationType("新增标签体系")
     @PostMapping("/create")
-    public Result<AitagTagCategory> createCategory(@Validated @RequestBody AitagTagCategoryCreateDTO dto) {
+    public Result<AitagTagCategory> createCategory(@Validated @RequestBody AitagTagCategoryCreateDto dto) {
         try {
             AitagTagCategory category = aiTagCategoryService.createCategory(dto);
             return Result.success(category);
@@ -43,8 +45,9 @@ public class AitagTagCategoryController {
         }
     }
 
+    @ApiOperationType("编辑标签体系")
     @PostMapping("/update")
-    public Result<AitagTagCategory> updateCategory(@Validated @RequestBody AitagTagCategoryUpdateDTO dto) {
+    public Result<AitagTagCategory> updateCategory(@Validated @RequestBody AitagTagCategoryUpdateDto dto) {
         try {
             AitagTagCategory category = aiTagCategoryService.updateCategory(dto);
             return Result.success(category);
@@ -53,6 +56,7 @@ public class AitagTagCategoryController {
         }
     }
 
+    @ApiOperationType("查询标签体系")
     @GetMapping("/query")
     public Result<List<AitagTagCategory>> searchByCategoryNm(@RequestParam String categoryNm) {
         try {
@@ -63,6 +67,7 @@ public class AitagTagCategoryController {
         }
     }
 
+    @ApiOperationType("启用标签体系")
     @PostMapping("/enable")
     public Result<Void> enableCategory(@RequestParam String id) {
         try {
@@ -73,6 +78,7 @@ public class AitagTagCategoryController {
         }
     }
 
+    @ApiOperationType("停用标签体系")
     @PostMapping("/disable")
     public Result<Void> disableCategory(@RequestParam String id) {
         try {
@@ -83,6 +89,7 @@ public class AitagTagCategoryController {
         }
     }
 
+    @ApiOperationType("删除标签体系")
     @PostMapping("/delete")
     public Result<Void> deleteCategory(@RequestParam String id) {
         try {

+ 24 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagApiLogQueryDto.java

@@ -0,0 +1,24 @@
+package cn.com.yusys.yusp.domain.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+@ApiModel("API日志查询条件DTO")
+public class AitagApiLogQueryDto {
+
+    @ApiModelProperty(value = "起始时间")
+    private Date startTime;
+
+    @ApiModelProperty(value = "结束时间")
+    private Date endTime;
+
+    @ApiModelProperty(value = "页码", example = "1")
+    private Integer page = 1;
+
+    @ApiModelProperty(value = "每页大小", example = "10")
+    private Integer pageSize = 10;
+}

+ 1 - 1
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagAppCreateDTO.java → server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagAppCreateDto.java

@@ -8,7 +8,7 @@ import javax.validation.constraints.NotBlank;
 
 @Data
 @ApiModel("新增应用请求DTO")
-public class AitagAppCreateDTO {
+public class AitagAppCreateDto {
 
     @NotBlank(message = "应用名称不能为空")
     @ApiModelProperty(value = "应用名称", required = true)

+ 1 - 1
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagTagCategoryCreateDTO.java → server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagTagCategoryCreateDto.java

@@ -8,7 +8,7 @@ import javax.validation.constraints.NotBlank;
 
 @Data
 @ApiModel("新建标签体系请求DTO")
-public class AitagTagCategoryCreateDTO {
+public class AitagTagCategoryCreateDto {
 
     @NotBlank(message = "标签体系名称不能为空")
     @ApiModelProperty(value = "标签体系名称", required = true)

+ 1 - 1
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagTagCategoryUpdateDTO.java → server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/dto/AitagTagCategoryUpdateDto.java

@@ -8,7 +8,7 @@ import javax.validation.constraints.NotBlank;
 
 @Data
 @ApiModel("编辑标签体系请求DTO")
-public class AitagTagCategoryUpdateDTO {
+public class AitagTagCategoryUpdateDto {
 
     @NotBlank(message = "ID不能为空")
     @ApiModelProperty(value = "标签体系ID", required = true)

+ 77 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/entity/AitagApiLog.java

@@ -0,0 +1,77 @@
+package cn.com.yusys.yusp.domain.entity;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Size;
+import javax.validation.constraints.NotNull;
+
+import java.io.Serializable;
+
+import java.util.Date;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.hibernate.validator.constraints.Length;
+
+/**
+* 操作日志
+* @TableName aitag_api_log
+*/
+@Data
+public class AitagApiLog implements Serializable {
+
+    /**
+    * 
+    */
+    @NotBlank(message="[]不能为空")
+    @Size(max= 100,message="编码长度不能超过100")
+    @ApiModelProperty("")
+    @Length(max= 100,message="编码长度不能超过100")
+    private String id;
+    /**
+    * 操作类型
+    */
+    @Size(max= 100,message="编码长度不能超过100")
+    @ApiModelProperty("操作类型")
+    @Length(max= 100,message="编码长度不能超过100")
+    private String operationType;
+    /**
+    * 输入数据
+    */
+    @Size(max= 100,message="编码长度不能超过100")
+    @ApiModelProperty("输入数据")
+    @Length(max= 100,message="编码长度不能超过100")
+    private String inputData;
+    /**
+     * 输出数据
+     */
+    @Size(max= 100,message="编码长度不能超过255")
+    @ApiModelProperty("输出数据")
+    @Length(max= 100,message="编码长度不能超过255")
+    private String outputData;
+    /**
+    * 创建日期
+    */
+    @ApiModelProperty("创建日期")
+    private Date createDate;
+    /**
+    * 操作人ID
+    */
+    @Size(max= 100,message="编码长度不能超过100")
+    @ApiModelProperty("操作人ID")
+    @Length(max= 100,message="编码长度不能超过100")
+    private String userId;
+    /**
+    * 操作人昵称
+    */
+    @Size(max= 100,message="编码长度不能超过100")
+    @ApiModelProperty("操作人昵称")
+    @Length(max= 100,message="编码长度不能超过100")
+    private String userName;
+    /**
+    * 耗时
+    */
+    @Size(max= -1,message="编码长度不能超过-1")
+    @ApiModelProperty("耗时")
+    @Length(max= -1,message="编码长度不能超过-1")
+    private String consumingTime;
+
+}

+ 0 - 99
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/entity/AitagTagInfo.java

@@ -1,99 +0,0 @@
-package cn.com.yusys.yusp.domain.entity;
-
-import javax.validation.constraints.NotBlank;
-import javax.validation.constraints.Size;
-import javax.validation.constraints.NotNull;
-
-import java.io.Serializable;
-
-import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
-import org.hibernate.validator.constraints.Length;
-
-/**
-* 
-* @TableName aitag_tag_info
-*/
-@Data
-public class AitagTagInfo implements Serializable {
-
-    /**
-    * 
-    */
-    @NotBlank(message="[]不能为空")
-    @Size(max= 100,message="编码长度不能超过100")
-    @ApiModelProperty("")
-    @Length(max= 100,message="编码长度不能超过100")
-    private String id;
-    /**
-    * 所属大类
-    */
-    @Size(max= 100,message="编码长度不能超过100")
-    @ApiModelProperty("所属大类")
-    @Length(max= 100,message="编码长度不能超过100")
-    private String categoryId;
-    /**
-    * 标签名称
-    */
-    @Size(max= 100,message="编码长度不能超过100")
-    @ApiModelProperty("标签名称")
-    @Length(max= 100,message="编码长度不能超过100")
-    private String tagNm;
-    /**
-    * 标签代码
-    */
-    @Size(max= 100,message="编码长度不能超过100")
-    @ApiModelProperty("标签代码")
-    @Length(max= 100,message="编码长度不能超过100")
-    private String tagCode;
-    /**
-    * 标签备注
-    */
-    @Size(max= 100,message="编码长度不能超过100")
-    @ApiModelProperty("标签备注")
-    @Length(max= 100,message="编码长度不能超过100")
-    private String tagRemark;
-    /**
-    * 父级ID
-    */
-    @Size(max= 100,message="编码长度不能超过100")
-    @ApiModelProperty("父级ID")
-    @Length(max= 100,message="编码长度不能超过100")
-    private String parentCode;
-    /**
-    * 标签规则
-    */
-    @Size(max= 100,message="编码长度不能超过100")
-    @ApiModelProperty("标签规则")
-    @Length(max= 100,message="编码长度不能超过100")
-    private String reg;
-    /**
-    * 标签等级
-    */
-    @ApiModelProperty("标签等级")
-    private Integer level;
-    /**
-    * tag1/tag2/tag3/...
-    */
-    @Size(max= 100,message="编码长度不能超过100")
-    @ApiModelProperty("tag1/tag2/tag3/...")
-    @Length(max= 100,message="编码长度不能超过100")
-    private String tagPath;
-    /**
-    * 0未删除;1删除
-    */
-    @ApiModelProperty("0未删除;1删除")
-    private Integer isDelete;
-    /**
-    * 0 正常;1 停用
-    */
-    @ApiModelProperty("0 正常;1 停用")
-    private Integer state;
-    /**
-    * 标签提示词
-    */
-    @Size(max= 1000,message="编码长度不能超过1000")
-    @ApiModelProperty("标签提示词")
-    @Length(max= 1000,message="编码长度不能超过1,000")
-    private String tagPrompt;
-}

+ 27 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/vo/AitagApiLogListVo.java

@@ -0,0 +1,27 @@
+package cn.com.yusys.yusp.domain.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+@ApiModel("API日志列表视图对象")
+public class AitagApiLogListVo {
+
+    @ApiModelProperty("日志ID")
+    private String id;
+
+    @ApiModelProperty("用户名称")
+    private String userName;
+
+    @ApiModelProperty("用户ID")
+    private String userId;
+
+    @ApiModelProperty("操作类型")
+    private String operationType;
+
+    @ApiModelProperty("操作时间")
+    private Date createDate;
+}

+ 1 - 1
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/vo/AitagTagCategoryVO.java → server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/domain/vo/AitagTagCategoryVo.java

@@ -6,7 +6,7 @@ import lombok.Data;
 
 @Data
 @ApiModel("标签体系视图对象")
-public class AitagTagCategoryVO {
+public class AitagTagCategoryVo {
     @ApiModelProperty("标签体系ID")
     private String id;
 

+ 54 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/mapper/AitagApiLogMapper.java

@@ -0,0 +1,54 @@
+package cn.com.yusys.yusp.mapper;
+
+import cn.com.yusys.yusp.domain.entity.AitagApiLog;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.Date;
+import java.util.List;
+
+@Mapper
+public interface AitagApiLogMapper {
+
+    /**
+     * 插入API调用日志
+     * @param apiLog 日志实体
+     * @return 影响行数
+     */
+    int insertApiLog(AitagApiLog apiLog);
+
+    /**
+     * 根据日期获取最大的日志ID
+     * @param dateStr 日期字符串(yyyyMMdd格式)
+     * @return 最大的日志ID
+     */
+    String getMaxIdByDate(@Param("dateStr") String dateStr);
+
+    /**
+     * 统计符合条件的日志数量
+     * @param startTime 起始时间
+     * @param endTime 结束时间
+     * @return 数量
+     */
+    long countApiLogs(@Param("startTime") Date startTime, @Param("endTime") Date endTime);
+
+    /**
+     * 分页查询日志列表
+     * @param startTime 起始时间
+     * @param endTime 结束时间
+     * @param offset 偏移量
+     * @param limit 限制数量
+     * @return 日志列表
+     */
+    List<AitagApiLog> selectApiLogs(@Param("startTime") Date startTime,
+                                    @Param("endTime") Date endTime,
+                                    @Param("offset") int offset,
+                                    @Param("limit") int limit);
+
+    /**
+     * 根据ID查询日志详情
+     * @param id 日志ID
+     * @return 日志详情
+     */
+    AitagApiLog selectApiLogById(@Param("id") String id);
+}

+ 43 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/AitagApiLogService.java

@@ -0,0 +1,43 @@
+package cn.com.yusys.yusp.service;
+
+import cn.com.yusys.yusp.domain.dto.AitagApiLogQueryDto;
+import cn.com.yusys.yusp.domain.entity.AitagApiLog;
+import cn.com.yusys.yusp.domain.vo.AitagApiLogListVo;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+public interface AitagApiLogService {
+
+    /**
+     * 记录API调用日志
+     * @param apiLog 日志实体
+     */
+    void recordApiLog(AitagApiLog apiLog);
+
+    /**
+     * 生成日志ID
+     * @return 日志ID
+     */
+    String generateLogId();
+
+    /**
+     * 分页查询日志列表
+     * @param queryDTO 查询条件
+     * @return 分页结果
+     */
+    Page<AitagApiLogListVo> listApiLogs(AitagApiLogQueryDto queryDTO);
+
+    /**
+     * 刷新日志列表(查询所有数据)
+     * @param page 页码
+     * @param pageSize 每页大小
+     * @return 分页结果
+     */
+    Page<AitagApiLogListVo> refreshApiLogs(Integer page, Integer pageSize);
+
+    /**
+     * 根据ID查询日志详情
+     * @param id 日志ID
+     * @return 日志详情
+     */
+    AitagApiLog getApiLogDetail(String id);
+}

+ 2 - 2
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/AitagAppService.java

@@ -1,7 +1,7 @@
 package cn.com.yusys.yusp.service;
 
 import cn.com.yusys.yusp.domain.entity.AitagApp;
-import cn.com.yusys.yusp.domain.dto.AitagAppCreateDTO;
+import cn.com.yusys.yusp.domain.dto.AitagAppCreateDto;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 
 import java.util.List;
@@ -10,7 +10,7 @@ public interface AitagAppService {
     Page<AitagApp> listApps(int page, int size);
     Page<AitagApp> queryByAppNameLikeWithPagination(String appName, int page, int pageSize);
 
-    AitagApp addApp(AitagAppCreateDTO dto);
+    AitagApp addApp(AitagAppCreateDto dto);
     List<AitagApp> queryByName(String appName);
     List<AitagApp> queryByAppNameLike(String appName);
     String resetSecret(String id);

+ 6 - 6
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/AitagTagCategoryService.java

@@ -1,17 +1,17 @@
 package cn.com.yusys.yusp.service;
 
-import cn.com.yusys.yusp.domain.dto.AitagTagCategoryCreateDTO;
-import cn.com.yusys.yusp.domain.dto.AitagTagCategoryUpdateDTO;
+import cn.com.yusys.yusp.domain.dto.AitagTagCategoryCreateDto;
+import cn.com.yusys.yusp.domain.dto.AitagTagCategoryUpdateDto;
 import cn.com.yusys.yusp.domain.entity.AitagTagCategory;
-import cn.com.yusys.yusp.domain.vo.AitagTagCategoryVO;
+import cn.com.yusys.yusp.domain.vo.AitagTagCategoryVo;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 
 import java.util.List;
 
 public interface AitagTagCategoryService {
-    Page<AitagTagCategoryVO> listCategories(int page, int size); // ← 改为 VO
-    AitagTagCategory createCategory(AitagTagCategoryCreateDTO dto);
-    AitagTagCategory updateCategory(AitagTagCategoryUpdateDTO dto);
+    Page<AitagTagCategoryVo> listCategories(int page, int size); // ← 改为 VO
+    AitagTagCategory createCategory(AitagTagCategoryCreateDto dto);
+    AitagTagCategory updateCategory(AitagTagCategoryUpdateDto dto);
     List<AitagTagCategory> searchByCategoryNm(String categoryNm);
     void enableCategory(String id);
     void disableCategory(String id);

+ 159 - 0
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/impl/AitagApiLogServiceImpl.java

@@ -0,0 +1,159 @@
+package cn.com.yusys.yusp.service.impl;
+
+import cn.com.yusys.yusp.domain.dto.AitagApiLogQueryDto;
+import cn.com.yusys.yusp.domain.entity.AitagApiLog;
+import cn.com.yusys.yusp.domain.vo.AitagApiLogListVo;
+import cn.com.yusys.yusp.mapper.AitagApiLogMapper;
+import cn.com.yusys.yusp.service.AitagApiLogService;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+
+@Service
+public class AitagApiLogServiceImpl implements AitagApiLogService {
+
+    private static final Logger logger = LoggerFactory.getLogger(AitagApiLogServiceImpl.class);
+
+    @Autowired
+    private AitagApiLogMapper apiLogMapper;
+
+    // 日期格式化器
+    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMdd");
+
+    // 缓存当天的最大序列号 key:日期 value:最大序列号
+    private static final Map<String, Long> DATE_SEQUENCE_CACHE = new ConcurrentHashMap<>();
+
+    // 当前缓存的日期
+    private volatile String cachedDate = "";
+
+    @Override
+    public void recordApiLog(AitagApiLog apiLog) {
+        try {
+            apiLogMapper.insertApiLog(apiLog);
+            logger.info("API调用日志记录成功: {} - {}", apiLog.getId(), apiLog.getOperationType());
+        } catch (Exception e) {
+            logger.error("记录API调用日志失败: {}", e.getMessage(), e);
+            // 不抛出异常,避免影响主业务流程
+        }
+    }
+
+    @Override
+    public String generateLogId() {
+        String currentDate = DATE_FORMAT.format(new Date());
+
+        // 检查是否需要刷新缓存(跨天了)
+        if (!currentDate.equals(cachedDate)) {
+            refreshCache(currentDate);
+        }
+
+        // 从缓存获取并递增序列号
+        Long currentSequence = DATE_SEQUENCE_CACHE.get(currentDate);
+        if (currentSequence == null) {
+            // 缓存中没有数据,从数据库查询
+            loadFromDatabase(currentDate);
+            currentSequence = DATE_SEQUENCE_CACHE.get(currentDate);
+        }
+
+        currentSequence++;
+        DATE_SEQUENCE_CACHE.put(currentDate, currentSequence);
+
+        // 重置序列号(超过6位数限制)
+        if (currentSequence > 999999) {
+            currentSequence = 1L;
+            DATE_SEQUENCE_CACHE.put(currentDate, currentSequence);
+        }
+
+        return String.format("API%s%06d", currentDate, currentSequence);
+    }
+
+    @Override
+    public Page<AitagApiLogListVo> listApiLogs(AitagApiLogQueryDto queryDTO) {
+        int page = queryDTO.getPage() != null ? queryDTO.getPage() : 1;
+        int pageSize = queryDTO.getPageSize() != null ? queryDTO.getPageSize() : 10;
+        int offset = (page - 1) * pageSize;
+
+        // 查询总记录数
+        long total = apiLogMapper.countApiLogs(queryDTO.getStartTime(), queryDTO.getEndTime());
+
+        // 查询列表数据
+        List<AitagApiLog> logs = apiLogMapper.selectApiLogs(
+                queryDTO.getStartTime(),
+                queryDTO.getEndTime(),
+                offset,
+                pageSize
+        );
+
+        // 转换为VO
+        List<AitagApiLogListVo> voList = logs.stream().map(log -> {
+            AitagApiLogListVo vo = new AitagApiLogListVo();
+            BeanUtils.copyProperties(log, vo);
+            return vo;
+        }).collect(Collectors.toList());
+
+        Page<AitagApiLogListVo> pageResult = new Page<>(page, pageSize, total);
+        pageResult.setRecords(voList);
+        return pageResult;
+    }
+
+    @Override
+    public Page<AitagApiLogListVo> refreshApiLogs(Integer page, Integer pageSize) {
+        AitagApiLogQueryDto queryDTO = new AitagApiLogQueryDto();
+        queryDTO.setPage(page != null ? page : 1);
+        queryDTO.setPageSize(pageSize != null ? pageSize : 10);
+        return listApiLogs(queryDTO);
+    }
+
+    @Override
+    public AitagApiLog getApiLogDetail(String id) {
+        return apiLogMapper.selectApiLogById(id);
+    }
+
+    /**
+     * 刷新缓存 - 每天0点执行
+     */
+    @Scheduled(cron = "0 0 0 * * ?")
+    public void dailyCacheRefresh() {
+        String newDate = DATE_FORMAT.format(new Date());
+        refreshCache(newDate);
+        logger.info("日志ID缓存已刷新,新日期: {}", newDate);
+    }
+
+    /**
+     * 刷新缓存
+     */
+    private synchronized void refreshCache(String newDate) {
+        cachedDate = newDate;
+        DATE_SEQUENCE_CACHE.clear();
+        loadFromDatabase(newDate);
+    }
+
+    /**
+     * 从数据库加载序列号
+     */
+    private void loadFromDatabase(String dateStr) {
+        String maxId = apiLogMapper.getMaxIdByDate(dateStr);
+        long sequence = 0;
+
+        if (maxId != null && maxId.length() >= 17) {
+            try {
+                String sequenceStr = maxId.substring(11, 17);
+                sequence = Long.parseLong(sequenceStr);
+            } catch (Exception e) {
+                logger.warn("解析数据库最大ID序列号失败: {}", e.getMessage());
+            }
+        }
+
+        DATE_SEQUENCE_CACHE.put(dateStr, sequence);
+    }
+}

+ 2 - 2
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/impl/AitagAppServiceImpl.java

@@ -1,6 +1,6 @@
 package cn.com.yusys.yusp.service.impl;
 
-import cn.com.yusys.yusp.domain.dto.AitagAppCreateDTO;
+import cn.com.yusys.yusp.domain.dto.AitagAppCreateDto;
 import cn.com.yusys.yusp.domain.entity.AitagApp;
 import cn.com.yusys.yusp.mapper.AitagAppMapper;
 import cn.com.yusys.yusp.service.AitagAppService;
@@ -31,7 +31,7 @@ public class AitagAppServiceImpl implements AitagAppService {
     }
 
     @Override
-    public AitagApp addApp(AitagAppCreateDTO dto) {
+    public AitagApp addApp(AitagAppCreateDto dto) {
         String appName = dto.getAppName();
 
         // 校验唯一性

+ 23 - 11
server/yusp-tagging-core/src/main/java/cn/com/yusys/yusp/service/impl/AitagTagCategoryServiceImpl.java

@@ -1,9 +1,9 @@
 package cn.com.yusys.yusp.service.impl;
 
-import cn.com.yusys.yusp.domain.dto.AitagTagCategoryCreateDTO;
-import cn.com.yusys.yusp.domain.dto.AitagTagCategoryUpdateDTO;
+import cn.com.yusys.yusp.domain.dto.AitagTagCategoryCreateDto;
+import cn.com.yusys.yusp.domain.dto.AitagTagCategoryUpdateDto;
 import cn.com.yusys.yusp.domain.entity.AitagTagCategory;
-import cn.com.yusys.yusp.domain.vo.AitagTagCategoryVO;
+import cn.com.yusys.yusp.domain.vo.AitagTagCategoryVo;
 import cn.com.yusys.yusp.mapper.AitagTagCategoryMapper;
 import cn.com.yusys.yusp.service.AitagTagCategoryService;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -21,14 +21,14 @@ public class AitagTagCategoryServiceImpl implements AitagTagCategoryService {
     private AitagTagCategoryMapper aiTagCategoryMapper;
 
     @Override
-    public Page<AitagTagCategoryVO> listCategories(int page, int size) {
+    public Page<AitagTagCategoryVo> listCategories(int page, int size) {
         int offset = (page - 1) * size;
         List<AitagTagCategory> records = aiTagCategoryMapper.selectPageCategories(offset, size);
         long total = aiTagCategoryMapper.selectCountAll();
 
         // 转换为 VO 并动态计算 tagNum
-        List<AitagTagCategoryVO> voList = records.stream().map(category -> {
-            AitagTagCategoryVO vo = new AitagTagCategoryVO();
+        List<AitagTagCategoryVo> voList = records.stream().map(category -> {
+            AitagTagCategoryVo vo = new AitagTagCategoryVo();
             vo.setId(category.getId());
             vo.setCategoryCode(category.getCategoryCode());
             vo.setCategoryNm(category.getCategoryNm());
@@ -44,14 +44,14 @@ public class AitagTagCategoryServiceImpl implements AitagTagCategoryService {
             return vo;
         }).collect(Collectors.toList());
 
-        Page<AitagTagCategoryVO> pageObj = new Page<>(page, size, total);
+        Page<AitagTagCategoryVo> pageObj = new Page<>(page, size, total);
         pageObj.setRecords(voList);
         return pageObj;
     }
 
 
     @Override
-    public AitagTagCategory createCategory(AitagTagCategoryCreateDTO dto) {
+    public AitagTagCategory createCategory(AitagTagCategoryCreateDto dto) {
         // 校验唯一性
         if (aiTagCategoryMapper.selectCountByNameAndNotDeleted(dto.getCategoryNm()) > 0) {
             throw new RuntimeException("标签体系名称已存在");
@@ -69,7 +69,7 @@ public class AitagTagCategoryServiceImpl implements AitagTagCategoryService {
     }
 
     @Override
-    public AitagTagCategory updateCategory(AitagTagCategoryUpdateDTO dto) {
+    public AitagTagCategory updateCategory(AitagTagCategoryUpdateDto dto) {
         AitagTagCategory existing = aiTagCategoryMapper.selectById(dto.getId());
         if (existing == null) {
             throw new RuntimeException("标签体系不存在");
@@ -100,9 +100,18 @@ public class AitagTagCategoryServiceImpl implements AitagTagCategoryService {
         if (category == null) {
             throw new RuntimeException("标签体系不存在");
         }
+
+        // 检查标签数量
+        int tagCount = aiTagCategoryMapper.countTagsByCategoryId(id);
+        if (tagCount == 0) {
+            throw new RuntimeException("体系内无可用标签!");
+        }
+
+        // 检查当前状态
         if (category.getState() == 0) {
-            throw new RuntimeException("标签体系已经是启用状态");
+            throw new RuntimeException("当前已为启用状态!");
         }
+
         aiTagCategoryMapper.updateState(id, 0);
     }
 
@@ -112,9 +121,12 @@ public class AitagTagCategoryServiceImpl implements AitagTagCategoryService {
         if (category == null) {
             throw new RuntimeException("标签体系不存在");
         }
+
+        // 检查当前状态
         if (category.getState() == 1) {
-            throw new RuntimeException("标签体系已经是停用状态");
+            throw new RuntimeException("当前已为停用状态!");
         }
+
         aiTagCategoryMapper.updateState(id, 1);
     }
 

+ 76 - 0
server/yusp-tagging-core/src/main/resources/mapper/AitagApiLogMapper.xml

@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.com.yusys.yusp.mapper.AitagApiLogMapper">
+
+    <!-- 插入API调用日志 -->
+    <insert id="insertApiLog" parameterType="cn.com.yusys.yusp.domain.entity.AitagApiLog">
+        INSERT INTO aitag_api_log (
+            id,
+            operation_type,
+            input_data,
+            output_data,
+            create_date,
+            user_id,
+            user_name,
+            consuming_time
+        ) VALUES (
+                     #{id},
+                     #{operationType},
+                     #{inputData},
+                     #{outputData},
+                     #{createDate},
+                     #{userId},
+                     #{userName},
+                     #{consumingTime}
+                 )
+    </insert>
+
+    <!-- 根据日期获取最大的日志ID -->
+    <select id="getMaxIdByDate" resultType="string">
+        SELECT id
+        FROM aitag_api_log
+        WHERE id LIKE CONCAT('API', #{dateStr}, '%')
+        ORDER BY id DESC
+            LIMIT 1
+    </select>
+
+    <!-- 统计符合条件的日志数量 -->
+    <select id="countApiLogs" resultType="long">
+        SELECT COUNT(*)
+        FROM aitag_api_log
+        <where>
+            <if test="startTime != null">
+                AND create_date >= #{startTime}
+            </if>
+            <if test="endTime != null">
+                <!-- 结束时间加一天,确保包含当天的所有记录 -->
+                AND create_date <![CDATA[<]]> DATE_ADD(#{endTime}, INTERVAL 1 DAY)
+            </if>
+        </where>
+    </select>
+
+    <!-- 分页查询日志列表 -->
+    <select id="selectApiLogs" resultType="cn.com.yusys.yusp.domain.entity.AitagApiLog">
+        SELECT id, user_name, user_id, operation_type, create_date
+        FROM aitag_api_log
+        <where>
+            <if test="startTime != null">
+                AND create_date >= #{startTime}
+            </if>
+            <if test="endTime != null">
+                <!-- 结束时间加一天,确保包含当天的所有记录 -->
+                AND create_date <![CDATA[<]]> DATE_ADD(#{endTime}, INTERVAL 1 DAY)
+            </if>
+        </where>
+        ORDER BY create_date DESC
+        LIMIT #{offset}, #{limit}
+    </select>
+
+    <!-- 根据ID查询日志详情 -->
+    <select id="selectApiLogById" resultType="cn.com.yusys.yusp.domain.entity.AitagApiLog">
+        SELECT *
+        FROM aitag_api_log
+        WHERE id = #{id}
+    </select>
+
+</mapper>

+ 1 - 1
server/yusp-tagging-core/src/main/resources/mapper/AitagTagCategoryMapper.xml

@@ -25,7 +25,7 @@
     <!-- 新增 -->
     <insert id="insertCategory">
         INSERT INTO aitag_tag_category (id, category_nm, category_desc, state, is_delete)
-        VALUES (#{id}, #{categoryNm}, #{categoryDesc}, 0, 0)
+        VALUES (#{id}, #{categoryNm}, #{categoryDesc}, 1, 0)
     </insert>
 
     <!-- 按 ID 查询 -->