1.北京短信接口
This commit is contained in:
@@ -266,6 +266,8 @@ public class LineServiceImpl extends ServiceImpl<LineMapper, Line> 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()));
|
||||
|
||||
@@ -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<PqsEventdetail> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
lambdaQueryWrapper.between(PqsEventdetail::getTimeid,startTime,endTime);
|
||||
List<PqsEventdetail> unsyncedEvents = pqsEventdetailMapper.selectList(lambdaQueryWrapper);
|
||||
log.info("查询到 " + unsyncedEvents.size() + " 个暂降事件");
|
||||
if(CollUtil.isEmpty(unsyncedEvents)){
|
||||
return ;
|
||||
}
|
||||
|
||||
// 查询已经存在记录的暂降事件
|
||||
LambdaQueryWrapper<PqsEventDetailStatusPO> statusPOLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
statusPOLambdaQueryWrapper.between(PqsEventDetailStatusPO::getEventTime,startTime,endTime);
|
||||
List<PqsEventDetailStatusPO> hasList = pqsEventDetailStatusMapper.selectList(statusPOLambdaQueryWrapper);
|
||||
log.info("查询到 " + hasList.size() + "条已存在记录事件");
|
||||
//波形文件失败的事件id
|
||||
List<String> waveFailEventDetailIds = hasList.stream().filter(it->it.getWaveFlag() == 0).map(PqsEventDetailStatusPO::getEventDetailId).collect(Collectors.toList());
|
||||
|
||||
|
||||
//排除已经成功的事件
|
||||
if(CollUtil.isNotEmpty(hasList)){
|
||||
List<String> 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<PqsDeptsline> pqLineDept = pqsDeptslineService.lambdaQuery().eq(PqsDeptsline::getLineIndex, lineId).eq(PqsDeptsline::getSystype, sysTypeZt).list();
|
||||
Set<String> deptIds = pqLineDept.stream().map(PqsDeptsline::getDeptsIndex).collect(Collectors.toSet());
|
||||
@@ -300,19 +312,38 @@ public class EventGateController extends BaseController {
|
||||
// System.out.println(stringBuilder);
|
||||
|
||||
List<MsgEventInfo> resultList = new ArrayList<>();
|
||||
List<MsgDTO> 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<SmsResponseDTO.SmsItem> result = smsUtils.sendSmSToUser(msgDTOList);
|
||||
Map<String,SmsResponseDTO.SmsItem> 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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<PqsEventDetailStatusPO> {
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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<SmsItem> items;
|
||||
|
||||
|
||||
@Data
|
||||
public static class SmsItem {
|
||||
private String msg;
|
||||
|
||||
private String code;
|
||||
|
||||
@JsonProperty(value = "customMsgID")
|
||||
private String customMsgID;
|
||||
}
|
||||
}
|
||||
@@ -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<ItemInner> items;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Data
|
||||
public static class ItemInner{
|
||||
private String content;
|
||||
|
||||
@JsonProperty(value = "customMsgID")
|
||||
private String customMsgID;
|
||||
|
||||
private String to;
|
||||
|
||||
private String ext;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -502,7 +502,18 @@ public class LargeScreenCountServiceImpl implements LargeScreenCountService {
|
||||
List<PqUserLineAssPO> assList = pqUserLineAssMapper.selectList(new LambdaQueryWrapper<PqUserLineAssPO>().in(PqUserLineAssPO::getLineIndex, ids));
|
||||
if (CollUtil.isNotEmpty(assList)) {
|
||||
List<String> userIds = assList.stream().map(PqUserLineAssPO::getUserIndex).distinct().collect(Collectors.toList());
|
||||
List<PqUserLedgerPO> poList = pqUserLedgerMapper.selectList(new LambdaQueryWrapper<PqUserLedgerPO>().in(PqUserLedgerPO::getId, userIds));
|
||||
LambdaQueryWrapper<PqUserLedgerPO> wrapper = new LambdaQueryWrapper<>();
|
||||
if(userIds.size()>1000){
|
||||
List<List<String>> userIdsList = CollUtil.split(userIds, 1000);
|
||||
wrapper.and(w -> {
|
||||
for (List<String> teIds : userIdsList) {
|
||||
w.or(wIn -> wIn.in(PqUserLedgerPO::getId, teIds));
|
||||
}
|
||||
});
|
||||
}else {
|
||||
wrapper.in(PqUserLedgerPO::getId, userIds);
|
||||
}
|
||||
List<PqUserLedgerPO> poList = pqUserLedgerMapper.selectList(wrapper);
|
||||
userMap = poList.stream().collect(Collectors.toMap(PqUserLedgerPO::getId, Function.identity()));
|
||||
assMap = assList.stream().collect(Collectors.groupingBy(PqUserLineAssPO::getLineIndex));
|
||||
} else {
|
||||
|
||||
@@ -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<SmsResponseDTO.SmsItem> sendSmSToUser(List<MsgDTO> 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<SmsSendDTO.ItemInner> 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<String> requestEntity = new HttpEntity<>(new JSONObject(smsSendDTO).toString(), headers);
|
||||
|
||||
ResponseEntity<SmsResponseDTO> response = restTemplate.exchange(
|
||||
url,
|
||||
HttpMethod.POST,
|
||||
requestEntity,
|
||||
SmsResponseDTO.class
|
||||
);
|
||||
// 处理响应
|
||||
return handleSmsResponse(response);
|
||||
} catch (RestClientException e) {
|
||||
log.error("短信接口调用失败", e);
|
||||
throw new RuntimeException("短信发送异常", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private List<SmsResponseDTO.SmsItem> handleSmsResponse(ResponseEntity<SmsResponseDTO> 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("调用短信服务失败");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user