diff --git a/.gitignore b/.gitignore index eb913770..12e0ef0c 100644 --- a/.gitignore +++ b/.gitignore @@ -52,4 +52,5 @@ rebel.xml # 个人工作文档,不与团队共享 CLAUDE.md docs/ -data/ \ No newline at end of file +data/ +.m2 \ No newline at end of file diff --git a/detection/pom.xml b/detection/pom.xml index 1a346a4d..7eae4b66 100644 --- a/detection/pom.xml +++ b/detection/pom.xml @@ -150,6 +150,10 @@ spring-boot-starter-test test + + org.springframework.boot + spring-boot-starter-data-redis + diff --git a/detection/src/main/java/com/njcn/gather/detection/handler/SocketDevResponseService.java b/detection/src/main/java/com/njcn/gather/detection/handler/SocketDevResponseService.java index 9715a2be..1f913ffa 100644 --- a/detection/src/main/java/com/njcn/gather/detection/handler/SocketDevResponseService.java +++ b/detection/src/main/java/com/njcn/gather/detection/handler/SocketDevResponseService.java @@ -16,6 +16,7 @@ import com.njcn.gather.detection.pojo.po.DevData; import com.njcn.gather.detection.pojo.po.IcdCheckData; import com.njcn.gather.detection.pojo.po.SourceCompareDev; import com.njcn.gather.detection.pojo.vo.*; +import com.njcn.gather.detection.service.FormalTestEventPublisher; import com.njcn.gather.detection.service.impl.DetectionServiceImpl; import com.njcn.gather.detection.util.DetectionUtil; import com.njcn.gather.detection.util.socket.*; @@ -83,6 +84,7 @@ public class SocketDevResponseService { private final IDictDataService dictDataService; private final IPqSourceService pqSourceService; private final IResultService resultService; + private final FormalTestEventPublisher formalTestEventPublisher; @Value("${dataCheck.enable}") private Boolean dataCheck; @@ -1229,6 +1231,7 @@ public class SocketDevResponseService { socketMsg.setOperateCode(SourceOperateCodeEnum.OPER_GATHER.getValue()); SocketManager.sendMsg(param.getUserPageId() + CnSocketUtil.SOURCE_TAG, JSON.toJSONString(socketMsg)); + this.publishFormalStartIfNeeded(); webSocketVO.setDesc(null); WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(webSocketVO)); } else { @@ -1386,7 +1389,7 @@ public class SocketDevResponseService { List valueType = iPqScriptCheckDataService.getValueType(checkDataParam); iPqDevService.updateResult(param.getDevIds(), valueType, param.getCode(), param.getUserId(), param.getTemperature(), param.getHumidity(), true); - if (dataCheck) { + if (Boolean.TRUE.equals(dataCheck)) { resultService.tryNotifyThirdPartyAfterFormalTest(param); } CnSocketUtil.quitSend(param); @@ -1527,6 +1530,7 @@ public class SocketDevResponseService { switch (Objects.requireNonNull(operateCodeEnum)) { case QUIT_INIT_01: //关闭所有 + publishFormalEndIfNeeded(); SocketManager.removeUser(s); CnSocketUtil.quitSendSource(param); break; @@ -1549,6 +1553,7 @@ public class SocketDevResponseService { case NO_INIT_DEV: switch (operateCodeEnum) { case QUIT_INIT_01: + publishFormalEndIfNeeded(); SocketManager.removeUser(s); // CnSocketUtil.quitSendSource(param); break; @@ -1571,6 +1576,22 @@ public class SocketDevResponseService { } + private void publishFormalEndIfNeeded() { + if (FormalTestManager.endEventPublished && !Boolean.TRUE.equals(dataCheck)) { + return; + } + formalTestEventPublisher.publishEnd(FormalTestManager.sessionId, FormalTestManager.devList); + FormalTestManager.endEventPublished = true; + } + + private void publishFormalStartIfNeeded() { + if (FormalTestManager.startEventPublished || ObjectUtil.isNull(FormalTestManager.sessionId) && !Boolean.TRUE.equals(dataCheck)) { + return; + } + formalTestEventPublisher.publishStart(FormalTestManager.sessionId, FormalTestManager.devList); + FormalTestManager.startEventPublished = true; + } + /** * @param issue * @return key为V或I,value为对应的源下发信息 @@ -1816,6 +1837,9 @@ public class SocketDevResponseService { FormalTestManager.overload = getOverloadResult(param); FormalTestManager.checkStartTime = LocalDateTime.now(); FormalTestManager.reCheckType = param.getReCheckType(); + FormalTestManager.sessionId = UUID.randomUUID().toString().replace("-", ""); + FormalTestManager.startEventPublished = false; + FormalTestManager.endEventPublished = false; } diff --git a/detection/src/main/java/com/njcn/gather/detection/pojo/vo/FormalTestDevicePayload.java b/detection/src/main/java/com/njcn/gather/detection/pojo/vo/FormalTestDevicePayload.java new file mode 100644 index 00000000..0b682243 --- /dev/null +++ b/detection/src/main/java/com/njcn/gather/detection/pojo/vo/FormalTestDevicePayload.java @@ -0,0 +1,17 @@ +package com.njcn.gather.detection.pojo.vo; + +import lombok.Data; + +@Data +public class FormalTestDevicePayload { + + private String deviceId; + + private String monitorId; + + private String deviceIp; + + private String deviceType; + + private String icdMappingName; +} diff --git a/detection/src/main/java/com/njcn/gather/detection/pojo/vo/FormalTestEventPayload.java b/detection/src/main/java/com/njcn/gather/detection/pojo/vo/FormalTestEventPayload.java new file mode 100644 index 00000000..a041bbb1 --- /dev/null +++ b/detection/src/main/java/com/njcn/gather/detection/pojo/vo/FormalTestEventPayload.java @@ -0,0 +1,18 @@ +package com.njcn.gather.detection.pojo.vo; + +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; + +@Data +public class FormalTestEventPayload { + + private String eventType; + + private LocalDateTime eventTime; + + private String sessionId; + + private List devices; +} diff --git a/detection/src/main/java/com/njcn/gather/detection/service/FormalTestEventPublisher.java b/detection/src/main/java/com/njcn/gather/detection/service/FormalTestEventPublisher.java new file mode 100644 index 00000000..19b67f45 --- /dev/null +++ b/detection/src/main/java/com/njcn/gather/detection/service/FormalTestEventPublisher.java @@ -0,0 +1,12 @@ +package com.njcn.gather.detection.service; + +import com.njcn.gather.device.pojo.vo.PreDetection; + +import java.util.List; + +public interface FormalTestEventPublisher { + + void publishStart(String sessionId, List devices); + + void publishEnd(String sessionId, List devices); +} diff --git a/detection/src/main/java/com/njcn/gather/detection/service/impl/FormalTestEventPublisherImpl.java b/detection/src/main/java/com/njcn/gather/detection/service/impl/FormalTestEventPublisherImpl.java new file mode 100644 index 00000000..21e7fcf3 --- /dev/null +++ b/detection/src/main/java/com/njcn/gather/detection/service/impl/FormalTestEventPublisherImpl.java @@ -0,0 +1,95 @@ +package com.njcn.gather.detection.service.impl; + +import com.alibaba.fastjson.JSON; +import com.njcn.gather.detection.pojo.vo.FormalTestDevicePayload; +import com.njcn.gather.detection.pojo.vo.FormalTestEventPayload; +import com.njcn.gather.detection.service.FormalTestEventPublisher; +import com.njcn.gather.device.pojo.vo.PreDetection; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +@Slf4j +@Service +@RequiredArgsConstructor +public class FormalTestEventPublisherImpl implements FormalTestEventPublisher { + + private final StringRedisTemplate stringRedisTemplate; + + private static String msgChannel = "formal-test-msg-channel"; + + private final Set publishedStartSessions = + Collections.newSetFromMap(new ConcurrentHashMap()); + + private final Set publishedEndSessions = + Collections.newSetFromMap(new ConcurrentHashMap()); + + @Override + public void publishStart(String sessionId, List devices) { + publish("start", sessionId, devices); + } + + @Override + public void publishEnd(String sessionId, List devices) { + publish("end", sessionId, devices); + } + + public FormalTestEventPayload buildPayload(String eventType, String sessionId, List devices) { + FormalTestEventPayload payload = new FormalTestEventPayload(); + payload.setEventType(eventType); + payload.setEventTime(LocalDateTime.now()); + payload.setSessionId(sessionId); + payload.setDevices(buildDevices(devices)); + return payload; + } + + private void publish(String eventType, String sessionId, List devices) { + if (sessionId == null) { + return; + } + Set dedupSet = "start".equals(eventType) ? publishedStartSessions : publishedEndSessions; + if (!dedupSet.add(sessionId)) { + return; + } + try { + FormalTestEventPayload payload = buildPayload(eventType, sessionId, devices); + stringRedisTemplate.convertAndSend(msgChannel, JSON.toJSONString(payload)); + } catch (Exception ex) { + log.error("publish formal test event failed, eventType={}, sessionId={}, deviceCount={}", + eventType, sessionId, devices == null ? 0 : devices.size(), ex); + } + } + + private List buildDevices(List devices) { + List results = new ArrayList<>(); + if (devices == null) { + return results; + } + for (PreDetection device : devices) { + if (device == null || device.getMonitorList() == null) { + continue; + } + for (PreDetection.MonitorListDTO monitor : device.getMonitorList()) { + if (monitor == null || monitor.getLine() == null) { + continue; + } + FormalTestDevicePayload payload = new FormalTestDevicePayload(); + payload.setDeviceId(device.getDevId()); + payload.setMonitorId(device.getDevId() + "_" + monitor.getLine()); + payload.setDeviceIp(device.getDevIP()); + payload.setDeviceType(device.getDevType()); + payload.setIcdMappingName(device.getIcdType()); + results.add(payload); + } + } + return results; + } +} diff --git a/detection/src/main/java/com/njcn/gather/detection/util/socket/CnSocketUtil.java b/detection/src/main/java/com/njcn/gather/detection/util/socket/CnSocketUtil.java index 8a9810de..16c13abc 100644 --- a/detection/src/main/java/com/njcn/gather/detection/util/socket/CnSocketUtil.java +++ b/detection/src/main/java/com/njcn/gather/detection/util/socket/CnSocketUtil.java @@ -49,7 +49,11 @@ public class CnSocketUtil { JSONObject jsonObject = new JSONObject(); jsonObject.put("sourceId", param.getSourceName()); socketMsg.setData(jsonObject.toJSONString()); - SocketManager.sendMsg(param.getUserPageId() + SOURCE_TAG, JSON.toJSONString(socketMsg)); + String sourceKey = param.getUserPageId() + SOURCE_TAG; + if (SocketManager.isChannelActive(sourceKey)) { + SocketManager.markActiveClose(sourceKey); + } + SocketManager.sendMsg(sourceKey, JSON.toJSONString(socketMsg)); WebServiceManager.removePreDetectionParam(param.getUserPageId()); } diff --git a/detection/src/main/java/com/njcn/gather/detection/util/socket/FormalTestManager.java b/detection/src/main/java/com/njcn/gather/detection/util/socket/FormalTestManager.java index 6845c69f..82953a5d 100644 --- a/detection/src/main/java/com/njcn/gather/detection/util/socket/FormalTestManager.java +++ b/detection/src/main/java/com/njcn/gather/detection/util/socket/FormalTestManager.java @@ -220,6 +220,12 @@ public class FormalTestManager { */ public static LocalDateTime checkStartTime; + public static String sessionId; + + public static boolean startEventPublished; + + public static boolean endEventPublished; + /** * 数模式 检测类型"1"-"全部检测" , "2"-"不合格项复检" */ diff --git a/detection/src/main/java/com/njcn/gather/detection/util/socket/SocketManager.java b/detection/src/main/java/com/njcn/gather/detection/util/socket/SocketManager.java index f8b813c2..da9b40b8 100644 --- a/detection/src/main/java/com/njcn/gather/detection/util/socket/SocketManager.java +++ b/detection/src/main/java/com/njcn/gather/detection/util/socket/SocketManager.java @@ -55,6 +55,11 @@ public class SocketManager { */ private static final Map socketGroup = new ConcurrentHashMap<>(); + /** + * 主动关闭中的连接。用于区分业务主动 close 和对端异常断线。 + */ + private static final Map activeClosingUsers = new ConcurrentHashMap<>(); + public static void addUser(String userId, Channel channel) { socketSessions.put(userId, channel); } @@ -65,20 +70,31 @@ public class SocketManager { public static void removeUser(String userId) { Channel channel = socketSessions.get(userId); + removeMapping(userId, false); if (ObjectUtil.isNotNull(channel)) { try { + markActiveClose(userId); channel.close().sync(); } catch (InterruptedException e) { e.printStackTrace(); } - NioEventLoopGroup eventExecutors = socketGroup.get(userId); - if (ObjectUtil.isNotNull(eventExecutors)) { - eventExecutors.shutdownGracefully(); - System.out.println(userId + "__" + channel.id() + "关闭了客户端"); - } + System.out.println(userId + "__" + channel.id() + "关闭了客户端"); } + } + + public static void removeMapping(String userId) { + removeMapping(userId, true); + } + + private static void removeMapping(String userId, boolean clearActiveClose) { socketSessions.remove(userId); - socketGroup.remove(userId); + NioEventLoopGroup eventExecutors = socketGroup.remove(userId); + if (clearActiveClose) { + consumeActiveClose(userId); + } + if (ObjectUtil.isNotNull(eventExecutors)) { + eventExecutors.shutdownGracefully(); + } } public static Channel getChannelByUserId(String userId) { @@ -89,6 +105,20 @@ public class SocketManager { return socketGroup.get(userId); } + public static void markActiveClose(String userId) { + if (StrUtil.isNotBlank(userId)) { + activeClosingUsers.put(userId, Boolean.TRUE); + } + } + + public static boolean consumeActiveClose(String userId) { + return StrUtil.isNotBlank(userId) && activeClosingUsers.remove(userId) != null; + } + + public static boolean isActiveClosing(String userId) { + return StrUtil.isNotBlank(userId) && activeClosingUsers.containsKey(userId); + } + public static void sendMsg(String userId, String msg) { Channel channel = socketSessions.get(userId); if (ObjectUtil.isNotNull(channel)) { diff --git a/detection/src/main/java/com/njcn/gather/detection/util/socket/cilent/NettyDevClientHandler.java b/detection/src/main/java/com/njcn/gather/detection/util/socket/cilent/NettyDevClientHandler.java index b01c2446..be1958d6 100644 --- a/detection/src/main/java/com/njcn/gather/detection/util/socket/cilent/NettyDevClientHandler.java +++ b/detection/src/main/java/com/njcn/gather/detection/util/socket/cilent/NettyDevClientHandler.java @@ -115,7 +115,11 @@ public class NettyDevClientHandler extends SimpleChannelInboundHandler { public void channelInactive(ChannelHandlerContext ctx) throws Exception { log.warn("设备通讯客户端断线"); ctx.close(); - SocketManager.removeUser(param.getUserPageId() + CnSocketUtil.DEV_TAG); + String key = param.getUserPageId() + CnSocketUtil.DEV_TAG; + if (SocketManager.consumeActiveClose(key)) { + return; + } + SocketManager.removeUser(key); CnSocketUtil.quitSendSource(param); // 设备主动断开 → 本次检测视为结束,释放检测锁 DetectionLockManager.getInstance() diff --git a/detection/src/main/java/com/njcn/gather/detection/util/socket/cilent/NettySourceClientHandler.java b/detection/src/main/java/com/njcn/gather/detection/util/socket/cilent/NettySourceClientHandler.java index 27601d50..88aaec15 100644 --- a/detection/src/main/java/com/njcn/gather/detection/util/socket/cilent/NettySourceClientHandler.java +++ b/detection/src/main/java/com/njcn/gather/detection/util/socket/cilent/NettySourceClientHandler.java @@ -70,7 +70,12 @@ public class NettySourceClientHandler extends SimpleChannelInboundHandler> listAll() { + String methodDescribe = getMethodDescribe("listAll"); + List result = pqPqdifPathService.listAll(); + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe); + } + + @OperateInfo + @PostMapping("/list") + @ApiOperation("分页查询PQDIF") + @ApiImplicitParam(name = "param", value = "查询参数", required = true) + public HttpResult> list(@RequestBody @Validated PqPqdifPathParam.QueryParam param) { + String methodDescribe = getMethodDescribe("list"); + LogUtil.njcnDebug(log, "{},查询数据为:{}", methodDescribe, param); + Page result = pqPqdifPathService.listPqdif(param); + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe); + } + + @OperateInfo(info = LogEnum.BUSINESS_COMMON, operateType = OperateType.ADD) + @PostMapping("/import/json") + @ApiOperation("导入PQDIF json") + @ApiImplicitParam(name = "file", value = "json文件", required = true) + public HttpResult importJson(@RequestParam("file") MultipartFile file) { + String methodDescribe = getMethodDescribe("importJson"); + LogUtil.njcnDebug(log, "{},导入文件为:{}", methodDescribe, file == null ? null : file.getOriginalFilename()); + List items = parseImportItems(file); + boolean result = pqPqdifPathService.importPqdif(items); + if (result) { + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, true, methodDescribe); + } + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, false, methodDescribe); + } + + private List parseImportItems(MultipartFile file) { + if (file == null || file.isEmpty()) { + throw new BusinessException(PqdifResponseEnum.JSON_FILE_NOT_NULL); + } + String fileName = file.getOriginalFilename(); + if (fileName == null || !fileName.toLowerCase().endsWith(".json")) { + throw new BusinessException(PqdifResponseEnum.JSON_FORMAT_ERROR); + } + try { + return PqdifImportParser.parse(new String(file.getBytes(), StandardCharsets.UTF_8)); + } catch (BusinessException ex) { + throw ex; + } catch (Exception ex) { + throw new BusinessException(PqdifResponseEnum.JSON_FORMAT_ERROR); + } + } +} diff --git a/detection/src/main/java/com/njcn/gather/pqdif/mapper/PqPqdifPathMapper.java b/detection/src/main/java/com/njcn/gather/pqdif/mapper/PqPqdifPathMapper.java new file mode 100644 index 00000000..a709dcbe --- /dev/null +++ b/detection/src/main/java/com/njcn/gather/pqdif/mapper/PqPqdifPathMapper.java @@ -0,0 +1,12 @@ +package com.njcn.gather.pqdif.mapper; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.github.yulichang.base.MPJBaseMapper; +import com.njcn.gather.pqdif.pojo.po.PqPqdifPath; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +public interface PqPqdifPathMapper extends MPJBaseMapper { + List selectPageList(Page page, @Param("name") String name, @Param("result") Integer result); +} diff --git a/detection/src/main/java/com/njcn/gather/pqdif/mapper/mapping/PqPqdifPathMapper.xml b/detection/src/main/java/com/njcn/gather/pqdif/mapper/mapping/PqPqdifPathMapper.xml new file mode 100644 index 00000000..80553aba --- /dev/null +++ b/detection/src/main/java/com/njcn/gather/pqdif/mapper/mapping/PqPqdifPathMapper.xml @@ -0,0 +1,28 @@ + + + + + diff --git a/detection/src/main/java/com/njcn/gather/pqdif/pojo/enums/PqdifResponseEnum.java b/detection/src/main/java/com/njcn/gather/pqdif/pojo/enums/PqdifResponseEnum.java new file mode 100644 index 00000000..012e0248 --- /dev/null +++ b/detection/src/main/java/com/njcn/gather/pqdif/pojo/enums/PqdifResponseEnum.java @@ -0,0 +1,20 @@ +package com.njcn.gather.pqdif.pojo.enums; + +import lombok.Getter; + +@Getter +public enum PqdifResponseEnum { + JSON_FILE_NOT_NULL("A019001", "JSON文件不能为空"), + JSON_FORMAT_ERROR("A019002", "JSON格式错误"), + IMPORT_ITEM_NOT_NULL("A019003", "导入数据项不能为空"), + IMPORT_ID_REPEAT("A019004", "导入数据中存在重复id"), + IMPORT_FAILED("A019005", "PQDIF导入失败"); + + private final String code; + private final String message; + + PqdifResponseEnum(String code, String message) { + this.code = code; + this.message = message; + } +} diff --git a/detection/src/main/java/com/njcn/gather/pqdif/pojo/param/PqPqdifPathParam.java b/detection/src/main/java/com/njcn/gather/pqdif/pojo/param/PqPqdifPathParam.java new file mode 100644 index 00000000..35a4c76b --- /dev/null +++ b/detection/src/main/java/com/njcn/gather/pqdif/pojo/param/PqPqdifPathParam.java @@ -0,0 +1,38 @@ +package com.njcn.gather.pqdif.pojo.param; + +import com.njcn.web.pojo.param.BaseParam; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +public class PqPqdifPathParam { + + @Data + @EqualsAndHashCode(callSuper = true) + public static class QueryParam extends BaseParam { + @ApiModelProperty(value = "name") + private String name; + + @ApiModelProperty(value = "result") + private Integer result; + } + + @Data + public static class ImportItem { + private String id; + private String name; + private String filePath; + private Long recordCount; + private Long observationCount; + private Integer sampleValueCount; + private Integer result; + private String msg; + private Integer state; + private Object parseResult; + private String createBy; + private String createTime; + private String updateBy; + private String updateTime; + } +} diff --git a/detection/src/main/java/com/njcn/gather/pqdif/pojo/po/PqPqdifPath.java b/detection/src/main/java/com/njcn/gather/pqdif/pojo/po/PqPqdifPath.java new file mode 100644 index 00000000..92fb9ff0 --- /dev/null +++ b/detection/src/main/java/com/njcn/gather/pqdif/pojo/po/PqPqdifPath.java @@ -0,0 +1,41 @@ +package com.njcn.gather.pqdif.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; + +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("pq_pqdif_path") +public class PqPqdifPath extends BaseEntity implements Serializable { + private static final long serialVersionUID = 2536904714178389110L; + + private String id; + + private String name; + + @TableField("File_Path") + private String filePath; + + @TableField("Record_Count") + private Long recordCount; + + @TableField("Observation_Count") + private Long observationCount; + + @TableField("Sample_Value_Count") + private Integer sampleValueCount; + + @TableField("Result") + private Integer result; + + @TableField("Msg") + private String msg; + + @TableField("State") + private Integer state; +} diff --git a/detection/src/main/java/com/njcn/gather/pqdif/service/IPqPqdifPathService.java b/detection/src/main/java/com/njcn/gather/pqdif/service/IPqPqdifPathService.java new file mode 100644 index 00000000..ac426905 --- /dev/null +++ b/detection/src/main/java/com/njcn/gather/pqdif/service/IPqPqdifPathService.java @@ -0,0 +1,16 @@ +package com.njcn.gather.pqdif.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import com.njcn.gather.pqdif.pojo.param.PqPqdifPathParam; +import com.njcn.gather.pqdif.pojo.po.PqPqdifPath; + +import java.util.List; + +public interface IPqPqdifPathService extends IService { + List listAll(); + + Page listPqdif(PqPqdifPathParam.QueryParam param); + + boolean importPqdif(List items); +} diff --git a/detection/src/main/java/com/njcn/gather/pqdif/service/impl/PqPqdifPathServiceImpl.java b/detection/src/main/java/com/njcn/gather/pqdif/service/impl/PqPqdifPathServiceImpl.java new file mode 100644 index 00000000..7055e641 --- /dev/null +++ b/detection/src/main/java/com/njcn/gather/pqdif/service/impl/PqPqdifPathServiceImpl.java @@ -0,0 +1,114 @@ +package com.njcn.gather.pqdif.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ReUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.njcn.common.pojo.constant.PatternRegex; +import com.njcn.common.pojo.enums.common.DataStateEnum; +import com.njcn.common.pojo.exception.BusinessException; +import com.njcn.gather.pojo.constant.DetectionValidMessage; +import com.njcn.gather.pqdif.mapper.PqPqdifPathMapper; +import com.njcn.gather.pqdif.pojo.enums.PqdifResponseEnum; +import com.njcn.gather.pqdif.pojo.param.PqPqdifPathParam; +import com.njcn.gather.pqdif.pojo.po.PqPqdifPath; +import com.njcn.gather.pqdif.service.IPqPqdifPathService; +import com.njcn.web.factory.PageFactory; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +@Slf4j +@Service +public class PqPqdifPathServiceImpl extends ServiceImpl implements IPqPqdifPathService { + + @Override + public List listAll() { + return this.lambdaQuery() + .select(PqPqdifPath::getId, PqPqdifPath::getName) + .eq(PqPqdifPath::getState, DataStateEnum.ENABLE.getCode()) + .orderByDesc(PqPqdifPath::getCreateTime) + .list(); + } + + @Override + public Page listPqdif(PqPqdifPathParam.QueryParam param) { + Page page = new Page<>(PageFactory.getPageNum(param), PageFactory.getPageSize(param)); + page.setRecords(this.baseMapper.selectPageList(page, StrUtil.trim(param.getName()), param.getResult())); + return page; + } + + @Override + @Transactional + public boolean importPqdif(List items) { + if (CollUtil.isEmpty(items)) { + return true; + } + validateItems(items); + for (PqPqdifPathParam.ImportItem item : items) { + PqPqdifPath entity = toEntity(item); + boolean saved = this.saveOrUpdate(entity); + if (!saved) { + throw new BusinessException(PqdifResponseEnum.IMPORT_FAILED); + } + } + return true; + } + + private void validateItems(List items) { + Set ids = new HashSet<>(); + for (PqPqdifPathParam.ImportItem item : items) { + if (item == null) { + throw new BusinessException(PqdifResponseEnum.IMPORT_ITEM_NOT_NULL); + } + String id = StrUtil.trim(item.getId()); + if (StrUtil.isBlank(id)) { + throw new BusinessException(DetectionValidMessage.ID_NOT_BLANK); + } + if (!ReUtil.isMatch(PatternRegex.SYSTEM_ID, id)) { + throw new BusinessException(DetectionValidMessage.ID_FORMAT_ERROR); + } + if (!ids.add(id)) { + throw new BusinessException(PqdifResponseEnum.IMPORT_ID_REPEAT); + } + if (StrUtil.isBlank(item.getName())) { + throw new BusinessException(DetectionValidMessage.NAME_NOT_BLANK); + } + } + } + + private PqPqdifPath toEntity(PqPqdifPathParam.ImportItem item) { + PqPqdifPath entity = new PqPqdifPath(); + entity.setId(StrUtil.trim(item.getId())); + entity.setName(StrUtil.trim(item.getName())); + entity.setFilePath(StrUtil.trim(item.getFilePath())); + entity.setRecordCount(item.getRecordCount()); + entity.setObservationCount(item.getObservationCount()); + entity.setSampleValueCount(item.getSampleValueCount()); + entity.setResult(item.getResult()); + entity.setMsg(item.getMsg()); + entity.setState(item.getState() == null ? DataStateEnum.ENABLE.getCode() : item.getState()); + entity.setCreateBy(StrUtil.trim(item.getCreateBy())); + entity.setUpdateBy(StrUtil.trim(item.getUpdateBy())); + entity.setCreateTime(parseDateTime(item.getCreateTime())); + entity.setUpdateTime(parseDateTime(item.getUpdateTime())); + return entity; + } + + private LocalDateTime parseDateTime(String value) { + if (StrUtil.isBlank(value)) { + return null; + } + try { + return LocalDateTime.parse(StrUtil.trim(value)); + } catch (Exception ex) { + throw new BusinessException(PqdifResponseEnum.JSON_FORMAT_ERROR); + } + } +} diff --git a/detection/src/main/java/com/njcn/gather/pqdif/service/support/PqdifImportParser.java b/detection/src/main/java/com/njcn/gather/pqdif/service/support/PqdifImportParser.java new file mode 100644 index 00000000..c20e5dec --- /dev/null +++ b/detection/src/main/java/com/njcn/gather/pqdif/service/support/PqdifImportParser.java @@ -0,0 +1,52 @@ +package com.njcn.gather.pqdif.service.support; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.njcn.common.pojo.exception.BusinessException; +import com.njcn.gather.pqdif.pojo.enums.PqdifResponseEnum; +import com.njcn.gather.pqdif.pojo.param.PqPqdifPathParam; + +import java.util.ArrayList; +import java.util.List; + +public final class PqdifImportParser { + + private PqdifImportParser() { + } + + public static List parse(String content) { + try { + JSONArray jsonArray = JSON.parseArray(content); + if (jsonArray == null) { + throw new BusinessException(PqdifResponseEnum.JSON_FORMAT_ERROR); + } + List items = new ArrayList<>(); + for (int i = 0; i < jsonArray.size(); i++) { + JSONObject jsonObject = jsonArray.getJSONObject(i); + if (jsonObject == null) { + throw new BusinessException(PqdifResponseEnum.IMPORT_ITEM_NOT_NULL); + } + PqPqdifPathParam.ImportItem item = jsonObject.toJavaObject(PqPqdifPathParam.ImportItem.class); + Object msg = jsonObject.get("msg"); + item.setMsg(normalizeMsg(msg)); + items.add(item); + } + return items; + } catch (BusinessException ex) { + throw ex; + } catch (Exception ex) { + throw new BusinessException(PqdifResponseEnum.JSON_FORMAT_ERROR); + } + } + + private static String normalizeMsg(Object msg) { + if (msg == null) { + return null; + } + if (msg instanceof String) { + return (String) msg; + } + return JSON.toJSONString(msg); + } +} diff --git a/detection/src/main/java/com/njcn/gather/result/controller/ResultController.java b/detection/src/main/java/com/njcn/gather/result/controller/ResultController.java index f746796c..e6391de9 100644 --- a/detection/src/main/java/com/njcn/gather/result/controller/ResultController.java +++ b/detection/src/main/java/com/njcn/gather/result/controller/ResultController.java @@ -164,7 +164,7 @@ public class ResultController extends BaseController { } @OperateInfo(info = LogEnum.BUSINESS_COMMON) - @PostMapping("/createChecksquareTask") + @GetMapping("/createChecksquareTask") @ApiOperation("调用第三方数模数据检测接口") @ApiImplicitParam(name = "devId", value = "设备id", required = true) public HttpResult createChecksquareTask(@RequestParam("devId") String devId) { diff --git a/detection/src/main/java/com/njcn/gather/result/service/impl/ResultServiceImpl.java b/detection/src/main/java/com/njcn/gather/result/service/impl/ResultServiceImpl.java index 180e9206..6602ee52 100644 --- a/detection/src/main/java/com/njcn/gather/result/service/impl/ResultServiceImpl.java +++ b/detection/src/main/java/com/njcn/gather/result/service/impl/ResultServiceImpl.java @@ -206,19 +206,23 @@ public class ResultServiceImpl implements IResultService { throw new BusinessException(CommonResponseEnum.FAIL, "该设备监测点不存在"); } - PqDevSub devSub = pqDevSubService.getOne(new LambdaQueryWrapper() - .eq(PqDevSub::getDevId, devId), false); - if (ObjectUtil.isNull(devSub) - || ObjectUtil.isNull(devSub.getCheckStartTime()) - || ObjectUtil.isNull(devSub.getCheckEndTime())) { - throw new BusinessException(CommonResponseEnum.FAIL, "该设备检测开始时间或结束时间为空"); - } +// PqDevSub devSub = pqDevSubService.getOne(new LambdaQueryWrapper() +// .eq(PqDevSub::getDevId, devId), false); +// if (ObjectUtil.isNull(devSub) +// || ObjectUtil.isNull(devSub.getCheckStartTime()) +// || ObjectUtil.isNull(devSub.getCheckEndTime())) { +// throw new BusinessException(CommonResponseEnum.FAIL, "该设备检测开始时间或结束时间为空"); +// } DataCheckRequest request = new DataCheckRequest(); - request.setLineIds(monitorList.stream().map(PqMonitor::getId).collect(Collectors.toList())); +// request.setLineIds(monitorList.stream().map(PqMonitor::getId).collect(Collectors.toList())); +// request.setIndicatorCodes(Collections.emptyList()); +// request.setTimeStart(CHECKSQUARE_TIME_FORMATTER.format(devSub.getCheckStartTime())); +// request.setTimeEnd(CHECKSQUARE_TIME_FORMATTER.format(devSub.getCheckEndTime())); + request.setLineIds(Arrays.asList("ee9a33337bfd4d5588c00a2dbef6bc7e")); request.setIndicatorCodes(Collections.emptyList()); - request.setTimeStart(CHECKSQUARE_TIME_FORMATTER.format(devSub.getCheckStartTime())); - request.setTimeEnd(CHECKSQUARE_TIME_FORMATTER.format(devSub.getCheckEndTime())); + request.setTimeStart("2026-05-22 09:00:00"); + request.setTimeEnd("2026-05-22 12:00:00"); return restTemplateUtil.postJson(CHECKSQUARE_CREATE_URL, request, String.class); } diff --git a/detection/src/main/java/com/njcn/gather/type/pojo/param/DevTypeParam.java b/detection/src/main/java/com/njcn/gather/type/pojo/param/DevTypeParam.java index 6d1d1895..3f411603 100644 --- a/detection/src/main/java/com/njcn/gather/type/pojo/param/DevTypeParam.java +++ b/detection/src/main/java/com/njcn/gather/type/pojo/param/DevTypeParam.java @@ -27,6 +27,11 @@ public class DevTypeParam { @NotBlank(message = DetectionValidMessage.ICD_NOT_BLANK) private String icd; + @ApiModelProperty(value = "设备关联的PQDIF", required = true) + @NotBlank(message = "PQDIF不能为空") + @Pattern(regexp = PatternRegex.SYSTEM_ID, message = DetectionValidMessage.ID_FORMAT_ERROR) + private String pqdif; + @ApiModelProperty(value = "工作电源", required = true) @NotBlank(message = DetectionValidMessage.POWER_NOT_BLANK) private String power; diff --git a/detection/src/main/java/com/njcn/gather/type/pojo/po/DevType.java b/detection/src/main/java/com/njcn/gather/type/pojo/po/DevType.java index 78d3c4db..199ed80d 100644 --- a/detection/src/main/java/com/njcn/gather/type/pojo/po/DevType.java +++ b/detection/src/main/java/com/njcn/gather/type/pojo/po/DevType.java @@ -37,6 +37,8 @@ public class DevType extends BaseEntity { /** * 工作电源 */ + private String pqdif; + private String power; /** diff --git a/detection/src/main/java/com/njcn/gather/type/service/impl/DevTypeServiceImpl.java b/detection/src/main/java/com/njcn/gather/type/service/impl/DevTypeServiceImpl.java index f1973f7f..bab9f2f3 100644 --- a/detection/src/main/java/com/njcn/gather/type/service/impl/DevTypeServiceImpl.java +++ b/detection/src/main/java/com/njcn/gather/type/service/impl/DevTypeServiceImpl.java @@ -7,6 +7,8 @@ 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.gather.pqdif.pojo.po.PqPqdifPath; +import com.njcn.gather.pqdif.service.IPqPqdifPathService; import com.njcn.gather.pojo.enums.DetectionResponseEnum; import com.njcn.gather.system.dictionary.pojo.po.DictData; import com.njcn.gather.system.dictionary.service.IDictDataService; @@ -36,6 +38,9 @@ public class DevTypeServiceImpl extends ServiceImpl impl @Resource private IDictDataService dictDataService; + @Resource + private IPqPqdifPathService pqPqdifPathService; + @Override public List listAll() { @@ -76,6 +81,7 @@ public class DevTypeServiceImpl extends ServiceImpl impl public boolean addDevType(DevTypeParam addParam) { addParam.setName(addParam.getName().trim()); this.checkRepeat(addParam, false); + this.checkPqdif(addParam.getPqdif()); DevType devType = new DevType(); BeanUtil.copyProperties(addParam, devType); devType.setState(DataStateEnum.ENABLE.getCode()); @@ -87,6 +93,7 @@ public class DevTypeServiceImpl extends ServiceImpl impl public boolean updateDevType(DevTypeParam.UpdateParam updateParam) { updateParam.setName(updateParam.getName().trim()); this.checkRepeat(updateParam, true); + this.checkPqdif(updateParam.getPqdif()); DevType devType = new DevType(); BeanUtil.copyProperties(updateParam, devType); return this.updateById(devType); @@ -121,4 +128,14 @@ public class DevTypeServiceImpl extends ServiceImpl impl throw new BusinessException(DetectionResponseEnum.DEV_TYPE_NAME_REPEAT); } } + + private void checkPqdif(String pqdifId) { + PqPqdifPath pqdif = pqPqdifPathService.lambdaQuery() + .eq(PqPqdifPath::getId, pqdifId) + .eq(PqPqdifPath::getState, DataStateEnum.ENABLE.getCode()) + .one(); + if (Objects.isNull(pqdif)) { + throw new BusinessException(DetectionResponseEnum.PQDIF_NOT_EXIST); + } + } } diff --git a/detection/src/test/java/com/njcn/gather/source/pojo/PqSourceCapacityFieldsTest.java b/detection/src/test/java/com/njcn/gather/source/pojo/PqSourceCapacityFieldsTest.java deleted file mode 100644 index d83698af..00000000 --- a/detection/src/test/java/com/njcn/gather/source/pojo/PqSourceCapacityFieldsTest.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.njcn.gather.source.pojo; - -import cn.hutool.core.bean.BeanUtil; -import com.baomidou.mybatisplus.annotation.TableField; -import com.njcn.gather.source.pojo.param.PqSourceParam; -import com.njcn.gather.source.pojo.po.PqSource; -import org.junit.Assert; -import org.junit.Test; - -import javax.validation.Validation; -import javax.validation.Validator; -import javax.validation.constraints.DecimalMin; -import java.lang.reflect.Field; -import java.math.BigDecimal; - -public class PqSourceCapacityFieldsTest { - - private final Validator validator = Validation.buildDefaultValidatorFactory().getValidator(); - - @Test - public void shouldExposeExplicitCapacityColumnMappings() throws Exception { - Field maxVoltage = PqSource.class.getDeclaredField("maxVoltage"); - Field maxCurrent = PqSource.class.getDeclaredField("maxCurrent"); - - Assert.assertEquals("Max_Voltage", maxVoltage.getAnnotation(TableField.class).value()); - Assert.assertEquals("Max_Current", maxCurrent.getAnnotation(TableField.class).value()); - } - - @Test - public void shouldExposeNonNegativeCapacityValidation() throws Exception { - Field maxVoltage = PqSourceParam.class.getDeclaredField("maxVoltage"); - Field maxCurrent = PqSourceParam.class.getDeclaredField("maxCurrent"); - - Assert.assertEquals("0", maxVoltage.getAnnotation(DecimalMin.class).value()); - Assert.assertEquals("0", maxCurrent.getAnnotation(DecimalMin.class).value()); - - PqSourceParam.UpdateParam param = new PqSourceParam.UpdateParam(); - param.setId("12345678901234567890123456789012"); - param.setPattern("12345678901234567890123456789012"); - param.setType("12345678901234567890123456789012"); - param.setDevType("12345678901234567890123456789012"); - param.setMaxVoltage(new BigDecimal("-1")); - - Assert.assertFalse(validator.validate(param).isEmpty()); - } - - @Test - public void shouldCopyCapacityFieldsFromRequestToEntity() { - PqSourceParam.UpdateParam param = new PqSourceParam.UpdateParam(); - param.setMaxVoltage(new BigDecimal("220.00")); - param.setMaxCurrent(new BigDecimal("5.00")); - - PqSource source = new PqSource(); - BeanUtil.copyProperties(param, source); - - Assert.assertEquals(new BigDecimal("220.00"), source.getMaxVoltage()); - Assert.assertEquals(new BigDecimal("5.00"), source.getMaxCurrent()); - } -} diff --git a/entrance/src/main/resources/application.yml b/entrance/src/main/resources/application.yml index 6c3c34c6..8e7d55d9 100644 --- a/entrance/src/main/resources/application.yml +++ b/entrance/src/main/resources/application.yml @@ -3,13 +3,16 @@ server: spring: application: name: entrance + redis: + host: localhost + port: 16379 datasource: druid: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://192.168.1.24:13306/pqs9100?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true -# username: root -# password: njcnpqs -# url: jdbc:mysql://127.0.0.1:3306/pqs9100?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true + # username: root + # password: njcnpqs + # url: jdbc:mysql://127.0.0.1:3306/pqs9100?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true username: root password: njcnpqs #初始化建立物理连接的个数、最小、最大连接数 @@ -67,8 +70,8 @@ sntp: port: 123 Dip: -# 暂态前时间(s) -# fPreTime: 2f + # 暂态前时间(s) + # fPreTime: 2f #写入时间(s) fRampIn: 0.001f #写出时间(s) @@ -86,8 +89,8 @@ Dip: # homeDir: D:\logs # commonLevel: info report: -# template: D:\template -# reportDir: D:\report + # template: D:\template + # reportDir: D:\report dateFormat: yyyy年MM月dd日 #data: # homeDir: D:\data @@ -133,4 +136,4 @@ activate: public-key: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnFMmIVanMxsW5S/qP8Wcxf/J3/i4631BP3UtWkRzO7jAw9HIAgK4Y7X53hXj6zMbfme1vMjQc0mq7m/KrH4WlTYpFexLO6Gnk8oH40F04tp+ABZIq93zNOydPEaVoZeTPH/LlkwrrxVGAMNNIKuebcqapp25JiWtlSFMv4kH/nDAj+2m8+P4zYVM1Ed6gO01eKDEYE3SBA1Ket2BfHTgviR/F8WKwlXh11enywsJnrHTM5dJQdlUxCjHy214TpheYOz/cv9elQnDfFAbmZW8mH5/hgMSTkm3h4uR7ITin6Erg+yc/t1kGaTWrzloyBRMSiFN/Pwr5yQjj+1wQqqUkwIDAQAB" dataCheck: - enable: true \ No newline at end of file + enable: false \ No newline at end of file diff --git a/entrance/src/test/java/com/njcn/AnalysisServiceStreamTest.java b/entrance/src/test/java/com/njcn/AnalysisServiceStreamTest.java deleted file mode 100644 index 8879ca23..00000000 --- a/entrance/src/test/java/com/njcn/AnalysisServiceStreamTest.java +++ /dev/null @@ -1,170 +0,0 @@ -package com.njcn; - -import com.njcn.gather.tools.comtrade.comparewave.core.model.CompareWaveDTO; -import com.njcn.gather.tools.comtrade.comparewave.service.ICompareWaveService; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; - - -/** - * 流式文件分析测试 - * 测试从本地文件读取并转换为流进行分析 - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = com.njcn.gather.EntranceApplication.class) -public class AnalysisServiceStreamTest { - - @Autowired - private ICompareWaveService compareWaveServiceImpl; - - // 测试文件路径 - 请根据实际情况修改 - private static final String SOURCE_CFG_PATH = "C:\\Users\\Administrator\\Desktop\\wave\\192.168.1.241\\PQ_PQLD2_000177_20251028_112422_833.cfg"; - private static final String SOURCE_DAT_PATH = "C:\\Users\\Administrator\\Desktop\\wave\\192.168.1.241\\PQ_PQLD2_000177_20251028_112422_833.dat"; - private static final String TARGET_CFG_PATH = "C:\\Users\\Administrator\\Desktop\\wave\\192.168.1.242\\PQ_PQLD2_000238_20251028_112422_518.cfg"; - private static final String TARGET_DAT_PATH = "C:\\Users\\Administrator\\Desktop\\wave\\192.168.1.242\\PQ_PQLD2_000238_20251028_112422_518.dat"; - - -// private static final String SOURCE_CFG_PATH = "F:\\hatch\\wavecompare\\数据比对\\统计数据1\\B码\\217\\PQMonitor_PQM1_000006_20200430_115517_889.cfg"; -// private static final String SOURCE_DAT_PATH = "F:\\hatch\\wavecompare\\数据比对\\统计数据1\\B码\\217\\PQMonitor_PQM1_000006_20200430_115517_889.dat"; -// private static final String TARGET_CFG_PATH = "F:\\hatch\\wavecompare\\数据比对\\统计数据1\\B码\\216\\PQMonitor_PQM1_000006_20200430_115515_479.cfg"; -// private static final String TARGET_DAT_PATH = "F:\\hatch\\wavecompare\\数据比对\\统计数据1\\B码\\216\\PQMonitor_PQM1_000006_20200430_115515_479.dat"; - - // 输出路径 - private static final String OUTPUT_PATH = "./test-output/"; - - /** - * 测试使用文件流进行电能质量分析 - */ - @Test - public void testAnalyzeWithStreams() throws Exception { - System.out.println("========================================"); - System.out.println("开始测试流式文件分析"); - System.out.println("========================================"); - - // 验证文件是否存在 - checkFileExists(SOURCE_CFG_PATH, "源CFG文件"); - checkFileExists(SOURCE_DAT_PATH, "源DAT文件"); - checkFileExists(TARGET_CFG_PATH, "目标CFG文件"); - checkFileExists(TARGET_DAT_PATH, "目标DAT文件"); - - // 读取本地文件并创建输入流 - try (InputStream sourceCfgStream = new FileInputStream(SOURCE_CFG_PATH); - InputStream sourceDatStream = new FileInputStream(SOURCE_DAT_PATH); - InputStream targetCfgStream = new FileInputStream(TARGET_CFG_PATH); - InputStream targetDatStream = new FileInputStream(TARGET_DAT_PATH)) { - - System.out.println("成功创建文件输入流"); - System.out.println("源CFG文件: " + SOURCE_CFG_PATH); - System.out.println("源DAT文件: " + SOURCE_DAT_PATH); - System.out.println("目标CFG文件: " + TARGET_CFG_PATH); - System.out.println("目标DAT文件: " + TARGET_DAT_PATH); - System.out.println("输出路径: " + OUTPUT_PATH); - - // 创建输出目录 - File outputDir = new File(OUTPUT_PATH); - if (!outputDir.exists()) { - outputDir.mkdirs(); - System.out.println("创建输出目录: " + outputDir.getAbsolutePath()); - } - - // 执行分析,使用星型接线方式(0) - System.out.println("\n开始执行电能质量分析(星型接线)..."); - long startTime = System.currentTimeMillis(); - - CompareWaveDTO result = compareWaveServiceImpl.analyzeAndCompareWithStreams( - sourceCfgStream, - sourceDatStream, - targetCfgStream, - targetDatStream, - // 接线方式: 0=星型接线, 1=V型接线 - 0 - ); - - long endTime = System.currentTimeMillis(); - long duration = endTime - startTime; - - // 输出分析结果 - System.out.println("========================================"); - System.out.println("分析完成!"); - System.out.println("总耗时: " + duration + " ms (" + String.format("%.2f", duration / 1000.0) + " 秒)"); - - - - - System.out.println("========================================"); - System.out.println("流式文件分析测试完成!"); - System.out.println("========================================"); - - } - } - - /** - * 测试段信息保留模式的波形分析(新方法) - *

