feat(ems、api、job): 新增定时任务

- 新增三个SnailJob任务执行器:设备告警、电阈值超限、小时耗量告警
- 实现RemoteEmsTaskService远程服务接口及其实现类
- 创建hwmom-api-ems模块并配置相关依赖
- 启用Spring定时任务支持并注释原有调度逻辑
- 移除旧模块依赖,引入新api模块依赖
- 完成采集设备告警、电阈值对比、小时耗量检查等核心业务逻辑
- 添加全局事务管理确保数据一致性
- 注释掉原有的Scheduled定时任务方法以便后续迁移
master
zangch@mesnac.com 2 months ago
parent c6bb03c5dc
commit 120f64b6b2

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-api</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>hwmom-api-ems</artifactId>
<description>
hwmom-api-ems ems接口模块
</description>
<dependencies>
<!-- RuoYi Common Core-->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-core</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-excel</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.aizuda</groupId>
<artifactId>snail-job-client-job-core</artifactId>
</dependency>
</dependencies>
</project>

@ -0,0 +1,13 @@
package org.dromara.ems.api;
import org.dromara.common.core.domain.R;
public interface RemoteEmsTaskService {
public R<Void> collectDeviceAlarmsTask();
public R<Void> exceedDnbThresholdAlarmsTask();
public R<Void> hourlyConsumptionAlarmsTask();
}

@ -20,6 +20,7 @@
<module>hwmom-api-dms</module>
<module>ruoyi-api-job</module>
<module>hwmom-api-wms</module>
<module>hwmom-api-ems</module>
</modules>
<artifactId>ruoyi-api</artifactId>

@ -181,15 +181,13 @@
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-system</artifactId>
<version>${revision}</version>
<scope>compile</scope>
<artifactId>hwmom-api-ems</artifactId>
<version>2.2.2</version>
</dependency>
</dependencies>
<build>

