diff --git a/jeecg-boot-base-core/pom.xml b/jeecg-boot-base-core/pom.xml
index dd73b651..1e5181eb 100644
--- a/jeecg-boot-base-core/pom.xml
+++ b/jeecg-boot-base-core/pom.xml
@@ -252,6 +252,11 @@
commons-fileupload
commons-fileupload
+
+
+ commons-net
+ commons-net
+ 3.3
+
-
\ No newline at end of file
diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/EmailConstant.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/EmailConstant.java
new file mode 100644
index 00000000..b547a7ee
--- /dev/null
+++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/EmailConstant.java
@@ -0,0 +1,9 @@
+package org.jeecg.common.constant;
+
+/**
+ * 邮件服务常量
+ */
+public class EmailConstant {
+
+ public static final String EMAIL_STATUS_PREFIX = "email_status";
+}
diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/email/EmailServiceManager.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/email/EmailServiceManager.java
new file mode 100644
index 00000000..70feb479
--- /dev/null
+++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/email/EmailServiceManager.java
@@ -0,0 +1,204 @@
+package org.jeecg.common.email;
+
+import com.google.common.collect.Lists;
+import com.sun.mail.imap.IMAPStore;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.email.emuns.MailContentType;
+import org.jeecg.modules.base.entity.SysEmail;
+import org.jetbrains.annotations.NotNull;
+import javax.mail.*;
+import javax.mail.internet.MimeUtility;
+import java.io.*;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * 邮件服务管理器
+ */
+@Slf4j
+public class EmailServiceManager {
+
+ private SysEmail email;
+ /** 邮件接收数量 */
+ private Integer receiveNum;
+ /** smtp协议的存储对象 */
+ private IMAPStore store = null;
+ /** 邮件附件临时存储路径 */
+ private String temporaryStoragePath;
+ /** 收件箱 */
+ private Folder folder = null;
+
+ @NotNull
+ public static EmailServiceManager getInstance(){
+ return new EmailServiceManager();
+ }
+
+ /**
+ * 初始化邮件服务管理器
+ * @param email 邮件属性
+ */
+ public void init(SysEmail email){
+ this.email = email;
+ }
+
+ /**
+ * 初始化邮件服务管理器
+ * @param email 邮件属性
+ */
+ public void init(SysEmail email,Integer receiveNum,String temporaryStoragePath){
+ this.email = email;
+ this.receiveNum = receiveNum;
+ this.temporaryStoragePath = temporaryStoragePath;
+ }
+
+ /**
+ * 测试邮件服务连通性
+ */
+ public boolean testConnectEmailServer(){
+ Socket socket = new Socket();
+ boolean flag = false;
+ try {
+ socket.connect(new InetSocketAddress(email.getEmailServerAddress(),email.getPort()),5000);
+ log.info("{}邮件服务连接测试成功",email.getEmailServerAddress());
+ flag = true;
+ } catch (IOException e) {
+ log.error("{}邮件服务连接测试失败,请检查邮件服务属性配置是否正确或邮件服务未开启,原因{}",email.getEmailServerAddress(),e.getMessage());
+ }finally {
+ try {
+ if(null != socket){
+ socket.close();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ return flag;
+ }
+
+ /**
+ * 接收邮件
+ */
+ public Message[] receiveMail() throws MessagingException {
+ //配置邮件服务属性
+ Properties props = new Properties();
+ props.put("mail.store.protocol","imap");
+ props.put("mail.imap.host",email.getEmailServerAddress());
+ props.put("mail.imap.port",email.getPort());
+ //获取邮件回话
+ final Session session = Session.getInstance(props, new Authenticator() {
+ @Override
+ protected PasswordAuthentication getPasswordAuthentication() {
+ return new PasswordAuthentication(email.getUsername(), email.getPassword());
+ }
+ });
+ Map iam = new HashMap<>();
+ iam.put("name", "myname");
+ iam.put("version", "1.0.0");
+ iam.put("vendor", "myclient");
+ iam.put("support-email", "testmail@test.com");
+ //获取smtp协议的存储对象
+ store = (IMAPStore) session.getStore();
+ //连接
+ store.connect();
+ store.id(iam);
+ //获取收件箱
+ folder = store.getFolder("INBOX");
+ folder.open(Folder.READ_WRITE);
+ //获取邮件数量
+ final int messageCount = folder.getMessageCount();
+ if(messageCount > 0){
+ Integer start = 1;
+ Integer end = this.receiveNum>messageCount?messageCount:this.receiveNum;
+ final Message[] messages = folder.getMessages(start,end);
+ return messages;
+ }
+ return null;
+ }
+
+ /**
+ * 获取邮件内容
+ * @param part
+ * @return
+ * @throws MessagingException
+ * @throws IOException
+ */
+ public void getMailContent(@NotNull Part part, StringBuilder content) throws MessagingException, IOException {
+ Multipart multipart = (Multipart) part.getContent();
+ for(int i=0;i saveAttachment(@NotNull Part part) throws MessagingException, IOException {
+ List filePathList = Lists.newArrayList();
+ Multipart multipart = (Multipart) part.getContent();
+ for(int i=0;i paths = Arrays.asList(localPath.split("/"));
+ if (CollectionUtils.isNotEmpty(paths)){
+ for (String workPath:paths) {
+ //切换工作文件路径
+ ftpClient.changeWorkingDirectory(workPath);
+ }
+ }
+ ftpClient.enterLocalPassiveMode();
+ ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
+ // 设置编码,当文件中存在中文且上传后文件乱码时可使用此配置项
+ ftpClient.setControlEncoding(encoding);
+ ftpClient.setFileTransferMode(FTPClient.STREAM_TRANSFER_MODE);
+ List ftpFiles = Arrays.asList(ftpClient.listFiles());
+ if (CollectionUtils.isNotEmpty(ftpFiles)){
+ for (FTPFile ftpFile:ftpFiles) {
+ if (ftpFile.getName().equals(fileName)){
+ in = ftpClient.retrieveFileStream(new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
+ }
+ }
+ }
+ //重置响应信息
+ response.reset();
+ //设置响应类型
+ response.setContentType("application/download");
+ //解决中文不能生成文件
+ response.setHeader("Content-Disposition", "attachment; fileName=" + URLEncoder.encode(fileName,"UTF-8"));
+ response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
+ //获取输出流
+ out = response.getOutputStream();
+ //声明一个长度参数
+ int len;
+ //声明字节数组
+ byte[] bytes = new byte[1024];
+ //判断如果输入流的字节长度不等于-1,进行字节数组内容的读取
+ while ((len = in.read(bytes)) != -1) {
+ out.write(bytes, 0, len);
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ } finally {
+ try {
+ out.flush();
+ if (out != null) {
+ out.close();
+ }
+ if (in != null) {
+ in.close();
+ }
+ if (ftpClient != null){
+ ftpClient.disconnect();
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ /**
+ * 检查目录是否存在,不存在则创建,支持递归创建
+ * @param path 目录路径
+ * @return 返回值true/false
+ */
+ public boolean checkDirectory(String path) {
+ final FTPClient ftpClient = this.LoginFTP();
+ try {
+ final boolean flag = this.checkDirectory(ftpClient, path);
+ return flag;
+ }catch (IOException e){
+ e.printStackTrace();
+ return false;
+ }finally {
+ try {
+ ftpClient.disconnect();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * 检查目录是否存在,不存在则创建,支持递归创建
+ * @param ftpClient FTP客户端
+ * @param path 目录路径
+ * @return 返回值true/false
+ * @throws IOException
+ */
+ private boolean checkDirectory(FTPClient ftpClient,String path) throws IOException {
+ final String rootPath = ftpClient.printWorkingDirectory();
+ final boolean changeFlag = ftpClient.changeWorkingDirectory(rootPath);
+ if(!changeFlag){
+ log.error("{},根目录切换失败",rootPath);
+ return false;
+ }
+ String[] directories = path.split("/");
+ for(String directory : directories){
+ if(StringUtils.isEmpty(directory)){
+ continue;
+ }
+ if(!ftpClient.changeWorkingDirectory(directory)){
+ if(!ftpClient.makeDirectory(directory)){
+ log.error("{},目录创建失败",directory);
+ return false;
+ }
+ if(!ftpClient.changeWorkingDirectory(directory)){
+ log.error("{},目录切换失败",directory);
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * 写入文件,若文件或文件目录不存在则自行创建
+ * @param filePath 文件路径
+ * @param fileName 文件名称
+ * @param inputStream 文件输入流
+ * @return 返回值true/false
+ */
+ public boolean saveFile(String filePath,String fileName,InputStream inputStream){
+ final FTPClient ftpClient = this.LoginFTP();
+ try{
+ final boolean flag = this.checkDirectory(ftpClient,filePath);
+ if(flag){
+ ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
+ String encodedName = new String(fileName.getBytes(StandardCharsets.UTF_8),StandardCharsets.ISO_8859_1);
+ final boolean result = ftpClient.storeFile(encodedName, inputStream);
+ return result;
+ }
+ }catch (IOException e){
+ log.error("{}文件创建失败,原因为:{}",filePath+"/"+fileName,e.getMessage());
+ e.printStackTrace();
+ return false;
+ }finally {
+ try {
+ ftpClient.disconnect();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ return false;
+ }
+
+ /**
+ * 删除文件
+ * @param filePath 文件路径
+ * @param fileName 文件名称
+ * @return 返回值true/false
+ */
+ public boolean removeFile(String filePath,String fileName){
+ final FTPClient ftpClient = this.LoginFTP();
+ try {
+ final String rootPath = ftpClient.printWorkingDirectory();
+ final boolean changeFlag = ftpClient.changeWorkingDirectory(rootPath);
+ if(!changeFlag){
+ log.error("{},根目录切换失败",rootPath);
+ return false;
+ }
+ String[] directories = filePath.split("/");
+ for(String directory : directories){
+ if(StringUtils.isEmpty(directory)){
+ continue;
+ }
+ if(!ftpClient.changeWorkingDirectory(directory)){
+ log.error("此文件目录不存在:{}",filePath);
+ return false;
+ }
+ }
+ boolean result = ftpClient.deleteFile(new String(fileName.getBytes(StandardCharsets.UTF_8),StandardCharsets.ISO_8859_1));
+ if(!result){
+ log.error("此文件不存在:{}",filePath+"/"+fileName);
+ }
+ return result;
+ } catch (IOException e) {
+ log.error("{}文件删除失败,原因为:{}",filePath,e.getMessage());
+ e.printStackTrace();
+ return false;
+ }finally {
+ try {
+ ftpClient.disconnect();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+}
diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/config/valid/InsertGroup.java b/jeecg-boot-base-core/src/main/java/org/jeecg/config/valid/InsertGroup.java
similarity index 100%
rename from jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/config/valid/InsertGroup.java
rename to jeecg-boot-base-core/src/main/java/org/jeecg/config/valid/InsertGroup.java
diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/config/valid/UpdateGroup.java b/jeecg-boot-base-core/src/main/java/org/jeecg/config/valid/UpdateGroup.java
similarity index 100%
rename from jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/config/valid/UpdateGroup.java
rename to jeecg-boot-base-core/src/main/java/org/jeecg/config/valid/UpdateGroup.java
diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/GardsMetData.java b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/GardsMetData.java
new file mode 100644
index 00000000..54d65a55
--- /dev/null
+++ b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/GardsMetData.java
@@ -0,0 +1,100 @@
+package org.jeecg.modules.base.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+@TableName(value = "gards_met_data")
+public class GardsMetData implements Serializable {
+
+ /**
+ * 台站id
+ */
+ @TableField(value = "STATION_ID")
+ private Integer stationId;
+
+ /**
+ * 台站编码
+ */
+ @TableField(value = "STATION_CODE")
+ private String stationCode;
+
+ /**
+ * 气象数据id
+ */
+ @TableField(value = "MET_ID")
+ private Integer metId;
+
+ /**
+ * 开始时间
+ */
+ @TableField(value = "START_TIME")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ private Date startTime;
+
+ /**
+ * 结束时间
+ */
+ @TableField(value = "END_TIME")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ private Date endTime;
+
+ /**
+ * 平均湿度(%)
+ */
+ @TableField(value = "AVE_HUMIDITY")
+ private Integer aveHumidity;
+
+ /**
+ * 平均温度(℃)
+ */
+ @TableField(value = "AVGTEMPERATURE")
+ private Integer avgtemperature;
+
+ /**
+ * 平均压力(hPa)
+ */
+ @TableField(value = "AVE_PRESSURE")
+ private Integer avePressure;
+
+ /**
+ * 平均风向(偏离正北的度数)
+ */
+ @TableField(value = "AVE_WIND_DIR")
+ private Integer aveWindDir;
+
+ /**
+ * 平均风速(m/s)
+ */
+ @TableField(value = "AVE_WIND_SPEED")
+ private Integer aveWindSpeed;
+
+ /**
+ * 降雨量(mm)
+ */
+ @TableField(value = "RAINFALL")
+ private Integer rainfall;
+
+ /**
+ * 文件路径
+ */
+ @TableField(value = "INPUT_FILE_NAME")
+ private String inputFileName;
+
+ /**
+ * 操作时间
+ */
+ @TableField(value = "MODDATE")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ private Date moddate;
+
+}
diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/GardsSampleData.java b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/GardsSampleData.java
similarity index 66%
rename from jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/GardsSampleData.java
rename to jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/GardsSampleData.java
index b641ac6d..41a7a183 100644
--- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/GardsSampleData.java
+++ b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/GardsSampleData.java
@@ -1,4 +1,4 @@
-package org.jeecg.modules.system.entity;
+package org.jeecg.modules.base.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
@@ -13,77 +13,147 @@ import java.util.Date;
@TableName("GARDS_SAMPLE_DATA")
public class GardsSampleData implements Serializable {
+ /**
+ * 探测器编码
+ */
@TableField(value = "SITE_DET_CODE")
private String siteDetCode;
+ /**
+ * 样品id
+ */
@TableField(value = "SAMPLE_ID")
private Integer sampleId;
+ /**
+ * 台站id
+ */
@TableField(value = "STATION_ID")
private Integer stationId;
+ /**
+ * 探测器id
+ */
@TableField(value = "DETECTOR_ID")
private Integer detectorId;
+ /**
+ * 导入文件名称
+ */
@TableField(value = "INPUT_FILE_NAME")
private String inputFileName;
+ /**
+ * 系统类型(P : particulate; B :gas with 3-D β-γ coincidence detection; G :all other gas systems (high-resolution
+ * γ-spectrometry or 2-D β-γ coincidence
+ * detection))
+ */
@TableField(value = "SAMPLE_TYPE")
private String sampleType;
+ /**
+ * 数据类型(S:SAMPLEPHD
+ * B:BLANKPHD
+ * D:DETBKPHD
+ * G:GASBKPHD
+ * C:CALIBPHD
+ * Q:QCPHD)
+ */
@TableField(value = "DATA_TYPE")
private String dataType;
+ /**
+ * 几何尺寸
+ */
@TableField(value = "GEOMETRY")
private String geometry;
+ /**
+ * 能谱限定符: 过程谱(PREL) 和 全谱(FULL)
+ */
@TableField(value = "SPECTRAL_QUALIFIE")
private String spectralQualifie;
+ /**
+ * 报文发送日期
+ */
@TableField(value = "TRANSMIT_DTG")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date transmitDtg;
+ /**
+ * 样品采集开始时间
+ */
@TableField(value = "COLLECT_START")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date collectStart;
+ /**
+ * 样品采集结束时间
+ */
@TableField(value = "COLLECT_STOP")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date collectStop;
+ /**
+ * 样品测量开始时间
+ */
@TableField(value = "ACQUISITION_START")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date acquisitionStart;
+ /**
+ * 样品测量结束时间
+ */
@TableField(value = "ACQUISITION_STOP")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date acquisitionStop;
+ /**
+ * 能谱获取实时间
+ */
@TableField(value = "ACQUISITION_REAL_SEC")
private Double acquisitionRealSec;
+ /**
+ * 能谱获取活时间
+ */
@TableField(value = "ACQUISITION_LIVE_SEC")
private Double acquisitionLiveSec;
+ /**
+ * 采样量(立方米)
+ */
@TableField(value = "QUANTITY")
private Double quantity;
+ /**
+ * 样品处理状态
+ */
@TableField(value = "STATUS")
private String status;
+ /**
+ * 操作时间
+ */
@TableField(value = "MODDATE")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date moddate;
+ /**
+ * 台站名称
+ */
@TableField(exist = false)
private String stationName;
+ /**
+ * 探测器名称
+ */
@TableField(exist = false)
private String detectorsName;
diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/GardsSohData.java b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/GardsSohData.java
new file mode 100644
index 00000000..d05b83ed
--- /dev/null
+++ b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/GardsSohData.java
@@ -0,0 +1,90 @@
+package org.jeecg.modules.base.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+@TableName(value = "gards_soh_data")
+public class GardsSohData implements Serializable {
+
+ /**
+ * 台站ID号
+ */
+ @TableField(value = "STATION_ID")
+ private Integer stationId;
+
+ /**
+ * 台站代码
+ */
+ @TableField(value = "STATION_CODE")
+ private String stationCode;
+
+ /**
+ * 报警ID号
+ */
+ @TableField(value = "SOH_ID")
+ private Integer sohId;
+
+ /**
+ * 状态数据采集开始时间
+ */
+ @TableField(value = "START_TIME")
+ private Date startTime;
+
+ /**
+ * 时间间隔长度(秒)
+ */
+ @TableField(value = "TIME")
+ private Integer time;
+
+ /**
+ * 采样流速均值(scm/h)
+ */
+ @TableField(value = "AVGFLOWRATE")
+ private Integer avgflowrate;
+
+ /**
+ * 采样流速偏差(scm/h)
+ */
+ @TableField(value = "FLOWRATEDEV")
+ private Integer flowratedev;
+
+ /**
+ * 文件路径
+ */
+ @TableField(value = "INPUT_FILE_NAME")
+ private String inputFileName;
+
+ /**
+ * 探测器id
+ */
+ @TableField(value = "DETECTOR_ID")
+ private Integer detectorId;
+
+ /**
+ * 操作时间
+ */
+ @TableField(value = "MODDATE")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ private Date moddate;
+
+ /**
+ * 台站名称
+ */
+ @TableField(exist = false)
+ private String stationName;
+
+ /**
+ * 探测器名称
+ */
+ @TableField(exist = false)
+ private String detectorName;
+
+}
diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/SysEmail.java b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/SysEmail.java
new file mode 100644
index 00000000..72a9e2fe
--- /dev/null
+++ b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/SysEmail.java
@@ -0,0 +1,95 @@
+package org.jeecg.modules.base.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.time.LocalDate;
+import java.util.Date;
+
+/**
+ * 邮件管理数据表
+ */
+@Data
+@TableName(value = "sys_email")
+public class SysEmail implements Serializable {
+
+ @TableId(value = "id", type = IdType.ASSIGN_ID)
+ private String id;
+
+ /**
+ * email服务地址
+ */
+ @TableField(value = "email_server_address")
+ private String emailServerAddress;
+
+ /**
+ * 邮箱类型(1-收件地址,2-发件地址)
+ */
+ @TableField(value = "emil_type")
+ private Integer emilType;
+
+ /**
+ * 邮箱登录名称
+ */
+ @TableField(value = "username")
+ private String username;
+
+ /**
+ * 邮箱登录密码
+ */
+ @TableField(value = "password")
+ private String password;
+
+ /**
+ * 端口
+ */
+ @TableField(value = "port")
+ private Integer port;
+
+ /**
+ * 是否启用邮箱(0-不启用,1-启用)
+ */
+ @TableField(value = "enabled")
+ private Integer enabled;
+
+ /**
+ * 定时获取邮件时间周期(秒)
+ */
+ @TableField(value = "receive_mail_fixed_cycle")
+ private Integer receiveMailFixedCycle;
+
+ /**
+ * 创建日期
+ */
+ @TableField(value = "create_time")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ @DateTimeFormat(pattern = "yyyy-MM-dd")
+ private LocalDate createTime;
+
+ /**
+ * 创建人员
+ */
+ @TableField(value = "create_by")
+ private String createBy;
+
+ /**
+ * 修改日期
+ */
+ @TableField(value = "update_time")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ @DateTimeFormat(pattern = "yyyy-MM-dd")
+ private LocalDate updateTime;
+
+ /**
+ * 修改人员
+ */
+ @TableField(value = "update_by")
+ private String updateBy;
+
+}
diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/SysEmailLog.java b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/SysEmailLog.java
new file mode 100644
index 00000000..d297cda9
--- /dev/null
+++ b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/SysEmailLog.java
@@ -0,0 +1,58 @@
+package org.jeecg.modules.base.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+/**
+ * 邮件接收日志数据表
+ */
+@Data
+@TableName(value = "sys_email_log")
+public class SysEmailLog implements Serializable {
+
+ @TableId(value = "id", type = IdType.ASSIGN_ID)
+ private String id;
+
+ /**
+ * 邮件id
+ */
+ @TableField(value = "email_id")
+ private String emailId;
+
+ /**
+ * 邮件主题
+ */
+ @TableField(value = "subject")
+ private String subject;
+
+ /**
+ * 邮件内容
+ */
+ @TableField(value = "context")
+ private String context;
+
+ /**
+ * 接收时间
+ */
+ @TableField(value = "receive_time")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ private Date receiveTime;
+
+ /**
+ * 创建时间
+ */
+ @TableField(value = "create_time")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ private Date createTime;
+}
diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/struct/EnergySpectrumStruct.java b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/struct/EnergySpectrumStruct.java
new file mode 100644
index 00000000..dfa92128
--- /dev/null
+++ b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/struct/EnergySpectrumStruct.java
@@ -0,0 +1,363 @@
+package org.jeecg.modules.base.struct;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 能谱结构体字段信息
+ */
+@Data
+public class EnergySpectrumStruct implements Serializable {
+
+ /************************* Infomations ******************/
+ /**
+ * 消息类型
+ */
+ private String msg_type;
+ /**
+ * 消息id
+ */
+ private String msg_id;
+ /**
+ * 数据类型
+ */
+ private String data_type;
+
+ /************************* Header Black ******************/
+ /**
+ * designator
+ */
+ private String designator;
+ /**
+ * site code
+ */
+ private String site_code;
+ /**
+ * detector code
+ */
+ private String detector_code;
+ /**
+ * system type: P for particulate; B for gas with 3-D β - γ coincidence detection; and
+ */
+ private String system_type;
+ /**
+ * sample geometry
+ */
+ private String sample_geometry;
+ /**
+ * spectrum qualifier: preliminary ( PREL )or full ( FULL)
+ */
+ private String spectrum_quantity;
+ /**
+ * sample reference identification
+ */
+ private String sample_ref_id;
+ /**
+ * measurement identification
+ */
+ private String measurement_id;
+ /**
+ * detector background measurement identification
+ */
+ private String detector_bk_measurement_id;
+ /**
+ * gas background measurement identification (memory effect)
+ */
+ private String gas_bk_measurement_id;
+ /**
+ * transmit date (yyyy / mm / dd)
+ */
+ private String transmit_date;
+ /**
+ * transmit time (hh : mm : ss . s)
+ */
+ private String transmit_time;
+
+ /************************* Comment ******************/
+ private String comment;
+
+ /************************* Acquisition Block ******************/
+ /**
+ * acquisition start date (yyyy / mm / dd)
+ */
+ private String acquisition_start_date;
+ /**
+ * acquisition start time (hh : mm : ss . s)
+ */
+ private String acquisition_start_time;
+ /**
+ * acquisition real time (s)
+ */
+ private Double acquisition_real_time;
+ /**
+ * acquisition live time (s)
+ */
+ private Double acquisition_live_time;
+
+ /************************* Collection Block ******************/
+
+ /**
+ * collection start date (yyyy / mm / dd)
+ */
+ private String collection_start_date;
+ /**
+ * collection start time (hh : mm : ss . s)
+ */
+ private String collection_start_time;
+ /**
+ * collection stop date (yyyy / mm / dd)
+ */
+ private String collection_stop_date;
+ /**
+ * collection stop time (hh : mm : ss . s)
+ */
+ private String collection_stop_time;
+ /**
+ * total air volume sampled (standard cubic meters [scm])
+ */
+ private Double air_volume;
+
+ /************************* Processing Block ******************/
+ /**
+ * sample volume of Xe (cm 3 )
+ */
+ private Double sample_volume_of_Xe;
+ /**
+ * uncertainty (cm 3 )
+ */
+ private Double uncertainty_1;
+ /**
+ * Xe collection yield (Xe gas in sample/total Xe gas sampled)
+ */
+ private Double Xe_collection_yield;
+ /**
+ * uncertainty (Xe gas in sample/total Xe gas sampled)
+ */
+ private Double uncertainty_2;
+ /**
+ * archive bottle identification
+ */
+ private String archive_bottle_id;
+
+ /************************* Calibration Block ******************/
+ /**
+ * date of last calibration (yyyy / mm / dd)
+ */
+ private String date_calibration;
+ /**
+ * time of last calibration (hh : mm : ss)
+ */
+ private String time_calibration;
+
+ /************************* g_Energy Block ******************/
+ /**
+ * γ -energy (keV)
+ */
+ private List g_energy;
+ /**
+ * centroid channel
+ */
+ private List g_centroid_channel;
+ /**
+ * uncertainty (channels)
+ */
+ private List g_uncertainty;
+
+ private Integer g_record_count;
+
+ /************************* b_Energy Block ******************/
+ /**
+ * electron energy (keV)
+ */
+ private List b_electron_energy;
+ /**
+ * decay mode descriptor: B for β-particle, C for conversion electron (CE)
+ */
+ private List b_decay_mode;
+ /**
+ * maximum channel of β-particle distribution or centroid channel of CE (channels)
+ */
+ private List b_channel;
+ /**
+ * uncertainty (channels)
+ */
+ private List b_uncertainty;
+
+ private Integer b_record_count;
+
+ /************************* g_Resolution Block ******************/
+ /**
+ * γ -energy (keV)
+ */
+ private List g_r_energy;
+ /**
+ * FWHM (keV)
+ */
+ private List g_r_FWHM;
+ /**
+ * uncertainty (keV)
+ */
+ private List g_r_uncertainty;
+
+ private Integer g_r_record_count;
+
+ /************************* b_Resolution Block ******************/
+ /**
+ * electron energy (keV)
+ */
+ private List b_r_electron_energy;
+ /**
+ * FWHM (keV)
+ */
+ private List b_r_FWHM;
+ /**
+ * uncertainty (keV)
+ */
+ private List b_r_uncertainty;
+
+ private Integer b_r_record_count;
+
+ /************************* g_Efficiency Block ******************/
+ /**
+ * γ -energy (keV)
+ */
+ private List g_e_energy;
+ /**
+ * efficiency (counts in peak/photon emitted)
+ */
+ private List g_e_efficiency;
+ /**
+ * uncertainty (counts in peak/photon emitted)
+ */
+ private List g_e_uncertainty;
+
+ private Integer g_e_record_count;
+
+ /************************* ROI_Limits Block ******************/
+ /**
+ * ROI number
+ */
+ private List ROI_number;
+ /**
+ * 2-D ROI β-range start, x 1 (keV)
+ */
+ private List POI_B_x1;
+ /**
+ * 2-D ROI β-range stop, x 2 (keV)
+ */
+ private List POI_B_x2;
+ /**
+ * 2-D ROI γ-range start, y 1 (keV)
+ */
+ private List POI_G_y1;
+ /**
+ * 2-D ROI γ-range stop, y 2 (keV)
+ */
+ private List POI_G_y2;
+
+ private Integer roi_record_count;
+
+ /************************* b-gEfficiency Block ******************/
+ /**
+ * nuclide name
+ */
+ private List bg_nuclide_name;
+ /**
+ * ROI number
+ */
+ private List bg_ROI_number;
+ /**
+ * β-γ coincidence efficiency (counts in ROI/β-γ pair emitted)
+ */
+ private List bg_efficiency;
+ /**
+ * uncertainty (counts in ROI/β-γ pair emitted)
+ */
+ private List bg_uncertainty;
+
+ private Integer bg_record_count;
+
+ /************************* Ratios Block ******************/
+ /**
+ * ratio identifier
+ */
+ private List ratio_id;
+ /**
+ * ROI number for the higher γ -energy ROI
+ */
+ private List ROI_num_highter_G_energy_ROI;
+ /**
+ * ROI number for the lower γ -energy ROI
+ */
+ private List ROI_num_lower_G_energy_ROI;
+ /**
+ * Q_DECLARE_METATYPE(RMSSOHData::HeaderBlock)count ratio(counts in higher γ -energy ROI/counts in lower γ -energy ROI)
+ */
+ private List count_ratio;
+ /**
+ * count ratio uncertainty (percent)
+ */
+ private List count_ratio_uncertainty;
+
+ private Integer ratio_record_count;
+
+ /************************* g_Spectrum Block ******************/
+ /**
+ * number of γ channels
+ */
+ private Long num_g_channel;
+ /**
+ * γ-energy span (keV)
+ */
+ private Long g_energy_span;
+ /**
+ * begin of channels
+ */
+ private Long g_begin_channel;
+ /**
+ * count at channel
+ */
+ private List g_counts;
+
+ /************************* b_Spectrum Block ******************/
+ /**
+ * number of β -channels
+ */
+ private Long num_b_channel;
+ /**
+ * β -energy span (keV)
+ */
+ private Long b_energy_span;
+ /**
+ * begin of channels
+ */
+ private Long b_begin_channel;
+ /**
+ * counts at channels
+ */
+ private List b_counts;
+
+ /************************* Histogram Block ******************/
+ /**
+ * β-channels
+ */
+ private Long b_channels;
+ /**
+ * γ-channels
+ */
+ private Long g_channels;
+ /**
+ * β-energy span
+ */
+ private Long b_h_energy_span;
+ /**
+ * γ-energy span
+ */
+ private Long g_h_energy_span;
+ /**
+ * counts at channels
+ */
+ private List h_counts;
+}
diff --git a/jeecg-module-abnormal-alarm/pom.xml b/jeecg-module-abnormal-alarm/pom.xml
new file mode 100644
index 00000000..738e3429
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/pom.xml
@@ -0,0 +1,36 @@
+
+
+ 4.0.0
+
+ org.jeecgframework.boot
+ jeecg-boot-parent
+ 3.5.1
+
+
+ jeecg-module-abnormal-alarm
+
+
+ 5.8.19
+
+
+
+
+
+ org.jeecgframework.boot
+ jeecg-system-cloud-api
+
+
+
+ org.jeecgframework.boot
+ jeecg-boot-base-core
+
+
+
+ org.jeecgframework.boot
+ jeecg-boot-starter-cloud
+
+
+
+
\ No newline at end of file
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/controller/AlarmContactGroupController.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/controller/AlarmContactGroupController.java
new file mode 100644
index 00000000..0d2981dc
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/controller/AlarmContactGroupController.java
@@ -0,0 +1,48 @@
+package org.jeecg.modules.controller;
+
+import io.swagger.annotations.ApiOperation;
+import org.jeecg.common.api.QueryRequest;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.modules.entity.AlarmContactGroup;
+import org.jeecg.modules.service.IAlarmContactGroupService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("alarmContactGroup")
+public class AlarmContactGroupController {
+
+ @Autowired
+ private IAlarmContactGroupService alarmContactGroupService;
+
+ @GetMapping("findPage")
+ @ApiOperation(value = "分页查询报警联系人组信息", notes = "分页查询报警联系人组信息")
+ public Result findPage(QueryRequest queryRequest, AlarmContactGroup alarmContactGroup){
+ return alarmContactGroupService.findPage(queryRequest, alarmContactGroup);
+ }
+
+ @GetMapping("findInfo")
+ @ApiOperation(value = "查询报警联系人组信息详情", notes = "查询报警联系人组信息详情")
+ public Result findInfo(String id){
+ return alarmContactGroupService.findInfo(id);
+ }
+
+ @PostMapping("create")
+ @ApiOperation(value = "新增报警人联系人组", notes = "新增报警联系人组")
+ public Result create(@RequestBody AlarmContactGroup alarmContactGroup){
+ return alarmContactGroupService.create(alarmContactGroup);
+ }
+
+ @PutMapping("update")
+ @ApiOperation(value = "修改报警人联系人组", notes = "修改报警联系人组")
+ public Result update(@RequestBody AlarmContactGroup alarmContactGroup){
+ return alarmContactGroupService.update(alarmContactGroup);
+ }
+
+ @DeleteMapping("deleteById")
+ @ApiOperation(value = "删除报警人联系人组", notes = "删除报警联系人组")
+ public Result deleteById(String id){
+ return alarmContactGroupService.deleteById(id);
+ }
+
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/controller/AlarmLogController.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/controller/AlarmLogController.java
new file mode 100644
index 00000000..bc5d7bee
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/controller/AlarmLogController.java
@@ -0,0 +1,85 @@
+package org.jeecg.modules.controller;
+
+import io.swagger.annotations.ApiOperation;
+import org.jeecg.common.api.QueryRequest;
+import org.jeecg.common.api.dto.message.MessageDTO;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.constant.enums.MessageTypeEnum;
+import org.jeecg.common.system.api.ISysBaseAPI;
+import org.jeecg.modules.entity.AlarmLog;
+import org.jeecg.modules.service.IAlarmLogService;
+import org.jeecg.modules.vo.AlarmVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@RestController
+@RequestMapping("alarmLog")
+public class AlarmLogController {
+
+ @Autowired
+ private IAlarmLogService alarmLogService;
+
+ @Autowired
+ private ISysBaseAPI sysBaseAPI;
+
+ @ApiOperation("报警日志量总览-柱状图")
+ @PostMapping("viewAll")
+ public Result viewAll(@RequestBody AlarmVo alarmVo){ return alarmLogService.viewAll(alarmVo); }
+ @ApiOperation("分页查询报警日志信息")
+ @PostMapping("findPage")
+ public Result findPage(@RequestBody AlarmVo alarmVo){
+ return alarmLogService.findPage(alarmVo);
+ }
+ @ApiOperation("各类型报警量统计-饼图")
+ @PostMapping("typeAlarms")
+ public Result typeAlarms(@RequestBody AlarmVo alarmVo){
+ return alarmLogService.typeAlarms(alarmVo);
+ }
+ @ApiOperation("报警规则top5-柱状图")
+ @PostMapping("ruleTop")
+ public Result ruleTop5(@RequestBody AlarmVo alarmVo){
+ return alarmLogService.ruleTop5(alarmVo);
+ }
+
+ @GetMapping("findInfo")
+ @ApiOperation(value = "查询报警日志信息详情", notes = "查询报警日志信息详情")
+ public Result findInfo(String id){
+ return alarmLogService.findInfo(id);
+ }
+
+ @PostMapping("create")
+ @ApiOperation(value = "新增报警日志", notes = "新增报警日志")
+ public Result create(@RequestBody AlarmLog alarmLog){
+ return alarmLogService.create(alarmLog);
+ }
+
+ @PutMapping("update")
+ @ApiOperation(value = "修改报警日志", notes = "修改报警日志")
+ public Result update(@RequestBody AlarmLog alarmLog){
+ return alarmLogService.update(alarmLog);
+ }
+
+ @DeleteMapping("deleteById")
+ @ApiOperation(value = "删除报警日志", notes = "删除报警日志")
+ public Result deleteById(String id){
+ return alarmLogService.deleteById(id);
+ }
+
+ @GetMapping("test")
+ public void test(){
+ MessageDTO message = new MessageDTO();
+ message.setFromUser("admin");
+ message.setToUser("nieziyan");
+ message.setTitle("测试消息");
+ message.setType(MessageTypeEnum.XT.getType());
+ message.setTemplateCode("SYS001");
+ Map data = new HashMap<>();
+ data.put("userName","聂子炎");
+ data.put("taskName","请假申请");
+ message.setData(data);
+ sysBaseAPI.sendTemplateMessage(message);
+ }
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/controller/AlarmRuleController.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/controller/AlarmRuleController.java
new file mode 100644
index 00000000..7b49f9a8
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/controller/AlarmRuleController.java
@@ -0,0 +1,51 @@
+package org.jeecg.modules.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.jeecg.common.api.QueryRequest;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.modules.entity.AlarmRule;
+import org.jeecg.modules.service.IAlarmRuleService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("alarmRule")
+@Api(value = "报警规则管理", tags = "报警规则管理")
+public class AlarmRuleController {
+
+ @Autowired
+ private IAlarmRuleService alarmRuleService;
+
+ @GetMapping("findPage")
+ @ApiOperation(value = "分页查询报警规则信息", notes = "分页查询报警规则信息")
+ public Result findPage(QueryRequest queryRequest, AlarmRule alarmRule){
+ return alarmRuleService.findPage(queryRequest, alarmRule);
+ }
+
+ @GetMapping("findInfo")
+ @ApiOperation(value = "查看规则信息详情", notes = "查看规则信息详情")
+ public Result findInfo(String id){
+ return alarmRuleService.findInfo(id);
+ }
+
+ @PostMapping("create")
+ @ApiOperation(value = "新增规则信息", notes = "新增规则信息")
+ public Result create(@RequestBody AlarmRule alarmRule){
+ return alarmRuleService.create(alarmRule);
+ }
+
+ @PutMapping("update")
+ @ApiOperation(value = "修改规则信息", notes = "修改规则信息")
+ public Result update(@RequestBody AlarmRule alarmRule){
+ return alarmRuleService.update(alarmRule);
+ }
+
+ @DeleteMapping("deleteById")
+ @ApiOperation(value = "删除规则信息", notes = "删除规则信息")
+ public Result deleteById(String id){
+ return alarmRuleService.deleteById(id);
+ }
+
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/controller/SysDatabaseController.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/controller/SysDatabaseController.java
new file mode 100644
index 00000000..b98a6045
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/controller/SysDatabaseController.java
@@ -0,0 +1,61 @@
+package org.jeecg.modules.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.jeecg.common.api.QueryRequest;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.modules.entity.SysDatabase;
+import org.jeecg.modules.service.ISysDatabaseService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.Date;
+
+@RestController
+@RequestMapping("sysDatabase")
+@Api(value = "数据库配置管理", tags = "数据库配置管理")
+public class SysDatabaseController {
+
+ @Autowired
+ private ISysDatabaseService sysDatabaseService;
+
+ @GetMapping("findPage")
+ @ApiOperation(value = "分页查询数据库配置信息", notes = "分页查询数据库配置信息")
+ public Result findPage(QueryRequest queryRequest, SysDatabase sysDatabase){
+ return sysDatabaseService.findPage(queryRequest, sysDatabase);
+ }
+
+ @GetMapping("findInfo")
+ @ApiOperation(value = "查询数据库配置信息详情", notes = "查询数据库配置信息详情")
+ public Result findInfo(String id){
+ return sysDatabaseService.findInfo(id);
+ }
+
+ @PostMapping("create")
+ @ApiOperation(value = "新增数据库配置信息", notes = "新增数据库配置信息")
+ public Result create(@RequestBody SysDatabase sysDatabase){
+ return sysDatabaseService.create(sysDatabase);
+ }
+
+ @PutMapping("update")
+ @ApiOperation(value = "修改数据库配置信息", notes = "修改数据库配置信息")
+ public Result update(@RequestBody SysDatabase sysDatabase){
+ return sysDatabaseService.update(sysDatabase);
+ }
+
+ @DeleteMapping("deleteById")
+ @ApiOperation(value = "删除数据库配置信息", notes = "删除数据库配置信息")
+ public Result deleteById(String id){
+ return sysDatabaseService.deleteById(id);
+ }
+
+ @GetMapping("findAlarmHistory")
+ @ApiOperation(value = "查询数据库历史报警信息", notes = "查询数据库历史报警信息")
+ public Result findAlarmHistory(String databaseId,
+ @DateTimeFormat(pattern = "yyyy-MM-dd") Date startTime, @DateTimeFormat(pattern = "yyyy-MM-dd") Date endTime){
+ return sysDatabaseService.findAlarmHistory(databaseId, startTime, endTime);
+ }
+
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/controller/SysEmailController.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/controller/SysEmailController.java
new file mode 100644
index 00000000..cc5bc3fa
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/controller/SysEmailController.java
@@ -0,0 +1,60 @@
+package org.jeecg.modules.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.jeecg.common.api.QueryRequest;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.modules.base.entity.SysEmail;
+import org.jeecg.modules.service.ISysEmailService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Date;
+
+@RestController
+@RequestMapping("sysEmail")
+@Api(value = "邮箱配置信息管理", tags = "邮箱配置信息管理")
+public class SysEmailController {
+
+ @Autowired
+ private ISysEmailService sysEmailService;
+
+ @GetMapping("findPage")
+ @ApiOperation(value = "分页查询邮箱配置信息", notes = "分页查询邮箱配置信息")
+ public Result findPage(QueryRequest queryRequest, SysEmail sysEmail){
+ return sysEmailService.findPage(queryRequest, sysEmail);
+ }
+
+ @GetMapping("findInfo")
+ @ApiOperation(value = "查询邮箱配置信息详情", notes = "查询邮箱配置信息详情")
+ public Result findInfo(String id){
+ return sysEmailService.findInfo(id);
+ }
+
+ @PostMapping("create")
+ @ApiOperation(value = "新增邮箱配置信息", notes = "新增邮箱配置信息")
+ public Result create(@RequestBody SysEmail sysEmail){
+ return sysEmailService.create(sysEmail);
+ }
+
+ @PutMapping("update")
+ @ApiOperation(value = "修改邮箱配置信息", notes = "修改邮箱配置信息")
+ public Result update(@RequestBody SysEmail sysEmail){
+ return sysEmailService.update(sysEmail);
+ }
+
+ @DeleteMapping("deleteById")
+ @ApiOperation(value = "删除邮箱配置信息", notes = "删除邮箱配置信息")
+ public Result deleteById(String id){
+ return sysEmailService.deleteById(id);
+ }
+
+ @GetMapping("findAlarmHistory")
+ @ApiOperation(value = "查询邮箱历史报警信息", notes = "查询邮箱历史报警信息")
+ public Result findAlarmHistory(String emailId,
+ @DateTimeFormat(pattern = "yyyy-MM-dd") Date startTime, @DateTimeFormat(pattern = "yyyy-MM-dd") Date endTime){
+ return sysEmailService.findAlarmHistory(emailId, startTime, endTime);
+ }
+
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/controller/SysEmailLogController.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/controller/SysEmailLogController.java
new file mode 100644
index 00000000..8809fb5b
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/controller/SysEmailLogController.java
@@ -0,0 +1,200 @@
+package org.jeecg.modules.controller;
+
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.constant.EmailConstant;
+import org.jeecg.common.util.RedisUtil;
+import org.jeecg.modules.base.entity.SysEmailLog;
+import org.jeecg.modules.service.ISysEmailLogService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@RestController
+@RequestMapping("sysEmailLog")
+@Api(value = "邮箱日志", tags = "邮箱日志")
+public class SysEmailLogController {
+ @Autowired
+ private ISysEmailLogService sysEmailLogService;
+
+ @Autowired
+ private RedisUtil redisUtil;
+
+ /**
+ * 邮箱服务器连接状态 正常/断开
+ *
+ * @param emailId 电子邮件id
+ */
+ @GetMapping("status")
+ public Result status(@RequestParam("emailId") String emailId){
+ String key = EmailConstant.EMAIL_STATUS_PREFIX;
+ Boolean emailSatus = (Boolean) redisUtil.hget(key, emailId);
+ return Result.OK(emailSatus == null ? false : emailSatus);
+ }
+
+ @GetMapping("space")
+ public Result space(@RequestParam("emailId") String emailId){
+ return null;
+ }
+
+ /**
+ * 分别获取今天、昨天、过去一周邮件量
+ *
+ * @param emailId 电子邮件id
+ */
+ @GetMapping("total")
+ public Result totalEmail(@RequestParam("emailId") String emailId){
+ // 当日邮件量
+ LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
+ wrapper.eq(SysEmailLog::getEmailId,emailId);
+ LocalDate today = LocalDate.now();
+ String todayStart = today + " 00:00:00";
+ String todayEnd = today + " 23:59:59";
+ wrapper.between(SysEmailLog::getReceiveTime,todayStart,todayEnd);
+ Long todayCount = sysEmailLogService.count(wrapper);
+ // 昨日邮件量
+ wrapper.clear();
+ wrapper.eq(SysEmailLog::getEmailId,emailId);
+ LocalDate yesterday = LocalDate.now().minusDays(1);
+ String yesterdayStart = yesterday + " 00:00:00";
+ String yesterdayEnd = yesterday + " 23:59:59";
+ wrapper.between(SysEmailLog::getReceiveTime,yesterdayStart,yesterdayEnd);
+ Long yesterdayCount = sysEmailLogService.count(wrapper);
+ // 过去一周邮件量
+ wrapper.clear();
+ wrapper.eq(SysEmailLog::getEmailId,emailId);
+ LocalDate passWeek = LocalDate.now().minusWeeks(1);
+ String weekStart = passWeek + " 00:00:00";
+ wrapper.between(SysEmailLog::getReceiveTime,weekStart,todayEnd);
+ Long weekCount = sysEmailLogService.count(wrapper);
+
+ Map result = new HashMap<>();
+ result.put("today",todayCount);
+ result.put("yesterday",yesterdayCount);
+ result.put("week",weekCount);
+ return Result.OK(result);
+ }
+
+ /**
+ * 今天邮件接收量 按小时划分
+ *
+ * @param emailId 电子邮件id
+ */
+ @GetMapping("today")
+ public Result today(@RequestParam("emailId") String emailId){
+ LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
+ wrapper.eq(SysEmailLog::getEmailId,emailId);
+ LocalDate today = LocalDate.now();
+ String todayStart = today + " 00:00:00";
+ String todayEnd = today + " 23:59:59";
+ wrapper.between(SysEmailLog::getReceiveTime,todayStart,todayEnd);
+ List emailLogs = sysEmailLogService.list(wrapper);
+ // 将Date转换为LocalDateTime
+ List allDate = emailLogs.stream()
+ .map(SysEmailLog::getReceiveTime)
+ .collect(Collectors.toList());
+ List allTime = allDate.stream()
+ .map(item -> {
+ ZoneId zoneId = ZoneId.systemDefault();
+ return item.toInstant()
+ .atZone(zoneId)
+ .toLocalDateTime();
+ })
+ .collect(Collectors.toList());
+ // 按照小时分组
+ Map statistic = new TreeMap<>();
+ Map> groupTime = allTime.stream()
+ .collect(Collectors.groupingBy(LocalDateTime::getHour));
+ for (int i = 0; i < 24; i++) {
+ if(groupTime.containsKey(i)){
+ Integer count = groupTime.get(i).size();
+ statistic.put(timeStr(i),count);
+ }else {
+ statistic.put(timeStr(i),0);
+ }
+ }
+ return Result.OK(statistic);
+ }
+
+ /**
+ * 根据日期筛选(折线图)
+ *
+ * @param emailId 电子邮件id
+ */
+ @GetMapping("analysis")
+ public Result analysis(@RequestParam("emailId") String emailId,
+ @RequestParam("startDate") String startDate,
+ @RequestParam("endDate") String endDate){
+ String startStr = startDate + " 00:00:00";
+ String endStr = endDate + " 23:59:59";
+ LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
+ wrapper.eq(SysEmailLog::getEmailId,emailId);
+ wrapper.between(SysEmailLog::getReceiveTime,startStr,endStr);
+ Set xData = new HashSet<>();
+ Collection yData = new ArrayList<>();
+ Map statistic = new TreeMap<>();
+ Map result = new HashMap<>();
+ List allDate = sysEmailLogService.listObjs(wrapper,
+ emailLog -> ((SysEmailLog) emailLog).getReceiveTime());
+ // 将Date转换为LocalDateTime
+ List allTime = allDate.stream()
+ .map(item -> {
+ ZoneId zoneId = ZoneId.systemDefault();
+ return item.toInstant()
+ .atZone(zoneId)
+ .toLocalDateTime();
+ })
+ .collect(Collectors.toList());
+ if (CollUtil.isEmpty(allDate)){
+ result.put("xData",xData);
+ result.put("yData",yData);
+ return Result.OK(result);
+ }
+
+ /* 支持跨年跨月选择 */
+ // 通过年月日进行分组 例:2023-06-06
+ DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE;
+ Map> group = allTime.stream()
+ .collect(Collectors.groupingBy(datetime -> datetime.format(formatter)));
+
+ // 列举出startDate-endDate中所有日期(包括闰年)
+ // 没有邮件的日期,对应的值设置为0
+ LocalDate start = LocalDate.parse(startDate);
+ LocalDate end = LocalDate.parse(endDate);
+ while (!start.isAfter(end)) {
+ String key = start.format(formatter);
+ if (group.containsKey(key)){
+ Integer count = group.get(key).size();
+ statistic.put(key,count);
+ }else {
+ statistic.put(key,0);
+ }
+ start = start.plusDays(1);
+ }
+ // 返回结果
+ xData = statistic.keySet();
+ yData = statistic.values();
+ result.put("xData",xData);
+ result.put("yData",yData);
+ return Result.OK(result);
+ }
+
+ private String timeStr(Integer time){
+ if (time < 10){
+ return "0" + time + ":00";
+ }
+ return time + ":00";
+ }
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/controller/SysServerController.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/controller/SysServerController.java
new file mode 100644
index 00000000..73e45938
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/controller/SysServerController.java
@@ -0,0 +1,60 @@
+package org.jeecg.modules.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.jeecg.common.api.QueryRequest;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.modules.entity.SysServer;
+import org.jeecg.modules.service.ISysServerService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Date;
+
+@RestController
+@RequestMapping("sysServer")
+@Api(value = "服务器配置信息管理", tags = "服务器配置信息管理")
+public class SysServerController {
+
+ @Autowired
+ private ISysServerService sysServerService;
+
+ @GetMapping("findPage")
+ @ApiOperation(value = "分页查询服务器数据", notes = "分页查询服务器数据")
+ public Result findPage(QueryRequest queryRequest, SysServer sysServer){
+ return sysServerService.findPage(queryRequest, sysServer);
+ }
+
+ @GetMapping("findInfo")
+ @ApiOperation(value = "服务器数据详情信息", notes = "服务器数据详情信息")
+ public Result findInfo(String id){
+ return sysServerService.findInfo(id);
+ }
+
+ @PostMapping("create")
+ @ApiOperation(value = "新增服务器数据信息", notes = "新增服务器数据信息")
+ public Result create(@RequestBody SysServer sysServer){
+ return sysServerService.create(sysServer);
+ }
+
+ @PutMapping("update")
+ @ApiOperation(value = "修改服务器数据信息", notes = "修改服务器数据信息")
+ public Result update(@RequestBody SysServer sysServer){
+ return sysServerService.update(sysServer);
+ }
+
+ @DeleteMapping("deleteById")
+ @ApiOperation(value = "删除服务器数据信息", notes = "删除服务器数据信息")
+ public Result deleteById(String id){
+ return sysServerService.deleteById(id);
+ }
+
+ @GetMapping("findAlarmHistory")
+ @ApiOperation(value = "查询服务器历史报警信息", notes = "查询服务器历史报警信息")
+ public Result findAlarmHistory(String serverId,
+ @DateTimeFormat(pattern = "yyyy-MM-dd") Date startTime,@DateTimeFormat(pattern = "yyyy-MM-dd") Date endTime){
+ return sysServerService.findAlarmHistory(serverId, startTime, endTime);
+ }
+
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/dto/TypeDto.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/dto/TypeDto.java
new file mode 100644
index 00000000..0705453d
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/dto/TypeDto.java
@@ -0,0 +1,13 @@
+package org.jeecg.modules.dto;
+
+import lombok.Data;
+
+@Data
+public class TypeDto {
+ // 1.资源类型 Server|Database|Email
+ // 2.规则名
+ private String name;
+ // 1.报警量
+ // 2.规则使用量
+ private Integer value;
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/entity/AlarmContactGroup.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/entity/AlarmContactGroup.java
new file mode 100644
index 00000000..f5e6cc38
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/entity/AlarmContactGroup.java
@@ -0,0 +1,83 @@
+package org.jeecg.modules.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.time.LocalDate;
+import java.util.List;
+
+@Data
+@TableName(value = "alarm_contact_group")
+public class AlarmContactGroup implements Serializable {
+
+ /**
+ * id
+ */
+ @TableId(value = "id", type = IdType.ASSIGN_ID)
+ private String id;
+
+ /**
+ * 联系人组名称
+ */
+ @TableField(value = "name")
+ private String name;
+
+ /**
+ * 联系人组描述
+ */
+ @TableField(value = "description")
+ private String description;
+
+ /**
+ * 创建时间
+ */
+ @TableField(value = "create_time")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ @DateTimeFormat(pattern = "yyyy-MM-dd")
+ private LocalDate createTime;
+
+ /**
+ * 创建人
+ */
+ @TableField(value = "create_by")
+ private String createBy;
+
+ /**
+ * 修改时间
+ */
+ @TableField(value = "update_time")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ @DateTimeFormat(pattern = "yyyy-MM-dd")
+ private LocalDate updateTime;
+
+ /**
+ * 修改人
+ */
+ @TableField(value = "update_by")
+ private String updateBy;
+
+ /**
+ * 联系人组关联的用户id
+ */
+ @TableField(exist = false)
+ List userIds;
+
+ /**
+ * 联系人组关联的用户集合
+ */
+ @TableField(exist = false)
+ List users;
+
+ /**
+ * 当前联系人组人员数量
+ */
+ @TableField(exist = false)
+ Integer personNumber;
+
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/entity/AlarmContactGroupMember.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/entity/AlarmContactGroupMember.java
new file mode 100644
index 00000000..b236c9c9
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/entity/AlarmContactGroupMember.java
@@ -0,0 +1,33 @@
+package org.jeecg.modules.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+@TableName(value = "alarm_contact_group_member")
+public class AlarmContactGroupMember implements Serializable {
+
+ /**
+ * id
+ */
+ @TableId(value = "id", type = IdType.ASSIGN_ID)
+ private String id;
+
+ /**
+ * 联系人组id
+ */
+ @TableField(value = "group_id")
+ private String groupId;
+
+ /**
+ * 用户id
+ */
+ @TableField(value = "user_id")
+ private String userId;
+
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/entity/AlarmHistory.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/entity/AlarmHistory.java
new file mode 100644
index 00000000..46e3e173
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/entity/AlarmHistory.java
@@ -0,0 +1,38 @@
+package org.jeecg.modules.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDate;
+
+@Data
+public class AlarmHistory {
+
+ /**
+ * 名称
+ */
+ private String name;
+
+ /**
+ * 报警开始时间
+ */
+ @DateTimeFormat(pattern = "yyyy-MM-dd")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private LocalDate alarmStartDate;
+
+ /**
+ * 报警详情
+ */
+ private String alarmInfo;
+
+ /**
+ * 规则信息
+ */
+ private String operator;
+
+ /**
+ * 来源类型
+ */
+ private String sourceType;
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/entity/AlarmLog.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/entity/AlarmLog.java
new file mode 100644
index 00000000..5111fd21
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/entity/AlarmLog.java
@@ -0,0 +1,44 @@
+package org.jeecg.modules.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+@Data
+@TableName(value = "alarm_log")
+public class AlarmLog implements Serializable {
+
+ /**
+ * id
+ */
+ @TableId(value = "id", type = IdType.ASSIGN_ID)
+ private String id;
+
+ /**
+ * 规则id
+ */
+ @TableField(value = "rule_id")
+ private String ruleId;
+
+ /**
+ * 报警开始时间
+ */
+ @TableField(value = "alarm_start_date")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ private LocalDateTime alarmStartDate;
+
+ /**
+ * 报警详情
+ */
+ @TableField(value = "alarm_info")
+ private String alarmInfo;
+
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/entity/AlarmRule.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/entity/AlarmRule.java
new file mode 100644
index 00000000..9c5f8d37
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/entity/AlarmRule.java
@@ -0,0 +1,100 @@
+package org.jeecg.modules.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.time.LocalDate;
+
+@Data
+@TableName(value = "alarm_rule")
+public class AlarmRule implements Serializable {
+
+ /**
+ * id
+ */
+ @TableId(value = "id", type = IdType.ASSIGN_ID)
+ private String id;
+
+ /**
+ * 名称
+ */
+ @TableField(value = "name")
+ private String name;
+
+ /**
+ * 规则信息
+ */
+ @TableField(value = "operator")
+ private String operator;
+
+ /**
+ * 沉默周期,单位为秒
+ */
+ @TableField(value = "silence_cycle")
+ private Integer silenceCycle;
+
+ /**
+ * 报警通知方式,如短信、邮件等
+ */
+ @TableField(value = "notification")
+ private String notification;
+
+ /**
+ * 是否启用该报警规则(0-未启用,1-启用)
+ */
+ @TableField(value = "enabled")
+ private Integer enabled;
+
+ /**
+ * 报警联系人组id
+ */
+ @TableField(value = "contact_id")
+ private String contactId;
+
+ /**
+ * 资源id
+ */
+ @TableField(value = "source_id")
+ private String sourceId;
+
+ /**
+ * 资源类型
+ */
+ @TableField(value = "source_type")
+ private String sourceType;
+
+ /**
+ * 创建时间
+ */
+ @TableField(value = "create_time")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ @DateTimeFormat(pattern = "yyyy-MM-dd")
+ private LocalDate createTime;
+
+ /**
+ * 创建人
+ */
+ @TableField(value = "create_by")
+ private String createBy;
+
+ /**
+ * 修改时间
+ */
+ @TableField(value = "update_time")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ @DateTimeFormat(pattern = "yyyy-MM-dd")
+ private LocalDate updateTime;
+
+ /**
+ * 修改人
+ */
+ @TableField(value = "update_by")
+ private String updateBy;
+
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/entity/SysDatabase.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/entity/SysDatabase.java
new file mode 100644
index 00000000..68fc51fd
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/entity/SysDatabase.java
@@ -0,0 +1,94 @@
+package org.jeecg.modules.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.time.LocalDate;
+
+@Data
+@TableName(value = "sys_database")
+public class SysDatabase implements Serializable {
+
+ /**
+ * id
+ */
+ @TableId(value = "id", type = IdType.ASSIGN_ID)
+ private String id;
+
+ /**
+ * 名称
+ */
+ @TableField(value = "name")
+ private String name;
+
+ /**
+ * 状态(0-断开连接,1-连接成功)
+ */
+ @TableField(value = "status")
+ private Integer status;
+
+ /**
+ * ip地址
+ */
+ @TableField(value = "ip_address")
+ private String ipAddress;
+
+ /**
+ * 端口
+ */
+ @TableField(value = "port")
+ private String port;
+
+ /**
+ * 用户名称
+ */
+ @TableField(value = "username")
+ private String username;
+
+ /**
+ * 密码
+ */
+ @TableField(value = "password")
+ private String password;
+
+ /**
+ * 数据库类型
+ */
+ @TableField(value = "type")
+ private String type;
+
+ /**
+ * 创建时间
+ */
+ @TableField(value = "create_time")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ @DateTimeFormat(pattern = "yyyy-MM-dd")
+ private LocalDate createTime;
+
+ /**
+ * 创建人
+ */
+ @TableField(value = "create_by")
+ private String createBy;
+
+ /**
+ * 修改时间
+ */
+ @TableField(value = "update_time")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ @DateTimeFormat(pattern = "yyyy-MM-dd")
+ private LocalDate updateTime;
+
+ /**
+ * 修改人
+ */
+ @TableField(value = "update_by")
+ private String updateBy;
+
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/entity/SysRole.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/entity/SysRole.java
new file mode 100644
index 00000000..2e78e250
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/entity/SysRole.java
@@ -0,0 +1,80 @@
+package org.jeecg.modules.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecgframework.poi.excel.annotation.Excel;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ *
+ * 角色表
+ *
+ *
+ * @Author scott
+ * @since 2018-12-19
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class SysRole implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * id
+ */
+ @TableId(type = IdType.ASSIGN_ID)
+ private String id;
+
+ /**
+ * 角色名称
+ */
+ @Excel(name="角色名",width=15)
+ private String roleName;
+
+ /**
+ * 角色编码
+ */
+ @Excel(name="角色编码",width=15)
+ private String roleCode;
+
+ /**
+ * 描述
+ */
+ @Excel(name="描述",width=60)
+ private String description;
+
+ /**
+ * 创建人
+ */
+ private String createBy;
+
+ /**
+ * 创建时间
+ */
+ @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
+ @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+ private Date createTime;
+
+ /**
+ * 更新人
+ */
+ private String updateBy;
+
+ /**
+ * 更新时间
+ */
+ @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
+ @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+ private Date updateTime;
+
+ /**租户ID*/
+ private Integer tenantId;
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/entity/SysServer.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/entity/SysServer.java
new file mode 100644
index 00000000..ad4c7267
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/entity/SysServer.java
@@ -0,0 +1,70 @@
+package org.jeecg.modules.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.time.LocalDate;
+
+@Data
+@TableName(value = "sys_server")
+public class SysServer implements Serializable {
+
+ /**
+ * id
+ */
+ @TableId(value = "id", type = IdType.ASSIGN_ID)
+ private String id;
+
+ /**
+ * 名称
+ */
+ @TableField(value = "name")
+ private String name;
+
+ /**
+ * 状态(0-停机,1-正常,2-故障)
+ */
+ @TableField(value = "status")
+ private Integer status;
+
+ /**
+ * ip地址
+ */
+ @TableField(value = "ip_address")
+ private String ipAddress;
+
+ /**
+ * 创建时间
+ */
+ @TableField(value = "create_time")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ @DateTimeFormat(pattern = "yyyy-MM-dd")
+ private LocalDate createTime;
+
+ /**
+ * 创建人
+ */
+ @TableField(value = "create_by")
+ private String createBy;
+
+ /**
+ * 修改时间
+ */
+ @TableField(value = "update_time")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ @DateTimeFormat(pattern = "yyyy-MM-dd")
+ private LocalDate updateTime;
+
+ /**
+ * 修改人
+ */
+ @TableField(value = "update_by")
+ private String updateBy;
+
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/entity/SysUser.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/entity/SysUser.java
new file mode 100644
index 00000000..3db925de
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/entity/SysUser.java
@@ -0,0 +1,208 @@
+package org.jeecg.modules.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecg.common.aspect.annotation.Dict;
+import org.jeecgframework.poi.excel.annotation.Excel;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ *
+ * 用户表
+ *
+ *
+ * @Author scott
+ * @since 2018-12-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class SysUser implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * id
+ */
+ @TableId(type = IdType.ASSIGN_ID)
+ private String id;
+
+ /**
+ * 登录账号
+ */
+ @Excel(name = "登录账号", width = 15)
+ private String username;
+
+ /**
+ * 真实姓名
+ */
+ @Excel(name = "真实姓名", width = 15)
+ private String realname;
+
+ /**
+ * 密码
+ */
+ @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
+ private String password;
+
+ /**
+ * md5密码盐
+ */
+ @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
+ private String salt;
+
+ /**
+ * 头像
+ */
+ @Excel(name = "头像", width = 15,type = 2)
+ private String avatar;
+
+ /**
+ * 生日
+ */
+ @Excel(name = "生日", width = 15, format = "yyyy-MM-dd")
+ @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
+ @DateTimeFormat(pattern = "yyyy-MM-dd")
+ private Date birthday;
+
+ /**
+ * 性别(1:男 2:女)
+ */
+ @Excel(name = "性别", width = 15,dicCode="sex")
+ @Dict(dicCode = "sex")
+ private Integer sex;
+
+ /**
+ * 电子邮件
+ */
+ @Excel(name = "电子邮件", width = 15)
+ private String email;
+
+ /**
+ * 电话
+ */
+ @Excel(name = "电话", width = 15)
+ private String phone;
+
+ /**
+ * 登录选择部门编码
+ */
+ private String orgCode;
+ /**
+ * 登录选择租户ID
+ */
+ private Integer loginTenantId;
+
+ /**部门名称*/
+ private transient String orgCodeTxt;
+
+ /**
+ * 状态(1:正常 2:冻结 )
+ */
+ @Excel(name = "状态", width = 15,dicCode="user_status")
+ @Dict(dicCode = "user_status")
+ private Integer status;
+
+ /**
+ * 删除状态(0,正常,1已删除)
+ */
+ @Excel(name = "删除状态", width = 15,dicCode="del_flag")
+ @TableLogic
+ private Integer delFlag;
+
+ /**
+ * 工号,唯一键
+ */
+ @Excel(name = "工号", width = 15)
+ private String workNo;
+
+ /**
+ * 职务,关联职务表
+ */
+ @Excel(name = "职务", width = 15)
+ @Dict(dictTable ="sys_position",dicText = "name",dicCode = "code")
+ private String post;
+
+ /**
+ * 座机号
+ */
+ @Excel(name = "座机号", width = 15)
+ private String telephone;
+
+ /**
+ * 创建人
+ */
+ private String createBy;
+
+ /**
+ * 创建时间
+ */
+ private Date createTime;
+
+ /**
+ * 更新人
+ */
+ private String updateBy;
+
+ /**
+ * 更新时间
+ */
+ private Date updateTime;
+ /**
+ * 同步工作流引擎1同步0不同步
+ */
+ private Integer activitiSync;
+
+ /**
+ * 身份(0 普通成员 1 上级)
+ */
+ @Excel(name="(1普通成员 2上级)",width = 15)
+ private Integer userIdentity;
+
+ /**
+ * 负责部门
+ */
+ @Excel(name="负责部门",width = 15,dictTable ="sys_depart",dicText = "depart_name",dicCode = "id")
+ @Dict(dictTable ="sys_depart",dicText = "depart_name",dicCode = "id")
+ private String departIds;
+
+ /**
+ * 多租户ids临时用,不持久化数据库(数据库字段不存在)
+ */
+ @TableField(exist = false)
+ private String relTenantIds;
+
+ /**设备id uniapp推送用*/
+ private String clientId;
+
+ /**
+ * 登录首页地址
+ */
+ @TableField(exist = false)
+ private String homePath;
+
+ /**
+ * 职位名称
+ */
+ @TableField(exist = false)
+ private String postText;
+
+ @TableField(exist = false)
+ private List roles;
+
+ /**
+ * 流程状态
+ */
+ private String bpmStatus;
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/AlarmContactGroupMapper.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/AlarmContactGroupMapper.java
new file mode 100644
index 00000000..b381ec5f
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/AlarmContactGroupMapper.java
@@ -0,0 +1,7 @@
+package org.jeecg.modules.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.jeecg.modules.entity.AlarmContactGroup;
+
+public interface AlarmContactGroupMapper extends BaseMapper {
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/AlarmContactGroupMemberMapper.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/AlarmContactGroupMemberMapper.java
new file mode 100644
index 00000000..92c5f1a2
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/AlarmContactGroupMemberMapper.java
@@ -0,0 +1,7 @@
+package org.jeecg.modules.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.jeecg.modules.entity.AlarmContactGroupMember;
+
+public interface AlarmContactGroupMemberMapper extends BaseMapper {
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/AlarmLogMapper.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/AlarmLogMapper.java
new file mode 100644
index 00000000..689520b2
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/AlarmLogMapper.java
@@ -0,0 +1,23 @@
+package org.jeecg.modules.mapper;
+
+import com.baomidou.dynamic.datasource.annotation.DS;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.jeecg.modules.dto.TypeDto;
+import org.jeecg.modules.entity.AlarmHistory;
+import org.jeecg.modules.entity.AlarmLog;
+import org.jeecg.modules.vo.AlarmVo;
+
+import java.time.LocalDateTime;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+public interface AlarmLogMapper extends BaseMapper {
+
+ List rangeDay(Map params);
+ List findPage(Map params);
+
+ List typeAlarms(Map params);
+
+ List ruleTop5(Map params);
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/AlarmRuleMapper.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/AlarmRuleMapper.java
new file mode 100644
index 00000000..ed2b8536
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/AlarmRuleMapper.java
@@ -0,0 +1,7 @@
+package org.jeecg.modules.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.jeecg.modules.entity.AlarmRule;
+
+public interface AlarmRuleMapper extends BaseMapper {
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/SysDatabaseMapper.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/SysDatabaseMapper.java
new file mode 100644
index 00000000..c3be5b15
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/SysDatabaseMapper.java
@@ -0,0 +1,15 @@
+package org.jeecg.modules.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+import org.jeecg.modules.entity.AlarmHistory;
+import org.jeecg.modules.entity.SysDatabase;
+
+import java.util.Date;
+import java.util.List;
+
+public interface SysDatabaseMapper extends BaseMapper {
+
+ List findAlarmHistory(@Param("databaseId") String databaseId, @Param("startDate") Date startDate, @Param("endDate") Date endDate);
+
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/SysEmailLogMapper.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/SysEmailLogMapper.java
new file mode 100644
index 00000000..674ed114
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/SysEmailLogMapper.java
@@ -0,0 +1,14 @@
+package org.jeecg.modules.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.jeecg.modules.base.entity.SysEmailLog;
+
+/**
+ * 系统邮件日志
+ *
+ * @author nieziyan
+ * @date 2023-06-19
+ */
+public interface SysEmailLogMapper extends BaseMapper {
+
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/SysEmailMapper.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/SysEmailMapper.java
new file mode 100644
index 00000000..69ea7234
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/SysEmailMapper.java
@@ -0,0 +1,15 @@
+package org.jeecg.modules.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+import org.jeecg.modules.entity.AlarmHistory;
+import org.jeecg.modules.base.entity.SysEmail;
+
+import java.util.Date;
+import java.util.List;
+
+public interface SysEmailMapper extends BaseMapper {
+
+ List findAlarmHistory( @Param("emailId") String emailId, @Param("startDate") Date startDate, @Param("endDate") Date endDate);
+
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/SysServerMapper.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/SysServerMapper.java
new file mode 100644
index 00000000..14a05596
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/SysServerMapper.java
@@ -0,0 +1,15 @@
+package org.jeecg.modules.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+import org.jeecg.modules.entity.AlarmHistory;
+import org.jeecg.modules.entity.SysServer;
+
+import java.util.Date;
+import java.util.List;
+
+public interface SysServerMapper extends BaseMapper {
+
+ List findAlarmHistory(@Param("serverId")String serverId, @Param("startDate") Date startDate, @Param("endDate") Date endDate);
+
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/xml/AlarmLogMapper.xml b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/xml/AlarmLogMapper.xml
new file mode 100644
index 00000000..e6913a5c
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/xml/AlarmLogMapper.xml
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/xml/SysEmailLogMapper.xml b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/xml/SysEmailLogMapper.xml
new file mode 100644
index 00000000..b05d4dd6
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/xml/SysEmailLogMapper.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/xml/SysEmailMapper.xml b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/xml/SysEmailMapper.xml
new file mode 100644
index 00000000..5d471498
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/xml/SysEmailMapper.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/xml/SysServerMapper.xml b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/xml/SysServerMapper.xml
new file mode 100644
index 00000000..c8ff987a
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/xml/SysServerMapper.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/xml/sysDatabaseMapper.xml b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/xml/sysDatabaseMapper.xml
new file mode 100644
index 00000000..5be1a952
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/mapper/xml/sysDatabaseMapper.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/IAlarmContactGroupService.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/IAlarmContactGroupService.java
new file mode 100644
index 00000000..8bb41e4a
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/IAlarmContactGroupService.java
@@ -0,0 +1,20 @@
+package org.jeecg.modules.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.common.api.QueryRequest;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.modules.entity.AlarmContactGroup;
+
+public interface IAlarmContactGroupService extends IService {
+
+ Result findPage(QueryRequest queryRequest, AlarmContactGroup alarmContactGroup);
+
+ Result findInfo(String id);
+
+ Result create(AlarmContactGroup alarmContactGroup);
+
+ Result update(AlarmContactGroup alarmContactGroup);
+
+ Result deleteById(String id);
+
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/IAlarmLogService.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/IAlarmLogService.java
new file mode 100644
index 00000000..02984b2f
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/IAlarmLogService.java
@@ -0,0 +1,28 @@
+package org.jeecg.modules.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.common.api.QueryRequest;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.modules.entity.AlarmLog;
+import org.jeecg.modules.vo.AlarmVo;
+
+public interface IAlarmLogService extends IService {
+
+ Result viewAll(AlarmVo alarmVo);
+
+ Result findPage(AlarmVo alarmVo);
+
+ Result typeAlarms(AlarmVo alarmVo);
+
+ Result ruleTop5(AlarmVo alarmVo);
+
+ Result findInfo(String id);
+
+ Result create(AlarmLog alarmLog);
+
+ Result update(AlarmLog alarmLog);
+
+ Result deleteById(String id);
+
+
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/IAlarmRuleService.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/IAlarmRuleService.java
new file mode 100644
index 00000000..66add3bb
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/IAlarmRuleService.java
@@ -0,0 +1,20 @@
+package org.jeecg.modules.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.common.api.QueryRequest;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.modules.entity.AlarmRule;
+
+public interface IAlarmRuleService extends IService {
+
+ Result findPage(QueryRequest queryRequest, AlarmRule alarmRule);
+
+ Result findInfo(String id);
+
+ Result create(AlarmRule alarmRule);
+
+ Result update(AlarmRule alarmRule);
+
+ Result deleteById(String id);
+
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/IAlarmSysUserService.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/IAlarmSysUserService.java
new file mode 100644
index 00000000..1dc4a1f9
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/IAlarmSysUserService.java
@@ -0,0 +1,17 @@
+package org.jeecg.modules.service;
+
+import org.jeecg.modules.entity.SysUser;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import java.util.Map;
+
+@Component
+@FeignClient(value = "jeecg-system")
+public interface IAlarmSysUserService {
+
+ @RequestMapping("/sys/user/findUserMap")
+ Map findUserMap();
+
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/ISysDatabaseService.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/ISysDatabaseService.java
new file mode 100644
index 00000000..f5d6ced3
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/ISysDatabaseService.java
@@ -0,0 +1,25 @@
+package org.jeecg.modules.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.common.api.QueryRequest;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.modules.entity.SysDatabase;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+public interface ISysDatabaseService extends IService {
+
+ Result findPage(QueryRequest queryRequest, SysDatabase sysDatabase);
+
+ Result findInfo(String id);
+
+ Result create(SysDatabase sysDatabase);
+
+ Result update(SysDatabase sysDatabase);
+
+ Result deleteById(String id);
+
+ Result findAlarmHistory(String databaseId, Date startTime, Date endTime);
+
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/ISysEmailLogService.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/ISysEmailLogService.java
new file mode 100644
index 00000000..1b2816ef
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/ISysEmailLogService.java
@@ -0,0 +1,7 @@
+package org.jeecg.modules.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.modules.base.entity.SysEmailLog;
+
+public interface ISysEmailLogService extends IService {
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/ISysEmailService.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/ISysEmailService.java
new file mode 100644
index 00000000..4253a0fc
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/ISysEmailService.java
@@ -0,0 +1,24 @@
+package org.jeecg.modules.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.common.api.QueryRequest;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.modules.base.entity.SysEmail;
+
+import java.util.Date;
+
+public interface ISysEmailService extends IService {
+
+ Result findPage(QueryRequest queryRequest, SysEmail sysEmail);
+
+ Result findInfo(String id);
+
+ Result create(SysEmail sysEmail);
+
+ Result update(SysEmail sysEmail);
+
+ Result deleteById(String id);
+
+ Result findAlarmHistory(String emailId, Date startTime, Date endTime);
+
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/ISysServerService.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/ISysServerService.java
new file mode 100644
index 00000000..db5c97f0
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/ISysServerService.java
@@ -0,0 +1,24 @@
+package org.jeecg.modules.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.common.api.QueryRequest;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.modules.entity.SysServer;
+
+import java.util.Date;
+
+public interface ISysServerService extends IService {
+
+ Result findPage(QueryRequest queryRequest, SysServer sysServer);
+
+ Result findInfo(String id);
+
+ Result create(SysServer sysServer);
+
+ Result update(SysServer sysServer);
+
+ Result deleteById(String id);
+
+ Result findAlarmHistory(String serverId, Date startTime, Date endTime);
+
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/impl/AlarmContactGroupServiceImpl.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/impl/AlarmContactGroupServiceImpl.java
new file mode 100644
index 00000000..5eb89be6
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/impl/AlarmContactGroupServiceImpl.java
@@ -0,0 +1,171 @@
+package org.jeecg.modules.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.jeecg.common.api.QueryRequest;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.util.JwtUtil;
+import org.jeecg.common.util.SpringContextUtils;
+import org.jeecg.modules.entity.AlarmContactGroup;
+import org.jeecg.modules.entity.AlarmContactGroupMember;
+import org.jeecg.modules.entity.SysUser;
+import org.jeecg.modules.mapper.AlarmContactGroupMapper;
+import org.jeecg.modules.mapper.AlarmContactGroupMemberMapper;
+import org.jeecg.modules.service.IAlarmContactGroupService;
+import org.jeecg.modules.service.IAlarmSysUserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.servlet.http.HttpServletRequest;
+import java.time.LocalDate;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Service("alarmContactGroupService")
+public class AlarmContactGroupServiceImpl extends ServiceImpl implements IAlarmContactGroupService {
+
+ @Autowired
+ private AlarmContactGroupMemberMapper alarmContactGroupMemberMapper;
+ @Autowired
+ private IAlarmSysUserService alarmSysUserService;
+
+ @Override
+ public Result findPage(QueryRequest queryRequest, AlarmContactGroup alarmContactGroup) {
+ Result result = new Result();
+ //获取用户信息
+ Map userList = alarmSysUserService.findUserMap();
+ Page page = new Page<>();
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ Page alarmContactGroupPage = this.baseMapper.selectPage(page, queryWrapper);
+ LambdaQueryWrapper contactGroupMemberQueryWrapper = new LambdaQueryWrapper<>();
+ List alarmContactGroupMembers = alarmContactGroupMemberMapper.selectList(contactGroupMemberQueryWrapper);
+ alarmContactGroupPage.getRecords().forEach(item->{
+ List sysUsers = new LinkedList<>();
+ //联系人组对应联系人信息不为空
+ if (CollectionUtils.isNotEmpty(alarmContactGroupMembers)){
+ //根据联系人组id过滤出对应的联系人信息集合
+ List contactGroupMembers = alarmContactGroupMembers.stream().filter(member-> member.getGroupId().equals(item.getId())).collect(Collectors.toList());
+ item.setPersonNumber(contactGroupMembers.size());
+ //过滤出对应的用户id集合
+ List userIds = contactGroupMembers.stream().map(AlarmContactGroupMember::getUserId).collect(Collectors.toList());
+ //根据用户id获得对应的用户信息
+ if (CollectionUtils.isNotEmpty(userList)){
+ for (String userId:userIds) {
+ if (userList.containsKey(userId)){
+ sysUsers.add(userList.get(userId));
+ }
+ }
+ item.setUsers(sysUsers);
+ }
+ }
+ });
+ result.setSuccess(true);
+ result.setResult(alarmContactGroupPage);
+ return result;
+ }
+
+ @Override
+ public Result findInfo(String id) {
+ Result result = new Result();
+ //根据id查询对应的数据 判断数据是否在数据库中
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(AlarmContactGroup::getId, id);
+ AlarmContactGroup alarmContactGroup = this.baseMapper.selectOne(queryWrapper);
+ if (Objects.isNull(alarmContactGroup)){
+ result.error500("查询数据失败,对应数据不存在");
+ return result;
+ }
+ //通过联系人组id查询出对应的联系人信息
+ LambdaQueryWrapper contactGroupMemberQueryWrapper = new LambdaQueryWrapper<>();
+ contactGroupMemberQueryWrapper.eq(AlarmContactGroupMember::getGroupId, alarmContactGroup.getId());
+ List contactGroupMembers = alarmContactGroupMemberMapper.selectList(contactGroupMemberQueryWrapper);
+ if (CollectionUtils.isNotEmpty(contactGroupMembers)){
+ List userIds = contactGroupMembers.stream().map(AlarmContactGroupMember::getUserId).collect(Collectors.toList());
+ alarmContactGroup.setUserIds(userIds);
+ }
+ result.setSuccess(true);
+ result.setResult(alarmContactGroup);
+ return result;
+ }
+
+ @Override
+ public Result create(AlarmContactGroup alarmContactGroup) {
+ Result result = new Result();
+ //获取request
+ HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
+ //获取当前操作人用户名
+ String username = JwtUtil.getUserNameByToken(request);
+ Long id = IdWorker.getId();
+ alarmContactGroup.setId(id.toString());
+ alarmContactGroup.setCreateTime(LocalDate.now());
+ alarmContactGroup.setCreateBy(username);
+ if (CollectionUtils.isNotEmpty(alarmContactGroup.getUserIds())){
+ List userIds = alarmContactGroup.getUserIds();
+ for (String userId:userIds) {
+ Long memberId = IdWorker.getId();
+ AlarmContactGroupMember alarmContactGroupMember = new AlarmContactGroupMember();
+ alarmContactGroupMember.setId(memberId.toString());
+ alarmContactGroupMember.setGroupId(alarmContactGroup.getId());
+ alarmContactGroupMember.setUserId(userId);
+ alarmContactGroupMemberMapper.insert(alarmContactGroupMember);
+ }
+ }
+ result.setSuccess(true);
+ result.success("新增成功");
+ return result;
+ }
+
+ @Override
+ public Result update(AlarmContactGroup alarmContactGroup) {
+ Result result = new Result();
+ //获取request
+ HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
+ //获取当前操作人用户名
+ String username = JwtUtil.getUserNameByToken(request);
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(AlarmContactGroup::getId, alarmContactGroup.getId());
+ AlarmContactGroup contactGroup = this.baseMapper.selectOne(queryWrapper);
+ if (Objects.isNull(contactGroup)){
+ result.error500("对应数据不存在");
+ return result;
+ }
+ if (CollectionUtils.isNotEmpty(alarmContactGroup.getUserIds())){
+ LambdaQueryWrapper contactGroupMemberQueryWrapper = new LambdaQueryWrapper<>();
+ contactGroupMemberQueryWrapper.eq(AlarmContactGroupMember::getGroupId, alarmContactGroup.getId());
+ alarmContactGroupMemberMapper.delete(contactGroupMemberQueryWrapper);
+ List userIds = alarmContactGroup.getUserIds();
+ for (String userId:userIds) {
+ Long memberId = IdWorker.getId();
+ AlarmContactGroupMember alarmContactGroupMember = new AlarmContactGroupMember();
+ alarmContactGroupMember.setId(memberId.toString());
+ alarmContactGroupMember.setGroupId(alarmContactGroup.getId());
+ alarmContactGroupMember.setUserId(userId);
+ alarmContactGroupMemberMapper.insert(alarmContactGroupMember);
+ }
+ }
+ alarmContactGroup.setUpdateTime(LocalDate.now());
+ alarmContactGroup.setUpdateBy(username);
+ this.baseMapper.updateById(alarmContactGroup);
+ result.setSuccess(true);
+ result.success("修改成功");
+ return result;
+ }
+
+ @Override
+ public Result deleteById(String id) {
+ Result result = new Result();
+ //根据联系人组id删除关联的联系人信息
+ LambdaQueryWrapper contactGroupMemberQueryWrapper = new LambdaQueryWrapper<>();
+ contactGroupMemberQueryWrapper.eq(AlarmContactGroupMember::getGroupId, id);
+ alarmContactGroupMemberMapper.delete(contactGroupMemberQueryWrapper);
+ //删除联系人组信息
+ this.baseMapper.deleteById(id);
+ result.setSuccess(true);
+ result.success("删除成功");
+ return result;
+ }
+
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/impl/AlarmLogServiceImpl.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/impl/AlarmLogServiceImpl.java
new file mode 100644
index 00000000..b5e323b6
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/impl/AlarmLogServiceImpl.java
@@ -0,0 +1,239 @@
+package org.jeecg.modules.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.DateUtil;
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.modules.dto.TypeDto;
+import org.jeecg.modules.entity.AlarmHistory;
+import org.jeecg.modules.entity.AlarmLog;
+import org.jeecg.modules.mapper.AlarmLogMapper;
+import org.jeecg.modules.service.IAlarmLogService;
+import org.jeecg.modules.vo.AlarmVo;
+import org.springframework.stereotype.Service;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Service("alarmLogService")
+public class AlarmLogServiceImpl extends ServiceImpl implements IAlarmLogService {
+
+ /**
+ * 总体统计柱状图
+ * @param alarmVo
+ * @return
+ */
+ @Override
+ public Result viewAll(AlarmVo alarmVo) {
+ String startDate = alarmVo.getStartDate();
+ String endDate = alarmVo.getEndDate();
+ // 拼接日期为合理的日期+时间范围
+ alarmVo.setStartDate(startDate + " 00:00:00");
+ alarmVo.setEndDate(endDate + " 23:59:59");
+ // 定义返回结果
+ Set xData = new HashSet<>();
+ Collection yData = new ArrayList<>();
+ Map statistic = new TreeMap<>();
+ Map result = new HashMap<>();
+ // 转换参数 数据查询
+ Map params = BeanUtil.beanToMap(alarmVo);
+ List allDate = baseMapper.rangeDay(params);
+ // 查询数据为空则直接返回空集合
+ if (CollUtil.isEmpty(allDate)){
+ result.put("xData",xData);
+ result.put("yData",yData);
+ return Result.OK(result);
+ }
+ // 分情况处理 1.按小时统计 2.按天统计
+
+ /* 1.选择日期为同一天 按照小时划分 0-23小时 */
+ if (startDate.equals(endDate)){
+ Map> groupTime = allDate.stream()
+ .collect(Collectors.groupingBy(LocalDateTime::getHour));
+ for (int i = 0; i < 24; i++) {
+ if(groupTime.containsKey(i)){
+ Integer count = groupTime.get(i).size();
+ statistic.put(timeStr(i),count);
+ }else {
+ statistic.put(timeStr(i),0);
+ }
+ }
+ // 返回x轴和y轴数据
+ xData = statistic.keySet();
+ yData = statistic.values();
+ result.put("xData",xData);
+ result.put("yData",yData);
+ return Result.OK(result);
+ }
+ /* 2.选择日期不是同一天 按照天划分 */
+ // 支持跨年跨月选择(包括闰年)
+ else {
+ // 通过年月日进行分组 例:2023-06-06
+ DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE;
+ Map> group = allDate.stream()
+ .collect(Collectors.groupingBy(datetime -> datetime.format(formatter)));
+
+ // 列举startDate和endDate之间所有日期(已考虑闰年情况)
+ // 没有报警日志的日期,对应的值设置为0
+ LocalDate start = LocalDate.parse(startDate);
+ LocalDate end = LocalDate.parse(endDate);
+ while (!start.isAfter(end)) {
+ String key = start.format(formatter);
+ if (group.containsKey(key)){
+ Integer count = group.get(key).size();
+ statistic.put(key,count);
+ }else {
+ statistic.put(key,0);
+ }
+ start = start.plusDays(1);
+ }
+ // 返回x轴和y轴数据
+ xData = statistic.keySet();
+ yData = statistic.values();
+ result.put("xData",xData);
+ result.put("yData",yData);
+ return Result.OK(result);
+ }
+ }
+
+ /**
+ * 报警信息分页列表
+ * @param alarmVo
+ * @return
+ */
+ @Override
+ public Result findPage(AlarmVo alarmVo) {
+ Integer pageNo = alarmVo.getPageNo();
+ Integer pageSize = alarmVo.getPageSize();
+ Page page = new Page<>(pageNo,pageSize);
+ Integer pageStart = (pageNo - 1) * pageSize;
+ alarmVo.setPageStart(pageStart);
+ Map params = BeanUtil.beanToMap(alarmVo);
+ List alarmHistories = baseMapper.findPage(params);
+ // 当前页数据
+ page.setRecords(alarmHistories);
+ // 获取数据总条数(经过查询条件过滤后的)
+ params.put("pageFlag","noPage");
+ Integer total = baseMapper.findPage(params).size();
+ page.setTotal(total);
+ return Result.OK(page);
+ }
+
+ /**
+ * ALARM ANALYSIS -> Monitor Type Alarms
+ * @return
+ */
+ @Override
+ public Result typeAlarms(AlarmVo alarmVo) {
+ /* 饼图数据 */
+ // 警报类型-警报数
+ Map params = BeanUtil.beanToMap(alarmVo);
+ List typeAlarms = baseMapper.typeAlarms(params);
+ // 警报总数
+ Integer total = typeAlarms.stream().mapToInt(TypeDto::getValue).sum();
+ Map result = new HashMap<>();
+ result.put("pieData",typeAlarms);
+ result.put("pieTotal",total);
+ return Result.OK(result);
+ }
+
+ /**
+ * ALARM ANALYSIS -> Alarms Rule Top5
+ * @return
+ */
+ @Override
+ public Result ruleTop5(AlarmVo alarmVo) {
+ /* 柱状图数据 */
+ Map params = BeanUtil.beanToMap(alarmVo);
+ List ruleTop5 = baseMapper.ruleTop5(params);
+ // x轴数据
+ List xData = ruleTop5.stream()
+ .map(TypeDto::getName)
+ .collect(Collectors.toList());
+ // y轴数据
+ List yData = ruleTop5.stream()
+ .map(TypeDto::getValue)
+ .collect(Collectors.toList());
+ Map result = new HashMap<>();
+ result.put("xData",xData);
+ result.put("yData",yData);
+ return Result.OK(result);
+ }
+
+ @Override
+ public Result findInfo(String id) {
+ Result result = new Result();
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(AlarmLog::getId, id);
+ AlarmLog alarmLog = this.baseMapper.selectOne(queryWrapper);
+ if (Objects.isNull(alarmLog)){
+ result.error500("当前查询数据不存在");
+ return result;
+ }
+ result.setSuccess(true);
+ result.setResult(alarmLog);
+ return result;
+ }
+
+ @Override
+ public Result create(AlarmLog alarmLog) {
+ Result result = new Result();
+ Long id = IdWorker.getId();
+ alarmLog.setId(id.toString());
+ if (StringUtils.isNotBlank(alarmLog.getAlarmInfo())){
+ String jsonString = JSON.toJSONString(alarmLog.getAlarmInfo());
+ alarmLog.setAlarmInfo(jsonString);
+ }
+ this.baseMapper.insert(alarmLog);
+ result.setSuccess(true);
+ result.success("新增成功");
+ return result;
+ }
+
+ @Override
+ public Result update(AlarmLog alarmLog) {
+ Result result = new Result();
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(AlarmLog::getId, alarmLog.getId());
+ AlarmLog log = this.baseMapper.selectOne(queryWrapper);
+ if (Objects.isNull(log)){
+ result.error500("对应数据不存在,修改失败");
+ return result;
+ }
+ if (StringUtils.isNotBlank(alarmLog.getAlarmInfo())){
+ String jsonString = JSON.toJSONString(alarmLog.getAlarmInfo());
+ alarmLog.setAlarmInfo(jsonString);
+ }
+ this.baseMapper.updateById(alarmLog);
+ result.setSuccess(true);
+ result.success("修改成功");
+ return result;
+ }
+
+ @Override
+ public Result deleteById(String id) {
+ Result result = new Result();
+ this.baseMapper.deleteById(id);
+ result.setSuccess(true);
+ result.success("删除成功");
+ return result;
+ }
+
+ private String timeStr(Integer time){
+ if (time < 10){
+ return "0" + time + ":00";
+ }
+ return time + ":00";
+ }
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/impl/AlarmRuleServiceImpl.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/impl/AlarmRuleServiceImpl.java
new file mode 100644
index 00000000..2ba6f004
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/impl/AlarmRuleServiceImpl.java
@@ -0,0 +1,112 @@
+package org.jeecg.modules.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import io.netty.util.internal.StringUtil;
+import org.jeecg.common.api.QueryRequest;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.util.JwtUtil;
+import org.jeecg.common.util.SpringContextUtils;
+import org.jeecg.modules.entity.AlarmRule;
+import org.jeecg.modules.mapper.AlarmRuleMapper;
+import org.jeecg.modules.service.IAlarmRuleService;
+import org.springframework.stereotype.Service;
+
+import javax.servlet.http.HttpServletRequest;
+import java.time.LocalDate;
+import java.util.Date;
+import java.util.Objects;
+
+@Service("alarmRuleService")
+public class AlarmRuleServiceImpl extends ServiceImpl implements IAlarmRuleService {
+
+ @Override
+ public Result findPage(QueryRequest queryRequest, AlarmRule alarmRule) {
+ Result result = new Result();
+ Page page = new Page<>(queryRequest.getPageNo(), queryRequest.getPageSize());
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(Objects.nonNull(alarmRule.getEnabled()), AlarmRule::getEnabled, alarmRule.getEnabled());
+ queryWrapper.eq(StringUtils.isNotBlank(alarmRule.getSourceId()), AlarmRule::getSourceId, alarmRule.getSourceId());
+ Page alarmRulePage = this.baseMapper.selectPage(page, queryWrapper);
+ result.setSuccess(true);
+ result.setResult(alarmRulePage);
+ return result;
+ }
+
+ @Override
+ public Result findInfo(String id) {
+ Result result = new Result();
+ //根据id查询对应数据信息
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(AlarmRule::getId, id);
+ AlarmRule alarmRule = this.baseMapper.selectOne(queryWrapper);
+ if (Objects.isNull(alarmRule)){
+ result.error500("查询数据不存在");
+ return result;
+ }
+ result.setSuccess(true);
+ result.setResult(alarmRule);
+ return result;
+ }
+
+ @Override
+ public Result create(AlarmRule alarmRule) {
+ Result result = new Result();
+ //获取request
+ HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
+ //获取当前操作人用户名
+ String username = JwtUtil.getUserNameByToken(request);
+ Long id = IdWorker.getId();
+ alarmRule.setId(id.toString());
+ alarmRule.setCreateTime(LocalDate.now());
+ alarmRule.setCreateBy(username);
+ if (StringUtils.isNotBlank(alarmRule.getOperator())){
+ String jsonString = JSON.toJSONString(alarmRule.getOperator());
+ alarmRule.setOperator(jsonString);
+ }
+ this.baseMapper.insert(alarmRule);
+ result.setSuccess(true);
+ result.success("新增成功");
+ return result;
+ }
+
+ @Override
+ public Result update(AlarmRule alarmRule) {
+ Result result = new Result();
+ //获取request
+ HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
+ //获取当前操作人用户名
+ String username = JwtUtil.getUserNameByToken(request);
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(AlarmRule::getId, alarmRule.getId());
+ AlarmRule rule = this.baseMapper.selectOne(queryWrapper);
+ if (Objects.isNull(rule)){
+ result.error500("对应数据不存在");
+ return result;
+ }
+ alarmRule.setUpdateTime(LocalDate.now());
+ alarmRule.setUpdateBy(username);
+ if (StringUtils.isNotBlank(alarmRule.getOperator())){
+ String jsonString = JSON.toJSONString(alarmRule.getOperator());
+ alarmRule.setOperator(jsonString);
+ }
+ this.baseMapper.updateById(alarmRule);
+ result.setSuccess(true);
+ result.success("修改成功");
+ return result;
+ }
+
+ @Override
+ public Result deleteById(String id) {
+ Result result = new Result();
+ this.baseMapper.deleteById(id);
+ result.setSuccess(true);
+ result.success("删除成功");
+ return result;
+ }
+
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/impl/SysDatabaseServiceImpl.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/impl/SysDatabaseServiceImpl.java
new file mode 100644
index 00000000..bc7eeeb7
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/impl/SysDatabaseServiceImpl.java
@@ -0,0 +1,132 @@
+package org.jeecg.modules.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.jeecg.common.api.QueryRequest;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.util.JwtUtil;
+import org.jeecg.common.util.DateUtils;
+import org.jeecg.common.util.SpringContextUtils;
+import org.jeecg.modules.entity.AlarmHistory;
+import org.jeecg.modules.entity.SysDatabase;
+import org.jeecg.modules.mapper.SysDatabaseMapper;
+import org.jeecg.modules.service.ISysDatabaseService;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.servlet.http.HttpServletRequest;
+import java.text.ParseException;
+import java.time.LocalDate;
+import java.util.Date;
+import java.util.List;
+import java.util.Objects;
+
+@Service("sysDatabaseService")
+public class SysDatabaseServiceImpl extends ServiceImpl implements ISysDatabaseService {
+
+ @Override
+ public Result findPage(QueryRequest queryRequest, SysDatabase sysDatabase) {
+ Result result = new Result();
+ //声明page
+ Page page = new Page<>(queryRequest.getPageNo(), queryRequest.getPageSize());
+ //分页查询数据库配置信息
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ Page sysDatabasePage = this.baseMapper.selectPage(page, queryWrapper);
+ result.setSuccess(true);
+ result.setResult(sysDatabasePage);
+ return result;
+ }
+
+ @Override
+ public Result findInfo(String id) {
+ Result result = new Result();
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(SysDatabase::getId, id);
+ SysDatabase database = this.baseMapper.selectOne(queryWrapper);
+ if (Objects.isNull(database)){
+ result.error500("当前数据不存在");
+ return result;
+ }
+ result.setSuccess(true);
+ result.setResult(database);
+ return result;
+ }
+
+ @Override
+ @Transactional
+ public Result create(SysDatabase sysDatabase) {
+ Result result = new Result();
+ //获取request
+ HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
+ //获取当前操作人用户名
+ String username = JwtUtil.getUserNameByToken(request);
+ //声明id
+ Long id = IdWorker.getId();
+ sysDatabase.setId(id.toString());
+ sysDatabase.setCreateTime(LocalDate.now());
+ sysDatabase.setCreateBy(username);
+ this.baseMapper.insert(sysDatabase);
+ result.setSuccess(true);
+ result.success("新增成功");
+ return result;
+ }
+
+ @Override
+ @Transactional
+ public Result update(SysDatabase sysDatabase) {
+ Result result = new Result();
+ //获取request
+ HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
+ //获取当前操作人用户名
+ String username = JwtUtil.getUserNameByToken(request);
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(SysDatabase::getId, sysDatabase.getId());
+ SysDatabase database = this.baseMapper.selectOne(queryWrapper);
+ if (Objects.isNull(database)){
+ result.error500("对应数据不存在,修改失败");
+ return result;
+ }
+ sysDatabase.setUpdateTime(LocalDate.now());
+ sysDatabase.setUpdateBy(username);
+ this.baseMapper.updateById(sysDatabase);
+ result.setSuccess(true);
+ result.success("修改成功");
+ return result;
+ }
+
+ @Override
+ @Transactional
+ public Result deleteById(String id) {
+ Result result = new Result();
+ this.baseMapper.deleteById(id);
+ result.setSuccess(true);
+ result.success("删除成功");
+ return result;
+ }
+
+ @Override
+ public Result findAlarmHistory(String databaseId, Date startTime, Date endTime) {
+ Result result = new Result();
+ try {
+ if (Objects.isNull(startTime)){
+ result.error500("开始时间不能为空");
+ return result;
+ }
+ if (Objects.isNull(endTime)){
+ result.error500("结束时间不能为空");
+ return result;
+ }
+ Date startDate = DateUtils.parseDate(DateUtils.formatDate(startTime, "yyyy-MM-dd") + " 00:00:00", "yyyy-MM-dd HH:mm:ss");
+ Date endDate = DateUtils.parseDate(DateUtils.formatDate(endTime, "yyyy-MM-dd") + " 23:59:59", "yyyy-MM-dd HH:mm:ss");
+ List alarmHistory = this.baseMapper.findAlarmHistory(databaseId, startDate, endDate);
+ result.setSuccess(true);
+ result.setResult(alarmHistory);
+ } catch (ParseException e) {
+ throw new RuntimeException(e);
+ }
+ return result;
+ }
+
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/impl/SysEmailLogServiceImpl.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/impl/SysEmailLogServiceImpl.java
new file mode 100644
index 00000000..06e9cb66
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/impl/SysEmailLogServiceImpl.java
@@ -0,0 +1,11 @@
+package org.jeecg.modules.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.jeecg.modules.base.entity.SysEmailLog;
+import org.jeecg.modules.mapper.SysEmailLogMapper;
+import org.jeecg.modules.service.ISysEmailLogService;
+import org.springframework.stereotype.Service;
+
+@Service("sysEmailLogService")
+public class SysEmailLogServiceImpl extends ServiceImpl implements ISysEmailLogService {
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/impl/SysEmailServiceImpl.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/impl/SysEmailServiceImpl.java
new file mode 100644
index 00000000..a9ba633d
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/impl/SysEmailServiceImpl.java
@@ -0,0 +1,136 @@
+package org.jeecg.modules.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.jeecg.common.api.QueryRequest;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.util.JwtUtil;
+import org.jeecg.common.util.DateUtils;
+import org.jeecg.common.util.SpringContextUtils;
+import org.jeecg.modules.entity.AlarmHistory;
+import org.jeecg.modules.base.entity.SysEmail;
+import org.jeecg.modules.mapper.SysEmailMapper;
+import org.jeecg.modules.service.ISysEmailService;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.servlet.http.HttpServletRequest;
+import java.text.ParseException;
+import java.time.LocalDate;
+import java.util.Date;
+import java.util.List;
+import java.util.Objects;
+
+@Service("sysEmailService")
+public class SysEmailServiceImpl extends ServiceImpl implements ISysEmailService {
+
+ @Override
+ public Result findPage(QueryRequest queryRequest, SysEmail sysEmail) {
+ Result result = new Result();
+ //声明page
+ Page page = new Page<>(queryRequest.getPageNo(), queryRequest.getPageSize());
+ //分页查询邮箱配置数据
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ Page sysEmailPage = this.baseMapper.selectPage(page, queryWrapper);
+ result.setSuccess(true);
+ result.setResult(sysEmailPage);
+ return result;
+ }
+
+ @Override
+ public Result findInfo(String id) {
+ Result result = new Result();
+ //根据id查询对应的邮箱配置信息
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(SysEmail::getId, id);
+ SysEmail sysEmail = this.baseMapper.selectOne(queryWrapper);
+ if (Objects.isNull(sysEmail)){
+ result.error500("查询数据不存在");
+ return result;
+ }
+ result.setSuccess(true);
+ result.setResult(sysEmail);
+ return result;
+ }
+
+ @Override
+ @Transactional
+ public Result create(SysEmail sysEmail) {
+ Result result = new Result();
+ //获取request
+ HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
+ //获取当前操作人用户名
+ String username = JwtUtil.getUserNameByToken(request);
+ //声明id
+ Long id = IdWorker.getId();
+ sysEmail.setId(id.toString());
+ //创建时间
+ sysEmail.setCreateTime(LocalDate.now());
+ sysEmail.setCreateBy(username);
+ this.baseMapper.insert(sysEmail);
+ result.setSuccess(true);
+ result.success("新增成功");
+ return result;
+ }
+
+ @Override
+ @Transactional
+ public Result update(SysEmail sysEmail) {
+ Result result = new Result();
+ //获取request
+ HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
+ //获取当前操作人用户名
+ String username = JwtUtil.getUserNameByToken(request);
+ //根据id查询数据
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(SysEmail::getId, sysEmail.getId());
+ SysEmail email = this.baseMapper.selectOne(queryWrapper);
+ if (Objects.isNull(email)){
+ result.error500("对应数据不存在");
+ return result;
+ }
+ //创建时间
+ sysEmail.setUpdateTime(LocalDate.now());
+ sysEmail.setUpdateBy(username);
+ this.baseMapper.updateById(sysEmail);
+ result.setSuccess(true);
+ result.success("修改成功");
+ return result;
+ }
+
+ @Override
+ @Transactional
+ public Result deleteById(String id) {
+ Result result = new Result();
+ this.baseMapper.deleteById(id);
+ result.setSuccess(true);
+ result.success("删除成功");
+ return result;
+ }
+
+ @Override
+ public Result findAlarmHistory(String emailId, Date startTime, Date endTime) {
+ Result result = new Result();
+ try {
+ if (Objects.isNull(startTime)){
+ result.error500("开始时间不能为空");
+ return result;
+ }
+ if (Objects.isNull(endTime)){
+ result.error500("结束时间不能为空");
+ return result;
+ }
+ Date startDate = DateUtils.parseDate(DateUtils.formatDate(startTime, "yyyy-MM-dd") + " 00:00:00", "yyyy-MM-dd HH:mm:ss");
+ Date endDate = DateUtils.parseDate(DateUtils.formatDate(endTime, "yyyy-MM-dd") + " 23:59:59", "yyyy-MM-dd HH:mm:ss");
+ List alarmHistory = this.baseMapper.findAlarmHistory(emailId, startDate, endDate);
+ result.setSuccess(true);
+ result.setResult(alarmHistory);
+ } catch (ParseException e) {
+ throw new RuntimeException(e);
+ }
+ return result;
+ }
+
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/impl/SysServerServiceImpl.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/impl/SysServerServiceImpl.java
new file mode 100644
index 00000000..3f2d7113
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/service/impl/SysServerServiceImpl.java
@@ -0,0 +1,137 @@
+package org.jeecg.modules.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.apache.commons.lang3.StringUtils;
+import org.jeecg.common.api.QueryRequest;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.util.JwtUtil;
+import org.jeecg.common.util.DateUtils;
+import org.jeecg.common.util.SpringContextUtils;
+import org.jeecg.modules.entity.AlarmHistory;
+import org.jeecg.modules.entity.SysServer;
+import org.jeecg.modules.mapper.SysServerMapper;
+import org.jeecg.modules.service.ISysServerService;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.servlet.http.HttpServletRequest;
+import java.text.ParseException;
+import java.time.LocalDate;
+import java.util.Date;
+import java.util.List;
+import java.util.Objects;
+
+@Service("sysServerService")
+public class SysServerServiceImpl extends ServiceImpl implements ISysServerService {
+
+ @Override
+ public Result findPage(QueryRequest queryRequest, SysServer sysServer) {
+ Result result = new Result();
+ Page page = new Page<>(queryRequest.getPageNo(), queryRequest.getPageSize());
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ Page sysServerPage = this.baseMapper.selectPage(page, queryWrapper);
+ result.setSuccess(true);
+ result.setResult(sysServerPage);
+ return result;
+ }
+
+ @Override
+ public Result findInfo(String id) {
+ Result result = new Result();
+ if (StringUtils.isBlank(id)){
+ result.error500("id信息不能为空");
+ }
+ //查询对应数据详情内容
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(SysServer::getId, id);
+ SysServer sysServer = this.baseMapper.selectOne(queryWrapper);
+ if (Objects.isNull(sysServer)){
+ result.error500("查询数据不存在");
+ return result;
+ }
+ result.setSuccess(true);
+ result.setResult(sysServer);
+ return result;
+ }
+
+ @Override
+ @Transactional
+ public Result create(SysServer sysServer) {
+ Result result = new Result();
+ //获取request
+ HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
+ //获取当前操作人用户名
+ String username = JwtUtil.getUserNameByToken(request);
+ //声明id
+ Long id = IdWorker.getId();
+ sysServer.setId(id.toString());
+ //赋值创建时间
+ sysServer.setCreateTime(LocalDate.now());
+ sysServer.setCreateBy(username);
+ this.baseMapper.insert(sysServer);
+ result.setSuccess(true);
+ result.success("新增成功");
+ return result;
+ }
+
+ @Override
+ @Transactional
+ public Result update(SysServer sysServer) {
+ Result result = new Result();
+ //获取request
+ HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
+ //获取当前操作人用户名
+ String username = JwtUtil.getUserNameByToken(request);
+ //根据id查询对应数据是否存在
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(SysServer::getId, sysServer.getId());
+ SysServer server = this.baseMapper.selectOne(queryWrapper);
+ if (Objects.isNull(server)){
+ result.error500("当前数据不存在");
+ return result;
+ }
+ sysServer.setUpdateTime(LocalDate.now());
+ sysServer.setUpdateBy(username);
+ this.baseMapper.updateById(sysServer);
+ result.setSuccess(true);
+ result.success("修改成功");
+ return result;
+ }
+
+ @Override
+ @Transactional
+ public Result deleteById(String id) {
+ Result result = new Result();
+ this.baseMapper.deleteById(id);
+ result.setSuccess(true);
+ result.success("删除成功");
+ return result;
+ }
+
+ @Override
+ public Result findAlarmHistory(String serverId, Date startTime, Date endTime) {
+ Result result = new Result();
+ try {
+ if (Objects.isNull(startTime)){
+ result.error500("开始时间不能为空");
+ return result;
+ }
+ if (Objects.isNull(endTime)){
+ result.error500("结束时间不能为空");
+ return result;
+ }
+ Date startDate = DateUtils.parseDate(DateUtils.formatDate(startTime, "yyyy-MM-dd") + " 00:00:00", "yyyy-MM-dd HH:mm:ss");
+ Date endDate = DateUtils.parseDate(DateUtils.formatDate(endTime, "yyyy-MM-dd") + " 23:59:59", "yyyy-MM-dd HH:mm:ss");
+ List alarmHistory = this.baseMapper.findAlarmHistory(serverId, startDate, endDate);
+ result.setSuccess(true);
+ result.setResult(alarmHistory);
+ } catch (ParseException e) {
+ throw new RuntimeException(e);
+ }
+ return result;
+ }
+
+}
diff --git a/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/vo/AlarmVo.java b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/vo/AlarmVo.java
new file mode 100644
index 00000000..6101023e
--- /dev/null
+++ b/jeecg-module-abnormal-alarm/src/main/java/org/jeecg/modules/vo/AlarmVo.java
@@ -0,0 +1,16 @@
+package org.jeecg.modules.vo;
+
+import lombok.Data;
+import org.jeecg.common.api.QueryRequest;
+import java.io.Serializable;
+
+@Data
+public class AlarmVo extends QueryRequest implements Serializable {
+ private String name;
+ private String type;
+ private String startDate;
+ private String endDate;
+ private Integer pageStart;
+ // 标记:根据条件查询但不进行分页
+ private String pageFlag;
+}
diff --git a/jeecg-module-auto-process/pom.xml b/jeecg-module-auto-process/pom.xml
new file mode 100644
index 00000000..7374c1ed
--- /dev/null
+++ b/jeecg-module-auto-process/pom.xml
@@ -0,0 +1,30 @@
+
+
+
+ jeecg-boot-parent
+ org.jeecgframework.boot
+ 3.5.1
+
+ 4.0.0
+
+ jeecg-module-auto-process
+
+
+
+ org.jeecgframework.boot
+ jeecg-boot-base-core
+
+
+
+ org.jeecgframework.boot
+ jeecg-boot-starter-cloud
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
+
+
\ No newline at end of file
diff --git a/jeecg-module-auto-process/src/main/java/org/jeecg/modules/AutoProcessManager.java b/jeecg-module-auto-process/src/main/java/org/jeecg/modules/AutoProcessManager.java
new file mode 100644
index 00000000..ff06c53d
--- /dev/null
+++ b/jeecg-module-auto-process/src/main/java/org/jeecg/modules/AutoProcessManager.java
@@ -0,0 +1,251 @@
+package org.jeecg.modules;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.constant.EmailConstant;
+import org.jeecg.common.email.EmailServiceManager;
+import org.jeecg.common.util.RedisUtil;
+import org.jeecg.modules.email.EmailParsingActuator;
+import org.jeecg.modules.emuns.SysMailEnableType;
+import org.jeecg.modules.email.EmailProperties;
+import org.jeecg.modules.properties.SpectrumPathProperties;
+import org.jeecg.modules.properties.TaskProperties;
+import org.jeecg.modules.service.ISysMailService;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 自动处理程序管理器
+ */
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class AutoProcessManager{
+
+ private final ISysMailService mailService;
+ private final TaskProperties taskProperties;
+ private final RedisUtil redisUtil;
+ private final SpectrumPathProperties spectrumPathProperties;
+
+ /**
+ * 邮件Map数据锁
+ */
+ private final Object lock = new Object();
+ /**
+ * 以邮件Id为key,邮件信息为value
+ */
+ private Map emailMap = new HashMap<>();
+
+ /**
+ * 以邮件id为key,以邮件执行线程为value
+ */
+ private Map emailExecThreadMap = new HashMap<>();
+
+ /**
+ * 启动自动处理
+ */
+ public void start() {
+ //邮件数据监测线程
+ final MailDataMonitor mailDataMonitor = new MailDataMonitor();
+ mailDataMonitor.setName("mail-data-monitor");
+ mailDataMonitor.start();
+ //邮件服务监测线程
+ final MailServerMonitor monitorThread = new MailServerMonitor();
+ monitorThread.setName("mail-server-monitor");
+ monitorThread.start();
+ //邮件执行线程管理
+ final MailExecManager autoProcessThread = new MailExecManager();
+ autoProcessThread.setName("mail-exec-thread-manage");
+ autoProcessThread.start();
+ }
+
+ /**
+ * 自动处理线程
+ */
+ private class MailExecManager extends Thread{
+
+ @Override
+ public void run() {
+ for(;;){
+ long start = System.currentTimeMillis();
+ if(!CollectionUtils.isEmpty(emailMap)){
+ Iterator iterator = emailMap.values().iterator();
+ while(iterator.hasNext()){
+ EmailProperties next = iterator.next();
+ if(next.isDelFlag()){
+ if(emailExecThreadMap.containsKey(next.getId())){
+ Thread thread = emailExecThreadMap.get(next.getId());
+ thread.interrupt();
+ emailExecThreadMap.remove(next.getId());
+ }
+ iterator.remove();
+ }
+ if(next.isNewEmailFlag()){
+ EmailParsingActuator emailParsingActuator = new EmailParsingActuator();
+ emailParsingActuator.init(taskProperties,next);
+ emailParsingActuator.setName(next.getUsername()+"-email-monitor");
+ emailParsingActuator.start();
+ //把邮件监测执行线程加入管理队列
+ emailExecThreadMap.put(next.getId(),emailParsingActuator);
+ //新邮件监测监测线程已启动则修改新邮件标记为false
+ next.setNewEmailFlag(false);
+ }
+ }
+ }
+ long end = System.currentTimeMillis();
+ long sleepTime = taskProperties.getMonitoringMailDataCycle() - (end-start);
+ //如果sleepTime > 0 需要睡眠到指定时间,否则继续下次获取邮件
+ if(sleepTime > 0){
+ try {
+ //如果本次
+ TimeUnit.MILLISECONDS.sleep(sleepTime);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * 邮箱通信监测线程,具体功能如下:
+ * 监测邮件服务通讯是否正常,把各邮箱通信状态写入redis
+ */
+ private class MailServerMonitor extends Thread{
+
+ @Override
+ public void run() {
+ for(;;){
+ long start = System.currentTimeMillis();
+ try{
+ if(!CollectionUtils.isEmpty(emailMap)){
+ emailMap.values().forEach(email->{
+ if(!email.isDelFlag()){
+ final EmailServiceManager emailServiceManager = EmailServiceManager.getInstance();
+ emailServiceManager.init(email);
+ boolean testFlag = emailServiceManager.testConnectEmailServer();
+ redisUtil.hset(EmailConstant.EMAIL_STATUS_PREFIX,email.getId(),testFlag);
+ if(testFlag && !emailExecThreadMap.containsKey(email.getId())){
+ email.setNewEmailFlag(true);
+ }
+ if(!testFlag){
+ //如果邮件服务通信测试失败则添加删除标记
+ email.setDelFlag(true);
+ }
+ }
+ });
+ }
+ //捕获异常不处理保障线程异常不退出
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+ long end = System.currentTimeMillis();
+ long sleepTime = taskProperties.getMonitoringMailCommStatusCycle() - (end-start);
+ //如果sleepTime > 0 需要睡眠到指定时间,否则继续下次监测
+ if(sleepTime > 0){
+ try {
+ TimeUnit.MILLISECONDS.sleep(sleepTime);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * 邮箱数据监测线程,具体功能如下:
+ * 1.监测邮件数据表是否有变化
+ * 1.1有新邮件记录并且已启用则启动新线程执行
+ * 1.2有邮件记录被删除并且此邮箱信息已有线程执行则停止执行
+ */
+ private class MailDataMonitor extends Thread{
+
+ @Override
+ public void run() {
+ for (;;){
+ long start = System.currentTimeMillis();
+ try{
+ final List receiveMails = mailService.findReceiveMails();
+ if(!CollectionUtils.isEmpty(receiveMails)){
+ //如果库里已有数据原来已开启使用并且监测Map中已存在,现在关闭使用则添加删除标记
+ //如果本次查询数据监测Map中不存在,并且已开启使用的则加入监测Map
+ for(EmailProperties email : receiveMails){
+ final boolean flag = emailMap.containsKey(email.getId());
+ if(flag && email.getEnabled().equals(SysMailEnableType.NOT_ENABLE.getMailEnableType())){
+ EmailProperties sourceEmail = emailMap.get(email.getId());
+ sourceEmail.setDelFlag(true);
+ }
+ if(!flag && email.getEnabled().equals(SysMailEnableType.ENABLE.getMailEnableType())){
+ email.setNewEmailFlag(true);
+ putSysEmailMap(email);
+ log.info("{}邮箱加入监测队列",email.getEmailServerAddress());
+ }
+ }
+ //如果监测Map中存在的邮箱数据,在本次查询数据中不存在说明库里已删除,则添加删除标记
+ emailMap.forEach((emailId,sourceEmail)->{
+ final long result = receiveMails.stream().filter(email -> emailId.equals(email.getId())).count();
+ if (result <= 0){
+ sourceEmail.setDelFlag(true);
+ }
+ });
+ }
+ //捕获异常不处理保障线程异常不退出
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+ long end = System.currentTimeMillis();
+ long sleepTime = taskProperties.getMonitoringMailDataCycle() - (end-start);
+ //如果sleepTime > 0 需要睡眠到指定时间,否则继续下次监测
+ if(sleepTime > 0){
+ try {
+ TimeUnit.MILLISECONDS.sleep(sleepTime);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * 新增邮箱数据
+ * @param email
+ */
+ private void putSysEmailMap(EmailProperties email){
+ synchronized (this.lock){
+ emailMap.put(email.getId(),email);
+ }
+ }
+
+ /**
+ * 删除邮箱数据
+ * @param emailId
+ */
+ private void removeSysEmailMap(String emailId){
+ synchronized (this.lock){
+ if (emailMap.containsKey(emailId)){
+ emailMap.remove(emailId);
+ }
+ }
+ }
+
+ /**
+ * 删除邮箱数据
+ * @param sysEmailIds
+ */
+ private void removeSysEmailMap(List sysEmailIds){
+ synchronized (this.lock){
+ for(String sysEmailId : sysEmailIds){
+ if (emailMap.containsKey(sysEmailId)){
+ emailMap.remove(sysEmailId);
+ }
+ }
+ }
+ }
+}
diff --git a/jeecg-module-auto-process/src/main/java/org/jeecg/modules/config/mybatis/CustomMetaObjectHandler.java b/jeecg-module-auto-process/src/main/java/org/jeecg/modules/config/mybatis/CustomMetaObjectHandler.java
new file mode 100644
index 00000000..8954a958
--- /dev/null
+++ b/jeecg-module-auto-process/src/main/java/org/jeecg/modules/config/mybatis/CustomMetaObjectHandler.java
@@ -0,0 +1,26 @@
+package org.jeecg.modules.config.mybatis;
+
+import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import org.apache.ibatis.reflection.MetaObject;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDateTime;
+
+/**
+ * 自定义实体字段填充
+ * @author 86187
+ */
+@Component
+public class CustomMetaObjectHandler implements MetaObjectHandler {
+
+
+ @Override
+ public void insertFill(MetaObject metaObject) {
+ this.strictInsertFill(metaObject,"createTime", LocalDateTime.class,LocalDateTime.now());
+ }
+
+ @Override
+ public void updateFill(MetaObject metaObject) {
+
+ }
+}
diff --git a/jeecg-module-auto-process/src/main/java/org/jeecg/modules/email/EmailLogProperties.java b/jeecg-module-auto-process/src/main/java/org/jeecg/modules/email/EmailLogProperties.java
new file mode 100644
index 00000000..98da3486
--- /dev/null
+++ b/jeecg-module-auto-process/src/main/java/org/jeecg/modules/email/EmailLogProperties.java
@@ -0,0 +1,18 @@
+package org.jeecg.modules.email;
+
+import lombok.Data;
+import org.jeecg.modules.base.entity.SysEmailLog;
+
+import java.util.List;
+
+/**
+ * 邮件日志属性
+ */
+@Data
+public class EmailLogProperties extends SysEmailLog {
+
+ /**
+ * 邮件附件本地存储路径
+ */
+ private List filePathList;
+}
diff --git a/jeecg-module-auto-process/src/main/java/org/jeecg/modules/email/EmailParsingActuator.java b/jeecg-module-auto-process/src/main/java/org/jeecg/modules/email/EmailParsingActuator.java
new file mode 100644
index 00000000..21880970
--- /dev/null
+++ b/jeecg-module-auto-process/src/main/java/org/jeecg/modules/email/EmailParsingActuator.java
@@ -0,0 +1,107 @@
+package org.jeecg.modules.email;
+
+import org.jeecg.common.email.EmailServiceManager;
+import org.jeecg.common.email.emuns.MailContentType;
+import org.jeecg.modules.properties.TaskProperties;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeUtility;
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 邮件解析执行器
+ */
+public class EmailParsingActuator extends Thread{
+
+ private TaskProperties taskProperties;
+ private EmailProperties emailProperties;
+ private ThreadPoolExecutor poolExecutor;
+
+ public void init(TaskProperties taskProperties,
+ EmailProperties emailProperties){
+ this.taskProperties = taskProperties;
+ this.emailProperties = emailProperties;
+ //初始化线程池
+ ThreadFactory threadFactory = new CustomizableThreadFactory("mail-parsing-");
+ ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(taskProperties.getReceiveNum(),taskProperties.getReceiveNum()*2,5, TimeUnit.SECONDS, new LinkedBlockingQueue<>(),threadFactory);
+ }
+
+ @Override
+ public void run() {
+ for(;;){
+ long start = System.currentTimeMillis();
+ final EmailServiceManager emailServiceManager = EmailServiceManager.getInstance();
+ emailServiceManager.init(emailProperties,taskProperties.getReceiveNum(),taskProperties.getTemporaryStoragePath());
+ try {
+ final Message[] messages = emailServiceManager.receiveMail();
+ for(Message message : messages){
+ final EmailLogProperties emailLogProperties = this.parseingMail(emailServiceManager,message);
+ //如果邮件没有附件、获取附件都不是PHD文件、也不是IMS2.0协议的文件,需把邮件删除
+
+// emailServiceManager.removeMail(message);
+ }
+ }catch (MessagingException e) {
+ e.printStackTrace();
+ }catch (IOException e) {
+ e.printStackTrace();
+ }finally {
+ //关闭资源
+ emailServiceManager.close();
+ }
+ break;
+// long end = System.currentTimeMillis();
+// long sleepTime = taskProperties.getMailThreadExecCycle() - (end-start);
+// //如果sleepTime > 0 需要睡眠到指定时间,否则继续下次获取邮件
+// if(sleepTime > 0){
+// try {
+// //如果本次
+// TimeUnit.MILLISECONDS.sleep(sleepTime);
+// } catch (InterruptedException e) {
+// e.printStackTrace();
+// }
+// }
+ }
+ }
+
+ /**
+ * 解析邮件
+ * @param message
+ */
+ public EmailLogProperties parseingMail(@NotNull EmailServiceManager emailServiceManager,@NotNull Message message) throws MessagingException, IOException {
+ //如果是带有附件的邮件
+ if(message.getContentType().startsWith(MailContentType.MIXED.getContentType())){
+ //封装邮件日志信息
+ EmailLogProperties mailLog = new EmailLogProperties();
+ mailLog.setEmailId(emailProperties.getId());
+ mailLog.setSubject(MimeUtility.decodeText(message.getSubject()));
+ final StringBuilder content = new StringBuilder();
+ emailServiceManager.getMailContent(message,content);
+ mailLog.setContext(content.toString());
+ mailLog.setReceiveTime(message.getSentDate());
+ final List filePathList = emailServiceManager.saveAttachment(message);
+ mailLog.setFilePathList(filePathList);
+ return mailLog;
+ }else{
+ //如果此邮件不带有附件,则删除
+ emailServiceManager.removeMail(message);
+ }
+ return null;
+ }
+
+ //Sauna:β,Spalax:γ
+ private boolean checkMail(String filePath){
+ File file = new File(filePath);
+ if(file.isFile()){
+
+ }
+ return true;
+ }
+}
diff --git a/jeecg-module-auto-process/src/main/java/org/jeecg/modules/email/EmailProperties.java b/jeecg-module-auto-process/src/main/java/org/jeecg/modules/email/EmailProperties.java
new file mode 100644
index 00000000..14f20f05
--- /dev/null
+++ b/jeecg-module-auto-process/src/main/java/org/jeecg/modules/email/EmailProperties.java
@@ -0,0 +1,27 @@
+package org.jeecg.modules.email;
+
+import lombok.Data;
+import org.jeecg.modules.base.entity.SysEmail;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.io.Serializable;
+
+/**
+ * 邮件属性
+ * @author 86187
+ */
+@Data
+public class EmailProperties extends SysEmail {
+
+ /**
+ * 是否是新邮件
+ */
+ private boolean newEmailFlag;
+
+ /**
+ * 该邮件处理线程是否需要删除
+ */
+ private boolean delFlag;
+
+}
diff --git a/jeecg-module-auto-process/src/main/java/org/jeecg/modules/emuns/SysMailEnableType.java b/jeecg-module-auto-process/src/main/java/org/jeecg/modules/emuns/SysMailEnableType.java
new file mode 100644
index 00000000..a996288e
--- /dev/null
+++ b/jeecg-module-auto-process/src/main/java/org/jeecg/modules/emuns/SysMailEnableType.java
@@ -0,0 +1,26 @@
+package org.jeecg.modules.emuns;
+
+/**
+ * 邮件类型
+ */
+public enum SysMailEnableType {
+
+ /**
+ * 未启用邮件
+ */
+ NOT_ENABLE(0),
+ /**
+ * 启用邮件
+ */
+ ENABLE(1);
+
+ private Integer mailEnableType;
+
+ SysMailEnableType(int mailEnableType) {
+ this.mailEnableType = mailEnableType;
+ }
+
+ public Integer getMailEnableType(){
+ return this.mailEnableType;
+ }
+}
diff --git a/jeecg-module-auto-process/src/main/java/org/jeecg/modules/mapper/SysMailMapper.java b/jeecg-module-auto-process/src/main/java/org/jeecg/modules/mapper/SysMailMapper.java
new file mode 100644
index 00000000..0ca57666
--- /dev/null
+++ b/jeecg-module-auto-process/src/main/java/org/jeecg/modules/mapper/SysMailMapper.java
@@ -0,0 +1,10 @@
+package org.jeecg.modules.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.jeecg.modules.base.entity.SysEmail;
+
+/**
+ * 邮件数据表Mapper
+ */
+public interface SysMailMapper extends BaseMapper {
+}
diff --git a/jeecg-module-auto-process/src/main/java/org/jeecg/modules/properties/SpectrumPathProperties.java b/jeecg-module-auto-process/src/main/java/org/jeecg/modules/properties/SpectrumPathProperties.java
new file mode 100644
index 00000000..11794f5c
--- /dev/null
+++ b/jeecg-module-auto-process/src/main/java/org/jeecg/modules/properties/SpectrumPathProperties.java
@@ -0,0 +1,28 @@
+package org.jeecg.modules.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ * 能谱文件存储路径属性
+ * @author 86187
+ */
+@Data
+@Component
+@ConfigurationProperties(prefix = "file-system")
+public class SpectrumPathProperties implements Serializable {
+
+ /**
+ * 能谱文件存储根路径
+ */
+ private String rootPath;
+
+ /**
+ * 能谱文件存储路径以能谱系统类型/能谱类型为key,以存储路径为value
+ */
+ private Map filePathMap;
+}
diff --git a/jeecg-module-auto-process/src/main/java/org/jeecg/modules/properties/TaskProperties.java b/jeecg-module-auto-process/src/main/java/org/jeecg/modules/properties/TaskProperties.java
new file mode 100644
index 00000000..f3d3b2db
--- /dev/null
+++ b/jeecg-module-auto-process/src/main/java/org/jeecg/modules/properties/TaskProperties.java
@@ -0,0 +1,42 @@
+package org.jeecg.modules.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.io.Serializable;
+
+/**
+ * 邮件任务运行参数
+ * @author 86187
+ */
+@Data
+@Component
+@ConfigurationProperties(prefix = "task")
+public class TaskProperties implements Serializable {
+
+ /**
+ * 单次获取邮件数量
+ */
+ private Integer receiveNum;
+
+ /**
+ * 监测数据库邮箱数据变化周期
+ */
+ private Long monitoringMailDataCycle;
+
+ /**
+ * 监测邮箱通信状态周期
+ */
+ private Long monitoringMailCommStatusCycle;
+
+ /**
+ * 获取邮箱邮件线程执行周期
+ */
+ private Long mailThreadExecCycle;
+
+ /**
+ * 邮件附件临时存储路径
+ */
+ private String temporaryStoragePath;
+}
diff --git a/jeecg-module-auto-process/src/main/java/org/jeecg/modules/service/ISysMailService.java b/jeecg-module-auto-process/src/main/java/org/jeecg/modules/service/ISysMailService.java
new file mode 100644
index 00000000..8e9549e3
--- /dev/null
+++ b/jeecg-module-auto-process/src/main/java/org/jeecg/modules/service/ISysMailService.java
@@ -0,0 +1,18 @@
+package org.jeecg.modules.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.modules.base.entity.SysEmail;
+import org.jeecg.modules.email.EmailProperties;
+import java.util.List;
+
+/**
+ * 邮箱数据服务
+ */
+public interface ISysMailService extends IService {
+
+ /**
+ * 查询接收邮箱数据
+ * @return
+ */
+ List findReceiveMails();
+}
diff --git a/jeecg-module-auto-process/src/main/java/org/jeecg/modules/service/impl/SysMailServiceImpl.java b/jeecg-module-auto-process/src/main/java/org/jeecg/modules/service/impl/SysMailServiceImpl.java
new file mode 100644
index 00000000..cc21366b
--- /dev/null
+++ b/jeecg-module-auto-process/src/main/java/org/jeecg/modules/service/impl/SysMailServiceImpl.java
@@ -0,0 +1,47 @@
+package org.jeecg.modules.service.impl;
+
+import com.baomidou.dynamic.datasource.annotation.DS;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.google.common.collect.Lists;
+import org.jeecg.common.email.emuns.SysMailType;
+import org.jeecg.modules.base.entity.SysEmail;
+import org.jeecg.modules.email.EmailProperties;
+import org.jeecg.modules.emuns.SysMailEnableType;
+import org.jeecg.modules.mapper.SysMailMapper;
+import org.jeecg.modules.service.ISysMailService;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * 邮箱数据服务实现
+ */
+@Service
+@DS("master")
+public class SysMailServiceImpl extends ServiceImpl implements ISysMailService {
+
+ /**
+ * 查询接收邮箱数据
+ * @return
+ */
+ @Override
+ public List findReceiveMails() {
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(SysEmail::getEmilType, SysMailType.RECEIVE_EMAIL.getEmailType());
+ queryWrapper.eq(SysEmail::getEnabled, SysMailEnableType.ENABLE.getMailEnableType());
+ List sysEmail = this.list(queryWrapper);
+ if(!CollectionUtils.isEmpty(sysEmail)){
+ List emailPropertiesList = Lists.newArrayList();
+ for (SysEmail email : sysEmail){
+ EmailProperties mailProperties = new EmailProperties();
+ BeanUtils.copyProperties(email,mailProperties);
+ emailPropertiesList.add(mailProperties);
+ }
+ return emailPropertiesList;
+ }
+ return Collections.emptyList();
+ }
+}
diff --git a/jeecg-module-log-manage/pom.xml b/jeecg-module-log-manage/pom.xml
index dbb0118b..062a533c 100644
--- a/jeecg-module-log-manage/pom.xml
+++ b/jeecg-module-log-manage/pom.xml
@@ -16,11 +16,11 @@
org.jeecgframework.boot
jeecg-boot-base-core
-
+
+
- commons-net
- commons-net
- 3.3
+ org.jeecgframework.boot
+ jeecg-boot-starter-cloud
diff --git a/jeecg-module-log-manage/src/main/java/org/jeecg/common/util/FTPUtil.java b/jeecg-module-log-manage/src/main/java/org/jeecg/common/util/FTPUtil.java
deleted file mode 100644
index d8fb73d2..00000000
--- a/jeecg-module-log-manage/src/main/java/org/jeecg/common/util/FTPUtil.java
+++ /dev/null
@@ -1,139 +0,0 @@
-package org.jeecg.common.util;
-
-import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.net.ftp.FTPClient;
-import org.apache.commons.net.ftp.FTPFile;
-import org.apache.commons.net.ftp.FTPReply;
-import org.jeecg.modules.entity.LogManage;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-
-@Component
-@Slf4j
-public class FTPUtil {
-
- @Value("${ftp.host}")
- private String host;
-
- @Value("${ftp.port}")
- private Integer port;
-
- @Value("${ftp.userName}")
- private String userName;
-
- @Value("${ftp.password}")
- private String password;
-
- @Value("${ftp.encoding}")
- private String encoding;
-
- /**
- * 登录ftp
- * @return
- */
- public FTPClient LoginFTP(){
- //声明FTP客户端
- FTPClient ftp = new FTPClient();
- try {
- // 切换为本地被动模式,可以解决FTP上传后文件为空的问题,但需要服务器将FTP服务添加至防火墙白名单
- ftp.enterLocalPassiveMode();
- //连接
- ftp.connect(host, port);
- //登录
- ftp.login(userName, password);
- //判断是否连接成功
- int reply = ftp.getReplyCode();
- if (!FTPReply.isPositiveCompletion(reply)) {
- ftp.disconnect();
- return null;
- }
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- return ftp;
- }
-
- /**
- * 遍历查询当前路径下的文件夹信息
- * @param ftp
- * @param list
- * @param filePath 以"/"开始和结束
- * @return
- */
- public List findDirectory(FTPClient ftp,List list,Integer parentNum,String filePath){
- try {
- if (filePath.indexOf("/")>0){
- List paths = Arrays.asList(filePath.split("/"));
- for (String path:paths) {
- ftp.changeWorkingDirectory(path);
- }
- }
- List ftpFiles = Arrays.asList(ftp.listDirectories());
- if (CollectionUtils.isNotEmpty(ftpFiles)){
- int num =1;
- for (FTPFile file : ftpFiles) {
- if (file.isDirectory()) {
- LogManage logManage = new LogManage();
- logManage.setName(file.getName());
- logManage.setOrderNum(num);
- logManage.setParentNum(parentNum);
- logManage.setPath(filePath +"/"+ file.getName());
- list.add(logManage);
- num++;
- // 需要加此判断。否则,ftp默认将‘项目文件所在目录之下的目录(./)’与‘项目文件所在目录向上一级目录下的目录(../)’都纳入递归,这样下去就陷入一个死循环了。需将其过滤掉。
- if (!".".equals(file.getName()) && !"..".equals(file.getName())) {
- findDirectory(ftp,list,num,filePath +"/"+ file.getName());
- ftp.changeToParentDirectory();
- }
- }
- }
- }
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- return list;
- }
-
- public InputStream downloadFTPFile(String localPath, String fileName){
- InputStream in = null;
- //传输模式
- try {
- FTPClient ftpClient = this.LoginFTP();
- if (Objects.isNull(ftpClient)){
- throw new RuntimeException("ftp连接失败!");
- }
- List paths = Arrays.asList(localPath.split("/"));
- if (CollectionUtils.isNotEmpty(paths)){
- for (String workPath:paths) {
- //切换工作文件路径
- ftpClient.changeWorkingDirectory(workPath);
- }
- }
- ftpClient.enterLocalPassiveMode();
- ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
- // 设置编码,当文件中存在中文且上传后文件乱码时可使用此配置项
- ftpClient.setControlEncoding(encoding);
- ftpClient.setFileTransferMode(FTPClient.STREAM_TRANSFER_MODE);
- List ftpFiles = Arrays.asList(ftpClient.listFiles());
- if (CollectionUtils.isNotEmpty(ftpFiles)){
- for (FTPFile ftpFile:ftpFiles) {
- if (ftpFile.getName().equals(fileName)){
- in = ftpClient.retrieveFileStream(new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
- }
- }
- }
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- return in;
- }
-
-}
diff --git a/jeecg-module-log-manage/src/main/java/org/jeecg/modules/controller/LogManageController.java b/jeecg-module-log-manage/src/main/java/org/jeecg/modules/controller/LogManageController.java
index 69050723..bc142853 100644
--- a/jeecg-module-log-manage/src/main/java/org/jeecg/modules/controller/LogManageController.java
+++ b/jeecg-module-log-manage/src/main/java/org/jeecg/modules/controller/LogManageController.java
@@ -9,6 +9,7 @@ import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.FTPUtil;
import org.jeecg.modules.entity.FileInfo;
import org.jeecg.modules.entity.LogManage;
+import org.jeecg.modules.service.ILogManageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@@ -28,78 +29,13 @@ public class LogManageController {
@Autowired
private FTPUtil ftpUtil;
+ @Autowired
+ private ILogManageService logManageService;
@GetMapping("findFtpFolders")
@ApiOperation(value = "查询日志文件夹树形结构", notes = "查询日志文件夹树形结构")
public List findFtpFolders(String workPath){
- List result = new ArrayList<>();
- try {
- FTPClient ftpClient = ftpUtil.LoginFTP();
- if(Objects.isNull(ftpClient)){
- throw new RuntimeException("ftp连接失败!");
- }
- //切换工作文件路径
- ftpClient.changeWorkingDirectory(workPath);
- ftpClient.enterLocalPassiveMode();
- List ftpFiles = Arrays.asList(ftpClient.listDirectories());
- if (CollectionUtils.isNotEmpty(ftpFiles)){
- int num =1;
- for (FTPFile ftpFile:ftpFiles) {
- LogManage logManage = new LogManage();
- logManage.setName(ftpFile.getName());
- logManage.setOrderNum(num);
- logManage.setParentNum(0);
- logManage.setPath(workPath + "/" + ftpFile.getName());
- result.add(logManage);
- num++;
- }
- }
- if (CollectionUtils.isNotEmpty(result)){
- List list = new LinkedList<>();
- for (LogManage logManage:result) {
- list = ftpUtil.findDirectory(ftpClient, list, logManage.getOrderNum(), workPath + "/" + logManage.getName());
- ftpClient.changeToParentDirectory();
- }
- result.addAll(list);
- }
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- result = this.LogManageTree(result);
- return result;
- }
-
- /**
- * 将当前的文件夹转换成树形结构
- * @param logManages
- * @return
- */
- public List LogManageTree(List logManages){
- if (logManages == null) {
- return null;
- }
- List result = new LinkedList<>();
- Integer TOP_NODE_ID = 0;
- logManages.forEach(logManage -> {
- Integer pid = logManage.getParentNum();
- if (pid == null || TOP_NODE_ID.equals(pid)) {
- result.add(logManage);
- return;
- }
- for (LogManage manage : logManages) {
- Integer id = manage.getOrderNum();
- if (id != null && id.equals(pid)) {
- if (manage.getChildren() == null) {
- manage.initChildren();
- }
- logManage.setHashParent(true);
- manage.getChildren().add(logManage);
- manage.setHashChild(true);
- return;
- }
- }
- });
- return result;
+ return logManageService.findFtpFolders(workPath);
}
/**
@@ -110,71 +46,16 @@ public class LogManageController {
@GetMapping("findFiles")
@ApiOperation(value = "查询目录下文件内容", notes = "查询目录下文件内容")
public List findFiles(String path){
- List result = new ArrayList<>();
- try {
- FTPClient ftpClient = ftpUtil.LoginFTP();
- if (Objects.isNull(ftpClient)){
- throw new RuntimeException("ftp连接失败!");
- }
- List paths = Arrays.asList(path.split("/"));
- if (CollectionUtils.isNotEmpty(paths)){
- for (String workPath:paths) {
- //切换工作文件路径
- ftpClient.changeWorkingDirectory(workPath);
- }
- }
- ftpClient.enterLocalPassiveMode();
- List ftpFiles = Arrays.asList(ftpClient.listFiles());
- if (CollectionUtils.isNotEmpty(ftpFiles)){
- for (FTPFile ftpFile:ftpFiles) {
- if (ftpFile.isFile()){
- FileInfo fileInfo = new FileInfo();
- fileInfo.setFileName(ftpFile.getName());
- fileInfo.setFilePath(path +"/"+ ftpFile.getName());
- fileInfo.setFileSize(String.format("%.2f", Double.valueOf(Double.valueOf(ftpFile.getSize())/1024)) + "KB");
- fileInfo.setFileDate(DateUtils.formatDate(ftpFile.getTimestamp(),"yyyy-MM-dd"));
- result.add(fileInfo);
- }
- }
- }
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- return result;
+ return logManageService.findFiles(path);
}
@PostMapping("downloadFile")
@ApiOperation(value = "ftp文件下载", notes = "ftp文件下载")
- public void downloadFile(String localPath, String fileName, HttpServletResponse response) throws IOException {
+ public void downloadFile(String localPath, String fileName, HttpServletResponse response) {
if (localPath.contains(fileName)){
localPath=localPath.substring(0,localPath.indexOf(fileName)-1);
}
- //重置响应信息
- response.reset();
- //设置响应类型
- response.setContentType("application/download");
- //解决中文不能生成文件
- response.setHeader("Content-Disposition", "attachment; fileName=" + URLEncoder.encode(fileName,"UTF-8"));
- response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
- //获取文件的输入流
- InputStream in = ftpUtil.downloadFTPFile(localPath, fileName);
- //获取输出流
- ServletOutputStream out = response.getOutputStream();
- //声明一个长度参数
- int len;
- //声明字节数组
- byte[] bytes = new byte[1024];
- //判断如果输入流的字节长度不等于-1,进行字节数组内容的读取
- while ((len = in.read(bytes)) != -1) {
- out.write(bytes, 0, len);
- }
- out.flush();
- if (out != null) {
- out.close();
- }
- if (in != null) {
- in.close();
- }
+ ftpUtil.downloadFTPFile(localPath, fileName,response);
}
}
diff --git a/jeecg-module-log-manage/src/main/java/org/jeecg/modules/entity/FileInfo.java b/jeecg-module-log-manage/src/main/java/org/jeecg/modules/entity/FileInfo.java
index b1aed381..6371eb3f 100644
--- a/jeecg-module-log-manage/src/main/java/org/jeecg/modules/entity/FileInfo.java
+++ b/jeecg-module-log-manage/src/main/java/org/jeecg/modules/entity/FileInfo.java
@@ -5,12 +5,24 @@ import lombok.Data;
@Data
public class FileInfo {
+ /**
+ * 文件名称
+ */
private String fileName;
+ /**
+ * 文件路径
+ */
private String filePath;
+ /**
+ * 文件大小
+ */
private String fileSize;
+ /**
+ * 文件日期
+ */
private String fileDate;
}
diff --git a/jeecg-module-log-manage/src/main/java/org/jeecg/modules/entity/LogManage.java b/jeecg-module-log-manage/src/main/java/org/jeecg/modules/entity/LogManage.java
index bcfd3004..9f60dfbe 100644
--- a/jeecg-module-log-manage/src/main/java/org/jeecg/modules/entity/LogManage.java
+++ b/jeecg-module-log-manage/src/main/java/org/jeecg/modules/entity/LogManage.java
@@ -8,18 +8,39 @@ import java.util.List;
@Data
public class LogManage {
+ /**
+ * 名称
+ */
private String name;
+ /**
+ * 路径
+ */
private String path;
+ /**
+ * 排序编号
+ */
private Integer orderNum;
+ /**
+ * 父级编号
+ */
private Integer parentNum;
+ /**
+ * 是否有父级
+ */
private boolean hashParent;
+ /**
+ * 是否有子级
+ */
private boolean hashChild;
+ /**
+ * 子级数组
+ */
private List children;
public void initChildren(){
diff --git a/jeecg-module-log-manage/src/main/java/org/jeecg/modules/service/ILogManageService.java b/jeecg-module-log-manage/src/main/java/org/jeecg/modules/service/ILogManageService.java
new file mode 100644
index 00000000..bab2dce0
--- /dev/null
+++ b/jeecg-module-log-manage/src/main/java/org/jeecg/modules/service/ILogManageService.java
@@ -0,0 +1,24 @@
+package org.jeecg.modules.service;
+
+import org.jeecg.modules.entity.FileInfo;
+import org.jeecg.modules.entity.LogManage;
+
+import java.util.List;
+
+public interface ILogManageService {
+
+ /**
+ * 查询日志文件夹树形结构
+ * @param workPath
+ * @return
+ */
+ List findFtpFolders(String workPath);
+
+ /**
+ * 查询目录下文件内容
+ * @param path
+ * @return
+ */
+ List findFiles(String path);
+
+}
diff --git a/jeecg-module-log-manage/src/main/java/org/jeecg/modules/service/impl/LogManageServiceImpl.java b/jeecg-module-log-manage/src/main/java/org/jeecg/modules/service/impl/LogManageServiceImpl.java
new file mode 100644
index 00000000..562aebea
--- /dev/null
+++ b/jeecg-module-log-manage/src/main/java/org/jeecg/modules/service/impl/LogManageServiceImpl.java
@@ -0,0 +1,177 @@
+package org.jeecg.modules.service.impl;
+
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import org.apache.commons.net.ftp.FTPClient;
+import org.apache.commons.net.ftp.FTPFile;
+import org.jeecg.common.util.DateUtils;
+import org.jeecg.common.util.FTPUtil;
+import org.jeecg.modules.entity.FileInfo;
+import org.jeecg.modules.entity.LogManage;
+import org.jeecg.modules.service.ILogManageService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.io.IOException;
+import java.util.*;
+
+@Service("logManageService")
+public class LogManageServiceImpl implements ILogManageService {
+
+ @Autowired
+ private FTPUtil ftpUtil;
+
+ @Override
+ public List findFtpFolders(String workPath) {
+ List result = new ArrayList<>();
+ try {
+ FTPClient ftpClient = ftpUtil.LoginFTP();
+ if(Objects.isNull(ftpClient)){
+ throw new RuntimeException("ftp连接失败!");
+ }
+ //切换工作文件路径
+ ftpClient.changeWorkingDirectory(workPath);
+ ftpClient.enterLocalPassiveMode();
+ List ftpFiles = Arrays.asList(ftpClient.listDirectories());
+ if (CollectionUtils.isNotEmpty(ftpFiles)){
+ int num =1;
+ for (FTPFile ftpFile:ftpFiles) {
+ LogManage logManage = new LogManage();
+ logManage.setName(ftpFile.getName());
+ logManage.setOrderNum(num);
+ logManage.setParentNum(0);
+ logManage.setPath(workPath + "/" + ftpFile.getName());
+ result.add(logManage);
+ num++;
+ }
+ }
+ if (CollectionUtils.isNotEmpty(result)){
+ List list = new LinkedList<>();
+ for (LogManage logManage:result) {
+ list = this.findDirectory(ftpClient, list, logManage.getOrderNum(), workPath + "/" + logManage.getName());
+ ftpClient.changeToParentDirectory();
+ }
+ result.addAll(list);
+ }
+ if (ftpClient != null){
+ ftpClient.disconnect();
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ result = this.LogManageTree(result);
+ return result;
+ }
+
+ @Override
+ public List findFiles(String path) {
+ List result = new ArrayList<>();
+ try {
+ FTPClient ftpClient = ftpUtil.LoginFTP();
+ if (Objects.isNull(ftpClient)){
+ throw new RuntimeException("ftp连接失败!");
+ }
+ List paths = Arrays.asList(path.split("/"));
+ if (CollectionUtils.isNotEmpty(paths)){
+ for (String workPath:paths) {
+ //切换工作文件路径
+ ftpClient.changeWorkingDirectory(workPath);
+ }
+ }
+ ftpClient.enterLocalPassiveMode();
+ List ftpFiles = Arrays.asList(ftpClient.listFiles());
+ if (CollectionUtils.isNotEmpty(ftpFiles)){
+ for (FTPFile ftpFile:ftpFiles) {
+ if (ftpFile.isFile()){
+ FileInfo fileInfo = new FileInfo();
+ fileInfo.setFileName(ftpFile.getName());
+ fileInfo.setFilePath(path +"/"+ ftpFile.getName());
+ fileInfo.setFileSize(String.format("%.2f", Double.valueOf(Double.valueOf(ftpFile.getSize())/1024)) + "KB");
+ fileInfo.setFileDate(DateUtils.formatDate(ftpFile.getTimestamp(),"yyyy-MM-dd"));
+ result.add(fileInfo);
+ }
+ }
+ }
+ if (ftpClient != null){
+ ftpClient.disconnect();
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ return result;
+ }
+
+ /**
+ * 遍历查询当前路径下的文件夹信息
+ * @param ftp
+ * @param list
+ * @param filePath 以"/"开始和结束
+ * @return
+ */
+ public List findDirectory(FTPClient ftp,List list,Integer parentNum,String filePath){
+ try {
+ if (filePath.indexOf("/")>0){
+ List paths = Arrays.asList(filePath.split("/"));
+ for (String path:paths) {
+ ftp.changeWorkingDirectory(path);
+ }
+ }
+ List ftpFiles = Arrays.asList(ftp.listDirectories());
+ if (CollectionUtils.isNotEmpty(ftpFiles)){
+ int num =1;
+ for (FTPFile file : ftpFiles) {
+ if (file.isDirectory()) {
+ LogManage logManage = new LogManage();
+ logManage.setName(file.getName());
+ logManage.setOrderNum(num);
+ logManage.setParentNum(parentNum);
+ logManage.setPath(filePath +"/"+ file.getName());
+ list.add(logManage);
+ num++;
+ // 需要加此判断。否则,ftp默认将‘项目文件所在目录之下的目录(./)’与‘项目文件所在目录向上一级目录下的目录(../)’都纳入递归,这样下去就陷入一个死循环了。需将其过滤掉。
+ if (!".".equals(file.getName()) && !"..".equals(file.getName())) {
+ findDirectory(ftp,list,num,filePath +"/"+ file.getName());
+ ftp.changeToParentDirectory();
+ }
+ }
+ }
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ return list;
+ }
+
+ /**
+ * 将当前的文件夹转换成树形结构
+ * @param logManages
+ * @return
+ */
+ public List LogManageTree(List logManages){
+ if (logManages == null) {
+ return null;
+ }
+ List result = new LinkedList<>();
+ Integer TOP_NODE_ID = 0;
+ logManages.forEach(logManage -> {
+ Integer pid = logManage.getParentNum();
+ if (pid == null || TOP_NODE_ID.equals(pid)) {
+ result.add(logManage);
+ return;
+ }
+ for (LogManage manage : logManages) {
+ Integer id = manage.getOrderNum();
+ if (id != null && id.equals(pid)) {
+ if (manage.getChildren() == null) {
+ manage.initChildren();
+ }
+ logManage.setHashParent(true);
+ manage.getChildren().add(logManage);
+ manage.setHashChild(true);
+ return;
+ }
+ }
+ });
+ return result;
+ }
+
+}
diff --git a/jeecg-module-station-operation/pom.xml b/jeecg-module-station-operation/pom.xml
new file mode 100644
index 00000000..5ecd6f67
--- /dev/null
+++ b/jeecg-module-station-operation/pom.xml
@@ -0,0 +1,34 @@
+
+
+ 4.0.0
+
+ org.jeecgframework.boot
+ jeecg-boot-parent
+ 3.5.1
+
+
+ jeecg-module-station-operation
+
+
+
+
+ org.jeecgframework.boot
+ jeecg-boot-starter-cloud
+
+
+
+ org.jeecgframework.boot
+ jeecg-boot-base-core
+
+
+
+
+ com.spatial4j
+ spatial4j
+ 0.5
+
+
+
+
\ No newline at end of file
diff --git a/jeecg-module-station-operation/src/main/java/org/jeecg/common/CacheName.java b/jeecg-module-station-operation/src/main/java/org/jeecg/common/CacheName.java
new file mode 100644
index 00000000..b4e775de
--- /dev/null
+++ b/jeecg-module-station-operation/src/main/java/org/jeecg/common/CacheName.java
@@ -0,0 +1,15 @@
+package org.jeecg.common;
+
+import org.springframework.stereotype.Component;
+
+public class CacheName {
+
+ public static final String cacheTime = "Cache time";
+
+ public static final String scaleInterval = "Scale interval";
+
+ public static final String timelineLength = "Timeline length";
+
+ public static final String updateIntervalTime = "Update interval time";
+
+}
diff --git a/jeecg-module-station-operation/src/main/java/org/jeecg/common/PointUtil.java b/jeecg-module-station-operation/src/main/java/org/jeecg/common/PointUtil.java
new file mode 100644
index 00000000..379bfa94
--- /dev/null
+++ b/jeecg-module-station-operation/src/main/java/org/jeecg/common/PointUtil.java
@@ -0,0 +1,39 @@
+package org.jeecg.common;
+
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+
+import java.util.Objects;
+
+public class PointUtil {
+
+ public static String calculate(String pointValue){
+ Double Degrees = 0.0;
+ Double minutes = 0.0;
+ Double seconds = 0.0;
+ if (pointValue.indexOf("°")>0 || pointValue.indexOf("′")>0 || pointValue.indexOf("″")>0){
+ if (pointValue.indexOf("°")>0){
+ Degrees = Double.valueOf(pointValue.substring(0, pointValue.indexOf("°")));
+ pointValue = pointValue.substring(pointValue.indexOf("°")+1);
+ }
+ if (pointValue.indexOf("′")>0){
+ minutes = Double.valueOf(pointValue.substring(0, pointValue.indexOf("′")));
+ pointValue = pointValue.substring(pointValue.indexOf("′")+1);
+ }
+ if (pointValue.indexOf("″")>0){
+ seconds = Double.valueOf(pointValue.substring(0, pointValue.indexOf("″")));
+ }
+ if (Objects.nonNull(Degrees) || Objects.nonNull(minutes) || Objects.nonNull(seconds)){
+ Double result = Degrees + minutes/60+seconds/3600;
+ if (pointValue.indexOf("W")>0 || pointValue.indexOf("S")>0){
+ result = -1 * result;
+ }
+ pointValue = String.valueOf(result);
+ }
+ }
+ return pointValue;
+ }
+
+
+
+}
diff --git a/jeecg-module-station-operation/src/main/java/org/jeecg/common/StationTypeUtil.java b/jeecg-module-station-operation/src/main/java/org/jeecg/common/StationTypeUtil.java
new file mode 100644
index 00000000..9ac4a4b2
--- /dev/null
+++ b/jeecg-module-station-operation/src/main/java/org/jeecg/common/StationTypeUtil.java
@@ -0,0 +1,36 @@
+package org.jeecg.common;
+
+import org.apache.commons.lang3.StringUtils;
+import org.jeecg.modules.entity.StationType;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Component
+public class StationTypeUtil {
+
+ @Autowired
+ private StationType stationType;
+
+ public List findAllStationType(){
+ List stationTypeList = stationType.getTypes();
+ List stationTypes = stationTypeList.stream().map(StationType::getName).collect(Collectors.toList());
+ return stationTypes;
+ }
+
+ public String getStationType(Integer stationId){
+ String type = "";
+ List stationTypeList = stationType.getTypes();
+ for (StationType stationType:stationTypeList) {
+ if (StringUtils.isNotBlank(stationType.getMinId()) && StringUtils.isNotBlank(stationType.getMaxId())){
+ if (stationId>Integer.valueOf(stationType.getMinId()) && stationId<=Integer.valueOf(stationType.getMaxId())){
+ type = stationType.getName();
+ }
+ }
+ }
+ return type;
+ }
+
+}
diff --git a/jeecg-module-station-operation/src/main/java/org/jeecg/modules/controller/StationOperationController.java b/jeecg-module-station-operation/src/main/java/org/jeecg/modules/controller/StationOperationController.java
new file mode 100644
index 00000000..aa6d7b1a
--- /dev/null
+++ b/jeecg-module-station-operation/src/main/java/org/jeecg/modules/controller/StationOperationController.java
@@ -0,0 +1,68 @@
+package org.jeecg.modules.controller;
+
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.modules.entity.Point;
+import org.jeecg.modules.entity.PointVo;
+import org.jeecg.modules.entity.StationOperation;
+import org.jeecg.modules.service.IStationOperationService;
+import org.jeecg.modules.system.entity.GardsNuclearfacility;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
+
+@RestController
+@RequestMapping("stationOperation")
+@Api(value = "台站运行管理", tags = "台站运行管理")
+public class StationOperationController {
+
+ @Autowired
+ private IStationOperationService stationOperationService;
+
+ @GetMapping("findStationType")
+ @ApiOperation(value = "查询台站,核设施类型", notes = "查询台站,核设施类型")
+ public List findStationType(){
+ List result = stationOperationService.findStationType();
+ return result;
+ }
+
+ @GetMapping("findList")
+ @ApiOperation(value = "查询所有台站,核设施信息", notes = "查询所有台站,核设施信息")
+ public List findList(String status, String stationType){
+ List result = stationOperationService.findList(status, stationType);
+ return result;
+ }
+
+ @GetMapping("findInfo")
+ @ApiOperation(value = "查询台站/核设施详情信息", notes = "查询台站/核设施详情信息")
+ public Result findInfo(String stationId, String type){
+ Result result = stationOperationService.findInfo(stationId, type);
+ return result;
+ }
+
+ @GetMapping("findTree")
+ @ApiOperation(value = "查询台站树形结构", notes = "查询台站树形结构")
+ public Result findTree(){
+ Result result = stationOperationService.findTree();
+ return result;
+ }
+
+ @PostMapping("getHitEquList")
+ @ApiOperation(value = "查询半径内核设施信息", notes = "查询半径内核设施信息")
+ public Result getHitEquList(@RequestBody PointVo pointVo){
+ Result result = stationOperationService.getHitEquList(pointVo);
+ return result;
+ }
+
+ @GetMapping("getDataReceivingStatus")
+ @ApiOperation(value = "查询台站监测数据信息", notes = "查询台站监测数据信息")
+ public Result getDataReceivingStatus(String userId){
+ return stationOperationService.getDataReceivingStatus(userId);
+ }
+
+}
diff --git a/jeecg-module-station-operation/src/main/java/org/jeecg/modules/controller/SysUserFocusStationController.java b/jeecg-module-station-operation/src/main/java/org/jeecg/modules/controller/SysUserFocusStationController.java
new file mode 100644
index 00000000..85ef4324
--- /dev/null
+++ b/jeecg-module-station-operation/src/main/java/org/jeecg/modules/controller/SysUserFocusStationController.java
@@ -0,0 +1,51 @@
+package org.jeecg.modules.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.config.valid.InsertGroup;
+import org.jeecg.modules.entity.SysUserFocusStation;
+import org.jeecg.modules.entity.UserFocusStation;
+import org.jeecg.modules.service.ISysUserFocusStationService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("sysUserFocusStation")
+@Api(value = "关注台站管理", tags = "关注台站管理")
+public class SysUserFocusStationController {
+
+ @Autowired
+ private ISysUserFocusStationService sysUserFocusStationService;
+
+ @GetMapping("findList")
+ @ApiOperation(value = "查询关注台站列表", notes = "查询关注台站列表")
+ public List findList(){
+ List result = sysUserFocusStationService.findList();
+ return result;
+ }
+
+ @PostMapping("saveUserFocusByUserId")
+ @ApiOperation(value = "保存用户关注台站及缓存配置信息", notes = "保存用户关注台站及缓存配置信息")
+ public Result create(@RequestBody UserFocusStation userFocusStation){
+ return sysUserFocusStationService.create(userFocusStation);
+ }
+
+ @DeleteMapping("deleteById")
+ @ApiOperation(value = "取消关注", notes = "取消关注")
+ public Result deleteById(String stationId){
+ return sysUserFocusStationService.deleteById(stationId);
+ }
+
+ @GetMapping("findUserFocusByUserId")
+ @ApiOperation(value = "根据用户id查询用户的缓存配置信息及关注台站信息", notes = "根据用户id查询用户的缓存配置信息及关注台站信息")
+ public Result findUserFocusByUserId(String userId){
+ return sysUserFocusStationService.findUserFocusByUserId(userId);
+ }
+
+
+
+}
diff --git a/jeecg-module-station-operation/src/main/java/org/jeecg/modules/entity/DataInfoVo.java b/jeecg-module-station-operation/src/main/java/org/jeecg/modules/entity/DataInfoVo.java
new file mode 100644
index 00000000..1fa773df
--- /dev/null
+++ b/jeecg-module-station-operation/src/main/java/org/jeecg/modules/entity/DataInfoVo.java
@@ -0,0 +1,43 @@
+package org.jeecg.modules.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+public class DataInfoVo implements Serializable {
+
+ /**
+ * 类型
+ */
+ private String type;
+
+ /**
+ * 状态
+ */
+ private String status;
+
+ /**
+ * 开始时间
+ */
+ private Double beginTime;
+
+ /**
+ * 结束时间
+ */
+ private Double endTime;
+
+ /**
+ * 时间间隔
+ */
+ private Double spanTime;
+
+ /**
+ * 比率
+ */
+ private Double rate;
+
+}
diff --git a/jeecg-module-station-operation/src/main/java/org/jeecg/modules/entity/DetectorData.java b/jeecg-module-station-operation/src/main/java/org/jeecg/modules/entity/DetectorData.java
new file mode 100644
index 00000000..2059a209
--- /dev/null
+++ b/jeecg-module-station-operation/src/main/java/org/jeecg/modules/entity/DetectorData.java
@@ -0,0 +1,26 @@
+package org.jeecg.modules.entity;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class DetectorData implements Serializable {
+
+ /**
+ * 探测器id
+ */
+ private Integer detectorId;
+
+ /**
+ * 探测器编码
+ */
+ private String detectorCode;
+
+ /**
+ * 数据集合
+ */
+ private List dataList;
+
+}
diff --git a/jeecg-module-station-operation/src/main/java/org/jeecg/modules/entity/Point.java b/jeecg-module-station-operation/src/main/java/org/jeecg/modules/entity/Point.java
new file mode 100644
index 00000000..bdd4af19
--- /dev/null
+++ b/jeecg-module-station-operation/src/main/java/org/jeecg/modules/entity/Point.java
@@ -0,0 +1,40 @@
+package org.jeecg.modules.entity;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class Point implements Serializable {
+
+ /**
+ * 台站名称
+ */
+ private String stationName;
+
+ /**
+ * 核设施名称
+ */
+ private String nuclearFacilityName;
+
+ /**
+ * 经度
+ */
+ private String lon;
+
+ /**
+ * 纬度
+ */
+ private String lat;
+
+ /**
+ * 半径
+ */
+ private String radius;
+
+ /**
+ * 核设施id
+ */
+ private String nuclearFacilityId;
+
+}
diff --git a/jeecg-module-station-operation/src/main/java/org/jeecg/modules/entity/PointVo.java b/jeecg-module-station-operation/src/main/java/org/jeecg/modules/entity/PointVo.java
new file mode 100644
index 00000000..f9677726
--- /dev/null
+++ b/jeecg-module-station-operation/src/main/java/org/jeecg/modules/entity/PointVo.java
@@ -0,0 +1,20 @@
+package org.jeecg.modules.entity;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class PointVo {
+
+ /**
+ * 台站id集合
+ */
+ private List stationIds;
+
+ /**
+ * 半径
+ */
+ private Double radius;
+
+}
diff --git a/jeecg-module-station-operation/src/main/java/org/jeecg/modules/entity/StationData.java b/jeecg-module-station-operation/src/main/java/org/jeecg/modules/entity/StationData.java
new file mode 100644
index 00000000..20ab50f2
--- /dev/null
+++ b/jeecg-module-station-operation/src/main/java/org/jeecg/modules/entity/StationData.java
@@ -0,0 +1,28 @@
+package org.jeecg.modules.entity;
+
+import lombok.Data;
+import org.jeecg.modules.system.entity.GardsDetectors;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+@Data
+public class StationData implements Serializable {
+
+ /**
+ * 台站id
+ */
+ private String stationId;
+
+ /**
+ * 台站编码
+ */
+ private String stationCode;
+
+ /**
+ * 探测器数据集合
+ */
+ private Map>> detectors;
+
+}
diff --git a/jeecg-module-station-operation/src/main/java/org/jeecg/modules/entity/StationOperation.java b/jeecg-module-station-operation/src/main/java/org/jeecg/modules/entity/StationOperation.java
new file mode 100644
index 00000000..d562f278
--- /dev/null
+++ b/jeecg-module-station-operation/src/main/java/org/jeecg/modules/entity/StationOperation.java
@@ -0,0 +1,50 @@
+package org.jeecg.modules.entity;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class StationOperation implements Serializable {
+
+ /**
+ * 台站/核设施id
+ */
+ private Integer stationId;
+
+ /**
+ * 台站/核设施名称
+ */
+ private String stationName;
+
+ /**
+ * 台站/核设施类型
+ */
+ private String stationType;
+
+ /**
+ * 海拔
+ */
+ private String altitude;
+
+ /**
+ * 经度
+ */
+ private String lon;
+
+ /**
+ * 纬度
+ */
+ private String lat;
+
+ /**
+ * 状态
+ */
+ private String status;
+
+ /**
+ * 标记
+ */
+ private String signal;
+
+}
diff --git a/jeecg-module-station-operation/src/main/java/org/jeecg/modules/entity/StationReceivingConfig.java b/jeecg-module-station-operation/src/main/java/org/jeecg/modules/entity/StationReceivingConfig.java
new file mode 100644
index 00000000..1983fe79
--- /dev/null
+++ b/jeecg-module-station-operation/src/main/java/org/jeecg/modules/entity/StationReceivingConfig.java
@@ -0,0 +1,58 @@
+package org.jeecg.modules.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+@TableName(value = "station_receiving_config")
+public class StationReceivingConfig implements Serializable {
+
+ /**
+ * id
+ */
+ @TableId(value = "id", type = IdType.ASSIGN_ID)
+ private String id;
+
+ /**
+ * 用户id
+ */
+ @TableField(value = "user_id")
+ private String userId;
+
+ /**
+ * 缓存时间
+ */
+ @TableField(value = "cache_time")
+ private Double cacheTime;
+
+ /**
+ * 间隔缩放
+ */
+ @TableField(value = "scale_interval")
+ private Double scaleInterval;
+
+ /**
+ * 时间线长度
+ */
+ @TableField(value = "timeline_length")
+ private Double timelineLength;
+
+ /**
+ * 更新间隔时间
+ */
+ @TableField(value = "update_interval_time")
+ private Double updateIntervalTime;
+
+ /**
+ * 用户关注台站信息
+ */
+ @TableField(exist = false)
+ List sysUserFocusStations;
+
+}
diff --git a/jeecg-module-station-operation/src/main/java/org/jeecg/modules/entity/StationTree.java b/jeecg-module-station-operation/src/main/java/org/jeecg/modules/entity/StationTree.java
new file mode 100644
index 00000000..c4010b9a
--- /dev/null
+++ b/jeecg-module-station-operation/src/main/java/org/jeecg/modules/entity/StationTree.java
@@ -0,0 +1,26 @@
+package org.jeecg.modules.entity;
+
+import lombok.Data;
+import org.jeecg.modules.system.entity.GardsStations;
+
+import java.util.List;
+
+@Data
+public class StationTree {
+
+ /**
+ * 台站id
+ */
+ private Integer stationId;
+
+ /**
+ * 编码
+ */
+ private String code;
+
+ /**
+ * 子数据集合
+ */
+ List