diff --git a/1-sql/2026-03-06/sys_log.sql b/1-sql/2026-03-06/sys_log.sql new file mode 100644 index 00000000..a221af35 --- /dev/null +++ b/1-sql/2026-03-06/sys_log.sql @@ -0,0 +1,4 @@ +ALTER TABLE spdm_baseline.sys_log ADD module varchar(32) NULL COMMENT '所属模块'; +ALTER TABLE spdm_baseline.sys_log ADD operateType varchar(32) NULL COMMENT '操作类型'; +ALTER TABLE spdm_baseline.sys_log ADD businessId varchar(100) NULL COMMENT '业务id'; +ALTER TABLE spdm_baseline.sys_log ADD fileId bigint NULL COMMENT '文件id'; diff --git a/capability/src/main/java/com/sdm/capability/controller/FlowController.java b/capability/src/main/java/com/sdm/capability/controller/FlowController.java index 891fe7a6..d4c88a8b 100644 --- a/capability/src/main/java/com/sdm/capability/controller/FlowController.java +++ b/capability/src/main/java/com/sdm/capability/controller/FlowController.java @@ -77,13 +77,11 @@ public class FlowController implements ISimulationFlowFeignClient { * @param req * @return */ - @SysLog("查询流程模版") @PostMapping("/queryFlowTemplate") public SdmResponse queryFlowTemplate(@RequestBody @Validated GetFlowTemplateReq req) { return IFlowService.getReleaseFlowTemplateByCondition(req.templateType,req.templateName,req.approveType,req.createTime,req.creator,req.current,req.size,req.type,req.templateStatus); } - @SysLog("批量查询流程模版") @PostMapping("/batchQueryFlowTemplate") public SdmResponse> batchQueryFlowTemplate(@RequestBody @Validated List templateCodes) { return IFlowService.getFlowTemplateByTemplateCodes(templateCodes); @@ -95,7 +93,6 @@ public class FlowController implements ISimulationFlowFeignClient { * @param type 0:uuid 1:templateCode * @return */ - @SysLog("查询仿真流程模版版本信息") @GetMapping("/queryFlowTemplateVersion") public SdmResponse queryFlowTemplateVersion(@RequestParam("code") String code,@RequestParam("type") int type) { return IFlowService.getFlowTemplateVersions(code,type); diff --git a/common/src/main/java/com/sdm/common/entity/resp/data/FileMetadataInfoResp.java b/common/src/main/java/com/sdm/common/entity/resp/data/FileMetadataInfoResp.java index b7d85f38..3f6c81cf 100644 --- a/common/src/main/java/com/sdm/common/entity/resp/data/FileMetadataInfoResp.java +++ b/common/src/main/java/com/sdm/common/entity/resp/data/FileMetadataInfoResp.java @@ -4,6 +4,7 @@ import com.alibaba.fastjson2.annotation.JSONField; import com.baomidou.mybatisplus.annotation.TableField; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.sdm.common.entity.req.data.TagReq; import com.sdm.common.entity.resp.BaseResp; import com.sdm.common.entity.resp.project.SimulationRunResp; import io.swagger.v3.oas.annotations.media.Schema; @@ -147,6 +148,10 @@ public class FileMetadataInfoResp extends BaseResp implements Serializable { private String taskId; + private String runId; + + private TagReq tagReq; + @Schema(description= "流程模板id") private String flowTemplate; diff --git a/common/src/main/java/com/sdm/common/feign/impl/system/SysLogFeignClientImpl.java b/common/src/main/java/com/sdm/common/feign/impl/system/SysLogFeignClientImpl.java index 186b5746..bc6051a9 100644 --- a/common/src/main/java/com/sdm/common/feign/impl/system/SysLogFeignClientImpl.java +++ b/common/src/main/java/com/sdm/common/feign/impl/system/SysLogFeignClientImpl.java @@ -8,6 +8,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.util.List; import java.util.Optional; @@ -33,4 +34,20 @@ public class SysLogFeignClientImpl implements ISysLogFeignClient { } return response; } + + @Override + public SdmResponse batchSaveLog(List req) { + SdmResponse response=null ; + try { + response = sysLogFeignClient.batchSaveLog(req); + if(response==null || !response.isSuccess()){ + log.error("batchSaveLog failed response:{}", JSONObject.toJSONString(Optional.ofNullable(response))); + return SdmResponse.failed("批量记录日志失败"); + } + } catch (Exception e) { + log.error("batchSaveLog error response:{}", JSONObject.toJSONString(Optional.ofNullable(response))); + return SdmResponse.failed("批量记录日志异常"); + } + return response; + } } diff --git a/common/src/main/java/com/sdm/common/feign/inter/system/ISysLogFeignClient.java b/common/src/main/java/com/sdm/common/feign/inter/system/ISysLogFeignClient.java index d825747e..7cb6eacf 100644 --- a/common/src/main/java/com/sdm/common/feign/inter/system/ISysLogFeignClient.java +++ b/common/src/main/java/com/sdm/common/feign/inter/system/ISysLogFeignClient.java @@ -6,10 +6,15 @@ import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +import java.util.List; + @FeignClient(name = "system",contextId = "systemLogClient") public interface ISysLogFeignClient { @PostMapping("/systemLog/saveLog") SdmResponse saveLog(@RequestBody SysLogDTO req); + + @PostMapping("/systemLog/batchSaveLog") + SdmResponse batchSaveLog(@RequestBody List req); } diff --git a/common/src/main/java/com/sdm/common/log/annotation/SysLog.java b/common/src/main/java/com/sdm/common/log/annotation/SysLog.java index a84973e6..a26c77be 100644 --- a/common/src/main/java/com/sdm/common/log/annotation/SysLog.java +++ b/common/src/main/java/com/sdm/common/log/annotation/SysLog.java @@ -35,6 +35,26 @@ public @interface SysLog { */ String value() default ""; + /** + * 所属模块 如任务/流程 + */ + String module() default ""; + + /** + * 操作类型 如增删改 + */ + String operateType() default ""; + + /** + * 业务id 如任务的taskId + */ + String businessId() default ""; + + /** + * 业务涉及文件id + */ + String fileId() default ""; + /** * spel 表达式 * @return 日志描述 diff --git a/common/src/main/java/com/sdm/common/log/aspect/SysLogAspect.java b/common/src/main/java/com/sdm/common/log/aspect/SysLogAspect.java index 19e53b6c..ac55c236 100644 --- a/common/src/main/java/com/sdm/common/log/aspect/SysLogAspect.java +++ b/common/src/main/java/com/sdm/common/log/aspect/SysLogAspect.java @@ -49,15 +49,25 @@ public class SysLogAspect { String strMethodName = point.getSignature().getName(); log.debug("[类名]:{},[方法]:{}", strClassName, strMethodName); - String value = sysLog.value(); + // 日志描述 + String title = sysLog.value(); + // 所属模块 + String module = sysLog.module(); + // 操作类型 + String operateType = sysLog.operateType(); + // 业务id + String businessId = sysLog.businessId(); SysLogDTO logVo = SysLogUtils.getSysLog(); - logVo.setTitle(value); - // 获取请求body参数 + logVo.setTitle(title); + logVo.setModule(module); + logVo.setOperateType(operateType); + logVo.setBusinessId(businessId); + if (StrUtil.isBlank(logVo.getParams())) { logVo.setBody(point.getArgs()); } - // 发送异步日志事件 + Long startTime = System.currentTimeMillis(); Object obj; diff --git a/common/src/main/java/com/sdm/common/log/constants/ModuleConstants.java b/common/src/main/java/com/sdm/common/log/constants/ModuleConstants.java new file mode 100644 index 00000000..649797be --- /dev/null +++ b/common/src/main/java/com/sdm/common/log/constants/ModuleConstants.java @@ -0,0 +1,7 @@ +package com.sdm.common.log.constants; + +public class ModuleConstants { + + public static final String TASK = "task"; + +} diff --git a/common/src/main/java/com/sdm/common/log/constants/OperateTypeConstants.java b/common/src/main/java/com/sdm/common/log/constants/OperateTypeConstants.java new file mode 100644 index 00000000..29021bd2 --- /dev/null +++ b/common/src/main/java/com/sdm/common/log/constants/OperateTypeConstants.java @@ -0,0 +1,13 @@ +package com.sdm.common.log.constants; + +public class OperateTypeConstants { + + public static final String UPDATE = "update"; + public static final String ADD = "add"; + public static final String DELETE = "delete"; + + public static final String UPLOAD = "upload"; + public static final String DOWNLOAD = "download"; + public static final String PREVIEW = "preview"; + +} diff --git a/common/src/main/java/com/sdm/common/log/dto/SysLogDTO.java b/common/src/main/java/com/sdm/common/log/dto/SysLogDTO.java index 01bc77a0..652f410c 100644 --- a/common/src/main/java/com/sdm/common/log/dto/SysLogDTO.java +++ b/common/src/main/java/com/sdm/common/log/dto/SysLogDTO.java @@ -51,26 +51,11 @@ public class SysLogDTO { @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime updateTime; - /** - * 操作IP地址 - */ - private String remoteAddr; - - /** - * 用户代理 - */ - private String userAgent; - /** * 请求URI */ private String requestUri; - /** - * 操作方式 - */ - private String method; - /** * 操作提交的数据 */ @@ -107,4 +92,13 @@ public class SysLogDTO { @Schema(description = "每页显示数量") private Integer size; + // 所属模块 + private String module; + // 操作类型 + private String operateType; + // 业务id + private String businessId; + // 文件id + private Long fileId; + } diff --git a/common/src/main/java/com/sdm/common/log/event/SysLogListener.java b/common/src/main/java/com/sdm/common/log/event/SysLogListener.java index f81b70f8..1e25986e 100644 --- a/common/src/main/java/com/sdm/common/log/event/SysLogListener.java +++ b/common/src/main/java/com/sdm/common/log/event/SysLogListener.java @@ -24,6 +24,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ser.FilterProvider; import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter; import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider; +import com.sdm.common.feign.impl.system.SysLogFeignClientImpl; import com.sdm.common.feign.inter.system.ISysLogFeignClient; import com.sdm.common.log.config.SysLogProperties; import com.sdm.common.log.dto.SysLogDTO; @@ -61,7 +62,7 @@ public class SysLogListener implements InitializingBean { */ private final static ObjectMapper objectMapper = new ObjectMapper(); - private final ISysLogFeignClient sysLogFeignClient; + private final SysLogFeignClientImpl sysLogFeignClient; private final SysLogProperties logProperties; diff --git a/common/src/main/java/com/sdm/common/log/utils/SysLogUtils.java b/common/src/main/java/com/sdm/common/log/utils/SysLogUtils.java index 49bba68e..d6f99ee2 100644 --- a/common/src/main/java/com/sdm/common/log/utils/SysLogUtils.java +++ b/common/src/main/java/com/sdm/common/log/utils/SysLogUtils.java @@ -44,24 +44,17 @@ import java.util.HashMap; import java.util.Map; import java.util.Objects; -/** - * 系统日志工具类 - * - * @author L.cm - */ + @UtilityClass @Slf4j public class SysLogUtils { public SysLogDTO getSysLog() { HttpServletRequest request = ((ServletRequestAttributes) Objects - .requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); + .requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); SysLogDTO sysLog = new SysLogDTO(); sysLog.setLogType(LogTypeEnum.NORMAL.getType()); sysLog.setRequestUri(URLUtil.getPath(request.getRequestURI())); - sysLog.setMethod(request.getMethod()); - sysLog.setRemoteAddr(JakartaServletUtil.getClientIP(request)); - sysLog.setUserAgent(request.getHeader(HttpHeaders.USER_AGENT)); sysLog.setCreateBy(String.valueOf(ThreadLocalContext.getUserId())); try { // 获取服务名称 diff --git a/data/src/main/java/com/sdm/data/controller/DataFileController.java b/data/src/main/java/com/sdm/data/controller/DataFileController.java index c6c2c0d7..124cd782 100644 --- a/data/src/main/java/com/sdm/data/controller/DataFileController.java +++ b/data/src/main/java/com/sdm/data/controller/DataFileController.java @@ -136,7 +136,6 @@ public class DataFileController implements IDataFeignClient { * @param req * @return */ - @SysLog("删除文件") @PostMapping("/delFile") @Operation(summary = "删除文件", description = "根据请求参数删除指定的文件(移入回收站)") public SdmResponse delFile(@RequestBody @Validated DelFileReq req) { @@ -414,7 +413,6 @@ public class DataFileController implements IDataFeignClient { * @return */ @AutoFillDictTags - @SysLog("上传文件") @PostMapping(value = "/uploadFiles", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @Operation( summary = "上传文件", diff --git a/data/src/main/java/com/sdm/data/controller/DataStorageAnalysisController.java b/data/src/main/java/com/sdm/data/controller/DataStorageAnalysisController.java index 8c74590a..205868aa 100644 --- a/data/src/main/java/com/sdm/data/controller/DataStorageAnalysisController.java +++ b/data/src/main/java/com/sdm/data/controller/DataStorageAnalysisController.java @@ -142,7 +142,6 @@ public class DataStorageAnalysisController { return dataStorageAnalysis.addUserQuota(addUserQuota); } // 查询用户配额 - @SysLog("查询用户配额") @PostMapping("/listUserQuota") @Operation(summary = "查询用户配额") public SdmResponse listUserQuota(@RequestBody ListUserQuotaReq listUserQuotaReq){ diff --git a/data/src/main/java/com/sdm/data/controller/ModelTraningController.java b/data/src/main/java/com/sdm/data/controller/ModelTraningController.java index e8d36f8b..93cddc4e 100644 --- a/data/src/main/java/com/sdm/data/controller/ModelTraningController.java +++ b/data/src/main/java/com/sdm/data/controller/ModelTraningController.java @@ -46,7 +46,6 @@ public class ModelTraningController { /** * 获取模型列表 */ - @SysLog("获取模型列表") @PostMapping("/getModelList") @Operation(summary = "获取模型列表", description = "获取模型列表") public SdmResponse getModelList(@RequestBody QueryModelReq baseReq) { @@ -56,7 +55,6 @@ public class ModelTraningController { /** * 获取模型详情 */ - @SysLog("获取模型详情") @GetMapping("/getModelDetail") @Operation(summary = "获取模型详情", description = "获取模型详情") public SdmResponse getModelDetail(@RequestParam Long modelId) { @@ -104,7 +102,6 @@ public class ModelTraningController { /** * 获取训练数据输入输出特征设置详情 */ - @SysLog("获取训练数据输入输出特征设置详情") @GetMapping("/getTrainingDataInPutOutPutColumn") @Operation(summary = "获取训练数据输入输出特征设置详情", description = "获取训练数据输入输出特征设置详情") public SdmResponse getTrainingDataInPutOutPutColumn(@RequestParam Long modelId) { @@ -124,7 +121,6 @@ public class ModelTraningController { /** * 获取算法参数设置详情 */ - @SysLog("获取算法参数设置详情") @GetMapping("/getAlgorithmParam") @Operation(summary = "获取算法参数设置详情", description = "获取算法参数设置详情") public SdmResponse getAlgorithmParam(@RequestParam Long modelId) { @@ -146,7 +142,6 @@ public class ModelTraningController { * * @param modelId */ - @SysLog("获取训练曲线和训练日志") @GetMapping("/getTrainingResult") @Operation(summary = "获取训练曲线和训练日志", description = "获取训练曲线和训练日志") public SdmResponse getTrainingResult(@RequestParam Long modelId) { @@ -166,7 +161,6 @@ public class ModelTraningController { /** * 进入模型预测页面,获取历史模型预测结果 */ - @SysLog("获取历史模型预测结果") @GetMapping("/getModelPredictResult") @Operation(summary = "进入模型预测页面,获取历史模型预测结果", description = "进入模型预测页面,获取历史模型预测结果") public SdmResponse getModelPredictResult(@RequestParam Long modelId) { diff --git a/data/src/main/java/com/sdm/data/controller/SimulationParameterLibraryController.java b/data/src/main/java/com/sdm/data/controller/SimulationParameterLibraryController.java index ca33fcda..bfc9c790 100644 --- a/data/src/main/java/com/sdm/data/controller/SimulationParameterLibraryController.java +++ b/data/src/main/java/com/sdm/data/controller/SimulationParameterLibraryController.java @@ -67,7 +67,6 @@ public class SimulationParameterLibraryController { /** * 获取仿真参数展示树 */ - @SysLog("获取仿真参数展示树") @GetMapping("/getSimulationParameterTree") @Operation(summary = "获取仿真参数展示树", description = "获取仿真参数展示树") public SdmResponse getSimulationParameterTree(@Parameter(description = "1:模型库/2:模型库分类/3:参数对象") @RequestParam(value = "type", required = false) Integer type, @Parameter(description = "传对应模型库id/模型库分类id/参数对象id,不传查所有的模型库") @RequestParam(value = "id", required = false) Long id) { @@ -77,7 +76,6 @@ public class SimulationParameterLibraryController { /** * 判断是否有参数对象 */ - @SysLog("判断是否有参数对象") @GetMapping("/hasParameterObject") @Operation(summary = "判断是否有参数对象", description = "判断是否有参数对象") public SdmResponse hasParameterObject(@Parameter(description = "1:模型库/2:模型库分类") @RequestParam(value = "type") Integer type, @Parameter(description = "传对应模型库id/模型库分类id") @RequestParam(value = "id") Long id) { @@ -112,7 +110,6 @@ public class SimulationParameterLibraryController { /** * 获取仿真参数库分类参数对象 和JSON数据 */ - @SysLog("获取仿真参数库分类参数对象") @GetMapping("/getSimulationParameterLibraryCategoryObject") @Operation(summary = "获取仿真参数库分类参数对象和JSON数据", description = "获取仿真参数库分类参数对象") public SdmResponse getSimulationParameterLibraryCategoryObject(@Parameter(description = "参数对象id") @RequestParam(value = "ObjectId") Long ObjectId) { diff --git a/data/src/main/java/com/sdm/data/service/impl/MinioFileIDataFileServiceImpl.java b/data/src/main/java/com/sdm/data/service/impl/MinioFileIDataFileServiceImpl.java index 9e2ad0b4..cbb531a3 100644 --- a/data/src/main/java/com/sdm/data/service/impl/MinioFileIDataFileServiceImpl.java +++ b/data/src/main/java/com/sdm/data/service/impl/MinioFileIDataFileServiceImpl.java @@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; +import com.github.pagehelper.util.StringUtil; import com.google.common.collect.Sets; import com.sdm.common.common.SdmResponse; import com.sdm.common.common.ThreadLocalContext; @@ -26,12 +27,17 @@ import com.sdm.common.entity.resp.data.*; import com.sdm.common.entity.resp.project.SimulationNodeResp; import com.sdm.common.entity.resp.system.CIDUserResp; import com.sdm.common.feign.impl.project.SimulationNodeFeignClientImpl; +import com.sdm.common.feign.impl.system.SysLogFeignClientImpl; import com.sdm.common.feign.impl.system.SysUserFeignClientImpl; import com.sdm.common.feign.inter.project.ISimulationNodeFeignClient; import com.sdm.common.feign.inter.system.IApproveFeignClient; import com.sdm.common.feign.inter.system.ISysConfigFeignClient; +import com.sdm.common.feign.inter.system.ISysLogFeignClient; import com.sdm.common.feign.inter.task.ISimuluationTaskPoolFeignClient; import com.sdm.common.log.CoreLogger; +import com.sdm.common.log.constants.ModuleConstants; +import com.sdm.common.log.constants.OperateTypeConstants; +import com.sdm.common.log.dto.SysLogDTO; import com.sdm.common.utils.*; import com.sdm.common.utils.excel.ExcelUtil; import com.sdm.data.aop.PermissionCheckAspect; @@ -109,12 +115,11 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService { private static final String FLOWABLE_SIMULATION_BASEDIR = "/home/simulation/"; @Value("${data.recycle.retention-days:7}") - - - - private Integer recycleRetentionDays; + @Autowired + private ISysLogFeignClient sysLogFeignClient; + @Autowired private IFileMetadataInfoService fileMetadataInfoService; @@ -824,6 +829,9 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService { ); } + // 记录删除日志 + saveTaskFileLog("删除了文件" + deleteFileMetadataInfo.getOriginalName(), OperateTypeConstants.DELETE, deleteFileMetadataInfo.getTaskId(), deleteFileMetadataInfo.getId()); + // 非知识库文件:直接移入回收站 (Rename + Soft Delete) LocalDateTime now = LocalDateTime.now(); LocalDateTime expireAt = now.plusDays(recycleRetentionDays); @@ -1662,10 +1670,11 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService { FileMetadataInfo targetParentMetadataInfo = fileMetadataInfoService.lambdaQuery().eq(FileMetadataInfo::getId, req.getParentDirId()).one(); String originalName = sourceMetadataInfo.getOriginalName(); - // 如果文件有后缀,则在文件名和后缀之间插入版本号 - int dotIndex = originalName.lastIndexOf('.'); + SdmResponse versionedNameResponse = buildVersionedFileName(originalName); + String modifiedFileName = versionedNameResponse.getData(); + // 新的路径名 - String newDirMinioObjectKey = getFileMinioObjectKey(targetParentMetadataInfo.getObjectKey() + originalName.substring(0, dotIndex) + "_V1" + originalName.substring(dotIndex)); + String newDirMinioObjectKey = getFileMinioObjectKey(targetParentMetadataInfo.getObjectKey() + modifiedFileName); // 把以前归档的过同名文件删除 保留最新的 Long tenantId = ThreadLocalContext.getTenantId(); @@ -1963,6 +1972,7 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService { } List addFileInfoRespList = new ArrayList<>(); + for (UploadFilesReq fileReq : req.getSourceFiles()) { SdmResponse handleResponse = handleBatchFileInfo(req, fileReq, dirMetadataInfo); if (!handleResponse.isSuccess()) { @@ -1970,9 +1980,41 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService { } addFileInfoRespList.add(handleResponse.getData()); } + batchSaveTaskFileLog(req.getTagReq(), req.getSourceFiles()); return SdmResponse.success(addFileInfoRespList); } + private void batchSaveTaskFileLog(TagReq tagReq, List files) { + List logDTOList = new ArrayList<>(); + files.forEach(file -> { + SysLogDTO logDTO = new SysLogDTO(); + logDTO.setTitle("上传了文件" + file.getFileName()); + logDTO.setModule(ModuleConstants.TASK); + logDTO.setOperateType(OperateTypeConstants.UPLOAD); + if (tagReq != null) { + logDTO.setBusinessId(tagReq.getTaskId()); + } + logDTO.setCreateBy(String.valueOf(ThreadLocalContext.getUserId())); + logDTO.setTenantId(ThreadLocalContext.getTenantId()); + logDTOList.add(logDTO); + }); + log.info("[MinioFileIDataFileServiceImpl] batchSaveTaskFileLog saveLog params:{}", JSON.toJSONString(logDTOList)); + sysLogFeignClient.batchSaveLog(logDTOList); + } + + private void saveTaskFileLog(String title, String operateType , String taskId, Long fileId) { + SysLogDTO logDTO = new SysLogDTO(); + logDTO.setTitle(title); + logDTO.setModule(ModuleConstants.TASK); + logDTO.setOperateType(operateType); + logDTO.setBusinessId(taskId); + logDTO.setFileId(fileId); + logDTO.setCreateBy(String.valueOf(ThreadLocalContext.getUserId())); + logDTO.setTenantId(ThreadLocalContext.getTenantId()); + log.info("[MinioFileIDataFileServiceImpl] saveTaskFileLog saveLog params:{}", JSON.toJSONString(logDTO)); + sysLogFeignClient.saveLog(logDTO); + } + @Override @@ -2136,6 +2178,8 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService { createFilePermission(fileInfo.getId()); triggerKnowledgeApproveIfNeeded(req, fileInfo, dirMetadataInfo); finalizeFileGroup(fileInfo); + // 记录日志 + saveTaskFileLog("上传了文件" + fileInfo.getOriginalName(), OperateTypeConstants.PREVIEW, fileInfo.getTaskId(), fileInfo.getId()); return buildUploadSuccess(fileInfo); } catch (Exception e) { @@ -3340,6 +3384,8 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService { KKFileViewURLFromMinioResp kkFileViewURLFromMinioResp = new KKFileViewURLFromMinioResp(minioPresignedUrl, encodeKKFileViewURL); // kkFileView已经二次开发,需要拼接 &lastModified=2025-10-13%2016:12:12 + // 记录预览日志 + saveTaskFileLog("预览了" + fileMetadataInfo.getOriginalName(), OperateTypeConstants.PREVIEW, fileMetadataInfo.getTaskId(), fileId); return SdmResponse.success(kkFileViewURLFromMinioResp); } @@ -3366,6 +3412,8 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService { if (minioDownloadUrl == null) { return SdmResponse.failed("获取下载链接失败"); } + // 记录下载日志 + saveTaskFileLog("下载了" + fileMetadataInfo.getOriginalName(), OperateTypeConstants.DOWNLOAD, fileMetadataInfo.getTaskId(), fileId); MinioDownloadUrlResp resp = new MinioDownloadUrlResp(minioDownloadUrl, fileName); return SdmResponse.success(resp); } diff --git a/project/src/main/java/com/sdm/project/controller/SimulationAnalysisController.java b/project/src/main/java/com/sdm/project/controller/SimulationAnalysisController.java index bb688f7f..56baf606 100644 --- a/project/src/main/java/com/sdm/project/controller/SimulationAnalysisController.java +++ b/project/src/main/java/com/sdm/project/controller/SimulationAnalysisController.java @@ -32,7 +32,6 @@ public class SimulationAnalysisController { * @param req * @return */ - @SysLog("数据分析(数据查询)-根据节点id获取仿真工况") @GetMapping("/taskList") @Operation(summary = "仿真工况", description = "仿真工况") public SdmResponse taskList(SpdmAnalysisTaskListReq req) { @@ -45,7 +44,6 @@ public class SimulationAnalysisController { * @param req * @return */ - @SysLog("数据分析(数据查询)-根据节点id获取指标") @GetMapping("/performanceList") @Operation(summary = "指标", description = "指标") public SdmResponse performanceList(SpdmAnalysisPerformanceListReq req) { @@ -58,7 +56,6 @@ public class SimulationAnalysisController { * @param req * @return */ - @SysLog("数据分析(数据查询)-根据节点id获取算例") @GetMapping("/runList") @Operation(summary = "算例", description = "算例") public SdmResponse runList(SpdmAnalysisRunListReq req) { @@ -69,7 +66,6 @@ public class SimulationAnalysisController { /** * 数据分析(数据查询)-根据任务id获取所有算列结果 */ - @SysLog("数据分析(数据查询)-根据任务id获取所有算列结果") @GetMapping("/getAllRunResultByTaskId") public SdmResponse getAllRunResultByTaskId(String taskId) { return taskService.getAllRunResultByTaskId(taskId); diff --git a/project/src/main/java/com/sdm/project/controller/SimulationDemandController.java b/project/src/main/java/com/sdm/project/controller/SimulationDemandController.java index 37f6f38c..1182d821 100644 --- a/project/src/main/java/com/sdm/project/controller/SimulationDemandController.java +++ b/project/src/main/java/com/sdm/project/controller/SimulationDemandController.java @@ -78,7 +78,6 @@ public class SimulationDemandController { * @param req * @return */ - @SysLog("查询需求列表") @GetMapping("/list") @Operation(summary = "需求列表(我发起的、我确认的)", description = "需求列表(我发起的、我确认的)") public SdmResponse list(@Validated SpdmDemandListReq req) { @@ -183,7 +182,6 @@ public class SimulationDemandController { * @param req * @return */ - @SysLog("查询需求列表") @GetMapping("/listNoPermission") @Operation(summary = "需求列表(我发起的、我确认的)", description = "需求列表(我发起的、我确认的)") public SdmResponse listNoPermission(@Validated SpdmDemandListReq req) { diff --git a/project/src/main/java/com/sdm/project/controller/SimulationLocalJobController.java b/project/src/main/java/com/sdm/project/controller/SimulationLocalJobController.java index 4aaa71fd..b3b4d43a 100644 --- a/project/src/main/java/com/sdm/project/controller/SimulationLocalJobController.java +++ b/project/src/main/java/com/sdm/project/controller/SimulationLocalJobController.java @@ -55,7 +55,6 @@ public class SimulationLocalJobController implements ISimulationLocalJobFeignCli * @param req * @return */ - @SysLog("查询本地应用任务") @PostMapping("/list") @Operation(summary = "查询本地应用任务", description = "查询本地应用任务") public SdmResponse list(@RequestBody SpdmLocalJobListReq req) { diff --git a/project/src/main/java/com/sdm/project/controller/SimulationNodeController.java b/project/src/main/java/com/sdm/project/controller/SimulationNodeController.java index 3abc2cc6..c2461529 100644 --- a/project/src/main/java/com/sdm/project/controller/SimulationNodeController.java +++ b/project/src/main/java/com/sdm/project/controller/SimulationNodeController.java @@ -79,7 +79,6 @@ public class SimulationNodeController implements ISimulationNodeFeignClient { * @param req * @return */ - @SysLog("查询项目列表") @PostMapping("/list") @Operation(summary = "项目列表", description = "项目列表") public SdmResponse list(@RequestBody SpdmNodeListReq req) { @@ -92,7 +91,6 @@ public class SimulationNodeController implements ISimulationNodeFeignClient { * @param req * @return */ - @SysLog("查询项目详情") @GetMapping("/getNodeDetail") @Operation(summary = "项目详情", description = "项目详情") public SdmResponse getNodeDetail(GetProjectDetailReq req) { @@ -105,7 +103,6 @@ public class SimulationNodeController implements ISimulationNodeFeignClient { * @param req * @return */ - @SysLog("获取团队成员") @GetMapping("/getProjectMemberList") @Operation(summary = "获取团队成员", description = "获取团队成员") public SdmResponse getProjectMemberList(@Validated GetProjectListReq req) { @@ -208,7 +205,6 @@ public class SimulationNodeController implements ISimulationNodeFeignClient { /** * 用户组项目统计 */ - @SysLog("用户组项目统计") @GetMapping("/getUserGroupProjectStatistics") @Operation(summary = "用户组项目统计", description = "用户组项目统计") public SdmResponse getUserGroupProjectStatistics(@Parameter(description = "用户组ID")@RequestParam( value = "userGroupId" )@NotNull(message = "用户组ID(userGroupId)为必传参数,请补充后重试") Long userGroupId, @Parameter(description = "用户ID")@RequestParam( value = "userId", required = false) Long userId) { @@ -221,7 +217,6 @@ public class SimulationNodeController implements ISimulationNodeFeignClient { * discipline 学科 * tag1-tag10 标签 */ - @SysLog("用户组任务完成情况统计") @PostMapping("/getUserGroupTaskCompleteStatistics") @Operation(summary = "用户组任务完成情况统计", description = "用户组任务完成情况统计") public SdmResponse getUserGroupTaskCompleteStatistics(@RequestBody @Validated GetUserGroupTaskCompleteStatisticsReq req) { @@ -236,7 +231,6 @@ public class SimulationNodeController implements ISimulationNodeFeignClient { * tag1-tag10 标签 * */ - @SysLog("用户组难度系数统计") @PostMapping("/getUserGroupDifficultyStatistics") @Operation(summary = "用户组难度系数统计", description = "用户组难度系数统计") public SdmResponse getUserGroupDifficultyStatistics(@RequestBody @Validated GetUserGroupTaskCompleteStatisticsReq req) { @@ -251,7 +245,6 @@ public class SimulationNodeController implements ISimulationNodeFeignClient { * tag1-tag10 标签 * resultTagType X轴(工位对应的tag)数据返回对应的Tag类型: tag1、tag2,tag3,tag4,tag5,tag6,tag7,tag8,tag9,tag10 */ - @SysLog("任务/指标 完成情况统计请求参数(工位)") @PostMapping("/getCommonCompleteStatistics") @Operation(summary = "任务/指标 完成情况统计请求参数(工位)", description = "任务/指标 完成情况统计请求参数(工位)") public SdmResponse getCommonCompleteStatistics(@RequestBody @Validated CommonGetCompleteStatisticsReq req) { @@ -264,7 +257,6 @@ public class SimulationNodeController implements ISimulationNodeFeignClient { * 需要传: * tag1-tag10 标签 */ - @SysLog("任务/指标 完成情况统计请求参数(学科)") @PostMapping("/getTaskCompleteStatisticsByDiscipline") @Operation(summary = "基于 学科(学科不是节点,是task的一个属性)查询 任务 完成统计", description = "基于 学科(学科不是节点,是task的一个属性)查询(任务/指标)完成统计") public SdmResponse getTaskCompleteStatisticsByDiscipline(@RequestBody @Validated CommonGetCompleteStatisticsReq req) { @@ -289,7 +281,6 @@ public class SimulationNodeController implements ISimulationNodeFeignClient { * discipline 下拉框选项学科 * resultTagType 数据返回Tag类型: tag1、tag2,tag3,tag4,tag5,tag6,tag7,tag8,tag9,tag10 */ - @SysLog("工位评审通过统计查询") @PostMapping("/getWorkstationReviewStatistics") @Operation(summary = "工位评审通过统计查询", description = "工位评审通过统计查询") public SdmResponse getWorkstationReviewStatistics(@RequestBody GetWorkstationApproveStatusReq req) { diff --git a/project/src/main/java/com/sdm/project/controller/SimulationProjectController.java b/project/src/main/java/com/sdm/project/controller/SimulationProjectController.java index 84e43863..34b9df75 100644 --- a/project/src/main/java/com/sdm/project/controller/SimulationProjectController.java +++ b/project/src/main/java/com/sdm/project/controller/SimulationProjectController.java @@ -65,7 +65,6 @@ public class SimulationProjectController implements ISimulationProjectFeignClien * @param req * @return */ - @SysLog("获取任务分析项树") @PostMapping("/getTaskTree") @Operation(summary = "任务分析项树", description = "任务分析项树") public SdmResponse getTaskTree(@RequestBody ProjectTreeTagReq req) { @@ -90,7 +89,6 @@ public class SimulationProjectController implements ISimulationProjectFeignClien * @param req * @return */ - @SysLog("获取多个项目的任务分析项树") @PostMapping("/getTaskTreeList") @Operation(summary = "获取多个项目的任务分析项树", description = "获取多个项目的任务分析项树") public SdmResponse getTaskTreeList(@RequestBody @Validated ProjectTreeListReq req) { diff --git a/project/src/main/java/com/sdm/project/controller/SimulationRunController.java b/project/src/main/java/com/sdm/project/controller/SimulationRunController.java index 682536c7..4a84670a 100644 --- a/project/src/main/java/com/sdm/project/controller/SimulationRunController.java +++ b/project/src/main/java/com/sdm/project/controller/SimulationRunController.java @@ -13,6 +13,8 @@ import com.sdm.common.entity.resp.data.BatchAddFileInfoResp; import com.sdm.common.entity.resp.data.FileMetadataInfoResp; import com.sdm.common.feign.inter.project.ISimulationRunFeignClient; import com.sdm.common.log.annotation.SysLog; +import com.sdm.common.log.constants.ModuleConstants; +import com.sdm.common.log.constants.OperateTypeConstants; import com.sdm.project.model.entity.*; import com.sdm.project.model.po.TaskRunPo; import com.sdm.project.model.req.*; @@ -45,7 +47,6 @@ public class SimulationRunController implements ISimulationRunFeignClient { * @param req * @return */ - @SysLog("获取任务分析项算例树") @PostMapping("/getTaskRunTree") @Operation(summary = "任务分析项算例树", description = "任务分析项算例树") public SdmResponse getTaskRunTree(@RequestBody ProjectTreeTagReq req) { @@ -73,7 +74,6 @@ public class SimulationRunController implements ISimulationRunFeignClient { /** * 查询算例详情 */ - @SysLog("查询算例详情") @PostMapping("/queryTaskRun") public SdmResponse> queryRunInfo(@RequestBody SpdmTaskRunReq req) { return runService.queryTaskRun(req); @@ -108,7 +108,6 @@ public class SimulationRunController implements ISimulationRunFeignClient { * * @return */ - @SysLog("获取任务下所有算例版本") @PostMapping("/getTaskRunVersion") public SdmResponse> getTaskRunVersion(@RequestBody GetRunVersionReq req) { return runService.getTaskRunVersion(req); @@ -119,7 +118,6 @@ public class SimulationRunController implements ISimulationRunFeignClient { * * @return */ - @SysLog("获取指定算例的版本结构") @PostMapping("/getRunVersion") public SdmResponse getRunVersion(@RequestBody GetRunVersionReq req) { return runService.getRunVersion(req); @@ -147,7 +145,6 @@ public class SimulationRunController implements ISimulationRunFeignClient { * * @return */ - @SysLog("上传交付物-文件信息和关键结果信息批量入库") @PostMapping(value = "/batchAddSimulationKeyResult") public SdmResponse> batchAddSimulationKeyResult(@RequestBody KeyResultReq req) { return runService.batchAddSimulationKeyResult(req); @@ -158,7 +155,12 @@ public class SimulationRunController implements ISimulationRunFeignClient { * * @return */ - @SysLog("提交交付物审批") + @SysLog( + value = "发起了交付物评审", + module = ModuleConstants.TASK, + operateType = OperateTypeConstants.UPDATE, + businessId = "#req.taskId" + ) @PostMapping(value = "/deliverableApprove") public SdmResponse deliverableApprove(@RequestBody DeliverableApproveReq req) { return runService.deliverableApprove(req); @@ -169,7 +171,6 @@ public class SimulationRunController implements ISimulationRunFeignClient { * * @return */ - @SysLog("交付物审批回调") @PostMapping(value = "/deliverableApproveCallback") public SdmResponse deliverableApproveCallback(@RequestBody LaunchApproveReq req) { return runService.deliverableApproveCallback(req); @@ -180,7 +181,6 @@ public class SimulationRunController implements ISimulationRunFeignClient { * * @return */ - @SysLog("算例关键结果查询") @PostMapping(value = "/listSimulationKeyResult") public SdmResponse>> listSimulationKeyResult(@RequestBody KeyResultReq req) { return runService.listSimulationKeyResult(req); @@ -288,7 +288,6 @@ public class SimulationRunController implements ISimulationRunFeignClient { /** * 任务执行 查询流程节点列表 */ - @SysLog("查询流程节点列表") @PostMapping("/listFlowNodes") public SdmResponse listFlowNodes(@RequestBody SpdmTaskRunReq req) { return runService.listFlowNodes(req); diff --git a/project/src/main/java/com/sdm/project/controller/SimulationTaskController.java b/project/src/main/java/com/sdm/project/controller/SimulationTaskController.java index 5394caaa..bd79d447 100644 --- a/project/src/main/java/com/sdm/project/controller/SimulationTaskController.java +++ b/project/src/main/java/com/sdm/project/controller/SimulationTaskController.java @@ -8,6 +8,8 @@ import com.sdm.common.entity.req.project.GetTaskDetailReq; import com.sdm.common.entity.req.task.TaskExportExcelFormat; import com.sdm.common.feign.inter.project.ISimulationTaskFeignClient; import com.sdm.common.log.annotation.SysLog; +import com.sdm.common.log.constants.ModuleConstants; +import com.sdm.common.log.constants.OperateTypeConstants; import com.sdm.project.model.bo.ModifyTaskNode; import com.sdm.project.model.req.*; import com.sdm.project.model.resp.*; @@ -54,14 +56,12 @@ public class SimulationTaskController implements ISimulationTaskFeignClient { /** * 驳回、启动、暂停、工时、关闭、关注、取消关注、编辑 */ - @SysLog("操作任务") @PostMapping("/operation") @Operation(summary = "操作任务", description = "操作任务") public SdmResponse operation(@RequestBody SpdmTaskOpr taskOpr) { return taskService.operation(taskOpr); } - @SysLog("关注或取消关注任务") @PostMapping("/attention") @Operation(summary = "关注或取消关注任务", description = "关注或取消关注任务") public SdmResponse attention(@RequestBody SpdmTaskAttentionReq req) { @@ -75,7 +75,6 @@ public class SimulationTaskController implements ISimulationTaskFeignClient { * @param req * @return */ - @SysLog("查询任务列表") @PostMapping("/list") @Operation(summary = "任务列表(我执行的、我关注的、所有)", description = "任务列表(我执行的、我关注的、所有)") public SdmResponse list(@Validated @RequestBody SpdmTaskListReq req) { @@ -103,7 +102,6 @@ public class SimulationTaskController implements ISimulationTaskFeignClient { /** * 工作负载 查询执行时间在指定时间段内,指定用户执行的任务列表 */ - @SysLog("查询用户工作负载") @PostMapping("/listUserWorkloads") @Operation(summary = "查询用户工作负载", description = "查询用户工作负载") public SdmResponse> listUserWorkloadsWithinTimeFrame(@RequestBody UserWorkloadReq req) { @@ -176,7 +174,6 @@ public class SimulationTaskController implements ISimulationTaskFeignClient { /** * 按工位、学科的仿真任务完成统计 */ - @SysLog("按工位、学科的仿真任务完成统计") @PostMapping("/getTaskCompleteStatistics") @Operation(summary = "按工位、学科的仿真任务完成统计", description = "按工位、学科的仿真任务完成统计") public SdmResponse getTaskCompleteStatistics(@RequestBody @Validated TaskCompleteStatisticsReq req) { @@ -186,7 +183,6 @@ public class SimulationTaskController implements ISimulationTaskFeignClient { /** * 按工位、学科的仿真指标完成统计 */ - @SysLog("按工位、学科的仿真指标完成统计") @PostMapping("/getPerformanceCompleteStatistics") @Operation(summary = "按工位、学科的仿真指标完成统计", description = "按工位、学科的仿真指标完成统计") public SdmResponse getPerformanceCompleteStatistics(@RequestBody @Validated PerformanceCompleteStatisticsReq req) { @@ -196,7 +192,6 @@ public class SimulationTaskController implements ISimulationTaskFeignClient { /** * 项目成员任务进度统计 */ - @SysLog("项目成员任务进度统计") @PostMapping("/getUserTaskCompleteStatistics") @Operation(summary = "项目成员任务进度统计", description = "项目成员任务进度统计") public SdmResponse getUserTaskCompleteStatistics(@RequestBody @Validated UserTaskCompleteStatisticsReq req) { @@ -207,7 +202,6 @@ public class SimulationTaskController implements ISimulationTaskFeignClient { * 项目成员难度系数统计 * */ - @SysLog("项目成员难度系数统计") @PostMapping("/getUserDifficultyStatistics") @Operation(summary = "项目成员难度系数统计", description = "项目成员难度系数统计") public SdmResponse getUserDifficultyStatistics(@RequestBody @Validated UserDifficultCompleteStatisticsReq req) { @@ -229,7 +223,6 @@ public class SimulationTaskController implements ISimulationTaskFeignClient { /** * 仿真任务达成统计 */ - @SysLog("仿真任务达成统计") @PostMapping("/getTaskAchieveStatistics") @Operation(summary = "仿真任务达成统计", description = "仿真任务达成统计") public SdmResponse getTaskAchieveStatistics(@RequestBody @Validated TaskCompleteStatisticsReq req) { @@ -239,7 +232,6 @@ public class SimulationTaskController implements ISimulationTaskFeignClient { /** * 仿真任务置信度统计 */ - @SysLog("仿真任务置信度统计") @GetMapping("/getTaskConfidenceStatistics") @Operation(summary = "仿真任务置信度统计", description = "仿真任务置信度统计") public SdmResponse> getTaskConfidenceStatistics(@RequestParam(value = "nodeType", required = true) String nodeType) { @@ -249,7 +241,6 @@ public class SimulationTaskController implements ISimulationTaskFeignClient { /** * 仿真任务难度系数统计 */ - @SysLog("仿真任务难度系数统计") @GetMapping("/getTaskDifficultStatistics") @Operation(summary = "仿真任务难度系数统计", description = "仿真任务难度系数统计") public SdmResponse> getTaskDifficultStatistics(@RequestParam(value = "nodeType", required = true) String nodeType) { @@ -259,7 +250,6 @@ public class SimulationTaskController implements ISimulationTaskFeignClient { /** * 仿真项目下的难度系数统计 */ - @SysLog("仿真项目下的难度系数统计") @PostMapping("/getProjectDifficultStatistics") @Operation(summary = "仿真项目下的难度系数统计", description = "仿真项目下的难度系数统计") public SdmResponse> getProjectDifficultStatistics(@RequestBody @Validated ProjectDifficultCompleteStatisticsReq req) { @@ -269,7 +259,6 @@ public class SimulationTaskController implements ISimulationTaskFeignClient { /** * 删除任务及相关数据 */ - @SysLog("删除任务及相关数据") @PostMapping("/deleteTask") @Operation(summary = "删除任务及相关数据", description = "删除任务及相关数据") public SdmResponse deleteTask(@RequestBody @Validated SpdmDeleteTaskReq req) { diff --git a/project/src/main/java/com/sdm/project/service/impl/ProjectServiceImpl.java b/project/src/main/java/com/sdm/project/service/impl/ProjectServiceImpl.java index 46243f43..cbd3fc09 100644 --- a/project/src/main/java/com/sdm/project/service/impl/ProjectServiceImpl.java +++ b/project/src/main/java/com/sdm/project/service/impl/ProjectServiceImpl.java @@ -25,7 +25,11 @@ import com.sdm.common.feign.impl.capability.SimulationFlowFeignClientImpl; import com.sdm.common.feign.impl.data.DataClientFeignClientImpl; import com.sdm.common.feign.impl.system.ApproveFeignClientImpl; import com.sdm.common.feign.impl.system.MessageFeignClientImpl; +import com.sdm.common.feign.impl.system.SysLogFeignClientImpl; import com.sdm.common.feign.impl.system.SysUserFeignClientImpl; +import com.sdm.common.log.constants.ModuleConstants; +import com.sdm.common.log.constants.OperateTypeConstants; +import com.sdm.common.log.dto.SysLogDTO; import com.sdm.common.service.BaseService; import com.sdm.common.service.TagMapService; import com.sdm.common.utils.RandomUtil; @@ -113,6 +117,10 @@ public class ProjectServiceImpl extends BaseService implements IProjectService { @Autowired private ApproveFeignClientImpl approveFeignClient; + @Autowired + private SysLogFeignClientImpl sysLogFeignClient; + + @Autowired private TagMapService tagMapService; @@ -432,6 +440,8 @@ public class ProjectServiceImpl extends BaseService implements IProjectService { // 5. 处理关注人(无权限同步,无消息通知) handleTaskMember(taskEditNodeReq, MemberTypeEnum.ATTENTION, taskEditNodeReq.getPayAttentionMemberList(), false, null); + // 6.记录编辑任务日志 + saveTaskLog("编辑了任务", OperateTypeConstants.UPDATE, taskUuid); } } @@ -2897,6 +2907,8 @@ public class ProjectServiceImpl extends BaseService implements IProjectService { return SdmResponse.failed("无权限删除任务"); } } + // 记录删除任务日志 + batchSaveTaskLog("删除了任务", OperateTypeConstants.DELETE, taskIdList); } if (CollectionUtils.isNotEmpty(performanceList)) { @@ -2940,6 +2952,34 @@ public class ProjectServiceImpl extends BaseService implements IProjectService { return SdmResponse.success(); } + private void saveTaskLog(String title, String operateType , String taskId) { + SysLogDTO logDTO = new SysLogDTO(); + logDTO.setTitle(title); + logDTO.setModule(ModuleConstants.TASK); + logDTO.setOperateType(operateType); + logDTO.setBusinessId(taskId); + logDTO.setCreateBy(String.valueOf(ThreadLocalContext.getUserId())); + logDTO.setTenantId(ThreadLocalContext.getTenantId()); + log.info("[modify] saveLog params:{}", JSON.toJSONString(logDTO)); + sysLogFeignClient.saveLog(logDTO); + } + + private void batchSaveTaskLog(String title, String operateType, List taskIds) { + List logDTOList = new ArrayList<>(); + taskIds.forEach(taskId -> { + SysLogDTO logDTO = new SysLogDTO(); + logDTO.setTitle(title); + logDTO.setModule(ModuleConstants.TASK); + logDTO.setOperateType(operateType); + logDTO.setBusinessId(taskId); + logDTO.setCreateBy(String.valueOf(ThreadLocalContext.getUserId())); + logDTO.setTenantId(ThreadLocalContext.getTenantId()); + logDTOList.add(logDTO); + }); + log.info("[modify] saveLog params:{}", JSON.toJSONString(logDTOList)); + sysLogFeignClient.batchSaveLog(logDTOList); + } + /** * 发起仿真策划评审 */ diff --git a/project/src/main/java/com/sdm/project/service/impl/SimulationRunServiceImpl.java b/project/src/main/java/com/sdm/project/service/impl/SimulationRunServiceImpl.java index 39f33674..dc71dafd 100644 --- a/project/src/main/java/com/sdm/project/service/impl/SimulationRunServiceImpl.java +++ b/project/src/main/java/com/sdm/project/service/impl/SimulationRunServiceImpl.java @@ -864,6 +864,20 @@ public class SimulationRunServiceImpl extends ServiceImpl fileBaseInfoResp = dataFeignClient.getFileBaseInfo(getFileBaseInfoReq); + if (fileBaseInfoResp.getData() != null && fileBaseInfoResp.getData().getTagReq() != null) { + TagReq tagReq = fileBaseInfoResp.getData().getTagReq(); + // 算例下的文件夹要塞runId + if (tagReq.getRunId() == null) { + tagReq.setRunId(uuid); + } + createDirReq.setTagReq(tagReq); + } + log.info("创建算例阶段时,调用创建文件夹的参数为:{}", createDirReq); SdmResponse response = dataFeignClient.createDir(createDirReq); log.info("创建算例阶段时,调用创建文件夹的返回值为:{}", response); @@ -877,6 +891,17 @@ public class SimulationRunServiceImpl extends ServiceImpl fileBaseInfoResp = dataFeignClient.getFileBaseInfo(getFileBaseInfoReq); + if (fileBaseInfoResp.getData() != null && fileBaseInfoResp.getData().getTagReq() != null) { + // 试验结果属于task下 tag没有runId + TagReq tagReq = fileBaseInfoResp.getData().getTagReq(); + createDirReq.setTagReq(tagReq); + } + log.info("上传试验结果时,调用创建文件夹的参数为:{}", createDirReq); SdmResponse response = dataFeignClient.createDir(createDirReq); log.info("上传试验结果时,调用创建文件夹的返回值为:{}", response); @@ -921,13 +946,18 @@ public class SimulationRunServiceImpl extends ServiceImpl fileMetadataInfoResp = dataFeignClient.queryFileMetadataInfo(req.getUuId(), NodeTypeEnum.RUN.getValue(), 0L); - if (fileMetadataInfoResp.getData() != null) { - createDirReq.setParDirId(fileMetadataInfoResp.getData().getId()); + // 查询上级算例文件夹信息 + GetFileBaseInfoReq getFileBaseInfoReq = new GetFileBaseInfoReq(); + getFileBaseInfoReq.setUuid(req.getUuId()); + SdmResponse fileBaseInfoResp = dataFeignClient.getFileBaseInfo(getFileBaseInfoReq); + if (fileBaseInfoResp.getData() != null && fileBaseInfoResp.getData().getTagReq() != null) { + TagReq tagReq = fileBaseInfoResp.getData().getTagReq(); + createDirReq.setTagReq(tagReq); + createDirReq.setParDirId(fileBaseInfoResp.getData().getId()); } createDirReq.setDirName(req.getDirName()); createDirReq.setDirType(DirTypeEnum.PROJECT_NODE_DIR.getValue()); + log.info("创建算例结果时,调用创建文件夹的参数为:{}", createDirReq); SdmResponse response = dataFeignClient.createDir(createDirReq); log.info("创建算例结果时,调用创建文件夹的返回值为:{}", response); @@ -941,6 +971,7 @@ public class SimulationRunServiceImpl extends ServiceImpl> listSdmResponse = dataFeignClient.batchAddFileInfo(req); // 神仙代码,废弃 @@ -963,6 +994,14 @@ public class SimulationRunServiceImpl extends ServiceImpl fileBaseInfoResp = dataFeignClient.getFileBaseInfo(getFileBaseInfoReq); + if (fileBaseInfoResp.getData() != null && fileBaseInfoResp.getData().getTagReq() != null) { + TagReq tagReq = fileBaseInfoResp.getData().getTagReq(); + req.setTagReq(tagReq); + } return dataFeignClient.uploadFiles(req); } @@ -1219,6 +1258,8 @@ public class SimulationRunServiceImpl extends ServiceImpl new UploadFilesReq(i.getFileName(), i.getFileSize(), i.getFileType())).toList()); + setTagReq(req.getTaskId(), null, filesReq); + // 批量存储文件信息,返回数据供第二步分片上传使用 SdmResponse> sdmResponse = dataFeignClient.batchAddFileInfo(filesReq); if (sdmResponse.isSuccess() && CollectionUtils.isNotEmpty(sdmResponse.getData())) { @@ -1247,6 +1288,21 @@ public class SimulationRunServiceImpl extends ServiceImpl()); } + private void setTagReq(String uuid, Long fileId, UploadFilesReq req) { + // 查询上级任务文件夹信息 + GetFileBaseInfoReq getFileBaseInfoReq = new GetFileBaseInfoReq(); + if (StringUtils.isNotBlank(uuid)) { + getFileBaseInfoReq.setUuid(uuid); + } else { + getFileBaseInfoReq.setFileId(fileId); + } + SdmResponse fileBaseInfoResp = dataFeignClient.getFileBaseInfo(getFileBaseInfoReq); + if (fileBaseInfoResp.getData() != null && fileBaseInfoResp.getData().getTagReq() != null) { + TagReq tagReq = fileBaseInfoResp.getData().getTagReq(); + req.setTagReq(tagReq); + } + } + @Override public SdmResponse deliverableApprove(DeliverableApproveReq req) { SimulationTask simulationTask = simulationTaskService.lambdaQuery().eq(SimulationTask::getUuid, req.getTaskId()).one(); @@ -2466,6 +2522,8 @@ public class SimulationRunServiceImpl extends ServiceImpl new UploadFilesReq(i.getFileName(), i.getFileSize(), i.getFileType())).toList()); + setTagReq(req.getTaskId(), null, filesReq); + // 批量存储文件信息,返回数据供第二步分片上传使用 SdmResponse> sdmResponse = dataFeignClient.batchAddFileInfo(filesReq); if (sdmResponse.isSuccess() && CollectionUtils.isNotEmpty(sdmResponse.getData())) { @@ -2619,6 +2677,9 @@ public class SimulationRunServiceImpl extends ServiceImpl new UploadFilesReq(i.getFileName(), i.getFileSize(), i.getFileType())).toList()); + + setTagReq(req.getTaskId(), null, filesReq); + // 批量存储文件信息,返回数据供第二步分片上传使用 batchAddResponse = dataFeignClient.batchAddFileInfo(filesReq); if (!batchAddResponse.isSuccess()) { @@ -2857,6 +2918,9 @@ public class SimulationRunServiceImpl extends ServiceImpl> batchAddFileInfoResp = dataFeignClient.batchAddFileInfo(req); if (batchAddFileInfoResp.isSuccess() && CollectionUtils.isNotEmpty(batchAddFileInfoResp.getData())) { List batchAddFileInfoList = batchAddFileInfoResp.getData(); diff --git a/project/src/main/java/com/sdm/project/service/impl/TaskServiceImpl.java b/project/src/main/java/com/sdm/project/service/impl/TaskServiceImpl.java index b903739b..01225773 100644 --- a/project/src/main/java/com/sdm/project/service/impl/TaskServiceImpl.java +++ b/project/src/main/java/com/sdm/project/service/impl/TaskServiceImpl.java @@ -34,6 +34,10 @@ import com.sdm.common.entity.resp.system.SysUserGroupDetailResp; import com.sdm.common.feign.impl.data.DataClientFeignClientImpl; import com.sdm.common.feign.impl.system.MessageFeignClientImpl; import com.sdm.common.feign.impl.system.SysUserFeignClientImpl; +import com.sdm.common.feign.inter.system.ISysLogFeignClient; +import com.sdm.common.log.constants.ModuleConstants; +import com.sdm.common.log.constants.OperateTypeConstants; +import com.sdm.common.log.dto.SysLogDTO; import com.sdm.common.utils.RandomUtil; import com.sdm.common.utils.SystemOperate; import com.sdm.common.utils.excel.ExcelUtil; @@ -136,6 +140,9 @@ public class TaskServiceImpl implements ITaskService { @Autowired private MessageFeignClientImpl messageFeignClient; + @Autowired + private ISysLogFeignClient sysLogFeignClient; + @Resource private INodeService nodeService; @@ -1589,11 +1596,26 @@ public class TaskServiceImpl implements ITaskService { .eq(SimulationTaskExtra::getId, simulationTaskExtra.getId()) .update(); } + // 记录编辑日志 + saveTaskLog("编辑了任务", OperateTypeConstants.UPDATE, taskId); + } } return SdmResponse.success(); } + private void saveTaskLog(String title, String operateType, String taskId) { + SysLogDTO logDTO = new SysLogDTO(); + logDTO.setTitle(title); + logDTO.setModule(ModuleConstants.TASK); + logDTO.setOperateType(operateType); + logDTO.setBusinessId(taskId); + logDTO.setCreateBy(String.valueOf(ThreadLocalContext.getUserId())); + logDTO.setTenantId(ThreadLocalContext.getTenantId()); + log.info("[operation] saveLog params:{}", JSON.toJSONString(logDTO)); + sysLogFeignClient.saveLog(logDTO); + } + private void sendMessage(MessageTemplateEnum templateEnum, String taskName, String userId, String uuid) { SendMsgReq req = new SendMsgReq(); req.setTitle(templateEnum.getTitle()); @@ -1989,10 +2011,14 @@ public class TaskServiceImpl implements ITaskService { mapper.saveAttentionList(attentionList); // task_member也新增下,兼容新逻辑 simulationTaskMemberService.saveTaskMemberList(taskId, MemberTypeEnum.ATTENTION.getCode(), addUserIdList); + // 记录日志 + saveTaskLog("关注了任务", OperateTypeConstants.UPDATE, taskId); } else { mapper.deleteAttentionByUserIdList(taskId, cancelUserIdList); // task_member也删除下,兼容新逻辑 simulationTaskMemberService.deleteTaskMemberListByIdList(taskId, MemberTypeEnum.ATTENTION.getCode(), cancelUserIdList); + // 记录日志 + saveTaskLog("取消关注了任务", OperateTypeConstants.UPDATE, taskId); } return SdmResponse.success(); } diff --git a/system/src/main/java/com/sdm/system/controller/SystemLogController.java b/system/src/main/java/com/sdm/system/controller/SystemLogController.java index 5c881806..b0a5dea0 100644 --- a/system/src/main/java/com/sdm/system/controller/SystemLogController.java +++ b/system/src/main/java/com/sdm/system/controller/SystemLogController.java @@ -7,6 +7,7 @@ import com.sdm.common.feign.inter.system.ISysLogFeignClient; import com.sdm.common.log.dto.SysLogDTO; import com.sdm.system.model.entity.SysLog; import com.sdm.system.model.resp.DailyOnlineStateResp; +import com.sdm.system.model.resp.DailyOperateStatsResp; import com.sdm.system.model.resp.LoginStateResp; import com.sdm.system.service.ISysLogService; import io.swagger.v3.oas.annotations.tags.Tag; @@ -40,6 +41,12 @@ public class SystemLogController implements ISysLogFeignClient { return logService.saveLog(req); } + + @PostMapping("/batchSaveLog") + public SdmResponse batchSaveLog(@RequestBody List req) { + return logService.batchSaveLog(req); + } + /** * 分页查询 * @param sysLog 系统日志 @@ -67,4 +74,15 @@ public class SystemLogController implements ISysLogFeignClient { public SdmResponse> getHourlyOnlineStatistics(@RequestParam @NotNull(message = "日期不能为空") String date) { return logService.getHourlyOnlineStatistics(date); } + + /** + * 统计每日下载和预览次数 + * @param createTimeArr 时间数组 [startDate, endDate],格式:yyyy-MM-dd + * @return 每日操作统计列表 + */ + @GetMapping("/getDailyOperateStatistics") + public SdmResponse> getDailyOperateStatistics( + @RequestParam("createTimeArr") @NotNull(message = "时间不能为空") String[] createTimeArr) { + return logService.getDailyOperateStatistics(createTimeArr); + } } diff --git a/system/src/main/java/com/sdm/system/model/entity/SysLog.java b/system/src/main/java/com/sdm/system/model/entity/SysLog.java index 7a2ad3bb..79215e3a 100644 --- a/system/src/main/java/com/sdm/system/model/entity/SysLog.java +++ b/system/src/main/java/com/sdm/system/model/entity/SysLog.java @@ -67,20 +67,6 @@ public class SysLog implements Serializable { @TableField("updateTime") private LocalDateTime updateTime; - /** - * 操作IP地址 - */ - @Schema(description = "操作ip地址") - @TableField("remoteAddr") - private String remoteAddr; - - /** - * 用户代理 - */ - @Schema(description = "用户代理") - @TableField("userAgent") - private String userAgent; - /** * 请求URI */ @@ -137,4 +123,32 @@ public class SysLog implements Serializable { @TableField("delFlag") private String delFlag; + /** + * 所属模块 + */ + @Schema(description = "所属模块") + @TableField("module") + private String module; + + /** + * 操作类型 + */ + @Schema(description = "操作类型") + @TableField("operateType") + private String operateType; + + /** + * 业务id + */ + @Schema(description = "业务id") + @TableField("businessId") + private String businessId; + + /** + * 文件id + */ + @Schema(description = "文件id") + @TableField("fileId") + private Long fileId; + } diff --git a/system/src/main/java/com/sdm/system/model/resp/DailyOperateStatsResp.java b/system/src/main/java/com/sdm/system/model/resp/DailyOperateStatsResp.java new file mode 100644 index 00000000..11f0a716 --- /dev/null +++ b/system/src/main/java/com/sdm/system/model/resp/DailyOperateStatsResp.java @@ -0,0 +1,19 @@ +package com.sdm.system.model.resp; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +@Schema(description = "每日操作统计响应") +public class DailyOperateStatsResp { + + @Schema(description = "日期") + private String date; + + @Schema(description = "下载次数") + private Integer downloadCount; + + @Schema(description = "预览次数") + private Integer previewCount; + +} diff --git a/system/src/main/java/com/sdm/system/service/ISysLogService.java b/system/src/main/java/com/sdm/system/service/ISysLogService.java index a6aa2e67..16c9d616 100644 --- a/system/src/main/java/com/sdm/system/service/ISysLogService.java +++ b/system/src/main/java/com/sdm/system/service/ISysLogService.java @@ -8,6 +8,7 @@ import com.sdm.common.entity.resp.PageDataResp; import com.sdm.common.log.dto.SysLogDTO; import com.sdm.system.model.entity.SysLog; import com.sdm.system.model.resp.DailyOnlineStateResp; +import com.sdm.system.model.resp.DailyOperateStatsResp; import com.sdm.system.model.resp.LoginStateResp; import java.util.List; @@ -44,4 +45,13 @@ public interface ISysLogService extends IService { */ SdmResponse saveLog(SysLogDTO sysLog); + SdmResponse batchSaveLog(List req); + + /** + * 统计每日下载和预览次数 + * @param createTimeArr 时间数组 [startDate, endDate],格式:yyyy-MM-dd + * @return 每日操作统计列表 + */ + SdmResponse> getDailyOperateStatistics(String[] createTimeArr); + } diff --git a/system/src/main/java/com/sdm/system/service/impl/ISysLogServiceImpl.java b/system/src/main/java/com/sdm/system/service/impl/ISysLogServiceImpl.java index f01fbdd8..967ef688 100644 --- a/system/src/main/java/com/sdm/system/service/impl/ISysLogServiceImpl.java +++ b/system/src/main/java/com/sdm/system/service/impl/ISysLogServiceImpl.java @@ -23,6 +23,7 @@ import com.sdm.system.model.dto.UserLastLoginDto; import com.sdm.system.model.dto.UserSessionDto; import com.sdm.system.model.entity.SysLog; import com.sdm.system.model.resp.DailyOnlineStateResp; +import com.sdm.system.model.resp.DailyOperateStatsResp; import com.sdm.system.model.resp.LoginStateResp; import com.sdm.system.service.ISysLogService; import lombok.extern.slf4j.Slf4j; @@ -64,7 +65,7 @@ public class ISysLogServiceImpl extends ServiceImpl implem if (ArrayUtil.isNotEmpty(sysLog.getCreateTimeArr())) { wrapper.ge(SysLog::getCreateTime, sysLog.getCreateTimeArr()[0]) - .le(SysLog::getCreateTime, sysLog.getCreateTimeArr()[1]); + .le(SysLog::getCreateTime, sysLog.getCreateTimeArr()[1]); } wrapper.eq(SysLog::getTenantId, ThreadLocalContext.getTenantId()); wrapper.orderByDesc(SysLog::getCreateTime); @@ -135,17 +136,17 @@ public class ISysLogServiceImpl extends ServiceImpl implem * 统计指定日期每小时的在线用户数(处理任意时间登录未退出的情况) */ public Map getHourlyOnlineUsers(LocalDate targetDate, Long tenantId) { - LocalDateTime now = LocalDateTime.now(); - LocalDate today = now.toLocalDate(); + LocalDateTime now = LocalDateTime.now(); + LocalDate today = now.toLocalDate(); - // 如果查询的是今天,只统计到当前小时 - int maxHour = 24; - if (targetDate.equals(today)) { - maxHour = now.getHour(); // 只统计到当前小时 - } + // 如果查询的是今天,只统计到当前小时 + int maxHour = 24; + if (targetDate.equals(today)) { + maxHour = now.getHour(); // 只统计到当前小时 + } - // 获取目标日期时间范围 - LocalDateTime targetDayStart = targetDate.atStartOfDay(); + // 获取目标日期时间范围 + LocalDateTime targetDayStart = targetDate.atStartOfDay(); LocalDateTime targetDayEnd = targetDate.plusDays(1).atStartOfDay(); // 2. 获取所有在目标日期之前登录的用户及其最后登录时间 @@ -167,7 +168,7 @@ public class ISysLogServiceImpl extends ServiceImpl implem private List buildActiveSessions( List UserLastLoginDtos, Map userLogoutTimes, - LocalDateTime targetDayStart, + LocalDateTime targetDayStart, LocalDateTime targetDayEnd) { List sessions = new ArrayList<>(); @@ -177,35 +178,35 @@ public class ISysLogServiceImpl extends ServiceImpl implem LocalDateTime loginTime = userLogin.getLastLoginTime(); LocalDateTime logoutTime = userLogoutTimes.get(userId); - // 判断会话是否覆盖目标日期: - // 1. 登录时间必须在目标日期结束之前(否则会话还没开始) - // 2. 退出时间必须在目标日期开始之后或为null(否则会话已结束) + // 判断会话是否覆盖目标日期: + // 1. 登录时间必须在目标日期结束之前(否则会话还没开始) + // 2. 退出时间必须在目标日期开始之后或为null(否则会话已结束) - // 会话开始时间 < 目标日期结束时间 - boolean sessionStartedBeforeTargetEnd = loginTime.isBefore(targetDayEnd); + // 会话开始时间 < 目标日期结束时间 + boolean sessionStartedBeforeTargetEnd = loginTime.isBefore(targetDayEnd); - // 会话结束时间 > 目标日期开始时间 或 会话未结束(有些上个月最后一次登录的了) - boolean sessionEndedAfterTargetStart = logoutTime == null || logoutTime.isAfter(targetDayStart); + // 会话结束时间 > 目标日期开始时间 或 会话未结束(有些上个月最后一次登录的了) + boolean sessionEndedAfterTargetStart = logoutTime == null || logoutTime.isAfter(targetDayStart); - if (sessionStartedBeforeTargetEnd && sessionEndedAfterTargetStart) { - // 计算有效的退出时间 - LocalDateTime effectiveLogoutTime; - if (logoutTime == null) { - // 未退出:认为持续到目标日期结束 - effectiveLogoutTime = targetDayEnd; - } else if (logoutTime.isAfter(targetDayEnd)) { - // 退出时间在目标日期之后:认为持续到目标日期结束 - effectiveLogoutTime = targetDayEnd; - } else { - // 在目标日期内退出:使用实际退出时间 - effectiveLogoutTime = logoutTime; - } + if (sessionStartedBeforeTargetEnd && sessionEndedAfterTargetStart) { + // 计算有效的退出时间 + LocalDateTime effectiveLogoutTime; + if (logoutTime == null) { + // 未退出:认为持续到目标日期结束 + effectiveLogoutTime = targetDayEnd; + } else if (logoutTime.isAfter(targetDayEnd)) { + // 退出时间在目标日期之后:认为持续到目标日期结束 + effectiveLogoutTime = targetDayEnd; + } else { + // 在目标日期内退出:使用实际退出时间 + effectiveLogoutTime = logoutTime; + } - // 确保登录时间不会早于实际需要考虑的时间 - LocalDateTime effectiveLoginTime = loginTime.isBefore(targetDayStart) ? targetDayStart : loginTime; + // 确保登录时间不会早于实际需要考虑的时间 + LocalDateTime effectiveLoginTime = loginTime.isBefore(targetDayStart) ? targetDayStart : loginTime; - sessions.add(new UserSessionDto(userId, effectiveLoginTime, effectiveLogoutTime)); - } + sessions.add(new UserSessionDto(userId, effectiveLoginTime, effectiveLogoutTime)); + } } return sessions; } @@ -233,32 +234,32 @@ public class ISysLogServiceImpl extends ServiceImpl implem private boolean isOnlineDuring(UserSessionDto session, LocalDateTime periodStart, LocalDateTime periodEnd) { - // 用户在该时段在线的条件: - // 1. 会话开始时间 < 时段结束时间(用户在时段结束前已登录) - // 2. 会话结束时间 > 时段开始时间(用户在时段开始后未退出) - boolean flag = session.getLoginTime().isBefore(periodEnd) && session.getEffectiveLogoutTime().isAfter(periodStart); - log.info("userId:{}, onlineFlag:{}, time interval:{}", session.getUserId(), flag, periodStart.toString() + "-" + periodEnd.toString()); - return flag; + // 用户在该时段在线的条件: + // 1. 会话开始时间 < 时段结束时间(用户在时段结束前已登录) + // 2. 会话结束时间 > 时段开始时间(用户在时段开始后未退出) + boolean flag = session.getLoginTime().isBefore(periodEnd) && session.getEffectiveLogoutTime().isAfter(periodStart); + log.info("userId:{}, onlineFlag:{}, time interval:{}", session.getUserId(), flag, periodStart.toString() + "-" + periodEnd.toString()); + return flag; } - private Map getUserNextLogoutTimes( - List userLastLogins, Long tenantId) { + private Map getUserNextLogoutTimes( + List userLastLogins, Long tenantId) { - Map logoutTimes = new HashMap<>(); + Map logoutTimes = new HashMap<>(); - if (userLastLogins.isEmpty()) { - return logoutTimes; - } + if (userLastLogins.isEmpty()) { + return logoutTimes; + } - // 批量查询每个用户在其最后登录时间之后的退出记录 - List logouts = baseMapper.findNextLogoutTimes(userLastLogins, tenantId); + // 批量查询每个用户在其最后登录时间之后的退出记录 + List logouts = baseMapper.findNextLogoutTimes(userLastLogins, tenantId); - for (UserLogoutDto logout : logouts) { - logoutTimes.put(logout.getUserId(), logout.getLogoutTime()); - } + for (UserLogoutDto logout : logouts) { + logoutTimes.put(logout.getUserId(), logout.getLogoutTime()); + } - return logoutTimes; - } + return logoutTimes; + } private void setCreatorNames(List list) { try { @@ -306,4 +307,67 @@ public class ISysLogServiceImpl extends ServiceImpl implem return SdmResponse.success(this.save(log)); } + @Override + public SdmResponse batchSaveLog(List req) { + List logList = new ArrayList<>(); + req.forEach(sysLog -> { + SysLog log = new SysLog(); + BeanUtils.copyProperties(sysLog, log); + logList.add(log); + }); + return SdmResponse.success(this.saveBatch(logList)); + } + + @Override + public SdmResponse> getDailyOperateStatistics(String[] createTimeArr) { + Long tenantId = ThreadLocalContext.getTenantId(); + + // 解析时间参数 + String startDate = createTimeArr[0]; + String endDate = createTimeArr[1]; + LocalDateTime startTime = LocalDate.parse(startDate, DATE_FORMATTER).atStartOfDay(); + LocalDateTime endTime = LocalDate.parse(endDate, DATE_FORMATTER).atTime(23, 59, 59); + + // 查询时间范围内的下载和预览日志 + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); + wrapper.eq(SysLog::getTenantId, tenantId); + wrapper.ge(SysLog::getCreateTime, startTime); + wrapper.le(SysLog::getCreateTime, endTime); + wrapper.in(SysLog::getOperateType, "download", "preview"); + List logList = this.list(wrapper); + + // 按日期分组统计 + DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + Map statsMap = new LinkedHashMap<>(); + + // 初始化日期范围内所有日期 + LocalDate start = LocalDate.parse(startDate, DATE_FORMATTER); + LocalDate end = LocalDate.parse(endDate, DATE_FORMATTER); + LocalDate current = start; + while (!current.isAfter(end)) { + String dateStr = current.format(dateFormatter); + DailyOperateStatsResp resp = new DailyOperateStatsResp(); + resp.setDate(dateStr); + resp.setDownloadCount(0); + resp.setPreviewCount(0); + statsMap.put(dateStr, resp); + current = current.plusDays(1); + } + + // 统计每日的下载和预览次数 + for (SysLog log : logList) { + String dateStr = log.getCreateTime().format(dateFormatter); + DailyOperateStatsResp resp = statsMap.get(dateStr); + if (resp != null) { + if ("download".equals(log.getOperateType())) { + resp.setDownloadCount(resp.getDownloadCount() + 1); + } else if ("preview".equals(log.getOperateType())) { + resp.setPreviewCount(resp.getPreviewCount() + 1); + } + } + } + + return SdmResponse.success(new ArrayList<>(statsMap.values())); + } + } diff --git a/task/src/main/java/com/sdm/task/service/impl/SimulationPerformanceServiceImpl.java b/task/src/main/java/com/sdm/task/service/impl/SimulationPerformanceServiceImpl.java index 4d2f3f21..4a67da09 100644 --- a/task/src/main/java/com/sdm/task/service/impl/SimulationPerformanceServiceImpl.java +++ b/task/src/main/java/com/sdm/task/service/impl/SimulationPerformanceServiceImpl.java @@ -1,7 +1,9 @@ package com.sdm.task.service.impl; +import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONArray; import com.sdm.common.common.SdmResponse; +import com.sdm.common.common.ThreadLocalContext; import com.sdm.common.entity.ExportExcelFormat; import com.sdm.common.entity.enums.ApprovalFileDataStatusEnum; import com.sdm.common.entity.enums.PerformanceStatusEnum; @@ -10,6 +12,11 @@ import com.sdm.common.entity.req.performance.PerformanceExportExcelFormat; import com.sdm.common.entity.req.performance.PerformanceExportExcelParam; import com.sdm.common.entity.resp.PageDataResp; import com.sdm.common.entity.resp.task.PerformanceResp; +import com.sdm.common.feign.impl.system.SysLogFeignClientImpl; +import com.sdm.common.feign.inter.system.ISysLogFeignClient; +import com.sdm.common.log.constants.ModuleConstants; +import com.sdm.common.log.constants.OperateTypeConstants; +import com.sdm.common.log.dto.SysLogDTO; import com.sdm.common.service.BaseService; import com.sdm.common.utils.CommonUtils; import com.sdm.common.utils.RandomUtil; @@ -25,6 +32,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.sdm.task.service.ISimulationTaskPoolService; import com.sdm.task.service.ISimulationTaskService; import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; @@ -47,6 +55,7 @@ import java.util.List; * @since 2025-10-14 */ @Service +@Slf4j public class SimulationPerformanceServiceImpl extends ServiceImpl implements ISimulationPerformanceService { @Autowired private ISimulationTaskService simulationTaskService; @@ -54,6 +63,9 @@ public class SimulationPerformanceServiceImpl extends ServiceImpl performanceIds) { + performanceIds.forEach(performanceId -> { + SimulationPerformance performance = this.lambdaQuery().eq(SimulationPerformance::getId, performanceId).one(); + saveTaskLog("删除了指标" + performance.getNodeName(), OperateTypeConstants.DELETE, performance.getTaskId()); + }); + // 删除该任务UUID关联的所有性能指标 boolean success = this.lambdaUpdate() .in(SimulationPerformance::getId, performanceIds) @@ -135,6 +154,18 @@ public class SimulationPerformanceServiceImpl extends ServiceImpl