@ -0,0 +1,252 @@
package org.dromara.ems.Dubbo;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.ems.api.RemoteEmsTaskService;
import org.dromara.ems.base.domain.EmsBaseCollectDeviceInfo;
import org.dromara.ems.base.domain.EmsBaseMonitorThreshold;
import org.dromara.ems.base.mapper.EmsBaseCollectDeviceInfoMapper;
import org.dromara.ems.base.mapper.EmsBaseMonitorThresholdMapper;
import org.dromara.ems.record.domain.EmsRecordAlarmData;
import org.dromara.ems.record.domain.EmsRecordAlarmRule;
import org.dromara.ems.record.domain.EmsRecordDnbInstant;
import org.dromara.ems.record.mapper.EmsRecordAlarmDataMapper;
import org.dromara.ems.record.mapper.EmsRecordAlarmRuleMapper;
import org.dromara.ems.record.mapper.EmsRecordDnbInstantMapper;
import org.dromara.ems.report.domain.EmsReportPointDnb;
import org.dromara.ems.report.mapper.EmsReportPointDnbMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@RequiredArgsConstructor
@Service
@DubboService
@Slf4j
public class RemoteEmsTaskServiceImpl implements RemoteEmsTaskService {
private final EmsRecordAlarmDataMapper emsRecordAlarmDataMapper;
private final EmsRecordAlarmRuleMapper emsRecordAlarmRuleMapper;
private final EmsBaseCollectDeviceInfoMapper emsBaseCollectDeviceInfoMapper;
private final EmsRecordDnbInstantMapper emsRecordDnbInstantMapper;
private final EmsBaseMonitorThresholdMapper emsBaseMonitorThresholdMapper;
private final EmsReportPointDnbMapper emsReportPointDnbMapper;
/* public RemoteEmsTaskServiceImpl(EmsRecordAlarmDataMapper emsRecordAlarmDataMapper, EmsRecordAlarmRuleMapper emsRecordAlarmRuleMapper, EmsBaseCollectDeviceInfoMapper emsBaseCollectDeviceInfoMapper, EmsRecordDnbInstantMapper emsRecordDnbInstantMapper, EmsBaseMonitorThresholdMapper emsBaseMonitorThresholdMapper, EmsReportPointDnbMapper emsReportPointDnbMapper) {
this.emsRecordAlarmDataMapper = emsRecordAlarmDataMapper;
this.emsRecordAlarmRuleMapper = emsRecordAlarmRuleMapper;
this.emsBaseCollectDeviceInfoMapper = emsBaseCollectDeviceInfoMapper;
this.emsRecordDnbInstantMapper = emsRecordDnbInstantMapper;
this.emsBaseMonitorThresholdMapper = emsBaseMonitorThresholdMapper;
this.emsReportPointDnbMapper = emsReportPointDnbMapper;
}*/
/**
*
*/
@GlobalTransactional(rollbackFor = Exception.class)
public R<Void> collectDeviceAlarmsTask() {
long minuteValue = 1000 * 60;
Date date = new Date();
EmsRecordAlarmRule alarmRule = new EmsRecordAlarmRule();
alarmRule.setTriggerRule(1L);
List<EmsRecordAlarmRule> alarmRules = emsRecordAlarmRuleMapper.selectEmsRecordAlarmRuleList(alarmRule);
if (alarmRules.size() > 0) {
minuteValue = alarmRules.get(0).getDeviceOfflineTime() * minuteValue;
} else {
System.out.println("未配置设备离线时间");
return R.fail();
}
System.out.println("开始执行设备告警定时任务");
EmsBaseCollectDeviceInfo collectDeviceInfo = new EmsBaseCollectDeviceInfo();
collectDeviceInfo.setIsFlag("1");
List<EmsBaseCollectDeviceInfo> deviceInfoList = emsBaseCollectDeviceInfoMapper.selectEmsBaseCollectDeviceInfoList(collectDeviceInfo);
if (deviceInfoList.size() > 0) {
EmsRecordAlarmData recordAlarmData = new EmsRecordAlarmData();
recordAlarmData.setAlarmType(1L);
recordAlarmData.setAlarmStatus(1L);
List<EmsRecordAlarmData> alarmDataList = emsRecordAlarmDataMapper.selectEmsRecordAlarmDataList(recordAlarmData);
List<String> collectDeviceIdList = alarmDataList.stream().map(EmsRecordAlarmData::getCollectDeviceId).collect(Collectors.toList());
for (EmsBaseCollectDeviceInfo deviceInfo : deviceInfoList) {
if (collectDeviceIdList.contains(deviceInfo.getCollectDeviceId())) {
continue;
}
if ((deviceInfo.getUpdateTime().getTime() + minuteValue) < date.getTime()) {
EmsRecordAlarmData alarmData = new EmsRecordAlarmData();
alarmData.setCollectDeviceId(deviceInfo.getCollectDeviceId());
alarmData.setCollectTime(new Date());
alarmData.setAlarmType(1L);
alarmData.setAlarmStatus(1L);
alarmData.setAlarmData("设备离线已超过" + alarmRules.get(0).getDeviceOfflineTime() + "分钟");
System.out.println("存入数据:" + alarmData);
emsRecordAlarmDataMapper.insertEmsRecordAlarmData(alarmData);
}
}
}
System.out.println("设备告警定时任务执行完毕");
return R.ok();
}
/**
*
*/
@GlobalTransactional(rollbackFor = Exception.class)
public R<Void> exceedDnbThresholdAlarmsTask() {
System.out.println("开始执行超过电阈值定时任务");
EmsBaseMonitorThreshold monitorThreshold = new EmsBaseMonitorThreshold();
monitorThreshold.setMonitorType(2L);
List<EmsBaseMonitorThreshold> thresholdList = emsBaseMonitorThresholdMapper.selectEmsBaseMonitorThresholdList(monitorThreshold);
EmsRecordDnbInstant dnbInstant = new EmsRecordDnbInstant();
List<EmsRecordDnbInstant> dnbInstantList = emsRecordDnbInstantMapper.selectEmsRecordDnbInstantList(dnbInstant);
Map<String, String> thresholdMap = compareThresholdAndRecord(thresholdList, dnbInstantList);
//防止多次存入异常数据
EmsRecordAlarmData recordAlarmData = new EmsRecordAlarmData();
recordAlarmData.setAlarmType(0L);
recordAlarmData.setAlarmStatus(1L);
List<EmsRecordAlarmData> alarmDataList = emsRecordAlarmDataMapper.selectEmsRecordAlarmDataList(recordAlarmData);
List<String> monitorIdList = alarmDataList.stream().map(EmsRecordAlarmData::getMonitorId).collect(Collectors.toList());
for (String monitorId : thresholdMap.keySet()) {
if (monitorIdList.contains(monitorId)) {
continue;
}
EmsRecordAlarmData alarmData = new EmsRecordAlarmData();
alarmData.setMonitorId(monitorId);
alarmData.setCollectTime(new Date());
alarmData.setAlarmType(0L);
alarmData.setAlarmStatus(1L);
alarmData.setAlarmData(thresholdMap.get(monitorId));
System.out.println("存入数据:" + alarmData);
emsRecordAlarmDataMapper.insertEmsRecordAlarmData(alarmData);
}
System.out.println("完成超过阈值定时任务");
return R.ok();
}
/**
*
*
* @param baseDnbThresholds
* @param recordDnbInstants
* @return
*/
public Map<String, String> compareThresholdAndRecord(List<EmsBaseMonitorThreshold> baseDnbThresholds, List<EmsRecordDnbInstant> recordDnbInstants) {
Map<String, String> resultMap = new HashMap<>();
for (EmsRecordDnbInstant recordDnbInstant : recordDnbInstants) {
String monitorCode = recordDnbInstant.getMonitorCode();
EmsBaseMonitorThreshold baseDnbThreshold = null;
for (EmsBaseMonitorThreshold threshold : baseDnbThresholds) {
if (threshold.getMonitorCode().equals(monitorCode)) {
baseDnbThreshold = threshold;
break;
}
}
if (baseDnbThreshold != null) {
String reason = compare(recordDnbInstant, baseDnbThreshold);
if (reason != null) {
resultMap.put(monitorCode, reason);
}
}
}
return resultMap;
}
private String compare(EmsRecordDnbInstant recordDnbInstant, EmsBaseMonitorThreshold baseDnbThreshold) {
if (StringUtils.isNull(recordDnbInstant.getIA())) {
return null;
}
BigDecimal zero = new BigDecimal("0.00");
if (recordDnbInstant.getVA().compareTo(zero) == 0 || recordDnbInstant.getVB().compareTo(zero) == 0
|| recordDnbInstant.getVC().compareTo(zero) == 0) {
return "缺项报警";
}
if (recordDnbInstant.getIA().compareTo(baseDnbThreshold.getIBMin()) > 0) {
return "超过A相电流最大值";
}
if (recordDnbInstant.getIB().compareTo(baseDnbThreshold.getIBMax()) > 0) {
return "超过B相电流最大值";
}
if (recordDnbInstant.getIC().compareTo(baseDnbThreshold.getICMax()) > 0) {
return "超过C相电流最大值";
}
if (recordDnbInstant.getVA().compareTo(baseDnbThreshold.getVAMax()) > 0) {
return "超过A相电压最大值";
}
if (recordDnbInstant.getVB().compareTo(baseDnbThreshold.getVBMax()) > 0) {
return "超过B相电压最大值";
}
if (recordDnbInstant.getVC().compareTo(baseDnbThreshold.getVCMax()) > 0) {
return "超过C相电压最大值";
}
if (recordDnbInstant.getIA().compareTo(baseDnbThreshold.getIAMin()) < 0) {
return "小于A相电流最小值";
}
if (recordDnbInstant.getIB().compareTo(baseDnbThreshold.getIBMin()) < 0) {
return "小于B相电流最小值";
}
if (recordDnbInstant.getIC().compareTo(baseDnbThreshold.getICMin()) < 0) {
return "小于C相电流最小值";
}
if (recordDnbInstant.getVA().compareTo(baseDnbThreshold.getVAMin()) < 0) {
return "小于A相电压最小值";
}
if (recordDnbInstant.getVB().compareTo(baseDnbThreshold.getVBMin()) < 0) {
return "小于B相电压最小值";
}
if (recordDnbInstant.getVC().compareTo(baseDnbThreshold.getVCMin()) < 0) {
return "小于C相电压最小值";
}
return null;
}
/**
*
*/
@GlobalTransactional(rollbackFor = Exception.class)
public R<Void> hourlyConsumptionAlarmsTask() {
System.out.println("开始执行小时耗量告警定时任务");
EmsBaseMonitorThreshold monitorThreshold = new EmsBaseMonitorThreshold();
monitorThreshold.setMonitorType(2L);
List<EmsBaseMonitorThreshold> thresholdList = emsBaseMonitorThresholdMapper.selectEmsBaseMonitorThresholdList(monitorThreshold);
for (EmsBaseMonitorThreshold threshold : thresholdList) {
BigDecimal consumption = threshold.getHourConsumption();
if (consumption.equals(new BigDecimal(0))){
continue;
}
EmsReportPointDnb reportPointDnb = new EmsReportPointDnb();
reportPointDnb.setMonitorCode(threshold.getMonitorCode());
System.out.println("查询数据:" + reportPointDnb);
List<EmsReportPointDnb> dnbList = emsReportPointDnbMapper.selectEmsReportPointDnbList(reportPointDnb);
}
System.out.println("完成小时耗量告警定时任务");
return R.ok();
}
}

