From 12858d28e9cdaf28d1191777e21fdcac23c3d8c5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=AE=B5=E9=A3=9E=E5=AE=87?= <2684146481@qq.com>
Date: Tue, 4 Apr 2023 10:57:36 +0800
Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=93=8D=E4=BD=9C=E6=97=A5?=
=?UTF-8?q?=E5=BF=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
hzims-biz-common/pom.xml | 1 +
.../logs/annotation/OperationAnnotation.java | 48 +
.../hnac/hzims/common/logs/aop/SysLogAspect.java | 259 +++++
.../hzims/common/logs/consumer/SysLogConsumer.java | 118 +++
.../hzims/common/logs/consumer/SysLogQueue.java | 43 +
.../hzims/common/logs/enums/BusinessStatus.java | 33 +
.../hnac/hzims/common/logs/enums/BusinessType.java | 73 ++
.../hnac/hzims/common/logs/enums/OperatorType.java | 45 +
.../common/logs/fegin/SysLogFeignService.java | 29 +
.../fegin/fallback/SysLogFeignServiceFallback.java | 30 +
.../hnac/hzims/common/logs/text/CharsetKit.java | 88 ++
.../com/hnac/hzims/common/logs/text/Convert.java | 1009 ++++++++++++++++++++
.../hnac/hzims/common/logs/text/StrFormatter.java | 93 ++
.../com/hnac/hzims/common/logs/to/SysLogTo.java | 145 +++
.../hnac/hzims/common/logs/utils/Constants.java | 130 +++
.../hnac/hzims/common/logs/utils/StringUtils.java | 567 +++++++++++
.../com/hnac/hzims/middle/MiddleApplication.java | 21 +
.../hzims/middle/mybatisplus/CodeGenerator.java | 104 ++
.../systemlog/controller/SysLogController.java | 60 ++
.../hnac/hzims/middle/systemlog/entity/SysLog.java | 191 ++++
.../middle/systemlog/mapper/SysLogMapper.java | 16 +
.../middle/systemlog/service/SysLogService.java | 16 +
.../systemlog/service/impl/SysLogServiceImpl.java | 20 +
.../src/main/resources/application.yml | 38 +
.../hzims-middle/src/main/resources/bootstrap.yml | 7 +
.../src/main/resources/mapper/SysLogMapper.xml | 5 +
.../hnac/hzims/middle/MiddleApplicationTests.java | 15 +
hzims-service/pom.xml | 1 +
hzims-service/ticket/pom.xml | 6 +
.../com/hnac/hzims/ticket/TicketApplication.java | 4 +-
.../com/hnac/hzims/ticket/aop/ApiLogAspect.java | 267 ------
.../hnac/hzims/ticket/aop/OperationAnnotation.java | 42 -
.../java/com/hnac/hzims/ticket/aop/SysLog.java | 80 --
.../controller/ProcessTypeController.java | 117 ++-
34 files changed, 3278 insertions(+), 443 deletions(-)
create mode 100644 hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/annotation/OperationAnnotation.java
create mode 100644 hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/aop/SysLogAspect.java
create mode 100644 hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/consumer/SysLogConsumer.java
create mode 100644 hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/consumer/SysLogQueue.java
create mode 100644 hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/enums/BusinessStatus.java
create mode 100644 hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/enums/BusinessType.java
create mode 100644 hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/enums/OperatorType.java
create mode 100644 hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/fegin/SysLogFeignService.java
create mode 100644 hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/fegin/fallback/SysLogFeignServiceFallback.java
create mode 100644 hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/text/CharsetKit.java
create mode 100644 hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/text/Convert.java
create mode 100644 hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/text/StrFormatter.java
create mode 100644 hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/to/SysLogTo.java
create mode 100644 hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/utils/Constants.java
create mode 100644 hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/utils/StringUtils.java
create mode 100644 hzims-service/hzims-middle/src/main/java/com/hnac/hzims/middle/MiddleApplication.java
create mode 100644 hzims-service/hzims-middle/src/main/java/com/hnac/hzims/middle/mybatisplus/CodeGenerator.java
create mode 100644 hzims-service/hzims-middle/src/main/java/com/hnac/hzims/middle/systemlog/controller/SysLogController.java
create mode 100644 hzims-service/hzims-middle/src/main/java/com/hnac/hzims/middle/systemlog/entity/SysLog.java
create mode 100644 hzims-service/hzims-middle/src/main/java/com/hnac/hzims/middle/systemlog/mapper/SysLogMapper.java
create mode 100644 hzims-service/hzims-middle/src/main/java/com/hnac/hzims/middle/systemlog/service/SysLogService.java
create mode 100644 hzims-service/hzims-middle/src/main/java/com/hnac/hzims/middle/systemlog/service/impl/SysLogServiceImpl.java
create mode 100644 hzims-service/hzims-middle/src/main/resources/application.yml
create mode 100644 hzims-service/hzims-middle/src/main/resources/bootstrap.yml
create mode 100644 hzims-service/hzims-middle/src/main/resources/mapper/SysLogMapper.xml
create mode 100644 hzims-service/hzims-middle/src/test/java/com/hnac/hzims/middle/MiddleApplicationTests.java
delete mode 100644 hzims-service/ticket/src/main/java/com/hnac/hzims/ticket/aop/ApiLogAspect.java
delete mode 100644 hzims-service/ticket/src/main/java/com/hnac/hzims/ticket/aop/OperationAnnotation.java
delete mode 100644 hzims-service/ticket/src/main/java/com/hnac/hzims/ticket/aop/SysLog.java
diff --git a/hzims-biz-common/pom.xml b/hzims-biz-common/pom.xml
index b3927d9..5255f48 100644
--- a/hzims-biz-common/pom.xml
+++ b/hzims-biz-common/pom.xml
@@ -41,6 +41,7 @@
blade-starter-datascope
+
diff --git a/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/annotation/OperationAnnotation.java b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/annotation/OperationAnnotation.java
new file mode 100644
index 0000000..f67c14b
--- /dev/null
+++ b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/annotation/OperationAnnotation.java
@@ -0,0 +1,48 @@
+package com.hnac.hzims.common.logs.annotation;
+
+import com.hnac.hzims.common.logs.enums.BusinessType;
+import com.hnac.hzims.common.logs.enums.OperatorType;
+
+import java.lang.annotation.*;
+
+/**
+ * @Author WL
+ * @Version v1.0
+ * @Serial 1.0
+ * @Date 2023/3/29 11:38
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.PARAMETER, ElementType.METHOD })
+public @interface OperationAnnotation {
+
+ /**
+ * 操作模块
+ * @return
+ */
+ String title() default "操作模块";
+
+ /**
+ * 系统类型(网页端,app端)
+ */
+ OperatorType operatorType() default OperatorType.OTHER;
+
+
+ /**
+ * 操作类型
+ * @return
+ */
+ BusinessType businessType() default BusinessType.OTHER;
+
+
+ /**
+ * 是否保存响应的参数
+ */
+ public boolean isSaveResponseData() default true;
+
+ /**
+ * 功能说明
+ * @return
+ */
+ String action() default "功能说明";
+}
diff --git a/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/aop/SysLogAspect.java b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/aop/SysLogAspect.java
new file mode 100644
index 0000000..1a23612
--- /dev/null
+++ b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/aop/SysLogAspect.java
@@ -0,0 +1,259 @@
+package com.hnac.hzims.common.logs.aop;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.hnac.hzims.common.logs.annotation.OperationAnnotation;
+import com.hnac.hzims.common.logs.consumer.SysLogQueue;
+import com.hnac.hzims.common.logs.to.SysLogTo;
+import com.hnac.hzims.common.logs.enums.BusinessStatus;
+import com.hnac.hzims.common.logs.utils.StringUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.*;
+import org.aspectj.lang.reflect.CodeSignature;
+import org.springblade.core.launch.props.BladeProperties;
+import org.springblade.core.launch.server.ServerInfo;
+import org.springblade.core.secure.utils.AuthUtil;
+import org.springblade.core.tool.constant.BladeConstant;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.core.tool.utils.WebUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StopWatch;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.lang.reflect.Method;
+import java.time.LocalDateTime;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author dfy
+ * @date 2023/3/29
+ * @description: 操作日志切面处理类
+ */
+@Aspect
+@Component
+@Slf4j
+public class SysLogAspect {
+
+
+ @Autowired
+ private ServerInfo serverInfo;
+
+
+ @Autowired
+ private BladeProperties bladeProperties;
+
+
+ @Autowired
+ private SysLogQueue sysLogQueue;
+
+ /**
+ * 请求地址
+ */
+ private String requestPath = null;
+
+ /**
+ * 操作人
+ */
+ private String userName = null;
+
+ /**
+ * 请求
+ */
+ private HttpServletRequest request = null;
+
+
+ private Long userId = -1L;
+
+
+ private StopWatch stopWatch = new StopWatch();
+
+
+ /**
+ * 设置操作日志切入点 在注解的位置切入代码
+ */
+ @Pointcut("@annotation(com.hnac.hzims.common.logs.annotation.OperationAnnotation)")
+ public void logPointCut() {
+ }
+
+ /**
+ * @param joinPoint
+ * @Description 前置通知 方法调用前触发 记录开始时间,从session中获取操作人
+ */
+ @Before(value = "logPointCut()")
+ public void before(JoinPoint joinPoint) {
+ stopWatch.start();
+ log.info("前置通知");
+ }
+
+ /**
+ * @param joinPoint
+ * @Description 后置通知 方法调用后触发 记录结束时间 ,操作人 ,入参等
+ */
+ @AfterReturning(value = "logPointCut()", returning = "jsonResult")
+ public void after(JoinPoint joinPoint, Object jsonResult) {
+ log.info("=========返回通知==============");
+ request = getHttpServletRequest();
+ handleLog(joinPoint, jsonResult, null);
+ }
+
+
+ /**
+ * @param joinPoint
+ * @return
+ * @Description 获取入参方法参数
+ */
+ public Map getNameAndValue(JoinPoint joinPoint) {
+ Map param = new HashMap<>(16);
+ Object[] paramValues = joinPoint.getArgs();
+ String[] paramNames = ((CodeSignature) joinPoint.getSignature()).getParameterNames();
+ for (int i = 0; i < paramNames.length; i++) {
+ if (paramValues[i] instanceof Integer || paramValues[i] instanceof String) {
+ param.put(paramNames[i], paramValues[i]);
+ }
+ }
+ return param;
+ }
+
+
+ /**
+ * @Description: 获取request
+ */
+ public HttpServletRequest getHttpServletRequest() {
+ RequestAttributes ra = RequestContextHolder.getRequestAttributes();
+ ServletRequestAttributes sra = (ServletRequestAttributes) ra;
+ HttpServletRequest request = sra.getRequest();
+ return request;
+ }
+
+
+ /**
+ * @param joinPoint
+ * @Description 异常通知
+ */
+ @AfterThrowing(pointcut = "logPointCut()", throwing = "e")
+ public void throwing(JoinPoint joinPoint, Exception e) {
+ log.info("=========异常通知==============");
+ handleLog(joinPoint, null, e);
+ }
+
+
+ /**
+ * 转换request 请求参数
+ *
+ * @param paramMap request获取的参数数组
+ */
+ public Map converMap(Map paramMap) {
+ Map rtnMap = new HashMap();
+ for (String key : paramMap.keySet()) {
+ rtnMap.put(key, paramMap.get(key)[0]);
+ }
+ return rtnMap;
+ }
+
+ /**
+ * 转换异常信息为字符串
+ *
+ * @param exceptionName 异常名称
+ * @param exceptionMessage 异常信息
+ * @param elements 堆栈信息
+ */
+ public String stackTraceToString(String exceptionName, String exceptionMessage, StackTraceElement[] elements) {
+ StringBuffer strbuff = new StringBuffer();
+ for (StackTraceElement stet : elements) {
+ strbuff.append(stet + "\n");
+ }
+ String message = exceptionName + ":" + exceptionMessage + "\n\t" + strbuff.toString();
+ return message;
+ }
+
+
+ /**
+ * 处理操作日志结果集
+ *
+ * @param joinPoint
+ * @param jsonResult
+ * @param exception
+ */
+ private void handleLog(JoinPoint joinPoint, Object jsonResult, Exception exception) {
+ String targetName = joinPoint.getTarget().getClass().getName();
+ String methodName = joinPoint.getSignature().getName();
+ Object[] arguments = joinPoint.getArgs();
+ Class> targetClass = null;
+ try {
+ targetClass = Class.forName(targetName);
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ Method[] methods = targetClass.getMethods();
+ String title;
+ String action;
+ String businessType;
+ String operatorType;
+ Class>[] clazzs;
+ for (Method method : methods) {
+ if (method.getName().equals(methodName)) {
+ clazzs = method.getParameterTypes();
+ if (clazzs != null && clazzs.length == arguments.length && method.getAnnotation(OperationAnnotation.class) != null) {
+ // 获取请求的类名
+ String className = joinPoint.getTarget().getClass().getName();
+ methodName = className + "." + methodName;
+ request = getHttpServletRequest();
+ requestPath = request.getServletPath();
+ OperationAnnotation annotation = method.getAnnotation(OperationAnnotation.class);
+ title = annotation.title();
+ action = annotation.action();
+ businessType = annotation.businessType().getValue();
+ operatorType = annotation.operatorType().getValue();
+ // 获取当前用户信息
+ userName = AuthUtil.getUserAccount(request);
+ userId = AuthUtil.getUserId(request);
+ SysLogTo sysLog = new SysLogTo();
+ if (StringUtils.isBlank(userName) && userId == -1) {
+ userName = "当前用户未登录";
+ }
+ sysLog.setOperationUserName(userName);
+ sysLog.setOperationUserId(userId);
+ sysLog.setTenantId(Func.toStr(AuthUtil.getTenantId(), BladeConstant.ADMIN_TENANT_ID));
+ sysLog.setLocalIp(WebUtil.getIP(request));// 请求IP
+ stopWatch.stop();
+ sysLog.setCostTime(stopWatch.getTotalTimeMillis() + "ms");
+ sysLog.setPath(requestPath);
+ sysLog.setTitle(title);
+ sysLog.setAction(action);
+ sysLog.setOperatorType(operatorType);
+ sysLog.setBusinessType(businessType);
+ sysLog.setParameter(getNameAndValue(joinPoint).toString());
+ sysLog.setMethodClass(className);
+ sysLog.setMethodName(methodName);
+ sysLog.setServerName(bladeProperties.getName());
+ sysLog.setServerHost(serverInfo.getHostName());
+ sysLog.setServerIp(serverInfo.getIpWithPort());
+ sysLog.setEnv(bladeProperties.getEnv());
+ sysLog.setMethod(request.getMethod());
+ sysLog.setUserAgent(request.getHeader(WebUtil.USER_AGENT_HEADER));
+ sysLog.setOperationTime(LocalDateTime.now());
+
+ //返回结果集
+ if (ObjectUtils.isNotEmpty(jsonResult)) {
+ sysLog.setStatus(BusinessStatus.SUCCESS.getKey());
+ sysLog.setJsonResult(StringUtils.substring(JSON.toJSONString(jsonResult), 0, 2000));
+ }
+
+ //异常结果集
+ if (exception != null) {
+ sysLog.setStatus(BusinessStatus.FAIL.getKey());
+ sysLog.setErrorMsg(StringUtils.substring(exception.getMessage(), 0, 2000));
+ }
+ //保存到阻塞队列里
+ sysLogQueue.add(sysLog);
+ }
+ }
+ }
+ }
+}
diff --git a/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/consumer/SysLogConsumer.java b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/consumer/SysLogConsumer.java
new file mode 100644
index 0000000..5601b3c
--- /dev/null
+++ b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/consumer/SysLogConsumer.java
@@ -0,0 +1,118 @@
+package com.hnac.hzims.common.logs.consumer;
+
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.hnac.hzims.common.logs.to.SysLogTo;
+import com.hnac.hzims.common.logs.fegin.SysLogFeignService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 执行异步线程操作
+ * @Author dfy
+ * @Version v1.0
+ * @Serial 1.0
+ * @Date 2023/4/3 14:00
+ */
+@Slf4j
+@Component
+public class SysLogConsumer implements Runnable {
+
+ /**
+ * 默认16
+ */
+ private static final int DEFAULT_BATCH_SIZE = 16;
+
+ @Resource
+ private SysLogQueue auditLogQueue;
+ /**
+ * 批次数
+ */
+ private int batchSize = DEFAULT_BATCH_SIZE;
+
+ @Autowired
+ private SysLogFeignService sysLogFeignService;
+
+
+ /**
+ * 默认为true
+ */
+ private boolean active = true;
+
+ private Thread thread;
+
+
+ /**
+ * 启动线程
+ */
+ @PostConstruct
+ public void init() {
+ thread = new Thread(this);
+ thread.start();
+ }
+
+ /**
+ * 使用该注解在项目结束的舒缓关闭
+ */
+ @PreDestroy
+ public void close() {
+ active = false;
+ }
+
+
+ /**
+ * 执行线程操作
+ */
+ @Override
+ public void run() {
+ while (active) {
+ execute();
+ }
+ }
+
+
+ /**
+ * 执行业务处理操作,新增日志记录
+ */
+ public void execute() {
+ List sysLogs = new ArrayList<>();
+ try {
+ int size = 0;
+ while (size < batchSize) {
+ //从队列中取出一个
+ SysLogTo sysLog = auditLogQueue.poll();
+ if (sysLog == null) {
+ break;
+ }
+ sysLogs.add(sysLog);
+ size++;
+ }
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ log.error(e.toString());
+ }
+ //如果当前的日志list不为空
+ if (CollectionUtils.isNotEmpty(sysLogs)) {
+ log.info("日志操作数据:" + sysLogs);
+ // TODO: 2023/4/4 添加到数据库
+ try {
+ // TODO: 2023/4/4 后期采取mq+elk实现,可以提高效率,操作日志数据越来越大,查询效率变大,提高性能
+ sysLogFeignService.saveBatch(sysLogs);
+ } catch (Exception e) {
+ // TODO: 2023/4/4 出现异常呢,
+ e.printStackTrace();
+ }
+
+ }
+ }
+
+
+
+
+}
diff --git a/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/consumer/SysLogQueue.java b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/consumer/SysLogQueue.java
new file mode 100644
index 0000000..1424a74
--- /dev/null
+++ b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/consumer/SysLogQueue.java
@@ -0,0 +1,43 @@
+package com.hnac.hzims.common.logs.consumer;
+
+import com.hnac.hzims.common.logs.to.SysLogTo;
+import org.springframework.stereotype.Component;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 定义队列
+ * @Author dfy
+ * @Version v1.0
+ * @Serial 1.0
+ * @Date 2023/4/3 14:01
+ */
+@Component
+public class SysLogQueue {
+
+ /**
+ * BlockingDequeue为双端阻塞队列,blockingQueue阻塞队列
+ */
+ private BlockingQueue blockingQueue = new LinkedBlockingQueue<>();
+
+ /**
+ * 存入数据
+ * @param auditLog
+ */
+ public void add(SysLogTo auditLog) {
+ blockingQueue.add(auditLog);
+ }
+
+ /**
+ * poll从队列的头部获取到信息
+ * @return
+ * @throws InterruptedException
+ */
+ public SysLogTo poll() throws InterruptedException {
+ //每秒钟执行一次
+ return blockingQueue.poll(1, TimeUnit.SECONDS);
+ }
+
+}
diff --git a/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/enums/BusinessStatus.java b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/enums/BusinessStatus.java
new file mode 100644
index 0000000..90cfa91
--- /dev/null
+++ b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/enums/BusinessStatus.java
@@ -0,0 +1,33 @@
+package com.hnac.hzims.common.logs.enums;
+
+import lombok.Getter;
+
+/**
+ * 操作状态
+ *
+ * @author ruoyi
+ *
+ */
+public enum BusinessStatus
+{
+ /**
+ * 成功
+ */
+ SUCCESS(0,"执行成功"),
+
+ /**
+ * 异常
+ */
+ FAIL(1,"执行异常");
+
+ @Getter
+ private Integer key;
+
+ @Getter
+ private String value;
+
+ BusinessStatus(Integer key,String value){
+ this.key = key;
+ this.value = value;
+ }
+}
diff --git a/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/enums/BusinessType.java b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/enums/BusinessType.java
new file mode 100644
index 0000000..6556577
--- /dev/null
+++ b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/enums/BusinessType.java
@@ -0,0 +1,73 @@
+package com.hnac.hzims.common.logs.enums;
+
+
+import lombok.Getter;
+
+/**
+ * 业务操作类型
+ *
+ * @author ruoyi
+ */
+public enum BusinessType
+{
+ /**
+ * 其它
+ */
+ OTHER("OTHER","其他"),
+
+ /**
+ * 新增
+ */
+ INSERT("INSERT","新增"),
+
+ /**
+ * 修改
+ */
+ UPDATE("UPDATE","修改"),
+
+ /**
+ * 删除
+ */
+ DELETE("DELETE","删除"),
+
+ /**
+ * 授权
+ */
+ GRANT("GRANT","授权"),
+
+ /**
+ * 导出
+ */
+ EXPORT("EXPORT","导出"),
+
+ /**
+ * 导入
+ */
+ IMPORT("IMPORT","导入"),
+
+ /**
+ * 强退
+ */
+ FORCE("FORCE","强退"),
+
+ /**
+ * 查询
+ */
+ GENCODE("GENCODE","查询"),
+
+ /**
+ * 清空数据
+ */
+ CLEAN("CLEAN","清空数据");
+
+ @Getter
+ private String key;
+
+ @Getter
+ private String value;
+
+ BusinessType(String key,String value){
+ this.key = key;
+ this.value = value;
+ }
+}
diff --git a/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/enums/OperatorType.java b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/enums/OperatorType.java
new file mode 100644
index 0000000..6ba76cd
--- /dev/null
+++ b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/enums/OperatorType.java
@@ -0,0 +1,45 @@
+package com.hnac.hzims.common.logs.enums;
+
+import lombok.Getter;
+
+/**
+ * 操作人类别
+ *
+ * @author ruoyi
+ */
+public enum OperatorType
+{
+ /**
+ * 其它
+ */
+ OTHER("OTHER","其它"),
+
+ /**
+ * 后台用户
+ */
+ MANAGE("MANAGE","后台用户"),
+
+ /**
+ * web 端
+ */
+ MOBILE("MOBILE","web端"),
+ /**
+ * app 端
+ */
+ APPSYSTEMS("APPSYSTEMS","app端");
+
+
+ @Getter
+ private String key;
+
+ @Getter
+ private String value;
+
+
+ OperatorType(String key,String value){
+ this.key = key;
+ this.value = value;
+ }
+
+
+}
diff --git a/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/fegin/SysLogFeignService.java b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/fegin/SysLogFeignService.java
new file mode 100644
index 0000000..5523cae
--- /dev/null
+++ b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/fegin/SysLogFeignService.java
@@ -0,0 +1,29 @@
+package com.hnac.hzims.common.logs.fegin;
+
+import com.hnac.hzims.common.logs.to.SysLogTo;
+import com.hnac.hzims.common.logs.fegin.fallback.SysLogFeignServiceFallback;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Repository;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import java.util.List;
+
+/**
+ * @Author WL
+ * @Version v1.0
+ * @Serial 1.0
+ * @Date 2023/4/3 13:46
+ */
+@Repository
+@FeignClient(value = "hzims-middle",fallback = SysLogFeignServiceFallback.class)
+public interface SysLogFeignService {
+
+ /**
+ * 报存日志操作
+ *
+ * @param sysLogs
+ */
+ @PostMapping("/systemlog/sys-log/batchSave")
+ void saveBatch(@RequestBody List sysLogs);
+}
diff --git a/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/fegin/fallback/SysLogFeignServiceFallback.java b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/fegin/fallback/SysLogFeignServiceFallback.java
new file mode 100644
index 0000000..2035023
--- /dev/null
+++ b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/fegin/fallback/SysLogFeignServiceFallback.java
@@ -0,0 +1,30 @@
+package com.hnac.hzims.common.logs.fegin.fallback;
+
+import com.hnac.hzims.common.logs.to.SysLogTo;
+import com.hnac.hzims.common.logs.fegin.SysLogFeignService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @Author WL
+ * @Version v1.0
+ * @Serial 1.0
+ * @Date 2023/4/4 9:45
+ */
+@Slf4j
+@Service
+public class SysLogFeignServiceFallback implements SysLogFeignService {
+ /**
+ * 报存日志操作
+ *
+ * @param sysLogs
+ */
+ @Override
+ public void saveBatch(List sysLogs) {
+ log.error("报存日志操作异常发生,进入fallback方法");
+ log.error("获取异常的数据 {}", sysLogs);
+ throw new IllegalArgumentException("报存日志操作异常发生,进入fallback方法");
+ }
+}
diff --git a/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/text/CharsetKit.java b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/text/CharsetKit.java
new file mode 100644
index 0000000..ca91975
--- /dev/null
+++ b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/text/CharsetKit.java
@@ -0,0 +1,88 @@
+package com.hnac.hzims.common.logs.text;
+
+
+import com.hnac.hzims.common.logs.utils.StringUtils;
+
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * 字符集工具类
+ *
+ * @author dfy
+ */
+public class CharsetKit
+{
+ /** ISO-8859-1 */
+ public static final String ISO_8859_1 = "ISO-8859-1";
+ /** UTF-8 */
+ public static final String UTF_8 = "UTF-8";
+ /** GBK */
+ public static final String GBK = "GBK";
+
+ /** ISO-8859-1 */
+ public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1);
+ /** UTF-8 */
+ public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8);
+ /** GBK */
+ public static final Charset CHARSET_GBK = Charset.forName(GBK);
+
+ /**
+ * 转换为Charset对象
+ *
+ * @param charset 字符集,为空则返回默认字符集
+ * @return Charset
+ */
+ public static Charset charset(String charset)
+ {
+ return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset);
+ }
+
+ /**
+ * 转换字符串的字符集编码
+ *
+ * @param source 字符串
+ * @param srcCharset 源字符集,默认ISO-8859-1
+ * @param destCharset 目标字符集,默认UTF-8
+ * @return 转换后的字符集
+ */
+ public static String convert(String source, String srcCharset, String destCharset)
+ {
+ return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset));
+ }
+
+ /**
+ * 转换字符串的字符集编码
+ *
+ * @param source 字符串
+ * @param srcCharset 源字符集,默认ISO-8859-1
+ * @param destCharset 目标字符集,默认UTF-8
+ * @return 转换后的字符集
+ */
+ public static String convert(String source, Charset srcCharset, Charset destCharset)
+ {
+ if (null == srcCharset)
+ {
+ srcCharset = StandardCharsets.ISO_8859_1;
+ }
+
+ if (null == destCharset)
+ {
+ destCharset = StandardCharsets.UTF_8;
+ }
+
+ if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset))
+ {
+ return source;
+ }
+ return new String(source.getBytes(srcCharset), destCharset);
+ }
+
+ /**
+ * @return 系统字符集编码
+ */
+ public static String systemCharset()
+ {
+ return Charset.defaultCharset().name();
+ }
+}
diff --git a/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/text/Convert.java b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/text/Convert.java
new file mode 100644
index 0000000..1d6b420
--- /dev/null
+++ b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/text/Convert.java
@@ -0,0 +1,1009 @@
+package com.hnac.hzims.common.logs.text;
+
+
+
+import com.hnac.hzims.common.logs.utils.StringUtils;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.text.NumberFormat;
+import java.util.Set;
+
+/**
+ * 类型转换器
+ *
+ * @author ruoyi
+ */
+public class Convert
+{
+ /**
+ * 转换为字符串
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错
+ *
+ * @param value 被转换的值
+ * @param defaultValue 转换错误时的默认值
+ * @return 结果
+ */
+ public static String toStr(Object value, String defaultValue)
+ {
+ if (null == value)
+ {
+ return defaultValue;
+ }
+ if (value instanceof String)
+ {
+ return (String) value;
+ }
+ return value.toString();
+ }
+
+ /**
+ * 转换为字符串
+ * 如果给定的值为null
,或者转换失败,返回默认值null
+ * 转换失败不会报错
+ *
+ * @param value 被转换的值
+ * @return 结果
+ */
+ public static String toStr(Object value)
+ {
+ return toStr(value, null);
+ }
+
+ /**
+ * 转换为字符
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错
+ *
+ * @param value 被转换的值
+ * @param defaultValue 转换错误时的默认值
+ * @return 结果
+ */
+ public static Character toChar(Object value, Character defaultValue)
+ {
+ if (null == value)
+ {
+ return defaultValue;
+ }
+ if (value instanceof Character)
+ {
+ return (Character) value;
+ }
+
+ final String valueStr = toStr(value, null);
+ return StringUtils.isEmpty(valueStr) ? defaultValue : valueStr.charAt(0);
+ }
+
+ /**
+ * 转换为字符
+ * 如果给定的值为null
,或者转换失败,返回默认值null
+ * 转换失败不会报错
+ *
+ * @param value 被转换的值
+ * @return 结果
+ */
+ public static Character toChar(Object value)
+ {
+ return toChar(value, null);
+ }
+
+ /**
+ * 转换为byte
+ * 如果给定的值为null
,或者转换失败,返回默认值
+ * 转换失败不会报错
+ *
+ * @param value 被转换的值
+ * @param defaultValue 转换错误时的默认值
+ * @return 结果
+ */
+ public static Byte toByte(Object value, Byte defaultValue)
+ {
+ if (value == null)
+ {
+ return defaultValue;
+ }
+ if (value instanceof Byte)
+ {
+ return (Byte) value;
+ }
+ if (value instanceof Number)
+ {
+ return ((Number) value).byteValue();
+ }
+ final String valueStr = toStr(value, null);
+ if (StringUtils.isEmpty(valueStr))
+ {
+ return defaultValue;
+ }
+ try
+ {
+ return Byte.parseByte(valueStr);
+ }
+ catch (Exception e)
+ {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * 转换为byte
+ * 如果给定的值为null
,或者转换失败,返回默认值null
+ * 转换失败不会报错
+ *
+ * @param value 被转换的值
+ * @return 结果
+ */
+ public static Byte toByte(Object value)
+ {
+ return toByte(value, null);
+ }
+
+ /**
+ * 转换为Short
+ * 如果给定的值为null
,或者转换失败,返回默认值
+ * 转换失败不会报错
+ *
+ * @param value 被转换的值
+ * @param defaultValue 转换错误时的默认值
+ * @return 结果
+ */
+ public static Short toShort(Object value, Short defaultValue)
+ {
+ if (value == null)
+ {
+ return defaultValue;
+ }
+ if (value instanceof Short)
+ {
+ return (Short) value;
+ }
+ if (value instanceof Number)
+ {
+ return ((Number) value).shortValue();
+ }
+ final String valueStr = toStr(value, null);
+ if (StringUtils.isEmpty(valueStr))
+ {
+ return defaultValue;
+ }
+ try
+ {
+ return Short.parseShort(valueStr.trim());
+ }
+ catch (Exception e)
+ {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * 转换为Short
+ * 如果给定的值为null
,或者转换失败,返回默认值null
+ * 转换失败不会报错
+ *
+ * @param value 被转换的值
+ * @return 结果
+ */
+ public static Short toShort(Object value)
+ {
+ return toShort(value, null);
+ }
+
+ /**
+ * 转换为Number
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错
+ *
+ * @param value 被转换的值
+ * @param defaultValue 转换错误时的默认值
+ * @return 结果
+ */
+ public static Number toNumber(Object value, Number defaultValue)
+ {
+ if (value == null)
+ {
+ return defaultValue;
+ }
+ if (value instanceof Number)
+ {
+ return (Number) value;
+ }
+ final String valueStr = toStr(value, null);
+ if (StringUtils.isEmpty(valueStr))
+ {
+ return defaultValue;
+ }
+ try
+ {
+ return NumberFormat.getInstance().parse(valueStr);
+ }
+ catch (Exception e)
+ {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * 转换为Number
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错
+ *
+ * @param value 被转换的值
+ * @return 结果
+ */
+ public static Number toNumber(Object value)
+ {
+ return toNumber(value, null);
+ }
+
+ /**
+ * 转换为int
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错
+ *
+ * @param value 被转换的值
+ * @param defaultValue 转换错误时的默认值
+ * @return 结果
+ */
+ public static Integer toInt(Object value, Integer defaultValue)
+ {
+ if (value == null)
+ {
+ return defaultValue;
+ }
+ if (value instanceof Integer)
+ {
+ return (Integer) value;
+ }
+ if (value instanceof Number)
+ {
+ return ((Number) value).intValue();
+ }
+ final String valueStr = toStr(value, null);
+ if (StringUtils.isEmpty(valueStr))
+ {
+ return defaultValue;
+ }
+ try
+ {
+ return Integer.parseInt(valueStr.trim());
+ }
+ catch (Exception e)
+ {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * 转换为int
+ * 如果给定的值为null
,或者转换失败,返回默认值null
+ * 转换失败不会报错
+ *
+ * @param value 被转换的值
+ * @return 结果
+ */
+ public static Integer toInt(Object value)
+ {
+ return toInt(value, null);
+ }
+
+ /**
+ * 转换为Integer数组
+ *
+ * @param str 被转换的值
+ * @return 结果
+ */
+ public static Integer[] toIntArray(String str)
+ {
+ return toIntArray(",", str);
+ }
+
+ /**
+ * 转换为Long数组
+ *
+ * @param str 被转换的值
+ * @return 结果
+ */
+ public static Long[] toLongArray(String str)
+ {
+ return toLongArray(",", str);
+ }
+
+ /**
+ * 转换为Integer数组
+ *
+ * @param split 分隔符
+ * @param str 被转换的值
+ * @return 结果
+ */
+ public static Integer[] toIntArray(String split, String str)
+ {
+ if (StringUtils.isEmpty(str))
+ {
+ return new Integer[] {};
+ }
+ String[] arr = str.split(split);
+ final Integer[] ints = new Integer[arr.length];
+ for (int i = 0; i < arr.length; i++)
+ {
+ final Integer v = toInt(arr[i], 0);
+ ints[i] = v;
+ }
+ return ints;
+ }
+
+ /**
+ * 转换为Long数组
+ *
+ * @param split 分隔符
+ * @param str 被转换的值
+ * @return 结果
+ */
+ public static Long[] toLongArray(String split, String str)
+ {
+ if (StringUtils.isEmpty(str))
+ {
+ return new Long[] {};
+ }
+ String[] arr = str.split(split);
+ final Long[] longs = new Long[arr.length];
+ for (int i = 0; i < arr.length; i++)
+ {
+ final Long v = toLong(arr[i], null);
+ longs[i] = v;
+ }
+ return longs;
+ }
+
+ /**
+ * 转换为String数组
+ *
+ * @param str 被转换的值
+ * @return 结果
+ */
+ public static String[] toStrArray(String str)
+ {
+ return toStrArray(",", str);
+ }
+
+ /**
+ * 转换为String数组
+ *
+ * @param split 分隔符
+ * @param str 被转换的值
+ * @return 结果
+ */
+ public static String[] toStrArray(String split, String str)
+ {
+ return str.split(split);
+ }
+
+ /**
+ * 转换为long
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错
+ *
+ * @param value 被转换的值
+ * @param defaultValue 转换错误时的默认值
+ * @return 结果
+ */
+ public static Long toLong(Object value, Long defaultValue)
+ {
+ if (value == null)
+ {
+ return defaultValue;
+ }
+ if (value instanceof Long)
+ {
+ return (Long) value;
+ }
+ if (value instanceof Number)
+ {
+ return ((Number) value).longValue();
+ }
+ final String valueStr = toStr(value, null);
+ if (StringUtils.isEmpty(valueStr))
+ {
+ return defaultValue;
+ }
+ try
+ {
+ // 支持科学计数法
+ return new BigDecimal(valueStr.trim()).longValue();
+ }
+ catch (Exception e)
+ {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * 转换为long
+ * 如果给定的值为null
,或者转换失败,返回默认值null
+ * 转换失败不会报错
+ *
+ * @param value 被转换的值
+ * @return 结果
+ */
+ public static Long toLong(Object value)
+ {
+ return toLong(value, null);
+ }
+
+ /**
+ * 转换为double
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错
+ *
+ * @param value 被转换的值
+ * @param defaultValue 转换错误时的默认值
+ * @return 结果
+ */
+ public static Double toDouble(Object value, Double defaultValue)
+ {
+ if (value == null)
+ {
+ return defaultValue;
+ }
+ if (value instanceof Double)
+ {
+ return (Double) value;
+ }
+ if (value instanceof Number)
+ {
+ return ((Number) value).doubleValue();
+ }
+ final String valueStr = toStr(value, null);
+ if (StringUtils.isEmpty(valueStr))
+ {
+ return defaultValue;
+ }
+ try
+ {
+ // 支持科学计数法
+ return new BigDecimal(valueStr.trim()).doubleValue();
+ }
+ catch (Exception e)
+ {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * 转换为double
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错
+ *
+ * @param value 被转换的值
+ * @return 结果
+ */
+ public static Double toDouble(Object value)
+ {
+ return toDouble(value, null);
+ }
+
+ /**
+ * 转换为Float
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错
+ *
+ * @param value 被转换的值
+ * @param defaultValue 转换错误时的默认值
+ * @return 结果
+ */
+ public static Float toFloat(Object value, Float defaultValue)
+ {
+ if (value == null)
+ {
+ return defaultValue;
+ }
+ if (value instanceof Float)
+ {
+ return (Float) value;
+ }
+ if (value instanceof Number)
+ {
+ return ((Number) value).floatValue();
+ }
+ final String valueStr = toStr(value, null);
+ if (StringUtils.isEmpty(valueStr))
+ {
+ return defaultValue;
+ }
+ try
+ {
+ return Float.parseFloat(valueStr.trim());
+ }
+ catch (Exception e)
+ {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * 转换为Float
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错
+ *
+ * @param value 被转换的值
+ * @return 结果
+ */
+ public static Float toFloat(Object value)
+ {
+ return toFloat(value, null);
+ }
+
+ /**
+ * 转换为boolean
+ * String支持的值为:true、false、yes、ok、no,1,0 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错
+ *
+ * @param value 被转换的值
+ * @param defaultValue 转换错误时的默认值
+ * @return 结果
+ */
+ public static Boolean toBool(Object value, Boolean defaultValue)
+ {
+ if (value == null)
+ {
+ return defaultValue;
+ }
+ if (value instanceof Boolean)
+ {
+ return (Boolean) value;
+ }
+ String valueStr = toStr(value, null);
+ if (StringUtils.isEmpty(valueStr))
+ {
+ return defaultValue;
+ }
+ valueStr = valueStr.trim().toLowerCase();
+ switch (valueStr)
+ {
+ case "true":
+ case "yes":
+ case "ok":
+ case "1":
+ return true;
+ case "false":
+ case "no":
+ case "0":
+ return false;
+ default:
+ return defaultValue;
+ }
+ }
+
+ /**
+ * 转换为boolean
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错
+ *
+ * @param value 被转换的值
+ * @return 结果
+ */
+ public static Boolean toBool(Object value)
+ {
+ return toBool(value, null);
+ }
+
+ /**
+ * 转换为Enum对象
+ * 如果给定的值为空,或者转换失败,返回默认值
+ *
+ * @param clazz Enum的Class
+ * @param value 值
+ * @param defaultValue 默认值
+ * @return Enum
+ */
+ public static > E toEnum(Class clazz, Object value, E defaultValue)
+ {
+ if (value == null)
+ {
+ return defaultValue;
+ }
+ if (clazz.isAssignableFrom(value.getClass()))
+ {
+ @SuppressWarnings("unchecked")
+ E myE = (E) value;
+ return myE;
+ }
+ final String valueStr = toStr(value, null);
+ if (StringUtils.isEmpty(valueStr))
+ {
+ return defaultValue;
+ }
+ try
+ {
+ return Enum.valueOf(clazz, valueStr);
+ }
+ catch (Exception e)
+ {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * 转换为Enum对象
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ *
+ * @param clazz Enum的Class
+ * @param value 值
+ * @return Enum
+ */
+ public static > E toEnum(Class clazz, Object value)
+ {
+ return toEnum(clazz, value, null);
+ }
+
+ /**
+ * 转换为BigInteger
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错
+ *
+ * @param value 被转换的值
+ * @param defaultValue 转换错误时的默认值
+ * @return 结果
+ */
+ public static BigInteger toBigInteger(Object value, BigInteger defaultValue)
+ {
+ if (value == null)
+ {
+ return defaultValue;
+ }
+ if (value instanceof BigInteger)
+ {
+ return (BigInteger) value;
+ }
+ if (value instanceof Long)
+ {
+ return BigInteger.valueOf((Long) value);
+ }
+ final String valueStr = toStr(value, null);
+ if (StringUtils.isEmpty(valueStr))
+ {
+ return defaultValue;
+ }
+ try
+ {
+ return new BigInteger(valueStr);
+ }
+ catch (Exception e)
+ {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * 转换为BigInteger
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错
+ *
+ * @param value 被转换的值
+ * @return 结果
+ */
+ public static BigInteger toBigInteger(Object value)
+ {
+ return toBigInteger(value, null);
+ }
+
+ /**
+ * 转换为BigDecimal
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错
+ *
+ * @param value 被转换的值
+ * @param defaultValue 转换错误时的默认值
+ * @return 结果
+ */
+ public static BigDecimal toBigDecimal(Object value, BigDecimal defaultValue)
+ {
+ if (value == null)
+ {
+ return defaultValue;
+ }
+ if (value instanceof BigDecimal)
+ {
+ return (BigDecimal) value;
+ }
+ if (value instanceof Long)
+ {
+ return new BigDecimal((Long) value);
+ }
+ if (value instanceof Double)
+ {
+ return BigDecimal.valueOf((Double) value);
+ }
+ if (value instanceof Integer)
+ {
+ return new BigDecimal((Integer) value);
+ }
+ final String valueStr = toStr(value, null);
+ if (StringUtils.isEmpty(valueStr))
+ {
+ return defaultValue;
+ }
+ try
+ {
+ return new BigDecimal(valueStr);
+ }
+ catch (Exception e)
+ {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * 转换为BigDecimal
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错
+ *
+ * @param value 被转换的值
+ * @return 结果
+ */
+ public static BigDecimal toBigDecimal(Object value)
+ {
+ return toBigDecimal(value, null);
+ }
+
+ /**
+ * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法
+ *
+ * @param obj 对象
+ * @return 字符串
+ */
+ public static String utf8Str(Object obj)
+ {
+ return str(obj, CharsetKit.CHARSET_UTF_8);
+ }
+
+ /**
+ * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法
+ *
+ * @param obj 对象
+ * @param charsetName 字符集
+ * @return 字符串
+ */
+ public static String str(Object obj, String charsetName)
+ {
+ return str(obj, Charset.forName(charsetName));
+ }
+
+ /**
+ * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法
+ *
+ * @param obj 对象
+ * @param charset 字符集
+ * @return 字符串
+ */
+ public static String str(Object obj, Charset charset)
+ {
+ if (null == obj)
+ {
+ return null;
+ }
+
+ if (obj instanceof String)
+ {
+ return (String) obj;
+ }
+ else if (obj instanceof byte[] || obj instanceof Byte[])
+ {
+ if (obj instanceof byte[])
+ {
+ return str((byte[]) obj, charset);
+ }
+ else
+ {
+ Byte[] bytes = (Byte[]) obj;
+ int length = bytes.length;
+ byte[] dest = new byte[length];
+ for (int i = 0; i < length; i++)
+ {
+ dest[i] = bytes[i];
+ }
+ return str(dest, charset);
+ }
+ }
+ else if (obj instanceof ByteBuffer)
+ {
+ return str((ByteBuffer) obj, charset);
+ }
+ return obj.toString();
+ }
+
+ /**
+ * 将byte数组转为字符串
+ *
+ * @param bytes byte数组
+ * @param charset 字符集
+ * @return 字符串
+ */
+ public static String str(byte[] bytes, String charset)
+ {
+ return str(bytes, StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset));
+ }
+
+ /**
+ * 解码字节码
+ *
+ * @param data 字符串
+ * @param charset 字符集,如果此字段为空,则解码的结果取决于平台
+ * @return 解码后的字符串
+ */
+ public static String str(byte[] data, Charset charset)
+ {
+ if (data == null)
+ {
+ return null;
+ }
+
+ if (null == charset)
+ {
+ return new String(data);
+ }
+ return new String(data, charset);
+ }
+
+ /**
+ * 将编码的byteBuffer数据转换为字符串
+ *
+ * @param data 数据
+ * @param charset 字符集,如果为空使用当前系统字符集
+ * @return 字符串
+ */
+ public static String str(ByteBuffer data, String charset)
+ {
+ if (data == null)
+ {
+ return null;
+ }
+
+ return str(data, Charset.forName(charset));
+ }
+
+ /**
+ * 将编码的byteBuffer数据转换为字符串
+ *
+ * @param data 数据
+ * @param charset 字符集,如果为空使用当前系统字符集
+ * @return 字符串
+ */
+ public static String str(ByteBuffer data, Charset charset)
+ {
+ if (null == charset)
+ {
+ charset = Charset.defaultCharset();
+ }
+ return charset.decode(data).toString();
+ }
+
+ // ----------------------------------------------------------------------- 全角半角转换
+ /**
+ * 半角转全角
+ *
+ * @param input String.
+ * @return 全角字符串.
+ */
+ public static String toSBC(String input)
+ {
+ return toSBC(input, null);
+ }
+
+ /**
+ * 半角转全角
+ *
+ * @param input String
+ * @param notConvertSet 不替换的字符集合
+ * @return 全角字符串.
+ */
+ public static String toSBC(String input, Set notConvertSet)
+ {
+ char[] c = input.toCharArray();
+ for (int i = 0; i < c.length; i++)
+ {
+ if (null != notConvertSet && notConvertSet.contains(c[i]))
+ {
+ // 跳过不替换的字符
+ continue;
+ }
+
+ if (c[i] == ' ')
+ {
+ c[i] = '\u3000';
+ }
+ else if (c[i] < '\177')
+ {
+ c[i] = (char) (c[i] + 65248);
+
+ }
+ }
+ return new String(c);
+ }
+
+ /**
+ * 全角转半角
+ *
+ * @param input String.
+ * @return 半角字符串
+ */
+ public static String toDBC(String input)
+ {
+ return toDBC(input, null);
+ }
+
+ /**
+ * 替换全角为半角
+ *
+ * @param text 文本
+ * @param notConvertSet 不替换的字符集合
+ * @return 替换后的字符
+ */
+ public static String toDBC(String text, Set notConvertSet)
+ {
+ char[] c = text.toCharArray();
+ for (int i = 0; i < c.length; i++)
+ {
+ if (null != notConvertSet && notConvertSet.contains(c[i]))
+ {
+ // 跳过不替换的字符
+ continue;
+ }
+
+ if (c[i] == '\u3000')
+ {
+ c[i] = ' ';
+ }
+ else if (c[i] > '\uFF00' && c[i] < '\uFF5F')
+ {
+ c[i] = (char) (c[i] - 65248);
+ }
+ }
+ return new String(c);
+ }
+
+ /**
+ * 数字金额大写转换 先写个完整的然后将如零拾替换成零
+ *
+ * @param n 数字
+ * @return 中文大写数字
+ */
+ public static String digitUppercase(double n)
+ {
+ String[] fraction = { "角", "分" };
+ String[] digit = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };
+ String[][] unit = { { "元", "万", "亿" }, { "", "拾", "佰", "仟" } };
+
+ String head = n < 0 ? "负" : "";
+ n = Math.abs(n);
+
+ String s = "";
+ for (int i = 0; i < fraction.length; i++)
+ {
+ s += (digit[(int) (Math.floor(n * 10 * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(零.)+", "");
+ }
+ if (s.length() < 1)
+ {
+ s = "整";
+ }
+ int integerPart = (int) Math.floor(n);
+
+ for (int i = 0; i < unit[0].length && integerPart > 0; i++)
+ {
+ String p = "";
+ for (int j = 0; j < unit[1].length && n > 0; j++)
+ {
+ p = digit[integerPart % 10] + unit[1][j] + p;
+ integerPart = integerPart / 10;
+ }
+ s = p.replaceAll("(零.)*零$", "").replaceAll("^$", "零") + unit[0][i] + s;
+ }
+ return head + s.replaceAll("(零.)*零元", "元").replaceFirst("(零.)+", "").replaceAll("(零.)+", "零").replaceAll("^整$", "零元整");
+ }
+}
diff --git a/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/text/StrFormatter.java b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/text/StrFormatter.java
new file mode 100644
index 0000000..2d805ea
--- /dev/null
+++ b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/text/StrFormatter.java
@@ -0,0 +1,93 @@
+package com.hnac.hzims.common.logs.text;
+
+
+import com.hnac.hzims.common.logs.utils.StringUtils;
+
+/**
+ * 字符串格式化
+ *
+ * @author ruoyi
+ */
+public class StrFormatter
+{
+ public static final String EMPTY_JSON = "{}";
+ public static final char C_BACKSLASH = '\\';
+ public static final char C_DELIM_START = '{';
+ public static final char C_DELIM_END = '}';
+
+ /**
+ * 格式化字符串
+ * 此方法只是简单将占位符 {} 按照顺序替换为参数
+ * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可
+ * 例:
+ * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b
+ * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a
+ * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b
+ *
+ * @param strPattern 字符串模板
+ * @param argArray 参数列表
+ * @return 结果
+ */
+ public static String format(final String strPattern, final Object... argArray)
+ {
+ if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray))
+ {
+ return strPattern;
+ }
+ final int strPatternLength = strPattern.length();
+
+ // 初始化定义好的长度以获得更好的性能
+ StringBuilder sbuf = new StringBuilder(strPatternLength + 50);
+
+ int handledPosition = 0;
+ int delimIndex;// 占位符所在位置
+ for (int argIndex = 0; argIndex < argArray.length; argIndex++)
+ {
+ delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition);
+ if (delimIndex == -1)
+ {
+ if (handledPosition == 0)
+ {
+ return strPattern;
+ }
+ else
+ { // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果
+ sbuf.append(strPattern, handledPosition, strPatternLength);
+ return sbuf.toString();
+ }
+ }
+ else
+ {
+ if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH)
+ {
+ if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH)
+ {
+ // 转义符之前还有一个转义符,占位符依旧有效
+ sbuf.append(strPattern, handledPosition, delimIndex - 1);
+ sbuf.append(Convert.utf8Str(argArray[argIndex]));
+ handledPosition = delimIndex + 2;
+ }
+ else
+ {
+ // 占位符被转义
+ argIndex--;
+ sbuf.append(strPattern, handledPosition, delimIndex - 1);
+ sbuf.append(C_DELIM_START);
+ handledPosition = delimIndex + 1;
+ }
+ }
+ else
+ {
+ // 正常占位符
+ sbuf.append(strPattern, handledPosition, delimIndex);
+ sbuf.append(Convert.utf8Str(argArray[argIndex]));
+ handledPosition = delimIndex + 2;
+ }
+ }
+ }
+ // 加入最后一个占位符后所有的字符
+ sbuf.append(strPattern, handledPosition, strPattern.length());
+
+ return sbuf.toString();
+ }
+}
diff --git a/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/to/SysLogTo.java b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/to/SysLogTo.java
new file mode 100644
index 0000000..930ebf9
--- /dev/null
+++ b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/to/SysLogTo.java
@@ -0,0 +1,145 @@
+package com.hnac.hzims.common.logs.to;
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * @Author WL
+ * @Version v1.0
+ * @Serial 1.0
+ * @Date 2023/3/29 13:24
+ */
+@Data
+public class SysLogTo {
+
+ private static final long serialVersionUID = 1L;
+
+
+ private Long id;
+
+ /**
+ * 租户ID
+ */
+ private String tenantId;
+
+ /**
+ * 服务器ip
+ */
+ protected String serverIp;
+
+
+ /**
+ * 服务器地址
+ */
+ protected String serverHost;
+
+ /**
+ * 服务名称
+ */
+ protected String serverName;
+
+
+ /**
+ * 环境
+ */
+ protected String env;
+
+
+ /**
+ * 操作人 id
+ */
+ private Long operationUserId;
+
+
+ /**
+ * 操作人
+ */
+ private String operationUserName;
+
+ /**
+ * 请求路径 (操作地址)
+ */
+ private String path;
+
+
+ /**
+ * 用户代理
+ */
+ protected String userAgent;
+
+
+ /**
+ * 操作方式
+ */
+ protected String method;
+
+ /**
+ * 方法类
+ */
+ protected String methodClass;
+
+ /**
+ * 方法名
+ */
+ protected String methodName;
+
+ /**
+ * 方法执行时间 消耗时间 毫秒
+ */
+ private String costTime;
+
+ /**
+ * 方法入参
+ */
+ private String parameter;
+
+ /**
+ * 操作方法
+ */
+ private String title;
+
+ /**
+ * 方法描述
+ */
+ private String action;
+
+ /**
+ * 系统类型
+ */
+ private String operatorType;
+
+ /**
+ * 操作人类别
+ */
+ private String businessType;
+
+
+ /**
+ * 返回结果
+ *
+ * @param jsonResult
+ */
+ public String jsonResult;
+
+ /**
+ * 请求的Ip
+ */
+ private String localIp;
+
+ /**
+ * 错误消息
+ */
+ private String errorMsg;
+ /**
+ * 操作时间
+ */
+ private LocalDateTime operationTime;
+
+
+ /**
+ * 操作状态(0 正常 1 异常)
+ */
+ private Integer status;
+
+}
diff --git a/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/utils/Constants.java b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/utils/Constants.java
new file mode 100644
index 0000000..2abbd51
--- /dev/null
+++ b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/utils/Constants.java
@@ -0,0 +1,130 @@
+package com.hnac.hzims.common.logs.utils;
+
+/**
+ * 通用常量信息
+ *
+ * @author ruoyi
+ */
+public class Constants
+{
+ /**
+ * UTF-8 字符集
+ */
+ public static final String UTF8 = "UTF-8";
+
+ /**
+ * GBK 字符集
+ */
+ public static final String GBK = "GBK";
+
+ /**
+ * www主域
+ */
+ public static final String WWW = "www.";
+
+ /**
+ * RMI 远程方法调用
+ */
+ public static final String LOOKUP_RMI = "rmi:";
+
+ /**
+ * LDAP 远程方法调用
+ */
+ public static final String LOOKUP_LDAP = "ldap:";
+
+ /**
+ * LDAPS 远程方法调用
+ */
+ public static final String LOOKUP_LDAPS = "ldaps:";
+
+ /**
+ * http请求
+ */
+ public static final String HTTP = "http://";
+
+ /**
+ * https请求
+ */
+ public static final String HTTPS = "https://";
+
+ /**
+ * 成功标记
+ */
+ public static final Integer SUCCESS = 200;
+
+ /**
+ * 失败标记
+ */
+ public static final Integer FAIL = 500;
+
+ /**
+ * 登录成功状态
+ */
+ public static final String LOGIN_SUCCESS_STATUS = "0";
+
+ /**
+ * 登录失败状态
+ */
+ public static final String LOGIN_FAIL_STATUS = "1";
+
+ /**
+ * 登录成功
+ */
+ public static final String LOGIN_SUCCESS = "Success";
+
+ /**
+ * 注销
+ */
+ public static final String LOGOUT = "Logout";
+
+ /**
+ * 注册
+ */
+ public static final String REGISTER = "Register";
+
+ /**
+ * 登录失败
+ */
+ public static final String LOGIN_FAIL = "Error";
+
+ /**
+ * 当前记录起始索引
+ */
+ public static final String PAGE_NUM = "pageNum";
+
+ /**
+ * 每页显示记录数
+ */
+ public static final String PAGE_SIZE = "pageSize";
+
+ /**
+ * 排序列
+ */
+ public static final String ORDER_BY_COLUMN = "orderByColumn";
+
+ /**
+ * 排序的方向 "desc" 或者 "asc".
+ */
+ public static final String IS_ASC = "isAsc";
+
+ /**
+ * 验证码有效期(分钟)
+ */
+ public static final long CAPTCHA_EXPIRATION = 2;
+
+ /**
+ * 资源映射路径 前缀
+ */
+ public static final String RESOURCE_PREFIX = "/profile";
+
+ /**
+ * 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加)
+ */
+ public static final String[] JOB_WHITELIST_STR = { "com.ruoyi" };
+
+ /**
+ * 定时任务违规的字符
+ */
+ public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml",
+ "org.springframework", "org.apache", "com.ruoyi.common.core.utils.file" };
+}
diff --git a/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/utils/StringUtils.java b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/utils/StringUtils.java
new file mode 100644
index 0000000..c0da05b
--- /dev/null
+++ b/hzims-biz-common/src/main/java/com/hnac/hzims/common/logs/utils/StringUtils.java
@@ -0,0 +1,567 @@
+package com.hnac.hzims.common.logs.utils;
+
+/**
+ * @Author WL
+ * @Version v1.0
+ * @Serial 1.0
+ * @Date 2023/3/31 15:43
+ */
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import com.hnac.hzims.common.logs.text.StrFormatter;
+import org.springframework.util.AntPathMatcher;
+
+/**
+ * 字符串工具类
+ *
+ * @author ruoyi
+ */
+public class StringUtils extends org.apache.commons.lang3.StringUtils
+{
+ /** 空字符串 */
+ private static final String NULLSTR = "";
+
+ /** 下划线 */
+ private static final char SEPARATOR = '_';
+
+ /**
+ * 获取参数不为空值
+ *
+ * @param value defaultValue 要判断的value
+ * @return value 返回值
+ */
+ public static T nvl(T value, T defaultValue)
+ {
+ return value != null ? value : defaultValue;
+ }
+
+ /**
+ * * 判断一个Collection是否为空, 包含List,Set,Queue
+ *
+ * @param coll 要判断的Collection
+ * @return true:为空 false:非空
+ */
+ public static boolean isEmpty(Collection> coll)
+ {
+ return isNull(coll) || coll.isEmpty();
+ }
+
+ /**
+ * * 判断一个Collection是否非空,包含List,Set,Queue
+ *
+ * @param coll 要判断的Collection
+ * @return true:非空 false:空
+ */
+ public static boolean isNotEmpty(Collection> coll)
+ {
+ return !isEmpty(coll);
+ }
+
+ /**
+ * * 判断一个对象数组是否为空
+ *
+ * @param objects 要判断的对象数组
+ ** @return true:为空 false:非空
+ */
+ public static boolean isEmpty(Object[] objects)
+ {
+ return isNull(objects) || (objects.length == 0);
+ }
+
+ /**
+ * * 判断一个对象数组是否非空
+ *
+ * @param objects 要判断的对象数组
+ * @return true:非空 false:空
+ */
+ public static boolean isNotEmpty(Object[] objects)
+ {
+ return !isEmpty(objects);
+ }
+
+ /**
+ * * 判断一个Map是否为空
+ *
+ * @param map 要判断的Map
+ * @return true:为空 false:非空
+ */
+ public static boolean isEmpty(Map, ?> map)
+ {
+ return isNull(map) || map.isEmpty();
+ }
+
+ /**
+ * * 判断一个Map是否为空
+ *
+ * @param map 要判断的Map
+ * @return true:非空 false:空
+ */
+ public static boolean isNotEmpty(Map, ?> map)
+ {
+ return !isEmpty(map);
+ }
+
+ /**
+ * * 判断一个字符串是否为空串
+ *
+ * @param str String
+ * @return true:为空 false:非空
+ */
+ public static boolean isEmpty(String str)
+ {
+ return isNull(str) || NULLSTR.equals(str.trim());
+ }
+
+ /**
+ * * 判断一个字符串是否为非空串
+ *
+ * @param str String
+ * @return true:非空串 false:空串
+ */
+ public static boolean isNotEmpty(String str)
+ {
+ return !isEmpty(str);
+ }
+
+ /**
+ * * 判断一个对象是否为空
+ *
+ * @param object Object
+ * @return true:为空 false:非空
+ */
+ public static boolean isNull(Object object)
+ {
+ return object == null;
+ }
+
+ /**
+ * * 判断一个对象是否非空
+ *
+ * @param object Object
+ * @return true:非空 false:空
+ */
+ public static boolean isNotNull(Object object)
+ {
+ return !isNull(object);
+ }
+
+ /**
+ * * 判断一个对象是否是数组类型(Java基本型别的数组)
+ *
+ * @param object 对象
+ * @return true:是数组 false:不是数组
+ */
+ public static boolean isArray(Object object)
+ {
+ return isNotNull(object) && object.getClass().isArray();
+ }
+
+ /**
+ * 去空格
+ */
+ public static String trim(String str)
+ {
+ return (str == null ? "" : str.trim());
+ }
+
+ /**
+ * 截取字符串
+ *
+ * @param str 字符串
+ * @param start 开始
+ * @return 结果
+ */
+ public static String substring(final String str, int start)
+ {
+ if (str == null)
+ {
+ return NULLSTR;
+ }
+
+ if (start < 0)
+ {
+ start = str.length() + start;
+ }
+
+ if (start < 0)
+ {
+ start = 0;
+ }
+ if (start > str.length())
+ {
+ return NULLSTR;
+ }
+
+ return str.substring(start);
+ }
+
+ /**
+ * 截取字符串
+ *
+ * @param str 字符串
+ * @param start 开始
+ * @param end 结束
+ * @return 结果
+ */
+ public static String substring(final String str, int start, int end)
+ {
+ if (str == null)
+ {
+ return NULLSTR;
+ }
+
+ if (end < 0)
+ {
+ end = str.length() + end;
+ }
+ if (start < 0)
+ {
+ start = str.length() + start;
+ }
+
+ if (end > str.length())
+ {
+ end = str.length();
+ }
+
+ if (start > end)
+ {
+ return NULLSTR;
+ }
+
+ if (start < 0)
+ {
+ start = 0;
+ }
+ if (end < 0)
+ {
+ end = 0;
+ }
+
+ return str.substring(start, end);
+ }
+
+ /**
+ * 判断是否为空,并且不是空白字符
+ *
+ * @param str 要判断的value
+ * @return 结果
+ */
+ public static boolean hasText(String str)
+ {
+ return (str != null && !str.isEmpty() && containsText(str));
+ }
+
+ private static boolean containsText(CharSequence str)
+ {
+ int strLen = str.length();
+ for (int i = 0; i < strLen; i++)
+ {
+ if (!Character.isWhitespace(str.charAt(i)))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * 格式化文本, {} 表示占位符
+ * 此方法只是简单将占位符 {} 按照顺序替换为参数
+ * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可
+ * 例:
+ * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b
+ * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a
+ * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b
+ *
+ * @param template 文本模板,被替换的部分用 {} 表示
+ * @param params 参数值
+ * @return 格式化后的文本
+ */
+ public static String format(String template, Object... params)
+ {
+ if (isEmpty(params) || isEmpty(template))
+ {
+ return template;
+ }
+ return StrFormatter.format(template, params);
+ }
+
+ /**
+ * 是否为http(s)://开头
+ *
+ * @param link 链接
+ * @return 结果
+ */
+ public static boolean ishttp(String link)
+ {
+ return startsWithAny(link, Constants.HTTP, Constants.HTTPS);
+ }
+
+ /**
+ * 判断给定的set列表中是否包含数组array 判断给定的数组array中是否包含给定的元素value
+ *
+ * @param array 给定的数组
+ * @return boolean 结果
+ */
+ public static boolean containsAny(Collection collection, String... array)
+ {
+ if (isEmpty(collection) || isEmpty(array))
+ {
+ return false;
+ }
+ else
+ {
+ for (String str : array)
+ {
+ if (collection.contains(str))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ /**
+ * 驼峰转下划线命名
+ */
+ public static String toUnderScoreCase(String str)
+ {
+ if (str == null)
+ {
+ return null;
+ }
+ StringBuilder sb = new StringBuilder();
+ // 前置字符是否大写
+ boolean preCharIsUpperCase = true;
+ // 当前字符是否大写
+ boolean curreCharIsUpperCase = true;
+ // 下一字符是否大写
+ boolean nexteCharIsUpperCase = true;
+ for (int i = 0; i < str.length(); i++)
+ {
+ char c = str.charAt(i);
+ if (i > 0)
+ {
+ preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1));
+ }
+ else
+ {
+ preCharIsUpperCase = false;
+ }
+
+ curreCharIsUpperCase = Character.isUpperCase(c);
+
+ if (i < (str.length() - 1))
+ {
+ nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));
+ }
+
+ if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase)
+ {
+ sb.append(SEPARATOR);
+ }
+ else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase)
+ {
+ sb.append(SEPARATOR);
+ }
+ sb.append(Character.toLowerCase(c));
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * 是否包含字符串
+ *
+ * @param str 验证字符串
+ * @param strs 字符串组
+ * @return 包含返回true
+ */
+ public static boolean inStringIgnoreCase(String str, String... strs)
+ {
+ if (str != null && strs != null)
+ {
+ for (String s : strs)
+ {
+ if (str.equalsIgnoreCase(trim(s)))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld
+ *
+ * @param name 转换前的下划线大写方式命名的字符串
+ * @return 转换后的驼峰式命名的字符串
+ */
+ public static String convertToCamelCase(String name)
+ {
+ StringBuilder result = new StringBuilder();
+ // 快速检查
+ if (name == null || name.isEmpty())
+ {
+ // 没必要转换
+ return "";
+ }
+ else if (!name.contains("_"))
+ {
+ // 不含下划线,仅将首字母大写
+ return name.substring(0, 1).toUpperCase() + name.substring(1);
+ }
+ // 用下划线将原始字符串分割
+ String[] camels = name.split("_");
+ for (String camel : camels)
+ {
+ // 跳过原始字符串中开头、结尾的下换线或双重下划线
+ if (camel.isEmpty())
+ {
+ continue;
+ }
+ // 首字母大写
+ result.append(camel.substring(0, 1).toUpperCase());
+ result.append(camel.substring(1).toLowerCase());
+ }
+ return result.toString();
+ }
+
+ /**
+ * 驼峰式命名法
+ * 例如:user_name->userName
+ */
+ public static String toCamelCase(String s)
+ {
+ if (s == null)
+ {
+ return null;
+ }
+ if (s.indexOf(SEPARATOR) == -1)
+ {
+ return s;
+ }
+ s = s.toLowerCase();
+ StringBuilder sb = new StringBuilder(s.length());
+ boolean upperCase = false;
+ for (int i = 0; i < s.length(); i++)
+ {
+ char c = s.charAt(i);
+
+ if (c == SEPARATOR)
+ {
+ upperCase = true;
+ }
+ else if (upperCase)
+ {
+ sb.append(Character.toUpperCase(c));
+ upperCase = false;
+ }
+ else
+ {
+ sb.append(c);
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * 查找指定字符串是否匹配指定字符串列表中的任意一个字符串
+ *
+ * @param str 指定字符串
+ * @param strs 需要检查的字符串数组
+ * @return 是否匹配
+ */
+ public static boolean matches(String str, List strs)
+ {
+ if (isEmpty(str) || isEmpty(strs))
+ {
+ return false;
+ }
+ for (String pattern : strs)
+ {
+ if (isMatch(pattern, str))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * 判断url是否与规则配置:
+ * ? 表示单个字符;
+ * * 表示一层路径内的任意字符串,不可跨层级;
+ * ** 表示任意层路径;
+ *
+ * @param pattern 匹配规则
+ * @param url 需要匹配的url
+ * @return
+ */
+ public static boolean isMatch(String pattern, String url)
+ {
+ AntPathMatcher matcher = new AntPathMatcher();
+ return matcher.match(pattern, url);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static T cast(Object obj)
+ {
+ return (T) obj;
+ }
+
+ /**
+ * 数字左边补齐0,使之达到指定长度。注意,如果数字转换为字符串后,长度大于size,则只保留 最后size个字符。
+ *
+ * @param num 数字对象
+ * @param size 字符串指定长度
+ * @return 返回数字的字符串格式,该字符串为指定长度。
+ */
+ public static final String padl(final Number num, final int size)
+ {
+ return padl(num.toString(), size, '0');
+ }
+
+ /**
+ * 字符串左补齐。如果原始字符串s长度大于size,则只保留最后size个字符。
+ *
+ * @param s 原始字符串
+ * @param size 字符串指定长度
+ * @param c 用于补齐的字符
+ * @return 返回指定长度的字符串,由原字符串左补齐或截取得到。
+ */
+ public static final String padl(final String s, final int size, final char c)
+ {
+ final StringBuilder sb = new StringBuilder(size);
+ if (s != null)
+ {
+ final int len = s.length();
+ if (s.length() <= size)
+ {
+ for (int i = size - len; i > 0; i--)
+ {
+ sb.append(c);
+ }
+ sb.append(s);
+ }
+ else
+ {
+ return s.substring(len - size, len);
+ }
+ }
+ else
+ {
+ for (int i = size; i > 0; i--)
+ {
+ sb.append(c);
+ }
+ }
+ return sb.toString();
+ }
+}
diff --git a/hzims-service/hzims-middle/src/main/java/com/hnac/hzims/middle/MiddleApplication.java b/hzims-service/hzims-middle/src/main/java/com/hnac/hzims/middle/MiddleApplication.java
new file mode 100644
index 0000000..4b48c6c
--- /dev/null
+++ b/hzims-service/hzims-middle/src/main/java/com/hnac/hzims/middle/MiddleApplication.java
@@ -0,0 +1,21 @@
+package com.hnac.hzims.middle;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springblade.core.cloud.feign.EnableBladeFeign;
+import org.springblade.core.launch.BladeApplication;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.SpringCloudApplication;
+import org.springframework.context.annotation.ComponentScan;
+
+@EnableBladeFeign
+@SpringCloudApplication
+@MapperScan("com.hnac.hzims.*.**.mapper.**")
+@ComponentScan(basePackages = {"com.hnac.*"})
+public class MiddleApplication {
+
+ public static void main(String[] args) {
+ BladeApplication.run("hzims-middle", MiddleApplication.class, args);
+ }
+
+}
diff --git a/hzims-service/hzims-middle/src/main/java/com/hnac/hzims/middle/mybatisplus/CodeGenerator.java b/hzims-service/hzims-middle/src/main/java/com/hnac/hzims/middle/mybatisplus/CodeGenerator.java
new file mode 100644
index 0000000..b3d63f6
--- /dev/null
+++ b/hzims-service/hzims-middle/src/main/java/com/hnac/hzims/middle/mybatisplus/CodeGenerator.java
@@ -0,0 +1,104 @@
+package com.hnac.hzims.middle.mybatisplus;
+
+import com.baomidou.mybatisplus.generator.AutoGenerator;
+import com.baomidou.mybatisplus.generator.InjectionConfig;
+import com.baomidou.mybatisplus.generator.config.*;
+import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @Author WL
+ * @Version v1.0
+ * @Serial 1.0
+ * @Date 2023/4/4 9:07
+ */
+public class CodeGenerator {
+
+
+ public static void main(String[] args) {
+ // 代码生成器
+ AutoGenerator mpg = new AutoGenerator();
+
+ // 全局配置
+ GlobalConfig gc = new GlobalConfig();
+ String projectPath = System.getProperty("user.dir") + "/hzims-service/hzims-middle";
+ gc.setOutputDir(projectPath + "/src/main/java");
+ gc.setAuthor("dfy");
+ gc.setOpen(false);
+ // gc.setSwagger2(true); 实体属性 Swagger2 注解
+ mpg.setGlobalConfig(gc);
+
+ // 数据源配置
+ DataSourceConfig dsc = new DataSourceConfig();
+ dsc.setUrl("jdbc:mysql://192.168.1.20:3576/dev_hzims_middle?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&tinyInt1isBit=false&allowMultiQueries=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true");
+ // dsc.setSchemaName("public");
+ dsc.setDriverName("com.mysql.cj.jdbc.Driver");
+ dsc.setUsername("root");
+ dsc.setPassword("123");
+ mpg.setDataSource(dsc);
+
+ // 包配置
+ PackageConfig pc = new PackageConfig();
+ pc.setModuleName("systemlog");
+ pc.setParent("com.hnac.hzims.middle");
+ mpg.setPackageInfo(pc);
+
+ // 自定义配置
+ InjectionConfig cfg = new InjectionConfig() {
+ @Override
+ public void initMap() {
+ // to do nothing
+ }
+ };
+
+ // 如果模板引擎是 freemarker
+ String templatePath = "/templates/mapper.xml.ftl";
+ // 如果模板引擎是 velocity
+ // String templatePath = "/templates/mapper.xml.vm";
+
+ // 自定义输出配置
+ List focList = new ArrayList<>();
+ cfg.setFileOutConfigList(focList);
+ mpg.setCfg(cfg);
+
+ // 配置模板
+ TemplateConfig templateConfig = new TemplateConfig();
+
+ // 配置自定义输出模板
+ //指定自定义模板路径,注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
+ // templateConfig.setEntity("templates/entity2.java");
+ // templateConfig.setService();
+ // templateConfig.setController();
+
+ // templateConfig.setXml(null);
+ mpg.setTemplate(templateConfig);
+
+ // 策略配置
+ StrategyConfig strategy = new StrategyConfig();
+ strategy.setNaming(NamingStrategy.underline_to_camel);
+ strategy.setColumnNaming(NamingStrategy.underline_to_camel);
+ // strategy.setSuperEntityClass("你自己的父类实体,没有就不用设置!");
+ strategy.setEntityLombokModel(true);
+ strategy.setRestControllerStyle(true);
+ strategy.setEntityBooleanColumnRemoveIsPrefix(true);
+ strategy.setEntityLombokModel(true);
+ strategy.setEntitySerialVersionUID(true);
+ strategy.setChainModel(true);
+ strategy.setEntityTableFieldAnnotationEnable(true);
+ // strategy.setFieldPrefix("hzims_");
+ // 公共父类
+ // strategy.setSuperControllerClass("你自己的父类控制器,没有就不用设置!");
+ // 写于父类中的公共字段
+ // strategy.setSuperEntityColumns("id");
+ strategy.setInclude("hzims_sys_log");
+ strategy.setControllerMappingHyphenStyle(true);
+ strategy.setTablePrefix("hzims_");
+ mpg.setStrategy(strategy);
+ // mpg.setTemplateEngine(new FreemarkerTemplateEngine());
+ mpg.execute();
+ }
+
+}
+
diff --git a/hzims-service/hzims-middle/src/main/java/com/hnac/hzims/middle/systemlog/controller/SysLogController.java b/hzims-service/hzims-middle/src/main/java/com/hnac/hzims/middle/systemlog/controller/SysLogController.java
new file mode 100644
index 0000000..b40b640
--- /dev/null
+++ b/hzims-service/hzims-middle/src/main/java/com/hnac/hzims/middle/systemlog/controller/SysLogController.java
@@ -0,0 +1,60 @@
+package com.hnac.hzims.middle.systemlog.controller;
+
+
+
+import com.hnac.hzims.common.logs.to.SysLogTo;
+import com.hnac.hzims.middle.systemlog.entity.SysLog;
+import com.hnac.hzims.middle.systemlog.service.SysLogService;
+import io.swagger.annotations.Api;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+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;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ *
+ * 前端控制器
+ *
+ *
+ * @author dfy
+ * @since 2023-04-04
+ */
+@Api(tags = "系统日志")
+@Slf4j
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/systemlog/sys-log")
+public class SysLogController {
+
+ private final SysLogService sysLogService;
+
+
+ /**
+ * 保存操作日志
+ * @param sysLogToList
+ */
+ @PostMapping("/batchSave")
+ public void saveBatch(@RequestBody List sysLogToList) {
+ //数据转换
+ List collect = sysLogToList.stream().map(item -> {
+ SysLog sysLog = new SysLog();
+ BeanUtils.copyProperties(item, sysLog);
+ return sysLog;
+ }).collect(Collectors.toList());
+ //添加到数据库
+ boolean save = sysLogService.saveBatch(collect);
+ if (save) {
+ log.info("操作日志新增成功 ~~~");
+ return;
+ }
+ log.info("操作日志新增失败 ~~~");
+ throw new IllegalArgumentException("操作日志新增失败");
+ }
+}
+
diff --git a/hzims-service/hzims-middle/src/main/java/com/hnac/hzims/middle/systemlog/entity/SysLog.java b/hzims-service/hzims-middle/src/main/java/com/hnac/hzims/middle/systemlog/entity/SysLog.java
new file mode 100644
index 0000000..7c8c262
--- /dev/null
+++ b/hzims-service/hzims-middle/src/main/java/com/hnac/hzims/middle/systemlog/entity/SysLog.java
@@ -0,0 +1,191 @@
+package com.hnac.hzims.middle.systemlog.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.time.LocalDateTime;
+import java.sql.Blob;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ *
+ *
+ *
+ *
+ * @author dfy
+ * @since 2023-04-04
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("hzims_sys_log")
+public class SysLog implements Serializable {
+
+ private static final long serialVersionUID=1L;
+
+ /**
+ * 操作日志编号
+ */
+ @TableField("id")
+ private Long id;
+
+ /**
+ * 租户ID
+ */
+ @TableField("tenant_id")
+ private String tenantId;
+
+ /**
+ * 服务器ip
+ */
+ @TableField("server_ip")
+ private String serverIp;
+
+ /**
+ * 服务器地址
+ */
+ @TableField("server_host")
+ private String serverHost;
+
+ /**
+ * 服务名称
+ */
+ @TableField("server_name")
+ private String serverName;
+
+ /**
+ * 环境
+ */
+ @TableField("env")
+ private String env;
+
+ /**
+ * 操作人Id
+ */
+ @TableField("operation_user_id")
+ private Long operationUserId;
+
+ /**
+ * 操作人名称
+ */
+ @TableField("operation_user_name")
+ private String operationUserName;
+
+ /**
+ * 请求路径 (操作地址)
+ */
+ @TableField("path")
+ private String path;
+
+ /**
+ * 用户代理
+ */
+ @TableField("user_agent")
+ private String userAgent;
+
+ /**
+ * 操作方式
+ */
+ @TableField("method")
+ private String method;
+
+ /**
+ * 方法类
+ */
+ @TableField("method_class")
+ private String methodClass;
+
+ /**
+ * 方法名
+ */
+ @TableField("method_name")
+ private String methodName;
+
+ /**
+ * 方法执行时间 消耗时间 毫秒
+ */
+ @TableField("cost_time")
+ private String costTime;
+
+ /**
+ * 方法入参
+ */
+ @TableField("parameter")
+ private String parameter;
+
+ /**
+ * 操作方法
+ */
+ @TableField("title")
+ private String title;
+
+ /**
+ * 方法描述
+ */
+ @TableField("action")
+ private String action;
+
+ /**
+ * 系统类型
+ */
+ @TableField("operator_type")
+ private String operatorType;
+
+ /**
+ * 操作人类别
+ */
+ @TableField("business_type")
+ private String businessType;
+
+ /**
+ * 返回结果
+ */
+ @TableField("json_result")
+ private String jsonResult;
+
+ /**
+ * 请求的Ip
+ */
+ @TableField("local_ip")
+ private String localIp;
+
+ /**
+ * 错误消息
+ */
+ @TableField("error_msg")
+ private String errorMsg;
+
+ /**
+ * 操作时间
+ */
+ @TableField("operation_time")
+ private LocalDateTime operationTime;
+
+ /**
+ * 操作状态(0 正常 1 异常)
+ */
+ @TableField("status")
+ private Integer status;
+
+ /**
+ * 创建时间
+ */
+ @TableField("create_time")
+ private LocalDateTime createTime;
+
+ /**
+ * 更新时间
+ */
+ @TableField("update_time")
+ private LocalDateTime updateTime;
+
+ /**
+ * 逻辑删除 (0 可用 1 删除)
+ */
+ @TableField("is_deleted")
+ private Integer isDeleted;
+
+
+}
diff --git a/hzims-service/hzims-middle/src/main/java/com/hnac/hzims/middle/systemlog/mapper/SysLogMapper.java b/hzims-service/hzims-middle/src/main/java/com/hnac/hzims/middle/systemlog/mapper/SysLogMapper.java
new file mode 100644
index 0000000..009f3a1
--- /dev/null
+++ b/hzims-service/hzims-middle/src/main/java/com/hnac/hzims/middle/systemlog/mapper/SysLogMapper.java
@@ -0,0 +1,16 @@
+package com.hnac.hzims.middle.systemlog.mapper;
+
+import com.hnac.hzims.middle.systemlog.entity.SysLog;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ *
+ * Mapper 接口
+ *
+ *
+ * @author dfy
+ * @since 2023-04-04
+ */
+public interface SysLogMapper extends BaseMapper {
+
+}
diff --git a/hzims-service/hzims-middle/src/main/java/com/hnac/hzims/middle/systemlog/service/SysLogService.java b/hzims-service/hzims-middle/src/main/java/com/hnac/hzims/middle/systemlog/service/SysLogService.java
new file mode 100644
index 0000000..e409a1e
--- /dev/null
+++ b/hzims-service/hzims-middle/src/main/java/com/hnac/hzims/middle/systemlog/service/SysLogService.java
@@ -0,0 +1,16 @@
+package com.hnac.hzims.middle.systemlog.service;
+
+import com.hnac.hzims.middle.systemlog.entity.SysLog;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ *
+ * 服务类
+ *
+ *
+ * @author dfy
+ * @since 2023-04-04
+ */
+public interface SysLogService extends IService {
+
+}
diff --git a/hzims-service/hzims-middle/src/main/java/com/hnac/hzims/middle/systemlog/service/impl/SysLogServiceImpl.java b/hzims-service/hzims-middle/src/main/java/com/hnac/hzims/middle/systemlog/service/impl/SysLogServiceImpl.java
new file mode 100644
index 0000000..a889cce
--- /dev/null
+++ b/hzims-service/hzims-middle/src/main/java/com/hnac/hzims/middle/systemlog/service/impl/SysLogServiceImpl.java
@@ -0,0 +1,20 @@
+package com.hnac.hzims.middle.systemlog.service.impl;
+
+import com.hnac.hzims.middle.systemlog.entity.SysLog;
+import com.hnac.hzims.middle.systemlog.mapper.SysLogMapper;
+import com.hnac.hzims.middle.systemlog.service.SysLogService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ * 服务实现类
+ *
+ *
+ * @author dfy
+ * @since 2023-04-04
+ */
+@Service
+public class SysLogServiceImpl extends ServiceImpl implements SysLogService {
+
+}
diff --git a/hzims-service/hzims-middle/src/main/resources/application.yml b/hzims-service/hzims-middle/src/main/resources/application.yml
new file mode 100644
index 0000000..6e69e09
--- /dev/null
+++ b/hzims-service/hzims-middle/src/main/resources/application.yml
@@ -0,0 +1,38 @@
+#服务器端口
+server:
+ port: 8400
+
+#数据源配置
+spring:
+ #排除DruidDataSourceAutoConfigure
+ autoconfigure:
+ exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
+ datasource:
+ url: jdbc:mysql://192.168.1.20:3576/dev_hzims_middle?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&tinyInt1isBit=false&allowMultiQueries=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true
+ username: root
+ password: 123
+
+
+#mybatis-plus配置
+mybatis-plus:
+ mapper-locations:
+ - classpath:com/hnac/hzims/**/mapper/*Mapper.xml
+ - classpath:/mapper/*Mapper.xml
+ #实体扫描,多个package用逗号或者分号分隔
+ typeAliasesPackage: com.hnac.hzims.**.entity
+
+#swagger扫描路径配置
+swagger:
+ base-packages:
+ - org.springbalde
+ - com.hnac
+
+blade:
+ data-scope:
+ enabled: false
+ lock:
+ enabled: true
+ address: redis://192.168.1.20:3577
+ password: 1qaz2WSX@redis
+ database: 0
+ ssl: false
diff --git a/hzims-service/hzims-middle/src/main/resources/bootstrap.yml b/hzims-service/hzims-middle/src/main/resources/bootstrap.yml
new file mode 100644
index 0000000..0abf99a
--- /dev/null
+++ b/hzims-service/hzims-middle/src/main/resources/bootstrap.yml
@@ -0,0 +1,7 @@
+spring:
+ cloud:
+ nacos:
+ discovery:
+ server-addr: 175.6.40.67:10042
+
+
diff --git a/hzims-service/hzims-middle/src/main/resources/mapper/SysLogMapper.xml b/hzims-service/hzims-middle/src/main/resources/mapper/SysLogMapper.xml
new file mode 100644
index 0000000..698fb08
--- /dev/null
+++ b/hzims-service/hzims-middle/src/main/resources/mapper/SysLogMapper.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/hzims-service/hzims-middle/src/test/java/com/hnac/hzims/middle/MiddleApplicationTests.java b/hzims-service/hzims-middle/src/test/java/com/hnac/hzims/middle/MiddleApplicationTests.java
new file mode 100644
index 0000000..ad2db3e
--- /dev/null
+++ b/hzims-service/hzims-middle/src/test/java/com/hnac/hzims/middle/MiddleApplicationTests.java
@@ -0,0 +1,15 @@
+package com.hnac.hzims.middle;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class MiddleApplicationTests {
+
+ @Test
+ void contextLoads() {
+
+ System.out.println("1");
+ }
+
+}
diff --git a/hzims-service/pom.xml b/hzims-service/pom.xml
index 9cfd5d3..cdace60 100644
--- a/hzims-service/pom.xml
+++ b/hzims-service/pom.xml
@@ -26,6 +26,7 @@
message
ticket
weather
+ hzims-middle
diff --git a/hzims-service/ticket/pom.xml b/hzims-service/ticket/pom.xml
index 57d9837..de7d2cc 100644
--- a/hzims-service/ticket/pom.xml
+++ b/hzims-service/ticket/pom.xml
@@ -275,6 +275,12 @@
redis.clients
jedis
+
+ com.aliyun
+ aliyun-java-sdk-ecs
+ 4.2.0
+ compile
+
diff --git a/hzims-service/ticket/src/main/java/com/hnac/hzims/ticket/TicketApplication.java b/hzims-service/ticket/src/main/java/com/hnac/hzims/ticket/TicketApplication.java
index 5f99b44..6a636a8 100644
--- a/hzims-service/ticket/src/main/java/com/hnac/hzims/ticket/TicketApplication.java
+++ b/hzims-service/ticket/src/main/java/com/hnac/hzims/ticket/TicketApplication.java
@@ -8,6 +8,7 @@ import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
import javax.annotation.Resource;
@@ -17,8 +18,9 @@ import javax.annotation.Resource;
@EnableBladeFeign
@SpringCloudApplication
@MapperScan("com.hnac.hzims.**.mapper.**")
-@ComponentScan(basePackages = {"com.hnac.*"})
+@ComponentScan(basePackages = {"com.hnac"})
@Resource
+@EnableAspectJAutoProxy(exposeProxy = true)
public class TicketApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
diff --git a/hzims-service/ticket/src/main/java/com/hnac/hzims/ticket/aop/ApiLogAspect.java b/hzims-service/ticket/src/main/java/com/hnac/hzims/ticket/aop/ApiLogAspect.java
deleted file mode 100644
index 67ff905..0000000
--- a/hzims-service/ticket/src/main/java/com/hnac/hzims/ticket/aop/ApiLogAspect.java
+++ /dev/null
@@ -1,267 +0,0 @@
-package com.hnac.hzims.ticket.aop;
-
-import com.alibaba.fastjson.JSON;
-import com.hnac.hzims.common.utils.IPUtils;
-import lombok.extern.slf4j.Slf4j;
-import org.aspectj.lang.JoinPoint;
-import org.aspectj.lang.ProceedingJoinPoint;
-import org.aspectj.lang.annotation.AfterReturning;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Before;
-import org.aspectj.lang.annotation.Pointcut;
-import org.aspectj.lang.reflect.CodeSignature;
-import org.springframework.stereotype.Component;
-import org.springframework.web.context.request.RequestAttributes;
-import org.springframework.web.context.request.RequestContextHolder;
-import org.springframework.web.context.request.ServletRequestAttributes;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSession;
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * @author dfy
- * @date 2023/3/29
- * @description: 操作日志切面处理类
- */
-@Aspect
-@Component
-@Slf4j
-public class ApiLogAspect {
-
-
- /**
- * 请求地址
- */
- private String requestPath = null;
- /**
- * 开始时间
- */
- private long startTimeMillis = 0;
- /**
- * 结束时间
- */
- private long endTimeMillis = 0;
- /**
- * 操作人
- */
- private String user = null;
-
- /**
- * 请求
- */
- private HttpServletRequest request = null;
-
-
-
-
- /**
- * 设置操作日志切入点 在注解的位置切入代码
- */
- @Pointcut("@annotation(com.hnac.hzims.ticket.aop.OperationAnnotation)")
- public void logPointCut() {
- }
-
- /**
- * @param joinPoint
- * @Description 前置通知 方法调用前触发 记录开始时间,从session中获取操作人
- */
- @Before(value = "logPointCut()")
- public void before(JoinPoint joinPoint) {
- log.info("前置通知");
- startTimeMillis = System.currentTimeMillis();
- }
-
- /**
- * @param joinPoint
- * @Description 后置通知 方法调用后触发 记录结束时间 ,操作人 ,入参等
- */
- @AfterReturning(value = "logPointCut()", returning = "keys")
- public void after(JoinPoint joinPoint, Object keys) {
- log.info("后置通知");
- request = getHttpServletRequest();
- String targetName = joinPoint.getTarget().getClass().getName();
- String methodName = joinPoint.getSignature().getName();
- Object[] arguments = joinPoint.getArgs();
- Class> targetClass = null;
- try {
- targetClass = Class.forName(targetName);
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- Method[] methods = targetClass.getMethods();
- String title;
- String action;
- Integer sysType;
- String opType;
- Class>[] clazzs;
- for (Method method : methods) {
- if (method.getName().equals(methodName)) {
- clazzs = method.getParameterTypes();
- if (clazzs != null && clazzs.length == arguments.length && method.getAnnotation(OperationAnnotation.class) != null) {
-
- // 获取请求的类名
- String className = joinPoint.getTarget().getClass().getName();
- methodName = className + "." + methodName;
-
-
- request = getHttpServletRequest();
- requestPath = request.getServletPath();
- HttpSession session = request.getSession();
- OperationAnnotation annotation = method.getAnnotation(OperationAnnotation.class);
- title = annotation.content();
- action = annotation.action();
- sysType = annotation.sysType();
- opType = annotation.operatingType();
- endTimeMillis = System.currentTimeMillis();
-
- if (user == null) {
- user = "dfy";
- }
-
- SysLog sysLog = new SysLog();
- sysLog.setOperRespParam(JSON.toJSONString(keys)); // 返回结果
- sysLog.setOperIp(IPUtils.getIpAddress(request)); // 请求IP
- sysLog.setOperationUser(user);
- sysLog.setTime((endTimeMillis - startTimeMillis) + "ms");
- sysLog.setPath(requestPath);
- sysLog.setTitle(title);
- sysLog.setAction(action);
- sysLog.setSysType(sysType);
- sysLog.setOperatingType(opType);
- sysLog.setParameter(getNameAndValue(joinPoint).toString());
- System.out.println("增加参数:" + sysLog);
- // logMapper.save(sysLog);
- }
- }
- }
- }
-
-
- /**
- * @param joinPoint
- * @return
- * @Description 获取入参方法参数
- */
- public Map getNameAndValue(JoinPoint joinPoint) {
- Map param = new HashMap<>(16);
- Object[] paramValues = joinPoint.getArgs();
- String[] paramNames = ((CodeSignature) joinPoint.getSignature()).getParameterNames();
- for (int i = 0; i < paramNames.length; i++) {
- if (paramValues[i] instanceof Integer || paramValues[i] instanceof String) {
- param.put(paramNames[i], paramValues[i]);
- }
- }
- return param;
- }
-
-
- /**
- * @Description: 获取request
- */
- public HttpServletRequest getHttpServletRequest() {
- RequestAttributes ra = RequestContextHolder.getRequestAttributes();
- ServletRequestAttributes sra = (ServletRequestAttributes) ra;
- HttpServletRequest request = sra.getRequest();
- return request;
- }
-
- /**
- * @param joinPoint
- * @return 环绕通知
- * @throws Throwable
- */
- public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
- log.info("环绕通知");
- return null;
- }
-
- // /**
- // * @param joinPoint
- // * @Description 异常通知
- // */
- // @AfterThrowing(pointcut = "operExceptionLogPoinCut()", throwing = "e")
- // public void throwing(JoinPoint joinPoint, Throwable e) {
- // log.info("异常通知");
- // // 获取RequestAttributes
- // RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
- // // 从获取RequestAttributes中获取HttpServletRequest的信息
- // HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
- //
- // SysExceptionLog excepLog = new SysExceptionLog();
- // try {
- // // 从切面织入点处通过反射机制获取织入点处的方法
- // MethodSignature signature = (MethodSignature) joinPoint.getSignature();
- // // 获取切入点所在的方法
- // Method method = signature.getMethod();
- // // 获取请求的类名
- // String className = joinPoint.getTarget().getClass().getName();
- // // 获取请求的方法名
- // String methodName = method.getName();
- // methodName = className + "." + methodName;
- // // 请求的参数
- // Map rtnMap = converMap(request.getParameterMap());
- // // 将参数所在的数组转换成json
- // String params = JSON.toJSONString(rtnMap);
- // //请求参数
- // excepLog.setExcRequParam(params);
- // // 请求方法名
- // excepLog.setOperMethod(methodName);
- // // 异常名称
- // excepLog.setExcName(e.getClass().getName());
- // // 异常信息
- // excepLog.setExcMessage(stackTraceToString(e.getClass().getName(), e.getMessage(), e.getStackTrace()));
- // // 操作员ID
- // excepLog.setOperUserId("2L");
- // // 操作员名称
- // excepLog.setOperUserName("duanfeiyu");
- // // 操作URI
- // excepLog.setOperUri(request.getRequestURI());
- // // 操作员IP
- // excepLog.setOperIp(IPUtil.localHostIP());
- // // 操作版本号
- // excepLog.setOperVer(operVer);
- // // 发生异常时间
- // excepLog.setOperCreateTime(new Date());
- //
- //
- // sysExceptionLogService.save(excepLog);
- //
- // } catch (Exception e2) {
- // e2.printStackTrace();
- // }
-
- // }
-
-
- /**
- * 转换request 请求参数
- *
- * @param paramMap request获取的参数数组
- */
- public Map converMap(Map paramMap) {
- Map rtnMap = new HashMap();
- for (String key : paramMap.keySet()) {
- rtnMap.put(key, paramMap.get(key)[0]);
- }
- return rtnMap;
- }
-
- /**
- * 转换异常信息为字符串
- *
- * @param exceptionName 异常名称
- * @param exceptionMessage 异常信息
- * @param elements 堆栈信息
- */
- public String stackTraceToString(String exceptionName, String exceptionMessage, StackTraceElement[] elements) {
- StringBuffer strbuff = new StringBuffer();
- for (StackTraceElement stet : elements) {
- strbuff.append(stet + "\n");
- }
- String message = exceptionName + ":" + exceptionMessage + "\n\t" + strbuff.toString();
- return message;
- }
-}
diff --git a/hzims-service/ticket/src/main/java/com/hnac/hzims/ticket/aop/OperationAnnotation.java b/hzims-service/ticket/src/main/java/com/hnac/hzims/ticket/aop/OperationAnnotation.java
deleted file mode 100644
index c0f7bf1..0000000
--- a/hzims-service/ticket/src/main/java/com/hnac/hzims/ticket/aop/OperationAnnotation.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.hnac.hzims.ticket.aop;
-
-import org.springframework.stereotype.Component;
-
-import java.lang.annotation.*;
-
-/**
- * @Author WL
- * @Version v1.0
- * @Serial 1.0
- * @Date 2023/3/29 11:38
- */
-@Documented
-@Component
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD)
-public @interface OperationAnnotation {
-
- /**
- * 操作模块
- * @return
- */
- String content();
-
- /**
- * 系统类型(网页端,app端)
- */
- int sysType() default 0;
-
-
- /**
- * 操作类型
- * @return
- */
- String operatingType() default "";
-
- /**
- * 功能说明
- * @return
- */
- String action() default "";
-}
diff --git a/hzims-service/ticket/src/main/java/com/hnac/hzims/ticket/aop/SysLog.java b/hzims-service/ticket/src/main/java/com/hnac/hzims/ticket/aop/SysLog.java
deleted file mode 100644
index b138a3e..0000000
--- a/hzims-service/ticket/src/main/java/com/hnac/hzims/ticket/aop/SysLog.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package com.hnac.hzims.ticket.aop;
-
-import lombok.Data;
-
-/**
- * @Author WL
- * @Version v1.0
- * @Serial 1.0
- * @Date 2023/3/29 13:24
- */
-@Data
-public class SysLog {
-
- private static final long serialVersionUID = 1L;
-
-
- private Long id;
-
- /**
- * 操作人
- */
- private String operationUser;
-
- /**
- * 请求路径
- */
- private String path;
-
- /**
- * 服务名称
- */
- private String serviceName;
-
- /**
- * 方法执行时间
- */
- private String time;
-
- /**
- * 方法入参
- */
- private String parameter;
-
- /**
- * 操作方法
- */
- private String title;
-
- /**
- * 方法描述
- */
- private String action;
-
- /**
- * 系统类型
- */
- private Integer sysType;
-
- /**
- * 操作类型
- */
- private String operatingType;
-
-
- /**
- * 返回结果
- * oper_resp_param
- *
- * @param toJSONString
- */
- public String operRespParam;
-
-
- /**
- * 返回结果
- *
- * @param toJSONString
- */
- public String operIp;
-}
diff --git a/hzims-service/ticket/src/main/java/com/hnac/hzims/ticket/processflow/controller/ProcessTypeController.java b/hzims-service/ticket/src/main/java/com/hnac/hzims/ticket/processflow/controller/ProcessTypeController.java
index e06a007..0f7d119 100644
--- a/hzims-service/ticket/src/main/java/com/hnac/hzims/ticket/processflow/controller/ProcessTypeController.java
+++ b/hzims-service/ticket/src/main/java/com/hnac/hzims/ticket/processflow/controller/ProcessTypeController.java
@@ -1,13 +1,17 @@
package com.hnac.hzims.ticket.processflow.controller;
+import com.alibaba.fastjson.JSON;
+import com.hnac.hzims.common.logs.annotation.OperationAnnotation;
+import com.hnac.hzims.common.logs.enums.BusinessType;
+import com.hnac.hzims.common.logs.enums.OperatorType;
import com.hnac.hzims.ticket.processflow.entity.ProcessType;
import com.hnac.hzims.ticket.processflow.properties.TicketProperties;
import com.hnac.hzims.ticket.processflow.properties.WorkTicketProperties;
import com.hnac.hzims.ticket.processflow.service.ProcessTypeService;
import com.hnac.hzims.ticket.processflow.strategy.entity.WorkflowQueue;
import com.hnac.hzims.ticket.processflow.strategy.service.TicketService;
-import org.springblade.core.log.annotation.ApiLog;
+import org.springblade.core.tool.api.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
@@ -30,57 +34,64 @@ import java.util.stream.Collectors;
@RequestMapping("/processflow/process-type")
public class ProcessTypeController {
- @Autowired
- private TicketProperties ticketProperties;
-
-
- @Autowired
- private ProcessTypeService processTypeService;
-
-
- @Autowired
- private List ticketServiceList;
-
- @Autowired
- private RedisTemplate redisTemplate;
-
-
-
- @GetMapping("/add")
- public void add() {
- List workTickets = ticketProperties.getWorkTickets();
- List processTypeList = workTickets.stream().map(item -> {
- ProcessType processType = new ProcessType();
- processType.setDeploymentId(item.getFlowId());
- processType.setDeploymentName(item.getSegment());
- processType.setSegment("新工作票");
- processType.setSequence(item.getStatus());
- return processType;
- }).collect(Collectors.toList());
- processTypeService.saveBatch(processTypeList);
- }
-
-
-
- @GetMapping("/list/{key}")
- public String list(@PathVariable String key) {
- //判断执行具体的实现类
- WorkflowQueue workflowQueue = new WorkflowQueue();
- workflowQueue.setDeploymentId(key);
- TicketService ticketService =
- ticketServiceList.stream().filter(item -> item.isWorkflowTicket(workflowQueue))
- .findFirst().orElse(null);
- String calculate = ticketService.calculate(null);
- return calculate;
- }
-
-
-
- @ApiLog("hellword")
- @GetMapping("/redis/{value}")
- public String opens(@PathVariable String value) {
- redisTemplate.opsForValue().set("name:hello",value);
- return "成功";
- }
+ @Autowired
+ private TicketProperties ticketProperties;
+
+
+ @Autowired
+ private ProcessTypeService processTypeService;
+
+
+ @Autowired
+ private List ticketServiceList;
+
+ @Autowired
+ private RedisTemplate redisTemplate;
+
+
+ @GetMapping("/add")
+ public void add() {
+ List workTickets = ticketProperties.getWorkTickets();
+ List processTypeList = workTickets.stream().map(item -> {
+ ProcessType processType = new ProcessType();
+ processType.setDeploymentId(item.getFlowId());
+ processType.setDeploymentName(item.getSegment());
+ processType.setSegment("新工作票");
+ processType.setSequence(item.getStatus());
+ return processType;
+ }).collect(Collectors.toList());
+ processTypeService.saveBatch(processTypeList);
+ }
+
+
+ @GetMapping("/list/{key}")
+ public String list(@PathVariable String key) {
+ //判断执行具体的实现类
+ WorkflowQueue workflowQueue = new WorkflowQueue();
+ workflowQueue.setDeploymentId(key);
+ TicketService ticketService =
+ ticketServiceList.stream().filter(item -> item.isWorkflowTicket(workflowQueue))
+ .findFirst().orElse(null);
+ String calculate = ticketService.calculate(null);
+ return calculate;
+ }
+
+
+ @OperationAnnotation(title = "操作模块", operatorType = OperatorType.MOBILE, businessType = BusinessType.GENCODE,action ="获取redis数据")
+ @GetMapping("/redis/{value}")
+ public int opens(@PathVariable String value) {
+ redisTemplate.opsForValue().set("name:hello", JSON.toJSONString(value));
+ return 0;
+ }
+
+
+ @OperationAnnotation(title = "工作流审批类型", operatorType = OperatorType.MOBILE, businessType = BusinessType.GENCODE,
+ action ="查询")
+ @GetMapping("/list")
+ public R list() {
+ List list = processTypeService.list();
+ System.out.println(1/0);
+ return R.data(list);
+ }
}