项目初始化
This commit is contained in:
9
system/Readme.md
Normal file
9
system/Readme.md
Normal file
@@ -0,0 +1,9 @@
|
||||
#### 简介
|
||||
系统模块主要包含以下功能:
|
||||
* 审计日志管理
|
||||
* 字典、树形字典管理
|
||||
* 版本注册
|
||||
* 主题管理
|
||||
* 系统文件资源管理
|
||||
* 定时任务管理
|
||||
|
||||
55
system/pom.xml
Normal file
55
system/pom.xml
Normal file
@@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.njcn.gather</groupId>
|
||||
<artifactId>CN_Tool</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
<artifactId>system</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.njcn</groupId>
|
||||
<artifactId>njcn-common</artifactId>
|
||||
<version>0.0.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.njcn</groupId>
|
||||
<artifactId>mybatis-plus</artifactId>
|
||||
<version>0.0.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.njcn</groupId>
|
||||
<artifactId>spingboot2.3.12</artifactId>
|
||||
<version>2.3.12</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.njcn.gather</groupId>
|
||||
<artifactId>user</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.83</version>
|
||||
</dependency>
|
||||
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.apache.poi</groupId>-->
|
||||
<!-- <artifactId>poi-ooxml</artifactId>-->
|
||||
<!-- <version>5.2.3</version>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.apache.poi</groupId>-->
|
||||
<!-- <artifactId>poi-ooxml-full</artifactId>-->
|
||||
<!-- <version>5.2.3</version>-->
|
||||
<!-- </dependency>-->
|
||||
</dependencies>
|
||||
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,80 @@
|
||||
package com.njcn.gather.system.cfg.controller;
|
||||
|
||||
import com.njcn.common.pojo.annotation.OperateInfo;
|
||||
import com.njcn.common.pojo.constant.OperateType;
|
||||
import com.njcn.common.pojo.enums.common.LogEnum;
|
||||
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
||||
import com.njcn.common.pojo.response.HttpResult;
|
||||
import com.njcn.common.utils.LogUtil;
|
||||
import com.njcn.gather.system.cfg.pojo.param.SysTestConfigParam;
|
||||
import com.njcn.gather.system.cfg.pojo.po.SysTestConfig;
|
||||
import com.njcn.gather.system.cfg.service.ISysTestConfigService;
|
||||
import com.njcn.web.controller.BaseController;
|
||||
import com.njcn.web.utils.HttpResultUtil;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @date 2024-11-16
|
||||
*/
|
||||
@Slf4j
|
||||
@Api(tags = "检测相关配置")
|
||||
@RestController
|
||||
@RequestMapping("/sysTestConfig")
|
||||
@RequiredArgsConstructor
|
||||
public class SysTestConfigController extends BaseController {
|
||||
private final ISysTestConfigService sysTestConfigService;
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON)
|
||||
@GetMapping("/getConfig")
|
||||
@ApiOperation("获取检测相关配置信息")
|
||||
public HttpResult<SysTestConfig> getConfig() {
|
||||
String methodDescribe = getMethodDescribe("getConfig");
|
||||
LogUtil.njcnDebug(log, "{}", methodDescribe);
|
||||
SysTestConfig sysTestConfig = sysTestConfigService.getOneConfig();
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, sysTestConfig, methodDescribe);
|
||||
}
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.UPDATE)
|
||||
@PostMapping("/update")
|
||||
@ApiOperation("修改检测相关配置信息")
|
||||
@ApiImplicitParam(name = "sysTestConfig", value = "检测相关配置信息", required = true)
|
||||
public HttpResult<Boolean> update(@RequestBody @Validated SysTestConfigParam.UpdateParam sysTestConfig) {
|
||||
String methodDescribe = getMethodDescribe("update");
|
||||
LogUtil.njcnDebug(log, "{}", methodDescribe);
|
||||
boolean result = sysTestConfigService.updateTestConfig(sysTestConfig);
|
||||
if (result) {
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, true, methodDescribe);
|
||||
} else {
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, false, methodDescribe);
|
||||
}
|
||||
}
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON)
|
||||
@ApiOperation("获取当前场景")
|
||||
@GetMapping("/getCurrentScene")
|
||||
public HttpResult<String> getCurrentScene() {
|
||||
String methodDescribe = getMethodDescribe("getCurrentScene");
|
||||
LogUtil.njcnDebug(log, "{}", methodDescribe);
|
||||
String currrentScene = sysTestConfigService.getCurrrentScene();
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, currrentScene, methodDescribe);
|
||||
}
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON)
|
||||
@ApiOperation("获取是否在检测时同时生成报告")
|
||||
@GetMapping("/getAutoGenerate")
|
||||
public HttpResult<Integer> getAutoGenerate() {
|
||||
String methodDescribe = getMethodDescribe("getAutoGenerate");
|
||||
LogUtil.njcnDebug(log, "{}", methodDescribe);
|
||||
Integer autoGenerate = sysTestConfigService.getAutoGenerate();
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, autoGenerate, methodDescribe);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.njcn.gather.system.cfg.mapper;
|
||||
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
import com.njcn.gather.system.cfg.pojo.po.SysTestConfig;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @date 2024-11-16
|
||||
*/
|
||||
public interface SysTestConfigMapper extends MPJBaseMapper<SysTestConfig> {
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.njcn.gather.system.cfg.mapper.SysTestConfigMapper">
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.njcn.gather.system.cfg.pojo.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @data 2025-03-25
|
||||
*/
|
||||
@Getter
|
||||
public enum SceneEnum {
|
||||
/**
|
||||
* 省级平台
|
||||
*/
|
||||
PROVINCE_PLATFORM("0", "province_platform"),
|
||||
|
||||
/**
|
||||
* 设备出场
|
||||
*/
|
||||
LEAVE_FACTORY_TEST("1", "leave_factory_test"),
|
||||
|
||||
/**
|
||||
* 研发自测
|
||||
*/
|
||||
SELF_TEST("2", "self_test");
|
||||
|
||||
private String value;
|
||||
private String msg;
|
||||
|
||||
SceneEnum(String value, String msg) {
|
||||
this.value = value;
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public static SceneEnum getSceneEnum(String value) {
|
||||
for (SceneEnum sceneEnum : SceneEnum.values()) {
|
||||
if (sceneEnum.getValue().equals(value)) {
|
||||
return sceneEnum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.njcn.gather.system.cfg.pojo.param;
|
||||
|
||||
import com.njcn.common.pojo.constant.PatternRegex;
|
||||
import com.njcn.gather.system.pojo.constant.SystemValidMessage;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.*;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @data 2024/11/16
|
||||
*/
|
||||
@Data
|
||||
public class SysTestConfigParam {
|
||||
|
||||
@ApiModelProperty(value = "检测报告是否自动生成0 否;1是")
|
||||
@Min(value = 0, message = SystemValidMessage.AUTO_GENERATE_FORMAT_ERROR)
|
||||
@Max(value = 1, message = SystemValidMessage.AUTO_GENERATE_FORMAT_ERROR)
|
||||
private Integer autoGenerate;
|
||||
|
||||
@ApiModelProperty(value = "最大检测次数")
|
||||
private Integer maxTime;
|
||||
|
||||
@ApiModelProperty(value = "数据精度")
|
||||
private Integer scale;
|
||||
|
||||
@ApiModelProperty(value = "场景")
|
||||
private String scene;
|
||||
|
||||
@ApiModelProperty(value = "比对监测后,当电压、电流不符合时,是否对标准设备进行系数校准")
|
||||
private Integer coefficient;
|
||||
|
||||
@Data
|
||||
public static class UpdateParam extends SysTestConfigParam {
|
||||
@ApiModelProperty("id")
|
||||
@Pattern(regexp = PatternRegex.SYSTEM_ID, message = SystemValidMessage.ID_FORMAT_ERROR)
|
||||
private String id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.njcn.gather.system.cfg.pojo.po;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.njcn.db.mybatisplus.bo.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @date 2024-11-16
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("sys_test_config")
|
||||
public class SysTestConfig extends BaseEntity implements Serializable {
|
||||
private static final long serialVersionUID = 352471858515754310L;
|
||||
/**
|
||||
* 系统配置表Id
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 检测报告是否自动生成: 0 否;1 是
|
||||
*/
|
||||
@TableField("Auto_Generate")
|
||||
private Integer autoGenerate;
|
||||
|
||||
/**
|
||||
* 最大检测次数,默认3次
|
||||
*/
|
||||
@TableField("Max_Time")
|
||||
private Integer maxTime;
|
||||
|
||||
/**
|
||||
* 数据处理规则, 关联字典(所有值、部分值、cp95值、平均值、任意值),默认任意值
|
||||
*/
|
||||
// @TableField("Data_Rule")
|
||||
// private String dataRule;
|
||||
|
||||
/**
|
||||
* 业务场景
|
||||
*/
|
||||
@TableField("Scene")
|
||||
private String scene;
|
||||
|
||||
/**
|
||||
* 小数点精度
|
||||
*/
|
||||
private Integer scale;
|
||||
|
||||
/**
|
||||
* 比对监测后,当电压、电流不符合时,是否对标准设备进行系数校准
|
||||
*/
|
||||
private Integer coefficient;
|
||||
|
||||
|
||||
/**
|
||||
* 状态:0-删除 1-正常
|
||||
*/
|
||||
private Integer state;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.njcn.gather.system.cfg.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.njcn.gather.system.cfg.pojo.param.SysTestConfigParam;
|
||||
import com.njcn.gather.system.cfg.pojo.po.SysTestConfig;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @date 2024-11-16
|
||||
*/
|
||||
public interface ISysTestConfigService extends IService<SysTestConfig> {
|
||||
|
||||
/**
|
||||
* 添加检测配置
|
||||
* @param scene 场景
|
||||
* @return 是否添加成功
|
||||
*/
|
||||
boolean addTestConfig(String scene);
|
||||
|
||||
/**
|
||||
* 更新检测配置
|
||||
* @param param 检测配置
|
||||
* @return 是否更新成功
|
||||
*/
|
||||
boolean updateTestConfig(SysTestConfigParam.UpdateParam param);
|
||||
|
||||
/**
|
||||
* 获取检测配置
|
||||
* @return
|
||||
*/
|
||||
SysTestConfig getOneConfig();
|
||||
|
||||
String getCurrrentScene();
|
||||
|
||||
/**
|
||||
* 获取是否在检测时自动生成报告
|
||||
*
|
||||
* @return 0-否,1-是
|
||||
*/
|
||||
Integer getAutoGenerate();
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.njcn.gather.system.cfg.service.impl;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.njcn.common.pojo.enums.common.DataStateEnum;
|
||||
import com.njcn.gather.system.cfg.mapper.SysTestConfigMapper;
|
||||
import com.njcn.gather.system.cfg.pojo.param.SysTestConfigParam;
|
||||
import com.njcn.gather.system.cfg.pojo.po.SysTestConfig;
|
||||
import com.njcn.gather.system.cfg.service.ISysTestConfigService;
|
||||
import com.njcn.gather.system.dictionary.pojo.po.DictData;
|
||||
import com.njcn.gather.system.dictionary.service.IDictDataService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @date 2024-11-16
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SysTestConfigServiceImpl extends ServiceImpl<SysTestConfigMapper, SysTestConfig> implements ISysTestConfigService {
|
||||
|
||||
private final IDictDataService dictDataService;
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public boolean addTestConfig(String scene) {
|
||||
SysTestConfig sysTestConfig = new SysTestConfig();
|
||||
sysTestConfig.setAutoGenerate(1);
|
||||
// 最大被检次数默认为3次
|
||||
sysTestConfig.setMaxTime(3);
|
||||
//sysTestConfig.setDataRule("46cf964bd76fb12a19cfb1700442eeeb"); // 任意值
|
||||
sysTestConfig.setScene(scene);
|
||||
sysTestConfig.setState(DataStateEnum.ENABLE.getCode());
|
||||
return this.save(sysTestConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public boolean updateTestConfig(SysTestConfigParam.UpdateParam param) {
|
||||
SysTestConfig oneConfig = this.getOneConfig();
|
||||
oneConfig.setAutoGenerate(ObjectUtil.isNotNull(param.getAutoGenerate()) ? param.getAutoGenerate() : oneConfig.getAutoGenerate());
|
||||
oneConfig.setScale(ObjectUtil.isNotNull(param.getScale()) ? param.getScale() : oneConfig.getScale());
|
||||
oneConfig.setMaxTime(ObjectUtil.isNotNull(param.getMaxTime()) ? param.getMaxTime() : oneConfig.getMaxTime());
|
||||
oneConfig.setScene(StringUtils.isNotBlank(param.getScene()) ? param.getScene() : oneConfig.getScene());
|
||||
oneConfig.setCoefficient(param.getCoefficient());
|
||||
return this.updateById(oneConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysTestConfig getOneConfig() {
|
||||
QueryWrapper<SysTestConfig> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("state", DataStateEnum.ENABLE.getCode());
|
||||
queryWrapper.last("LIMIT 1");
|
||||
return this.getOne(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrrentScene() {
|
||||
String scene = getOneConfig().getScene();
|
||||
DictData dictData = dictDataService.getDictDataById(scene);
|
||||
if (ObjectUtil.isNotNull(dictData)) {
|
||||
return dictData.getValue();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getAutoGenerate() {
|
||||
return getOneConfig().getAutoGenerate();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.njcn.gather.system.config;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@Slf4j
|
||||
@Configuration
|
||||
public class LogExecutorConfig {
|
||||
|
||||
@Bean(name = "logAuditExecutor", destroyMethod = "shutdown")
|
||||
public ExecutorService logAuditExecutor() {
|
||||
AtomicInteger threadIndex = new AtomicInteger(1);
|
||||
return new ThreadPoolExecutor(
|
||||
4, 8, 30, TimeUnit.SECONDS,
|
||||
new LinkedBlockingQueue<>(100),
|
||||
runnable -> {
|
||||
Thread thread = new Thread(runnable);
|
||||
thread.setName("log-audit-" + threadIndex.getAndIncrement());
|
||||
return thread;
|
||||
},
|
||||
(runnable, executor) -> log.warn("审计日志线程池已满,丢弃本次日志任务")
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.njcn.gather.system.config;
|
||||
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import com.njcn.common.bean.CustomCacheUtil;
|
||||
import org.springframework.boot.web.servlet.MultipartConfigFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.util.unit.DataSize;
|
||||
|
||||
import javax.servlet.MultipartConfigElement;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @data 2025-03-24
|
||||
*/
|
||||
@Configuration
|
||||
public class WebConfig {
|
||||
|
||||
/**
|
||||
* 将自定缓存工具类注入到spring容器中
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public CustomCacheUtil customCacheUtil() {
|
||||
CustomCacheUtil customCacheUtil = SpringUtil.getBean(CustomCacheUtil.CACHE_NAME);
|
||||
return customCacheUtil;
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置上传文件大小限制
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public MultipartConfigElement multipartConfigElement() {
|
||||
MultipartConfigFactory factory = new MultipartConfigFactory();
|
||||
// 单个文件最大6MB
|
||||
factory.setMaxFileSize(DataSize.ofMegabytes(1024));
|
||||
// 整个请求最大12MB
|
||||
factory.setMaxRequestSize(DataSize.ofMegabytes(2048));
|
||||
return factory.createMultipartConfig();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
package com.njcn.gather.system.config.advice;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
||||
import com.njcn.common.pojo.response.HttpResult;
|
||||
import com.njcn.gather.system.log.pojo.dto.SysLogAuditRecord;
|
||||
import com.njcn.gather.system.log.service.ISysLogAuditService;
|
||||
import com.njcn.web.utils.ReflectCommonUtil;
|
||||
import com.njcn.web.utils.RequestUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.server.ServerHttpRequest;
|
||||
import org.springframework.http.server.ServerHttpResponse;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Resource;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @data 2024-12-2
|
||||
*/
|
||||
@Slf4j
|
||||
@ControllerAdvice
|
||||
public class LogAdvice implements ResponseBodyAdvice<Object> {
|
||||
|
||||
@Resource
|
||||
private ISysLogAuditService logService;
|
||||
|
||||
@Resource(name = "logAuditExecutor")
|
||||
private Executor logAuditExecutor;
|
||||
|
||||
private static final List<String> UN_LOG_INFO = Collections.singletonList("未知业务");
|
||||
|
||||
private static final List<String> FILTER_CODE = Arrays.asList(
|
||||
CommonResponseEnum.SUCCESS.getCode(),
|
||||
CommonResponseEnum.FAIL.getCode(),
|
||||
CommonResponseEnum.NO_DATA.getCode()
|
||||
);
|
||||
|
||||
@Override
|
||||
public boolean supports(MethodParameter returnType, Class converterType) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object beforeBodyWrite(Object body, @Nonnull MethodParameter returnType, @Nonnull MediaType selectedContentType,
|
||||
@Nonnull Class selectedConverterType, @Nonnull ServerHttpRequest request,
|
||||
@Nonnull ServerHttpResponse response) {
|
||||
if (body instanceof HttpResult) {
|
||||
HttpResult<?> httpResult = (HttpResult<?>) body;
|
||||
if (FILTER_CODE.contains(httpResult.getCode())) {
|
||||
Method method = returnType.getMethod();
|
||||
String methodDescribe = resolveMethodDescribe(method);
|
||||
if (!UN_LOG_INFO.contains(methodDescribe)) {
|
||||
SysLogAuditRecord logRecord = buildAdviceLogRecord(method, httpResult, methodDescribe);
|
||||
submitLogTask(() -> logService.recodeAdviceLog(logRecord));
|
||||
}
|
||||
}
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
private SysLogAuditRecord buildAdviceLogRecord(Method method, HttpResult<?> httpResult, String methodDescribe) {
|
||||
Integer level = resolveOperateLevel(method);
|
||||
return SysLogAuditRecord.builder()
|
||||
.userId(resolveUserId())
|
||||
.loginName(resolveLoginName())
|
||||
.ip(resolveUserIp())
|
||||
.operate(methodDescribe)
|
||||
.operateType(resolveOperateType(method))
|
||||
.result(CommonResponseEnum.FAIL.getCode().equalsIgnoreCase(httpResult.getCode())
|
||||
? CommonResponseEnum.FAIL.getMessage()
|
||||
: CommonResponseEnum.SUCCESS.getMessage())
|
||||
.type(resolveEventType(method))
|
||||
.level(level)
|
||||
.warn(level == 1 ? 1 : 0)
|
||||
.build();
|
||||
}
|
||||
|
||||
private void submitLogTask(Runnable task) {
|
||||
try {
|
||||
logAuditExecutor.execute(() -> {
|
||||
try {
|
||||
task.run();
|
||||
} catch (Exception e) {
|
||||
log.error("异步记录审计日志失败", e);
|
||||
}
|
||||
});
|
||||
} catch (RuntimeException e) {
|
||||
log.error("提交审计日志任务失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
private String resolveMethodDescribe(Method method) {
|
||||
if (method == null) {
|
||||
return "未知业务";
|
||||
}
|
||||
try {
|
||||
String methodDescribe = ReflectCommonUtil.getMethodDescribeByMethod(method);
|
||||
return StrUtil.isBlank(methodDescribe) ? "未知业务" : methodDescribe;
|
||||
} catch (Exception e) {
|
||||
log.warn("解析审计日志方法描述失败,method={}", method.getName(), e);
|
||||
return "未知业务";
|
||||
}
|
||||
}
|
||||
|
||||
private Integer resolveEventType(Method method) {
|
||||
try {
|
||||
if (method == null) {
|
||||
return 1;
|
||||
}
|
||||
String type = ReflectCommonUtil.getOperateInfoByMethod(method).getOperateType();
|
||||
return "业务事件".equalsIgnoreCase(type) ? 0 : 1;
|
||||
} catch (Exception e) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
private Integer resolveOperateLevel(Method method) {
|
||||
try {
|
||||
if (method == null) {
|
||||
return 0;
|
||||
}
|
||||
String level = ReflectCommonUtil.getOperateInfoByMethod(method).getOperateLevel();
|
||||
if ("中等".equals(level)) {
|
||||
return 1;
|
||||
}
|
||||
if ("严重".equals(level)) {
|
||||
return 2;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private String resolveOperateType(Method method) {
|
||||
try {
|
||||
if (method == null) {
|
||||
return "";
|
||||
}
|
||||
return ReflectCommonUtil.getOperateTypeByMethod(method);
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private String resolveUserId() {
|
||||
try {
|
||||
String userId = RequestUtil.getUserId();
|
||||
return StrUtil.isBlank(userId) ? "" : userId;
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private String resolveLoginName() {
|
||||
try {
|
||||
String loginName = RequestUtil.getLoginName();
|
||||
return StrUtil.isBlank(loginName) ? "" : loginName;
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private String resolveUserIp() {
|
||||
try {
|
||||
String userIp = RequestUtil.getUserIp();
|
||||
return StrUtil.isBlank(userIp) ? "" : userIp;
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.njcn.gather.system.config.handler;
|
||||
|
||||
import com.njcn.common.pojo.constant.LogInfo;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author hongawen
|
||||
* @version 1.0.0
|
||||
* @date 2021年06月22日 10:25
|
||||
*/
|
||||
@Slf4j
|
||||
public class ControllerUtil {
|
||||
|
||||
/**
|
||||
* 针对methodArgumentNotValidException 异常的处理
|
||||
* @author cdf
|
||||
*/
|
||||
public static String getMethodArgumentNotValidException(MethodArgumentNotValidException methodArgumentNotValidException) {
|
||||
String operate = LogInfo.UNKNOWN_OPERATE;
|
||||
Method method = null;
|
||||
try {
|
||||
method = methodArgumentNotValidException.getParameter().getMethod();
|
||||
if (!Objects.isNull(method) && method.isAnnotationPresent(ApiOperation.class)) {
|
||||
ApiOperation apiOperation = method.getAnnotation(ApiOperation.class);
|
||||
operate = apiOperation.value();
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.error("根据方法参数非法异常获取@ApiOperation注解值失败,参数非法异常信息:{},方法名:{},异常信息:{}",methodArgumentNotValidException.getMessage(),method,e.getMessage());
|
||||
}
|
||||
return operate;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,335 @@
|
||||
package com.njcn.gather.system.config.handler;
|
||||
|
||||
import cn.hutool.core.text.StrFormatter;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
||||
import com.njcn.common.pojo.exception.BusinessException;
|
||||
import com.njcn.common.pojo.response.HttpResult;
|
||||
import com.njcn.common.utils.LogUtil;
|
||||
import com.njcn.gather.system.log.pojo.dto.SysLogAuditRecord;
|
||||
import com.njcn.gather.system.log.service.ISysLogAuditService;
|
||||
import com.njcn.gather.system.pojo.enums.SystemResponseEnum;
|
||||
import com.njcn.web.utils.HttpResultUtil;
|
||||
import com.njcn.web.utils.ReflectCommonUtil;
|
||||
import com.njcn.web.utils.RequestUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.json.JSONException;
|
||||
import org.springframework.validation.ObjectError;
|
||||
import org.springframework.web.HttpMediaTypeNotSupportedException;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import org.springframework.web.util.NestedServletException;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.ConstraintViolationException;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.file.NoSuchFileException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* 全局通用业务异常处理器
|
||||
*
|
||||
* @author hongawen
|
||||
* @version 1.0.0
|
||||
* @date 2021年04月20日 18:04
|
||||
*/
|
||||
@Slf4j
|
||||
@RestControllerAdvice
|
||||
public class GlobalBusinessExceptionHandler {
|
||||
|
||||
@Resource
|
||||
private ISysLogAuditService sysLogAuditService;
|
||||
|
||||
@Resource(name = "logAuditExecutor")
|
||||
private Executor logAuditExecutor;
|
||||
|
||||
@ExceptionHandler(BusinessException.class)
|
||||
public HttpResult<String> handleBusinessException(BusinessException businessException) {
|
||||
String operate = resolveMethodDescribeByException(businessException);
|
||||
recodeBusinessExceptionLog(businessException, businessException.getMessage());
|
||||
return HttpResultUtil.assembleBusinessExceptionResult(businessException, null, operate);
|
||||
}
|
||||
|
||||
@ExceptionHandler(NullPointerException.class)
|
||||
public HttpResult<String> handleNullPointerException(NullPointerException nullPointerException) {
|
||||
LogUtil.logExceptionStackInfo(CommonResponseEnum.NULL_POINTER_EXCEPTION.getMessage(), nullPointerException);
|
||||
recodeBusinessExceptionLog(nullPointerException, CommonResponseEnum.NULL_POINTER_EXCEPTION.getMessage());
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.NULL_POINTER_EXCEPTION, null, resolveMethodDescribeByException(nullPointerException));
|
||||
}
|
||||
|
||||
@ExceptionHandler(ArithmeticException.class)
|
||||
public HttpResult<String> handleArithmeticException(ArithmeticException arithmeticException) {
|
||||
LogUtil.logExceptionStackInfo(CommonResponseEnum.ARITHMETIC_EXCEPTION.getMessage(), arithmeticException);
|
||||
recodeBusinessExceptionLog(arithmeticException, CommonResponseEnum.ARITHMETIC_EXCEPTION.getMessage());
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.ARITHMETIC_EXCEPTION, null, resolveMethodDescribeByException(arithmeticException));
|
||||
}
|
||||
|
||||
@ExceptionHandler(ClassCastException.class)
|
||||
public HttpResult<String> handleClassCastException(ClassCastException classCastException) {
|
||||
LogUtil.logExceptionStackInfo(CommonResponseEnum.CLASS_CAST_EXCEPTION.getMessage(), classCastException);
|
||||
recodeBusinessExceptionLog(classCastException, CommonResponseEnum.CLASS_CAST_EXCEPTION.getMessage());
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.CLASS_CAST_EXCEPTION, null, resolveMethodDescribeByException(classCastException));
|
||||
}
|
||||
|
||||
@ExceptionHandler(IndexOutOfBoundsException.class)
|
||||
public HttpResult<String> handleIndexOutOfBoundsException(IndexOutOfBoundsException indexOutOfBoundsException) {
|
||||
LogUtil.logExceptionStackInfo(CommonResponseEnum.INDEX_OUT_OF_BOUNDS_EXCEPTION.getMessage(), indexOutOfBoundsException);
|
||||
recodeBusinessExceptionLog(indexOutOfBoundsException, CommonResponseEnum.INDEX_OUT_OF_BOUNDS_EXCEPTION.getMessage());
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.INDEX_OUT_OF_BOUNDS_EXCEPTION, null, resolveMethodDescribeByException(indexOutOfBoundsException));
|
||||
}
|
||||
|
||||
@ExceptionHandler(NoSuchFileException.class)
|
||||
public HttpResult<String> handleNoSuchFileException(NoSuchFileException noSuchFileException) {
|
||||
String filePath = noSuchFileException.getFile();
|
||||
log.warn("文件未找到异常 - 文件路径: {}", filePath, noSuchFileException);
|
||||
recodeBusinessExceptionLog(noSuchFileException, SystemResponseEnum.FILE_NOT_FOUND.getMessage());
|
||||
return HttpResultUtil.assembleResult(SystemResponseEnum.FILE_NOT_FOUND.getCode(), null,
|
||||
StrFormatter.format("{}{}{}", resolveMethodDescribeByException(noSuchFileException),
|
||||
StrUtil.C_COMMA, SystemResponseEnum.FILE_NOT_FOUND.getMessage()));
|
||||
}
|
||||
|
||||
@ExceptionHandler(IOException.class)
|
||||
public HttpResult<String> handleIOException(IOException ioException) {
|
||||
if (ioException instanceof NoSuchFileException) {
|
||||
return handleNoSuchFileException((NoSuchFileException) ioException);
|
||||
}
|
||||
LogUtil.logExceptionStackInfo(SystemResponseEnum.FILE_IO_ERROR.getMessage(), ioException);
|
||||
recodeBusinessExceptionLog(ioException, SystemResponseEnum.FILE_IO_ERROR.getMessage());
|
||||
return HttpResultUtil.assembleResult(SystemResponseEnum.FILE_IO_ERROR.getCode(), null,
|
||||
StrFormatter.format("{}{}{}", resolveMethodDescribeByException(ioException),
|
||||
StrUtil.C_COMMA, SystemResponseEnum.FILE_IO_ERROR.getMessage()));
|
||||
}
|
||||
|
||||
@ExceptionHandler(HttpMediaTypeNotSupportedException.class)
|
||||
public HttpResult<String> httpMediaTypeNotSupportedExceptionHandler(HttpMediaTypeNotSupportedException httpMediaTypeNotSupportedException) {
|
||||
LogUtil.logExceptionStackInfo(CommonResponseEnum.HTTP_MEDIA_TYPE_NOT_SUPPORTED_EXCEPTION.getMessage(), httpMediaTypeNotSupportedException);
|
||||
recodeBusinessExceptionLog(httpMediaTypeNotSupportedException, CommonResponseEnum.HTTP_MEDIA_TYPE_NOT_SUPPORTED_EXCEPTION.getMessage());
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.HTTP_MEDIA_TYPE_NOT_SUPPORTED_EXCEPTION, null, resolveMethodDescribeByException(httpMediaTypeNotSupportedException));
|
||||
}
|
||||
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
public HttpResult<String> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException methodArgumentNotValidException) {
|
||||
String messages = methodArgumentNotValidException.getBindingResult().getAllErrors()
|
||||
.stream().map(ObjectError::getDefaultMessage).collect(Collectors.joining(";"));
|
||||
LogUtil.njcnDebug(log, "参数校验异常,异常为:{}", messages);
|
||||
recodeBusinessExceptionLog(methodArgumentNotValidException, CommonResponseEnum.METHOD_ARGUMENT_NOT_VALID_EXCEPTION.getMessage());
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.METHOD_ARGUMENT_NOT_VALID_EXCEPTION, messages, ControllerUtil.getMethodArgumentNotValidException(methodArgumentNotValidException));
|
||||
}
|
||||
|
||||
@ExceptionHandler(ConstraintViolationException.class)
|
||||
public HttpResult<String> constraintViolationExceptionExceptionHandler(ConstraintViolationException constraintViolationException) {
|
||||
String exceptionMessage = constraintViolationException.getMessage();
|
||||
StringBuilder messages = new StringBuilder();
|
||||
if (exceptionMessage.indexOf(StrUtil.COMMA) > 0) {
|
||||
String[] tempMessage = exceptionMessage.split(StrUtil.COMMA);
|
||||
Stream.of(tempMessage).forEach(message -> messages.append(message.substring(message.indexOf(StrUtil.COLON) + 2)).append(';'));
|
||||
} else {
|
||||
messages.append(exceptionMessage.substring(exceptionMessage.indexOf(StrUtil.COLON) + 2));
|
||||
}
|
||||
LogUtil.njcnDebug(log, "参数校验异常,异常为:{}", messages);
|
||||
recodeBusinessExceptionLog(constraintViolationException, CommonResponseEnum.METHOD_ARGUMENT_NOT_VALID_EXCEPTION.getMessage());
|
||||
List<ConstraintViolation<?>> constraintViolationList = new ArrayList<>(constraintViolationException.getConstraintViolations());
|
||||
ConstraintViolation<?> constraintViolation = constraintViolationList.get(0);
|
||||
Class<?> rootBeanClass = constraintViolation.getRootBeanClass();
|
||||
if (rootBeanClass.getName().endsWith("Controller")) {
|
||||
String methodName = constraintViolation.getPropertyPath().toString().substring(0, constraintViolation.getPropertyPath().toString().indexOf(StrUtil.DOT));
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.METHOD_ARGUMENT_NOT_VALID_EXCEPTION, messages.toString(), resolveMethodDescribeByClassAndMethodName(rootBeanClass, methodName));
|
||||
} else {
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.METHOD_ARGUMENT_NOT_VALID_EXCEPTION, messages.toString(), resolveMethodDescribeByException(constraintViolationException));
|
||||
}
|
||||
}
|
||||
|
||||
@ExceptionHandler(IllegalArgumentException.class)
|
||||
public HttpResult<String> handleIndexOutOfBoundsException(IllegalArgumentException illegalArgumentException) {
|
||||
LogUtil.logExceptionStackInfo(CommonResponseEnum.ILLEGAL_ARGUMENT_EXCEPTION.getMessage(), illegalArgumentException);
|
||||
recodeBusinessExceptionLog(illegalArgumentException, CommonResponseEnum.ILLEGAL_ARGUMENT_EXCEPTION.getMessage());
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.ILLEGAL_ARGUMENT_EXCEPTION, illegalArgumentException.getMessage(), resolveMethodDescribeByException(illegalArgumentException));
|
||||
}
|
||||
|
||||
@ExceptionHandler(Exception.class)
|
||||
public HttpResult<String> handleException(Exception exception) {
|
||||
Exception tempException = exception;
|
||||
String exceptionCause = CommonResponseEnum.UN_DECLARE.getMessage();
|
||||
String code = CommonResponseEnum.UN_DECLARE.getCode();
|
||||
if (exception instanceof NestedServletException) {
|
||||
Throwable cause = exception.getCause();
|
||||
if (cause instanceof AssertionError) {
|
||||
if (cause.getCause() instanceof BusinessException) {
|
||||
tempException = (BusinessException) cause.getCause();
|
||||
BusinessException tempBusinessException = (BusinessException) cause.getCause();
|
||||
exceptionCause = tempBusinessException.getMessage();
|
||||
code = tempBusinessException.getCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
LogUtil.logExceptionStackInfo(exceptionCause, tempException);
|
||||
recodeBusinessExceptionLog(exception, exceptionCause);
|
||||
return HttpResultUtil.assembleResult(code, null, StrFormatter.format("{}{}{}", resolveMethodDescribeByException(tempException), StrUtil.C_COMMA, exceptionCause));
|
||||
}
|
||||
|
||||
@ExceptionHandler(JSONException.class)
|
||||
public HttpResult<String> handleIndexOutOfBoundsException(JSONException jsonException) {
|
||||
LogUtil.logExceptionStackInfo(CommonResponseEnum.JSON_CONVERT_EXCEPTION.getMessage(), jsonException);
|
||||
recodeBusinessExceptionLog(jsonException, CommonResponseEnum.JSON_CONVERT_EXCEPTION.getMessage());
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.JSON_CONVERT_EXCEPTION, jsonException.getMessage(), resolveMethodDescribeByException(jsonException));
|
||||
}
|
||||
|
||||
private void recodeBusinessExceptionLog(Exception businessException, String message) {
|
||||
SysLogAuditRecord logRecord = buildExceptionLogRecord(businessException, message);
|
||||
submitLogTask(() -> sysLogAuditService.recodeBusinessExceptionLog(logRecord));
|
||||
}
|
||||
|
||||
private SysLogAuditRecord buildExceptionLogRecord(Exception exception, String message) {
|
||||
Method method = resolveMethod(exception);
|
||||
Integer level = resolveOperateLevel(method);
|
||||
return SysLogAuditRecord.builder()
|
||||
.userId(resolveUserId())
|
||||
.loginName(resolveLoginName())
|
||||
.ip(resolveUserIp())
|
||||
.operate(resolveExceptionOperate(method, exception))
|
||||
.operateType(resolveOperateType(method))
|
||||
.result(CommonResponseEnum.FAIL.getMessage())
|
||||
.reason(message)
|
||||
.type(resolveEventType(method))
|
||||
.level(level)
|
||||
.warn(level == 1 ? 1 : 0)
|
||||
.build();
|
||||
}
|
||||
|
||||
private Method resolveMethod(Exception exception) {
|
||||
if (exception instanceof MethodArgumentNotValidException) {
|
||||
MethodArgumentNotValidException methodArgumentNotValidException = (MethodArgumentNotValidException) exception;
|
||||
return methodArgumentNotValidException.getParameter().getMethod();
|
||||
}
|
||||
try {
|
||||
return ReflectCommonUtil.getMethod(exception);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private String resolveExceptionOperate(Method method, Exception exception) {
|
||||
if (method != null) {
|
||||
try {
|
||||
String methodDescribe = ReflectCommonUtil.getMethodDescribeByMethod(method);
|
||||
if (StrUtil.isNotBlank(methodDescribe)) {
|
||||
return methodDescribe;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("解析异常日志方法描述失败,method={}", method.getName(), e);
|
||||
}
|
||||
}
|
||||
try {
|
||||
return resolveMethodDescribeByException(exception);
|
||||
} catch (Exception e) {
|
||||
return "未知业务";
|
||||
}
|
||||
}
|
||||
|
||||
private Integer resolveEventType(Method method) {
|
||||
try {
|
||||
if (method == null) {
|
||||
return 1;
|
||||
}
|
||||
String type = ReflectCommonUtil.getOperateInfoByMethod(method).getOperateType();
|
||||
return "业务事件".equalsIgnoreCase(type) ? 0 : 1;
|
||||
} catch (Exception e) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
private Integer resolveOperateLevel(Method method) {
|
||||
try {
|
||||
if (method == null) {
|
||||
return 0;
|
||||
}
|
||||
String level = ReflectCommonUtil.getOperateInfoByMethod(method).getOperateLevel();
|
||||
if ("中等".equals(level)) {
|
||||
return 1;
|
||||
}
|
||||
if ("严重".equals(level)) {
|
||||
return 2;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private String resolveOperateType(Method method) {
|
||||
try {
|
||||
if (method == null) {
|
||||
return "";
|
||||
}
|
||||
return ReflectCommonUtil.getOperateTypeByMethod(method);
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private String resolveMethodDescribeByException(Exception exception) {
|
||||
try {
|
||||
String methodDescribe = ReflectCommonUtil.getMethodDescribeByException(exception);
|
||||
return StrUtil.isBlank(methodDescribe) ? "未知业务" : methodDescribe;
|
||||
} catch (Exception e) {
|
||||
return "未知业务";
|
||||
}
|
||||
}
|
||||
|
||||
private String resolveMethodDescribeByClassAndMethodName(Class<?> rootBeanClass, String methodName) {
|
||||
try {
|
||||
String methodDescribe = ReflectCommonUtil.getMethodDescribeByClassAndMethodName(rootBeanClass, methodName);
|
||||
return StrUtil.isBlank(methodDescribe) ? "未知业务" : methodDescribe;
|
||||
} catch (Exception e) {
|
||||
return "未知业务";
|
||||
}
|
||||
}
|
||||
|
||||
private String resolveUserId() {
|
||||
try {
|
||||
String userId = RequestUtil.getUserId();
|
||||
return StrUtil.isBlank(userId) ? "" : userId;
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private String resolveLoginName() {
|
||||
try {
|
||||
String loginName = RequestUtil.getLoginName();
|
||||
return StrUtil.isBlank(loginName) ? "" : loginName;
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private String resolveUserIp() {
|
||||
try {
|
||||
String userIp = RequestUtil.getUserIp();
|
||||
return StrUtil.isBlank(userIp) ? "" : userIp;
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private void submitLogTask(Runnable task) {
|
||||
try {
|
||||
logAuditExecutor.execute(() -> {
|
||||
try {
|
||||
task.run();
|
||||
} catch (Exception e) {
|
||||
log.error("异步记录异常审计日志失败", e);
|
||||
}
|
||||
});
|
||||
} catch (RuntimeException e) {
|
||||
log.error("提交异常审计日志任务失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.njcn.gather.system.config.handler;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.njcn.common.pojo.exception.BusinessException;
|
||||
import com.njcn.db.mybatisplus.handler.AutoFillValueHandler;
|
||||
import com.njcn.web.utils.RequestUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Primary
|
||||
@Component
|
||||
@Slf4j
|
||||
public class NonWebAutoFillValueHandler extends AutoFillValueHandler {
|
||||
|
||||
/**
|
||||
* 当前用户ID的线程本地变量,用于非Web环境
|
||||
*/
|
||||
private static final ThreadLocal<String> CURRENT_USER_ID = new ThreadLocal<>();
|
||||
|
||||
|
||||
@Override
|
||||
public Supplier<String> getUserIdSupplier() {
|
||||
return () -> {
|
||||
try {
|
||||
// 首先尝试从Web环境获取用户ID
|
||||
String userId = RequestUtil.getUserId();
|
||||
String actualUserId = StrUtil.isBlank(userId) ? "未知用户" : userId;
|
||||
return actualUserId;
|
||||
} catch (BusinessException e) {
|
||||
// 如果是"当前请求web环境为空"异常,则尝试从线程本地变量获取
|
||||
if (e.getMessage().contains("当前请求web环境为空")) {
|
||||
String userId = CURRENT_USER_ID.get();
|
||||
if (userId != null) {
|
||||
return userId;
|
||||
}
|
||||
// 如果线程本地变量中也没有用户ID,则返回默认值
|
||||
log.warn("无法获取当前用户ID");
|
||||
return "未知用户";
|
||||
}
|
||||
// 其他异常直接抛出
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 在非Web环境中设置当前用户ID
|
||||
*
|
||||
* @param userId 用户ID
|
||||
*/
|
||||
public static void setCurrentUserId(String userId) {
|
||||
CURRENT_USER_ID.set(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除当前线程的用户ID设置
|
||||
*/
|
||||
public static void clearCurrentUserId() {
|
||||
CURRENT_USER_ID.remove();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
package com.njcn.gather.system.dictionary.controller;
|
||||
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.njcn.common.pojo.annotation.OperateInfo;
|
||||
import com.njcn.common.pojo.constant.OperateType;
|
||||
import com.njcn.common.pojo.enums.common.LogEnum;
|
||||
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
||||
import com.njcn.common.pojo.response.HttpResult;
|
||||
import com.njcn.common.utils.LogUtil;
|
||||
import com.njcn.gather.system.dictionary.pojo.param.DictDataParam;
|
||||
import com.njcn.gather.system.dictionary.pojo.po.DictData;
|
||||
import com.njcn.gather.system.dictionary.service.IDictDataService;
|
||||
import com.njcn.web.controller.BaseController;
|
||||
import com.njcn.web.pojo.dto.SimpleTreeDTO;
|
||||
import com.njcn.web.utils.HttpResultUtil;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author hongawen
|
||||
* @since 2021-12-13
|
||||
*/
|
||||
@Validated
|
||||
@Slf4j
|
||||
@Api(tags = "字典数据操作")
|
||||
@RestController
|
||||
@RequestMapping("/dictData")
|
||||
@RequiredArgsConstructor
|
||||
public class DictDataController extends BaseController {
|
||||
|
||||
private final IDictDataService dictDataService;
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON)
|
||||
@PostMapping("/listByTypeId")
|
||||
@ApiOperation("根据字典类型id查询字典数据")
|
||||
@ApiImplicitParam(name = "queryParam", value = "查询参数", required = true)
|
||||
public HttpResult<Page<DictData>> listByTypeId(@RequestBody @Validated DictDataParam.QueryParam queryParam) {
|
||||
String methodDescribe = getMethodDescribe("listByTypeId");
|
||||
LogUtil.njcnDebug(log, "{},查询数据为:{}", methodDescribe, queryParam);
|
||||
Page<DictData> result = dictDataService.getDictDataByTypeId(queryParam);
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
|
||||
}
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.ADD)
|
||||
@PostMapping("/add")
|
||||
@ApiOperation("新增字典数据")
|
||||
@ApiImplicitParam(name = "dictDataParam", value = "字典数据", required = true)
|
||||
public HttpResult<Boolean> add(@RequestBody @Validated DictDataParam dictDataParam) {
|
||||
String methodDescribe = getMethodDescribe("add");
|
||||
LogUtil.njcnDebug(log, "{},字典数据为:{}", methodDescribe, dictDataParam);
|
||||
boolean result = dictDataService.addDictData(dictDataParam);
|
||||
if (result) {
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, true, methodDescribe);
|
||||
} else {
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, false, methodDescribe);
|
||||
}
|
||||
}
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.UPDATE)
|
||||
@PostMapping("/update")
|
||||
@ApiOperation("修改字典数据")
|
||||
@ApiImplicitParam(name = "updateParam", value = "字典数据", required = true)
|
||||
public HttpResult<Boolean> update(@RequestBody @Validated DictDataParam.UpdateParam updateParam) {
|
||||
String methodDescribe = getMethodDescribe("update");
|
||||
LogUtil.njcnDebug(log, "{},字典数据为:{}", methodDescribe, updateParam);
|
||||
boolean result = dictDataService.updateDictData(updateParam);
|
||||
if (result) {
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, true, methodDescribe);
|
||||
} else {
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, false, methodDescribe);
|
||||
}
|
||||
}
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.UPDATE)
|
||||
@PostMapping("/delete")
|
||||
@ApiOperation("删除字典数据")
|
||||
@ApiImplicitParam(name = "ids", value = "字典索引", required = true, dataTypeClass = List.class)
|
||||
public HttpResult<Boolean> delete(@RequestBody List<String> ids) {
|
||||
String methodDescribe = getMethodDescribe("delete");
|
||||
LogUtil.njcnDebug(log, "{},字典ID数据为:{}", methodDescribe, String.join(StrUtil.COMMA, ids));
|
||||
boolean result = dictDataService.deleteDictData(ids);
|
||||
if (result) {
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, true, methodDescribe);
|
||||
} else {
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, false, methodDescribe);
|
||||
}
|
||||
}
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON)
|
||||
@GetMapping("/getDicDataById")
|
||||
@ApiOperation("根据字典id查询字典数据")
|
||||
@ApiImplicitParam(name = "dicIndex", value = "字典id", required = true)
|
||||
public HttpResult<DictData> getDicDataById(@RequestParam("dicIndex") String dicIndex) {
|
||||
String methodDescribe = getMethodDescribe("getDicDataById");
|
||||
DictData result = dictDataService.getDictDataById(dicIndex);
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
|
||||
}
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON)
|
||||
@GetMapping("/getDicDataByCode")
|
||||
@ApiOperation("根据字典code查询字典数据")
|
||||
@ApiImplicitParam(name = "code", value = "字典code", required = true)
|
||||
public HttpResult<DictData> getDicDataByCode(@RequestParam("code") String code) {
|
||||
String methodDescribe = getMethodDescribe("getDicDataByCode");
|
||||
DictData result = dictDataService.getDictDataByCode(code);
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
|
||||
}
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON)
|
||||
@GetMapping("/dictDataCache")
|
||||
@ApiOperation("获取所有字典数据缓存到前端")
|
||||
public HttpResult<List<SimpleTreeDTO>> dictDataCache() {
|
||||
String methodDescribe = getMethodDescribe("dictDataCache");
|
||||
LogUtil.njcnDebug(log, "{},获取所有字典数据缓存到前端", methodDescribe);
|
||||
List<SimpleTreeDTO> dictData = dictDataService.dictDataCache();
|
||||
if (CollectionUtil.isNotEmpty(dictData)) {
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, dictData, methodDescribe);
|
||||
} else {
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.NO_DATA, null, methodDescribe);
|
||||
}
|
||||
}
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.DOWNLOAD)
|
||||
@PostMapping("/export")
|
||||
@ApiOperation("导出字典数据")
|
||||
@ApiImplicitParam(name = "queryParam", value = "查询参数", required = true)
|
||||
public void export(@RequestBody @Validated DictDataParam.QueryParam queryParam) {
|
||||
dictDataService.exportDictData(queryParam);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
package com.njcn.gather.system.dictionary.controller;
|
||||
|
||||
|
||||
import com.njcn.common.pojo.annotation.OperateInfo;
|
||||
import com.njcn.common.pojo.constant.OperateType;
|
||||
import com.njcn.common.pojo.enums.common.LogEnum;
|
||||
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
||||
import com.njcn.common.pojo.response.HttpResult;
|
||||
import com.njcn.common.utils.LogUtil;
|
||||
import com.njcn.gather.system.dictionary.pojo.param.DictTreeParam;
|
||||
import com.njcn.gather.system.dictionary.pojo.po.DictTree;
|
||||
import com.njcn.gather.system.dictionary.service.IDictTreeService;
|
||||
import com.njcn.web.controller.BaseController;
|
||||
import com.njcn.web.utils.HttpResultUtil;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author hongawen
|
||||
* @since 2021-12-13
|
||||
*/
|
||||
@Validated
|
||||
@Slf4j
|
||||
@Api(tags = "字典树操作")
|
||||
@RestController
|
||||
@RequestMapping("/dictTree")
|
||||
@RequiredArgsConstructor
|
||||
public class DictTreeController extends BaseController {
|
||||
|
||||
private final IDictTreeService dictTreeService;
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON)
|
||||
@GetMapping("/getTreeByCode")
|
||||
@ApiOperation("按照code查询字典树")
|
||||
@ApiImplicitParam(name = "code", value = "查询参数", required = true)
|
||||
public HttpResult<List<DictTree>> getTreeByCode(@RequestParam("code") String code) {
|
||||
String methodDescribe = getMethodDescribe("getTreeByCode");
|
||||
LogUtil.njcnDebug(log, "{},查询数据为:{}", methodDescribe, code);
|
||||
List<DictTree> result = dictTreeService.getTreeByCode(code);
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
|
||||
}
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON)
|
||||
@GetMapping("/getTreeByName")
|
||||
@ApiOperation("按照name模糊查询字典树")
|
||||
@ApiImplicitParam(name = "keyword", value = "查询参数", required = true)
|
||||
public HttpResult<List<DictTree>> getTreeByName(@RequestParam("name") String name) {
|
||||
String methodDescribe = getMethodDescribe("getTreeByName");
|
||||
LogUtil.njcnDebug(log, "{},查询数据为:{}", methodDescribe, name);
|
||||
List<DictTree> result = dictTreeService.getTreeByName(name);
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
|
||||
}
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.ADD)
|
||||
@PostMapping("/add")
|
||||
@ApiOperation("新增字典树数据")
|
||||
@ApiImplicitParam(name = "dictTreeParam", value = "字典数据", required = true)
|
||||
public HttpResult<Boolean> add(@RequestBody @Validated DictTreeParam dictTreeParam) {
|
||||
String methodDescribe = getMethodDescribe("add");
|
||||
LogUtil.njcnDebug(log, "{},字典数据为:{}", methodDescribe, dictTreeParam);
|
||||
boolean result = dictTreeService.addDictTree(dictTreeParam);
|
||||
if (result) {
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, true, methodDescribe);
|
||||
} else {
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, false, methodDescribe);
|
||||
}
|
||||
}
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.UPDATE)
|
||||
@PostMapping("/update")
|
||||
@ApiOperation("修改字典树数据")
|
||||
@ApiImplicitParam(name = "dicParam", value = "数据", required = true)
|
||||
public HttpResult<Boolean> update(@RequestBody @Validated DictTreeParam.UpdateParam dicParam) {
|
||||
String methodDescribe = getMethodDescribe("update");
|
||||
LogUtil.njcnDebug(log, "{},更新的信息为:{}", methodDescribe, dicParam);
|
||||
boolean result = dictTreeService.updateDictTree(dicParam);
|
||||
if (result) {
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, true, methodDescribe);
|
||||
} else {
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, false, methodDescribe);
|
||||
}
|
||||
}
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.DELETE)
|
||||
@PostMapping("/delete")
|
||||
@ApiOperation("删除字典树数据")
|
||||
@ApiImplicitParam(name = "id", value = "id", required = true)
|
||||
public HttpResult<Boolean> delete(@RequestParam @Validated String id) {
|
||||
String methodDescribe = getMethodDescribe("delete");
|
||||
LogUtil.njcnDebug(log, "{},删除的id为:{}", methodDescribe, id);
|
||||
boolean result = dictTreeService.deleteDictTree(id);
|
||||
if (result) {
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, true, methodDescribe);
|
||||
} else {
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, false, methodDescribe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
package com.njcn.gather.system.dictionary.controller;
|
||||
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.njcn.common.pojo.annotation.OperateInfo;
|
||||
import com.njcn.common.pojo.constant.OperateType;
|
||||
import com.njcn.common.pojo.enums.common.DataStateEnum;
|
||||
import com.njcn.common.pojo.enums.common.LogEnum;
|
||||
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
||||
import com.njcn.common.pojo.response.HttpResult;
|
||||
import com.njcn.common.utils.LogUtil;
|
||||
import com.njcn.gather.system.dictionary.pojo.param.DictTypeParam;
|
||||
import com.njcn.gather.system.dictionary.pojo.po.DictType;
|
||||
import com.njcn.gather.system.dictionary.service.IDictTypeService;
|
||||
import com.njcn.web.controller.BaseController;
|
||||
import com.njcn.web.utils.HttpResultUtil;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author hongawen
|
||||
* @since 2021-12-13
|
||||
*/
|
||||
@Slf4j
|
||||
@Api(tags = "字典类型表操作")
|
||||
@RestController
|
||||
@RequestMapping("/dictType")
|
||||
@RequiredArgsConstructor
|
||||
public class DictTypeController extends BaseController {
|
||||
|
||||
private final IDictTypeService dictTypeService;
|
||||
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON)
|
||||
@PostMapping("/list")
|
||||
@ApiOperation("查询字典类型")
|
||||
@ApiImplicitParam(name = "queryParam", value = "查询参数", required = true)
|
||||
public HttpResult<Page<DictType>> list(@RequestBody @Validated DictTypeParam.QueryParam queryParam) {
|
||||
String methodDescribe = getMethodDescribe("list");
|
||||
LogUtil.njcnDebug(log, "{},查询数据为:{}", methodDescribe, queryParam);
|
||||
Page<DictType> result = dictTypeService.listDictTypes(queryParam);
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
|
||||
}
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON)
|
||||
@GetMapping("/listAll")
|
||||
@ApiOperation("查询所有字典类型数据")
|
||||
public HttpResult<List<DictType>> listAll() {
|
||||
String methodDescribe = getMethodDescribe("listAll");
|
||||
LogUtil.njcnDebug(log, "{}", methodDescribe);
|
||||
List<DictType> dictTypeList = dictTypeService.list(new LambdaQueryWrapper<DictType>().eq(DictType::getState, DataStateEnum.ENABLE.getCode()));
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, dictTypeList, methodDescribe);
|
||||
}
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.ADD)
|
||||
@PostMapping("/add")
|
||||
@ApiOperation("新增字典类型")
|
||||
@ApiImplicitParam(name = "dictTypeParam", value = "字典类型数据", required = true)
|
||||
public HttpResult<Boolean> add(@RequestBody @Validated DictTypeParam dictTypeParam) {
|
||||
String methodDescribe = getMethodDescribe("add");
|
||||
LogUtil.njcnDebug(log, "{},字典类型数据为:{}", methodDescribe, dictTypeParam);
|
||||
boolean result = dictTypeService.addDictType(dictTypeParam);
|
||||
if (result) {
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, true, methodDescribe);
|
||||
} else {
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, false, methodDescribe);
|
||||
}
|
||||
}
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.UPDATE)
|
||||
@PostMapping("/update")
|
||||
@ApiOperation("修改字典类型")
|
||||
@ApiImplicitParam(name = "updateParam", value = "字典类型数据", required = true)
|
||||
public HttpResult<Boolean> update(@RequestBody @Validated DictTypeParam.UpdateParam updateParam) {
|
||||
String methodDescribe = getMethodDescribe("update");
|
||||
LogUtil.njcnDebug(log, "{},字典类型数据为:{}", methodDescribe, updateParam);
|
||||
boolean result = dictTypeService.updateDictType(updateParam);
|
||||
if (result) {
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, true, methodDescribe);
|
||||
} else {
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, false, methodDescribe);
|
||||
}
|
||||
}
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.DELETE)
|
||||
@PostMapping("/delete")
|
||||
@ApiOperation("删除字典类型")
|
||||
@ApiImplicitParam(name = "ids", value = "字典索引", required = true)
|
||||
public HttpResult<Boolean> delete(@RequestBody List<String> ids) {
|
||||
String methodDescribe = getMethodDescribe("delete");
|
||||
LogUtil.njcnDebug(log, "{},字典ID数据为:{}", methodDescribe, String.join(StrUtil.COMMA, ids));
|
||||
boolean result = dictTypeService.deleteDictType(ids);
|
||||
if (result) {
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, true, methodDescribe);
|
||||
} else {
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, false, methodDescribe);
|
||||
}
|
||||
}
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.DOWNLOAD)
|
||||
@PostMapping("/export")
|
||||
@ApiOperation("导出字典类型数据")
|
||||
@ApiImplicitParam(name = "queryParam", value = "查询参数", required = true)
|
||||
public void export(@RequestBody @Validated DictTypeParam.QueryParam queryParam) {
|
||||
dictTypeService.exportDictType(queryParam);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.njcn.gather.system.dictionary.mapper;
|
||||
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
import com.njcn.gather.system.dictionary.pojo.po.DictData;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author hongawen
|
||||
* @since 2021-12-13
|
||||
*/
|
||||
public interface DictDataMapper extends MPJBaseMapper<DictData> {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.njcn.gather.system.dictionary.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.njcn.gather.system.dictionary.pojo.po.DictTree;
|
||||
import com.njcn.gather.system.dictionary.pojo.vo.DictTreeVO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @data 2024/11/8
|
||||
*/
|
||||
public interface DictTreeMapper extends BaseMapper<DictTree> {
|
||||
List<DictTreeVO> queryLastLevelById(@Param("id") String id);
|
||||
|
||||
/**
|
||||
* 获取电压相角、电流相角的id列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<String> getPhaseAngleIds();
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.njcn.gather.system.dictionary.mapper;
|
||||
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
import com.njcn.gather.system.dictionary.pojo.po.DictType;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
*
|
||||
* @author hongawen
|
||||
* @since 2021-12-13
|
||||
*/
|
||||
public interface DictTypeMapper extends MPJBaseMapper<DictType> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.njcn.gather.system.dictionary.mapper.DictDataMapper">
|
||||
|
||||
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.njcn.gather.system.dictionary.mapper.DictTreeMapper">
|
||||
<select id="queryLastLevelById" resultType="com.njcn.gather.system.dictionary.pojo.vo.DictTreeVO">
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
sys_dict_tree a
|
||||
WHERE
|
||||
a.pids LIKE concat('%',#{id},'%')
|
||||
AND NOT EXISTS (
|
||||
SELECT
|
||||
1
|
||||
FROM
|
||||
sys_dict_tree b
|
||||
WHERE
|
||||
b.pids LIKE concat('%',#{id},'%') and a.id = b.pid)
|
||||
</select>
|
||||
<select id="getPhaseAngleIds" resultType="java.lang.String">
|
||||
select id from sys_dict_tree where name like '电压相角' or name like '电流相角'
|
||||
</select>
|
||||
</mapper>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.njcn.gather.system.dictionary.mapper.DictTypeMapper">
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.njcn.gather.system.dictionary.pojo.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author hongawen
|
||||
* @version 1.0
|
||||
* @data 2024/10/30 15:52
|
||||
*/
|
||||
@Data
|
||||
public class DictDataCache implements Serializable {
|
||||
|
||||
private String id;
|
||||
|
||||
private String name;
|
||||
|
||||
private String code;
|
||||
|
||||
private String value;
|
||||
|
||||
private int sort;
|
||||
|
||||
private String typeId;
|
||||
|
||||
private String typeName;
|
||||
|
||||
private String typeCode;
|
||||
|
||||
private Integer algoDescribe;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.njcn.gather.system.dictionary.pojo.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @data 2024-12-12
|
||||
*/
|
||||
@Getter
|
||||
public enum DictDataEnum {
|
||||
|
||||
/**
|
||||
* Key cleanup point: only keep registration-related platform capability
|
||||
* types that are still referenced by the retained activation flow.
|
||||
*/
|
||||
DIGITAL("数字式", "Digital"),
|
||||
SIMULATE("模拟式", "Simulate"),
|
||||
CONTRAST("比对式", "Contrast");
|
||||
|
||||
private final String name;
|
||||
private final String code;
|
||||
|
||||
DictDataEnum(String name, String code) {
|
||||
this.name = name;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public static String getMsgByValue(Integer name) {
|
||||
for (DictDataEnum state : DictDataEnum.values()) {
|
||||
if (state.getName().equals(name)) {
|
||||
return state.getCode();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static DictDataEnum getDictDataEnumByCode(String code) {
|
||||
for (DictDataEnum steadyIndicatorEnum : DictDataEnum.values()) {
|
||||
if (StringUtils.equals(code, steadyIndicatorEnum.getCode())) {
|
||||
return steadyIndicatorEnum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package com.njcn.gather.system.dictionary.pojo.param;
|
||||
|
||||
import com.njcn.common.pojo.constant.PatternRegex;
|
||||
import com.njcn.gather.system.pojo.constant.SystemValidMessage;
|
||||
import com.njcn.web.pojo.param.BaseParam;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import javax.validation.constraints.*;
|
||||
|
||||
/**
|
||||
* @author hongawen
|
||||
* @version 1.0.0
|
||||
* @date 2021年12月17日 15:49
|
||||
*/
|
||||
@Data
|
||||
public class DictDataParam {
|
||||
|
||||
|
||||
@ApiModelProperty("字典类型id")
|
||||
@NotBlank(message = SystemValidMessage.DICT_TYPE_ID_NOT_BLANK)
|
||||
@Pattern(regexp = PatternRegex.SYSTEM_ID, message = SystemValidMessage.DICT_TYPE_ID_FORMAT_ERROR)
|
||||
private String typeId;
|
||||
|
||||
|
||||
@ApiModelProperty("名称")
|
||||
@NotBlank(message = SystemValidMessage.NAME_NOT_BLANK)
|
||||
@Pattern(regexp = PatternRegex.DICT_DATA_NAME_REGEX, message = SystemValidMessage.DICT_DATA_NAME_FORMAT_ERROR)
|
||||
private String name;
|
||||
|
||||
|
||||
@ApiModelProperty("编码")
|
||||
@NotBlank(message = SystemValidMessage.CODE_NOT_BLANK)
|
||||
@Pattern(regexp = PatternRegex.DICT_DATA_CODE_REGEX, message = SystemValidMessage.DICT_DATA_CODE_FORMAT_ERROR)
|
||||
private String code;
|
||||
|
||||
|
||||
@ApiModelProperty("排序")
|
||||
@NotNull(message = SystemValidMessage.SORT_NOT_NULL)
|
||||
@Min(value = 1, message = SystemValidMessage.SORT_FORMAT_ERROR)
|
||||
@Max(value = 999, message = SystemValidMessage.SORT_FORMAT_ERROR)
|
||||
private Integer sort;
|
||||
|
||||
|
||||
@ApiModelProperty("事件等级:0-普通;1-中等;2-严重(默认为0)")
|
||||
private Integer level;
|
||||
|
||||
@ApiModelProperty("与高级算法内部Id描述对应")
|
||||
private Integer algoDescribe;
|
||||
|
||||
//todo 待定
|
||||
@ApiModelProperty("字典值")
|
||||
private String value;
|
||||
|
||||
/**
|
||||
* 是否开启使用Value值:0-关闭;1-开启(默认为0)
|
||||
*/
|
||||
@ApiModelProperty("是否开启使用Value值")
|
||||
private Integer openValue;
|
||||
|
||||
|
||||
/**
|
||||
* 更新操作实体
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public static class UpdateParam extends DictDataParam {
|
||||
|
||||
/**
|
||||
* 表Id
|
||||
*/
|
||||
@ApiModelProperty("id")
|
||||
@NotBlank(message = SystemValidMessage.ID_NOT_BLANK)
|
||||
@Pattern(regexp = PatternRegex.SYSTEM_ID, message = SystemValidMessage.ID_FORMAT_ERROR)
|
||||
private String id;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典类型id分页查询字典数据
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public static class QueryParam extends BaseParam {
|
||||
@ApiModelProperty("字典类型id")
|
||||
@NotBlank(message = SystemValidMessage.DICT_TYPE_ID_NOT_BLANK)
|
||||
@Pattern(regexp = PatternRegex.SYSTEM_ID, message = SystemValidMessage.DICT_TYPE_ID_FORMAT_ERROR)
|
||||
private String typeId;
|
||||
|
||||
@ApiModelProperty("名称")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("编码")
|
||||
private String code;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.njcn.gather.system.dictionary.pojo.param;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.njcn.common.pojo.constant.PatternRegex;
|
||||
import com.njcn.gather.system.pojo.constant.SystemValidMessage;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Pattern;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @data 2024/11/8
|
||||
*/
|
||||
@Data
|
||||
public class DictTreeParam {
|
||||
/**
|
||||
* 父id
|
||||
*/
|
||||
@ApiModelProperty(value = "父id")
|
||||
private String pid;
|
||||
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
@ApiModelProperty(value = "名称")
|
||||
@NotBlank(message = SystemValidMessage.NAME_NOT_BLANK)
|
||||
@Pattern(regexp = PatternRegex.DICT_NAME_REGEX, message = SystemValidMessage.DICT_TYPE_NAME_FORMAT_ERROR)
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 编码
|
||||
*/
|
||||
@ApiModelProperty(value = "编码")
|
||||
@TableField(value = "编码")
|
||||
@NotBlank(message = SystemValidMessage.CODE_NOT_BLANK)
|
||||
@Pattern(regexp = PatternRegex.DICT_CODE_REGEX, message = SystemValidMessage.DICT_TYPE_CODE_FORMAT_ERROR)
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 用于区分多种类型的字典树 0.台账对象类型 1.自定义报表指标类型
|
||||
*/
|
||||
@ApiModelProperty(value = "0.台账对象类型 1.自定义报表指标类型")
|
||||
private Integer type;
|
||||
|
||||
/**
|
||||
* 根据type自定义内容,type:0用于区分对象类型是101电网侧 102用户侧
|
||||
*/
|
||||
@ApiModelProperty(value = "根据type自定义内容,type:0用于区分对象类型是101电网侧 102用户侧")
|
||||
private String extend;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
@ApiModelProperty(value = "排序")
|
||||
private Integer sort;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
@ApiModelProperty(value = "描述")
|
||||
private String remark;
|
||||
|
||||
|
||||
/**
|
||||
* 更新操作实体
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public static class UpdateParam extends DictTreeParam {
|
||||
|
||||
|
||||
@ApiModelProperty("id")
|
||||
@NotBlank(message = SystemValidMessage.ID_NOT_BLANK)
|
||||
@Pattern(regexp = PatternRegex.SYSTEM_ID, message = SystemValidMessage.ID_FORMAT_ERROR)
|
||||
private String id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.njcn.gather.system.dictionary.pojo.param;
|
||||
|
||||
import com.njcn.common.pojo.constant.PatternRegex;
|
||||
import com.njcn.gather.system.pojo.constant.SystemValidMessage;
|
||||
import com.njcn.web.pojo.param.BaseParam;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import javax.validation.constraints.*;
|
||||
|
||||
/**
|
||||
* @author hongawen
|
||||
* @version 1.0
|
||||
* @data 2024/10/30 14:39
|
||||
*/
|
||||
@Data
|
||||
public class DictTypeParam {
|
||||
|
||||
@ApiModelProperty("名称")
|
||||
@NotBlank(message = SystemValidMessage.NAME_NOT_BLANK)
|
||||
@Pattern(regexp = PatternRegex.DICT_NAME_REGEX, message = SystemValidMessage.DICT_TYPE_NAME_FORMAT_ERROR)
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("编码")
|
||||
@NotBlank(message = SystemValidMessage.CODE_NOT_BLANK)
|
||||
@Pattern(regexp = PatternRegex.DICT_CODE_REGEX, message = SystemValidMessage.DICT_TYPE_CODE_FORMAT_ERROR)
|
||||
private String code;
|
||||
|
||||
|
||||
@ApiModelProperty("排序")
|
||||
@NotNull(message = SystemValidMessage.SORT_NOT_NULL)
|
||||
@Min(value = 1, message = SystemValidMessage.SORT_FORMAT_ERROR)
|
||||
@Max(value = 999, message = SystemValidMessage.SORT_FORMAT_ERROR)
|
||||
private Integer sort;
|
||||
|
||||
|
||||
@ApiModelProperty("开启等级:0-不开启;1-开启,默认不开启")
|
||||
@NotNull(message = SystemValidMessage.OPEN_LEVEL_NOT_NULL)
|
||||
@Min(value = 0, message = SystemValidMessage.OPEN_LEVEL_FORMAT_ERROR)
|
||||
@Max(value = 1, message = SystemValidMessage.OPEN_LEVEL_FORMAT_ERROR)
|
||||
private Integer openLevel;
|
||||
|
||||
|
||||
@ApiModelProperty("开启算法描述:0-不开启;1-开启,默认不开启")
|
||||
@NotNull(message = SystemValidMessage.OPEN_DESCRIBE_NOT_NULL)
|
||||
@Min(value = 0, message = SystemValidMessage.OPEN_DESCRIBE_FORMAT_ERROR)
|
||||
@Max(value = 1, message = SystemValidMessage.OPEN_DESCRIBE_FORMAT_ERROR)
|
||||
private Integer openDescribe;
|
||||
|
||||
|
||||
@ApiModelProperty("描述")
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 更新操作实体
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public static class UpdateParam extends DictTypeParam {
|
||||
|
||||
|
||||
@ApiModelProperty("id")
|
||||
@NotBlank(message = SystemValidMessage.ID_NOT_BLANK)
|
||||
@Pattern(regexp = PatternRegex.SYSTEM_ID, message = SystemValidMessage.ID_FORMAT_ERROR)
|
||||
private String id;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询实体
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public static class QueryParam extends BaseParam {
|
||||
@ApiModelProperty("名称")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("编码")
|
||||
private String code;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.njcn.gather.system.dictionary.pojo.po;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.njcn.db.mybatisplus.bo.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hongawen
|
||||
* @since 2021-12-13
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("sys_dict_data")
|
||||
public class DictData extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 字典数据表Id
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 字典类型表Id
|
||||
*/
|
||||
private String typeId;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 编码
|
||||
*/
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
private Integer sort;
|
||||
|
||||
/**
|
||||
* 事件等级:0-普通;1-中等;2-严重(默认为0)
|
||||
*/
|
||||
private Integer level;
|
||||
|
||||
/**
|
||||
* 与高级算法内部Id描述对应;
|
||||
*/
|
||||
private Integer algoDescribe;
|
||||
|
||||
/**
|
||||
* 目前只用于表示电压等级数值
|
||||
*/
|
||||
@TableField(fill = FieldFill.UPDATE)
|
||||
private String value;
|
||||
|
||||
/**
|
||||
* 是否开启使用Value值:0-关闭;1-开启(默认为0)
|
||||
*/
|
||||
private Integer openValue;
|
||||
|
||||
/**
|
||||
* 状态:0-删除 1-正常
|
||||
*/
|
||||
private Integer state;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.njcn.gather.system.dictionary.pojo.po;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.njcn.db.mybatisplus.bo.BaseEntity;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @data 2024/11/8
|
||||
*/
|
||||
@Data
|
||||
@TableName(value = "sys_dict_tree")
|
||||
public class DictTree extends BaseEntity {
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value = "id", type = IdType.ASSIGN_UUID)
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 父id
|
||||
*/
|
||||
@TableField(value = "pid")
|
||||
private String pid;
|
||||
|
||||
/**
|
||||
* 父ids
|
||||
*/
|
||||
@TableField(value = "pids")
|
||||
private String pids;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
@TableField(value = "name")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 编码
|
||||
*/
|
||||
@TableField(value = "code")
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 用于区分多种类型的字典树 0.台账对象类型 1.自定义报表指标类型
|
||||
*/
|
||||
private Integer type;
|
||||
|
||||
/**
|
||||
* 根据type自定义内容,type:0用于区分对象类型是101电网侧 102用户侧
|
||||
*/
|
||||
private String extend;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
@TableField(value = "sort")
|
||||
private Integer sort;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
@TableField(value = "remark")
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 状态(字典 0正常 1停用 2删除)
|
||||
*/
|
||||
@TableField(value = "state")
|
||||
private Integer state;
|
||||
|
||||
/**
|
||||
* 子类
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private List<DictTree> children;
|
||||
|
||||
// @TableField(exist = false)
|
||||
// private Integer level;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.njcn.gather.system.dictionary.pojo.po;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.njcn.db.mybatisplus.bo.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hongawen
|
||||
* @since 2021-12-13
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("sys_dict_type")
|
||||
public class DictType extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 字典类型表Id
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 编码
|
||||
*/
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
private Integer sort;
|
||||
|
||||
/**
|
||||
* 开启等级:0-不开启;1-开启,默认不开启
|
||||
*/
|
||||
private Integer openLevel;
|
||||
|
||||
|
||||
/**
|
||||
* 开启描述:0-不开启;1-开启,默认不开启
|
||||
*/
|
||||
private Integer openDescribe;
|
||||
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 状态:0-删除 1-正常
|
||||
*/
|
||||
private Integer state;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.njcn.gather.system.dictionary.pojo.vo;
|
||||
|
||||
import cn.afterturn.easypoi.excel.annotation.Excel;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @data 2024/11/6
|
||||
*/
|
||||
@Data
|
||||
public class DictDataExcel implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 字典数据表Id
|
||||
*/
|
||||
// @Excel(name = "字典数据id", width = 40)
|
||||
// private String id;
|
||||
|
||||
/**
|
||||
* 字典类型表Id
|
||||
*/
|
||||
// @Excel(name = "字典类型id", width = 40)
|
||||
// private String typeId;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
@Excel(name = "名称", width = 20)
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 编码
|
||||
*/
|
||||
@Excel(name = "编码", width = 20)
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
@Excel(name = "排序", width = 15)
|
||||
private Integer sort;
|
||||
|
||||
/**
|
||||
* 事件等级:0-普通;1-中等;2-严重(默认为0)
|
||||
*/
|
||||
@Excel(name = "事件等级", width = 15, replace = {"普通_0", "中等_1", "严重_2"})
|
||||
private Integer level;
|
||||
|
||||
/**
|
||||
* 与高级算法内部Id描述对应;
|
||||
*/
|
||||
@Excel(name = "高级算法内部id", width = 15)
|
||||
private Integer algoDescribe;
|
||||
|
||||
/**
|
||||
* 目前只用于表示电压等级数值
|
||||
*/
|
||||
@Excel(name = "数值", width = 15)
|
||||
private String value;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.njcn.gather.system.dictionary.pojo.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @data 2024/11/8
|
||||
*/
|
||||
@Data
|
||||
public class DictTreeVO implements Serializable {
|
||||
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 父id
|
||||
*/
|
||||
private String pid;
|
||||
/**
|
||||
* 父类名称
|
||||
*/
|
||||
private String pname;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 编码
|
||||
*/
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 用于区分多种类型的字典树 0.台账对象类型 1.自定义报表指标类型
|
||||
*/
|
||||
private Integer type;
|
||||
|
||||
/**
|
||||
* 根据type自定义内容,type:0用于区分对象类型是101电网侧 102用户侧
|
||||
*/
|
||||
private String extend;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
private Integer sort;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 状态(字典 0正常 1停用 2删除)
|
||||
*/
|
||||
private String state;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.njcn.gather.system.dictionary.pojo.vo;
|
||||
|
||||
import cn.afterturn.easypoi.excel.annotation.Excel;
|
||||
import cn.afterturn.easypoi.excel.annotation.ExcelCollection;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @date 2024/11/5
|
||||
*/
|
||||
@Data
|
||||
public class DictTypeExcel implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
@Excel(name = "名称", width = 20, needMerge = true)
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 编码
|
||||
*/
|
||||
@Excel(name = "编码", width = 20, needMerge = true)
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
@Excel(name = "排序", width = 15, needMerge = true)
|
||||
private Integer sort;
|
||||
|
||||
/**
|
||||
* 开启等级:0-不开启;1-开启,默认不开启
|
||||
*/
|
||||
@Excel(name = "开启等级", width = 15, replace = {"开启_1", "不开启_0"}, needMerge = true)
|
||||
private Integer openLevel;
|
||||
|
||||
/**
|
||||
* 开启描述:0-不开启;1-开启,默认不开启
|
||||
*/
|
||||
@Excel(name = "开启描述", width = 15, replace = {"开启_1", "不开启_0"}, needMerge = true)
|
||||
private Integer openDescribe;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
@Excel(name = "描述", width = 50, needMerge = true)
|
||||
private String remark;
|
||||
|
||||
@ExcelCollection(name = "字典内容")
|
||||
private List<DictDataExcel> dictDataExcels;
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package com.njcn.gather.system.dictionary.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.njcn.gather.system.dictionary.pojo.param.DictDataParam;
|
||||
import com.njcn.gather.system.dictionary.pojo.po.DictData;
|
||||
import com.njcn.web.pojo.dto.SimpleTreeDTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author hongawen
|
||||
* @since 2021-12-13
|
||||
*/
|
||||
public interface IDictDataService extends IService<DictData> {
|
||||
|
||||
|
||||
/**
|
||||
* 根据字典类型id查询字典信息
|
||||
* @param queryParam 查询参数
|
||||
* @return 操作结果
|
||||
*/
|
||||
Page<DictData> getDictDataByTypeId(DictDataParam.QueryParam queryParam);
|
||||
|
||||
/**
|
||||
* 根据字典类型id查询该类型下所有字典数据
|
||||
*
|
||||
* @param typeId
|
||||
* @return
|
||||
*/
|
||||
List<DictData> listDictDataByTypeId(String typeId);
|
||||
|
||||
/**
|
||||
* 根据字典类型id查询字典信息
|
||||
* @param typeId 字典类型id
|
||||
* @return 操作结果
|
||||
*/
|
||||
List<DictData> getDictDataByTypeId(String typeId);
|
||||
|
||||
/**
|
||||
* 新增数据字典
|
||||
* @param dictDataParam 字典数据
|
||||
* @return 操作结果
|
||||
*/
|
||||
boolean addDictData(DictDataParam dictDataParam);
|
||||
|
||||
|
||||
/**
|
||||
* 更新字典数据
|
||||
* @param updateParam 字典数据
|
||||
* @return 操作结果
|
||||
*/
|
||||
boolean updateDictData(DictDataParam.UpdateParam updateParam);
|
||||
|
||||
/**
|
||||
* 批量逻辑删除字典数据
|
||||
* @param ids 字典id集合
|
||||
* @return 操作结果
|
||||
*/
|
||||
boolean deleteDictData(List<String> ids);
|
||||
|
||||
/**
|
||||
* 根据字典id获取字典数据
|
||||
* @param id 查询参数
|
||||
* @return 根据字典id查询字典数据
|
||||
*/
|
||||
DictData getDictDataById(String id);
|
||||
|
||||
/**
|
||||
* 根据字典名称获取字典数据
|
||||
* @param name 字典名称
|
||||
* @return 根据字典名称查询字典数据
|
||||
*/
|
||||
DictData getDictDataByName(String name);
|
||||
|
||||
/**
|
||||
* 根据字典code获取字典数据
|
||||
* @param code 字典code
|
||||
* @return 根据字典code查询字典数据
|
||||
*/
|
||||
DictData getDictDataByCode(String code);
|
||||
|
||||
/**
|
||||
* 获取所有字典数据基础信息
|
||||
* @return 返回所有字典数据
|
||||
*/
|
||||
List<SimpleTreeDTO> dictDataCache();
|
||||
|
||||
/**
|
||||
* 导出字典数据
|
||||
* @param queryParam 查询参数
|
||||
*/
|
||||
void exportDictData(DictDataParam.QueryParam queryParam);
|
||||
|
||||
/**
|
||||
* 根据字典类型id删除字典数据
|
||||
* @param ids 字典类型id集合
|
||||
* @return 成功返回true,失败返回false
|
||||
*/
|
||||
boolean deleteDictDataByDictTypeId(List<String> ids);
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.njcn.gather.system.dictionary.service;
|
||||
|
||||
import com.njcn.gather.system.dictionary.pojo.param.DictTreeParam;
|
||||
import com.njcn.gather.system.dictionary.pojo.po.DictTree;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.njcn.gather.system.dictionary.pojo.vo.DictTreeVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @data 2024/11/8
|
||||
*/
|
||||
public interface IDictTreeService extends IService<DictTree> {
|
||||
|
||||
/**
|
||||
* 根据code查询字典树
|
||||
*
|
||||
* @param code 编码
|
||||
* @return 字典树
|
||||
*/
|
||||
List<DictTree> getTreeByCode(String code);
|
||||
|
||||
/**
|
||||
* 根据name查询字典树
|
||||
*
|
||||
* @param name 编码
|
||||
* @return 字典树
|
||||
*/
|
||||
List<DictTree> getTreeByName(String name);
|
||||
|
||||
boolean addDictTree(DictTreeParam dictTreeParam);
|
||||
|
||||
boolean updateDictTree(DictTreeParam.UpdateParam param);
|
||||
|
||||
boolean deleteDictTree(String id);
|
||||
|
||||
/**
|
||||
* 根据id查询字典数据
|
||||
*
|
||||
* @param id id
|
||||
*/
|
||||
DictTree queryById(String id);
|
||||
|
||||
/**
|
||||
* 查询所有字典树
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<DictTree> queryTree();
|
||||
|
||||
/**
|
||||
* 根据字典树id查询字典树
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
List<DictTree> getDictTreeById(List<String> ids);
|
||||
|
||||
DictTree getDictTreeByCode(String code);
|
||||
|
||||
List<DictTree> listByFatherIds(List<String> fatherIdList);
|
||||
|
||||
/**
|
||||
* 获取父级字典树
|
||||
* @param id 字典树ID
|
||||
* @return 父级字典树
|
||||
*/
|
||||
DictTree queryParentById(String id);
|
||||
|
||||
/**
|
||||
* 根据id获取所有子节点的ID
|
||||
* @param scriptId 字典树ID
|
||||
* @return 所有子节点ID
|
||||
*/
|
||||
List<String> getChildIds(String scriptId);
|
||||
|
||||
/**
|
||||
* 测试项排个序
|
||||
* @param scriptList 测试项
|
||||
* @return 有序的测试项
|
||||
*/
|
||||
List<String> sort(List<String> scriptList);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.njcn.gather.system.dictionary.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.njcn.gather.system.dictionary.pojo.param.DictTypeParam;
|
||||
import com.njcn.gather.system.dictionary.pojo.po.DictType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author hongawen
|
||||
* @since 2021-12-13
|
||||
*/
|
||||
public interface IDictTypeService extends IService<DictType> {
|
||||
|
||||
/**
|
||||
* 根据前台传递参数,分页查询字典类型数据
|
||||
* @param queryParam 查询参数
|
||||
* @return 字典列表
|
||||
*/
|
||||
Page<DictType> listDictTypes(DictTypeParam.QueryParam queryParam);
|
||||
|
||||
/**
|
||||
* 新增字典类型数据
|
||||
*
|
||||
* @param dictTypeParam 字典类型数据
|
||||
* @return 操作结果
|
||||
*/
|
||||
boolean addDictType(DictTypeParam dictTypeParam);
|
||||
|
||||
/**
|
||||
* 修改字典类型
|
||||
*
|
||||
* @param updateParam 字典类型数据
|
||||
* @return 操作结果
|
||||
*/
|
||||
boolean updateDictType(DictTypeParam.UpdateParam updateParam);
|
||||
|
||||
/**
|
||||
* 批量逻辑删除字典类型数据
|
||||
* @param ids id集合
|
||||
* @return 操作结果
|
||||
*/
|
||||
boolean deleteDictType(List<String> ids);
|
||||
|
||||
/**
|
||||
* 导出字典类型数据
|
||||
* @param queryParam 查询参数
|
||||
*/
|
||||
void exportDictType(DictTypeParam.QueryParam queryParam);
|
||||
|
||||
/**
|
||||
* 根据code获取字典类型数据
|
||||
*
|
||||
* @param code 字典类型code
|
||||
* @return
|
||||
*/
|
||||
DictType getByCode(String code);
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
package com.njcn.gather.system.dictionary.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
||||
import com.njcn.common.pojo.enums.common.DataStateEnum;
|
||||
import com.njcn.common.pojo.exception.BusinessException;
|
||||
import com.njcn.db.mybatisplus.constant.DbConstant;
|
||||
import com.njcn.gather.system.dictionary.mapper.DictDataMapper;
|
||||
import com.njcn.gather.system.dictionary.pojo.dto.DictDataCache;
|
||||
import com.njcn.gather.system.dictionary.pojo.param.DictDataParam;
|
||||
import com.njcn.gather.system.dictionary.pojo.po.DictData;
|
||||
import com.njcn.gather.system.dictionary.pojo.po.DictType;
|
||||
import com.njcn.gather.system.dictionary.pojo.vo.DictDataExcel;
|
||||
import com.njcn.gather.system.dictionary.service.IDictDataService;
|
||||
import com.njcn.gather.system.pojo.enums.SystemResponseEnum;
|
||||
import com.njcn.web.factory.PageFactory;
|
||||
import com.njcn.web.pojo.dto.SimpleDTO;
|
||||
import com.njcn.web.pojo.dto.SimpleTreeDTO;
|
||||
import com.njcn.web.utils.ExcelUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author hongawen
|
||||
* @since 2021-12-13
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class DictDataServiceImpl extends ServiceImpl<DictDataMapper, DictData> implements IDictDataService {
|
||||
|
||||
@Override
|
||||
public Page<DictData> getDictDataByTypeId(DictDataParam.QueryParam queryParam) {
|
||||
QueryWrapper<DictData> queryWrapper = new QueryWrapper<>();
|
||||
if (ObjectUtil.isNotNull(queryParam)) {
|
||||
queryWrapper.like(StrUtil.isNotBlank(queryParam.getName()), "sys_dict_data.name", queryParam.getName())
|
||||
.like(StrUtil.isNotBlank(queryParam.getCode()), "sys_dict_data.code", queryParam.getCode());
|
||||
//排序
|
||||
if (ObjectUtil.isAllNotEmpty(queryParam.getSortBy(), queryParam.getOrderBy())) {
|
||||
queryWrapper.orderBy(true, queryParam.getOrderBy().equals(DbConstant.ASC), StrUtil.toUnderlineCase(queryParam.getSortBy()));
|
||||
} else {
|
||||
//没有排序参数,默认根据sort字段排序,没有排序字段的,根据updateTime更新时间排序
|
||||
queryWrapper.orderBy(true, true, "sys_dict_data.sort").orderByDesc("sys_dict_data.update_time");
|
||||
}
|
||||
} else {
|
||||
queryWrapper.orderBy(true, true, "sys_dict_data.sort").orderByDesc("sys_dict_data.update_time");
|
||||
}
|
||||
queryWrapper.ne("sys_dict_data.state", DataStateEnum.DELETED.getCode())
|
||||
.eq("sys_dict_data.type_id", queryParam.getTypeId());
|
||||
//初始化分页数据
|
||||
return this.baseMapper.selectPage(new Page<>(PageFactory.getPageNum(queryParam), PageFactory.getPageSize(queryParam)), queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictData> listDictDataByTypeId(String typeId) {
|
||||
return this.lambdaQuery().eq(DictData::getTypeId, typeId).eq(DictData::getState, DataStateEnum.ENABLE.getCode()).list();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictData> getDictDataByTypeId(String typeId) {
|
||||
return this.lambdaQuery().eq(DictData::getTypeId, typeId).eq(DictData::getState, DataStateEnum.ENABLE.getCode()).list();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public boolean addDictData(DictDataParam dictDataParam) {
|
||||
dictDataParam.setName(dictDataParam.getName().trim());
|
||||
checkDicDataName(dictDataParam, false);
|
||||
DictData dictData = new DictData();
|
||||
BeanUtil.copyProperties(dictDataParam, dictData);
|
||||
//默认为正常状态
|
||||
dictData.setState(DataStateEnum.ENABLE.getCode());
|
||||
return this.save(dictData);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public boolean updateDictData(DictDataParam.UpdateParam updateParam) {
|
||||
updateParam.setName(updateParam.getName().trim());
|
||||
checkDicDataName(updateParam, true);
|
||||
DictData dictData = new DictData();
|
||||
BeanUtil.copyProperties(updateParam, dictData);
|
||||
return this.updateById(dictData);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public boolean deleteDictData(List<String> ids) {
|
||||
return this.lambdaUpdate()
|
||||
.set(DictData::getState, DataStateEnum.DELETED.getCode())
|
||||
.in(DictData::getId, ids)
|
||||
.update();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DictData getDictDataById(String id) {
|
||||
return this.lambdaQuery().eq(DictData::getId, id).eq(DictData::getState, DataStateEnum.ENABLE.getCode()).one();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DictData getDictDataByName(String name) {
|
||||
return this.lambdaQuery().eq(DictData::getName, name).eq(DictData::getState, DataStateEnum.ENABLE.getCode()).one();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DictData getDictDataByCode(String code) {
|
||||
LambdaQueryWrapper<DictData> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(DictData::getCode, code)
|
||||
.eq(DictData::getState, DataStateEnum.ENABLE.getCode());
|
||||
return this.baseMapper.selectOne(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SimpleTreeDTO> dictDataCache() {
|
||||
MPJLambdaWrapper<DictData> dictTypeWrapper = new MPJLambdaWrapper<DictData>()
|
||||
.eq(DictData::getState, DataStateEnum.ENABLE.getCode())
|
||||
.selectAll(DictData.class)
|
||||
.selectAs(DictType::getId, DictDataCache::getTypeId)
|
||||
.selectAs(DictType::getName, DictDataCache::getTypeName)
|
||||
.selectAs(DictType::getCode, DictDataCache::getTypeCode)
|
||||
.leftJoin(DictType.class, DictType::getId, DictData::getTypeId)
|
||||
.eq(DictType::getState, DataStateEnum.ENABLE.getCode());
|
||||
List<DictDataCache> allDictData = this.getBaseMapper().selectJoinList(DictDataCache.class, dictTypeWrapper);
|
||||
|
||||
Map<Object, List<DictDataCache>> dictDataCacheMap = allDictData.stream()
|
||||
.collect(Collectors.groupingBy(DictDataCache::getTypeId));
|
||||
return dictDataCacheMap.keySet().stream().map(typeId -> {
|
||||
SimpleTreeDTO simpleTreeDTO = new SimpleTreeDTO();
|
||||
List<DictDataCache> dictDataCaches = dictDataCacheMap.get(typeId);
|
||||
List<SimpleDTO> simpleDTOList = dictDataCaches.stream().map(dictDataCache -> {
|
||||
simpleTreeDTO.setCode(dictDataCache.getTypeCode());
|
||||
simpleTreeDTO.setId(dictDataCache.getTypeId());
|
||||
simpleTreeDTO.setName(dictDataCache.getTypeName());
|
||||
SimpleDTO simpleDTO = new SimpleDTO();
|
||||
simpleDTO.setCode(dictDataCache.getCode());
|
||||
simpleDTO.setId(dictDataCache.getId());
|
||||
simpleDTO.setName(dictDataCache.getName());
|
||||
simpleDTO.setSort(dictDataCache.getSort());
|
||||
simpleDTO.setValue(dictDataCache.getValue());
|
||||
simpleDTO.setAlgoDescribe(dictDataCache.getAlgoDescribe());
|
||||
return simpleDTO;
|
||||
}).sorted(Comparator.comparing(SimpleDTO::getSort)).collect(Collectors.toList());
|
||||
simpleTreeDTO.setChildren(simpleDTOList);
|
||||
return simpleTreeDTO;
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void exportDictData(DictDataParam.QueryParam queryParam) {
|
||||
QueryWrapper<DictData> queryWrapper = new QueryWrapper<>();
|
||||
if (ObjectUtil.isNotNull(queryParam)) {
|
||||
queryWrapper.like(StrUtil.isNotBlank(queryParam.getName()), "sys_dict_data.name", queryParam.getName())
|
||||
.like(StrUtil.isNotBlank(queryParam.getCode()), "sys_dict_data.code", queryParam.getCode());
|
||||
//排序
|
||||
if (ObjectUtil.isAllNotEmpty(queryParam.getSortBy(), queryParam.getOrderBy())) {
|
||||
queryWrapper.orderBy(true, queryParam.getOrderBy().equals(DbConstant.ASC), StrUtil.toUnderlineCase(queryParam.getSortBy()));
|
||||
} else {
|
||||
//没有排序参数,默认根据sort字段排序,没有排序字段的,根据updateTime更新时间排序
|
||||
queryWrapper.orderBy(true, true, "sys_dict_data.sort").orderByDesc("sys_dict_data.update_time");
|
||||
}
|
||||
}
|
||||
queryWrapper.ne("sys_dict_data.state", DataStateEnum.DELETED.getCode())
|
||||
.eq("sys_dict_data.type_id", queryParam.getTypeId());
|
||||
List<DictData> dictDatas = this.list(queryWrapper);
|
||||
List<DictDataExcel> dictDataExcels = BeanUtil.copyToList(dictDatas, DictDataExcel.class);
|
||||
ExcelUtil.exportExcel("字典数据导出数据.xlsx", "字典数据", DictDataExcel.class, dictDataExcels);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public boolean deleteDictDataByDictTypeId(List<String> ids) {
|
||||
return this.lambdaUpdate().in(DictData::getTypeId, ids).set(DictData::getState, DataStateEnum.DELETED.getCode()).update();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 校验参数,检查是否存在相同名称的字典类型
|
||||
*/
|
||||
private void checkDicDataName(DictDataParam dictDataParam, boolean isExcludeSelf) {
|
||||
LambdaQueryWrapper<DictData> dictDataLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
dictDataLambdaQueryWrapper.eq(DictData::getTypeId, dictDataParam.getTypeId())
|
||||
.eq(DictData::getState, DataStateEnum.ENABLE.getCode())
|
||||
.and(w -> w.eq(DictData::getName, dictDataParam.getName()).or().eq(DictData::getCode, dictDataParam.getCode()));
|
||||
//更新的时候,需排除当前记录
|
||||
if (isExcludeSelf) {
|
||||
if (dictDataParam instanceof DictDataParam.UpdateParam) {
|
||||
dictDataLambdaQueryWrapper.ne(DictData::getId, ((DictDataParam.UpdateParam) dictDataParam).getId());
|
||||
}
|
||||
}
|
||||
int countByAccount = this.count(dictDataLambdaQueryWrapper);
|
||||
//大于等于1个则表示重复
|
||||
if (countByAccount >= 1) {
|
||||
throw new BusinessException(SystemResponseEnum.DICT_DATA_REPEAT);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
package com.njcn.gather.system.dictionary.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.text.StrPool;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.njcn.common.pojo.exception.BusinessException;
|
||||
import com.njcn.gather.system.dictionary.mapper.DictTreeMapper;
|
||||
import com.njcn.gather.system.dictionary.pojo.param.DictTreeParam;
|
||||
import com.njcn.gather.system.dictionary.pojo.po.DictTree;
|
||||
import com.njcn.gather.system.dictionary.service.IDictTreeService;
|
||||
import com.njcn.gather.system.pojo.constant.DictConst;
|
||||
import com.njcn.gather.system.pojo.enums.SystemResponseEnum;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @data 2024/11/8
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class DictTreeServiceImpl extends ServiceImpl<DictTreeMapper, DictTree> implements IDictTreeService {
|
||||
|
||||
|
||||
@Override
|
||||
public List<DictTree> getTreeByCode(String code) {
|
||||
List<DictTree> dictTree = this.queryTree();
|
||||
|
||||
if (ObjectUtil.isNotEmpty(dictTree)) {
|
||||
dictTree = dictTree.stream().filter(item -> item.getCode().equals(code)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
return dictTree;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictTree> getTreeByName(String name) {
|
||||
List<DictTree> dictTree = this.queryTree();
|
||||
|
||||
if (ObjectUtil.isNotEmpty(dictTree) && StrUtil.isNotBlank(name)) {
|
||||
dictTree = dictTree.stream().filter(item -> item.getName().contains(name)).collect(Collectors.toList());
|
||||
}
|
||||
return dictTree;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public boolean addDictTree(DictTreeParam dictTreeParam) {
|
||||
dictTreeParam.setName(dictTreeParam.getName().trim());
|
||||
checkRepeat(dictTreeParam, false);
|
||||
boolean result;
|
||||
DictTree dictTree = new DictTree();
|
||||
BeanUtils.copyProperties(dictTreeParam, dictTree);
|
||||
if (!Objects.equals(dictTree.getPid(), DictConst.FATHER_ID)) {
|
||||
QueryWrapper<DictTree> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("id", dictTree.getPid());
|
||||
DictTree instance = this.baseMapper.selectOne(queryWrapper);
|
||||
dictTree.setPids(instance.getPids() + StrPool.COMMA + instance.getId());
|
||||
} else {
|
||||
dictTree.setPids(DictConst.FATHER_ID);
|
||||
}
|
||||
dictTree.setState(DictConst.ENABLE);
|
||||
result = this.save(dictTree);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public boolean updateDictTree(DictTreeParam.UpdateParam param) {
|
||||
param.setName(param.getName().trim());
|
||||
DictTree dictTree = this.getById(param.getId());
|
||||
if ("975f63baeb6f653c54fca226a9ae36ca".equals(param.getId()) || dictTree.getPids().contains("975f63baeb6f653c54fca226a9ae36ca")) {
|
||||
throw new BusinessException(SystemResponseEnum.CAN_NOT_UPDATE_USED_DICT);
|
||||
}
|
||||
checkRepeat(param, true);
|
||||
DictTree copyDictTree = new DictTree();
|
||||
BeanUtils.copyProperties(param, copyDictTree);
|
||||
return this.updateById(copyDictTree);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public boolean deleteDictTree(String id) {
|
||||
boolean result = false;
|
||||
DictTree dictTree = this.getById(id);
|
||||
if ("975f63baeb6f653c54fca226a9ae36ca".equals(id) || dictTree.getPids().contains("975f63baeb6f653c54fca226a9ae36ca")) {
|
||||
throw new BusinessException(SystemResponseEnum.CAN_NOT_DELETE_USED_DICT);
|
||||
}
|
||||
|
||||
List<DictTree> childrenList = this.lambdaQuery().eq(DictTree::getState, DictConst.ENABLE).eq(DictTree::getPid, id).list();
|
||||
if (CollectionUtils.isEmpty(childrenList)) {
|
||||
result = this.lambdaUpdate().set(DictTree::getState, DictConst.DELETE).in(DictTree::getId, id).update();
|
||||
} else {
|
||||
throw new BusinessException(SystemResponseEnum.EXISTS_CHILDREN_NOT_DELETE);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DictTree queryById(String id) {
|
||||
return this.lambdaQuery().eq(DictTree::getId, id).eq(DictTree::getState, DictConst.ENABLE).one();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictTree> queryTree() {
|
||||
LambdaQueryWrapper<DictTree> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
lambdaQueryWrapper.eq(DictTree::getState, DictConst.ENABLE);
|
||||
List<DictTree> dictTreeList = this.list(lambdaQueryWrapper);
|
||||
return dictTreeList.stream().filter(item -> DictConst.FATHER_ID.equals(item.getPid())).peek(item -> {
|
||||
// item.setLevel(0);
|
||||
item.setChildren(getChildren(item, dictTreeList));
|
||||
}).sorted(Comparator.comparingInt(DictTree::getSort)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictTree> getDictTreeById(List<String> ids) {
|
||||
return this.list(new LambdaQueryWrapper<DictTree>()
|
||||
.in(CollUtil.isNotEmpty(ids), DictTree::getId, ids)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DictTree getDictTreeByCode(String code) {
|
||||
return this.getOne(new LambdaQueryWrapper<DictTree>()
|
||||
.eq(DictTree::getCode, code)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictTree> listByFatherIds(List<String> fatherIdList) {
|
||||
if (CollUtil.isNotEmpty(fatherIdList)) {
|
||||
return this.lambdaQuery().in(DictTree::getPid, fatherIdList).eq(DictTree::getState, DictConst.ENABLE).list();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DictTree queryParentById(String id) {
|
||||
DictTree temp = this.lambdaQuery().eq(DictTree::getId, id).eq(DictTree::getState, DictConst.ENABLE).one();
|
||||
return this.lambdaQuery().eq(DictTree::getId, temp.getPid()).one();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getChildIds(String scriptId) {
|
||||
List<DictTree> subTree = this.lambdaQuery().eq(DictTree::getPid, scriptId)
|
||||
.eq(DictTree::getState, DictConst.ENABLE)
|
||||
.list();
|
||||
if(CollectionUtil.isNotEmpty(subTree)){
|
||||
return subTree.stream().map(DictTree::getId).collect(Collectors.toList());
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> sort(List<String> scriptList) {
|
||||
if (CollectionUtil.isEmpty(scriptList)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return this.lambdaQuery()
|
||||
.in(DictTree::getId, scriptList)
|
||||
.orderByAsc(DictTree::getSort)
|
||||
.list()
|
||||
.stream()
|
||||
.map(DictTree::getId)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private void checkRepeat(DictTreeParam dictTreeParam, boolean isExcludeSelf) {
|
||||
LambdaQueryWrapper<DictTree> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(DictTree::getPid, dictTreeParam.getPid()) // 同一父节点下不能有相同的code
|
||||
.eq(DictTree::getCode, dictTreeParam.getCode())
|
||||
.eq(DictTree::getState, DictConst.ENABLE);
|
||||
if (isExcludeSelf) {
|
||||
if (dictTreeParam instanceof DictTreeParam.UpdateParam) {
|
||||
wrapper.ne(DictTree::getId, ((DictTreeParam.UpdateParam) dictTreeParam).getId());
|
||||
}
|
||||
}
|
||||
int count = this.count(wrapper);
|
||||
if (count > 0) {
|
||||
throw new BusinessException(SystemResponseEnum.CODE_REPEAT);
|
||||
}
|
||||
}
|
||||
|
||||
private List<DictTree> filterTreeByName(List<DictTree> tree, String keyword) {
|
||||
if (CollectionUtils.isEmpty(tree) || !StrUtil.isNotBlank(keyword)) {
|
||||
return tree;
|
||||
}
|
||||
filter(tree, keyword);
|
||||
return tree;
|
||||
}
|
||||
|
||||
private void filter(List<DictTree> list, String keyword) {
|
||||
for (int i = list.size() - 1; i >= 0; i--) {
|
||||
DictTree dictTree = list.get(i);
|
||||
List<DictTree> children = dictTree.getChildren();
|
||||
if (!dictTree.getName().contains(keyword)) {
|
||||
if (!CollectionUtils.isEmpty(children)) {
|
||||
filter(children, keyword);
|
||||
}
|
||||
if (CollectionUtils.isEmpty(dictTree.getChildren())) {
|
||||
list.remove(i);
|
||||
}
|
||||
}
|
||||
// else {
|
||||
// if (!CollectionUtils.isEmpty(children)) {
|
||||
// filter(children, keyword);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
private List<DictTree> getChildren(DictTree dictTree, List<DictTree> all) {
|
||||
return all.stream().filter(item -> item.getPid().equals(dictTree.getId())).peek(item -> {
|
||||
// item.setLevel(dictTree.getLevel() + 1);
|
||||
item.setChildren(getChildren(item, all));
|
||||
}).sorted(Comparator.comparingInt(DictTree::getSort)).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
package com.njcn.gather.system.dictionary.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.njcn.common.pojo.enums.common.DataStateEnum;
|
||||
import com.njcn.common.pojo.exception.BusinessException;
|
||||
import com.njcn.db.mybatisplus.constant.DbConstant;
|
||||
import com.njcn.gather.system.dictionary.mapper.DictTypeMapper;
|
||||
import com.njcn.gather.system.dictionary.pojo.param.DictTypeParam;
|
||||
import com.njcn.gather.system.dictionary.pojo.po.DictData;
|
||||
import com.njcn.gather.system.dictionary.pojo.po.DictType;
|
||||
import com.njcn.gather.system.dictionary.pojo.vo.DictDataExcel;
|
||||
import com.njcn.gather.system.dictionary.pojo.vo.DictTypeExcel;
|
||||
import com.njcn.gather.system.dictionary.service.IDictDataService;
|
||||
import com.njcn.gather.system.dictionary.service.IDictTypeService;
|
||||
import com.njcn.gather.system.pojo.enums.SystemResponseEnum;
|
||||
import com.njcn.web.factory.PageFactory;
|
||||
import com.njcn.web.utils.ExcelUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author hongawen
|
||||
* @since 2021-12-13
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class DictTypeServiceImpl extends ServiceImpl<DictTypeMapper, DictType> implements IDictTypeService {
|
||||
private final IDictDataService dictDataService;
|
||||
|
||||
@Override
|
||||
public Page<DictType> listDictTypes(DictTypeParam.QueryParam queryParam) {
|
||||
QueryWrapper<DictType> queryWrapper = new QueryWrapper<>();
|
||||
if (ObjectUtil.isNotNull(queryParam)) {
|
||||
queryWrapper.like(StrUtil.isNotBlank(queryParam.getName()), "sys_dict_type.name", queryParam.getName())
|
||||
.like(StrUtil.isNotBlank(queryParam.getCode()), "sys_dict_type.code", queryParam.getCode());
|
||||
//排序
|
||||
if (ObjectUtil.isAllNotEmpty(queryParam.getSortBy(), queryParam.getOrderBy())) {
|
||||
queryWrapper.orderBy(true, queryParam.getOrderBy().equals(DbConstant.ASC), StrUtil.toUnderlineCase(queryParam.getSortBy()));
|
||||
} else {
|
||||
//没有排序参数,默认根据sort字段排序,没有排序字段的,根据updateTime更新时间排序
|
||||
queryWrapper.orderBy(true, true, "sys_dict_type.sort").orderByDesc("sys_dict_type.update_time");
|
||||
}
|
||||
} else {
|
||||
queryWrapper.orderBy(true, true, "sys_dict_type.sort").orderByDesc("sys_dict_type.update_time");
|
||||
}
|
||||
queryWrapper.ne("sys_dict_type.state", DataStateEnum.DELETED.getCode());
|
||||
return this.baseMapper.selectPage(new Page<>(PageFactory.getPageNum(queryParam), PageFactory.getPageSize(queryParam)), queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public boolean addDictType(DictTypeParam dictTypeParam) {
|
||||
dictTypeParam.setName(dictTypeParam.getName().trim());
|
||||
checkDicTypeName(dictTypeParam, false);
|
||||
DictType dictType = new DictType();
|
||||
BeanUtil.copyProperties(dictTypeParam, dictType);
|
||||
//默认为正常状态
|
||||
dictType.setState(DataStateEnum.ENABLE.getCode());
|
||||
return this.save(dictType);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public boolean updateDictType(DictTypeParam.UpdateParam updateParam) {
|
||||
updateParam.setName(updateParam.getName().trim());
|
||||
checkDicTypeName(updateParam, true);
|
||||
DictType dictType = new DictType();
|
||||
BeanUtil.copyProperties(updateParam, dictType);
|
||||
return this.updateById(dictType);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public boolean deleteDictType(List<String> ids) {
|
||||
dictDataService.deleteDictDataByDictTypeId(ids);
|
||||
return this.lambdaUpdate()
|
||||
.set(DictType::getState, DataStateEnum.DELETED.getCode())
|
||||
.in(DictType::getId, ids)
|
||||
.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportDictType(DictTypeParam.QueryParam queryParam) {
|
||||
QueryWrapper<DictType> queryWrapper = new QueryWrapper<>();
|
||||
if (ObjectUtil.isNotNull(queryParam)) {
|
||||
queryWrapper.like(StrUtil.isNotBlank(queryParam.getName()), "sys_dict_type.name", queryParam.getName())
|
||||
.like(StrUtil.isNotBlank(queryParam.getCode()), "sys_dict_type.code", queryParam.getCode());
|
||||
//排序
|
||||
if (ObjectUtil.isAllNotEmpty(queryParam.getSortBy(), queryParam.getOrderBy())) {
|
||||
queryWrapper.orderBy(true, queryParam.getOrderBy().equals(DbConstant.ASC), StrUtil.toUnderlineCase(queryParam.getSortBy()));
|
||||
} else {
|
||||
//没有排序参数,默认根据sort字段排序,没有排序字段的,根据updateTime更新时间排序
|
||||
queryWrapper.orderBy(true, true, "sys_dict_type.sort").orderByDesc("sys_dict_type.update_time");
|
||||
}
|
||||
}
|
||||
queryWrapper.ne("sys_dict_type.state", DataStateEnum.DELETED.getCode());
|
||||
List<DictType> dictTypes = this.list(queryWrapper);
|
||||
|
||||
List<DictTypeExcel> dictTypeVOS = new ArrayList<>();
|
||||
dictTypes.forEach(dictType -> {
|
||||
DictTypeExcel dictTypeExcel = BeanUtil.copyProperties(dictType, DictTypeExcel.class);
|
||||
List<DictData> dictDataList = dictDataService.listDictDataByTypeId(dictType.getId());
|
||||
List<DictDataExcel> dictDataExcels = BeanUtil.copyToList(dictDataList, DictDataExcel.class);
|
||||
dictTypeExcel.setDictDataExcels(dictDataExcels);
|
||||
dictTypeVOS.add(dictTypeExcel);
|
||||
});
|
||||
|
||||
ExcelUtil.exportExcel("字典类型导出数据.xlsx", "字典类型", DictTypeExcel.class, dictTypeVOS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DictType getByCode(String code) {
|
||||
return this.lambdaQuery().eq(DictType::getCode, code).eq(DictType::getState, DataStateEnum.ENABLE.getCode()).one();
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验参数,检查是否存在相同名称的字典类型
|
||||
*/
|
||||
private void checkDicTypeName(DictTypeParam dictTypeParam, boolean isExcludeSelf) {
|
||||
LambdaQueryWrapper<DictType> dictTypeLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
dictTypeLambdaQueryWrapper.eq(DictType::getState, DataStateEnum.ENABLE.getCode())
|
||||
.and(w -> w.eq(DictType::getCode, dictTypeParam.getCode()).or().eq(DictType::getName, dictTypeParam.getName()));
|
||||
//更新的时候,需排除当前记录
|
||||
if (isExcludeSelf) {
|
||||
if (dictTypeParam instanceof DictTypeParam.UpdateParam) {
|
||||
dictTypeLambdaQueryWrapper.ne(DictType::getId, ((DictTypeParam.UpdateParam) dictTypeParam).getId());
|
||||
}
|
||||
}
|
||||
int countByAccount = this.count(dictTypeLambdaQueryWrapper);
|
||||
//大于等于1个则表示重复
|
||||
if (countByAccount >= 1) {
|
||||
throw new BusinessException(SystemResponseEnum.DICT_TYPE_REPEAT);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.njcn.gather.system.log.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.njcn.common.pojo.annotation.OperateInfo;
|
||||
import com.njcn.common.pojo.constant.OperateType;
|
||||
import com.njcn.common.pojo.enums.common.LogEnum;
|
||||
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
||||
import com.njcn.common.pojo.response.HttpResult;
|
||||
import com.njcn.common.utils.LogUtil;
|
||||
import com.njcn.gather.system.log.pojo.param.SysLogParam;
|
||||
import com.njcn.gather.system.log.pojo.po.SysLogAudit;
|
||||
import com.njcn.gather.system.log.service.ISysLogAuditService;
|
||||
import com.njcn.web.controller.BaseController;
|
||||
import com.njcn.web.utils.HttpResultUtil;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
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;
|
||||
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @date 2024-11-29
|
||||
*/
|
||||
@Slf4j
|
||||
@Api(tags = "日志管理")
|
||||
@RestController
|
||||
@RequestMapping("/sysLog")
|
||||
@RequiredArgsConstructor
|
||||
public class SysLogController extends BaseController {
|
||||
private final ISysLogAuditService sysLogAuditService;
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON)
|
||||
@PostMapping("/list")
|
||||
@ApiOperation(value = "获取日志列表")
|
||||
@ApiImplicitParam(name = "param", value = "查询参数", required = true)
|
||||
public HttpResult<Page<SysLogAudit>> list(@RequestBody @Validated SysLogParam.QueryParam param) {
|
||||
String methodDescribe = getMethodDescribe("list");
|
||||
LogUtil.njcnDebug(log, "{},查询数据为:{}", methodDescribe, param);
|
||||
Page<SysLogAudit> result = sysLogAuditService.listSysLogAudit(param);
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
|
||||
}
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.DOWNLOAD)
|
||||
@PostMapping("/exportCSV")
|
||||
@ApiOperation("日志导出为csv文件")
|
||||
@ApiImplicitParam(name = "param", value = "查询参数", required = true)
|
||||
public void exportCSV(@RequestBody @Validated SysLogParam.QueryParam param) {
|
||||
String methodDescribe = getMethodDescribe("export");
|
||||
LogUtil.njcnDebug(log, "{},查询数据为:{}", methodDescribe, param);
|
||||
sysLogAuditService.exportCSV(param);
|
||||
}
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.DOWNLOAD)
|
||||
@PostMapping("/analyse")
|
||||
@ApiOperation("日志分析")
|
||||
@ApiImplicitParam(name = "param", value = "查询参数", required = true)
|
||||
public void analyse(@RequestBody @Validated SysLogParam.QueryParam param) {
|
||||
String methodDescribe = getMethodDescribe("analyze");
|
||||
LogUtil.njcnDebug(log, "{},查询数据为:{}", methodDescribe, param);
|
||||
sysLogAuditService.analyse(param);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.njcn.gather.system.log.mapper;
|
||||
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
import com.njcn.gather.system.log.pojo.po.SysLogAudit;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @date 2024-11-29
|
||||
*/
|
||||
public interface SysLogAuditMapper extends MPJBaseMapper<SysLogAudit> {
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.njcn.gather.system.log.mapper;
|
||||
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
import com.njcn.gather.system.log.pojo.po.SysLogRun;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @date 2024-11-29
|
||||
*/
|
||||
public interface SysLogRunMapper extends MPJBaseMapper<SysLogRun> {
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.njcn.gather.system.log.mapper.SysLogAuditMapper">
|
||||
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.njcn.gather.system.log.mapper.SysLogRunMapper">
|
||||
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.njcn.gather.system.log.pojo.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class SysLogAuditRecord {
|
||||
|
||||
private String userId;
|
||||
|
||||
private String loginName;
|
||||
|
||||
private String ip;
|
||||
|
||||
private String operate;
|
||||
|
||||
private String operateType;
|
||||
|
||||
private String result;
|
||||
|
||||
private String reason;
|
||||
|
||||
private Integer type;
|
||||
|
||||
private Integer level;
|
||||
|
||||
private Integer warn;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.njcn.gather.system.log.pojo.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @data 2025-02-12
|
||||
*/
|
||||
@Getter
|
||||
public enum LogLevelEnum {
|
||||
DEBUG(1, "DEBUG"),
|
||||
INFO(2, "INFO"),
|
||||
WARN(3, "WARN"),
|
||||
ERROR(4, "ERROR"),
|
||||
FATAL(5, "FATAL");
|
||||
|
||||
private final int code;
|
||||
private final String msg;
|
||||
|
||||
LogLevelEnum(int code, String msg) {
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public static LogLevelEnum getEnum(int code) {
|
||||
return LogLevelEnum.values()[code - 1];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.njcn.gather.system.log.pojo.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @data 2025-02-12
|
||||
*/
|
||||
@Getter
|
||||
public enum LogOperationTypeEnum {
|
||||
OPERATE("操作日志"),
|
||||
WARNING("告警日志");
|
||||
|
||||
private String msg;
|
||||
LogOperationTypeEnum(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.njcn.gather.system.log.pojo.param;
|
||||
|
||||
import com.njcn.common.pojo.constant.PatternRegex;
|
||||
import com.njcn.gather.system.pojo.constant.SystemValidMessage;
|
||||
import com.njcn.web.pojo.param.BaseParam;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import javax.validation.constraints.Pattern;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @data 2024-11-25
|
||||
*/
|
||||
@Data
|
||||
public class SysLogParam {
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public static class QueryParam extends BaseParam {
|
||||
|
||||
@ApiModelProperty("操作用户")
|
||||
private String userName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package com.njcn.gather.system.log.pojo.po;
|
||||
|
||||
import cn.afterturn.easypoi.excel.annotation.Excel;
|
||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @date 2024-11-29
|
||||
*/
|
||||
@Data
|
||||
@TableName("sys_log_audit")
|
||||
public class SysLogAudit implements Serializable {
|
||||
private static final long serialVersionUID = -56962081010894238L;
|
||||
/**
|
||||
* 审计日志Id
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 登录名
|
||||
*/
|
||||
@Excel(name = "登录名")
|
||||
private String loginName;
|
||||
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
@Excel(name = "用户名")
|
||||
private String userName;
|
||||
|
||||
|
||||
/**
|
||||
* IP
|
||||
*/
|
||||
@Excel(name = "IP", width = 20)
|
||||
private String ip;
|
||||
|
||||
/**
|
||||
* 操作内容
|
||||
*/
|
||||
@Excel(name = "操作内容", width = 80)
|
||||
private String operate;
|
||||
|
||||
|
||||
/**
|
||||
* 操作类型 (比如:查询、新增、删除、下载等等)
|
||||
*/
|
||||
@Excel(name = "操作类型")
|
||||
private String operateType;
|
||||
|
||||
/**
|
||||
* 事件结果 0失败 1成功
|
||||
*/
|
||||
@Excel(name = "事件结果", replace = {"失败_0", "成功_1"})
|
||||
private String result;
|
||||
|
||||
/**
|
||||
* 失败原因
|
||||
*/
|
||||
@Excel(name = "失败原因")
|
||||
private String reason;
|
||||
|
||||
/**
|
||||
* 事件类型
|
||||
*/
|
||||
@Excel(name = "事件类型", replace = {"业务事件_0", "系统事件_1"})
|
||||
private Integer type;
|
||||
|
||||
|
||||
/**
|
||||
* 事件严重度(0.普通 1.中等 2.严重)
|
||||
*/
|
||||
@Excel(name = "事件严重度", replace = {"普通_0", "中等_1", "严重_2"})
|
||||
private Integer level;
|
||||
|
||||
/**
|
||||
* 告警标志(0:未告警;1:已告警),默认未告警
|
||||
*/
|
||||
@Excel(name = "告警标志", replace = {"未告警_0", "已告警_1"})
|
||||
private Integer warn;
|
||||
|
||||
|
||||
/**
|
||||
* 日志发生时间
|
||||
*/
|
||||
@Excel(name = "日志发生时间", width = 30, exportFormat = "yyyy-MM-dd HH:mm:ss")
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
|
||||
@JsonSerialize(using = LocalDateTimeSerializer.class)
|
||||
private LocalDateTime logTime;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.njcn.gather.system.log.pojo.po;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @date 2024-11-29
|
||||
*/
|
||||
@Data
|
||||
@TableName("sys_log_run")
|
||||
public class SysLogRun implements Serializable {
|
||||
private static final long serialVersionUID = -37126398654461376L;
|
||||
/**
|
||||
* 运行日志Id
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 类型(数据源、被检设备)
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* IP
|
||||
*/
|
||||
private String ip;
|
||||
|
||||
/**
|
||||
* 事件结果
|
||||
*/
|
||||
private String result;
|
||||
|
||||
/**
|
||||
* 事件描述
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 告警标志(0:未告警;1:已告警),默认未告警
|
||||
*/
|
||||
private Integer warn;
|
||||
|
||||
/**
|
||||
* 创建用户
|
||||
*/
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.njcn.gather.system.log.pojo.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @data 2024-11-25
|
||||
*/
|
||||
@Data
|
||||
public class SysLogVO {
|
||||
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 操作类型,审计日志独有字段。
|
||||
*/
|
||||
private String operateType;
|
||||
|
||||
/**
|
||||
* 类型(数据源、被检设备),运行日志独有字段。
|
||||
*/
|
||||
private String type;
|
||||
|
||||
private String ip;
|
||||
|
||||
private String result;
|
||||
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 事件严重度(0.普通 1.中等 2.严重),审计日志独有字段。
|
||||
*/
|
||||
private Integer level;
|
||||
|
||||
private Integer warn;
|
||||
|
||||
private String createBy;
|
||||
|
||||
private LocalDateTime createTime;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.njcn.gather.system.log.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.njcn.gather.system.log.pojo.dto.SysLogAuditRecord;
|
||||
import com.njcn.gather.system.log.pojo.param.SysLogParam;
|
||||
import com.njcn.gather.system.log.pojo.po.SysLogAudit;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @date 2024-11-29
|
||||
*/
|
||||
public interface ISysLogAuditService extends IService<SysLogAudit> {
|
||||
|
||||
/**
|
||||
* 分页查询审计日志
|
||||
*
|
||||
* @param param 查询参数
|
||||
* @return 分页结果
|
||||
*/
|
||||
Page<SysLogAudit> listSysLogAudit(SysLogParam.QueryParam param);
|
||||
|
||||
/**
|
||||
* 导出审计日志数据
|
||||
*
|
||||
* @param param 查询参数
|
||||
*/
|
||||
void exportCSV(SysLogParam.QueryParam param);
|
||||
|
||||
/**
|
||||
* 分析日志
|
||||
*
|
||||
* @param param 查询参数
|
||||
*/
|
||||
void analyse(SysLogParam.QueryParam param);
|
||||
|
||||
void recodeAdviceLog(SysLogAuditRecord logRecord);
|
||||
|
||||
/**
|
||||
* 全局异常拦截器捕获异常后的日志记录入库
|
||||
*
|
||||
* @param logRecord 日志记录
|
||||
*/
|
||||
void recodeBusinessExceptionLog(SysLogAuditRecord logRecord);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.njcn.gather.system.log.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.njcn.gather.system.log.pojo.po.SysLogRun;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @date 2024-11-29
|
||||
*/
|
||||
public interface ISysLogRunService extends IService<SysLogRun> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
package com.njcn.gather.system.log.service.impl;
|
||||
|
||||
import cn.afterturn.easypoi.csv.entity.CsvExportParams;
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.njcn.common.pojo.constant.LogInfo;
|
||||
import com.njcn.db.mybatisplus.constant.UserConstant;
|
||||
import com.njcn.gather.system.log.mapper.SysLogAuditMapper;
|
||||
import com.njcn.gather.system.log.pojo.dto.SysLogAuditRecord;
|
||||
import com.njcn.gather.system.log.pojo.param.SysLogParam;
|
||||
import com.njcn.gather.system.log.pojo.po.SysLogAudit;
|
||||
import com.njcn.gather.system.log.service.ISysLogAuditService;
|
||||
import com.njcn.gather.system.log.util.CSVUtil;
|
||||
import com.njcn.gather.user.user.pojo.po.SysUser;
|
||||
import com.njcn.gather.user.user.service.ISysUserService;
|
||||
import com.njcn.web.factory.PageFactory;
|
||||
import com.njcn.web.utils.HttpServletUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @date 2024-11-29
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SysLogAuditServiceImpl extends ServiceImpl<SysLogAuditMapper, SysLogAudit> implements ISysLogAuditService {
|
||||
|
||||
private final ISysUserService sysUserService;
|
||||
|
||||
@Override
|
||||
public Page<SysLogAudit> listSysLogAudit(SysLogParam.QueryParam param) {
|
||||
QueryWrapper<SysLogAudit> queryWrapper = new QueryWrapper<>();
|
||||
if (ObjectUtil.isNotNull(param)) {
|
||||
queryWrapper.like(StrUtil.isNotBlank(param.getUserName()), "sys_log_audit.User_name", param.getUserName())
|
||||
.ge(StrUtil.isNotBlank(param.getSearchBeginTime()), "sys_log_audit.Log_time", LocalDateTimeUtil.parse(param.getSearchBeginTime() + " 00:00:00", DatePattern.NORM_DATETIME_FORMATTER))
|
||||
.le(StrUtil.isNotBlank(param.getSearchEndTime()), "sys_log_audit.Log_time", LocalDateTimeUtil.parse(param.getSearchEndTime() + " 23:59:59", DatePattern.NORM_DATETIME_FORMATTER));
|
||||
}
|
||||
queryWrapper.orderByDesc("sys_log_audit.Log_time");
|
||||
return this.page(new Page<>(PageFactory.getPageNum(param), PageFactory.getPageSize(param)), queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportCSV(SysLogParam.QueryParam param) {
|
||||
QueryWrapper<SysLogAudit> queryWrapper = new QueryWrapper<>();
|
||||
if (ObjectUtil.isNotNull(param)) {
|
||||
queryWrapper.like(StrUtil.isNotBlank(param.getUserName()), "sys_log_audit.User_name", param.getUserName())
|
||||
.ge(StrUtil.isNotBlank(param.getSearchBeginTime()), "sys_log_audit.Log_time", LocalDateTimeUtil.parse(param.getSearchBeginTime() + " 00:00:00", DatePattern.NORM_DATETIME_FORMATTER))
|
||||
.le(StrUtil.isNotBlank(param.getSearchEndTime()), "sys_log_audit.Log_time", LocalDateTimeUtil.parse(param.getSearchEndTime() + " 23:59:59", DatePattern.NORM_DATETIME_FORMATTER));
|
||||
}
|
||||
queryWrapper.orderByDesc("sys_log_audit.Log_time");
|
||||
List<SysLogAudit> list = this.list(queryWrapper);
|
||||
CsvExportParams params = new CsvExportParams();
|
||||
CSVUtil.exportCsv("日志数据.csv", params, SysLogAudit.class, list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂时废弃,有需要再重新写
|
||||
*
|
||||
* @param param .
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public void analyse(SysLogParam.QueryParam param) {
|
||||
QueryWrapper<SysLogAudit> queryWrapper = new QueryWrapper<>();
|
||||
if (ObjectUtil.isNotNull(param)) {
|
||||
queryWrapper.like(StrUtil.isNotBlank(param.getUserName()), "sys_log_audit.User_name", param.getUserName())
|
||||
.between(StrUtil.isAllNotBlank(param.getSearchBeginTime(), param.getSearchEndTime()), "sys_log_audit.Log_time", param.getSearchBeginTime(), param.getSearchEndTime());
|
||||
}
|
||||
List<SysLogAudit> list = this.list(queryWrapper);
|
||||
Map<String, Long> collect = list.stream().collect(Collectors.groupingBy(SysLogAudit::getLoginName, Collectors.counting()));
|
||||
|
||||
this.exportAnalyseExcel("分析结果", collect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recodeAdviceLog(SysLogAuditRecord logRecord) {
|
||||
saveAuditLog(logRecord);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recodeBusinessExceptionLog(SysLogAuditRecord logRecord) {
|
||||
saveAuditLog(logRecord);
|
||||
}
|
||||
|
||||
private void saveAuditLog(SysLogAuditRecord logRecord) {
|
||||
if (ObjectUtil.isNull(logRecord)) {
|
||||
return;
|
||||
}
|
||||
SysLogAudit sysLogAudit = new SysLogAudit();
|
||||
fillOperator(sysLogAudit, logRecord);
|
||||
sysLogAudit.setIp(logRecord.getIp());
|
||||
sysLogAudit.setOperate(logRecord.getOperate());
|
||||
sysLogAudit.setOperateType(logRecord.getOperateType());
|
||||
sysLogAudit.setResult(logRecord.getResult());
|
||||
sysLogAudit.setReason(logRecord.getReason());
|
||||
sysLogAudit.setType(logRecord.getType() == null ? 1 : logRecord.getType());
|
||||
Integer level = logRecord.getLevel() == null ? 0 : logRecord.getLevel();
|
||||
sysLogAudit.setLevel(level);
|
||||
Integer warn = logRecord.getWarn() == null ? (level == 1 ? 1 : 0) : logRecord.getWarn();
|
||||
sysLogAudit.setWarn(warn);
|
||||
sysLogAudit.setLogTime(LocalDateTime.now());
|
||||
this.save(sysLogAudit);
|
||||
}
|
||||
|
||||
private void fillOperator(SysLogAudit sysLogAudit, SysLogAuditRecord logRecord) {
|
||||
String userId = logRecord.getUserId();
|
||||
String loginName = logRecord.getLoginName();
|
||||
|
||||
if (StrUtil.isNotBlank(userId)) {
|
||||
SysUser sysUser = sysUserService.getById(userId);
|
||||
if (sysUser != null) {
|
||||
sysLogAudit.setUserName(sysUser.getName());
|
||||
sysLogAudit.setLoginName(sysUser.getLoginName());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (StrUtil.isNotBlank(loginName) && !LogInfo.UNKNOWN_USER.equalsIgnoreCase(loginName)) {
|
||||
sysLogAudit.setUserName(loginName);
|
||||
sysLogAudit.setLoginName(loginName);
|
||||
} else {
|
||||
sysLogAudit.setUserName(UserConstant.UN_LOGIN);
|
||||
sysLogAudit.setLoginName(UserConstant.UN_LOGIN);
|
||||
}
|
||||
}
|
||||
|
||||
private void exportAnalyseExcel(String fileName, Map<String, Long> collect) {
|
||||
HttpServletResponse response = HttpServletUtil.getResponse();
|
||||
XSSFWorkbook wb = new XSSFWorkbook();
|
||||
|
||||
try (ServletOutputStream outputStream = response.getOutputStream()) {
|
||||
fileName = URLEncoder.encode(fileName, CharsetUtil.UTF_8);
|
||||
response.reset();
|
||||
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
|
||||
response.setContentType("application/octet-stream;charset=UTF-8");
|
||||
|
||||
XSSFSheet sheet = wb.createSheet("sheet1");
|
||||
|
||||
//createPieChart(sheet, collect.keySet().stream().collect(Collectors.toList()), collect.values().stream().collect(Collectors.toList()));
|
||||
|
||||
wb.write(outputStream);
|
||||
wb.close();
|
||||
} catch (IOException e) {
|
||||
log.error(">>> 导出数据异常:{}", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.njcn.gather.system.log.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.njcn.gather.system.log.pojo.po.SysLogRun;
|
||||
import com.njcn.gather.system.log.mapper.SysLogRunMapper;
|
||||
import com.njcn.gather.system.log.service.ISysLogRunService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @date 2024-11-29
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SysLogRunServiceImpl extends ServiceImpl<SysLogRunMapper, SysLogRun> implements ISysLogRunService {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
package com.njcn.gather.system.log.util;
|
||||
|
||||
|
||||
import cn.afterturn.easypoi.csv.CsvExportUtil;
|
||||
import cn.afterturn.easypoi.csv.entity.CsvExportParams;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
import com.njcn.web.utils.HttpServletUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @data 2024-12-2
|
||||
*/
|
||||
@Slf4j
|
||||
public class CSVUtil {
|
||||
|
||||
/**
|
||||
* CSV文件列分隔符
|
||||
*/
|
||||
private static final String CSV_COLUMN_SEPARATOR = ",";
|
||||
|
||||
/**
|
||||
* CSV文件行分隔符
|
||||
*/
|
||||
private static final String CSV_ROW_SEPARATOR = System.lineSeparator();
|
||||
|
||||
/**
|
||||
* 导出CSV文件
|
||||
*
|
||||
* @param fileName 文件名
|
||||
* @param titles 表头
|
||||
* @param keys 字段名
|
||||
* @param dataList 数据集
|
||||
*/
|
||||
public static void export(String fileName, String[] titles, String[] keys, List<Map<String, Object>> dataList) {
|
||||
// 保证线程安全
|
||||
StringBuffer buf = new StringBuffer();
|
||||
|
||||
// 组装表头
|
||||
for (String title : titles) {
|
||||
buf.append(title).append(CSV_COLUMN_SEPARATOR);
|
||||
}
|
||||
buf.append(CSV_ROW_SEPARATOR);
|
||||
// 组装数据
|
||||
if (CollectionUtils.isNotEmpty(dataList)) {
|
||||
for (Map<String, Object> map : dataList) {
|
||||
for (String key : keys) {
|
||||
if (ObjectUtil.isEmpty(map.get(key))) {
|
||||
buf.append("").append(CSV_COLUMN_SEPARATOR);
|
||||
} else {
|
||||
// 如果数据内容中包含逗号,则进行使用!替换
|
||||
buf.append(map.get(key).toString().replaceAll(",", "!")).append(CSV_COLUMN_SEPARATOR);
|
||||
}
|
||||
}
|
||||
buf.deleteCharAt(buf.length() - 1).append(CSV_ROW_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
HttpServletResponse response = HttpServletUtil.getResponse();
|
||||
|
||||
try {
|
||||
ServletOutputStream os = response.getOutputStream();
|
||||
Throwable var1 = null;
|
||||
|
||||
try {
|
||||
fileName = URLEncoder.encode(fileName, "UTF-8");
|
||||
response.reset();
|
||||
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
|
||||
response.setContentType("application/octet-stream;charset=UTF-8");
|
||||
// 写出响应
|
||||
os.write(buf.toString().getBytes("UTF-8"));
|
||||
os.flush();
|
||||
} catch (Throwable var2) {
|
||||
var1 = var2;
|
||||
throw var2;
|
||||
} finally {
|
||||
if (os != null) {
|
||||
if (var1 != null) {
|
||||
try {
|
||||
os.close();
|
||||
} catch (Throwable var3) {
|
||||
var1.addSuppressed(var3);
|
||||
}
|
||||
} else {
|
||||
os.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException var4) {
|
||||
IOException e = var4;
|
||||
log.error(">>> 导出数据异常:{}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void exportCsv(String fileName, CsvExportParams params, Class<?> pojoClass, Collection<?> dataSet) {
|
||||
HttpServletResponse response = HttpServletUtil.getResponse();
|
||||
ServletOutputStream os = null;
|
||||
try {
|
||||
os = response.getOutputStream();
|
||||
fileName = URLEncoder.encode(fileName, "UTF-8");
|
||||
response.reset();
|
||||
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
|
||||
response.setContentType("application/octet-stream;charset=UTF-8");
|
||||
|
||||
CsvExportUtil.exportCsv(params, pojoClass, dataSet, os);
|
||||
os.flush();
|
||||
os.close();
|
||||
} catch (Exception e) {
|
||||
log.error(">>> 导出数据异常:{}", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.njcn.gather.system.pojo.constant;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @data 2024/11/8
|
||||
*/
|
||||
public interface DictConst {
|
||||
/**
|
||||
* 状态 0-正常;1-停用;2-删除 默认正常
|
||||
*/
|
||||
int ENABLE = 0;
|
||||
|
||||
int PAUSE = 1;
|
||||
|
||||
int DELETE = 2;
|
||||
|
||||
/**
|
||||
* 顶层父类的pid
|
||||
*/
|
||||
String FATHER_ID = "0";
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.njcn.gather.system.pojo.constant;
|
||||
|
||||
/**
|
||||
* @author hongawen
|
||||
* @version 1.0
|
||||
* @data 2024/10/30 14:46
|
||||
*/
|
||||
public interface SystemValidMessage {
|
||||
|
||||
|
||||
String MISS_PREFIX = "字段不能为空,请检查";
|
||||
|
||||
|
||||
String ID_NOT_BLANK = "id不能为空,请检查id参数";
|
||||
|
||||
String ID_FORMAT_ERROR = "id格式错误,请检查id参数";
|
||||
|
||||
String DICT_TYPE_ID_NOT_BLANK = "typeId不能为空,请检查typeId参数";
|
||||
|
||||
String DICT_TYPE_ID_FORMAT_ERROR = "typeId格式错误,请检查typeId参数";
|
||||
|
||||
String NAME_NOT_BLANK = "名称不能为空,请检查name参数";
|
||||
|
||||
String DICT_TYPE_NAME_FORMAT_ERROR = "名称格式错误,只能包含字母、数字、中文、下划线、中划线、空格,长度为1~32个字符";
|
||||
String DICT_TYPE_CODE_FORMAT_ERROR = "编码格式错误,只能包含字母、数字、下划线,长度为1~30个字符";
|
||||
|
||||
String INDUSTRY_NOT_BLANK = "行业不能为空,请检查industry参数";
|
||||
String INDUSTRY_FORMAT_ERROR = "行业格式错误,请检查industry参数";
|
||||
String ADDR_NOT_BLANK = "所属区域不能为空,请检查addr参数";
|
||||
|
||||
String CODE_NOT_BLANK = "编码不能为空,请检查code参数";
|
||||
|
||||
String SORT_NOT_NULL = "排序不能为空,请检查sort参数";
|
||||
|
||||
String SORT_FORMAT_ERROR = "排序范围在1至999,请检查sort参数";
|
||||
|
||||
String OPEN_LEVEL_NOT_NULL = "开启等级不能为空,请检查openLevel参数";
|
||||
|
||||
String OPEN_LEVEL_FORMAT_ERROR = "开启等级格式错误,请检查openLevel参数";
|
||||
|
||||
String OPEN_DESCRIBE_NOT_NULL = "开启描述不能为空,请检查openDescribe参数";
|
||||
|
||||
String OPEN_DESCRIBE_FORMAT_ERROR = "开启描述格式错误,请检查openDescribe参数";
|
||||
|
||||
String AREA_NOT_BLANK = "行政区域不能为空,请检查area参数";
|
||||
|
||||
String AREA_FORMAT_ERROR = "行政区域格式错误,请检查area参数";
|
||||
|
||||
String PID_NOT_BLANK = "父节点不能为空,请检查pid参数";
|
||||
|
||||
String PID_FORMAT_ERROR = "父节点格式错误,请检查pid参数";
|
||||
|
||||
String COLOR_NOT_BLANK = "主题色不能为空,请检查color参数";
|
||||
|
||||
String COLOR_FORMAT_ERROR = "主题色格式错误,请检查color参数";
|
||||
|
||||
String LOGO_NOT_BLANK = "iconUrl不能为空,请检查iconUrl参数";
|
||||
|
||||
String FAVICON_NOT_BLANK = "faviconUrl不能为空,请检查faviconUrl参数";
|
||||
|
||||
String REMARK_NOT_BLANK = "描述不能为空,请检查remark参数";
|
||||
|
||||
String REMARK_FORMAT_ERROR = "描述格式错误,请检查remark参数";
|
||||
|
||||
String PARAM_FORMAT_ERROR = "参数值非法";
|
||||
|
||||
String IP_FORMAT_ERROR = "IP格式非法";
|
||||
|
||||
String DEVICE_VERSION_NOT_BLANK = "装置版本json文件不能为空,请检查deviceVersionFile参数";
|
||||
|
||||
String PHASE_NOT_BLANK = "相别不能为空,请检查phase参数";
|
||||
|
||||
String DATA_TYPE_NOT_BLANK = "数据模型不能为空,请检查dataType参数";
|
||||
|
||||
String CLASS_ID_NOT_BLANK = "数据表表名不能为空,请检查classId参数";
|
||||
|
||||
String AUTO_GENERATE_NOT_NULL = "是否自动生成不能为空,请检查autoGenerate参数";
|
||||
|
||||
String MAX_RECHECK_NOT_NULL = "最大检测次数不能为空,请检查maxRecheck参数";
|
||||
|
||||
String DATA_RULE_NOT_BLANK = "数据处理规则不能为空,请检查dataRule参数";
|
||||
|
||||
String DATA_RULE_FORMAT_ERROR = "数据处理规则格式错误,请检查dataRule参数";
|
||||
|
||||
String TYPE_NOT_BLANK = "版本类型不能为空,请检查type参数";
|
||||
|
||||
String AUTO_GENERATE_FORMAT_ERROR = "是否自动生成格式错误,请检查autoGenerate参数";
|
||||
|
||||
String USER_ID_FORMAT_ERROR = "用户id格式错误,请检查userId参数";
|
||||
String DICT_DATA_NAME_FORMAT_ERROR = "字典数据名称格式错误,只能包含字母、数字、中文、下划线、中划线、空格、点、斜线、反斜线、百分号、摄氏度符号,长度为1~32个字符";
|
||||
String DICT_DATA_CODE_FORMAT_ERROR = "字典数据编码格式错误,只能包含字母、数字、中文、下划线、中划线、空格、点、斜线、反斜线、百分号、摄氏度符号,长度为1~30个字符";
|
||||
String DICT_PQ_OTHER_NAME_FORMAT_ERROR = "别名格式错误,只能包含字母、数字、中文、下划线、中划线、空格,长度最大为32个字符";
|
||||
String DICT_PQ_SHOW_NAME_FORMAT_ERROR = "显示名称格式错误,只能包含字母、数字、中文、下划线、中划线、空格,长度最大为32个字符";
|
||||
String SCALE_NOT_NULL = "数据精度不能为空,请检查scale参数";
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.njcn.gather.system.pojo.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author cdf
|
||||
* @version 1.0.0
|
||||
*/
|
||||
@Getter
|
||||
public enum DicDataEnum {
|
||||
|
||||
|
||||
FREQ("FREQ","频率"),
|
||||
V("V","电压"),
|
||||
I("I","电流"),
|
||||
IMBV("IMBV","三相电压不平衡度"),
|
||||
IMBA("IMBA","三相电流不平衡度"),
|
||||
|
||||
HV("HV","谐波电压"),
|
||||
HI("HI","谐波电流"),
|
||||
HP("HP","谐波有功功率"),
|
||||
HSV("HSV","间谐波电压"),
|
||||
HSI("HSI","间谐波电流"),
|
||||
VOLTAGE("VOLTAGE","暂态"),
|
||||
F("F","闪变"),
|
||||
|
||||
|
||||
|
||||
;
|
||||
|
||||
|
||||
private final String code;
|
||||
|
||||
private final String message;
|
||||
|
||||
DicDataEnum(String code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public static DicDataEnum getEnumByCode(String code) {
|
||||
for (DicDataEnum e : DicDataEnum.values()) {
|
||||
if (e.getCode().equals(code)) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getMessageByCode(String code) {
|
||||
DicDataEnum e = getEnumByCode(code);
|
||||
if (e!= null) {
|
||||
return e.getMessage();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.njcn.gather.system.pojo.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author hongawen
|
||||
* @version 1.0.0
|
||||
* @date 2021年12月20日 09:56
|
||||
*/
|
||||
@Getter
|
||||
public enum SystemResponseEnum {
|
||||
|
||||
/**
|
||||
* 系统模块异常响应码的范围:
|
||||
* A01000 ~ A01
|
||||
*/
|
||||
DICT_TYPE_REPEAT("A01000", "字典类型名称或编码重复"),
|
||||
DICT_DATA_REPEAT("A01002", "字典数据名称或编码重复"),
|
||||
DICT_PQ_NAME_EXIST("A01003", "当前数据模型及相别下已存在相同名称"),
|
||||
EXISTS_CHILDREN_NOT_DELETE("A01004", "当前字典下存在子字典,不能删除"),
|
||||
CODE_REPEAT("A01005", "该层级下已存在相同的编码"),
|
||||
CAN_NOT_DELETE_USED_DICT("A01006", "该字典在使用中,不能删除"),
|
||||
CAN_NOT_UPDATE_USED_DICT("A01007", "该字典在使用中,不能修改"),
|
||||
LOG_RECORD_FAILED("A01008", "日志记录失败"),
|
||||
|
||||
|
||||
GET_MAC_ADDRESS_FAILED("A01040", "获取本机MAC地址失败"),
|
||||
REGISTRATION_CODE_FORMAT_ERROR("A01041", "注册码格式错误"),
|
||||
MAC_ADDRESS_NOT_MATCH("A01042","注册码中的MAC地址与本机MAC地址不匹配"),
|
||||
REGISTRATION_CODE_EXPIRED("A01043","注册码已过期"),
|
||||
FILE_NOT_FOUND("A01050", "模板文件不存在"),
|
||||
FILE_IO_ERROR("A01051", "文件读写异常"),;
|
||||
|
||||
private final String code;
|
||||
|
||||
private final String message;
|
||||
|
||||
SystemResponseEnum(String code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package com.njcn.gather.system.reg.controller;
|
||||
|
||||
import com.njcn.common.pojo.annotation.OperateInfo;
|
||||
import com.njcn.common.pojo.constant.OperateType;
|
||||
import com.njcn.common.pojo.enums.common.LogEnum;
|
||||
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
||||
import com.njcn.common.pojo.response.HttpResult;
|
||||
import com.njcn.common.utils.LogUtil;
|
||||
import com.njcn.gather.system.reg.pojo.param.SysRegResParam;
|
||||
import com.njcn.gather.system.reg.pojo.po.SysRegRes;
|
||||
import com.njcn.gather.system.reg.pojo.vo.SysRegResVO;
|
||||
import com.njcn.gather.system.reg.service.ISysRegResService;
|
||||
import com.njcn.web.controller.BaseController;
|
||||
import com.njcn.web.utils.HttpResultUtil;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @date 2024-11-21
|
||||
*/
|
||||
@Slf4j
|
||||
@Api(tags = "注册版本管理")
|
||||
@RestController
|
||||
@RequestMapping("/sysRegRes")
|
||||
@RequiredArgsConstructor
|
||||
public class SysRegResController extends BaseController {
|
||||
private final ISysRegResService sysRegResService;
|
||||
|
||||
// @OperateInfo(info = LogEnum.SYSTEM_COMMON)
|
||||
// @GetMapping("/list")
|
||||
// @ApiOperation("查询注册版本列表")
|
||||
// public HttpResult<SysRegResVO> listRegRes() {
|
||||
// String methodDescribe = getMethodDescribe("listRegRes");
|
||||
// LogUtil.njcnDebug(log, "{},查询参数为空", methodDescribe);
|
||||
// SysRegResVO result = sysRegResService.listRegRes();
|
||||
// return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
|
||||
// }
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON)
|
||||
@GetMapping("/getRegResByType")
|
||||
@ApiOperation("根据类型id查询配置")
|
||||
@ApiImplicitParam(name = "typeId", value = "类型id,字典值", required = true)
|
||||
public HttpResult<SysRegRes> getRegResByType(@RequestParam("typeId") String typeId) {
|
||||
String methodDescribe = getMethodDescribe("listByTypeId");
|
||||
LogUtil.njcnDebug(log, "{},查询参数为:{}", methodDescribe, typeId);
|
||||
SysRegRes result = sysRegResService.getRegResByType(typeId);
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
|
||||
}
|
||||
|
||||
// @OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.ADD)
|
||||
// @PostMapping("/add")
|
||||
// @ApiOperation("新增注册版本")
|
||||
// @ApiImplicitParam(name = "sysRegRes", value = "注册版本对象", required = true)
|
||||
// public HttpResult<Boolean> addRegRes(@RequestBody @Validated SysRegResParam param) {
|
||||
// String methodDescribe = getMethodDescribe("addRegRes");
|
||||
// LogUtil.njcnDebug(log, "{},新增参数为:{}", methodDescribe, param);
|
||||
// boolean result = sysRegResService.addRegRes(param);
|
||||
// if (result) {
|
||||
// return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, true, methodDescribe);
|
||||
// } else {
|
||||
// return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, false, methodDescribe);
|
||||
// }
|
||||
// }
|
||||
|
||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.UPDATE)
|
||||
@PostMapping("/update")
|
||||
@ApiOperation("修改配置")
|
||||
@ApiImplicitParam(name = "param", value = "注册版本更新对象", required = true)
|
||||
public HttpResult<Boolean> updateRegRes(@RequestBody @Validated SysRegResParam.UpdateParam param) {
|
||||
String methodDescribe = getMethodDescribe("updateRegRes");
|
||||
LogUtil.njcnDebug(log, "{},更新参数为:{}", methodDescribe, param);
|
||||
boolean result = sysRegResService.updateRegRes(param);
|
||||
if (result) {
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, true, methodDescribe);
|
||||
} else {
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, false, methodDescribe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.njcn.gather.system.reg.mapper;
|
||||
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
import com.njcn.gather.system.reg.pojo.po.SysRegRes;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @date 2024-11-21
|
||||
*/
|
||||
public interface SysRegResMapper extends MPJBaseMapper<SysRegRes> {
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.njcn.gather.system.reg.mapper.SysRegResMapper">
|
||||
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.njcn.gather.system.reg.pojo;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @data 2025-02-11
|
||||
*/
|
||||
public interface RegResValidMessage {
|
||||
String CODE_NOT_BLANK="注册码不能为空";
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.njcn.gather.system.reg.pojo.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @data 2025-02-11
|
||||
*/
|
||||
@Data
|
||||
public class RegInfoData {
|
||||
/**
|
||||
* mac地址
|
||||
*/
|
||||
private String macAddress;
|
||||
|
||||
/**
|
||||
* 注册模式
|
||||
*/
|
||||
private List<String> typeList;
|
||||
|
||||
/**
|
||||
* 到期日期
|
||||
*/
|
||||
private List<String> expireDateList;
|
||||
|
||||
/**
|
||||
* 使用场景
|
||||
*/
|
||||
private String scene;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.njcn.gather.system.reg.pojo.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @data 2025-03-13
|
||||
*/
|
||||
@Getter
|
||||
public enum RegStatusEnum {
|
||||
UNREGISTERED(0, "未激活"),
|
||||
REGISTERED(1, "已激活"),
|
||||
EXPIRED(2, "已过期");
|
||||
|
||||
private int code;
|
||||
private String message;
|
||||
RegStatusEnum(int code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.njcn.gather.system.reg.pojo.param;
|
||||
|
||||
import com.njcn.common.pojo.constant.PatternRegex;
|
||||
import com.njcn.gather.system.pojo.constant.SystemValidMessage;
|
||||
import com.njcn.gather.system.reg.pojo.RegResValidMessage;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Pattern;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @data 2024-11-21
|
||||
*/
|
||||
@Data
|
||||
public class SysRegResParam {
|
||||
|
||||
// @ApiModelProperty("版本类型")
|
||||
// @NotBlank(message = SystemValidMessage.TYPE_NOT_BLANK)
|
||||
// @Pattern(regexp = PatternRegex.SYSTEM_ID, message = SystemValidMessage.ID_FORMAT_ERROR)
|
||||
// private String type;
|
||||
|
||||
@ApiModelProperty("注册码")
|
||||
@NotBlank(message = RegResValidMessage.CODE_NOT_BLANK)
|
||||
private String code;
|
||||
|
||||
// @ApiModelProperty("密钥")
|
||||
// private String licenseKey;
|
||||
|
||||
@Data
|
||||
public static class UpdateParam {
|
||||
|
||||
@ApiModelProperty("id")
|
||||
@NotBlank(message = SystemValidMessage.ID_NOT_BLANK)
|
||||
@Pattern(regexp = PatternRegex.SYSTEM_ID, message = SystemValidMessage.ID_FORMAT_ERROR)
|
||||
private String id;
|
||||
|
||||
@ApiModelProperty("录波数据有效组数")
|
||||
private Integer waveRecord;
|
||||
|
||||
@ApiModelProperty("实时数据有效组数")
|
||||
private Integer realTime;
|
||||
|
||||
@ApiModelProperty("统计数据有效组数")
|
||||
private Integer statistics;
|
||||
|
||||
@ApiModelProperty("短闪数据有效组数")
|
||||
private Integer flicker;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.njcn.gather.system.reg.pojo.po;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.njcn.db.mybatisplus.bo.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @date 2024-11-21
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("sys_reg_res")
|
||||
public class SysRegRes extends BaseEntity implements Serializable {
|
||||
private static final long serialVersionUID = 801772692898301698L;
|
||||
/**
|
||||
* 版本注册表Id
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 版本类型(模拟式、数字式、比对式)
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 注册码
|
||||
*/
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 密钥
|
||||
*/
|
||||
private String licenseKey;
|
||||
|
||||
/**
|
||||
* 到期时间
|
||||
*/
|
||||
// private LocalDate expireDate;
|
||||
private String expireDate;
|
||||
|
||||
/**
|
||||
* 录波数据有效组数
|
||||
*/
|
||||
private Integer waveRecord;
|
||||
|
||||
/**
|
||||
* 实时数据有效组数
|
||||
*/
|
||||
private Integer realTime;
|
||||
|
||||
/**
|
||||
* 统计数据有效组数
|
||||
*/
|
||||
private Integer statistics;
|
||||
|
||||
/**
|
||||
* 短闪数据有效组数
|
||||
*/
|
||||
private Integer flicker;
|
||||
|
||||
/**
|
||||
* 状态:0-删除 1-正常
|
||||
*/
|
||||
private Integer state;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.njcn.gather.system.reg.pojo.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @data 2024-11-25
|
||||
*/
|
||||
@Data
|
||||
public class SysRegResVO {
|
||||
/**
|
||||
* 注册码。如果未激活,则为null
|
||||
*/
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 模拟式激活状态。0:未激活;1:已激活;2:已过期
|
||||
*/
|
||||
private int simulateStatus;
|
||||
|
||||
/**
|
||||
* 模拟式激活到期日期。如果未激活,则为null
|
||||
*/
|
||||
private String simulateExpireDate;
|
||||
|
||||
/**
|
||||
* 数字式激活状态。0:未激活;1:已激活;2:已过期
|
||||
*/
|
||||
private int digitalStatus;
|
||||
|
||||
/**
|
||||
* 数字式激活到期日期。如果未激活,则为null
|
||||
*/
|
||||
private String digitalExpireDate;
|
||||
|
||||
/**
|
||||
* 比对式激活状态。0:未激活;1:已激活;2:已过期
|
||||
*/
|
||||
private int contrastStatus;
|
||||
|
||||
/**
|
||||
* 比对式激活到期日期。如果未激活,则为null
|
||||
*/
|
||||
private String contrastExpireDate;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.njcn.gather.system.reg.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.njcn.gather.system.reg.pojo.param.SysRegResParam;
|
||||
import com.njcn.gather.system.reg.pojo.po.SysRegRes;
|
||||
import com.njcn.gather.system.reg.pojo.vo.SysRegResVO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @date 2024-11-21
|
||||
*/
|
||||
public interface ISysRegResService extends IService<SysRegRes> {
|
||||
/**
|
||||
* 查询版本注册信息
|
||||
* @return
|
||||
*/
|
||||
SysRegRes getRegResByType(String type);
|
||||
|
||||
/**
|
||||
* 新增版本注册表
|
||||
* @param sysRegResParam 版本注册表参数
|
||||
* @return 成功返回true,失败返回false
|
||||
*/
|
||||
boolean addRegRes(SysRegResParam sysRegResParam);
|
||||
|
||||
/**
|
||||
* 修改配置
|
||||
* @param param
|
||||
* @return 成功返回true,失败返回false
|
||||
*/
|
||||
boolean updateRegRes(SysRegResParam.UpdateParam param);
|
||||
|
||||
/**
|
||||
* 查询版本注册表列表
|
||||
* @return 版本注册信息
|
||||
*/
|
||||
SysRegResVO listRegRes();
|
||||
|
||||
/**
|
||||
* 获取比对式的注册信息
|
||||
* @return
|
||||
*/
|
||||
SysRegRes getContrastRegRes();
|
||||
}
|
||||
@@ -0,0 +1,326 @@
|
||||
package com.njcn.gather.system.reg.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.net.NetUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.njcn.common.pojo.enums.common.DataStateEnum;
|
||||
import com.njcn.common.pojo.exception.BusinessException;
|
||||
import com.njcn.common.utils.EncryptionUtil;
|
||||
import com.njcn.gather.system.cfg.service.ISysTestConfigService;
|
||||
import com.njcn.gather.system.dictionary.pojo.enums.DictDataEnum;
|
||||
import com.njcn.gather.system.dictionary.pojo.po.DictData;
|
||||
import com.njcn.gather.system.dictionary.service.IDictDataService;
|
||||
import com.njcn.gather.system.pojo.enums.SystemResponseEnum;
|
||||
import com.njcn.gather.system.reg.mapper.SysRegResMapper;
|
||||
import com.njcn.gather.system.reg.pojo.dto.RegInfoData;
|
||||
import com.njcn.gather.system.reg.pojo.enums.RegStatusEnum;
|
||||
import com.njcn.gather.system.reg.pojo.param.SysRegResParam;
|
||||
import com.njcn.gather.system.reg.pojo.po.SysRegRes;
|
||||
import com.njcn.gather.system.reg.pojo.vo.SysRegResVO;
|
||||
import com.njcn.gather.system.reg.service.ISysRegResService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.Key;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author caozehui
|
||||
* @date 2024-11-21
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SysRegResServiceImpl extends ServiceImpl<SysRegResMapper, SysRegRes> implements ISysRegResService {
|
||||
|
||||
private final ISysTestConfigService sysTestConfigService;
|
||||
|
||||
/**
|
||||
* 固定私钥
|
||||
*/
|
||||
private static final String fixedPrivateKeyStr = "-----BEGIN PRIVATE KEY-----\n" +
|
||||
"MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDTC6MQkjHAIyPQ\n" +
|
||||
"12tfSBsmS12OspsmJORW2cf7s+xwe3lJ3nb9KohjAuRBG4jLceAXdZoCuk1+Xt8l\n" +
|
||||
"kesXp930DWmb7SBHLa7imGgvIm/9hP7Y48yDJqM2Ia6CFbMCmLYCiU3oDLZ2DuUq\n" +
|
||||
"QbE2j9QuTTMiOVHBy4M82XwkEXNfIQez9PB+Osex2X9FesyMoWvsoOcnDD8iWmbP\n" +
|
||||
"Ag0syuutt4YkrU8IWC5v2vyTxb+N+F36wqbC8td1wOgUrf2K3kQtTe7xB1b3i5RI\n" +
|
||||
"DAsjxPd1a3uzJVjJ7Onla+B4dkFGOSlX/w8/GJQzMgegskKEPRONyXRWCaVpBt9O\n" +
|
||||
"6yDjKz7vAgMBAAECggEATnj+vowlnJRUXnSjM5AbrD8MwCEQSHwiPVsIHcLWkTKQ\n" +
|
||||
"NFPYeaVFhk9OcRkcYc1rbj2nsQj2BJ2hKpaZzDd6c6NDGBvxSxYk95OE9bW/34wC\n" +
|
||||
"uMHnSwLkYB3hBfSslbQTxVipk7WaaMZ8FpzLmIaddkP1Ve3rRPx3xXn2y3CDriRs\n" +
|
||||
"WxVKm4+ri8Ncnk0dBqjEBNwgdsvRlxPMAB9t4mTxS6NENriIWgiBGDiMFT3dstkw\n" +
|
||||
"tIvxX/gdrLCd9CbV1iZgH+a/CiKIYcSGzPiYfwEi446cPZwfwYo65C1HBS1mMJju\n" +
|
||||
"FwLw0r9OQ9LEsO+ar6d7hss4RmHgRR1JdQyBoq/wbQKBgQD1kkE1TfJpFmCpWR/P\n" +
|
||||
"wdl88ABnwEZtaKKMS1A+T2+ywEl3y+iUPoouJ+69zG0s7NuwpeJ2c1S0BB+yFRWx\n" +
|
||||
"ExGjJ2Z0GbK++f2R38Y3kvj2lGiB4AZ1sentTuatGHWRzwEd913swrKd/fkFBA/I\n" +
|
||||
"x38Mmq7wDqkqIxNh20W2jWWd3QKBgQDcAgg39l5zYeNIUdm/PQINd4G1UjCTcgvn\n" +
|
||||
"+7AFpuoCYfx9ReXzvLjGDs8VmuoBIg5Y4bWIUhTSQVQIIRE12EXrysawHs7loegp\n" +
|
||||
"FTU6cZAjxT72sRhesr12f5s5Hd3zaMB0Y8PUljAG7lvAVNPQDUkAL7+bmYLxWokq\n" +
|
||||
"G/FHJooBOwKBgQCidDWVKNKTuI0Lmv0TeL8DCtaJzEYK/OyDeRNFlVFkZBZ2HLvo\n" +
|
||||
"zhKlhB9JCiKzVKHlE2hkSdmgGRZKve4SrXW+hEMfzRxVgJXB2dKMUztGDFmyiVxc\n" +
|
||||
"oe0J42dw3Txx0AqCI3HMPeTh5fDF47D5dxhSY0YVYu2ABaI920wb/yBZNQKBgGlz\n" +
|
||||
"P+Uy3QqIvJuJP8j9wOIbibwS7N1/KF3EsRXEbx09Qfv5aMJujlG//1nnqolofV/0\n" +
|
||||
"r0HrtbchQNm0n78jLkBaLOl1ms1N0Sz/0Ud17xR2EjvDnl6lZVJKz2eM/TkR2Ezx\n" +
|
||||
"FIfshJCN5sRE5FEwTPEd8cTuy2hLcLsSMY9c1YDJAoGBAMIPLraI8c7h4hOCNE66\n" +
|
||||
"Eg2nEOcqCzmIYTS6ARCPYrOC4cx23+uAScbZCq+vBk34KSJyun1OgfvnRmVerpUU\n" +
|
||||
"lld8v62FR3FnNwSY/zeySP8ENCzAUluql0yHzgpBwF3NNYihVdYY4Lm3vlUe4fTt\n" +
|
||||
"krNC84FOePuC5qaIefZ03oRX\n" +
|
||||
"-----END PRIVATE KEY-----";
|
||||
|
||||
private final IDictDataService dictDataService;
|
||||
|
||||
@Override
|
||||
public SysRegRes getRegResByType(String type) {
|
||||
return this.lambdaQuery().eq(SysRegRes::getType, type).eq(SysRegRes::getState, DataStateEnum.ENABLE.getCode()).one();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public boolean addRegRes(SysRegResParam sysRegResParam) {
|
||||
List<SysRegRes> regResList = new ArrayList<>();
|
||||
|
||||
RegInfoData regInfoData = decodeRegistrationCode(sysRegResParam.getCode());
|
||||
if (ObjectUtil.isNotNull(regInfoData)) {
|
||||
// 对比Mac地址
|
||||
String mac = getMAC();
|
||||
if (!mac.equals(regInfoData.getMacAddress())) {
|
||||
throw new BusinessException(SystemResponseEnum.MAC_ADDRESS_NOT_MATCH);
|
||||
}
|
||||
|
||||
List<String> expireDateList = regInfoData.getExpireDateList();
|
||||
for (int i = 0; i < regInfoData.getTypeList().size(); i++) {
|
||||
expireDateList.set(i, formatDate(expireDateList.get(i)));
|
||||
}
|
||||
// 比对到期日期
|
||||
String maxExpireDate = expireDateList.stream().max((a, b) -> a.compareTo(b)).get();
|
||||
if (LocalDate.parse(maxExpireDate).isBefore(LocalDate.now())) {
|
||||
throw new BusinessException(SystemResponseEnum.REGISTRATION_CODE_EXPIRED);
|
||||
}
|
||||
|
||||
sysTestConfigService.addTestConfig(regInfoData.getScene());
|
||||
|
||||
for (int i = 0; i < regInfoData.getTypeList().size(); i++) {
|
||||
// 忽略过期的
|
||||
// if (isExpire(expireDateList.get(i))) {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
SysRegRes sysRegRes = new SysRegRes();
|
||||
BeanUtil.copyProperties(sysRegResParam, sysRegRes);
|
||||
sysRegRes.setState(DataStateEnum.ENABLE.getCode());
|
||||
sysRegRes.setCode(sysRegResParam.getCode());
|
||||
sysRegRes.setExpireDate(EncryptionUtil.encodeString(1, formatDate(regInfoData.getExpireDateList().get(i))));
|
||||
|
||||
DictData dictData = dictDataService.getDictDataByCode(regInfoData.getTypeList().get(i));
|
||||
if (ObjectUtil.isNotNull(dictData)) {
|
||||
sysRegRes.setType(dictData.getId());
|
||||
}
|
||||
|
||||
sysRegRes.setRealTime(20);
|
||||
sysRegRes.setStatistics(5);
|
||||
sysRegRes.setFlicker(1);
|
||||
|
||||
if (regInfoData.getTypeList().get(i).equals(DictDataEnum.CONTRAST.getCode())) {
|
||||
sysRegRes.setWaveRecord(1);
|
||||
sysRegRes.setRealTime(200);
|
||||
sysRegRes.setStatistics(5);
|
||||
sysRegRes.setFlicker(3);
|
||||
}
|
||||
|
||||
regResList.add(sysRegRes);
|
||||
}
|
||||
}
|
||||
|
||||
// 删除原有的所有数据
|
||||
this.remove(null);
|
||||
return this.saveBatch(regResList);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public boolean updateRegRes(SysRegResParam.UpdateParam param) {
|
||||
SysRegRes sysRegRes = new SysRegRes();
|
||||
BeanUtil.copyProperties(param, sysRegRes);
|
||||
if (sysRegRes.getWaveRecord() == -1) {
|
||||
sysRegRes.setWaveRecord(null);
|
||||
}
|
||||
return this.updateById(sysRegRes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysRegResVO listRegRes() {
|
||||
// todo 需要切面检测是否到期,到期则状态设为0
|
||||
SysRegResVO sysRegResVO = new SysRegResVO();
|
||||
List<SysRegRes> regResList = this.lambdaQuery().eq(SysRegRes::getState, DataStateEnum.ENABLE.getCode()).list();
|
||||
if (ObjectUtil.isNotEmpty(regResList)) {
|
||||
sysRegResVO.setCode(regResList.get(0).getCode());
|
||||
sysRegResVO.setSimulateStatus(RegStatusEnum.UNREGISTERED.getCode());
|
||||
sysRegResVO.setDigitalStatus(RegStatusEnum.UNREGISTERED.getCode());
|
||||
sysRegResVO.setContrastStatus(RegStatusEnum.UNREGISTERED.getCode());
|
||||
for (SysRegRes regRes : regResList) {
|
||||
DictData dictData = dictDataService.getDictDataById(regRes.getType());
|
||||
String s = EncryptionUtil.decoderString(1, regRes.getExpireDate());
|
||||
boolean expire = isExpire(s);
|
||||
if (ObjectUtil.isNotNull(dictData)) {
|
||||
if (dictData.getCode().equals(DictDataEnum.SIMULATE.getCode())) {
|
||||
if (expire) {
|
||||
sysRegResVO.setSimulateStatus(RegStatusEnum.EXPIRED.getCode());
|
||||
} else {
|
||||
sysRegResVO.setSimulateStatus(RegStatusEnum.REGISTERED.getCode());
|
||||
}
|
||||
sysRegResVO.setSimulateExpireDate(s);
|
||||
}
|
||||
if (dictData.getCode().equals(DictDataEnum.DIGITAL.getCode())) {
|
||||
if (expire) {
|
||||
sysRegResVO.setDigitalStatus(RegStatusEnum.EXPIRED.getCode());
|
||||
} else {
|
||||
sysRegResVO.setDigitalStatus(RegStatusEnum.REGISTERED.getCode());
|
||||
}
|
||||
sysRegResVO.setDigitalExpireDate(s);
|
||||
}
|
||||
if (dictData.getCode().equals(DictDataEnum.CONTRAST.getCode())) {
|
||||
if (expire) {
|
||||
sysRegResVO.setContrastStatus(RegStatusEnum.EXPIRED.getCode());
|
||||
} else {
|
||||
sysRegResVO.setContrastStatus(RegStatusEnum.REGISTERED.getCode());
|
||||
}
|
||||
sysRegResVO.setContrastExpireDate(s);
|
||||
}
|
||||
} else {
|
||||
throw new BusinessException("字典数据缺失,请联系管理员!");
|
||||
}
|
||||
}
|
||||
}
|
||||
return sysRegResVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysRegRes getContrastRegRes() {
|
||||
return this.getRegResByType("7cd65363a6bf675ae408f28a281b77d4");
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化日期 (将日期格式化为yyyy-MM-dd)
|
||||
*
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
private String formatDate(String date) {
|
||||
String[] split = date.split("-");
|
||||
if (split[1].length() == 1) {
|
||||
split[1] = "0" + split[1];
|
||||
}
|
||||
if (split[2].length() == 1) {
|
||||
split[2] = "0" + split[2];
|
||||
}
|
||||
return split[0] + "-" + split[1] + "-" + split[2];
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否到期
|
||||
*
|
||||
* @param expireDate 到期日期
|
||||
* @return
|
||||
*/
|
||||
private boolean isExpire(String expireDate) {
|
||||
expireDate = formatDate(expireDate);
|
||||
String today = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
|
||||
if (today.compareTo(expireDate) >= 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用hutool工具获取本机mac地址
|
||||
*
|
||||
* @return mac地址
|
||||
*/
|
||||
private String getMAC() {
|
||||
InetAddress inetAddress = null;
|
||||
try {
|
||||
inetAddress = InetAddress.getLocalHost();
|
||||
} catch (UnknownHostException e) {
|
||||
throw new BusinessException(SystemResponseEnum.GET_MAC_ADDRESS_FAILED);
|
||||
}
|
||||
return NetUtil.getMacAddress(inetAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析 PEM 格式的密钥
|
||||
*
|
||||
* @param pem PEM 格式的密钥
|
||||
* @return 密钥对象
|
||||
* @throws Exception
|
||||
*/
|
||||
private Key parsePemKey(String pem) throws Exception {
|
||||
// 去掉 PEM 格式中的头部和尾部
|
||||
String cleanPem = pem
|
||||
.replaceAll("-----BEGIN (.*?)-----", "")
|
||||
.replaceAll("-----END (.*?)-----", "")
|
||||
.replaceAll("\\s+", ""); // 移除换行和空格
|
||||
|
||||
byte[] decodedKey = Base64.getDecoder().decode(cleanPem);
|
||||
|
||||
// 根据密钥类型导入密钥
|
||||
if (pem.contains("PRIVATE")) {
|
||||
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKey);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
|
||||
return privateKey;
|
||||
} else {
|
||||
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedKey);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||
PublicKey publicKey = keyFactory.generatePublic(keySpec);
|
||||
return publicKey;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析注册码
|
||||
*
|
||||
* @param encryptedCode 加密后的注册码
|
||||
* @return
|
||||
*/
|
||||
private RegInfoData decodeRegistrationCode(String encryptedCode) {
|
||||
try {
|
||||
byte[] encryptedData = Base64.getDecoder().decode(encryptedCode);
|
||||
Key privateKey = parsePemKey(fixedPrivateKeyStr);
|
||||
|
||||
// 使用 RSA/OAEP 解密
|
||||
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||
byte[] decryptedData = cipher.doFinal(encryptedData);
|
||||
|
||||
// 将解密后的字节数组转换为字符串
|
||||
String decodedString = new String(decryptedData, StandardCharsets.UTF_8);
|
||||
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
RegInfoData regInfoData = objectMapper.readValue(decodedString, RegInfoData.class);
|
||||
if (ObjectUtil.isNull(regInfoData) || ObjectUtil.isNull(regInfoData.getScene()) || regInfoData.getTypeList().size() == 0 || regInfoData.getTypeList().size() != regInfoData.getExpireDateList().size()) {
|
||||
throw new BusinessException(SystemResponseEnum.REGISTRATION_CODE_FORMAT_ERROR);
|
||||
}
|
||||
return regInfoData;
|
||||
} catch (Exception e) {
|
||||
throw new BusinessException(SystemResponseEnum.REGISTRATION_CODE_FORMAT_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user