@ -6,6 +6,7 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
*
@ -15,6 +16,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
@EnableDubbo
@SpringBootApplication
@EnableConfigurationProperties(MesProperties.class)
@EnableScheduling
public class HwMomEmsApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(HwMomEmsApplication.class);

@ -79,19 +79,19 @@ public interface IEmsRecordAlarmDataService
*/
public int handleExceptionsAlarmData(Long[] objIds);
/**
/* *//**
*
*/
*//*
public void collectDeviceAlarmsTask();
/**
*//**
*
*/
*//*
public void exceedDnbThresholdAlarmsTask();
/**
*//**
*
*/
public void hourlyConsumptionAlarmsTask();
*//*
public void hourlyConsumptionAlarmsTask();*/
}

@ -24,6 +24,7 @@ import org.dromara.ems.record.mapper.EmsRecordDnbInstantMapper;
import org.dromara.ems.record.service.IEmsRecordAlarmDataService;
import org.dromara.ems.report.domain.EmsReportPointDnb;
import org.dromara.ems.report.mapper.EmsReportPointDnbMapper;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
@ -192,10 +193,15 @@ public class EmsRecordAlarmDataServiceImpl implements IEmsRecordAlarmDataService
}
return 1;
}
/*
/**
*/
/**
*
*/
*//*
// @Scheduled(cron = "0 0/9 * * * ?")
@Transactional(rollbackFor = Exception.class)
public void collectDeviceAlarmsTask() {
long minuteValue = 1000 * 60;
Date date = new Date();
@ -235,9 +241,13 @@ public class EmsRecordAlarmDataServiceImpl implements IEmsRecordAlarmDataService
}
}
/**
*/
/**
*
*/
*//*
// @Scheduled(cron = "0 0/8 * * * ?")
@Transactional(rollbackFor = Exception.class)
public void exceedDnbThresholdAlarmsTask() {
EmsBaseMonitorThreshold monitorThreshold = new EmsBaseMonitorThreshold();
monitorThreshold.setMonitorType(2L);
@ -267,13 +277,15 @@ public class EmsRecordAlarmDataServiceImpl implements IEmsRecordAlarmDataService
}
/**
*/
/**
*
*
* @param baseDnbThresholds
* @param recordDnbInstants
* @return
*/
*//*
public Map<String, String> compareThresholdAndRecord(List<EmsBaseMonitorThreshold> baseDnbThresholds, List<EmsRecordDnbInstant> recordDnbInstants) {
Map<String, String> resultMap = new HashMap<>();
for (EmsRecordDnbInstant recordDnbInstant : recordDnbInstants) {
@ -343,9 +355,13 @@ public class EmsRecordAlarmDataServiceImpl implements IEmsRecordAlarmDataService
return null;
}
/**
*/
/**
*
*/
*//*
// @Scheduled(cron = "0 0 0/1 * * ?")
@Transactional(rollbackFor = Exception.class)
public void hourlyConsumptionAlarmsTask() {
EmsBaseMonitorThreshold monitorThreshold = new EmsBaseMonitorThreshold();
monitorThreshold.setMonitorType(2L);
@ -361,5 +377,6 @@ public class EmsRecordAlarmDataServiceImpl implements IEmsRecordAlarmDataService
}
}
*/
}

