From bac506af207170375cbced94579c5c330bac0eb1 Mon Sep 17 00:00:00 2001 From: zhuxinru Date: Fri, 5 Dec 2025 09:53:09 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E6=97=A5=E5=BF=97=E9=9B=86=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../capability/controller/FlowController.java | 5 + .../controller/TaskPoolController.java | 2 + common/pom.xml | 6 + .../impl/system/SysLogFeignClientImpl.java | 36 +++++ .../inter/system/ISysLogFeignClient.java | 15 +++ .../com/sdm/common/log/annotation/SysLog.java | 44 ++++++ .../sdm/common/log/aspect/SysLogAspect.java | 81 +++++++++++ .../common/log/config/SysLogProperties.java | 56 ++++++++ .../com/sdm/common/log/dto/SysLogDTO.java | 98 ++++++++++++++ .../common/log/event/SpringContextHolder.java | 127 ++++++++++++++++++ .../com/sdm/common/log/event/SysLogEvent.java | 31 +++++ .../sdm/common/log/event/SysLogListener.java | 111 +++++++++++++++ .../sdm/common/log/utils/JavaTimeModule.java | 61 +++++++++ .../com/sdm/common/log/utils/LogTypeEnum.java | 33 +++++ .../com/sdm/common/log/utils/SysLogUtils.java | 87 ++++++++++++ .../data/controller/DataFileController.java | 2 + .../DataStorageAnalysisController.java | 4 + .../DimensionTemplateController.java | 3 + .../FileSimulationMappingController.java | 2 + .../controller/ModelTraningController.java | 8 ++ .../SimulationParameterLibraryController.java | 6 + .../SimulationAnalysisController.java | 5 + .../SimulationDemandController.java | 5 + .../controller/SimulationNodeController.java | 5 +- .../controller/SimulationRunController.java | 9 ++ .../project/service/impl/NodeServiceImpl.java | 6 - .../controller/SystemLogController.java | 36 +++++ .../system/service/ISimulationLogService.java | 11 ++ .../impl/SimulationLogServiceImpl.java | 44 ++++++ system/src/main/resources/application-dev.yml | 4 +- .../src/main/resources/application-local.yml | 2 + .../src/main/resources/application-prod.yml | 4 +- 32 files changed, 940 insertions(+), 9 deletions(-) create mode 100644 common/src/main/java/com/sdm/common/feign/impl/system/SysLogFeignClientImpl.java create mode 100644 common/src/main/java/com/sdm/common/feign/inter/system/ISysLogFeignClient.java create mode 100644 common/src/main/java/com/sdm/common/log/annotation/SysLog.java create mode 100644 common/src/main/java/com/sdm/common/log/aspect/SysLogAspect.java create mode 100644 common/src/main/java/com/sdm/common/log/config/SysLogProperties.java create mode 100644 common/src/main/java/com/sdm/common/log/dto/SysLogDTO.java create mode 100644 common/src/main/java/com/sdm/common/log/event/SpringContextHolder.java create mode 100644 common/src/main/java/com/sdm/common/log/event/SysLogEvent.java create mode 100644 common/src/main/java/com/sdm/common/log/event/SysLogListener.java create mode 100644 common/src/main/java/com/sdm/common/log/utils/JavaTimeModule.java create mode 100644 common/src/main/java/com/sdm/common/log/utils/LogTypeEnum.java create mode 100644 common/src/main/java/com/sdm/common/log/utils/SysLogUtils.java create mode 100644 system/src/main/java/com/sdm/system/controller/SystemLogController.java create mode 100644 system/src/main/java/com/sdm/system/service/ISimulationLogService.java create mode 100644 system/src/main/java/com/sdm/system/service/impl/SimulationLogServiceImpl.java 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 10a86d24..70baea21 100644 --- a/capability/src/main/java/com/sdm/capability/controller/FlowController.java +++ b/capability/src/main/java/com/sdm/capability/controller/FlowController.java @@ -9,6 +9,7 @@ import com.sdm.common.common.SdmResponse; import com.sdm.common.entity.req.capability.FlowNodeDto; import com.sdm.common.entity.req.system.LaunchApproveReq; import com.sdm.common.feign.inter.capability.ISimulationFlowFeignClient; +import com.sdm.common.log.annotation.SysLog; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -35,6 +36,7 @@ public class FlowController implements ISimulationFlowFeignClient { * @param template * @return */ + @SysLog("添加仿真流程模版草稿") @PostMapping("/upgradeFlowTemplateDraft") public SdmResponse upgradeFlowTemplateDraft(@RequestBody @Validated SimulationFlowTemplate template) { return IFlowService.upgradeFlowTemplateDraft(template); @@ -45,6 +47,7 @@ public class FlowController implements ISimulationFlowFeignClient { * @param template * @return */ + @SysLog("弃用模板") @PostMapping("/updateFlowTemplateDraft") public SdmResponse updateFlowTemplateDraft(@RequestBody @Validated SimulationFlowTemplate template) { return IFlowService.updateFlowTemplateDraft(template); @@ -55,11 +58,13 @@ public class FlowController implements ISimulationFlowFeignClient { * @param flowTemplate * @return */ + @SysLog("删除流程模版草稿") @PostMapping("/deleteFlowTemplateDraft") public SdmResponse deleteFlowTemplateDraft(@RequestBody SimulationFlowTemplate flowTemplate) { return IFlowService.deleteFlowTemplateDraft(flowTemplate.uuid); } + @SysLog("发布流程模版草稿") @PostMapping("/releaseFlowTemplate") public SdmResponse releaseFlowTemplateDraft(@RequestBody @Validated ReleaseFlowTemplateReq req) { return IFlowService.releaseFlowTemplate(req.uuid,req.versionType,req.approveTemplateName,req.approveTemplateId); diff --git a/capability/src/main/java/com/sdm/capability/controller/TaskPoolController.java b/capability/src/main/java/com/sdm/capability/controller/TaskPoolController.java index 4b581618..e2059501 100644 --- a/capability/src/main/java/com/sdm/capability/controller/TaskPoolController.java +++ b/capability/src/main/java/com/sdm/capability/controller/TaskPoolController.java @@ -4,6 +4,7 @@ import com.sdm.capability.model.req.taskPool.DelTaskPoolReq; import com.sdm.capability.model.req.taskPool.QueryTaskPoolReq; import com.sdm.capability.service.TaskPoolService; import com.sdm.common.common.SdmResponse; +import com.sdm.common.log.annotation.SysLog; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -22,6 +23,7 @@ public class TaskPoolController { * @param req req * @return SdmResponse */ + @SysLog("删除任务库") @PostMapping("/delTaskPool") public SdmResponse delTaskPool(@RequestBody @Validated DelTaskPoolReq req) { return taskPoolService.delTaskPool(req); diff --git a/common/pom.xml b/common/pom.xml index 7b7b35c0..788c1fc7 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -58,6 +58,12 @@ springdoc-openapi-starter-webmvc-ui + + + org.aspectj + aspectjrt + + jakarta.servlet 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 new file mode 100644 index 00000000..186b5746 --- /dev/null +++ b/common/src/main/java/com/sdm/common/feign/impl/system/SysLogFeignClientImpl.java @@ -0,0 +1,36 @@ +package com.sdm.common.feign.impl.system; + +import com.alibaba.fastjson2.JSONObject; +import com.sdm.common.common.SdmResponse; +import com.sdm.common.feign.inter.system.ISysLogFeignClient; +import com.sdm.common.log.dto.SysLogDTO; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Optional; + + +@Slf4j +@Component +public class SysLogFeignClientImpl implements ISysLogFeignClient { + + @Autowired + private ISysLogFeignClient sysLogFeignClient; + + @Override + public SdmResponse saveLog(SysLogDTO req) { + SdmResponse response=null ; + try { + response = sysLogFeignClient.saveLog(req); + if(response==null || !response.isSuccess()){ + log.error("saveLog failed response:{}", JSONObject.toJSONString(Optional.ofNullable(response))); + return SdmResponse.failed("记录日志失败"); + } + } catch (Exception e) { + log.error("saveLog 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 new file mode 100644 index 00000000..d825747e --- /dev/null +++ b/common/src/main/java/com/sdm/common/feign/inter/system/ISysLogFeignClient.java @@ -0,0 +1,15 @@ +package com.sdm.common.feign.inter.system; + +import com.sdm.common.common.SdmResponse; +import com.sdm.common.log.dto.SysLogDTO; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + + +@FeignClient(name = "system",contextId = "systemLogClient") +public interface ISysLogFeignClient { + + @PostMapping("/systemLog/saveLog") + SdmResponse saveLog(@RequestBody SysLogDTO 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 new file mode 100644 index 00000000..a84973e6 --- /dev/null +++ b/common/src/main/java/com/sdm/common/log/annotation/SysLog.java @@ -0,0 +1,44 @@ +/* + * + * Copyright (c) 2018-2025, honeycom All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: honeycom + * + */ + +package com.sdm.common.log.annotation; + +import java.lang.annotation.*; + +/** + * 操作日志注解 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface SysLog { + + /** + * 描述 + * @return {String} + */ + String value() default ""; + + /** + * spel 表达式 + * @return 日志描述 + */ + String expression() default ""; + +} 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 new file mode 100644 index 00000000..f480aca8 --- /dev/null +++ b/common/src/main/java/com/sdm/common/log/aspect/SysLogAspect.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2020 pig4cloud Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sdm.common.log.aspect; + +import cn.hutool.core.util.StrUtil; +import com.sdm.common.common.ThreadLocalContext; +import com.sdm.common.log.annotation.SysLog; +import com.sdm.common.log.dto.SysLogDTO; +import com.sdm.common.log.event.SpringContextHolder; +import com.sdm.common.log.event.SysLogEvent; +import com.sdm.common.log.utils.LogTypeEnum; +import com.sdm.common.log.utils.SysLogUtils; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.stereotype.Component; + +/** + * 操作日志使用spring event异步入库 + */ +@Aspect +@Slf4j +@Component +@RequiredArgsConstructor +public class SysLogAspect { + + @Around("@annotation(sysLog)") + @SneakyThrows + public Object around(ProceedingJoinPoint point, SysLog sysLog) { + String strClassName = point.getTarget().getClass().getName(); + String strMethodName = point.getSignature().getName(); + log.debug("[类名]:{},[方法]:{}", strClassName, strMethodName); + + String value = sysLog.value(); + + SysLogDTO logVo = SysLogUtils.getSysLog(); + logVo.setTitle(value); + // 获取请求body参数 + if (StrUtil.isBlank(logVo.getParams())) { + logVo.setBody(point.getArgs()); + } + // 发送异步日志事件 + Long startTime = System.currentTimeMillis(); + Object obj; + + try { + obj = point.proceed(); + } + catch (Exception e) { + logVo.setLogType(LogTypeEnum.ERROR.getType()); + logVo.setException(e.getMessage()); + throw e; + } + finally { + Long endTime = System.currentTimeMillis(); + logVo.setTime(endTime - startTime); + logVo.setTenantId(ThreadLocalContext.getTenantId()); + SpringContextHolder.publishEvent(new SysLogEvent(logVo)); + } + + return obj; + } + +} diff --git a/common/src/main/java/com/sdm/common/log/config/SysLogProperties.java b/common/src/main/java/com/sdm/common/log/config/SysLogProperties.java new file mode 100644 index 00000000..5c16e333 --- /dev/null +++ b/common/src/main/java/com/sdm/common/log/config/SysLogProperties.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net). + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sdm.common.log.config; + +import lombok.Data; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 日志配置类 + * + */ +@Data +@Component +@ConfigurationProperties(prefix = "sys.log") +public class SysLogProperties { + + /** + * 开启日志记录 + */ + private boolean enabled = true; + + /** + * 记录请求报文体 + */ + private boolean requestEnabled = true; + + /** + * 放行字段,password,mobile,idcard,phone + */ + @Value("${log.exclude-fields:password,mobile,idcard,phone}") + private List excludeFields; + + /** + * 请求报文最大存储长度 + */ + private Integer maxLength = 2000; + +} 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 new file mode 100644 index 00000000..7f8f0844 --- /dev/null +++ b/common/src/main/java/com/sdm/common/log/dto/SysLogDTO.java @@ -0,0 +1,98 @@ +package com.sdm.common.log.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 日志查询传输对象 + */ +@Data +@Schema(description = "日志查询对象") +public class SysLogDTO { + + /** + * 编号 + */ + private Long id; + + /** + * 日志类型 + */ + @NotBlank(message = "日志类型不能为空") + private String logType; + + /** + * 日志标题 + */ + @NotBlank(message = "日志标题不能为空") + private String title; + + /** + * 创建者 + */ + private String createBy; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + /** + * 操作IP地址 + */ + private String remoteAddr; + + /** + * 用户代理 + */ + private String userAgent; + + /** + * 请求URI + */ + private String requestUri; + + /** + * 操作方式 + */ + private String method; + + /** + * 操作提交的数据 + */ + private String params; + + /** + * 参数重写成object + */ + private Object body; + + /** + * 执行时间 + */ + private Long time; + + /** + * 异常信息 + */ + private String exception; + + /** + * 服务ID + */ + private String serviceId; + + /** + * 创建时间区间 [开始时间,结束时间] + */ + private LocalDateTime[] createTime; + + /** + * 租户编号 + */ + private Long tenantId; + +} diff --git a/common/src/main/java/com/sdm/common/log/event/SpringContextHolder.java b/common/src/main/java/com/sdm/common/log/event/SpringContextHolder.java new file mode 100644 index 00000000..6b22081c --- /dev/null +++ b/common/src/main/java/com/sdm/common/log/event/SpringContextHolder.java @@ -0,0 +1,127 @@ +/* + * + * Copyright (c) 2018-2025, honeycom All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: honeycom + * + */ + +package com.sdm.common.log.event; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.ListableBeanFactory; +import org.springframework.beans.factory.config.BeanFactoryPostProcessor; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; + +import java.util.Map; + +/** + * @author honeycom + * Spring 工具类 + */ +@Slf4j +@Service +@Lazy(false) +public class SpringContextHolder implements BeanFactoryPostProcessor, ApplicationContextAware, DisposableBean { + + private static ConfigurableListableBeanFactory beanFactory; + + private static ApplicationContext applicationContext = null; + + /** + * 取得存储在静态变量中的ApplicationContext. + */ + public static ApplicationContext getApplicationContext() { + return applicationContext; + } + + /** + * BeanFactoryPostProcessor, 注入Context到静态变量中. + */ + @Override + public void postProcessBeanFactory(ConfigurableListableBeanFactory factory) throws BeansException { + SpringContextHolder.beanFactory = factory; + } + + /** + * 实现ApplicationContextAware接口, 注入Context到静态变量中. + */ + @Override + public void setApplicationContext(ApplicationContext applicationContext) { + SpringContextHolder.applicationContext = applicationContext; + } + + public static ListableBeanFactory getBeanFactory() { + return null == beanFactory ? applicationContext : beanFactory; + } + + /** + * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型. + */ + @SuppressWarnings("unchecked") + public static T getBean(String name) { + return (T) getBeanFactory().getBean(name); + } + + /** + * 从静态变量applicationContext中取得Bean, Map + */ + public static Map getBeansOfType(Class type) { + return getBeanFactory().getBeansOfType(type); + } + + /** + * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型. + */ + public static T getBean(Class requiredType) { + return getBeanFactory().getBean(requiredType); + } + + /** + * 清除SpringContextHolder中的ApplicationContext为Null. + */ + public static void clearHolder() { + if (log.isDebugEnabled()) { + log.debug("清除SpringContextHolder中的ApplicationContext:" + applicationContext); + } + applicationContext = null; + } + + /** + * 发布事件 + * @param event + */ + public static void publishEvent(ApplicationEvent event) { + if (applicationContext == null) { + return; + } + applicationContext.publishEvent(event); + } + + /** + * 实现DisposableBean接口, 在Context关闭时清理静态变量. + */ + @Override + public void destroy() { + SpringContextHolder.clearHolder(); + } + +} diff --git a/common/src/main/java/com/sdm/common/log/event/SysLogEvent.java b/common/src/main/java/com/sdm/common/log/event/SysLogEvent.java new file mode 100644 index 00000000..69a31671 --- /dev/null +++ b/common/src/main/java/com/sdm/common/log/event/SysLogEvent.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2020 pig4cloud Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sdm.common.log.event; + +import com.sdm.common.log.dto.SysLogDTO; +import org.springframework.context.ApplicationEvent; + +/** + * @author honeycom 系统日志事件 + */ +public class SysLogEvent extends ApplicationEvent { + + public SysLogEvent(SysLogDTO source) { + super(source); + } + +} 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 new file mode 100644 index 00000000..4fd00fe7 --- /dev/null +++ b/common/src/main/java/com/sdm/common/log/event/SysLogListener.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2020 pig4cloud Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sdm.common.log.event; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.fasterxml.jackson.annotation.JsonFilter; +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.inter.system.ISysLogFeignClient; +import com.sdm.common.log.config.SysLogProperties; +import com.sdm.common.log.dto.SysLogDTO; +import com.sdm.common.log.utils.JavaTimeModule; +import jakarta.servlet.ServletRequest; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.event.EventListener; +import org.springframework.core.annotation.Order; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; +import org.springframework.validation.BindingResult; + +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +/** + * @author honeycom 异步监听日志事件 + */ +@Slf4j +@RequiredArgsConstructor +@Component +public class SysLogListener implements InitializingBean { + + /** + * 忽略序列化的对象类型 + */ + private final static Class[] ignoreClass = { ServletRequest.class, BindingResult.class }; + + /** + * new 一个 避免日志脱敏策略影响全局ObjectMapper + */ + private final static ObjectMapper objectMapper = new ObjectMapper(); + + private final ISysLogFeignClient sysLogFeignClient; + + private final SysLogProperties logProperties; + + @SneakyThrows + @Async + @Order + @EventListener(SysLogEvent.class) + public void saveSysLog(SysLogEvent event) { + SysLogDTO source = (SysLogDTO) event.getSource(); + + // json 格式刷参数放在异步中处理,提升性能 + if (Objects.nonNull(source.getBody()) && logProperties.isRequestEnabled()) { + Object[] args = (Object[]) source.getBody(); + List list = CollUtil.toList(args); + // 删除部分无法序列化的参数 + list.removeIf(obj -> Arrays.stream(ignoreClass).anyMatch(clazz -> clazz.isAssignableFrom(obj.getClass()))); + + try { + // 序列化参数 + String params = objectMapper.writeValueAsString(list); + source.setParams(StrUtil.subPre(params, logProperties.getMaxLength())); + } + catch (Exception e) { + log.error("请求参数序列化异常:{}", e.getMessage()); + } + } + + source.setBody(null); + sysLogFeignClient.saveLog(source); + } + + @Override + public void afterPropertiesSet() { + objectMapper.addMixIn(Object.class, PropertyFilterMixIn.class); + String[] ignorableFieldNames = logProperties.getExcludeFields().toArray(new String[0]); + + FilterProvider filters = new SimpleFilterProvider().addFilter("filter properties by name", + SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames)); + objectMapper.setFilterProvider(filters); + objectMapper.registerModule(new JavaTimeModule()); + } + + @JsonFilter("filter properties by name") + class PropertyFilterMixIn { + + } + +} diff --git a/common/src/main/java/com/sdm/common/log/utils/JavaTimeModule.java b/common/src/main/java/com/sdm/common/log/utils/JavaTimeModule.java new file mode 100644 index 00000000..c6ab38eb --- /dev/null +++ b/common/src/main/java/com/sdm/common/log/utils/JavaTimeModule.java @@ -0,0 +1,61 @@ +package com.sdm.common.log.utils; + +import cn.hutool.core.date.DatePattern; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.datatype.jsr310.PackageVersion; +import com.fasterxml.jackson.datatype.jsr310.deser.InstantDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.InstantSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; + +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; + +/** + * java 8 时间默认序列化 + */ +public class JavaTimeModule extends SimpleModule { + + /** + * 指定序列化规则 + */ + public JavaTimeModule() { + super(PackageVersion.VERSION); + + // ======================= 时间序列化规则 =============================== + // yyyy-MM-dd HH:mm:ss + this.addSerializer(LocalDateTime.class, + new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN))); + // yyyy-MM-dd + this.addSerializer(LocalDate.class, + new LocalDateSerializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN))); + // HH:mm:ss + this.addSerializer(LocalTime.class, + new LocalTimeSerializer(DateTimeFormatter.ofPattern(DatePattern.NORM_TIME_PATTERN))); + + // Instant 类型序列化 + this.addSerializer(Instant.class, InstantSerializer.INSTANCE); + + // ======================= 时间反序列化规则 ============================== + // yyyy-MM-dd HH:mm:ss + this.addDeserializer(LocalDateTime.class, + new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN))); + // yyyy-MM-dd + this.addDeserializer(LocalDate.class, + new LocalDateDeserializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN))); + // HH:mm:ss + this.addDeserializer(LocalTime.class, + new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DatePattern.NORM_TIME_PATTERN))); + // Instant 反序列化 + this.addDeserializer(Instant.class, InstantDeserializer.INSTANT); + + } + +} diff --git a/common/src/main/java/com/sdm/common/log/utils/LogTypeEnum.java b/common/src/main/java/com/sdm/common/log/utils/LogTypeEnum.java new file mode 100644 index 00000000..95943ee6 --- /dev/null +++ b/common/src/main/java/com/sdm/common/log/utils/LogTypeEnum.java @@ -0,0 +1,33 @@ +package com.sdm.common.log.utils; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + * 日志类型 + */ +@Getter +@RequiredArgsConstructor +public enum LogTypeEnum { + + /** + * 正常日志类型 + */ + NORMAL("0", "正常日志"), + + /** + * 错误日志类型 + */ + ERROR("9", "错误日志"); + + /** + * 类型 + */ + private final String type; + + /** + * 描述 + */ + private final String description; + +} \ No newline at end of file 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 new file mode 100644 index 00000000..5254106f --- /dev/null +++ b/common/src/main/java/com/sdm/common/log/utils/SysLogUtils.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2020 pig4cloud Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sdm.common.log.utils; + +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.URLUtil; +import cn.hutool.extra.servlet.JakartaServletUtil; +import cn.hutool.extra.spring.SpringUtil; +import cn.hutool.http.HttpUtil; +import com.sdm.common.common.ThreadLocalContext; +import com.sdm.common.log.config.SysLogProperties; +import com.sdm.common.log.dto.SysLogDTO; +import com.sdm.common.utils.DateUtils; +import jakarta.servlet.http.HttpServletRequest; +import lombok.experimental.UtilityClass; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.expression.EvaluationContext; +import org.springframework.expression.Expression; +import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.http.HttpHeaders; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import java.time.LocalDateTime; +import java.util.Map; +import java.util.Objects; + +/** + * 系统日志工具类 + * + * @author L.cm + */ +@UtilityClass +public class SysLogUtils { + + public SysLogDTO getSysLog() { + HttpServletRequest request = ((ServletRequestAttributes) Objects + .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(ObjectUtils.isNotEmpty(ThreadLocalContext.getUserName()) ? ThreadLocalContext.getUserName() : "anonymousUser"); + // 获取服务名称 + sysLog.setServiceId("simulation-" + SpringUtil.getProperty("spring.application.name")); + + // get 参数脱敏 + SysLogProperties logProperties = SpringUtil.getBean(SysLogProperties.class); + Map paramsMap = MapUtil.removeAny(request.getParameterMap(), ArrayUtil.toArray(logProperties.getExcludeFields(), String.class)); + sysLog.setParams(HttpUtil.toParams(paramsMap)); + return sysLog; + } + + /** + * 获取spel 定义的参数值 + * @param context 参数容器 + * @param key key + * @param clazz 需要返回的类型 + * @param 返回泛型 + * @return 参数值 + */ + public T getValue(EvaluationContext context, String key, Class clazz) { + SpelExpressionParser spelExpressionParser = new SpelExpressionParser(); + Expression expression = spelExpressionParser.parseExpression(key); + return expression.getValue(context, clazz); + } + + +} 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 17f9a320..eb288988 100644 --- a/data/src/main/java/com/sdm/data/controller/DataFileController.java +++ b/data/src/main/java/com/sdm/data/controller/DataFileController.java @@ -8,6 +8,7 @@ import com.sdm.common.entity.resp.data.BatchAddFileInfoResp; import com.sdm.common.entity.resp.data.ChunkUploadMinioFileResp; import com.sdm.common.entity.resp.data.FileMetadataInfoResp; import com.sdm.common.feign.inter.data.IDataFeignClient; +import com.sdm.common.log.annotation.SysLog; import com.sdm.data.model.entity.FileMetadataInfo; import com.sdm.data.model.req.*; import com.sdm.data.model.resp.KKFileViewURLFromMinioResp; @@ -162,6 +163,7 @@ public class DataFileController implements IDataFeignClient { * @param req * @return */ + @SysLog("更新用户权限") @PostMapping("/updatePermission") @Operation(summary = "更新用户权限", description = "更新用户对指定文件或文件夹的权限") public SdmResponse updatePermission(@RequestBody @Validated UpdatePermissionReq req) { 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 f5ef6cb5..be5fb884 100644 --- a/data/src/main/java/com/sdm/data/controller/DataStorageAnalysisController.java +++ b/data/src/main/java/com/sdm/data/controller/DataStorageAnalysisController.java @@ -3,6 +3,7 @@ package com.sdm.data.controller; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.sdm.common.common.SdmResponse; import com.sdm.common.entity.resp.PageDataResp; +import com.sdm.common.log.annotation.SysLog; import com.sdm.data.model.entity.FileStorage; import com.sdm.data.model.req.AddUserQuotaEntity; import com.sdm.data.model.req.ListUserQuotaReq; @@ -85,6 +86,7 @@ public class DataStorageAnalysisController { } //新增用户配额 + @SysLog("新增用户配额") @PostMapping("/addUserQuota") @Operation(summary = "新增用户配额") public SdmResponse addUserQuota(@RequestBody AddUserQuotaEntity addUserQuota){ @@ -96,7 +98,9 @@ public class DataStorageAnalysisController { public SdmResponse listUserQuota(@RequestBody ListUserQuotaReq listUserQuotaReq){ return dataStorageAnalysis.listUserQuota(listUserQuotaReq); } + //批量修改用户配额 + @SysLog("批量修改用户配额") @PostMapping("/batchUpdateUserQuota") @Operation(summary = "批量修改用户配额") public SdmResponse batchUpdateUserQuota(@RequestBody List addUserQuota){ diff --git a/data/src/main/java/com/sdm/data/controller/DimensionTemplateController.java b/data/src/main/java/com/sdm/data/controller/DimensionTemplateController.java index 4cf17499..eeda8b40 100644 --- a/data/src/main/java/com/sdm/data/controller/DimensionTemplateController.java +++ b/data/src/main/java/com/sdm/data/controller/DimensionTemplateController.java @@ -3,6 +3,7 @@ package com.sdm.data.controller; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.sdm.common.common.SdmResponse; +import com.sdm.common.log.annotation.SysLog; import com.sdm.data.model.req.dimensionTemplate.TemplateCreationRequest; import com.sdm.data.service.IDimensionTemplateService; import io.swagger.v3.oas.annotations.Operation; @@ -35,6 +36,7 @@ public class DimensionTemplateController { * @param request 包含模板信息和层级列表的请求参数 * @return 是否创建成功 */ + @SysLog("创建或更新模板及层级信息") @PostMapping("/saveTemplateWithHierarchies") @Operation(summary = "创建或更新模板及层级信息", description = "根据请求参数中的ID判断是创建还是更新维度模板及层级信息") public SdmResponse saveTemplateWithHierarchies(@Valid @RequestBody @Parameter(description = "包含模板信息和层级列表的请求参数") TemplateCreationRequest request) { @@ -87,6 +89,7 @@ public class DimensionTemplateController { * @return 返回操作结果的SdmResponse对象 * @throws RuntimeException 如果删除过程中发生异常,则抛出RuntimeException异常 */ + @SysLog("删除模板及层级信息") @GetMapping("/deleteTemplateWithHierarchies") @Operation(summary = "删除模板及层级信息", description = "根据给定的模板ID,删除该模板及其相关的层级关系数据") public SdmResponse deleteTemplateWithHierarchies(@RequestParam("id") @Parameter(description = "维度模板ID") Long id) { diff --git a/data/src/main/java/com/sdm/data/controller/FileSimulationMappingController.java b/data/src/main/java/com/sdm/data/controller/FileSimulationMappingController.java index 1e8bfdf9..a69b68a0 100644 --- a/data/src/main/java/com/sdm/data/controller/FileSimulationMappingController.java +++ b/data/src/main/java/com/sdm/data/controller/FileSimulationMappingController.java @@ -6,6 +6,7 @@ import com.sdm.common.entity.req.data.GetFileSimulationMappingReq; import com.sdm.common.entity.resp.data.FileMetadataInfoResp; import com.sdm.common.feign.inter.data.IFileSimulationMappingFeignClient; import com.sdm.common.entity.req.data.SaveFileSimulationMappingReq; +import com.sdm.common.log.annotation.SysLog; import com.sdm.data.service.IFileSimulationMappingService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; @@ -33,6 +34,7 @@ public class FileSimulationMappingController implements IFileSimulationMappingFe /** * 保存工况任务与文件绑定关系 */ + @SysLog("保存工况任务与文件绑定关系") @PostMapping("/saveFileSimulationMapping") public SdmResponse batchSaveFileSimulationMapping(@RequestBody List saveFileSimulationMappingReq) { return fileSimulationMappingService.batchSaveFileSimulationMapping(saveFileSimulationMappingReq); 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 b837c3b2..93cddc4e 100644 --- a/data/src/main/java/com/sdm/data/controller/ModelTraningController.java +++ b/data/src/main/java/com/sdm/data/controller/ModelTraningController.java @@ -3,6 +3,7 @@ package com.sdm.data.controller; import com.sdm.common.common.SdmResponse; import com.sdm.common.entity.req.data.BaseReq; import com.sdm.common.entity.req.data.ModelExportExcelFormat; +import com.sdm.common.log.annotation.SysLog; import com.sdm.data.model.req.*; import com.sdm.data.service.IModelService; import io.swagger.v3.oas.annotations.Operation; @@ -25,6 +26,7 @@ public class ModelTraningController { /** * 新增训练模型 */ + @SysLog("新增训练模型") @PostMapping("/addModel") @Operation(summary = "新增训练模型", description = "新增训练模型") public SdmResponse addModel(@RequestBody AddModelReq addModelReq) { @@ -34,6 +36,7 @@ public class ModelTraningController { /** * 删除模型 */ + @SysLog("删除模型") @GetMapping("/deleteModel") @Operation(summary = "删除模型", description = "删除模型") public SdmResponse deleteModel(@RequestParam Long modelId) { @@ -61,6 +64,7 @@ public class ModelTraningController { /** * 修改模型 */ + @SysLog("修改模型") @PostMapping("/updateModel") @Operation(summary = "修改模型", description = "修改模型") public SdmResponse updateModel(@RequestBody AddModelReq addModelReq) { @@ -88,6 +92,7 @@ public class ModelTraningController { /** * 设置训练数据输入输出特征列 */ + @SysLog("设置训练数据输入输出特征列") @PostMapping("/setTrainingDataInPutOutPutColumn") @Operation(summary = "设置训练数据输入输出特征列", description = "设置训练数据输入输出特征列") public SdmResponse setTrainingDataInPutOutPutColumn(@RequestBody SetTrainingDataInPutOutPutColumnReq req) { @@ -106,6 +111,7 @@ public class ModelTraningController { /** * 算法参数设置并提交训练 */ + @SysLog("算法参数设置并提交训练") @PostMapping("/submitTraining") @Operation(summary = "算法参数设置并提交训练", description = "算法参数设置并提交训练") public SdmResponse submitTraining(@RequestBody AlgorithmParamReq algorithmParamReq) { @@ -124,6 +130,7 @@ public class ModelTraningController { /** * 停止模型训练 */ + @SysLog("停止模型训练") @GetMapping("/stopTraining") @Operation(summary = "停止模型训练", description = "停止模型训练") public SdmResponse stopTraining(@RequestParam Long modelId) { @@ -144,6 +151,7 @@ public class ModelTraningController { /** * 开始数据预测 */ + @SysLog("数据预测") @PostMapping("/startPredict") @Operation(summary = "数据预测", description = "数据预测") public SdmResponse startPredict(@Parameter(description = "数据预测请求对象") @RequestBody ModelPredictReq modelPredictReq) { 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 f7fc563e..7ccf69af 100644 --- a/data/src/main/java/com/sdm/data/controller/SimulationParameterLibraryController.java +++ b/data/src/main/java/com/sdm/data/controller/SimulationParameterLibraryController.java @@ -2,6 +2,7 @@ package com.sdm.data.controller; import com.sdm.common.common.SdmResponse; +import com.sdm.common.log.annotation.SysLog; import com.sdm.data.model.req.SimulationParamLibraryReq; import com.sdm.data.model.req.SimulationParameterLibraryCategoryObjectReq; import com.sdm.data.model.resp.SimulationParameterLibraryCategoryObjectResp; @@ -35,6 +36,7 @@ public class SimulationParameterLibraryController { * @param parameterLibraryName 仿真参数库名 * @return 添加结果 */ + @SysLog("添加仿真参数库") @GetMapping("/addLibrary") @Operation(summary = "添加仿真参数库", description = "添加新的仿真参数库") public SdmResponse addLibrary(@Parameter(description = "仿真参数库名") @RequestParam(value = "parameterLibraryName") String parameterLibraryName) { @@ -44,6 +46,7 @@ public class SimulationParameterLibraryController { /** * 添加仿真参数库分类 */ + @SysLog("添加仿真参数库分类") @GetMapping("/addLibraryCategory") @Operation(summary = "添加仿真参数库分类", description = "添加新的仿真参数库分类") public SdmResponse addLibraryCategory(@Parameter(description = "仿真参数库ID") @RequestParam(value = "parameterLibraryId") Long parameterLibraryId, @Parameter(description = "仿真参数库分类名") @RequestParam(value = "parameterLibraryCategoryName") String parameterLibraryCategoryName) { @@ -53,6 +56,7 @@ public class SimulationParameterLibraryController { /** * 添加仿真参数库分类的参数对象 */ + @SysLog("添加仿真参数库分类的参数对象") @PostMapping(value = "/addLibraryCategoryObject", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @Operation(summary = "添加仿真参数库分类的参数对象", description = "添加新的仿真参数库分类的参数对象") public SdmResponse addLibraryCategoryObject(SimulationParameterLibraryCategoryObjectReq simulationParameterLibraryCategoryObjectReq) { @@ -72,6 +76,7 @@ public class SimulationParameterLibraryController { * 编辑仿真参数库、仿真参数库分类、真参数库分类的参数对象的名称 * @return */ + @SysLog("编辑仿真参数库、仿真参数库分类、真参数库分类的参数对象的名称") @PostMapping("/editSimulationParameter") @Operation(summary = "编辑仿真参数库、仿真参数库分类、真参数库分类的参数对象的名称", description = "编辑仿真参数库、仿真参数库分类、真参数库分类的参数对象的名称") SdmResponse editSimulationParameter(@RequestBody SimulationParamLibraryReq req) { @@ -83,6 +88,7 @@ public class SimulationParameterLibraryController { * * @return */ + @SysLog("删除仿真参数库数据") @PostMapping("/deleteSimulationParameter") @Operation(summary = "删除仿真参数库数据", description = "删除仿真参数库数据") SdmResponse deleteSimulationParameter(@RequestBody SimulationParamLibraryReq req) { 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 99cd98a5..1a1a3f27 100644 --- a/project/src/main/java/com/sdm/project/controller/SimulationAnalysisController.java +++ b/project/src/main/java/com/sdm/project/controller/SimulationAnalysisController.java @@ -1,6 +1,7 @@ package com.sdm.project.controller; import com.sdm.common.common.SdmResponse; +import com.sdm.common.log.annotation.SysLog; import com.sdm.project.model.req.SpdmAnalysisPerformanceListReq; import com.sdm.project.model.req.SpdmAnalysisRunListReq; import com.sdm.project.model.req.SpdmAnalysisTaskListReq; @@ -30,6 +31,7 @@ public class SimulationAnalysisController { * @param req * @return */ + @SysLog("数据分析(数据查询)-根据节点id获取仿真工况") @GetMapping("/taskList") @Operation(summary = "仿真工况", description = "仿真工况") public SdmResponse taskList(SpdmAnalysisTaskListReq req) { @@ -42,6 +44,7 @@ public class SimulationAnalysisController { * @param req * @return */ + @SysLog("数据分析(数据查询)-根据节点id获取指标") @GetMapping("/performanceList") @Operation(summary = "指标", description = "指标") public SdmResponse performanceList(SpdmAnalysisPerformanceListReq req) { @@ -54,6 +57,7 @@ public class SimulationAnalysisController { * @param req * @return */ + @SysLog("数据分析(数据查询)-根据节点id获取算例") @GetMapping("/runList") @Operation(summary = "算例", description = "算例") public SdmResponse runList(SpdmAnalysisRunListReq req) { @@ -64,6 +68,7 @@ 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 a4cda20d..f76b8df2 100644 --- a/project/src/main/java/com/sdm/project/controller/SimulationDemandController.java +++ b/project/src/main/java/com/sdm/project/controller/SimulationDemandController.java @@ -5,6 +5,7 @@ import com.sdm.common.entity.req.data.UploadFilesReq; import com.sdm.common.entity.req.task.DemandExportExcelFormat; import com.sdm.common.entity.req.task.TaskExportExcelFormat; import com.sdm.common.feign.inter.data.IDataFeignClient; +import com.sdm.common.log.annotation.SysLog; import com.sdm.project.model.bo.ModifyProjectNode; import com.sdm.project.model.req.*; import com.sdm.project.service.IDemandService; @@ -33,6 +34,7 @@ public class SimulationDemandController { * @param req * @return */ + @SysLog("新增需求") @PostMapping("/addDemand") @Operation(summary = "新增需求", description = "新增需求") public SdmResponse addDemand(@RequestBody @Validated SpdmAddDemandReq req) { @@ -45,6 +47,7 @@ public class SimulationDemandController { * @param req * @return */ + @SysLog("修改需求") @PostMapping("/editDemand") @Operation(summary = "修改需求", description = "修改需求") public SdmResponse editDemand(@RequestBody SpdmEditDemandReq req) { @@ -57,6 +60,7 @@ public class SimulationDemandController { * @param req * @return */ + @SysLog("删除需求") @PostMapping("/deleteDemand") @Operation(summary = "删除需求", description = "删除需求") public SdmResponse deleteDemand(@RequestBody @Validated SpdmDeleteDemandReq req) { @@ -81,6 +85,7 @@ public class SimulationDemandController { * @param req * @return */ + @SysLog("下发任务") @PostMapping("/issueTask") @Operation(summary = "下发任务(可批量)", description = "下发任务(可批量)") public SdmResponse issueTask(@RequestBody SpdmTaskIssue 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 620e13fe..09c76852 100644 --- a/project/src/main/java/com/sdm/project/controller/SimulationNodeController.java +++ b/project/src/main/java/com/sdm/project/controller/SimulationNodeController.java @@ -7,10 +7,10 @@ import com.sdm.common.entity.req.project.DelNodeReq; import com.sdm.common.entity.req.project.ProjectExportExcelFormat; import com.sdm.common.entity.req.project.RenameNodeReq; import com.sdm.common.entity.req.project.SpdmNodeListReq; -import com.sdm.common.entity.req.task.TaskExportExcelFormat; import com.sdm.common.entity.resp.AllNodeByProjectIdAndTypeResp; import com.sdm.common.entity.resp.project.SimulationNodeResp; import com.sdm.common.feign.inter.project.ISimulationNodeFeignClient; +import com.sdm.common.log.annotation.SysLog; import com.sdm.project.model.req.*; import com.sdm.project.service.INodeService; import io.swagger.v3.oas.annotations.Operation; @@ -40,6 +40,7 @@ public class SimulationNodeController implements ISimulationNodeFeignClient { * @param req * @return */ + @SysLog("新增节点") @PostMapping("/addNode") @Operation(summary = "新增项目或阶段", description = "新增项目或阶段") public SdmResponse addNode(@RequestBody @Validated SpdmAddNodeReq req) { @@ -52,6 +53,7 @@ public class SimulationNodeController implements ISimulationNodeFeignClient { * @param req * @return */ + @SysLog("修改节点") @PostMapping("/editNode") @Operation(summary = "修改项目或阶段", description = "修改项目或阶段") public SdmResponse editNode(@RequestBody @Validated SpdmEditNodeReq req) { @@ -64,6 +66,7 @@ public class SimulationNodeController implements ISimulationNodeFeignClient { * @param req * @return */ + @SysLog("删除节点") @PostMapping("/deleteNode") @Operation(summary = "删除项目或阶段", description = "删除项目或阶段") public SdmResponse deleteNode(@RequestBody SpdmDeleteNodeReq 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 1de55ac7..b6a19313 100644 --- a/project/src/main/java/com/sdm/project/controller/SimulationRunController.java +++ b/project/src/main/java/com/sdm/project/controller/SimulationRunController.java @@ -11,6 +11,7 @@ import com.sdm.common.entity.resp.PageDataResp; 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.project.model.entity.SimulationRun; import com.sdm.project.model.entity.SimulationRunKeyResult; import com.sdm.project.model.req.*; @@ -55,6 +56,7 @@ public class SimulationRunController implements ISimulationRunFeignClient { /** * 任务执行 创建算例 */ + @SysLog("任务执行 创建算例") @PostMapping("/addTaskRun") public SdmResponse addTaskRun(@RequestBody @Validated SpdmAddTaskRunReq req) { return runService.addTaskRun(req); @@ -63,6 +65,7 @@ public class SimulationRunController implements ISimulationRunFeignClient { /** * 任务执行 删除算例 */ + @SysLog("任务执行 删除算例") @PostMapping("/deleteTaskRun") public SdmResponse deleteTaskRun(@RequestBody SpdmTaskRunReq req) { return runService.deleteTaskRun(req); @@ -125,6 +128,7 @@ public class SimulationRunController implements ISimulationRunFeignClient { * * @return */ + @SysLog("任务执行后 算例录入关键结果") @PostMapping(value = "/addSimulationKeyResult", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public SdmResponse addSimulationKeyResult(KeyResultReq req) { return runService.addSimulationKeyResult(req); @@ -135,6 +139,7 @@ public class SimulationRunController implements ISimulationRunFeignClient { * * @return */ + @SysLog("上传交付物-文件信息和关键结果信息批量入库") @PostMapping(value = "/batchAddSimulationKeyResult") public SdmResponse> batchAddSimulationKeyResult(@RequestBody KeyResultReq req) { return runService.batchAddSimulationKeyResult(req); @@ -145,6 +150,7 @@ public class SimulationRunController implements ISimulationRunFeignClient { * * @return */ + @SysLog("提交交付物审批") @PostMapping(value = "/deliverableApprove") public SdmResponse deliverableApprove(@RequestBody DeliverableApproveReq req) { return runService.deliverableApprove(req); @@ -155,6 +161,7 @@ public class SimulationRunController implements ISimulationRunFeignClient { * * @return */ + @SysLog("交付物审批回调") @PostMapping(value = "/deliverableApproveCallback") public SdmResponse deliverableApproveCallback(@RequestBody LaunchApproveReq req) { return runService.deliverableApproveCallback(req); @@ -185,6 +192,7 @@ public class SimulationRunController implements ISimulationRunFeignClient { * * @return */ + @SysLog("删除算例关键结果") @PostMapping(value = "/deleteSimulationKeyResult") public SdmResponse deleteSimulationKeyResult(@RequestBody KeyResultReq req) { return runService.deleteSimulationKeyResult(req); @@ -204,6 +212,7 @@ public class SimulationRunController implements ISimulationRunFeignClient { /** * 任务执行 一键执行 启动流程 */ + @SysLog("任务执行 一键执行 启动流程") @PostMapping("/startProcessInstance") public SdmResponse startProcessInstance(@RequestBody SpdmTaskRunReq req) { return runService.startProcessInstance(req); diff --git a/project/src/main/java/com/sdm/project/service/impl/NodeServiceImpl.java b/project/src/main/java/com/sdm/project/service/impl/NodeServiceImpl.java index b5b5db83..b9cfe76b 100644 --- a/project/src/main/java/com/sdm/project/service/impl/NodeServiceImpl.java +++ b/project/src/main/java/com/sdm/project/service/impl/NodeServiceImpl.java @@ -2,8 +2,6 @@ package com.sdm.project.service.impl; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.sdm.common.common.ResultCode; import com.sdm.common.common.SdmResponse; @@ -44,11 +42,9 @@ import com.sdm.project.model.entity.SimulationTask; import com.sdm.project.model.entity.SimulationTaskMember; import com.sdm.project.model.po.PerformanceNodePo; import com.sdm.project.model.po.ProjectNodePo; -import com.sdm.project.model.po.TaskNodeExtraPo; import com.sdm.project.model.po.TaskNodePo; import com.sdm.project.model.req.*; import com.sdm.project.model.req.YA.SyncCidProjectReq; -import com.sdm.project.model.resp.YA.BosimSaveNodeInfoRsp; import com.sdm.project.model.resp.YA.BosimSaveProjectTaskRsp; import com.sdm.project.model.vo.*; import com.sdm.project.service.*; @@ -58,7 +54,6 @@ import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.MapUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; -import org.jetbrains.annotations.Nullable; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -68,7 +63,6 @@ import org.springframework.transaction.interceptor.TransactionAspectSupport; import javax.annotation.Resource; import java.lang.reflect.Field; -import java.sql.Wrapper; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; diff --git a/system/src/main/java/com/sdm/system/controller/SystemLogController.java b/system/src/main/java/com/sdm/system/controller/SystemLogController.java new file mode 100644 index 00000000..339104d9 --- /dev/null +++ b/system/src/main/java/com/sdm/system/controller/SystemLogController.java @@ -0,0 +1,36 @@ +package com.sdm.system.controller; + +import com.sdm.common.common.SdmResponse; +import com.sdm.common.feign.inter.system.ISysLogFeignClient; +import com.sdm.common.log.dto.SysLogDTO; +import com.sdm.system.service.ISimulationLogService; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + *

+ * 消息通知 + *

+ * + */ +@Slf4j +@RestController +@RequestMapping("/systemLog") +@Tag(name = "系统评审") +public class SystemLogController implements ISysLogFeignClient { + + @Autowired + private ISimulationLogService logService; + + @PostMapping("/saveLog") + public SdmResponse saveLog(@RequestBody SysLogDTO req) + { + return logService.saveLog(req); + } + +} diff --git a/system/src/main/java/com/sdm/system/service/ISimulationLogService.java b/system/src/main/java/com/sdm/system/service/ISimulationLogService.java new file mode 100644 index 00000000..db5204b0 --- /dev/null +++ b/system/src/main/java/com/sdm/system/service/ISimulationLogService.java @@ -0,0 +1,11 @@ +package com.sdm.system.service; + +import com.sdm.common.common.SdmResponse; +import com.sdm.common.log.dto.SysLogDTO; +import org.springframework.web.bind.annotation.RequestBody; + +public interface ISimulationLogService { + + SdmResponse saveLog(@RequestBody SysLogDTO req); + +} diff --git a/system/src/main/java/com/sdm/system/service/impl/SimulationLogServiceImpl.java b/system/src/main/java/com/sdm/system/service/impl/SimulationLogServiceImpl.java new file mode 100644 index 00000000..6e8db2d5 --- /dev/null +++ b/system/src/main/java/com/sdm/system/service/impl/SimulationLogServiceImpl.java @@ -0,0 +1,44 @@ +package com.sdm.system.service.impl; + +import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson2.JSON; +import com.sdm.common.common.SdmResponse; +import com.sdm.common.log.dto.SysLogDTO; +import com.sdm.common.utils.HttpClientUtil; +import com.sdm.system.service.ISimulationLogService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +@Service +@Slf4j +public class SimulationLogServiceImpl implements ISimulationLogService { + + @Value("${cid.url}") + private String cidUrl; + + @Value("${cid.log.saveLog}") + private String saveLogPath; + + @Autowired + private HttpClientUtil httpClientUtil; + + @Override + public SdmResponse saveLog(SysLogDTO req) { + String url = cidUrl + saveLogPath; + try { + log.info("[saveLog] url:{}, param:{}", url, JSONUtil.toJsonStr(req)); + String resultString = httpClientUtil.doPostJson(url, JSON.toJSONString(req)); + SdmResponse response = JSON.parseObject(resultString, SdmResponse.class); + if (response.isSuccess()) { + return response; + } + return SdmResponse.failed("保存日志失败:"); + } catch (Exception e) { + log.error("保存日志失败", e); + return SdmResponse.failed("保存日志失败"); + } + } + +} diff --git a/system/src/main/resources/application-dev.yml b/system/src/main/resources/application-dev.yml index ed101625..7dc4b95b 100644 --- a/system/src/main/resources/application-dev.yml +++ b/system/src/main/resources/application-dev.yml @@ -168,4 +168,6 @@ cid: # 批量查询的cid 接口,配合上面url使用 batchInterfacePath: /spdm-flow/listFlowNodeDetail msg: - sendMessage: /spdm-msg/sendMessage \ No newline at end of file + sendMessage: /spdm-msg/sendMessage + log: + saveLog: /spdm-log/saveLog \ No newline at end of file diff --git a/system/src/main/resources/application-local.yml b/system/src/main/resources/application-local.yml index 38ad281d..93cd950d 100644 --- a/system/src/main/resources/application-local.yml +++ b/system/src/main/resources/application-local.yml @@ -169,6 +169,8 @@ cid: batchInterfacePath: /spdm-flow/listFlowNodeDetail msg: sendMessage: /spdm-msg/sendMessage + log: + saveLog: /spdm-log/saveLog # 0单机处理,可以指向本地,1负载均衡轮询 serverType: 0 diff --git a/system/src/main/resources/application-prod.yml b/system/src/main/resources/application-prod.yml index 0fc8aae5..de92d899 100644 --- a/system/src/main/resources/application-prod.yml +++ b/system/src/main/resources/application-prod.yml @@ -180,4 +180,6 @@ cid: # 批量查询的cid 接口,配合上面url使用 batchInterfacePath: /spdm-flow/listFlowNodeDetail msg: - sendMessage: /spdm-msg/sendMessage \ No newline at end of file + sendMessage: /spdm-msg/sendMessage + log: + saveLog: /spdm-log/saveLog \ No newline at end of file