Parcourir la source

停机和告警数据治理。

wukai il y a 11 mois
Parent
commit
c0d27e451c

+ 45 - 136
ruoyi-admin/src/main/java/com/ruoyi/biz/domain/TwinCalcAlarms.java

@@ -1,13 +1,13 @@
 package com.ruoyi.biz.domain;
 
-import java.util.Date;
 import com.fasterxml.jackson.annotation.JsonFormat;
-import org.apache.commons.lang3.builder.ToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
 import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
-import com.ruoyi.common.core.domain.BaseEntity;
+import lombok.Data;
+
+import java.util.Date;
 
 /**
  * 告警数据统计对象 twin_calc_alarms
@@ -16,183 +16,92 @@ import com.ruoyi.common.core.domain.BaseEntity;
  * @date 2024-06-28
  */
 @ApiModel(value = "ITwinCalcAlarms", description = "告警数据统计")
-public class TwinCalcAlarms extends BaseEntity
-{
+@Data
+public class TwinCalcAlarms extends BaseEntity {
     private static final long serialVersionUID = 1L;
 
-    /** ID */
+    /**
+     * ID
+     */
     private Long id;
 
-    /** 设备ID */
+    /**
+     * 设备ID
+     */
     @Excel(name = "设备ID")
     @ApiModelProperty("设备ID")
     private Long deviceId;
 
-    /** 日期 */
+    /**
+     * 日期
+     */
     @JsonFormat(pattern = "yyyy-MM-dd")
     @Excel(name = "日期", width = 30, dateFormat = "yyyy-MM-dd")
     @ApiModelProperty("日期")
     private Date dataDate;
 
-    /** 小时;0-23 */
+    /**
+     * 小时;0-23
+     */
     @Excel(name = "小时;0-23")
     @ApiModelProperty("小时;0-23")
     private String hour;
 
-    /** 告警开始时间 */
+    /**
+     * 告警开始时间
+     */
     @JsonFormat(pattern = "yyyy-MM-dd")
     @Excel(name = "告警开始时间", width = 30, dateFormat = "yyyy-MM-dd")
     @ApiModelProperty("告警开始时间")
     private Date startTime;
 
-    /** 告警停止时间 */
+    /**
+     * 告警停止时间
+     */
     @JsonFormat(pattern = "yyyy-MM-dd")
     @Excel(name = "告警停止时间", width = 30, dateFormat = "yyyy-MM-dd")
     @ApiModelProperty("告警停止时间")
     private Date endTime;
 
-    /** 告警类型;接口对应的编号 */
+    /**
+     * 告警类型;接口对应的编号
+     */
     @Excel(name = "告警类型;接口对应的编号")
     @ApiModelProperty("告警类型;接口对应的编号")
     private Long alarmType;
-
-    /** 创建人 */
+    /**
+     * 统计状态
+     */
+    @Excel(name = "统计状态")
+    @ApiModelProperty("统计状态")
+    private String calcStatus;
+    /**
+     * 创建人
+     */
     @Excel(name = "创建人")
     @ApiModelProperty("创建人")
     private String createdBy;
 
-    /** 创建时间 */
+    /**
+     * 创建时间
+     */
     @JsonFormat(pattern = "yyyy-MM-dd")
     @Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd")
     @ApiModelProperty("创建时间")
     private Date createdTime;
 
-    /** 更新人 */
+    /**
+     * 更新人
+     */
     @Excel(name = "更新人")
     @ApiModelProperty("更新人")
     private String updatedBy;
 
-    /** 更新时间 */
+    /**
+     * 更新时间
+     */
     @JsonFormat(pattern = "yyyy-MM-dd")
     @Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd")
     @ApiModelProperty("更新时间")
     private Date updatedTime;
-
-    public void setId(Long id)
-    {
-        this.id = id;
-    }
-
-    public Long getId()
-    {
-        return id;
-    }
-    public void setDeviceId(Long deviceId)
-    {
-        this.deviceId = deviceId;
-    }
-
-    public Long getDeviceId()
-    {
-        return deviceId;
-    }
-    public void setDataDate(Date dataDate)
-    {
-        this.dataDate = dataDate;
-    }
-
-    public Date getDataDate()
-    {
-        return dataDate;
-    }
-    public void setHour(String hour)
-    {
-        this.hour = hour;
-    }
-
-    public String getHour()
-    {
-        return hour;
-    }
-    public void setStartTime(Date startTime)
-    {
-        this.startTime = startTime;
-    }
-
-    public Date getStartTime()
-    {
-        return startTime;
-    }
-    public void setEndTime(Date endTime)
-    {
-        this.endTime = endTime;
-    }
-
-    public Date getEndTime()
-    {
-        return endTime;
-    }
-    public void setAlarmType(Long alarmType)
-    {
-        this.alarmType = alarmType;
-    }
-
-    public Long getAlarmType()
-    {
-        return alarmType;
-    }
-    public void setCreatedBy(String createdBy)
-    {
-        this.createdBy = createdBy;
-    }
-
-    public String getCreatedBy()
-    {
-        return createdBy;
-    }
-    public void setCreatedTime(Date createdTime)
-    {
-        this.createdTime = createdTime;
-    }
-
-    public Date getCreatedTime()
-    {
-        return createdTime;
-    }
-    public void setUpdatedBy(String updatedBy)
-    {
-        this.updatedBy = updatedBy;
-    }
-
-    public String getUpdatedBy()
-    {
-        return updatedBy;
-    }
-    public void setUpdatedTime(Date updatedTime)
-    {
-        this.updatedTime = updatedTime;
-    }
-
-    public Date getUpdatedTime()
-    {
-        return updatedTime;
-    }
-
-    @Override
-    public String toString() {
-        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
-            .append("id", getId())
-            .append("deviceId", getDeviceId())
-            .append("dataDate", getDataDate())
-            .append("hour", getHour())
-            .append("startTime", getStartTime())
-            .append("endTime", getEndTime())
-            .append("alarmType", getAlarmType())
-            .append("createdBy", getCreatedBy())
-            .append("createdTime", getCreatedTime())
-            .append("updatedBy", getUpdatedBy())
-            .append("updatedTime", getUpdatedTime())
-            .append("remark", getRemark())
-            .toString();
-    }
 }

+ 6 - 1
ruoyi-admin/src/main/java/com/ruoyi/biz/domain/TwinCalcStop.java

@@ -69,7 +69,12 @@ public class TwinCalcStop extends BaseEntity {
     @Excel(name = "停机类型;1停经片停机,2-CCD停机(相机号+断纱/故障),3-人工停机,4-断电停机,5-设备故障停机,6-落布米数达到停机,7-盘头剩余圈数达到停机")
     @ApiModelProperty("停机类型;1停经片停机,2-CCD停机(相机号+断纱/故障),3-人工停机,4-断电停机,5-设备故障停机,6-落布米数达到停机,7-盘头剩余圈数达到停机")
     private Integer stopType;
-
+    /**
+     * 统计状态
+     */
+    @Excel(name = "统计状态")
+    @ApiModelProperty("统计状态")
+    private String calcStatus;
     /**
      * 创建人
      */

+ 20 - 10
ruoyi-admin/src/main/java/com/ruoyi/biz/service/ITwinCalcAlarmsService.java

@@ -1,19 +1,21 @@
 package com.ruoyi.biz.service;
 
-import java.util.List;
 import com.ruoyi.biz.domain.TwinCalcAlarms;
+import com.ruoyi.biz.domain.TwinDevice;
+
+import java.time.LocalDateTime;
+import java.util.List;
 
 /**
  * 告警数据统计Service接口
- * 
+ *
  * @author wukai
  * @date 2024-06-28
  */
-public interface ITwinCalcAlarmsService 
-{
+public interface ITwinCalcAlarmsService {
     /**
      * 查询告警数据统计
-     * 
+     *
      * @param id 告警数据统计主键
      * @return 告警数据统计
      */
@@ -21,7 +23,7 @@ public interface ITwinCalcAlarmsService
 
     /**
      * 查询告警数据统计列表
-     * 
+     *
      * @param twinCalcAlarms 告警数据统计
      * @return 告警数据统计集合
      */
@@ -29,7 +31,7 @@ public interface ITwinCalcAlarmsService
 
     /**
      * 新增告警数据统计
-     * 
+     *
      * @param twinCalcAlarms 告警数据统计
      * @return 结果
      */
@@ -37,7 +39,7 @@ public interface ITwinCalcAlarmsService
 
     /**
      * 修改告警数据统计
-     * 
+     *
      * @param twinCalcAlarms 告警数据统计
      * @return 结果
      */
@@ -45,7 +47,7 @@ public interface ITwinCalcAlarmsService
 
     /**
      * 批量删除告警数据统计
-     * 
+     *
      * @param ids 需要删除的告警数据统计主键集合
      * @return 结果
      */
@@ -53,9 +55,17 @@ public interface ITwinCalcAlarmsService
 
     /**
      * 删除告警数据统计信息
-     * 
+     *
      * @param id 告警数据统计主键
      * @return 结果
      */
     public int deleteTwinCalcAlarmsById(Long id);
+
+    /**
+     * 告警数据治理,从告警记录表到告警统计表中
+     *
+     * @param startTime  开始时间
+     * @param deviceList 设备列表
+     */
+    void process(LocalDateTime startTime, List<TwinDevice> deviceList);
 }

+ 20 - 10
ruoyi-admin/src/main/java/com/ruoyi/biz/service/ITwinCalcStopService.java

@@ -1,19 +1,21 @@
 package com.ruoyi.biz.service;
 
-import java.util.List;
 import com.ruoyi.biz.domain.TwinCalcStop;
+import com.ruoyi.biz.domain.TwinDevice;
+
+import java.time.LocalDateTime;
+import java.util.List;
 
 /**
  * 停机数据统计Service接口
- * 
+ *
  * @author ruoyi
  * @date 2024-06-28
  */
-public interface ITwinCalcStopService 
-{
+public interface ITwinCalcStopService {
     /**
      * 查询停机数据统计
-     * 
+     *
      * @param id 停机数据统计主键
      * @return 停机数据统计
      */
@@ -21,7 +23,7 @@ public interface ITwinCalcStopService
 
     /**
      * 查询停机数据统计列表
-     * 
+     *
      * @param twinCalcStop 停机数据统计
      * @return 停机数据统计集合
      */
@@ -29,7 +31,7 @@ public interface ITwinCalcStopService
 
     /**
      * 新增停机数据统计
-     * 
+     *
      * @param twinCalcStop 停机数据统计
      * @return 结果
      */
@@ -37,7 +39,7 @@ public interface ITwinCalcStopService
 
     /**
      * 修改停机数据统计
-     * 
+     *
      * @param twinCalcStop 停机数据统计
      * @return 结果
      */
@@ -45,7 +47,7 @@ public interface ITwinCalcStopService
 
     /**
      * 批量删除停机数据统计
-     * 
+     *
      * @param ids 需要删除的停机数据统计主键集合
      * @return 结果
      */
@@ -53,9 +55,17 @@ public interface ITwinCalcStopService
 
     /**
      * 删除停机数据统计信息
-     * 
+     *
      * @param id 停机数据统计主键
      * @return 结果
      */
     public int deleteTwinCalcStopById(Long id);
+
+    /**
+     * 停机数据治理,从停机记录表到停机统计表中
+     *
+     * @param startTime  开始时间
+     * @param deviceList 设备列表
+     */
+    void process(LocalDateTime startTime, List<TwinDevice> deviceList);
 }

+ 63 - 29
ruoyi-admin/src/main/java/com/ruoyi/biz/service/impl/TaskServiceImpl.java

@@ -43,6 +43,10 @@ public class TaskServiceImpl implements ITaskService {
     private AsyncServiceImpl asyncService;
     @Resource
     private ITwinCalcDayService dayService;
+    @Resource
+    private ITwinCalcStopService stopService;
+    @Resource
+    private ITwinCalcAlarmsService alarmsService;
 
     /**
      * 从数据库最后一个时间段统计至当前的上一个偶数时间点
@@ -84,7 +88,7 @@ public class TaskServiceImpl implements ITaskService {
     @Override
     public void calcLastHour() {
         LocalDateTime ldt = Tools.currWholeTime();
-        //当前时间之前的偶数时间段
+        //上一个小时
         ldt = ldt.minusHours(1);
         //开始时间需要向前取一秒
         LocalDateTime start = ldt.minusSeconds(1);
@@ -193,37 +197,27 @@ public class TaskServiceImpl implements ITaskService {
         }
 
         Date d = new Date();
+        dbProcess(endTime, calcHours, stopList, alarmsList, panList);
+        stopService.process(ldt, list);
+        alarmsService.process(ldt, list);
         log.info("总共消耗:{}ms", d.getTime() - s.getTime());
-        //1小时统计数据
-        String sql = "INSERT INTO TWIN_CALC_HOUR(DATA_DATE,HOUR,DEVICE_ID,KWH,WEIGHT,LENGTH,OPEN_TIME,CLOSE_TIME) VALUES (?,?,?,?,?,?,?,?)";
-        jdbcTemplate.batchUpdate(sql, calcHours);
-        //盘头数据
-        sql = "INSERT INTO TWIN_PAN_HEAD_INFO (DEVICE_ID,PH_NUM,PH_MAX,RECORD_TIME) VALUES (?,?,?,?)";
-        jdbcTemplate.batchUpdate(sql, panList);
-        //执行停机记录处理
-        stopList.forEach(stop -> {
-            if (stop.getStartTime() != null) {
-                jdbcTemplate.update("INSERT INTO TWIN_RECORD_STOP (DEVICE_ID,DATA_DATE,HOUR,START_TIME,STOP_TYPE,CALC_STATUS) VALUES (?,?,?,?,?,?)", stop.getDeviceId(), stop.getDataDate(), stop.getHour(), stop.getStartTime(), stop.getStopType(), "0");
-            }
-            if (stop.getEndTime() != null) {
-                jdbcTemplate.update("UPDATE TWIN_RECORD_STOP SET END_TIME=? WHERE DEVICE_ID=? AND STOP_TYPE=? AND END_TIME IS NULL", stop.getEndTime(), stop.getDeviceId(), stop.getStopType());
-            }
-        });
-        //补一次,所有没有结束时间的为当前结束时间
-        jdbcTemplate.update("UPDATE TWIN_RECORD_STOP SET END_TIME=? WHERE END_TIME IS NULL", new Date(endTime));
-        //执行告警记录处理
-        alarmsList.forEach(alarms -> {
-            if (alarms.getStartTime() != null) {
-                jdbcTemplate.update("INSERT INTO TWIN_RECORD_ALARMS (DEVICE_ID,DATA_DATE,HOUR,START_TIME,ALARM_TYPE,CALC_STATUS) VALUES (?,?,?,?,?,?)", alarms.getDeviceId(), alarms.getDataDate(), alarms.getHour(), alarms.getStartTime(), alarms.getAlarmType(), "0");
-            }
-            if (alarms.getEndTime() != null) {
-                jdbcTemplate.update("UPDATE TWIN_RECORD_ALARMS SET END_TIME=? WHERE DEVICE_ID=? AND ALARM_TYPE=? AND END_TIME IS NULL", alarms.getEndTime(), alarms.getDeviceId(), alarms.getAlarmType());
-            }
-        });
-        //补一次,所有没有结束时间的为当前结束时间
-        jdbcTemplate.update("UPDATE TWIN_RECORD_ALARMS SET END_TIME=? WHERE END_TIME IS NULL", new Date(endTime));
+
     }
 
+    /**
+     * 执行数据获取操作
+     *
+     * @param list         设备列表
+     * @param date         日期
+     * @param startTime    开始时间
+     * @param endTime      结束时间
+     * @param period       小时数
+     * @param calcHourList 1小时统计数据
+     * @param stopList     停机数据
+     * @param panList      盘头数据
+     * @param alarmsList   告警数据
+     * @return 返回未获取成功的数据列表
+     */
 
     private List<TwinDevice> exec(List<TwinDevice> list, Date date, Long startTime, Long endTime, int period, List<Object[]> calcHourList, List<TwinRecordStop> stopList, List<Object[]> panList, List<TwinRecordAlarms> alarmsList) {
         List<Future<Map<String, List<?>>>> futureList = new ArrayList<>();
@@ -260,4 +254,44 @@ public class TaskServiceImpl implements ITaskService {
 
         return errList;
     }
+
+    /**
+     * 数据入库操作
+     *
+     * @param endTime    结束时间
+     * @param calcHours  1小时统计数据
+     * @param stopList   停机记录
+     * @param alarmsList 告警记录
+     * @param panList    盘头记录
+     */
+    private void dbProcess(long endTime, List<Object[]> calcHours, List<TwinRecordStop> stopList, List<TwinRecordAlarms> alarmsList, List<Object[]> panList) {
+        //1小时统计数据
+        String sql = "INSERT INTO TWIN_CALC_HOUR(DATA_DATE,HOUR,DEVICE_ID,KWH,WEIGHT,LENGTH,OPEN_TIME,CLOSE_TIME) VALUES (?,?,?,?,?,?,?,?)";
+        jdbcTemplate.batchUpdate(sql, calcHours);
+        //盘头数据
+        sql = "INSERT INTO TWIN_PAN_HEAD_INFO (DEVICE_ID,PH_NUM,PH_MAX,RECORD_TIME) VALUES (?,?,?,?)";
+        jdbcTemplate.batchUpdate(sql, panList);
+        //执行停机记录处理
+        stopList.forEach(stop -> {
+            if (stop.getStartTime() != null) {
+                jdbcTemplate.update("INSERT INTO TWIN_RECORD_STOP (DEVICE_ID,DATA_DATE,HOUR,START_TIME,STOP_TYPE,CALC_STATUS) VALUES (?,?,?,?,?,?)", stop.getDeviceId(), stop.getDataDate(), stop.getHour(), stop.getStartTime(), stop.getStopType(), "0");
+            }
+            if (stop.getEndTime() != null) {
+                jdbcTemplate.update("UPDATE TWIN_RECORD_STOP SET END_TIME=? WHERE DEVICE_ID=? AND STOP_TYPE=? AND END_TIME IS NULL", stop.getEndTime(), stop.getDeviceId(), stop.getStopType());
+            }
+        });
+        //补一次,所有没有结束时间的为当前结束时间
+        jdbcTemplate.update("UPDATE TWIN_RECORD_STOP SET END_TIME=?,CALC_STATUS=1 WHERE END_TIME IS NULL", new Date(endTime));
+        //执行告警记录处理
+        alarmsList.forEach(alarms -> {
+            if (alarms.getStartTime() != null) {
+                jdbcTemplate.update("INSERT INTO TWIN_RECORD_ALARMS (DEVICE_ID,DATA_DATE,HOUR,START_TIME,ALARM_TYPE,CALC_STATUS) VALUES (?,?,?,?,?,?)", alarms.getDeviceId(), alarms.getDataDate(), alarms.getHour(), alarms.getStartTime(), alarms.getAlarmType(), "0");
+            }
+            if (alarms.getEndTime() != null) {
+                jdbcTemplate.update("UPDATE TWIN_RECORD_ALARMS SET END_TIME=? WHERE DEVICE_ID=? AND ALARM_TYPE=? AND END_TIME IS NULL", alarms.getEndTime(), alarms.getDeviceId(), alarms.getAlarmType());
+            }
+        });
+        //补一次,所有没有结束时间的为当前结束时间
+        jdbcTemplate.update("UPDATE TWIN_RECORD_ALARMS SET END_TIME=?,CALC_STATUS=1 WHERE END_TIME IS NULL", new Date(endTime));
+    }
 }

+ 117 - 26
ruoyi-admin/src/main/java/com/ruoyi/biz/service/impl/TwinCalcAlarmsServiceImpl.java

@@ -1,94 +1,185 @@
 package com.ruoyi.biz.service.impl;
 
-import java.util.List;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import com.ruoyi.biz.mapper.TwinCalcAlarmsMapper;
 import com.ruoyi.biz.domain.TwinCalcAlarms;
+import com.ruoyi.biz.domain.TwinDevice;
+import com.ruoyi.biz.domain.TwinRecordAlarms;
+import com.ruoyi.biz.mapper.TwinCalcAlarmsMapper;
 import com.ruoyi.biz.service.ITwinCalcAlarmsService;
+import com.ruoyi.biz.service.ITwinRecordAlarmsService;
 import com.ruoyi.common.core.text.Convert;
+import com.ruoyi.common.utils.bean.BeanUtils;
+import com.ruoyi.system.service.ISysConfigService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * 告警数据统计Service业务层处理
- * 
+ *
  * @author wukai
  * @date 2024-06-28
  */
 @Service
-public class TwinCalcAlarmsServiceImpl implements ITwinCalcAlarmsService 
-{
-    @Autowired
+public class TwinCalcAlarmsServiceImpl implements ITwinCalcAlarmsService {
+    @Resource
     private TwinCalcAlarmsMapper twinCalcAlarmsMapper;
+    @Resource
+    private ITwinRecordAlarmsService alarmsService;
+    @Resource
+    private ISysConfigService configService;
 
     /**
      * 查询告警数据统计
-     * 
+     *
      * @param id 告警数据统计主键
      * @return 告警数据统计
      */
     @Override
-    public TwinCalcAlarms selectTwinCalcAlarmsById(Long id)
-    {
+    public TwinCalcAlarms selectTwinCalcAlarmsById(Long id) {
         return twinCalcAlarmsMapper.selectTwinCalcAlarmsById(id);
     }
 
     /**
      * 查询告警数据统计列表
-     * 
+     *
      * @param twinCalcAlarms 告警数据统计
      * @return 告警数据统计
      */
     @Override
-    public List<TwinCalcAlarms> selectTwinCalcAlarmsList(TwinCalcAlarms twinCalcAlarms)
-    {
+    public List<TwinCalcAlarms> selectTwinCalcAlarmsList(TwinCalcAlarms twinCalcAlarms) {
         return twinCalcAlarmsMapper.selectTwinCalcAlarmsList(twinCalcAlarms);
     }
 
     /**
      * 新增告警数据统计
-     * 
+     *
      * @param twinCalcAlarms 告警数据统计
      * @return 结果
      */
     @Override
-    public int insertTwinCalcAlarms(TwinCalcAlarms twinCalcAlarms)
-    {
+    public int insertTwinCalcAlarms(TwinCalcAlarms twinCalcAlarms) {
         return twinCalcAlarmsMapper.insertTwinCalcAlarms(twinCalcAlarms);
     }
 
     /**
      * 修改告警数据统计
-     * 
+     *
      * @param twinCalcAlarms 告警数据统计
      * @return 结果
      */
     @Override
-    public int updateTwinCalcAlarms(TwinCalcAlarms twinCalcAlarms)
-    {
+    public int updateTwinCalcAlarms(TwinCalcAlarms twinCalcAlarms) {
         return twinCalcAlarmsMapper.updateTwinCalcAlarms(twinCalcAlarms);
     }
 
     /**
      * 批量删除告警数据统计
-     * 
+     *
      * @param ids 需要删除的告警数据统计主键
      * @return 结果
      */
     @Override
-    public int deleteTwinCalcAlarmsByIds(String ids)
-    {
+    public int deleteTwinCalcAlarmsByIds(String ids) {
         return twinCalcAlarmsMapper.deleteTwinCalcAlarmsByIds(Convert.toStrArray(ids));
     }
 
     /**
      * 删除告警数据统计信息
-     * 
+     *
      * @param id 告警数据统计主键
      * @return 结果
      */
     @Override
-    public int deleteTwinCalcAlarmsById(Long id)
-    {
+    public int deleteTwinCalcAlarmsById(Long id) {
         return twinCalcAlarmsMapper.deleteTwinCalcAlarmsById(id);
     }
+
+    /**
+     * 告警数据治理,从告警记录表到告警统计表中
+     *
+     * @param startTime  开始时间
+     * @param deviceList 设备列表
+     */
+    @Override
+    public void process(LocalDateTime startTime, List<TwinDevice> deviceList) {
+        String config = configService.selectConfigByKey("data.legal.time");
+        int legalTime = Integer.parseInt(config) * 1000;
+
+        Date date = Date.from(startTime.toLocalDate().atStartOfDay(ZoneOffset.of("+8")).toInstant());
+        String oldStr = "old";
+        deviceList.forEach(device -> {
+            //先处理上次未统计完整的数据
+            TwinCalcAlarms calcSearch = new TwinCalcAlarms();
+            calcSearch.setDeviceId(device.getDeviceId());
+            calcSearch.setCalcStatus("1");
+            List<TwinRecordAlarms> list = new ArrayList<>();
+            List<TwinCalcAlarms> oldList = selectTwinCalcAlarmsList(calcSearch);
+            oldList.forEach(old -> {
+                TwinRecordAlarms alarms = new TwinRecordAlarms();
+                BeanUtils.copyProperties(old, alarms);
+                alarms.setRemark(oldStr);
+                list.add(alarms);
+            });
+            //再处理本次数据,2次结合
+            TwinRecordAlarms recordSearch = new TwinRecordAlarms();
+            recordSearch.setDeviceId(device.getDeviceId());
+            recordSearch.setDataDate(date);
+            recordSearch.setHour(startTime.getHour());
+            List<TwinRecordAlarms> newList = alarmsService.selectTwinRecordAlarmsList(recordSearch);
+            list.addAll(newList);
+
+            Map<Integer, List<TwinRecordAlarms>> groupList = list.stream().collect(Collectors.groupingBy(TwinRecordAlarms::getAlarmType));
+            List<TwinRecordAlarms> recordList = new ArrayList<>();
+            for (Map.Entry<Integer, List<TwinRecordAlarms>> entry : groupList.entrySet()) {
+                List<TwinRecordAlarms> temp = entry.getValue();
+                if (temp.size() == 1) {
+                    //只有一条记录,则直接记录下来
+                    recordList.add(temp.get(0));
+                }
+                TwinRecordAlarms lastAlarms = null;
+                for (int i = 0; i < temp.size(); i++) {
+                    TwinRecordAlarms currAlarms = temp.get(i);
+                    if (lastAlarms == null) {
+                        lastAlarms = currAlarms;
+                    } else {
+                        //1.第一轮,下一条开始时间-上一条结束时间小于 seconds 则两条记录合并
+                        if (currAlarms.getStartTime().getTime() - lastAlarms.getEndTime().getTime() < legalTime) {
+                            lastAlarms.setEndTime(currAlarms.getEndTime());
+                            lastAlarms.setCalcStatus(currAlarms.getCalcStatus());
+                        } else {
+                            //2.判断持续时间,如果大于seconds则记录
+                            if (lastAlarms.getEndTime().getTime() - lastAlarms.getStartTime().getTime() > legalTime) {
+                                recordList.add(lastAlarms);
+                            }
+                            lastAlarms = currAlarms;
+                        }
+                        if (i + 1 == temp.size()) {
+                            //补一次最后一条记录,如果最后一条记录是统计未完成的,或者持续时间大于seconds的,则补录
+                            if ("1".equals(lastAlarms.getCalcStatus()) || lastAlarms.getEndTime().getTime() - lastAlarms.getStartTime().getTime() > legalTime) {
+                                recordList.add(lastAlarms);
+                            }
+                        }
+                    }
+                }
+            }
+
+            recordList.forEach(stop -> {
+                TwinCalcAlarms v = new TwinCalcAlarms();
+                BeanUtils.copyProperties(stop, v);
+                if (oldStr.equals(stop.getRemark())) {
+                    updateTwinCalcAlarms(v);
+                } else {
+                    v.setId(null);
+                    insertTwinCalcAlarms(v);
+                }
+            });
+        });
+    }
 }

+ 119 - 26
ruoyi-admin/src/main/java/com/ruoyi/biz/service/impl/TwinCalcStopServiceImpl.java

@@ -1,94 +1,187 @@
 package com.ruoyi.biz.service.impl;
 
-import java.util.List;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import com.ruoyi.biz.mapper.TwinCalcStopMapper;
 import com.ruoyi.biz.domain.TwinCalcStop;
+import com.ruoyi.biz.domain.TwinDevice;
+import com.ruoyi.biz.domain.TwinRecordStop;
+import com.ruoyi.biz.mapper.TwinCalcStopMapper;
 import com.ruoyi.biz.service.ITwinCalcStopService;
+import com.ruoyi.biz.service.ITwinRecordStopService;
 import com.ruoyi.common.core.text.Convert;
+import com.ruoyi.common.utils.bean.BeanUtils;
+import com.ruoyi.system.service.ISysConfigService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * 停机数据统计Service业务层处理
- * 
+ *
  * @author ruoyi
  * @date 2024-06-28
  */
 @Service
-public class TwinCalcStopServiceImpl implements ITwinCalcStopService 
-{
-    @Autowired
+public class TwinCalcStopServiceImpl implements ITwinCalcStopService {
+    @Resource
     private TwinCalcStopMapper twinCalcStopMapper;
 
+    @Resource
+    private ISysConfigService configService;
+
+    @Resource
+    private ITwinRecordStopService stopService;
+
     /**
      * 查询停机数据统计
-     * 
+     *
      * @param id 停机数据统计主键
      * @return 停机数据统计
      */
     @Override
-    public TwinCalcStop selectTwinCalcStopById(Long id)
-    {
+    public TwinCalcStop selectTwinCalcStopById(Long id) {
         return twinCalcStopMapper.selectTwinCalcStopById(id);
     }
 
     /**
      * 查询停机数据统计列表
-     * 
+     *
      * @param twinCalcStop 停机数据统计
      * @return 停机数据统计
      */
     @Override
-    public List<TwinCalcStop> selectTwinCalcStopList(TwinCalcStop twinCalcStop)
-    {
+    public List<TwinCalcStop> selectTwinCalcStopList(TwinCalcStop twinCalcStop) {
         return twinCalcStopMapper.selectTwinCalcStopList(twinCalcStop);
     }
 
     /**
      * 新增停机数据统计
-     * 
+     *
      * @param twinCalcStop 停机数据统计
      * @return 结果
      */
     @Override
-    public int insertTwinCalcStop(TwinCalcStop twinCalcStop)
-    {
+    public int insertTwinCalcStop(TwinCalcStop twinCalcStop) {
         return twinCalcStopMapper.insertTwinCalcStop(twinCalcStop);
     }
 
     /**
      * 修改停机数据统计
-     * 
+     *
      * @param twinCalcStop 停机数据统计
      * @return 结果
      */
     @Override
-    public int updateTwinCalcStop(TwinCalcStop twinCalcStop)
-    {
+    public int updateTwinCalcStop(TwinCalcStop twinCalcStop) {
         return twinCalcStopMapper.updateTwinCalcStop(twinCalcStop);
     }
 
     /**
      * 批量删除停机数据统计
-     * 
+     *
      * @param ids 需要删除的停机数据统计主键
      * @return 结果
      */
     @Override
-    public int deleteTwinCalcStopByIds(String ids)
-    {
+    public int deleteTwinCalcStopByIds(String ids) {
         return twinCalcStopMapper.deleteTwinCalcStopByIds(Convert.toStrArray(ids));
     }
 
     /**
      * 删除停机数据统计信息
-     * 
+     *
      * @param id 停机数据统计主键
      * @return 结果
      */
     @Override
-    public int deleteTwinCalcStopById(Long id)
-    {
+    public int deleteTwinCalcStopById(Long id) {
         return twinCalcStopMapper.deleteTwinCalcStopById(id);
     }
+
+    /**
+     * 停机数据治理,从停机记录表到停机统计表中
+     *
+     * @param startTime  开始时间
+     * @param deviceList 设备列表
+     */
+    @Override
+    public void process(LocalDateTime startTime, List<TwinDevice> deviceList) {
+        String config = configService.selectConfigByKey("data.legal.time");
+        int legalTime = Integer.parseInt(config) * 1000;
+
+        Date date = Date.from(startTime.toLocalDate().atStartOfDay(ZoneOffset.of("+8")).toInstant());
+        String oldStr = "old";
+        deviceList.forEach(device -> {
+            //先处理上次未统计完整的数据
+            TwinCalcStop calcSearch = new TwinCalcStop();
+            calcSearch.setDeviceId(device.getDeviceId());
+            calcSearch.setCalcStatus("1");
+            List<TwinRecordStop> list = new ArrayList<>();
+            List<TwinCalcStop> oldList = selectTwinCalcStopList(calcSearch);
+            oldList.forEach(old -> {
+                TwinRecordStop stop = new TwinRecordStop();
+                BeanUtils.copyProperties(old, stop);
+                stop.setRemark(oldStr);
+                list.add(stop);
+            });
+            //再处理本次数据,2次结合
+            TwinRecordStop recordSearch = new TwinRecordStop();
+            recordSearch.setDeviceId(device.getDeviceId());
+            recordSearch.setDataDate(date);
+            recordSearch.setHour(startTime.getHour());
+            List<TwinRecordStop> newList = stopService.selectTwinRecordStopList(recordSearch);
+            list.addAll(newList);
+
+            Map<Integer, List<TwinRecordStop>> groupList = list.stream().collect(Collectors.groupingBy(TwinRecordStop::getStopType));
+            List<TwinRecordStop> recordList = new ArrayList<>();
+            for (Map.Entry<Integer, List<TwinRecordStop>> entry : groupList.entrySet()) {
+                List<TwinRecordStop> temp = entry.getValue();
+                if (temp.size() == 1) {
+                    //只有一条记录,则直接记录下来
+                    recordList.add(temp.get(0));
+                }
+                TwinRecordStop lastStop = null;
+                for (int i = 0; i < temp.size(); i++) {
+                    TwinRecordStop currStop = temp.get(i);
+                    if (lastStop == null) {
+                        lastStop = currStop;
+                    } else {
+                        //1.第一轮,下一条开始时间-上一条结束时间小于 seconds 则两条记录合并
+                        if (currStop.getStartTime().getTime() - lastStop.getEndTime().getTime() < legalTime) {
+                            lastStop.setEndTime(currStop.getEndTime());
+                            lastStop.setCalcStatus(currStop.getCalcStatus());
+                        } else {
+                            //2.判断持续时间,如果大于seconds则记录
+                            if (lastStop.getEndTime().getTime() - lastStop.getStartTime().getTime() > legalTime) {
+                                recordList.add(lastStop);
+                            }
+                            lastStop = currStop;
+                        }
+                        if (i + 1 == temp.size()) {
+                            //补一次最后一条记录,如果最后一条记录是统计未完成的,或者持续时间大于seconds的,则补录
+                            if ("1".equals(lastStop.getCalcStatus()) || lastStop.getEndTime().getTime() - lastStop.getStartTime().getTime() > legalTime) {
+                                recordList.add(lastStop);
+                            }
+                        }
+                    }
+                }
+            }
+
+            recordList.forEach(stop -> {
+                TwinCalcStop v = new TwinCalcStop();
+                BeanUtils.copyProperties(stop, v);
+                if (oldStr.equals(stop.getRemark())) {
+                    updateTwinCalcStop(v);
+                } else {
+                    v.setId(null);
+                    insertTwinCalcStop(v);
+                }
+            });
+        });
+    }
 }

+ 51 - 35
ruoyi-admin/src/main/resources/mapper/biz/TwinCalcAlarmsMapper.xml

@@ -1,50 +1,61 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <!DOCTYPE mapper
-PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.ruoyi.biz.mapper.TwinCalcAlarmsMapper">
-    
+
     <resultMap type="TwinCalcAlarms" id="TwinCalcAlarmsResult">
-        <result property="id"    column="ID"    />
-        <result property="deviceId"    column="DEVICE_ID"    />
-        <result property="dataDate"    column="DATA_DATE"    />
-        <result property="hour"    column="HOUR"    />
-        <result property="startTime"    column="START_TIME"    />
-        <result property="endTime"    column="END_TIME"    />
-        <result property="alarmType"    column="ALARM_TYPE"    />
-        <result property="createdBy"    column="CREATED_BY"    />
-        <result property="createdTime"    column="CREATED_TIME"    />
-        <result property="updatedBy"    column="UPDATED_BY"    />
-        <result property="updatedTime"    column="UPDATED_TIME"    />
-        <result property="remark"    column="REMARK"    />
+        <result property="id" column="ID"/>
+        <result property="deviceId" column="DEVICE_ID"/>
+        <result property="dataDate" column="DATA_DATE"/>
+        <result property="hour" column="HOUR"/>
+        <result property="startTime" column="START_TIME"/>
+        <result property="endTime" column="END_TIME"/>
+        <result property="alarmType" column="ALARM_TYPE"/>
+        <result property="calcStatus" column="CALC_STATUS"/>
+        <result property="createdBy" column="CREATED_BY"/>
+        <result property="createdTime" column="CREATED_TIME"/>
+        <result property="updatedBy" column="UPDATED_BY"/>
+        <result property="updatedTime" column="UPDATED_TIME"/>
+        <result property="remark" column="REMARK"/>
     </resultMap>
 
     <sql id="selectTwinCalcAlarmsVo">
-        select ID, DEVICE_ID, DATA_DATE, HOUR, START_TIME, END_TIME, ALARM_TYPE, CREATED_BY, CREATED_TIME, UPDATED_BY, UPDATED_TIME, REMARK from twin_calc_alarms
+        select ID,
+               DEVICE_ID,
+               DATA_DATE, HOUR, START_TIME, END_TIME, ALARM_TYPE, CALC_STATUS, CREATED_BY, CREATED_TIME, UPDATED_BY, UPDATED_TIME, REMARK
+        from twin_calc_alarms
     </sql>
 
     <select id="selectTwinCalcAlarmsList" parameterType="TwinCalcAlarms" resultMap="TwinCalcAlarmsResult">
         <include refid="selectTwinCalcAlarmsVo"/>
-        <where>  
-            <if test="deviceId != null "> and DEVICE_ID = #{deviceId}</if>
-            <if test="params.beginDataDate != null and params.beginDataDate != '' and params.endDataDate != null and params.endDataDate != ''"> and DATA_DATE between #{params.beginDataDate} and #{params.endDataDate}</if>
-            <if test="hour != null  and hour != ''"> and HOUR = #{hour}</if>
-            <if test="params.beginStartTime != null and params.beginStartTime != '' and params.endStartTime != null and params.endStartTime != ''"> and START_TIME between #{params.beginStartTime} and #{params.endStartTime}</if>
-            <if test="params.beginEndTime != null and params.beginEndTime != '' and params.endEndTime != null and params.endEndTime != ''"> and END_TIME between #{params.beginEndTime} and #{params.endEndTime}</if>
-            <if test="alarmType != null "> and ALARM_TYPE = #{alarmType}</if>
-            <if test="createdBy != null  and createdBy != ''"> and CREATED_BY = #{createdBy}</if>
-            <if test="createdTime != null "> and CREATED_TIME = #{createdTime}</if>
-            <if test="updatedBy != null  and updatedBy != ''"> and UPDATED_BY = #{updatedBy}</if>
-            <if test="updatedTime != null "> and UPDATED_TIME = #{updatedTime}</if>
-            <if test="remark != null  and remark != ''"> and REMARK = #{remark}</if>
+        <where>
+            <if test="deviceId != null ">and DEVICE_ID = #{deviceId}</if>
+            <if test="params.beginDataDate != null and params.beginDataDate != '' and params.endDataDate != null and params.endDataDate != ''">
+                and DATA_DATE between #{params.beginDataDate} and #{params.endDataDate}
+            </if>
+            <if test="hour != null  and hour != ''">and HOUR = #{hour}</if>
+            <if test="params.beginStartTime != null and params.beginStartTime != '' and params.endStartTime != null and params.endStartTime != ''">
+                and START_TIME between #{params.beginStartTime} and #{params.endStartTime}
+            </if>
+            <if test="params.beginEndTime != null and params.beginEndTime != '' and params.endEndTime != null and params.endEndTime != ''">
+                and END_TIME between #{params.beginEndTime} and #{params.endEndTime}
+            </if>
+            <if test="alarmType != null ">and ALARM_TYPE = #{alarmType}</if>
+            <if test="calcStatus != null ">and CALC_STATUS = #{calcStatus}</if>
+            <if test="createdBy != null  and createdBy != ''">and CREATED_BY = #{createdBy}</if>
+            <if test="createdTime != null ">and CREATED_TIME = #{createdTime}</if>
+            <if test="updatedBy != null  and updatedBy != ''">and UPDATED_BY = #{updatedBy}</if>
+            <if test="updatedTime != null ">and UPDATED_TIME = #{updatedTime}</if>
+            <if test="remark != null  and remark != ''">and REMARK = #{remark}</if>
         </where>
     </select>
-    
+
     <select id="selectTwinCalcAlarmsById" parameterType="Long" resultMap="TwinCalcAlarmsResult">
         <include refid="selectTwinCalcAlarmsVo"/>
         where ID = #{id}
     </select>
-        
+
     <insert id="insertTwinCalcAlarms" parameterType="TwinCalcAlarms" useGeneratedKeys="true" keyProperty="id">
         insert into twin_calc_alarms
         <trim prefix="(" suffix=")" suffixOverrides=",">
@@ -54,12 +65,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="startTime != null">START_TIME,</if>
             <if test="endTime != null">END_TIME,</if>
             <if test="alarmType != null">ALARM_TYPE,</if>
+            <if test="calcStatus != null ">CALC_STATUS,</if>
             <if test="createdBy != null">CREATED_BY,</if>
             <if test="createdTime != null">CREATED_TIME,</if>
             <if test="updatedBy != null">UPDATED_BY,</if>
             <if test="updatedTime != null">UPDATED_TIME,</if>
             <if test="remark != null">REMARK,</if>
-         </trim>
+        </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="deviceId != null">#{deviceId},</if>
             <if test="dataDate != null">#{dataDate},</if>
@@ -67,12 +79,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="startTime != null">#{startTime},</if>
             <if test="endTime != null">#{endTime},</if>
             <if test="alarmType != null">#{alarmType},</if>
+            <if test="calcStatus != null ">#{calcStatus},</if>
             <if test="createdBy != null">#{createdBy},</if>
             <if test="createdTime != null">#{createdTime},</if>
             <if test="updatedBy != null">#{updatedBy},</if>
             <if test="updatedTime != null">#{updatedTime},</if>
             <if test="remark != null">#{remark},</if>
-         </trim>
+        </trim>
     </insert>
 
     <update id="updateTwinCalcAlarms" parameterType="TwinCalcAlarms">
@@ -84,6 +97,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="startTime != null">START_TIME = #{startTime},</if>
             <if test="endTime != null">END_TIME = #{endTime},</if>
             <if test="alarmType != null">ALARM_TYPE = #{alarmType},</if>
+            <if test="calcStatus != null ">CALC_STATUS = #{calcStatus},</if>
             <if test="createdBy != null">CREATED_BY = #{createdBy},</if>
             <if test="createdTime != null">CREATED_TIME = #{createdTime},</if>
             <if test="updatedBy != null">UPDATED_BY = #{updatedBy},</if>
@@ -94,14 +108,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </update>
 
     <delete id="deleteTwinCalcAlarmsById" parameterType="Long">
-        delete from twin_calc_alarms where ID = #{id}
+        delete
+        from twin_calc_alarms
+        where ID = #{id}
     </delete>
 
     <delete id="deleteTwinCalcAlarmsByIds" parameterType="String">
-        delete from twin_calc_alarms where ID in 
+        delete from twin_calc_alarms where ID in
         <foreach item="id" collection="array" open="(" separator="," close=")">
             #{id}
         </foreach>
     </delete>
 
-</mapper>
+</mapper>

+ 46 - 29
ruoyi-admin/src/main/resources/mapper/biz/TwinCalcStopMapper.xml

@@ -1,43 +1,55 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <!DOCTYPE mapper
-PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.ruoyi.biz.mapper.TwinCalcStopMapper">
 
     <resultMap type="TwinCalcStop" id="TwinCalcStopResult">
-        <result property="id"    column="ID"    />
-        <result property="deviceId"    column="DEVICE_ID"    />
-        <result property="dataDate"    column="DATA_DATE"    />
-        <result property="hour"    column="HOUR"    />
-        <result property="startTime"    column="START_TIME"    />
-        <result property="endTime"    column="END_TIME"    />
-        <result property="stopType"    column="STOP_TYPE"    />
-        <result property="createdBy"    column="CREATED_BY"    />
-        <result property="createdTime"    column="CREATED_TIME"    />
-        <result property="updatedBy"    column="UPDATED_BY"    />
-        <result property="updatedTime"    column="UPDATED_TIME"    />
-        <result property="remark"    column="REMARK"    />
+        <result property="id" column="ID"/>
+        <result property="deviceId" column="DEVICE_ID"/>
+        <result property="dataDate" column="DATA_DATE"/>
+        <result property="hour" column="HOUR"/>
+        <result property="startTime" column="START_TIME"/>
+        <result property="endTime" column="END_TIME"/>
+        <result property="stopType" column="STOP_TYPE"/>
+        <result property="calcStatus" column="CALC_STATUS"/>
+        <result property="createdBy" column="CREATED_BY"/>
+        <result property="createdTime" column="CREATED_TIME"/>
+        <result property="updatedBy" column="UPDATED_BY"/>
+        <result property="updatedTime" column="UPDATED_TIME"/>
+        <result property="remark" column="REMARK"/>
     </resultMap>
 
     <sql id="selectTwinCalcStopVo">
-        select ID, DEVICE_ID, DATA_DATE, HOUR, START_TIME, END_TIME, STOP_TYPE, CREATED_BY, CREATED_TIME, UPDATED_BY, UPDATED_TIME, REMARK from twin_calc_stop
+        select ID,
+               DEVICE_ID,
+               DATA_DATE, HOUR, START_TIME, END_TIME, STOP_TYPE, CALC_STATUS, CREATED_BY, CREATED_TIME, UPDATED_BY, UPDATED_TIME, REMARK
+        from twin_calc_stop
     </sql>
 
     <select id="selectTwinCalcStopList" parameterType="TwinCalcStop" resultMap="TwinCalcStopResult">
         <include refid="selectTwinCalcStopVo"/>
         <where>
-            <if test="deviceId != null "> and DEVICE_ID = #{deviceId}</if>
-            <if test="params.beginDataDate != null and params.beginDataDate != '' and params.endDataDate != null and params.endDataDate != ''"> and DATA_DATE between #{params.beginDataDate} and #{params.endDataDate}</if>
-            <if test="hour != null"> and HOUR = #{hour}</if>
-            <if test="params.beginStartTime != null and params.beginStartTime != '' and params.endStartTime != null and params.endStartTime != ''"> and START_TIME between #{params.beginStartTime} and #{params.endStartTime}</if>
-            <if test="params.beginEndTime != null and params.beginEndTime != '' and params.endEndTime != null and params.endEndTime != ''"> and END_TIME between #{params.beginEndTime} and #{params.endEndTime}</if>
-            <if test="stopType != null "> and STOP_TYPE = #{stopType}</if>
-            <if test="createdBy != null  and createdBy != ''"> and CREATED_BY = #{createdBy}</if>
-            <if test="createdTime != null "> and CREATED_TIME = #{createdTime}</if>
-            <if test="updatedBy != null  and updatedBy != ''"> and UPDATED_BY = #{updatedBy}</if>
-            <if test="updatedTime != null "> and UPDATED_TIME = #{updatedTime}</if>
-            <if test="remark != null  and remark != ''"> and REMARK = #{remark}</if>
+            <if test="deviceId != null ">and DEVICE_ID = #{deviceId}</if>
+            <if test="params.beginDataDate != null and params.beginDataDate != '' and params.endDataDate != null and params.endDataDate != ''">
+                and DATA_DATE between #{params.beginDataDate} and #{params.endDataDate}
+            </if>
+            <if test="hour != null">and HOUR = #{hour}</if>
+            <if test="params.beginStartTime != null and params.beginStartTime != '' and params.endStartTime != null and params.endStartTime != ''">
+                and START_TIME between #{params.beginStartTime} and #{params.endStartTime}
+            </if>
+            <if test="params.beginEndTime != null and params.beginEndTime != '' and params.endEndTime != null and params.endEndTime != ''">
+                and END_TIME between #{params.beginEndTime} and #{params.endEndTime}
+            </if>
+            <if test="stopType != null ">and STOP_TYPE = #{stopType}</if>
+            <if test="calcStatus != null ">and CALC_STATUS = #{calcStatus}</if>
+            <if test="createdBy != null  and createdBy != ''">and CREATED_BY = #{createdBy}</if>
+            <if test="createdTime != null ">and CREATED_TIME = #{createdTime}</if>
+            <if test="updatedBy != null  and updatedBy != ''">and UPDATED_BY = #{updatedBy}</if>
+            <if test="updatedTime != null ">and UPDATED_TIME = #{updatedTime}</if>
+            <if test="remark != null  and remark != ''">and REMARK = #{remark}</if>
         </where>
+        order by START_TIME
     </select>
 
     <select id="selectTwinCalcStopById" parameterType="Long" resultMap="TwinCalcStopResult">
@@ -54,12 +66,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="startTime != null">START_TIME,</if>
             <if test="endTime != null">END_TIME,</if>
             <if test="stopType != null">STOP_TYPE,</if>
+            <if test="calcStatus != null ">CALC_STATUS,</if>
             <if test="createdBy != null">CREATED_BY,</if>
             <if test="createdTime != null">CREATED_TIME,</if>
             <if test="updatedBy != null">UPDATED_BY,</if>
             <if test="updatedTime != null">UPDATED_TIME,</if>
             <if test="remark != null">REMARK,</if>
-         </trim>
+        </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="deviceId != null">#{deviceId},</if>
             <if test="dataDate != null">#{dataDate},</if>
@@ -67,12 +80,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="startTime != null">#{startTime},</if>
             <if test="endTime != null">#{endTime},</if>
             <if test="stopType != null">#{stopType},</if>
+            <if test="calcStatus != null ">#{calcStatus},</if>
             <if test="createdBy != null">#{createdBy},</if>
             <if test="createdTime != null">#{createdTime},</if>
             <if test="updatedBy != null">#{updatedBy},</if>
             <if test="updatedTime != null">#{updatedTime},</if>
             <if test="remark != null">#{remark},</if>
-         </trim>
+        </trim>
     </insert>
 
     <update id="updateTwinCalcStop" parameterType="TwinCalcStop">
@@ -84,6 +98,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="startTime != null">START_TIME = #{startTime},</if>
             <if test="endTime != null">END_TIME = #{endTime},</if>
             <if test="stopType != null">STOP_TYPE = #{stopType},</if>
+            <if test="calcStatus != null ">CALC_STATUS = #{calcStatus},</if>
             <if test="createdBy != null">CREATED_BY = #{createdBy},</if>
             <if test="createdTime != null">CREATED_TIME = #{createdTime},</if>
             <if test="updatedBy != null">UPDATED_BY = #{updatedBy},</if>
@@ -94,7 +109,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </update>
 
     <delete id="deleteTwinCalcStopById" parameterType="Long">
-        delete from twin_calc_stop where ID = #{id}
+        delete
+        from twin_calc_stop
+        where ID = #{id}
     </delete>
 
     <delete id="deleteTwinCalcStopByIds" parameterType="String">

+ 51 - 35
ruoyi-admin/src/main/resources/mapper/biz/TwinRecordAlarmsMapper.xml

@@ -1,50 +1,61 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <!DOCTYPE mapper
-PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.ruoyi.biz.mapper.TwinRecordAlarmsMapper">
-    
+
     <resultMap type="TwinRecordAlarms" id="TwinRecordAlarmsResult">
-        <result property="id"    column="ID"    />
-        <result property="deviceId"    column="DEVICE_ID"    />
-        <result property="dataDate"    column="DATA_DATE"    />
-        <result property="hour"    column="HOUR"    />
-        <result property="startTime"    column="START_TIME"    />
-        <result property="endTime"    column="END_TIME"    />
-        <result property="alarmType"    column="ALARM_TYPE"    />
-        <result property="createdBy"    column="CREATED_BY"    />
-        <result property="createdTime"    column="CREATED_TIME"    />
-        <result property="updatedBy"    column="UPDATED_BY"    />
-        <result property="updatedTime"    column="UPDATED_TIME"    />
-        <result property="remark"    column="REMARK"    />
+        <result property="id" column="ID"/>
+        <result property="deviceId" column="DEVICE_ID"/>
+        <result property="dataDate" column="DATA_DATE"/>
+        <result property="hour" column="HOUR"/>
+        <result property="startTime" column="START_TIME"/>
+        <result property="endTime" column="END_TIME"/>
+        <result property="alarmType" column="ALARM_TYPE"/>
+        <result property="calcStatus" column="CALC_STATUS"/>
+        <result property="createdBy" column="CREATED_BY"/>
+        <result property="createdTime" column="CREATED_TIME"/>
+        <result property="updatedBy" column="UPDATED_BY"/>
+        <result property="updatedTime" column="UPDATED_TIME"/>
+        <result property="remark" column="REMARK"/>
     </resultMap>
 
     <sql id="selectTwinRecordAlarmsVo">
-        select ID, DEVICE_ID, DATA_DATE, HOUR, START_TIME, END_TIME, ALARM_TYPE, CREATED_BY, CREATED_TIME, UPDATED_BY, UPDATED_TIME, REMARK from twin_record_alarms
+        select ID,
+               DEVICE_ID,
+               DATA_DATE, HOUR, START_TIME, END_TIME, ALARM_TYPE, CALC_STATUS, CREATED_BY, CREATED_TIME, UPDATED_BY, UPDATED_TIME, REMARK
+        from twin_record_alarms
     </sql>
 
     <select id="selectTwinRecordAlarmsList" parameterType="TwinRecordAlarms" resultMap="TwinRecordAlarmsResult">
         <include refid="selectTwinRecordAlarmsVo"/>
-        <where>  
-            <if test="deviceId != null "> and DEVICE_ID = #{deviceId}</if>
-            <if test="params.beginDataDate != null and params.beginDataDate != '' and params.endDataDate != null and params.endDataDate != ''"> and DATA_DATE between #{params.beginDataDate} and #{params.endDataDate}</if>
-            <if test="hour != null  and hour != ''"> and HOUR = #{hour}</if>
-            <if test="params.beginStartTime != null and params.beginStartTime != '' and params.endStartTime != null and params.endStartTime != ''"> and START_TIME between #{params.beginStartTime} and #{params.endStartTime}</if>
-            <if test="params.beginEndTime != null and params.beginEndTime != '' and params.endEndTime != null and params.endEndTime != ''"> and END_TIME between #{params.beginEndTime} and #{params.endEndTime}</if>
-            <if test="alarmType != null "> and ALARM_TYPE = #{alarmType}</if>
-            <if test="createdBy != null  and createdBy != ''"> and CREATED_BY = #{createdBy}</if>
-            <if test="createdTime != null "> and CREATED_TIME = #{createdTime}</if>
-            <if test="updatedBy != null  and updatedBy != ''"> and UPDATED_BY = #{updatedBy}</if>
-            <if test="updatedTime != null "> and UPDATED_TIME = #{updatedTime}</if>
-            <if test="remark != null  and remark != ''"> and REMARK = #{remark}</if>
+        <where>
+            <if test="deviceId != null ">and DEVICE_ID = #{deviceId}</if>
+            <if test="params.beginDataDate != null and params.beginDataDate != '' and params.endDataDate != null and params.endDataDate != ''">
+                and DATA_DATE between #{params.beginDataDate} and #{params.endDataDate}
+            </if>
+            <if test="hour != null  and hour != ''">and HOUR = #{hour}</if>
+            <if test="params.beginStartTime != null and params.beginStartTime != '' and params.endStartTime != null and params.endStartTime != ''">
+                and START_TIME between #{params.beginStartTime} and #{params.endStartTime}
+            </if>
+            <if test="params.beginEndTime != null and params.beginEndTime != '' and params.endEndTime != null and params.endEndTime != ''">
+                and END_TIME between #{params.beginEndTime} and #{params.endEndTime}
+            </if>
+            <if test="alarmType != null ">and ALARM_TYPE = #{alarmType}</if>
+            <if test="calcStatus != null ">and CALC_STATUS = #{calcStatus}</if>
+            <if test="createdBy != null  and createdBy != ''">and CREATED_BY = #{createdBy}</if>
+            <if test="createdTime != null ">and CREATED_TIME = #{createdTime}</if>
+            <if test="updatedBy != null  and updatedBy != ''">and UPDATED_BY = #{updatedBy}</if>
+            <if test="updatedTime != null ">and UPDATED_TIME = #{updatedTime}</if>
+            <if test="remark != null  and remark != ''">and REMARK = #{remark}</if>
         </where>
     </select>
-    
+
     <select id="selectTwinRecordAlarmsById" parameterType="Long" resultMap="TwinRecordAlarmsResult">
         <include refid="selectTwinRecordAlarmsVo"/>
         where ID = #{id}
     </select>
-        
+
     <insert id="insertTwinRecordAlarms" parameterType="TwinRecordAlarms" useGeneratedKeys="true" keyProperty="id">
         insert into twin_record_alarms
         <trim prefix="(" suffix=")" suffixOverrides=",">
@@ -54,12 +65,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="startTime != null">START_TIME,</if>
             <if test="endTime != null">END_TIME,</if>
             <if test="alarmType != null">ALARM_TYPE,</if>
+            <if test="calcStatus != null ">CALC_STATUS,</if>
             <if test="createdBy != null">CREATED_BY,</if>
             <if test="createdTime != null">CREATED_TIME,</if>
             <if test="updatedBy != null">UPDATED_BY,</if>
             <if test="updatedTime != null">UPDATED_TIME,</if>
             <if test="remark != null">REMARK,</if>
-         </trim>
+        </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="deviceId != null">#{deviceId},</if>
             <if test="dataDate != null">#{dataDate},</if>
@@ -67,12 +79,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="startTime != null">#{startTime},</if>
             <if test="endTime != null">#{endTime},</if>
             <if test="alarmType != null">#{alarmType},</if>
+            <if test="calcStatus != null ">#{calcStatus},</if>
             <if test="createdBy != null">#{createdBy},</if>
             <if test="createdTime != null">#{createdTime},</if>
             <if test="updatedBy != null">#{updatedBy},</if>
             <if test="updatedTime != null">#{updatedTime},</if>
             <if test="remark != null">#{remark},</if>
-         </trim>
+        </trim>
     </insert>
 
     <update id="updateTwinRecordAlarms" parameterType="TwinRecordAlarms">
@@ -84,6 +97,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="startTime != null">START_TIME = #{startTime},</if>
             <if test="endTime != null">END_TIME = #{endTime},</if>
             <if test="alarmType != null">ALARM_TYPE = #{alarmType},</if>
+            <if test="calcStatus != null ">CALC_STATUS = #{calcStatus},</if>
             <if test="createdBy != null">CREATED_BY = #{createdBy},</if>
             <if test="createdTime != null">CREATED_TIME = #{createdTime},</if>
             <if test="updatedBy != null">UPDATED_BY = #{updatedBy},</if>
@@ -94,14 +108,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </update>
 
     <delete id="deleteTwinRecordAlarmsById" parameterType="Long">
-        delete from twin_record_alarms where ID = #{id}
+        delete
+        from twin_record_alarms
+        where ID = #{id}
     </delete>
 
     <delete id="deleteTwinRecordAlarmsByIds" parameterType="String">
-        delete from twin_record_alarms where ID in 
+        delete from twin_record_alarms where ID in
         <foreach item="id" collection="array" open="(" separator="," close=")">
             #{id}
         </foreach>
     </delete>
 
-</mapper>
+</mapper>

+ 46 - 31
ruoyi-admin/src/main/resources/mapper/biz/TwinRecordStopMapper.xml

@@ -1,44 +1,54 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <!DOCTYPE mapper
-PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.ruoyi.biz.mapper.TwinRecordStopMapper">
 
     <resultMap type="TwinRecordStop" id="TwinRecordStopResult">
-        <result property="id"    column="ID"    />
-        <result property="deviceId"    column="DEVICE_ID"    />
-        <result property="dataDate"    column="DATA_DATE"    />
-        <result property="hour"    column="HOUR"    />
-        <result property="startTime"    column="START_TIME"    />
-        <result property="endTime"    column="END_TIME"    />
-        <result property="stopType"    column="STOP_TYPE"    />
-        <result property="calcStatus"    column="CALC_STATUS"    />
-        <result property="createdBy"    column="CREATED_BY"    />
-        <result property="createdTime"    column="CREATED_TIME"    />
-        <result property="updatedBy"    column="UPDATED_BY"    />
-        <result property="updatedTime"    column="UPDATED_TIME"    />
-        <result property="remark"    column="REMARK"    />
+        <result property="id" column="ID"/>
+        <result property="deviceId" column="DEVICE_ID"/>
+        <result property="dataDate" column="DATA_DATE"/>
+        <result property="hour" column="HOUR"/>
+        <result property="startTime" column="START_TIME"/>
+        <result property="endTime" column="END_TIME"/>
+        <result property="stopType" column="STOP_TYPE"/>
+        <result property="calcStatus" column="CALC_STATUS"/>
+        <result property="createdBy" column="CREATED_BY"/>
+        <result property="createdTime" column="CREATED_TIME"/>
+        <result property="updatedBy" column="UPDATED_BY"/>
+        <result property="updatedTime" column="UPDATED_TIME"/>
+        <result property="remark" column="REMARK"/>
     </resultMap>
 
     <sql id="selectTwinRecordStopVo">
-        select ID, DEVICE_ID, DATA_DATE, HOUR, START_TIME, END_TIME, STOP_TYPE, CREATED_BY, CREATED_TIME, UPDATED_BY, UPDATED_TIME, REMARK from twin_record_stop
+        select ID,
+               DEVICE_ID,
+               DATA_DATE, HOUR, START_TIME, END_TIME, STOP_TYPE, CALC_STATUS, CREATED_BY, CREATED_TIME, UPDATED_BY, UPDATED_TIME, REMARK
+        from twin_record_stop
     </sql>
 
     <select id="selectTwinRecordStopList" parameterType="TwinRecordStop" resultMap="TwinRecordStopResult">
         <include refid="selectTwinRecordStopVo"/>
         <where>
-            <if test="deviceId != null "> and DEVICE_ID = #{deviceId}</if>
-            <if test="params.beginDataDate != null and params.beginDataDate != '' and params.endDataDate != null and params.endDataDate != ''"> and DATA_DATE between #{params.beginDataDate} and #{params.endDataDate}</if>
-            <if test="hour != null  and hour != ''"> and HOUR = #{hour}</if>
-            <if test="params.beginStartTime != null and params.beginStartTime != '' and params.endStartTime != null and params.endStartTime != ''"> and START_TIME between #{params.beginStartTime} and #{params.endStartTime}</if>
-            <if test="params.beginEndTime != null and params.beginEndTime != '' and params.endEndTime != null and params.endEndTime != ''"> and END_TIME between #{params.beginEndTime} and #{params.endEndTime}</if>
-            <if test="stopType != null "> and STOP_TYPE = #{stopType}</if>
-            <if test="calcStatus != null "> and CALC_STATUS = #{calcStatus}</if>
-            <if test="createdBy != null  and createdBy != ''"> and CREATED_BY = #{createdBy}</if>
-            <if test="createdTime != null "> and CREATED_TIME = #{createdTime}</if>
-            <if test="updatedBy != null  and updatedBy != ''"> and UPDATED_BY = #{updatedBy}</if>
-            <if test="updatedTime != null "> and UPDATED_TIME = #{updatedTime}</if>
-            <if test="remark != null  and remark != ''"> and REMARK = #{remark}</if>
+            <if test="deviceId != null ">and DEVICE_ID = #{deviceId}</if>
+            <if test="dataDate != null ">and DATA_DATE = #{dataDate}</if>
+            <if test="params.beginDataDate != null and params.beginDataDate != '' and params.endDataDate != null and params.endDataDate != ''">
+                and DATA_DATE between #{params.beginDataDate} and #{params.endDataDate}
+            </if>
+            <if test="hour != null  and hour != ''">and HOUR = #{hour}</if>
+            <if test="params.beginStartTime != null and params.beginStartTime != '' and params.endStartTime != null and params.endStartTime != ''">
+                and START_TIME between #{params.beginStartTime} and #{params.endStartTime}
+            </if>
+            <if test="params.beginEndTime != null and params.beginEndTime != '' and params.endEndTime != null and params.endEndTime != ''">
+                and END_TIME between #{params.beginEndTime} and #{params.endEndTime}
+            </if>
+            <if test="stopType != null ">and STOP_TYPE = #{stopType}</if>
+            <if test="calcStatus != null ">and CALC_STATUS = #{calcStatus}</if>
+            <if test="createdBy != null  and createdBy != ''">and CREATED_BY = #{createdBy}</if>
+            <if test="createdTime != null ">and CREATED_TIME = #{createdTime}</if>
+            <if test="updatedBy != null  and updatedBy != ''">and UPDATED_BY = #{updatedBy}</if>
+            <if test="updatedTime != null ">and UPDATED_TIME = #{updatedTime}</if>
+            <if test="remark != null  and remark != ''">and REMARK = #{remark}</if>
         </where>
         order by START_TIME
     </select>
@@ -57,12 +67,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="startTime != null">START_TIME,</if>
             <if test="endTime != null">END_TIME,</if>
             <if test="stopType != null">STOP_TYPE,</if>
+            <if test="calcStatus != null ">CALC_STATUS</if>
             <if test="createdBy != null">CREATED_BY,</if>
             <if test="createdTime != null">CREATED_TIME,</if>
             <if test="updatedBy != null">UPDATED_BY,</if>
             <if test="updatedTime != null">UPDATED_TIME,</if>
             <if test="remark != null">REMARK,</if>
-         </trim>
+        </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="deviceId != null">#{deviceId},</if>
             <if test="dataDate != null">#{dataDate},</if>
@@ -70,12 +81,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="startTime != null">#{startTime},</if>
             <if test="endTime != null">#{endTime},</if>
             <if test="stopType != null">#{stopType},</if>
+            <if test="calcStatus != null ">#{calcStatus},</if>
             <if test="createdBy != null">#{createdBy},</if>
             <if test="createdTime != null">#{createdTime},</if>
             <if test="updatedBy != null">#{updatedBy},</if>
             <if test="updatedTime != null">#{updatedTime},</if>
             <if test="remark != null">#{remark},</if>
-         </trim>
+        </trim>
     </insert>
 
     <update id="updateTwinRecordStop" parameterType="TwinRecordStop">
@@ -87,6 +99,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="startTime != null">START_TIME = #{startTime},</if>
             <if test="endTime != null">END_TIME = #{endTime},</if>
             <if test="stopType != null">STOP_TYPE = #{stopType},</if>
+            <if test="calcStatus != null ">CALC_STATUS = #{calcStatus},</if>
             <if test="createdBy != null">CREATED_BY = #{createdBy},</if>
             <if test="createdTime != null">CREATED_TIME = #{createdTime},</if>
             <if test="updatedBy != null">UPDATED_BY = #{updatedBy},</if>
@@ -97,7 +110,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </update>
 
     <delete id="deleteTwinRecordStopById" parameterType="Long">
-        delete from twin_record_stop where ID = #{id}
+        delete
+        from twin_record_stop
+        where ID = #{id}
     </delete>
 
     <delete id="deleteTwinRecordStopByIds" parameterType="String">

+ 47 - 11
ruoyi-admin/src/test/java/com/jjt/DataGovernance.java

@@ -5,6 +5,7 @@ import com.ruoyi.biz.domain.TwinCalcStop;
 import com.ruoyi.biz.domain.TwinRecordStop;
 import com.ruoyi.biz.service.ITwinCalcStopService;
 import com.ruoyi.biz.service.ITwinRecordStopService;
+import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.common.utils.bean.BeanUtils;
 import org.junit.jupiter.api.Test;
 import org.springframework.boot.test.context.SpringBootTest;
@@ -36,27 +37,54 @@ public class DataGovernance {
 
     @Test
     void test() {
-        int seconds = 30 * 1000;
-        TwinRecordStop search = new TwinRecordStop();
-        search.setCalcStatus("0");
-//        search.setDeviceId(8l);
+        for (int i = 20; i <= 24; i++) {
+            TwinRecordStop search = new TwinRecordStop();
+            search.setDeviceId(104l);
+            search.setDataDate(DateUtils.parseDate("2024-06-26"));
+            search.setHour(i);
+            process(search);
+        }
 //        search.setStopType(3);
-        List<TwinRecordStop> list = stopService.selectTwinRecordStopList(search);
+
+    }
+
+    private void process(TwinRecordStop search) {
+        int seconds = 30 * 1000;
+        String oldStr = "old";
+        TwinCalcStop oldSearch = new TwinCalcStop();
+        BeanUtils.copyProperties(search, oldSearch);
+        oldSearch.setHour(null);
+        oldSearch.setCalcStatus("1");
+        List<TwinCalcStop> oldList = calcStopService.selectTwinCalcStopList(oldSearch);
+        List<TwinRecordStop> list = new ArrayList<>();
+        oldList.forEach(old -> {
+            TwinRecordStop stop = new TwinRecordStop();
+            BeanUtils.copyProperties(old, stop);
+            stop.setRemark(oldStr);
+            list.add(stop);
+        });
+        List<TwinRecordStop> newList = stopService.selectTwinRecordStopList(search);
+        list.addAll(newList);
         Map<Integer, List<TwinRecordStop>> groupList = list.stream().collect(Collectors.groupingBy(TwinRecordStop::getStopType));
         List<Object[]> ids = new ArrayList<>();
         List<TwinRecordStop> recordList = new ArrayList<>();
         for (Map.Entry<Integer, List<TwinRecordStop>> entry : groupList.entrySet()) {
             List<TwinRecordStop> temp = entry.getValue();
+            if (temp.size() == 1) {
+                //只有一条记录,则直接记录下来
+                recordList.add(temp.get(0));
+            }
             TwinRecordStop lastStop = null;
-            for (int i = 0; i < temp.size() - 1; i++) {
+            for (int i = 0; i < temp.size(); i++) {
                 TwinRecordStop currStop = temp.get(i);
                 if (lastStop == null) {
                     lastStop = currStop;
-                } else if (lastStop.getEndTime() != null) {
+                } else {
                     ids.add(new Object[]{currStop.getId()});
                     //1.第一轮,下一条开始时间-上一条结束时间小于 seconds 则两条记录合并
                     if (currStop.getStartTime().getTime() - lastStop.getEndTime().getTime() < seconds) {
                         lastStop.setEndTime(currStop.getEndTime());
+                        lastStop.setCalcStatus(currStop.getCalcStatus());
                     } else {
                         //2.判断持续时间,如果大于seconds则记录
                         if (lastStop.getEndTime().getTime() - lastStop.getStartTime().getTime() > seconds) {
@@ -64,6 +92,12 @@ public class DataGovernance {
                         }
                         lastStop = currStop;
                     }
+                    if (i + 1 == temp.size()) {
+                        //补一次最后一条记录,如果最后一条记录是统计未完成的,或者持续时间大于seconds的,则补录
+                        if ("1".equals(lastStop.getCalcStatus()) || lastStop.getEndTime().getTime() - lastStop.getStartTime().getTime() > seconds) {
+                            recordList.add(lastStop);
+                        }
+                    }
                 }
             }
         }
@@ -71,11 +105,13 @@ public class DataGovernance {
         recordList.forEach(stop -> {
             TwinCalcStop v = new TwinCalcStop();
             BeanUtils.copyProperties(stop, v);
-            v.setId(null);
-            calcStopService.insertTwinCalcStop(v);
+            if (oldStr.equals(stop.getRemark())) {
+                calcStopService.updateTwinCalcStop(v);
+            } else {
+                v.setId(null);
+                calcStopService.insertTwinCalcStop(v);
+            }
         });
-        String sql = "UPDATE TWIN_RECORD_STOP SET CALC_STATUS='1' WHERE ID=?";
-        jdbcTemplate.batchUpdate(sql, ids);
     }
 
 }

+ 3 - 3
ruoyi-admin/src/test/java/com/jjt/DataHour.java

@@ -31,13 +31,13 @@ public class DataHour {
     @Test
     public void test() {
         for (int i = 7; i < 24; i++) {
-            taskService.calc("2024-06-26", i);
+            taskService.calc("2024-07-01", i);
         }
         for (int i = 0; i < 24; i++) {
-            taskService.calc("2024-06-27", i);
+            taskService.calc("2024-07-02", i);
         }
         for (int i = 0; i < 7; i++) {
-            taskService.calc("2024-06-28", i);
+            taskService.calc("2024-07-03", i);
         }
     }