@ -115,14 +115,21 @@
<version>2.2.2</version>
</dependency>
<!--
<dependency>
<groupId>com.aizuda</groupId>
<artifactId>snail-job-datasource-template</artifactId>
<version>1.4.0</version>
<scope>compile</scope>
<groupId>org.dromara</groupId>
<artifactId>hwmom-api-ems</artifactId>
<version>2.2.2</version>
</dependency>
-->
<!--
<dependency>
<groupId>com.aizuda</groupId>
<artifactId>snail-job-datasource-template</artifactId>
<version>1.4.0</version>
<scope>compile</scope>
</dependency>
-->
</dependencies>

@ -0,0 +1,38 @@
package org.dromara.job.snailjob;
import com.aizuda.snailjob.client.job.core.annotation.JobExecutor;
import com.aizuda.snailjob.client.job.core.dto.JobArgs;
import com.aizuda.snailjob.client.model.ExecuteResult;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.dubbo.config.annotation.DubboReference;
import org.dromara.common.core.domain.R;
import org.dromara.ems.api.RemoteEmsTaskService;
import org.springframework.stereotype.Component;
@Component
@JobExecutor(name = "collectDeviceAlarmsTask")
public class EmsCollectDeviceAlarmsTask {
private static final ObjectMapper objectMapper = new ObjectMapper();
@DubboReference(timeout = 60000)
private RemoteEmsTaskService remoteEmsTaskService;
public EmsCollectDeviceAlarmsTask(RemoteEmsTaskService remoteEmsTaskService) {
this.remoteEmsTaskService = remoteEmsTaskService;
}
public ExecuteResult jobExecute(JobArgs jobArgs) {
try {
R<Void> instance = remoteEmsTaskService.collectDeviceAlarmsTask();
return ExecuteResult.success(instance);
} catch (Exception e) {
return ExecuteResult.failure(e.getMessage());
}
}
}

