From 2a0367f1ff2666e3350e626d29ee31c16a109d8a Mon Sep 17 00:00:00 2001 From: chendaofei <857448963@qq.com> Date: Mon, 20 Oct 2025 16:24:36 +0800 Subject: [PATCH] =?UTF-8?q?1.=E5=8C=97=E4=BA=AC=E7=9F=AD=E4=BF=A1=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/LineServiceImpl.java | 2 + .../dataTransmit/dataSynchronization.java | 224 ++++++++++++++++++ .../controller/EventGateController.java | 43 +++- .../event/transientes/job/ScheduledEvent.java | 112 +++++++++ .../mapper/PqsEventDetailStatusMapper.java | 13 + .../event/transientes/pojo/dto/MsgDTO.java | 20 ++ .../transientes/pojo/dto/SmsResponseDTO.java | 31 +++ .../transientes/pojo/dto/SmsSendDTO.java | 42 ++++ .../pojo/po/PqsEventDetailStatusPO.java | 39 +++ .../service/impl/EventGateServiceImpl.java | 9 +- .../impl/LargeScreenCountServiceImpl.java | 13 +- .../event/transientes/utils/SmsUtils.java | 102 ++++++++ .../src/main/resources/application-dev.yml | 5 + .../src/main/resources/application-prod.yml | 5 + .../src/main/resources/application.yml | 5 +- 15 files changed, 658 insertions(+), 7 deletions(-) create mode 100644 event_smart/src/main/java/com/njcn/product/event/dataTransmit/dataSynchronization.java create mode 100644 event_smart/src/main/java/com/njcn/product/event/transientes/job/ScheduledEvent.java create mode 100644 event_smart/src/main/java/com/njcn/product/event/transientes/mapper/PqsEventDetailStatusMapper.java create mode 100644 event_smart/src/main/java/com/njcn/product/event/transientes/pojo/dto/MsgDTO.java create mode 100644 event_smart/src/main/java/com/njcn/product/event/transientes/pojo/dto/SmsResponseDTO.java create mode 100644 event_smart/src/main/java/com/njcn/product/event/transientes/pojo/dto/SmsSendDTO.java create mode 100644 event_smart/src/main/java/com/njcn/product/event/transientes/pojo/po/PqsEventDetailStatusPO.java create mode 100644 event_smart/src/main/java/com/njcn/product/event/transientes/utils/SmsUtils.java diff --git a/cn-terminal/src/main/java/com/njcn/product/terminal/mysqlTerminal/service/impl/LineServiceImpl.java b/cn-terminal/src/main/java/com/njcn/product/terminal/mysqlTerminal/service/impl/LineServiceImpl.java index 38be67c..d8bd896 100644 --- a/cn-terminal/src/main/java/com/njcn/product/terminal/mysqlTerminal/service/impl/LineServiceImpl.java +++ b/cn-terminal/src/main/java/com/njcn/product/terminal/mysqlTerminal/service/impl/LineServiceImpl.java @@ -266,6 +266,8 @@ public class LineServiceImpl extends ServiceImpl implements Li UserReportPO userReportPO = userReportPOMapper.selectById(lineDetail.getObjId()); if(Objects.nonNull(userReportPO)){ lineDetailDataVO.setObjName(userReportPO.getProjectName()); + }else { + lineDetailDataVO.setObjName("/"); } lineDetailDataVO.setId(lineDetail.getNum()); lineDetailDataVO.setPtType(TerminalUtils.ptType(lineDetail.getPtType())); diff --git a/event_smart/src/main/java/com/njcn/product/event/dataTransmit/dataSynchronization.java b/event_smart/src/main/java/com/njcn/product/event/dataTransmit/dataSynchronization.java new file mode 100644 index 0000000..d2038a5 --- /dev/null +++ b/event_smart/src/main/java/com/njcn/product/event/dataTransmit/dataSynchronization.java @@ -0,0 +1,224 @@ +package com.njcn.product.event.dataTransmit; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.DatePattern; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.njcn.product.event.transientes.mapper.PqsEventDetailStatusMapper; +import com.njcn.product.event.transientes.mapper.PqsEventdetailMapper; +import com.njcn.product.event.transientes.pojo.po.PqsEventDetailStatusPO; +import com.njcn.product.event.transientes.pojo.po.PqsEventdetail; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @Author: cdf + * @CreateTime: 2025-10-20 + * @Description: 暂降事件同步 + */ +@Service +@EnableScheduling +@Slf4j +@RequiredArgsConstructor +public class dataSynchronization { + + private final PqsEventdetailMapper pqsEventdetailMapper; + + private final PqsEventDetailStatusMapper pqsEventDetailStatusMapper; + + // 文件配置 + @Value("${business.wavePath}") + private String sourceWaveDir; + + @Value("${business.exportBaseDir}") + private String exportBaseDir; + + // 定时任务配置 + // 默认每2小时执行一次 + private String cronExpression = "0 0 */2 * * ?"; + + private volatile boolean isRunning = false; + + + + + /** + * 定时执行的同步任务 + */ + @Scheduled(cron = "${sag.sync.cronExpression}") + @Transactional + public void syncPqsEventdetails() { + // 防止任务并发执行 + if (isRunning) { + log.warn("同步任务正在执行中,跳过本次调度"); + return; + } + + try { + isRunning = true; + log.info("=== 开始暂降事件波形文件同步任务 ==="); + + // 初始化 + initialize(); + + // 同步最近N天的事件,因为存在事件补招,延迟的原因,采用大范围扫描 + LocalDateTime end = LocalDateTime.now(); + LocalDateTime start = end.minusHours(24); + syncEvents(start, end); + + log.info("=== 同步任务完成 ==="); + + } catch (Exception e) { + log.error("同步任务执行失败", e); + } finally { + isRunning = false; + } + } + + /** + * 初始化操作 + */ + private void initialize() throws Exception { + // 检查目录 + checkDirectories(); + + // 检查同步状态表 + checkSyncStatusTable(); + } + + /** + * 同步指定时间范围内的事件 + */ + public void syncEvents(LocalDateTime startTime, LocalDateTime endTime) throws Exception { + // 创建导出目录 + String startStr = startTime.format(DateTimeFormatter.ofPattern(DatePattern.PURE_DATETIME_PATTERN)); + String endStr = startTime.format(DateTimeFormatter.ofPattern(DatePattern.PURE_DATETIME_PATTERN)); + + String exportDirName = String.format("%s_%s.json", startStr,endStr); + Path exportDir = Paths.get(exportBaseDir, exportDirName); + Files.createDirectories(exportDir); + log.info("创建导出目录: " + exportDir.toAbsolutePath()); + + // 查询未同步的事件 + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + lambdaQueryWrapper.between(PqsEventdetail::getTimeid,startTime,endTime); + List unsyncedEvents = pqsEventdetailMapper.selectList(lambdaQueryWrapper); + log.info("查询到 " + unsyncedEvents.size() + " 个暂降事件"); + if(CollUtil.isEmpty(unsyncedEvents)){ + return ; + } + + // 查询已经存在记录的暂降事件 + LambdaQueryWrapper statusPOLambdaQueryWrapper = new LambdaQueryWrapper<>(); + statusPOLambdaQueryWrapper.between(PqsEventDetailStatusPO::getEventTime,startTime,endTime); + List hasList = pqsEventDetailStatusMapper.selectList(statusPOLambdaQueryWrapper); + log.info("查询到 " + hasList.size() + "条已存在记录事件"); + //波形文件失败的事件id + List waveFailEventDetailIds = hasList.stream().filter(it->it.getWaveFlag() == 0).map(PqsEventDetailStatusPO::getEventDetailId).collect(Collectors.toList()); + + + //排除已经成功的事件 + if(CollUtil.isNotEmpty(hasList)){ + List hasIds = hasList.stream().map(PqsEventDetailStatusPO::getEventDetailId).collect(Collectors.toList()); + unsyncedEvents = unsyncedEvents.stream().filter(it->!hasIds.contains(it.getEventdetailIndex())).collect(Collectors.toList()); + } + + //对为上传的事件进行上传操作 + + + + + + } + + /** + * 检查必要的目录是否存在 + */ + private void checkDirectories() throws IOException { + // 检查源目录 + Path sourceDir = Paths.get(sourceWaveDir); + if (!Files.exists(sourceDir)) { + throw new IOException("源波形文件目录不存在: " + sourceDir); + } + + // 检查导出基础目录 + Path exportDir = Paths.get(exportBaseDir); + if (!Files.exists(exportDir)) { + Files.createDirectories(exportDir); + log.info("创建导出基础目录: " + exportDir); + } + } + + /** + * 检查同步状态表是否存在 + */ + private void checkSyncStatusTable() { + + } + + /** + * 导出单个事件 + */ + private void exportSingleEvent(Path exportDir, PqsEventdetail event) throws Exception { + + } + + /** + * 生成事件信息文件 + */ + private void generateEventInfoFile(Path eventDir, PqsEventdetail event) throws Exception { + + } + + /** + * 生成同步报告 + */ + private void generateSyncReport(Path exportDir, int totalEvents, int successCount, int failureCount) throws Exception { + + } + + /** + * 更新事件同步状态 + */ + private void updateSyncStatus(PqsEventdetail event, int status, String errorMessage) { + + } + + + + /** + * 获取波形类型描述 + */ + private String getWaveTypeDesc(Integer waveType) { + if (waveType == null) return "未知"; + + switch (waveType) { + case 1: return "电压暂降"; + case 2: return "电压暂升"; + case 3: return "电压中断"; + case 4: return "电压波动"; + default: return "未知类型(" + waveType + ")"; + } + } + + /** + * 获取任务运行状态 + */ + public boolean isRunning() { + return isRunning; + } + +} diff --git a/event_smart/src/main/java/com/njcn/product/event/transientes/controller/EventGateController.java b/event_smart/src/main/java/com/njcn/product/event/transientes/controller/EventGateController.java index d75bc5f..56b83db 100644 --- a/event_smart/src/main/java/com/njcn/product/event/transientes/controller/EventGateController.java +++ b/event_smart/src/main/java/com/njcn/product/event/transientes/controller/EventGateController.java @@ -5,6 +5,7 @@ import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; +import cn.hutool.crypto.digest.SM3; import cn.hutool.json.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.njcn.common.pojo.annotation.OperateInfo; @@ -19,11 +20,15 @@ import com.njcn.product.event.devcie.pojo.po.PqsDeptsline; import com.njcn.product.event.devcie.service.PqsDeptslineService; import com.njcn.product.event.transientes.mapper.PqUserLedgerMapper; import com.njcn.product.event.transientes.mapper.PqUserLineAssMapper; +import com.njcn.product.event.transientes.pojo.dto.MsgDTO; +import com.njcn.product.event.transientes.pojo.dto.SmsResponseDTO; +import com.njcn.product.event.transientes.pojo.dto.SmsSendDTO; import com.njcn.product.event.transientes.pojo.param.MonitorTerminalParam; import com.njcn.product.event.transientes.pojo.param.SimulationMsgParam; import com.njcn.product.event.transientes.pojo.po.*; import com.njcn.product.event.transientes.service.*; import com.njcn.product.event.transientes.service.impl.MsgEventInfoServiceImpl; +import com.njcn.product.event.transientes.utils.SmsUtils; import com.njcn.product.event.transientes.websocket.WebSocketServer; import com.njcn.redis.utils.RedisUtil; import com.njcn.web.controller.BaseController; @@ -34,12 +39,15 @@ import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.*; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import org.springframework.web.client.RestTemplate; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -64,6 +72,7 @@ public class EventGateController extends BaseController { @Value("${SYS_TYPE_ZT}") private String sysTypeZt; + private final WebSocketServer webSocketServer; private final PqsDeptslineService pqsDeptslineService; @@ -84,6 +93,8 @@ public class EventGateController extends BaseController { private final RedisUtil redisUtil; + private final SmsUtils smsUtils; + @OperateInfo @GetMapping("/eventMsg") @@ -174,6 +185,7 @@ public class EventGateController extends BaseController { try { sendMessage(jsonObject); }catch (Exception e){ + e.printStackTrace(); log.error("短信组装发送失败!失败原因{}",e.getMessage()); } @@ -275,7 +287,7 @@ public class EventGateController extends BaseController { } - private void sendMessage(JSONObject jsonObject) throws Exception{ + private void sendMessage(JSONObject jsonObject){ Integer lineId = Integer.valueOf(jsonObject.get("lineid").toString()); List pqLineDept = pqsDeptslineService.lambdaQuery().eq(PqsDeptsline::getLineIndex, lineId).eq(PqsDeptsline::getSystype, sysTypeZt).list(); Set deptIds = pqLineDept.stream().map(PqsDeptsline::getDeptsIndex).collect(Collectors.toSet()); @@ -300,19 +312,38 @@ public class EventGateController extends BaseController { // System.out.println(stringBuilder); List resultList = new ArrayList<>(); + List msgDTOList = new ArrayList<>(); for (PqsUser user : pqsUserList) { + String msgId = IdUtil.simpleUUID(); + + MsgDTO dto = new MsgDTO(); + dto.setMessage(stringBuilder.toString()); + dto.setPhone(user.getPhone()); + dto.setCustomMsgID(msgId); + msgDTOList.add(dto); + MsgEventInfo msgEventInfo = new MsgEventInfo(); - msgEventInfo.setEventIndex(jsonObject.get("eventdetail_index").toString()); + msgEventInfo.setMsgIndex(msgId); msgEventInfo.setMsgContent(stringBuilder.toString()); - msgEventInfo.setMsgIndex(IdUtil.simpleUUID()); msgEventInfo.setPhone(user.getPhone()); - msgEventInfo.setSendResult(0); msgEventInfo.setUserId(user.getUserIndex()); msgEventInfo.setUserName(user.getName()); msgEventInfo.setIsHandle(0); + msgEventInfo.setSendResult(0); msgEventInfo.setSendTime(LocalDateTime.now()); + msgEventInfo.setEventIndex(jsonObject.get("eventdetail_index").toString()); resultList.add(msgEventInfo); } + + List result = smsUtils.sendSmSToUser(msgDTOList); + Map stringSmsItemMap = result.stream().collect(Collectors.toMap(SmsResponseDTO.SmsItem::getCustomMsgID,Function.identity())); + + resultList.forEach(item->{ + if(stringSmsItemMap.containsKey(item.getMsgIndex())){ + SmsResponseDTO.SmsItem smsItem = stringSmsItemMap.get(item.getMsgIndex()); + item.setSendResult(Objects.equals(smsItem.getCode(),"0")?1:0); + } + }); msgEventInfoService.saveBatch(resultList); } } @@ -326,6 +357,10 @@ public class EventGateController extends BaseController { } private boolean apiSend(){ + + + + return false; } diff --git a/event_smart/src/main/java/com/njcn/product/event/transientes/job/ScheduledEvent.java b/event_smart/src/main/java/com/njcn/product/event/transientes/job/ScheduledEvent.java new file mode 100644 index 0000000..ccdbf98 --- /dev/null +++ b/event_smart/src/main/java/com/njcn/product/event/transientes/job/ScheduledEvent.java @@ -0,0 +1,112 @@ +package com.njcn.product.event.transientes.job; + +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.scheduling.annotation.SchedulingConfigurer; +import org.springframework.scheduling.config.ScheduledTaskRegistrar; +import org.springframework.scheduling.support.CronTrigger; +import org.springframework.stereotype.Component; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.*; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +/** + * @Author: cdf + * @CreateTime: 2025-10-16 + * @Description: 定时同步暂降数据包 + */ +@Component +@EnableScheduling +@RequiredArgsConstructor +public class ScheduledEvent implements SchedulingConfigurer { + + @Value("${}") + private final String cronStr = ""; + + // 源文件夹路径 + private final String sourceFolderPath = "D:\\"; + // 压缩文件输出路径 + private final String zipOutputPath = "./output_zips"; + // 最终存放压缩文件的目录 + private final String finalDestination = "./archive"; + + + + @Override + public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { + taskRegistrar.addTriggerTask( + () -> dataToFile(), + triggerContext -> { + CronTrigger trigger = new CronTrigger(cronStr); + return trigger.nextExecutionTime(triggerContext); + } + ); + } + + public void dataToFile() { + try { + // 1. 创建临时文件夹并写入测试文件 + String folderName = "data_" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss")); + Path sourceDir = Paths.get(sourceFolderPath, folderName); + Files.createDirectories(sourceDir); + + // 模拟生成文件(例如:log.txt) + Path testFile = sourceDir.resolve("log.txt"); + Files.write(testFile, "This is a test log file.".getBytes(), StandardOpenOption.CREATE); + + // 2. 压缩文件夹 + Path zipOutputDir = Paths.get(zipOutputPath); + Files.createDirectories(zipOutputDir); + Path zipFile = zipOutputDir.resolve(folderName + ".zip"); + + try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile.toFile()))) { + Files.walk(sourceDir) + .filter(path -> !Files.isDirectory(path)) + .forEach(path -> { + String zipEntryName = sourceDir.relativize(path).toString(); + try { + zos.putNextEntry(new ZipEntry(zipEntryName)); + Files.copy(path, zos); + zos.closeEntry(); + } catch (IOException e) { + throw new RuntimeException("Failed to add file to zip: " + path, e); + } + }); + } + + // 3. 移动压缩文件到最终目录 + Path finalDir = Paths.get(finalDestination); + Files.createDirectories(finalDir); + Path targetPath = finalDir.resolve(zipFile.getFileName()); + Files.move(zipFile, targetPath, StandardCopyOption.REPLACE_EXISTING); + + // 4. 删除临时文件夹(可选) + deleteDirectory(sourceDir.toFile()); + + System.out.println("Task completed: " + targetPath); + }catch (Exception e){ + e.printStackTrace(); + } + } + + /** + * 递归删除目录 + */ + private void deleteDirectory(File directory) { + File[] allContents = directory.listFiles(); + if (allContents != null) { + for (File file : allContents) { + deleteDirectory(file); + } + } + directory.delete(); + } +} diff --git a/event_smart/src/main/java/com/njcn/product/event/transientes/mapper/PqsEventDetailStatusMapper.java b/event_smart/src/main/java/com/njcn/product/event/transientes/mapper/PqsEventDetailStatusMapper.java new file mode 100644 index 0000000..bd45f72 --- /dev/null +++ b/event_smart/src/main/java/com/njcn/product/event/transientes/mapper/PqsEventDetailStatusMapper.java @@ -0,0 +1,13 @@ +package com.njcn.product.event.transientes.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.njcn.product.event.transientes.pojo.po.PqsEventDetailStatusPO; + +/** + * @Author: cdf + * @CreateTime: 2025-10-20 + * @Description: + */ +public interface PqsEventDetailStatusMapper extends BaseMapper { + +} diff --git a/event_smart/src/main/java/com/njcn/product/event/transientes/pojo/dto/MsgDTO.java b/event_smart/src/main/java/com/njcn/product/event/transientes/pojo/dto/MsgDTO.java new file mode 100644 index 0000000..a592179 --- /dev/null +++ b/event_smart/src/main/java/com/njcn/product/event/transientes/pojo/dto/MsgDTO.java @@ -0,0 +1,20 @@ +package com.njcn.product.event.transientes.pojo.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +/** + * @Author: cdf + * @CreateTime: 2025-10-15 + * @Description: + */ +@Data +public class MsgDTO { + + private String message; + + private String phone; + + @JsonProperty(value = "customMsgID") + private String customMsgID; +} diff --git a/event_smart/src/main/java/com/njcn/product/event/transientes/pojo/dto/SmsResponseDTO.java b/event_smart/src/main/java/com/njcn/product/event/transientes/pojo/dto/SmsResponseDTO.java new file mode 100644 index 0000000..543cd15 --- /dev/null +++ b/event_smart/src/main/java/com/njcn/product/event/transientes/pojo/dto/SmsResponseDTO.java @@ -0,0 +1,31 @@ +package com.njcn.product.event.transientes.pojo.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.List; + +/** + * @Author: cdf + * @CreateTime: 2025-10-15 + * @Description: + */ +@Data +public class SmsResponseDTO { + + private String code; + private String message; + private String batchId; + private List items; + + + @Data + public static class SmsItem { + private String msg; + + private String code; + + @JsonProperty(value = "customMsgID") + private String customMsgID; + } +} diff --git a/event_smart/src/main/java/com/njcn/product/event/transientes/pojo/dto/SmsSendDTO.java b/event_smart/src/main/java/com/njcn/product/event/transientes/pojo/dto/SmsSendDTO.java new file mode 100644 index 0000000..5932a12 --- /dev/null +++ b/event_smart/src/main/java/com/njcn/product/event/transientes/pojo/dto/SmsSendDTO.java @@ -0,0 +1,42 @@ +package com.njcn.product.event.transientes.pojo.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.List; + +/** + * @Author: cdf + * @CreateTime: 2025-10-15 + * @Description: + */ +@Data +public class SmsSendDTO { + + private String serviceCode; + + private String account; + + private String token; + + private String ts; + + private List items; + + + + + + @Data + public static class ItemInner{ + private String content; + + @JsonProperty(value = "customMsgID") + private String customMsgID; + + private String to; + + private String ext; + } + +} diff --git a/event_smart/src/main/java/com/njcn/product/event/transientes/pojo/po/PqsEventDetailStatusPO.java b/event_smart/src/main/java/com/njcn/product/event/transientes/pojo/po/PqsEventDetailStatusPO.java new file mode 100644 index 0000000..5cf4d0c --- /dev/null +++ b/event_smart/src/main/java/com/njcn/product/event/transientes/pojo/po/PqsEventDetailStatusPO.java @@ -0,0 +1,39 @@ +package com.njcn.product.event.transientes.pojo.po; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.Date; + +/** + * @Author: cdf + * @CreateTime: 2025-10-20 + * @Description: 暂降事件同步记录 + */ +@Data +public class PqsEventDetailStatusPO { + + @TableId(value = "EVENT_DETAIL_ID") + private String eventDetailId; + + @TableField(value = "EVENT_TIME") + private Date eventTime; + + @TableField(value = "WAVE_FLAG") + private int waveFlag; + + @TableField(value = "SYNC_STATUE") + private int syncStatus; + + @TableField(value = "SYNC_TIME") + private LocalDateTime syncTime; + + @TableField(value = "REMARK") + private String remark; + + @TableField(value = "RETRY_COUNT") + private int retryCount; + +} diff --git a/event_smart/src/main/java/com/njcn/product/event/transientes/service/impl/EventGateServiceImpl.java b/event_smart/src/main/java/com/njcn/product/event/transientes/service/impl/EventGateServiceImpl.java index 4c306fd..adc16e1 100644 --- a/event_smart/src/main/java/com/njcn/product/event/transientes/service/impl/EventGateServiceImpl.java +++ b/event_smart/src/main/java/com/njcn/product/event/transientes/service/impl/EventGateServiceImpl.java @@ -38,8 +38,15 @@ public class EventGateServiceImpl implements EventGateService { private final WaveFileComponent waveFileComponent; private final PqLineService pqLineService; private final PqLinedetailMapper pqLinedetailMapper; - @Value("${WAVEPATH}") + @Value("${business.wavePath}") private String WAVEPATH; + + + /** + * 波形分析 + * @param param + * @return + */ @Override public WaveDataDTO getTransientAnalyseWave(MonitorTerminalParam param) { WaveDataDTO waveDataDTO; diff --git a/event_smart/src/main/java/com/njcn/product/event/transientes/service/impl/LargeScreenCountServiceImpl.java b/event_smart/src/main/java/com/njcn/product/event/transientes/service/impl/LargeScreenCountServiceImpl.java index 1de5e52..737b64d 100644 --- a/event_smart/src/main/java/com/njcn/product/event/transientes/service/impl/LargeScreenCountServiceImpl.java +++ b/event_smart/src/main/java/com/njcn/product/event/transientes/service/impl/LargeScreenCountServiceImpl.java @@ -502,7 +502,18 @@ public class LargeScreenCountServiceImpl implements LargeScreenCountService { List assList = pqUserLineAssMapper.selectList(new LambdaQueryWrapper().in(PqUserLineAssPO::getLineIndex, ids)); if (CollUtil.isNotEmpty(assList)) { List userIds = assList.stream().map(PqUserLineAssPO::getUserIndex).distinct().collect(Collectors.toList()); - List poList = pqUserLedgerMapper.selectList(new LambdaQueryWrapper().in(PqUserLedgerPO::getId, userIds)); + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + if(userIds.size()>1000){ + List> userIdsList = CollUtil.split(userIds, 1000); + wrapper.and(w -> { + for (List teIds : userIdsList) { + w.or(wIn -> wIn.in(PqUserLedgerPO::getId, teIds)); + } + }); + }else { + wrapper.in(PqUserLedgerPO::getId, userIds); + } + List poList = pqUserLedgerMapper.selectList(wrapper); userMap = poList.stream().collect(Collectors.toMap(PqUserLedgerPO::getId, Function.identity())); assMap = assList.stream().collect(Collectors.groupingBy(PqUserLineAssPO::getLineIndex)); } else { diff --git a/event_smart/src/main/java/com/njcn/product/event/transientes/utils/SmsUtils.java b/event_smart/src/main/java/com/njcn/product/event/transientes/utils/SmsUtils.java new file mode 100644 index 0000000..e217d95 --- /dev/null +++ b/event_smart/src/main/java/com/njcn/product/event/transientes/utils/SmsUtils.java @@ -0,0 +1,102 @@ +package com.njcn.product.event.transientes.utils; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.util.IdUtil; +import cn.hutool.crypto.digest.SM3; +import cn.hutool.json.JSONObject; +import com.njcn.common.pojo.exception.BusinessException; +import com.njcn.product.event.transientes.pojo.dto.MsgDTO; +import com.njcn.product.event.transientes.pojo.dto.SmsResponseDTO; +import com.njcn.product.event.transientes.pojo.dto.SmsSendDTO; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.*; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestTemplate; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +/** + * @Author: cdf + * @CreateTime: 2025-10-15 + * @Description: 短信工具 + */ +@Component +@Slf4j +public class SmsUtils { + + @Autowired + private RestTemplate restTemplate; + + @Value("${smsServer.info}") + private String smsServer; + + @Value("${smsServer.account}") + private String account; + + @Value("${smsServer.password}") + private String password; + + + public List sendSmSToUser(List msgDTOList) { + SmsSendDTO smsSendDTO = new SmsSendDTO(); + smsSendDTO.setServiceCode("101001101"); + smsSendDTO.setAccount(account); + + String nowTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern(DatePattern.PURE_DATETIME_PATTERN)); + String sm3Hash = new SM3().digestHex(account + password + nowTime); + smsSendDTO.setToken(sm3Hash); + smsSendDTO.setTs(nowTime); + + List temList = new ArrayList<>(); + for (MsgDTO dto : msgDTOList) { + SmsSendDTO.ItemInner inner = new SmsSendDTO.ItemInner(); + inner.setTo(dto.getPhone()); + inner.setContent(dto.getMessage()); + temList.add(inner); + } + smsSendDTO.setItems(temList); + + String url = smsServer + "/sms/msg"; + try { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + HttpEntity requestEntity = new HttpEntity<>(new JSONObject(smsSendDTO).toString(), headers); + + ResponseEntity response = restTemplate.exchange( + url, + HttpMethod.POST, + requestEntity, + SmsResponseDTO.class + ); + // 处理响应 + return handleSmsResponse(response); + } catch (RestClientException e) { + log.error("短信接口调用失败", e); + throw new RuntimeException("短信发送异常", e); + } + + } + + private List handleSmsResponse(ResponseEntity response) { + if (response.getStatusCode() == HttpStatus.OK) { + SmsResponseDTO smsResponse = response.getBody(); + if (smsResponse != null && "0".equals(smsResponse.getCode())) { + log.info("短信发送成功,batchId: {}", smsResponse.getBatchId()); + return smsResponse.getItems(); + } else { + log.error("短信发送失败: {}", (smsResponse != null ? smsResponse.getMessage() : "API 返回异常")); + throw new BusinessException("调用短信服务失败"); + } + } else { + log.error("HTTP 请求失败,状态码: {}", response.getStatusCode()); + throw new BusinessException("调用短信服务失败"); + } + } + +} diff --git a/event_smart/src/main/resources/application-dev.yml b/event_smart/src/main/resources/application-dev.yml index 2c95ddb..31bddbf 100644 --- a/event_smart/src/main/resources/application-dev.yml +++ b/event_smart/src/main/resources/application-dev.yml @@ -51,3 +51,8 @@ spring: min-idle: 0 +smsServer: + info: http://22.33.194.50:18096 + netInfo: http://22.33.191.206:18096 + account: sms + password: aaa diff --git a/event_smart/src/main/resources/application-prod.yml b/event_smart/src/main/resources/application-prod.yml index 334d60d..00c5061 100644 --- a/event_smart/src/main/resources/application-prod.yml +++ b/event_smart/src/main/resources/application-prod.yml @@ -53,3 +53,8 @@ spring: min-idle: 0 +smsServer: + info: http://22.33.194.49:18095 + netInfo: http://20.33.234.143:18095 + account: sms + password: aaa diff --git a/event_smart/src/main/resources/application.yml b/event_smart/src/main/resources/application.yml index 5f33029..12f13a6 100644 --- a/event_smart/src/main/resources/application.yml +++ b/event_smart/src/main/resources/application.yml @@ -38,6 +38,9 @@ db: business: #处理波形数据位置 wavePath: D://Comtrade + + exportBaseDir: D://exportComtrade + cronExpression: #wavePath: /usr/local/comtrade #处理临时数据 tempPath: D://file @@ -67,7 +70,7 @@ threadPool: maxPoolSize: 20 queueCapacity: 500 keepAliveSeconds: 60 -WAVEPATH: D:/Comtrade +