不进行跨段的统一降采样,保留每个段的原始采样率(超过512才降到256)

- *

跨段的窗口会被丢弃,只计算不跨段的窗口

- */ - @Test - public void testAnalyzeWithSegmentPreservation() throws Exception { - System.out.println("========================================"); - System.out.println("开始执行电能质量分析(段信息保留模式)..."); - System.out.println("========================================"); - - // 检查文件是否存在 - checkFileExists(SOURCE_CFG_PATH, "源CFG文件"); - checkFileExists(SOURCE_DAT_PATH, "源DAT文件"); - checkFileExists(TARGET_CFG_PATH, "目标CFG文件"); - checkFileExists(TARGET_DAT_PATH, "目标DAT文件"); - - long startTime = System.currentTimeMillis(); - - try (InputStream sourceCfgStream = new FileInputStream(SOURCE_CFG_PATH); - InputStream sourceDatStream = new FileInputStream(SOURCE_DAT_PATH); - InputStream targetCfgStream = new FileInputStream(TARGET_CFG_PATH); - InputStream targetDatStream = new FileInputStream(TARGET_DAT_PATH)) { - - CompareWaveDTO result = compareWaveServiceImpl.analyzeWithSegmentPreservation( - sourceCfgStream, - sourceDatStream, - targetCfgStream, - targetDatStream, - 0 // 接线方式: 0=星型接线, 1=V型接线 - ); - - long endTime = System.currentTimeMillis(); - long duration = endTime - startTime; - - // 输出分析结果 - System.out.println("========================================"); - System.out.println("分析完成!"); - System.out.println("总耗时: " + duration + " ms (" + String.format("%.2f", duration / 1000.0) + " 秒)"); - System.out.println("源文件有效窗口数: " + (result.getSourceResults() != null ? result.getSourceResults().size() : 0)); - System.out.println("目标文件有效窗口数: " + (result.getTargetResults() != null ? result.getTargetResults().size() : 0)); - System.out.println("========================================"); - System.out.println("段信息保留模式测试完成!"); - System.out.println("========================================"); - - } - } - - /** - * 检查文件是否存在 - */ - private void checkFileExists(String filePath, String description) { - File file = new File(filePath); - if (!file.exists()) { - System.err.println("警告: " + description + " 不存在: " + filePath); - System.err.println("请确保文件路径正确,或修改测试中的文件路径"); - } else { - System.out.println(description + " 存在: " + filePath); - System.out.println(" 文件大小: " + file.length() + " bytes"); - } - } - -} \ No newline at end of file diff --git a/entrance/src/test/java/com/njcn/BaseJunitTest.java b/entrance/src/test/java/com/njcn/BaseJunitTest.java deleted file mode 100644 index 0193eb2b..00000000 --- a/entrance/src/test/java/com/njcn/BaseJunitTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.njcn; - -import com.njcn.gather.EntranceApplication; -import com.njcn.gather.report.service.IPqReportService; -import com.njcn.http.util.RestTemplateUtil; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.http.ResponseEntity; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.context.web.WebAppConfiguration; - -import java.io.File; - - -/** - * @author hongawen - * @version 1.0.0 - * @date 2021年12月10日 15:05 - */ -@RunWith(SpringRunner.class) -@WebAppConfiguration -@SpringBootTest(classes = EntranceApplication.class) -public class BaseJunitTest { - - @Autowired - private IPqReportService pqReportService; - - @Autowired - private RestTemplateUtil restTemplateUtil; - - @Test - public void test() { - File file = new File("D:\\report\\PQS_882B4\\5555.docx"); - - try{ - ResponseEntity stringResponseEntity = restTemplateUtil.uploadFile("http://localhost:18082/api/file/upload",file); - }catch (Exception runtimeException){ - System.out.println(runtimeException.getMessage()); - } - } - -} diff --git a/entrance/src/test/java/com/njcn/DynamicTableTest.java b/entrance/src/test/java/com/njcn/DynamicTableTest.java deleted file mode 100644 index 7edc6ece..00000000 --- a/entrance/src/test/java/com/njcn/DynamicTableTest.java +++ /dev/null @@ -1,175 +0,0 @@ -package com.njcn; - -import com.njcn.gather.tools.report.util.Docx4jUtil; -import org.docx4j.openpackaging.packages.WordprocessingMLPackage; -import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart; -import org.docx4j.wml.ObjectFactory; -import org.docx4j.wml.P; -import org.docx4j.wml.Tbl; - -import javax.xml.bind.JAXBElement; -import java.io.File; -import java.util.Arrays; -import java.util.List; - -/** - * 动态表格生成测试 - * - * @author hongawen - * @version 1.0 - * @date 2025/9/21 - */ -public class DynamicTableTest { - - public static void main(String[] args) { - try { - // 测试场景1:2个回路,7个检测项目(与result.png一致) - testScenario1(); - - // 测试场景2:1个回路,只检测电压和频率 - testScenario2(); - - // 测试场景3:4个回路,多个检测项目 - testScenario3(); - - System.out.println("所有测试场景执行完成!"); - - } catch (Exception e) { - e.printStackTrace(); - } - } - - /** - * 测试场景1:2个回路,7个检测项目(模拟result.png的数据) - */ - public static void testScenario1() throws Exception { - System.out.println("=== 测试场景1:2个回路,7个检测项目 ==="); - - // 创建Word文档 - WordprocessingMLPackage wordPackage = WordprocessingMLPackage.createPackage(); - MainDocumentPart mainDocumentPart = wordPackage.getMainDocumentPart(); - ObjectFactory factory = new ObjectFactory(); - - // 1. 添加标题 - P titleP = factory.createP(); - Docx4jUtil.createTitle(factory, titleP, "检测结果(场景1:2回路7项目)", 32, true); - mainDocumentPart.getContent().add(titleP); - - // 2. 检测项目配置 - List testItems = Arrays.asList( - "电压", - "电压不平衡度", - "电流不平衡度", - "谐波电压", - "谐波电流", - "间谐波电压", - "短时间闪变" - ); - - // 3. 检测结果数据(模拟result.png中的数据) - String[][] testResults = { - {"不合格", "不合格"}, // 电压 - {"无法比较", "无法比较"}, // 电压不平衡度 - {"合格", "合格"}, // 电流不平衡度 - {"合格", "合格"}, // 谐波电压 - {"合格", "合格"}, // 谐波电流 - {"不合格", "不合格"}, // 间谐波电压 - {"无法比较", "无法比较"} // 短时间闪变 - }; - - // 4. 定义回路名称 - List circuitNames = Arrays.asList("测量回路 1", "测量回路 2"); - - // 5. 生成动态表格(包含说明内容) - JAXBElement table = Docx4jUtil.createDynamicTestResultTable( - factory, testItems, circuitNames, testResults, "不合格", - "部分值", "200", "去除最大最小值"); - mainDocumentPart.getContent().add(table); - - // 6. 保存文档 - File outputFile = new File("检测结果_场景1_2回路7项目.docx"); - wordPackage.save(outputFile); - System.out.println("文档已保存:" + outputFile.getAbsolutePath()); - } - - /** - * 测试场景2:1个回路,只检测电压和频率 - */ - public static void testScenario2() throws Exception { - System.out.println("=== 测试场景2:1个回路,2个检测项目 ==="); - - WordprocessingMLPackage wordPackage = WordprocessingMLPackage.createPackage(); - MainDocumentPart mainDocumentPart = wordPackage.getMainDocumentPart(); - ObjectFactory factory = new ObjectFactory(); - - // 标题 - P titleP = factory.createP(); - Docx4jUtil.createTitle(factory, titleP, "检测结果(场景2:1回路2项目)", 32, true); - mainDocumentPart.getContent().add(titleP); - - // 简单的检测项目 - List testItems = Arrays.asList("电压", "频率"); - - // 1个回路的检测结果 - String[][] testResults = { - {"不合格"}, // 电压 - {"合格"} // 频率 - }; - - // 定义回路名称 - List circuitNames = Arrays.asList("#1母线"); - - // 生成表格(包含说明内容) - JAXBElement table = Docx4jUtil.createDynamicTestResultTable( - factory, testItems, circuitNames, testResults, "不合格", - "任意值", "100", "取第一个满足条件的数据"); - mainDocumentPart.getContent().add(table); - - File outputFile = new File("检测结果_场景2_1回路2项目.docx"); - wordPackage.save(outputFile); - System.out.println("文档已保存:" + outputFile.getAbsolutePath()); - } - - /** - * 测试场景3:4个回路,多个检测项目 - */ - public static void testScenario3() throws Exception { - System.out.println("=== 测试场景3:4个回路,5个检测项目 ==="); - - WordprocessingMLPackage wordPackage = WordprocessingMLPackage.createPackage(); - MainDocumentPart mainDocumentPart = wordPackage.getMainDocumentPart(); - ObjectFactory factory = new ObjectFactory(); - - // 标题 - P titleP = factory.createP(); - Docx4jUtil.createTitle(factory, titleP, "检测结果(场景3:4回路5项目)", 32, true); - mainDocumentPart.getContent().add(titleP); - - // 检测项目 - List testItems = Arrays.asList( - "电压", "频率", "电压不平衡度", "谐波电压", "间谐波电压" - ); - - // 4个回路的检测结果 - String[][] testResults = { - {"不合格", "合格", "合格", "不合格"}, // 电压 - {"合格", "合格", "合格", "合格"}, // 频率 - {"无法比较", "无法比较", "合格", "合格"}, // 电压不平衡度 - {"合格", "不合格", "合格", "合格"}, // 谐波电压 - {"不合格", "不合格", "不合格", "合格"} // 间谐波电压 - }; - - // 定义回路名称(自定义名称示例) - List circuitNames = Arrays.asList("主变高压侧", "主变低压侧", "备用线路1", "备用线路2"); - - // 生成表格(包含说明内容) - JAXBElement table = Docx4jUtil.createDynamicTestResultTable( - factory, testItems, circuitNames, testResults, "不合格", - "平均值", "300", "取算术平均值"); - mainDocumentPart.getContent().add(table); - - File outputFile = new File("检测结果_场景3_4回路5项目.docx"); - wordPackage.save(outputFile); - System.out.println("文档已保存:" + outputFile.getAbsolutePath()); - } -} \ No newline at end of file diff --git a/entrance/src/test/java/com/njcn/ResultChecksquareCreateTest.java b/entrance/src/test/java/com/njcn/ResultChecksquareCreateTest.java deleted file mode 100644 index 60461f51..00000000 --- a/entrance/src/test/java/com/njcn/ResultChecksquareCreateTest.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.njcn; - -import com.njcn.gather.device.pojo.po.PqDevSub; -import com.njcn.gather.device.service.IPqDevSubService; -import com.njcn.gather.monitor.pojo.po.PqMonitor; -import com.njcn.gather.monitor.service.IPqMonitorService; -import com.njcn.gather.result.pojo.param.DataCheckRequest; -import com.njcn.gather.result.service.impl.ResultServiceImpl; -import com.njcn.http.util.RestTemplateUtil; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; - -import java.time.LocalDateTime; -import java.util.Arrays; -import java.util.Collections; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; - -@RunWith(MockitoJUnitRunner.class) -public class ResultChecksquareCreateTest { - - @Mock - private IPqMonitorService pqMonitorService; - @Mock - private IPqDevSubService pqDevSubService; - @Mock - private RestTemplateUtil restTemplateUtil; - - @Test - public void createChecksquareTaskByDevIdBuildsRequestAndReturnsThirdPartyResponse() { - String devId = "dev-1"; - PqMonitor monitor1 = new PqMonitor(); - monitor1.setId("line-1"); - PqMonitor monitor2 = new PqMonitor(); - monitor2.setId("line-2"); - PqDevSub devSub = new PqDevSub(); - devSub.setCheckStartTime(LocalDateTime.of(2026, 6, 22, 10, 1, 2)); - devSub.setCheckEndTime(LocalDateTime.of(2026, 6, 22, 11, 3, 4)); - - when(pqMonitorService.listPqMonitorByDevIds(Collections.singletonList(devId))).thenReturn(Arrays.asList(monitor1, monitor2)); - when(pqDevSubService.getOne(any(), eq(false))).thenReturn(devSub); - ArgumentCaptor requestCaptor = ArgumentCaptor.forClass(DataCheckRequest.class); - when(restTemplateUtil.postJson(eq(ResultServiceImpl.CHECKSQUARE_CREATE_URL), requestCaptor.capture(), eq(String.class))) - .thenReturn("{\"code\":0}"); - - ResultServiceImpl resultService = new ResultServiceImpl(null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, pqMonitorService, null, null, - pqDevSubService, null, restTemplateUtil); - - String response = resultService.createChecksquareTaskByDevId(devId); - - DataCheckRequest request = requestCaptor.getValue(); - assertEquals("{\"code\":0}", response); - assertEquals(Arrays.asList("line-1", "line-2"), request.getLineIds()); - assertTrue(request.getIndicatorCodes().isEmpty()); - assertEquals("2026-06-22 10:01:02", request.getTimeStart()); - assertEquals("2026-06-22 11:03:04", request.getTimeEnd()); - } -} diff --git a/entrance/src/test/java/com/njcn/ResultServiceImplTest.java b/entrance/src/test/java/com/njcn/ResultServiceImplTest.java deleted file mode 100644 index 393f3baf..00000000 --- a/entrance/src/test/java/com/njcn/ResultServiceImplTest.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.njcn; - -import com.alibaba.fastjson.JSON; -import com.njcn.gather.detection.pojo.vo.DetectionData; -import com.njcn.gather.device.pojo.vo.PqDevVO; -import com.njcn.gather.device.service.IPqDevService; -import com.njcn.gather.device.service.impl.PqDevServiceImpl; -import com.njcn.gather.report.pojo.DevReportParam; -import com.njcn.gather.report.pojo.result.ContrastTestResult; -import com.njcn.gather.report.service.IPqReportService; -import com.njcn.gather.result.pojo.vo.MonitorResultVO; -import com.njcn.gather.result.service.impl.ResultServiceImpl; -import com.njcn.gather.storage.pojo.po.ContrastHarmonicResult; -import com.njcn.gather.system.dictionary.pojo.po.DictTree; -import lombok.extern.slf4j.Slf4j; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import static org.junit.Assert.*; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.when; - -/** - * ResultServiceImpl 测试类 - * 专门测试 getContrastResultHarm 方法 - * - * @author test - * @date 2025-01-18 - */ -@Slf4j -@RunWith(SpringRunner.class) -@SpringBootTest(classes = com.njcn.gather.EntranceApplication.class) -public class ResultServiceImplTest extends BaseJunitTest { - - @Autowired - private ResultServiceImpl resultService; - - @Autowired - private IPqDevService pqDevService; - - @Autowired - private IPqReportService pqReportService; - - /** - * 测试 getContrastResultHarm 方法 - 正常情况,所有数据合格 - */ - @Test - public void testGetContrastResultHarm_AllQualified() throws Exception { - log.info("==================== 开始测试:所有数据合格场景 ===================="); - - // 准备测试数据 - DevReportParam devReportParam = new DevReportParam(); - devReportParam.setPlanId("307a4b57abe84746acec5fd62f58e789"); - devReportParam.setPlanCode("1"); - devReportParam.setDevId("11b1a3cadafd4d51986d5c88815c2ece"); - devReportParam.setDevIdList(Collections.singletonList(devReportParam.getDevId())); -// PqDevVO pqDevVO = pqDevService.getPqDevById(devReportParam.getDevId()); -// Map> contrastResultHarm = resultService.getContrastResultForReport(devReportParam, pqDevVO); - - - pqReportService.generateReport(devReportParam); - System.out.println(1); - System.out.println(1); - System.out.println(1); - } - - -} \ No newline at end of file diff --git a/entrance/src/test/java/com/njcn/gather/detection/lock/DetectionLockManagerTest.java b/entrance/src/test/java/com/njcn/gather/detection/lock/DetectionLockManagerTest.java deleted file mode 100644 index 97b8891e..00000000 --- a/entrance/src/test/java/com/njcn/gather/detection/lock/DetectionLockManagerTest.java +++ /dev/null @@ -1,151 +0,0 @@ -package com.njcn.gather.detection.lock; - -import org.junit.Before; -import org.junit.Test; - -import java.lang.reflect.Field; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; - -import static org.junit.Assert.*; - -public class DetectionLockManagerTest { - - private DetectionLockManager manager; - - @Before - public void setUp() throws Exception { - manager = DetectionLockManager.getInstance(); - // 通过反射把 current 清零,避免不同测试方法间状态污染 - Field f = DetectionLockManager.class.getDeclaredField("current"); - f.setAccessible(true); - ((AtomicReference) f.get(manager)).set(null); - } - - @Test - public void tryAcquire_whenEmpty_returnsOk() { - DetectionLockManager.AcquireResult r = manager.tryAcquire("u1", "alice", "page-1"); - assertTrue(r.isOk()); - assertNull(r.getHolder()); - assertEquals("u1", manager.getCurrent().getUserId()); - } - - @Test - public void tryAcquire_whenHeldByOther_returnsBusyWithHolder() { - manager.tryAcquire("u1", "alice", "page-1"); - DetectionLockManager.AcquireResult r = manager.tryAcquire("u2", "bob", "page-2"); - assertFalse(r.isOk()); - assertNotNull(r.getHolder()); - assertEquals("u1", r.getHolder().getHolderUserId()); - assertEquals("alice", r.getHolder().getHolderUserName()); - } - - @Test - public void tryAcquire_reentrantSameUser_refreshesPageAndExpireAt() throws Exception { - manager.tryAcquire("u1", "alice", "page-1"); - long oldAcquire = manager.getCurrent().getAcquireTime(); - long oldExpire = manager.getCurrent().getExpireAt(); - // sleep 50ms(远超 Windows 系统时钟 ~15ms 精度),保证时间戳推进 - Thread.sleep(50); - DetectionLockManager.AcquireResult r = manager.tryAcquire("u1", "alice", "page-2"); - assertTrue(r.isOk()); - assertEquals("page-2", manager.getCurrent().getUserPageId()); - assertTrue("acquireTime 应推进", manager.getCurrent().getAcquireTime() > oldAcquire); - assertTrue("expireAt 应推进", manager.getCurrent().getExpireAt() > oldExpire); - } - - @Test - public void tryAcquire_whenExpired_anyUserCanAcquire() throws Exception { - // 直接构造一个 expireAt 在过去的 lock 写进去 - Field f = DetectionLockManager.class.getDeclaredField("current"); - f.setAccessible(true); - @SuppressWarnings("unchecked") - AtomicReference ref = (AtomicReference) f.get(manager); - long past = System.currentTimeMillis() - 1000; - ref.set(new DetectionLock("u1", "alice", "page-1", past - 1000, past)); - - DetectionLockManager.AcquireResult r = manager.tryAcquire("u2", "bob", "page-2"); - assertTrue(r.isOk()); - assertEquals("u2", manager.getCurrent().getUserId()); - } - - @Test - public void releaseIfHeldBy_matchingUser_clears() { - manager.tryAcquire("u1", "alice", "page-1"); - manager.releaseIfHeldBy("u1", "TEST"); - assertNull(manager.getCurrent()); - } - - @Test - public void releaseIfHeldBy_nonMatchingUser_isNoOp() { - manager.tryAcquire("u1", "alice", "page-1"); - manager.releaseIfHeldBy("u2", "TEST"); - assertNotNull(manager.getCurrent()); - assertEquals("u1", manager.getCurrent().getUserId()); - } - - @Test - public void releaseIfHeldBy_whenEmpty_isNoOp() { - manager.releaseIfHeldBy("u1", "TEST"); - assertNull(manager.getCurrent()); - } - - @Test - public void releaseIfMatchPage_matchingPage_clears() { - manager.tryAcquire("u1", "alice", "page-1"); - manager.releaseIfMatchPage("page-1", "TEST"); - assertNull(manager.getCurrent()); - } - - @Test - public void releaseIfMatchPage_nonMatchingPage_isNoOp() { - manager.tryAcquire("u1", "alice", "page-1"); - manager.releaseIfMatchPage("page-2", "TEST"); - assertNotNull(manager.getCurrent()); - } - - @Test - public void forceRelease_alwaysClears() { - manager.tryAcquire("u1", "alice", "page-1"); - manager.forceRelease("admin", "TEST"); - assertNull(manager.getCurrent()); - } - - @Test - public void concurrentTryAcquire_onlyOneWins() throws Exception { - int n = 100; - ExecutorService pool = Executors.newFixedThreadPool(16); - CountDownLatch start = new CountDownLatch(1); - CountDownLatch done = new CountDownLatch(n); - AtomicInteger okCount = new AtomicInteger(0); - // 记下胜出线程的 userId,便于断言 holder 身份与胜出者一致 - AtomicReference winnerUserId = new AtomicReference<>(null); - for (int i = 0; i < n; i++) { - final String uid = "u" + i; - pool.submit(() -> { - try { - start.await(); - DetectionLockManager.AcquireResult r = manager.tryAcquire(uid, uid, "page-" + uid); - if (r.isOk()) { - okCount.incrementAndGet(); - winnerUserId.set(uid); - } - } catch (InterruptedException ignored) { - } finally { - done.countDown(); - } - }); - } - start.countDown(); - done.await(5, TimeUnit.SECONDS); - pool.shutdownNow(); - assertEquals("100 个不同账号并发只能有 1 个抢到锁", 1, okCount.get()); - assertNotNull(manager.getCurrent()); - // 持锁者必须就是宣称 ok 的那个线程,不能是别人 - assertEquals("holder 身份必须等于胜出线程的 userId", winnerUserId.get(), manager.getCurrent().getUserId()); - } -} diff --git a/entrance/src/test/resources/logback-test.xml b/entrance/src/test/resources/logback-test.xml deleted file mode 100644 index 27583867..00000000 --- a/entrance/src/test/resources/logback-test.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - UTF-8 - - - - - - - - ${logHomeDir}/${log.projectName}/debug/debug.log - - - - - DEBUG - - ACCEPT - - DENY - - - - - - ${logHomeDir}/${log.projectName}/debug/debug.log.%d{yyyy-MM-dd}.%i.log - - 10MB - - ${log.maxHistory:-30} - - - - - - - - - - ${log.pattern} - - UTF-8 - - - - - - - INFO - ACCEPT - DENY - - - ${logHomeDir}/${log.projectName}/info/info.log - - - - ${logHomeDir}/${log.projectName}/info/info.log.%d{yyyy-MM-dd}.%i.log - - 10MB - ${log.maxHistory:-30} - - - - ${log.pattern} - - UTF-8 - - - - - - - - ${logHomeDir}/${log.projectName}/error/error.log - - - ERROR - ACCEPT - DENY - - - - ${logHomeDir}/${log.projectName}/error/error.log.%d{yyyy-MM-dd}.%i.log - - 10MB - ${log.maxHistory:-30} - - - - ${log.pattern} - - UTF-8 - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file