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());
|
UserReportPO userReportPO = userReportPOMapper.selectById(lineDetail.getObjId());
|
||||||
if(Objects.nonNull(userReportPO)){
|
if(Objects.nonNull(userReportPO)){
|
||||||
lineDetailDataVO.setObjName(userReportPO.getProjectName());
|
lineDetailDataVO.setObjName(userReportPO.getProjectName());
|
||||||
|
}else {
|
||||||
|
lineDetailDataVO.setObjName("/");
|
||||||
}
|
}
|
||||||
lineDetailDataVO.setId(lineDetail.getNum());
|
lineDetailDataVO.setId(lineDetail.getNum());
|
||||||
lineDetailDataVO.setPtType(TerminalUtils.ptType(lineDetail.getPtType()));
|
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.date.DateUtil;
|
||||||
import cn.hutool.core.util.IdUtil;
|
import cn.hutool.core.util.IdUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.crypto.digest.SM3;
|
||||||
import cn.hutool.json.JSONObject;
|
import cn.hutool.json.JSONObject;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.njcn.common.pojo.annotation.OperateInfo;
|
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.devcie.service.PqsDeptslineService;
|
||||||
import com.njcn.product.event.transientes.mapper.PqUserLedgerMapper;
|
import com.njcn.product.event.transientes.mapper.PqUserLedgerMapper;
|
||||||
import com.njcn.product.event.transientes.mapper.PqUserLineAssMapper;
|
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.MonitorTerminalParam;
|
||||||
import com.njcn.product.event.transientes.pojo.param.SimulationMsgParam;
|
import com.njcn.product.event.transientes.pojo.param.SimulationMsgParam;
|
||||||
import com.njcn.product.event.transientes.pojo.po.*;
|
import com.njcn.product.event.transientes.pojo.po.*;
|
||||||
import com.njcn.product.event.transientes.service.*;
|
import com.njcn.product.event.transientes.service.*;
|
||||||
import com.njcn.product.event.transientes.service.impl.MsgEventInfoServiceImpl;
|
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.product.event.transientes.websocket.WebSocketServer;
|
||||||
import com.njcn.redis.utils.RedisUtil;
|
import com.njcn.redis.utils.RedisUtil;
|
||||||
import com.njcn.web.controller.BaseController;
|
import com.njcn.web.controller.BaseController;
|
||||||
@@ -34,12 +39,15 @@ import io.swagger.annotations.ApiOperation;
|
|||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.http.*;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -64,6 +72,7 @@ public class EventGateController extends BaseController {
|
|||||||
@Value("${SYS_TYPE_ZT}")
|
@Value("${SYS_TYPE_ZT}")
|
||||||
private String sysTypeZt;
|
private String sysTypeZt;
|
||||||
|
|
||||||
|
|
||||||
private final WebSocketServer webSocketServer;
|
private final WebSocketServer webSocketServer;
|
||||||
|
|
||||||
private final PqsDeptslineService pqsDeptslineService;
|
private final PqsDeptslineService pqsDeptslineService;
|
||||||
@@ -84,6 +93,8 @@ public class EventGateController extends BaseController {
|
|||||||
|
|
||||||
private final RedisUtil redisUtil;
|
private final RedisUtil redisUtil;
|
||||||
|
|
||||||
|
private final SmsUtils smsUtils;
|
||||||
|
|
||||||
|
|
||||||
@OperateInfo
|
@OperateInfo
|
||||||
@GetMapping("/eventMsg")
|
@GetMapping("/eventMsg")
|
||||||
@@ -174,6 +185,7 @@ public class EventGateController extends BaseController {
|
|||||||
try {
|
try {
|
||||||
sendMessage(jsonObject);
|
sendMessage(jsonObject);
|
||||||
}catch (Exception e){
|
}catch (Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
log.error("短信组装发送失败!失败原因{}",e.getMessage());
|
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());
|
Integer lineId = Integer.valueOf(jsonObject.get("lineid").toString());
|
||||||
List<PqsDeptsline> pqLineDept = pqsDeptslineService.lambdaQuery().eq(PqsDeptsline::getLineIndex, lineId).eq(PqsDeptsline::getSystype, sysTypeZt).list();
|
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());
|
Set<String> deptIds = pqLineDept.stream().map(PqsDeptsline::getDeptsIndex).collect(Collectors.toSet());
|
||||||
@@ -300,19 +312,38 @@ public class EventGateController extends BaseController {
|
|||||||
// System.out.println(stringBuilder);
|
// System.out.println(stringBuilder);
|
||||||
|
|
||||||
List<MsgEventInfo> resultList = new ArrayList<>();
|
List<MsgEventInfo> resultList = new ArrayList<>();
|
||||||
|
List<MsgDTO> msgDTOList = new ArrayList<>();
|
||||||
for (PqsUser user : pqsUserList) {
|
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 msgEventInfo = new MsgEventInfo();
|
||||||
msgEventInfo.setEventIndex(jsonObject.get("eventdetail_index").toString());
|
msgEventInfo.setMsgIndex(msgId);
|
||||||
msgEventInfo.setMsgContent(stringBuilder.toString());
|
msgEventInfo.setMsgContent(stringBuilder.toString());
|
||||||
msgEventInfo.setMsgIndex(IdUtil.simpleUUID());
|
|
||||||
msgEventInfo.setPhone(user.getPhone());
|
msgEventInfo.setPhone(user.getPhone());
|
||||||
msgEventInfo.setSendResult(0);
|
|
||||||
msgEventInfo.setUserId(user.getUserIndex());
|
msgEventInfo.setUserId(user.getUserIndex());
|
||||||
msgEventInfo.setUserName(user.getName());
|
msgEventInfo.setUserName(user.getName());
|
||||||
msgEventInfo.setIsHandle(0);
|
msgEventInfo.setIsHandle(0);
|
||||||
|
msgEventInfo.setSendResult(0);
|
||||||
msgEventInfo.setSendTime(LocalDateTime.now());
|
msgEventInfo.setSendTime(LocalDateTime.now());
|
||||||
|
msgEventInfo.setEventIndex(jsonObject.get("eventdetail_index").toString());
|
||||||
resultList.add(msgEventInfo);
|
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);
|
msgEventInfoService.saveBatch(resultList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -326,6 +357,10 @@ public class EventGateController extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean apiSend(){
|
private boolean apiSend(){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return false;
|
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 WaveFileComponent waveFileComponent;
|
||||||
private final PqLineService pqLineService;
|
private final PqLineService pqLineService;
|
||||||
private final PqLinedetailMapper pqLinedetailMapper;
|
private final PqLinedetailMapper pqLinedetailMapper;
|
||||||
@Value("${WAVEPATH}")
|
@Value("${business.wavePath}")
|
||||||
private String WAVEPATH;
|
private String WAVEPATH;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 波形分析
|
||||||
|
* @param param
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public WaveDataDTO getTransientAnalyseWave(MonitorTerminalParam param) {
|
public WaveDataDTO getTransientAnalyseWave(MonitorTerminalParam param) {
|
||||||
WaveDataDTO waveDataDTO;
|
WaveDataDTO waveDataDTO;
|
||||||
|
|||||||
@@ -502,7 +502,18 @@ public class LargeScreenCountServiceImpl implements LargeScreenCountService {
|
|||||||
List<PqUserLineAssPO> assList = pqUserLineAssMapper.selectList(new LambdaQueryWrapper<PqUserLineAssPO>().in(PqUserLineAssPO::getLineIndex, ids));
|
List<PqUserLineAssPO> assList = pqUserLineAssMapper.selectList(new LambdaQueryWrapper<PqUserLineAssPO>().in(PqUserLineAssPO::getLineIndex, ids));
|
||||||
if (CollUtil.isNotEmpty(assList)) {
|
if (CollUtil.isNotEmpty(assList)) {
|
||||||
List<String> userIds = assList.stream().map(PqUserLineAssPO::getUserIndex).distinct().collect(Collectors.toList());
|
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()));
|
userMap = poList.stream().collect(Collectors.toMap(PqUserLedgerPO::getId, Function.identity()));
|
||||||
assMap = assList.stream().collect(Collectors.groupingBy(PqUserLineAssPO::getLineIndex));
|
assMap = assList.stream().collect(Collectors.groupingBy(PqUserLineAssPO::getLineIndex));
|
||||||
} else {
|
} 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
|
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
|
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:
|
business:
|
||||||
#处理波形数据位置
|
#处理波形数据位置
|
||||||
wavePath: D://Comtrade
|
wavePath: D://Comtrade
|
||||||
|
|
||||||
|
exportBaseDir: D://exportComtrade
|
||||||
|
cronExpression:
|
||||||
#wavePath: /usr/local/comtrade
|
#wavePath: /usr/local/comtrade
|
||||||
#处理临时数据
|
#处理临时数据
|
||||||
tempPath: D://file
|
tempPath: D://file
|
||||||
@@ -67,7 +70,7 @@ threadPool:
|
|||||||
maxPoolSize: 20
|
maxPoolSize: 20
|
||||||
queueCapacity: 500
|
queueCapacity: 500
|
||||||
keepAliveSeconds: 60
|
keepAliveSeconds: 60
|
||||||
WAVEPATH: D:/Comtrade
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user