@ -0,0 +1,38 @@
package org.dromara.job.snailjob;
import com.aizuda.snailjob.client.job.core.annotation.JobExecutor;
import com.aizuda.snailjob.client.job.core.dto.JobArgs;
import com.aizuda.snailjob.client.model.ExecuteResult;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.dubbo.config.annotation.DubboReference;
import org.dromara.common.core.domain.R;
import org.dromara.ems.api.RemoteEmsTaskService;
import org.springframework.stereotype.Component;
@Component
@JobExecutor(name = "exceedDnbThresholdAlarmsTask")
public class EmsExceedDnbThresholdAlarmsTask {
private static final ObjectMapper objectMapper = new ObjectMapper();
@DubboReference(timeout = 60000)
private RemoteEmsTaskService remoteEmsTaskService;
public EmsExceedDnbThresholdAlarmsTask(RemoteEmsTaskService remoteEmsTaskService) {
this.remoteEmsTaskService = remoteEmsTaskService;
}
public ExecuteResult jobExecute(JobArgs jobArgs) {
try {
R<Void> instance = remoteEmsTaskService.exceedDnbThresholdAlarmsTask();
return ExecuteResult.success(instance);
} catch (Exception e) {
return ExecuteResult.failure(e.getMessage());
}
}
}

@ -0,0 +1,38 @@
package org.dromara.job.snailjob;
import com.aizuda.snailjob.client.job.core.annotation.JobExecutor;
import com.aizuda.snailjob.client.job.core.dto.JobArgs;
import com.aizuda.snailjob.client.model.ExecuteResult;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.dubbo.config.annotation.DubboReference;
import org.dromara.common.core.domain.R;
import org.dromara.ems.api.RemoteEmsTaskService;
import org.springframework.stereotype.Component;
@Component
@JobExecutor(name = "hourlyConsumptionAlarmsTask")
public class EmsHourlyConsumptionAlarmsTask {
private static final ObjectMapper objectMapper = new ObjectMapper();
@DubboReference(timeout = 60000)
private RemoteEmsTaskService remoteEmsTaskService;
public EmsHourlyConsumptionAlarmsTask(RemoteEmsTaskService remoteEmsTaskService) {
this.remoteEmsTaskService = remoteEmsTaskService;
}
public ExecuteResult jobExecute(JobArgs jobArgs) {
try {
R<Void> instance = remoteEmsTaskService.hourlyConsumptionAlarmsTask();
return ExecuteResult.success(instance);
} catch (Exception e) {
return ExecuteResult.failure(e.getMessage());
}
}
}
Loading…
Cancel
Save