范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

SpringBoot利用AOP写一个日志管理

  1. 需求
  目前有这么个问题,有两个系统CSP和OMS,这俩系统共用的是同一套日志操作:Log;目前想区分下这俩系统的日志操作,那没办法了,只能重写一份Log的日志操作;
  你也可以参照若依框架的日志系统实现。  2. 新建一张日志表
  sys_oper_csp_log  /*  Navicat Premium Data Transfer   Source Server         : jp-csc-admin  Source Server Type    : MySQL  Source Server Version : 50728  Source Host           : rm-uf6miy84gu8u433x9.mysql.rds.aliyuncs.com:3306  Source Schema         : jp_oms   Target Server Type    : MySQL  Target Server Version : 50728  File Encoding         : 65001   Date: 08/09/2022 09:21:45 */  SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0;  -- ---------------------------- -- Table structure for sys_oper_csp_log -- ---------------------------- DROP TABLE IF EXISTS `sys_oper_csp_log`; CREATE TABLE `sys_oper_csp_log`  (   `oper_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT "日志主键",   `title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT "" COMMENT "模块标题",   `business_type` int(2) NULL DEFAULT 0 COMMENT "业务类型(0=其它,1=新增,2=修改,3=删除,4=授权,5=导出,6=导入,7=强退,8=生成代码,9=清空数据)",   `method` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT "" COMMENT "方法名称",   `request_method` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT "" COMMENT "请求方式",   `operator_type` int(1) NULL DEFAULT 0 COMMENT "操作类别(0其它 1后台用户 2手机端用户)",   `oper_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT "" COMMENT "操作人员",   `dept_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT "" COMMENT "部门名称",   `oper_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT "" COMMENT "请求URL",   `oper_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT "" COMMENT "主机地址",   `oper_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT "" COMMENT "操作地点",   `oper_param` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT "" COMMENT "请求参数",   `json_result` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT "返回参数",   `status` int(1) NULL DEFAULT 0 COMMENT "操作状态(0正常 1异常)",   `error_msg` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT "" COMMENT "错误消息",   `oper_time` datetime NULL DEFAULT NULL COMMENT "操作时间",   PRIMARY KEY (`oper_id`) USING BTREE,   INDEX `idx_time`(`oper_time`, `title`, `oper_name`) USING BTREE ) ENGINE = InnoD CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = "CSP系统操作日志记录";3. 写相应的Controller层package com.juepeiscm.csp.controller.csplog;  import com.juepeiscm.admin.api.domain.SysOperLog; import com.juepeiscm.common.core.controller.BaseController; import com.juepeiscm.common.core.domain.AjaxResult; import com.juepeiscm.common.core.page.TableDataInfo; import com.juepeiscm.common.enums.BusinessType; import com.juepeiscm.common.utils.poi.ExcelUtil; import com.juepeiscm.csp.annotation.CspLog; import com.juepeiscm.csp.domain.csplog.SysOperCspLog; import com.juepeiscm.csp.service.csplog.ISysOperCspLogService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*;  import java.util.List;  /**  * 操作CSP系统日志  * @Author: py.sun  * @Date: 2022/9/7 14:51  */ @RestController @RequestMapping({  "/csplog/opercsplog"}) public class SysOperCsplogController extends BaseController {       @Autowired     private ISysOperCspLogService operCspLogService;      public SysOperCsplogController() {       }      /**      * 查询操作日志列表      * @param sysOperCspLog      * @return      */     @PreAuthorize("@ss.hasPermi("monitor:operlog:list")")     @GetMapping({  "/list"})     public TableDataInfo list(SysOperCspLog sysOperCspLog) {           this.startPage();         List list = this.operCspLogService.selectOperLogList(sysOperCspLog);         return this.getDataTable(list);     }      /**      * 查询系统模块的分类      * @param      * @return      */     @GetMapping({  "/listTitle"})     public TableDataInfo listTitle() {           this.startPage();         List list = this.operCspLogService.selectOperLogListTitle();         return this.getDataTable(list);     }      @CspLog(             title = "导出CSP系统日志",             businessType = BusinessType.EXPORT     )     @PreAuthorize("@ss.hasPermi("monitor:operlog:export")")     @GetMapping({  "/export"})     public AjaxResult export(SysOperCspLog operLog) {           List list = this.operCspLogService.selectOperLogList(operLog);         ExcelUtil util = new ExcelUtil(SysOperLog.class);         return util.exportExcel(list, "操作CSP系统日志");     }      @CspLog(             title = "操作CSP系统日志",             businessType = BusinessType.DELETE     )     @PreAuthorize("@ss.hasPermi("monitor:operlog:remove")")     @DeleteMapping({  "/{operIds}"})     public AjaxResult remove(@PathVariable Long[] operIds) {           return this.toAjax(this.operCspLogService.deleteOperLogByIds(operIds));     }      @CspLog(             title = "清除CSP系统日志",             businessType = BusinessType.CLEAN     )     @PreAuthorize("@ss.hasPermi("monitor:operlog:remove")")     @DeleteMapping({  "/clean"})     public AjaxResult clean() {           this.operCspLogService.cleanOperLog();         return AjaxResult.success();     }   }Service接口层package com.juepeiscm.csp.service.csplog;  import com.juepeiscm.admin.api.domain.SysOperLog; import com.juepeiscm.csp.domain.csplog.SysOperCspLog;  import java.util.List;  /**  * @Author: py.sun  * @Date: 2022/9/7 15:02  */ public interface ISysOperCspLogService {       void insertOperlog(SysOperCspLog var1);      List selectOperLogList(SysOperCspLog var1);      List selectOperLogListTitle();      int deleteOperLogByIds(Long[] var1);      SysOperLog selectOperLogById(Long var1);      void cleanOperLog(); }Service实现package com.juepeiscm.csp.service.impl.csplog;  import com.juepeiscm.admin.api.domain.SysOperLog; import com.juepeiscm.common.core.domain.AjaxResult; import com.juepeiscm.common.core.domain.entity.SysDept; import com.juepeiscm.common.core.domain.entity.SysUser; import com.juepeiscm.common.core.domain.model.LoginUser; import com.juepeiscm.common.exception.CustomException; import com.juepeiscm.common.utils.SecurityUtils; import com.juepeiscm.common.utils.ServletUtils; import com.juepeiscm.common.utils.StringUtils; import com.juepeiscm.csp.domain.csplog.SysOperCspLog; import com.juepeiscm.csp.mapper.csplog.SysOperCspLogMapper; import com.juepeiscm.csp.service.csplog.ISysOperCspLogService; import com.juepeiscm.framework.web.service.TokenService; import com.juepeiscm.uam.service.ISysDeptService; import com.juepeiscm.uam.version.UamVersion; import org.apache.dubbo.config.annotation.Reference; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;  import java.util.List;  /**  * @Author: py.sun  * @Date: 2022/9/7 15:03  */ @Service public class SysOperCspLogServiceImpl implements ISysOperCspLogService {       @Autowired     private SysOperCspLogMapper operLogMapper;      @Autowired     private TokenService tokenService;      @Reference(version = UamVersion.idV)     public ISysDeptService deptService;      @Override     public void insertOperlog(SysOperCspLog sysOperCspLog) {           try {               this.operLogMapper.insertOperlog(sysOperCspLog);         } catch (Exception e) {               e.printStackTrace();             throw new CustomException("CSP系统日志插入失败,请联系管理员!!!");         }      }      @Override     public List selectOperLogList(SysOperCspLog sysOperCspLog) {           return this.operLogMapper.selectOperLogList(sysOperCspLog);     }      @Override     public List selectOperLogListTitle() {           return this.operLogMapper.selectOperLogListTitle();     }      @Override     public int deleteOperLogByIds(Long[] operIds) {           return this.operLogMapper.deleteOperLogByIds(operIds);     }      @Override     public SysOperLog selectOperLogById(Long operId) {           return this.operLogMapper.selectOperLogById(operId);     }      @Override     public void cleanOperLog() {           this.operLogMapper.cleanOperLog();     } }Mapper接口package com.juepeiscm.csp.mapper.csplog;  import com.juepeiscm.admin.api.domain.SysOperLog; import com.juepeiscm.csp.domain.csplog.SysOperCspLog;  import java.util.List;  /**  * @Author: py.sun  * @Date: 2022/9/7 15:06  */ public interface SysOperCspLogMapper {        void insertOperlog(SysOperCspLog var1);      List selectOperLogList(SysOperCspLog sysOperCspLog);      List selectOperLogListTitle();      int deleteOperLogByIds(Long[] var1);      SysOperLog selectOperLogById(Long var1);      void cleanOperLog(); }Mapper.xml(我用的是Mybatis)<?xml version="1.0" encoding="UTF-8" ?>                                                                                                                                                                            select oper_id, title, business_type, method, request_method, operator_type, oper_name, dept_name, oper_url, oper_ip, oper_location, oper_param, json_result, status, error_msg, oper_time         from sys_oper_csp_log                    insert into sys_oper_csp_log(title, business_type, method, request_method, operator_type, oper_name, dept_name, oper_url, oper_ip, oper_location, oper_param, json_result, status, error_msg, oper_time)         values (#{  title}, #{  businessType}, #{  method}, #{  requestMethod}, #{  operatorType}, #{  operName}, #{  deptName}, #{  operUrl}, #{  operIp}, #{  operLocation}, #{  operParam}, #{  jsonResult}, #{  status}, #{  errorMsg}, sysdate())                          delete from sys_oper_csp_log where oper_id in                      #{  operId}                                         truncate table sys_oper_csp_log       
  定义一个日志管理的名称:CspLog  package com.juepeiscm.csp.annotation;  import com.juepeiscm.common.enums.BusinessType; import com.juepeiscm.common.enums.OperatorType;  import java.lang.annotation.*;  /**  * CSP系统的日志管理  * @Author: py.sun  * @Date: 2022/9/7 14:42  * @Target表示注解可以使用到哪些地方,可以是类,方法,或者是属性上,定义在ElementType枚举中:  * @Retention作用是定义被它所注解的注解保留多久,一共有三种策略,定义在RetentionPolicy枚举中:  *  * 我们的@CspLog注解,可以作用在方法和参数上,将由编译器记录在类文件中,并在运行时由VM保留,因此可以反射性地读取。该注解是通过AOP进行解析的  */ @Target({  ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface CspLog {       /**      * 模块      * @return      */     String title() default "";      /**      * 功能      * @return      */     BusinessType businessType() default BusinessType.OTHER;      /**      * 操作人类别      * @return      */     OperatorType operatorType() default OperatorType.MANAGE;      /**      * 是否保存请求的参数      * @return      */     boolean isSaveRequestData() default true; }实体类SysOperCspLogpackage com.juepeiscm.csp.domain.csplog;  import com.fasterxml.jackson.annotation.JsonFormat; import com.juepeiscm.common.annotation.Excel; import com.juepeiscm.common.core.domain.BaseEntity;  import java.util.Date;  /**  * @Author: py.sun  * @Date: 2022/9/7 15:04  */ public class SysOperCspLog extends BaseEntity {       private static final long serialVersionUID = 1L;     @Excel(             name = "操作序号",             cellType = Excel.ColumnType.NUMERIC     )     private Long operId;     @Excel(             name = "操作模块"     )     private String title;     @Excel(             name = "业务类型",             readConverterExp = "0=其它,1=新增,2=修改,3=删除,4=授权,5=导出,6=导入,7=强退,8=生成代码,9=清空数据"     )     private Integer businessType;     private Integer[] businessTypes;     @Excel(             name = "请求方法"     )     private String method;     @Excel(             name = "请求方式"     )     private String requestMethod;     @Excel(             name = "操作类别",             readConverterExp = "0=其它,1=后台用户,2=手机端用户"     )     private Integer operatorType;     @Excel(             name = "操作人员"     )     private String operName;     @Excel(             name = "部门名称"     )     private String deptName;     @Excel(             name = "请求地址"     )     private String operUrl;     @Excel(             name = "操作地址"     )     private String operIp;     @Excel(             name = "操作地点"     )     private String operLocation;     @Excel(             name = "请求参数"     )     private String operParam;     @Excel(             name = "返回参数"     )     private String jsonResult;     @Excel(             name = "状态",             readConverterExp = "0=正常,1=异常"     )     private Integer status;     @Excel(             name = "错误消息"     )     private String errorMsg;     @JsonFormat(             pattern = "yyyy-MM-dd HH:mm:ss"     )     @Excel(             name = "操作时间",             width = 30.0D,             dateFormat = "yyyy-MM-dd HH:mm:ss"     )     private Date operTime;      public SysOperCspLog() {       }      public Long getOperId() {           return this.operId;     }      public void setOperId(Long operId) {           this.operId = operId;     }      public String getTitle() {           return this.title;     }      public void setTitle(String title) {           this.title = title;     }      public Integer getBusinessType() {           return this.businessType;     }      public void setBusinessType(Integer businessType) {           this.businessType = businessType;     }      public Integer[] getBusinessTypes() {           return this.businessTypes;     }      public void setBusinessTypes(Integer[] businessTypes) {           this.businessTypes = businessTypes;     }      public String getMethod() {           return this.method;     }      public void setMethod(String method) {           this.method = method;     }      public String getRequestMethod() {           return this.requestMethod;     }      public void setRequestMethod(String requestMethod) {           this.requestMethod = requestMethod;     }      public Integer getOperatorType() {           return this.operatorType;     }      public void setOperatorType(Integer operatorType) {           this.operatorType = operatorType;     }      public String getOperName() {           return this.operName;     }      public void setOperName(String operName) {           this.operName = operName;     }      public String getDeptName() {           return this.deptName;     }      public void setDeptName(String deptName) {           this.deptName = deptName;     }      public String getOperUrl() {           return this.operUrl;     }      public void setOperUrl(String operUrl) {           this.operUrl = operUrl;     }      public String getOperIp() {           return this.operIp;     }      public void setOperIp(String operIp) {           this.operIp = operIp;     }      public String getOperLocation() {           return this.operLocation;     }      public void setOperLocation(String operLocation) {           this.operLocation = operLocation;     }      public String getOperParam() {           return this.operParam;     }      public void setOperParam(String operParam) {           this.operParam = operParam;     }      public String getJsonResult() {           return this.jsonResult;     }      public void setJsonResult(String jsonResult) {           this.jsonResult = jsonResult;     }      public Integer getStatus() {           return this.status;     }      public void setStatus(Integer status) {           this.status = status;     }      public String getErrorMsg() {           return this.errorMsg;     }      public void setErrorMsg(String errorMsg) {           this.errorMsg = errorMsg;     }      public Date getOperTime() {           return this.operTime;     }      public void setOperTime(Date operTime) {           this.operTime = operTime;     } }10. 定义日志管理的切面
  大家一定要记住哈,所有针对实体的SysOperCspLog赋值操作必须在这里main执行。  package com.juepeiscm.csp.controller.utils;  import com.alibaba.fastjson.JSON; import com.juepeiscm.common.core.domain.entity.SysDept; import com.juepeiscm.common.core.domain.model.LoginUser; import com.juepeiscm.common.enums.BusinessStatus; import com.juepeiscm.common.enums.HttpMethod; import com.juepeiscm.common.utils.ServletUtils; import com.juepeiscm.common.utils.StringUtils; import com.juepeiscm.common.utils.ip.IpUtils; import com.juepeiscm.common.utils.spring.SpringUtils; import com.juepeiscm.csp.annotation.CspLog; import com.juepeiscm.csp.domain.csplog.SysOperCspLog; import com.juepeiscm.framework.aspectj.LogAspect; import com.juepeiscm.framework.manager.AsyncManager; import com.juepeiscm.framework.web.service.TokenService; import com.juepeiscm.uam.service.ISysDeptService; import com.juepeiscm.uam.version.UamVersion; import org.apache.dubbo.config.annotation.Reference; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.validation.BindingResult; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.HandlerMapping;  import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.lang.reflect.Method; import java.util.Collection; import java.util.Iterator; import java.util.Map;  /**  * @Author: py.sun  * @Date: 2022/9/7 16:31  * 操作日志记录处理  */ @Aspect @Component public class CspLogAspect {       private static final Logger log = LoggerFactory.getLogger(CspLog.class);      @Reference(version = UamVersion.idV)     public ISysDeptService deptService;      public CspLogAspect() {       }      //把@CspLog配置为切入点。   配置织入点     @Pointcut("@annotation(com.juepeiscm.csp.annotation.CspLog)")     public void logPointCut() {       }      //拦截异常操作     // 处理完请求后执行该方法。也就是用@CspLog注解的方法,执行完后,调用handleLog方法,处理返回结果。     @AfterReturning(             pointcut = "logPointCut()",             returning = "jsonResult"     )     public void doAfterReturning(JoinPoint joinPoint, Object jsonResult) {           this.handleLog(joinPoint, (Exception)null, jsonResult);     }      @AfterThrowing(             value = "logPointCut()",             throwing = "e"     )     public void doAfterThrowing(JoinPoint joinPoint, Exception e) {           this.handleLog(joinPoint, e, (Object)null);     }      // 如果函数抛出了异常,也是执行handleLog方法,不过和正常返回的参数不一样,此处是为了处理异常。     protected void handleLog(JoinPoint joinPoint, Exception e, Object jsonResult) {           try {               // 获得注解             CspLog controllerLog = this.getAnnotationLog(joinPoint);             if (controllerLog == null) {                   return;             }              // 获取当前的用户             LoginUser loginUser = ((TokenService) SpringUtils.getBean(TokenService.class)).getLoginUser(ServletUtils.getRequest());             // *========数据库日志=========*//             SysOperCspLog operLog = new SysOperCspLog();             operLog.setStatus(BusinessStatus.SUCCESS.ordinal());             // 请求的地址             String ip = IpUtils.getIpAddr(ServletUtils.getRequest());             operLog.setOperIp(ip);             // 返回参数             operLog.setJsonResult(JSON.toJSONString(jsonResult));             operLog.setOperUrl(ServletUtils.getRequest().getRequestURI());             if (loginUser != null) {                   operLog.setOperName(loginUser.getUsername());             }              // 获取当前登录用户的部门名称             SysDept sysDept = deptService.selectDeptIdByUserIdAndAppId(loginUser.getUser().getUserId(), "oms");             if(sysDept != null && StringUtils.isNotEmpty(sysDept.getDeptName())){                       operLog.setDeptName(sysDept.getDeptName());             }              if (e != null) {                   operLog.setStatus(BusinessStatus.FAIL.ordinal());                 operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));             }              // 设置方法名称             String className = joinPoint.getTarget().getClass().getName();             String methodName = joinPoint.getSignature().getName();             operLog.setMethod(className + "." + methodName + "()");             // 设置请求方式             operLog.setRequestMethod(ServletUtils.getRequest().getMethod());             // 处理设置注解上的参数             this.getControllerMethodDescription(joinPoint, controllerLog, operLog);             // 保存数据库             AsyncManager.me().execute(AsyncFactoryCsp.recordOper(operLog));         } catch (Exception var10) {               // 记录本地异常日志             log.error("==前置通知异常==");             log.error("异常信息:{}", var10.getMessage());             var10.printStackTrace();         }      }      public void getControllerMethodDescription(JoinPoint joinPoint, CspLog log, SysOperCspLog operLog) throws Exception {           operLog.setBusinessType(log.businessType().ordinal());         operLog.setTitle(log.title());         operLog.setOperatorType(log.operatorType().ordinal());         if (log.isSaveRequestData()) {               this.setRequestValue(joinPoint, operLog);         }      }      private void setRequestValue(JoinPoint joinPoint, SysOperCspLog operLog) throws Exception {           String requestMethod = operLog.getRequestMethod();         if (!HttpMethod.PUT.name().equals(requestMethod) && !HttpMethod.POST.name().equals(requestMethod)) {               Map<?, ?> paramsMap = (Map)ServletUtils.getRequest().getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);             operLog.setOperParam(StringUtils.substring(paramsMap.toString(), 0, 2000));         } else {               String params = this.argsArrayToString(joinPoint.getArgs());             operLog.setOperParam(StringUtils.substring(params, 0, 2000));         }      }      private CspLog getAnnotationLog(JoinPoint joinPoint) throws Exception {           Signature signature = joinPoint.getSignature();         MethodSignature methodSignature = (MethodSignature)signature;         Method method = methodSignature.getMethod();         return method != null ? (CspLog)method.getAnnotation(CspLog.class) : null;     }      private String argsArrayToString(Object[] paramsArray) {           String params = "";         if (paramsArray != null && paramsArray.length > 0) {               for(int i = 0; i < paramsArray.length; ++i) {                   if (StringUtils.isNotNull(paramsArray[i]) && !this.isFilterObject(paramsArray[i])) {                       Object jsonObj = JSON.toJSON(paramsArray[i]);                     params = params + jsonObj.toString() + " ";                 }             }         }          return params.trim();     }      public boolean isFilterObject(Object o) {           Class<?> clazz = o.getClass();         if (clazz.isArray()) {               return clazz.getComponentType().isAssignableFrom(MultipartFile.class);         } else {               Iterator iter;             if (Collection.class.isAssignableFrom(clazz)) {                   Collection collection = (Collection)o;                 iter = collection.iterator();                 if (iter.hasNext()) {                       return iter.next() instanceof MultipartFile;                 }             } else if (Map.class.isAssignableFrom(clazz)) {                   Map map = (Map)o;                 iter = map.entrySet().iterator();                 if (iter.hasNext()) {                       Map.Entry entry = (Map.Entry)iter.next();                     return entry.getValue() instanceof MultipartFile;                 }             }              return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse || o instanceof BindingResult;         }     } }AsyncFactoryCsppackage com.juepeiscm.csp.controller.utils; import com.juepeiscm.common.utils.ip.AddressUtils; import com.juepeiscm.common.utils.spring.SpringUtils; import com.juepeiscm.csp.domain.csplog.SysOperCspLog; import com.juepeiscm.csp.service.csplog.ISysOperCspLogService; import org.slf4j.Logger; import org.slf4j.LoggerFactory;  import java.util.TimerTask;  /**  * @Author: py.sun  * @Date: 2022/9/7 16:47  */ public class AsyncFactoryCsp {       private static final Logger sys_user_logger = LoggerFactory.getLogger("sys-user");      public AsyncFactoryCsp() {       }      public static TimerTask recordOper(final SysOperCspLog operLog) {           return new TimerTask() {               public void run() {                   operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp()));                 ((ISysOperCspLogService) SpringUtils.getBean(ISysOperCspLogService.class)).insertOperlog(operLog);             }         };     } }12. 写一个Controller的Demo来执行一条日志试试在这里插入代码片package com.juepeiscm.csp.controller.order;  import com.alibaba.fastjson.JSON; import com.juepeiscm.admin.api.service.ISysDictDataService; import com.juepeiscm.common.annotation.RepeatSubmit; import com.juepeiscm.common.core.controller.BaseController; import com.juepeiscm.common.core.domain.AjaxResult; import com.juepeiscm.common.core.domain.entity.SysDictData; import com.juepeiscm.common.core.page.TableDataInfo; import com.juepeiscm.common.enums.BusinessType; import com.juepeiscm.common.exception.BaseException; import com.juepeiscm.common.utils.StringUtils; import com.juepeiscm.common.utils.poi.ExcelUtil; import com.juepeiscm.csp.annotation.CspLog; import com.juepeiscm.csp.domain.order.CspGodownEntry; import com.juepeiscm.csp.domain.order.CspGodownEntryDetails; import com.juepeiscm.csp.service.common.MenuLogService; import com.juepeiscm.csp.service.data.ICspGoodsdataService; import com.juepeiscm.csp.service.order.ICspGodownEntryService; import com.juepeiscm.csp.vo.GodownEntryExcel; import com.juepeiscm.csp.vo.GoodsDataForGodownEntryDetails; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.util.CollectionUtils; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile;  import javax.validation.Valid; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.*; import java.util.stream.Collectors;  /**  * 入库订单Controller  *  * @author juepeiscm  * @date 2021-07-23  */ @Api(tags = "入库订单接口") @RestController @RequestMapping("/order/godownEntry") public class CspGodownEntryController extends BaseController {        private static final Logger logger = LoggerFactory.getLogger(CspGodownEntryController.class);      @Autowired     private ICspGodownEntryService cspGodownEntryService;     @Autowired     private ICspGoodsdataService goodsDataService;     @Autowired     private MenuLogService menuLogService;     @Autowired     private ISysDictDataService sysDictDataService;      /**      * 新增入库订单Demo      */     @PreAuthorize("@ss.hasPermi("order:godownEntry:add")")     @ApiOperation(value = "新增入库订单")     @CspLog(title = "入库订单demo4", businessType = BusinessType.INSERT)     @PostMapping("/addOrder")     @RepeatSubmit     public AjaxResult addDemo(@RequestBody @Valid CspGodownEntry godownEntry) {           try {               return toAjax(cspGodownEntryService.insertOmsGodownEntry(godownEntry));         } catch (Exception e) {               e.printStackTrace();             return AjaxResult.error("新增失败,请联系管理员");         }     } }测试下,看看数据库内容

世界杯决赛,豪门儿媳奚梦瑶出镜,与小姑子何超欣开心自拍昨天相信不少小伙伴们都彻夜未眠,原因就是看世界杯最后一场比赛,当然了这次世界杯比赛的结果也是很多人都非常满意,阿根廷获得了本届世界杯冠军,梅西不仅坚持到了最后还圆了很多足球粉丝的梦推特表示将不再允许免费推广其他社交媒体平台根据该公司周日分享的一条推文,Twitter表示将不再允许用户在其平台上推广其他社交媒体账户。我们认识到我们的许多用户在其他社交媒体平台上都很活跃,该公司表示。但是,我们将不再允许梅西一战创造16大纪录!球王正式加冕,GOAT之争彻底没悬念了球王加冕!梅西率领阿根廷夺得队史第三座世界杯冠军奖杯,8年前从世界杯旁落寞离开的梅西,终于在今天圆梦亲吻了大力神杯,而他也用此战创造的16项纪录,宣告了自己正式加冕第三代球王,也让事关UFO和外星人!美国国防部最新发声每经编辑黄胜,孙志成,易启江据新华社12月19日消息,美国国防部日前说,国防部今年7月组建新部门调查不明飞行物以来,收到几百份发现不明飞行物(UFO)的报告,但是没有证据显示它们与班凯罗谈再胜绿军我们想要赢得联盟的尊重要证明有些人错了直播吧12月19日讯今天,魔术9592战胜了凯尔特人,他们在连续两场比赛里完成了对绿军的双杀。在两天前赢下绿军后,前绿军后卫埃迪豪斯在评球时仍然称魔术是一支烂队,且无法进入季后赛,厦门环东半程马拉松赛圆满落幕中国半马最新纪录诞生!选手们从美峰体育公园起跑福建日报新福建客户端12月19日讯(记者施辰静)12月18日上午7时30分,2022国升基金厦门环东半程马拉松赛鸣枪开赛。伴随着3枪发令枪响,参赛选手从厦门山东大学山东科技大学AEM钠电粘结剂最新成果httpsdoi。org10。1002aenm。202202939背景钠离子电池(SIBs)被认为是低成本和大规模储能的最有希望的候选者。因为丰富的钠资源电解质中Na的小斯托克斯直双旦换机别乱选!这三部安卓轻旗舰体验不输苹果,售价都在4K以内时间来到年底,2022年即将过去,不出意外的话近期手机行业将迎来一波换机高潮。因为年底很多用户都有买新手机回家的打算,而且随着圣诞节元旦等节日的临近,部分厂商也有打折促销的计划,进雅诗兰黛研究了十几年的黑科技,讲的是什么故事?发源于小棕瓶,在众多护肤黑科技中,昼夜节律为何受到认可?来源聚美丽作者诗诗如果说,高端化是化妆品行业的尽头,那么国际品牌必定象征着高端化发展方向上的一根标杆,引导着整个行业的风向。高帅猫51海盗和船长童话睡前故事儿童故事儿童爱听讲故事原创童话故事连载高帅猫全集点击链接上集说到,小波斯猫莉莉说他们在海上遇到海盗,当他们要去告诉船长时,却被海盗堵在门口。团团着急地催她快讲下去。小波斯猫喝了口茶说正当海剿匪纪实故事第二十七集联合姚大榜(1)夕阳斜照(根据历史改编,欢迎指正!)作者舒青作品简介一九五零年初,解放军挺进大西南,湖南晃县兵力空虚。良知(今凉伞镇)汪昌仁趁机纠集一伙流氓,当起了土匪,逼反时任良知乡长杨德庄,投
TGS2022落幕的第十天,我们盘点了可能被遗忘的游戏细节9月18日,为期4天的2022东京电玩展(以下简称TGS)正式落幕,期间参展的各大游戏公司都放出了大量内容,包括游戏预告片和实机演示等,为我们带来了许多值得深入挖掘的情报,也有许多你会买上万元的RTX4090显卡打游戏吗?前几天,黄仁勋在英伟达发布会上正式公布了GeForceRTX408090两款新显卡,不过看一眼平均近万元的售价着实令人望而却步。对于PC玩家而言,显卡是玩游戏必备装备,但这两年黄牛十一长假户外活动带什么?手机就选2699元起华为nova10系列十一假期就快到了,相信很多小伙伴已经计划着和朋友各种聚餐活动了?今天,本文就来跟大家安利一款出行神器。不管你是外出旅行,还是参加露营飞盘等活动,亦或是亲友小聚,它都能为你这次外出再卧游有感解封了,却已经习惯了蜗居,每天追剧,还有时不时地瞅瞅微信,看看网络跳出来的一些心灵鸡汤的慰藉。闲着也是闲着,但涌动的心潮,却倒不出千言外语,人生苦短,此时此刻,也只能卧游而已机智机意难平的文案我在头条搞创作第二期1。我的一年,活了一天,重复364遍。2。压抑这件事,越来越顺手了。3。都会走的,无一例外。4。以前你给的快乐,现在都陪我难过。5。和谁讲,怎么讲,讲什么,不用国庆家宴,分享5道压轴硬菜,提前练练手,待客有面不用愁秋日生活打卡季马上就要国庆了,很多朋友是不是跟小小一样,数着日子盼假期!国庆可以说是继春节以后,最长的一个法定节假日了,在这个举国同庆的日子里,除了长长的假期,也是亲朋好友团聚的日那些可以百分百确定的勾兑酒,你们家是否也有?看完赶紧丢掉在我们的生活中,好多的时候都需要有白酒的陪伴,但是随着人们的需求,白酒的价位,也是越差越大,现在比较好的有茅台五粮液等等,他不但好喝,更是一种身份的象征。每次谁家的宴会上,用的上他长春小伙去西安赴宴,小姨做8道硬菜来款待,小伙真不想回去早闻西安美食种类繁多,数不胜数,前不久去了一趟西安,看到大唐不夜城这里诸多各种各样的美食,瞬间觉得人间真值!假如你是一个吃货,西安还真得去一趟。众所周知,陕西被称之为面都,这里消耗八角放火上烧一烧,太厉害了,解决家家户户大麻烦,省钱又实用八角是一种大料,一般我们在炖肉的时候,就会在肉里面放上一两颗八角,用来增加香味。平时,我们也可以把八角放在火上烧一烧,烧过之后,就会有比较多的用处,方法省钱又实用,下面一起来了解一蒸馒头,不要只加酵母!多加2白,馒头凉了也不硬,又白又香对于大部分人来说,蒸馒头其实很简单,无非就是掌握面粉比例,揉面和面发面蒸熟,但对于新手来说,却有着无形的压力,配料比例一窍不通,这可怎么办呢?一般情况,500克面粉需要搭配2502入秋后,遇到这菜别手软,全身是宝!多买点晒干囤起来,炒肉特香您好,我是小朋!每天为你分享美食菜谱,做菜技巧!初秋养生,清补为上。入秋后,各种瓜果蔬菜纷纷大量上市,为我们的饮食生活提供了丰富多彩的食材。这个季节应该多吃一些具有健脾,清热的食物