Prechádzať zdrojové kódy

染整线工艺参数功能基本完成

wukai 2 mesiacov pred
rodič
commit
a2ddef4e53

+ 70 - 0
jjt-admin/src/test/java/com/jjt/dye/DyeTest.java

@@ -0,0 +1,70 @@
+package com.jjt.dye;
+
+import com.jjt.JjtApplication;
+import com.jjt.dye.service.IDyeCalcHourService;
+import com.jjt.dye.service.IDyeHourLineService;
+import com.jjt.dyeing.service.IDyeingHourAvgService;
+import com.jjt.dyeing.service.IDyeingHourLineService;
+import com.jjt.utils.IotService;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import javax.annotation.Resource;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+
+/**
+ * EnergyTest$
+ *
+ * @author wukai
+ * @date 2025/10/19 03:38
+ */
+@SpringBootTest(classes = JjtApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+public class DyeTest {
+    @Resource
+    private IotService iotService;
+    @Resource
+    private IDyeCalcHourService calcHourService;
+    @Resource
+    private IDyeHourLineService hourLineService;
+    String st = "2025-11-01";
+    String ed = "2025-11-04";
+    LocalDate localDate = LocalDate.parse(st);
+    LocalDate endDate = LocalDate.parse(ed);
+    LocalDateTime start = LocalDateTime.of(localDate, LocalTime.MIN);
+
+    @Test
+    public void calc() {
+        iotService.setToken();
+//        calcHourService.calc(start.toLocalDate(), 18);
+        LocalDateTime end = LocalDateTime.of(endDate.plusDays(1), LocalTime.MIN).plusHours(23);
+        LocalDateTime curr = LocalDateTime.now();
+        if (end.isAfter(curr)) {
+            end = curr.minusHours(1);
+        }
+        do {
+            int i = start.getHour();
+            System.err.println(start.toLocalDate().toString() + "\t" + i);
+            calcHourService.calc(start.toLocalDate(), i);
+            start = start.plusHours(1);
+        } while (!start.isAfter(end));
+    }
+
+    @Test
+    public void line() {
+        iotService.setToken();
+//        calcHourService.calc(start.toLocalDate(), 18);
+        LocalDateTime end = LocalDateTime.of(endDate.plusDays(1), LocalTime.MIN).plusHours(23);
+        LocalDateTime curr = LocalDateTime.now();
+        if (end.isAfter(curr)) {
+            end = curr.minusHours(1);
+        }
+        do {
+            int i = start.getHour();
+            System.err.println(start.toLocalDate().toString() + "\t" + i);
+            hourLineService.calc(start.toLocalDate(), i);
+            start = start.plusHours(1);
+        } while (!start.isAfter(end));
+    }
+}

+ 113 - 0
jjt-biz/src/main/java/com/jjt/dye/controller/DyeHourLineController.java

@@ -0,0 +1,113 @@
+package com.jjt.dye.controller;
+
+import java.util.List;
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.jjt.common.annotation.Log;
+import com.jjt.common.core.controller.BaseController;
+import com.jjt.common.core.domain.AjaxResult;
+import com.jjt.common.enums.BusinessType;
+import com.jjt.dye.domain.DyeHourLine;
+import com.jjt.dye.service.IDyeHourLineService;
+import com.jjt.common.utils.poi.ExcelUtil;
+import com.jjt.common.core.page.TableDataInfo;
+
+/**
+ * 产线小时统计数据Controller
+ *
+ * @author wukai
+ * @date 2025-11-04
+ */
+@Api(tags="产线小时统计数据")
+@RestController
+@RequestMapping("/dye/line")
+public class DyeHourLineController extends BaseController{
+    @Resource
+    private IDyeHourLineService dyeHourLineService;
+
+    /**
+     * 查询产线小时统计数据列表
+     */
+    @ApiOperation("查询产线小时统计数据列表")
+    @PreAuthorize("@ss.hasPermi('dye:line:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(DyeHourLine dyeHourLine)
+    {
+        startPage();
+        List<DyeHourLine> list = dyeHourLineService.selectDyeHourLineList(dyeHourLine);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出产线小时统计数据列表
+     */
+    @ApiOperation("导出产线小时统计数据列表")
+    @PreAuthorize("@ss.hasPermi('dye:line:export')")
+    @Log(title = "产线小时统计数据", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, DyeHourLine dyeHourLine)
+    {
+        List<DyeHourLine> list = dyeHourLineService.selectDyeHourLineList(dyeHourLine);
+        ExcelUtil<DyeHourLine> util = new ExcelUtil<DyeHourLine>(DyeHourLine.class);
+        util.exportExcel(response, list, "产线小时统计数据数据");
+    }
+
+    /**
+     * 获取产线小时统计数据详细信息
+     */
+    @ApiOperation("获取产线小时统计数据详细信息")
+    @PreAuthorize("@ss.hasPermi('dye:line:query')")
+    @GetMapping(value = "/{hourLineId}")
+    public AjaxResult getInfo(@PathVariable("hourLineId") Long hourLineId)
+    {
+        return success(dyeHourLineService.selectDyeHourLineByHourLineId(hourLineId));
+    }
+
+    /**
+     * 新增产线小时统计数据
+     */
+    @ApiOperation("新增产线小时统计数据")
+    @PreAuthorize("@ss.hasPermi('dye:line:add')")
+    @Log(title = "产线小时统计数据", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody DyeHourLine dyeHourLine)
+    {
+        return toAjax(dyeHourLineService.insertDyeHourLine(dyeHourLine));
+    }
+
+    /**
+     * 修改产线小时统计数据
+     */
+    @ApiOperation("修改产线小时统计数据")
+    @PreAuthorize("@ss.hasPermi('dye:line:edit')")
+    @Log(title = "产线小时统计数据", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody DyeHourLine dyeHourLine)
+    {
+        return toAjax(dyeHourLineService.updateDyeHourLine(dyeHourLine));
+    }
+
+    /**
+     * 删除产线小时统计数据
+     */
+    @ApiOperation("删除产线小时统计数据")
+    @PreAuthorize("@ss.hasPermi('dye:line:remove')")
+    @Log(title = "产线小时统计数据", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{hourLineIds}")
+    public AjaxResult remove(@PathVariable Long[] hourLineIds)
+    {
+        return toAjax(dyeHourLineService.deleteDyeHourLineByHourLineIds(hourLineIds));
+    }
+}

+ 61 - 21
jjt-biz/src/main/java/com/jjt/dye/domain/DyeCalcHour.java

@@ -1,16 +1,16 @@
 package com.jjt.dye.domain;
 
-import java.math.BigDecimal;
-import java.util.Date;
-import com.fasterxml.jackson.annotation.JsonFormat;
 import com.baomidou.mybatisplus.annotation.TableId;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.jjt.common.annotation.Excel;
+import com.jjt.common.core.domain.BaseEntity;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
-import org.apache.commons.lang3.builder.ToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
-import com.jjt.common.annotation.Excel;
-import com.jjt.common.core.domain.BaseEntity;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
 
 /**
  * 小时统计数据对象 DYE_CALC_HOUR
@@ -20,64 +20,104 @@ import com.jjt.common.core.domain.BaseEntity;
  */
 @ApiModel(value = "DyeCalcHour", description = "小时统计数据")
 @Data
-public class DyeCalcHour extends BaseEntity{
+public class DyeCalcHour extends BaseEntity {
     private static final long serialVersionUID = 1L;
 
-    /** 统计ID */
+    /**
+     * 统计ID
+     */
     @ApiModelProperty("统计ID")
     @TableId
     private Long chId;
 
-    /** 日期 */
+    /**
+     * 日期
+     */
     @ApiModelProperty("日期")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     @Excel(name = "日期", width = 30, dateFormat = "yyyy-MM-dd")
     private Date dataDate;
 
-    /** 小时 */
+    /**
+     * 小时
+     */
     @ApiModelProperty("小时")
     @Excel(name = "小时")
-    private Long hour;
+    private Integer hour;
 
-    /** 设备ID */
+    /**
+     * 设备ID
+     */
     @ApiModelProperty("设备ID")
     @Excel(name = "设备ID")
     private Long deviceId;
 
-    /** 参数编码 */
+    @ApiModelProperty("设备名称")
+    private String deviceName;
+
+    /**
+     * 参数编码
+     */
     @ApiModelProperty("参数编码")
     @Excel(name = "参数编码")
     private String paraCode;
 
-    /** 参数名称 */
+    /**
+     * 参数名称
+     */
     @ApiModelProperty("参数名称")
     @Excel(name = "参数名称")
     private String paraName;
 
-    /** 参数值 */
+    /**
+     * 参数值
+     */
     @ApiModelProperty("参数值")
     @Excel(name = "参数值")
     private BigDecimal paraValue;
 
-    /** 参数分钟级数据 */
+    /**
+     * 参数分钟级数据
+     */
     @ApiModelProperty("参数分钟级数据")
     @Excel(name = "参数分钟级数据")
     private String paraMValue;
+    /**
+     * 分钟级数据列表
+     */
+    private List<BigDecimal> mValues;
+    /**
+     * 时间列表,只取分钟
+     */
+    private List<String> times;
 
-    /** 创建人 */
+    /**
+     * 创建人
+     */
     @ApiModelProperty("创建人")
     private String createdBy;
 
-    /** 创建时间 */
+    /**
+     * 创建时间
+     */
     @ApiModelProperty("创建时间")
     private Date createdTime;
 
-    /** 更新人 */
+    /**
+     * 更新人
+     */
     @ApiModelProperty("更新人")
     private String updatedBy;
 
-    /** 更新时间 */
+    /**
+     * 更新时间
+     */
     @ApiModelProperty("更新时间")
     private Date updatedTime;
+    /**
+     * 数据点数
+     */
+    @ApiModelProperty("数据点数")
+    private Integer num;
 
 }

+ 104 - 0
jjt-biz/src/main/java/com/jjt/dye/domain/DyeHourLine.java

@@ -0,0 +1,104 @@
+package com.jjt.dye.domain;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.baomidou.mybatisplus.annotation.TableId;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.jjt.common.annotation.Excel;
+import com.jjt.common.core.domain.BaseEntity;
+
+/**
+ * 产线小时统计数据对象 DYE_HOUR_LINE
+ *
+ * @author wukai
+ * @date 2025-11-04
+ */
+@ApiModel(value = "DyeHourLine", description = "产线小时统计数据")
+@Data
+public class DyeHourLine extends BaseEntity{
+    private static final long serialVersionUID = 1L;
+
+    /** 产线小时统计ID */
+    @ApiModelProperty("产线小时统计ID")
+    @TableId
+    private Long hourLineId;
+
+    /** 日期 */
+    @ApiModelProperty("日期")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "日期", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date dataDate;
+
+    /** 小时 */
+    @ApiModelProperty("小时")
+    @Excel(name = "小时")
+    private Integer hour;
+
+    /** 产线编号 */
+    @ApiModelProperty("产线编号")
+    @Excel(name = "产线编号")
+    private String line;
+
+    /** 稼动率 */
+    @ApiModelProperty("稼动率")
+    @Excel(name = "稼动率")
+    private BigDecimal uptime;
+
+    /** 产量 */
+    @ApiModelProperty("产量")
+    @Excel(name = "产量")
+    private BigDecimal length;
+
+    /** 产量分钟级数据 */
+    @ApiModelProperty("产量分钟级数据")
+    private String lengthM;
+
+    /** 速度 */
+    @ApiModelProperty("速度")
+    @Excel(name = "速度")
+    private BigDecimal speed;
+
+    /** 速度分钟级数据 */
+    @ApiModelProperty("速度分钟级数据")
+    private String speedM;
+
+    /** 电量 */
+    @ApiModelProperty("电量")
+    @Excel(name = "电量")
+    private BigDecimal energy;
+
+    /** 电量分钟级数据 */
+    @ApiModelProperty("电量分钟级数据")
+    private String energyM;
+
+    /** 电流 */
+    @ApiModelProperty("电流")
+    @Excel(name = "电流")
+    private BigDecimal amp;
+
+    /** 电流分钟级数据 */
+    @ApiModelProperty("电流分钟级数据")
+    private String ampM;
+
+    /** 创建人 */
+    @ApiModelProperty("创建人")
+    private String createdBy;
+
+    /** 创建时间 */
+    @ApiModelProperty("创建时间")
+    private Date createdTime;
+
+    /** 更新人 */
+    @ApiModelProperty("更新人")
+    private String updatedBy;
+
+    /** 更新时间 */
+    @ApiModelProperty("更新时间")
+    private Date updatedTime;
+
+}

+ 20 - 10
jjt-biz/src/main/java/com/jjt/dye/mapper/DyeCalcHourMapper.java

@@ -1,20 +1,22 @@
 package com.jjt.dye.mapper;
 
-import java.util.List;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.jjt.dye.domain.DyeCalcHour;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.Date;
+import java.util.List;
 
 /**
  * 小时统计数据Mapper接口
- * 
+ *
  * @author wukai
  * @date 2025-11-01
  */
-public interface DyeCalcHourMapper extends BaseMapper<DyeCalcHour>
-{
+public interface DyeCalcHourMapper extends BaseMapper<DyeCalcHour> {
     /**
      * 查询小时统计数据
-     * 
+     *
      * @param chId 小时统计数据主键
      * @return 小时统计数据
      */
@@ -22,7 +24,7 @@ public interface DyeCalcHourMapper extends BaseMapper<DyeCalcHour>
 
     /**
      * 查询小时统计数据列表
-     * 
+     *
      * @param dyeCalcHour 小时统计数据
      * @return 小时统计数据集合
      */
@@ -30,7 +32,7 @@ public interface DyeCalcHourMapper extends BaseMapper<DyeCalcHour>
 
     /**
      * 新增小时统计数据
-     * 
+     *
      * @param dyeCalcHour 小时统计数据
      * @return 结果
      */
@@ -38,7 +40,7 @@ public interface DyeCalcHourMapper extends BaseMapper<DyeCalcHour>
 
     /**
      * 修改小时统计数据
-     * 
+     *
      * @param dyeCalcHour 小时统计数据
      * @return 结果
      */
@@ -46,7 +48,7 @@ public interface DyeCalcHourMapper extends BaseMapper<DyeCalcHour>
 
     /**
      * 删除小时统计数据
-     * 
+     *
      * @param chId 小时统计数据主键
      * @return 结果
      */
@@ -54,9 +56,17 @@ public interface DyeCalcHourMapper extends BaseMapper<DyeCalcHour>
 
     /**
      * 批量删除小时统计数据
-     * 
+     *
      * @param chIds 需要删除的数据主键集合
      * @return 结果
      */
     public int deleteDyeCalcHourByChIds(Long[] chIds);
+
+    /**
+     * 按小时删除数据
+     *
+     * @param date  时间
+     * @param hour  小时
+     */
+    void deleteByHour(@Param("date") Date date, @Param("hour") int hour);
 }

+ 70 - 0
jjt-biz/src/main/java/com/jjt/dye/mapper/DyeHourLineMapper.java

@@ -0,0 +1,70 @@
+package com.jjt.dye.mapper;
+
+import java.util.Date;
+import java.util.List;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.jjt.dye.domain.DyeHourLine;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * 产线小时统计数据Mapper接口
+ *
+ * @author wukai
+ * @date 2025-11-04
+ */
+public interface DyeHourLineMapper extends BaseMapper<DyeHourLine>
+{
+    /**
+     * 查询产线小时统计数据
+     *
+     * @param hourLineId 产线小时统计数据主键
+     * @return 产线小时统计数据
+     */
+    public DyeHourLine selectDyeHourLineByHourLineId(Long hourLineId);
+
+    /**
+     * 查询产线小时统计数据列表
+     *
+     * @param dyeHourLine 产线小时统计数据
+     * @return 产线小时统计数据集合
+     */
+    public List<DyeHourLine> selectDyeHourLineList(DyeHourLine dyeHourLine);
+
+    /**
+     * 新增产线小时统计数据
+     *
+     * @param dyeHourLine 产线小时统计数据
+     * @return 结果
+     */
+    public int insertDyeHourLine(DyeHourLine dyeHourLine);
+
+    /**
+     * 修改产线小时统计数据
+     *
+     * @param dyeHourLine 产线小时统计数据
+     * @return 结果
+     */
+    public int updateDyeHourLine(DyeHourLine dyeHourLine);
+
+    /**
+     * 删除产线小时统计数据
+     *
+     * @param hourLineId 产线小时统计数据主键
+     * @return 结果
+     */
+    public int deleteDyeHourLineByHourLineId(Long hourLineId);
+
+    /**
+     * 批量删除产线小时统计数据
+     *
+     * @param hourLineIds 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteDyeHourLineByHourLineIds(Long[] hourLineIds);
+    /**
+     * 按小时删除数据
+     * @param date 时间
+     * @param hour 小时
+     */
+    void deleteByHour(@Param("date") Date date, @Param("hour") int hour);
+}

+ 24 - 1
jjt-biz/src/main/java/com/jjt/dye/service/IDyeCalcHourService.java

@@ -1,8 +1,10 @@
 package com.jjt.dye.service;
 
-import java.util.List;
 import com.jjt.dye.domain.DyeCalcHour;
 
+import java.time.LocalDate;
+import java.util.List;
+
 /**
  * 小时统计数据Service接口
  *
@@ -57,4 +59,25 @@ public interface IDyeCalcHourService {
      * @return 结果
      */
     public int deleteDyeCalcHourByChId(Long chId);
+
+    /**
+     * 计算上一小时数据
+     */
+    void calcLastHour();
+
+    /**
+     * 计算指定时间指定小时数据
+     *
+     * @param date 时间
+     * @param hour 小时
+     */
+    void calc(LocalDate date, int hour);
+
+    /**
+     * 查询指定时间指定小时数据
+     *
+     * @param date 时间
+     * @param hour 小时
+     */
+    List<DyeCalcHour> selectByTime(LocalDate date, int hour);
 }

+ 18 - 1
jjt-biz/src/main/java/com/jjt/dye/service/IDyeDeviceService.java

@@ -1,7 +1,10 @@
 package com.jjt.dye.service;
 
-import java.util.List;
 import com.jjt.dye.domain.DyeDevice;
+import com.jjt.dye.vo.DyeDeviceVO;
+
+import java.util.List;
+import java.util.Map;
 
 /**
  * 染整线设备管理Service接口
@@ -57,4 +60,18 @@ public interface IDyeDeviceService {
      * @return 结果
      */
     public int deleteDyeDeviceByDeviceId(Long deviceId);
+
+    /**
+     * 根据线别获取设备
+     *
+     * @return 结果
+     */
+    Map<String, List<DyeDeviceVO>> deviceByLine();
+
+    /**
+     * 按设备ID分组
+     *
+     * @return 结果
+     */
+    Map<Long, DyeDevice> deviceMap();
 }

+ 75 - 0
jjt-biz/src/main/java/com/jjt/dye/service/IDyeHourLineService.java

@@ -0,0 +1,75 @@
+package com.jjt.dye.service;
+
+import com.jjt.dye.domain.DyeHourLine;
+
+import java.time.LocalDate;
+import java.util.List;
+
+/**
+ * 产线小时统计数据Service接口
+ *
+ * @author wukai
+ * @date 2025-11-04
+ */
+public interface IDyeHourLineService {
+    /**
+     * 查询产线小时统计数据
+     *
+     * @param hourLineId 产线小时统计数据主键
+     * @return 产线小时统计数据
+     */
+    public DyeHourLine selectDyeHourLineByHourLineId(Long hourLineId);
+
+    /**
+     * 查询产线小时统计数据列表
+     *
+     * @param dyeHourLine 产线小时统计数据
+     * @return 产线小时统计数据集合
+     */
+    public List<DyeHourLine> selectDyeHourLineList(DyeHourLine dyeHourLine);
+
+    /**
+     * 新增产线小时统计数据
+     *
+     * @param dyeHourLine 产线小时统计数据
+     * @return 结果
+     */
+    public int insertDyeHourLine(DyeHourLine dyeHourLine);
+
+    /**
+     * 修改产线小时统计数据
+     *
+     * @param dyeHourLine 产线小时统计数据
+     * @return 结果
+     */
+    public int updateDyeHourLine(DyeHourLine dyeHourLine);
+
+    /**
+     * 批量删除产线小时统计数据
+     *
+     * @param hourLineIds 需要删除的产线小时统计数据主键集合
+     * @return 结果
+     */
+    public int deleteDyeHourLineByHourLineIds(Long[] hourLineIds);
+
+    /**
+     * 删除产线小时统计数据信息
+     *
+     * @param hourLineId 产线小时统计数据主键
+     * @return 结果
+     */
+    public int deleteDyeHourLineByHourLineId(Long hourLineId);
+
+    /**
+     * 计算上一小时数据
+     */
+    void calcLastHour();
+
+    /**
+     * 计算指定时间指定小时数据
+     *
+     * @param date 时间
+     * @param hour 小时
+     */
+    void calc(LocalDate date, int hour);
+}

+ 248 - 4
jjt-biz/src/main/java/com/jjt/dye/service/impl/DyeCalcHourServiceImpl.java

@@ -1,11 +1,33 @@
 package com.jjt.dye.service.impl;
 
-import java.util.List;
-import org.springframework.stereotype.Service;
-import com.jjt.dye.mapper.DyeCalcHourMapper;
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
+import com.jjt.common.utils.DateUtils;
 import com.jjt.dye.domain.DyeCalcHour;
+import com.jjt.dye.domain.DyeDevicePara;
+import com.jjt.dye.domain.DyeTypePara;
+import com.jjt.dye.mapper.DyeCalcHourMapper;
 import com.jjt.dye.service.IDyeCalcHourService;
+import com.jjt.dye.service.IDyeDeviceService;
+import com.jjt.dye.service.IDyeHourLineService;
+import com.jjt.dye.vo.DyeDeviceVO;
+import com.jjt.utils.IotService;
+import com.jjt.utils.Tools;
+import org.apache.ibatis.session.ExecutorType;
+import org.apache.ibatis.session.SqlSession;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.springframework.stereotype.Service;
+
 import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 /**
  * 小时统计数据Service业务层处理
@@ -17,6 +39,14 @@ import javax.annotation.Resource;
 public class DyeCalcHourServiceImpl implements IDyeCalcHourService {
     @Resource
     private DyeCalcHourMapper dyeCalcHourMapper;
+    @Resource
+    private IotService iotService;
+    @Resource
+    private SqlSessionFactory factory;
+    @Resource
+    private IDyeDeviceService dyeDeviceService;
+    @Resource
+    private IDyeHourLineService dyeHourLineService;
 
     /**
      * 查询小时统计数据
@@ -48,7 +78,7 @@ public class DyeCalcHourServiceImpl implements IDyeCalcHourService {
      */
     @Override
     public int insertDyeCalcHour(DyeCalcHour dyeCalcHour) {
-            return dyeCalcHourMapper.insertDyeCalcHour(dyeCalcHour);
+        return dyeCalcHourMapper.insertDyeCalcHour(dyeCalcHour);
     }
 
     /**
@@ -83,4 +113,218 @@ public class DyeCalcHourServiceImpl implements IDyeCalcHourService {
     public int deleteDyeCalcHourByChId(Long chId) {
         return dyeCalcHourMapper.deleteDyeCalcHourByChId(chId);
     }
+
+    /**
+     * 计算上一小时数据
+     */
+    @Override
+    public void calcLastHour() {
+        LocalDateTime end = Tools.currWholeTime();
+        LocalDateTime start = end.minusHours(1);
+        calc(start.toLocalDate(), start.getHour());
+    }
+
+    /**
+     * 计算指定时间指定小时数据
+     *
+     * @param date 时间
+     * @param hour 小时
+     */
+    @Override
+    public void calc(LocalDate date, int hour) {
+        LocalDateTime start = LocalDateTime.of(date, LocalTime.MIN).plusHours(hour);
+        LocalDateTime end = start.plusHours(1);
+        dyeCalcHourMapper.deleteByHour(DateUtils.toDate(date), hour);
+        Map<String, List<DyeDeviceVO>> deviceByLine = dyeDeviceService.deviceByLine();
+        deviceByLine.forEach((line, devices) -> {
+            // 计算能源参数
+            calcCommon(start, end, devices,
+                    (device, d) -> device.getEngParas(),
+                    (exp, device) -> exp);
+
+            // 计算类型参数
+            calcCommon(start, end, devices,
+                    (device, d) -> device.getTypeParas(),
+                    (exp, device) -> exp.replace("${code}", device.getDeviceCode()));
+        });
+        dyeHourLineService.calc(date, hour);
+    }
+
+    /**
+     * 查询指定时间指定小时数据
+     *
+     * @param date 时间
+     * @param hour 小时
+     */
+    @Override
+    public List<DyeCalcHour> selectByTime(LocalDate date, int hour) {
+        DyeCalcHour dyeCalcHour = new DyeCalcHour();
+        dyeCalcHour.setDataDate(DateUtils.toDate(date));
+        dyeCalcHour.setHour(hour);
+        return selectDyeCalcHourList(dyeCalcHour);
+    }
+
+    /**
+     * 通用计算方法
+     *
+     * @param start         开始时间
+     * @param end           结束时间
+     * @param devices       设备列表
+     * @param parasSupplier 参数提供者函数
+     * @param expProcessor  表达式处理器
+     */
+    private void calcCommon(LocalDateTime start, LocalDateTime end, List<DyeDeviceVO> devices,
+                            java.util.function.BiFunction<DyeDeviceVO, Object, List<?>> parasSupplier,
+                            java.util.function.BiFunction<String, DyeDeviceVO, String> expProcessor) {
+        Map<String, DyeCalcHour> calcMap = new HashMap<>(16);
+        List<String> fields = new ArrayList<>();
+
+        devices.forEach(device -> {
+            List<?> paras = parasSupplier.apply(device, device);
+            if (paras != null) {
+                paras.forEach(para -> {
+                    String key;
+                    String paraCode;
+                    String paraName;
+                    String paraExp;
+                    String remark = "";
+
+                    // 根据参数类型获取相应属性
+                    if (para instanceof DyeDevicePara) {
+                        DyeDevicePara dyePara = (DyeDevicePara) para;
+                        key = dyePara.getParaCode() + device.getDeviceId();
+                        paraCode = dyePara.getParaCode();
+                        paraName = dyePara.getParaName();
+                        paraExp = dyePara.getParaExp();
+                    } else if (para instanceof DyeTypePara) {
+                        DyeTypePara typePara = (DyeTypePara) para;
+                        key = typePara.getParaCode() + device.getDeviceId();
+                        paraCode = typePara.getParaCode();
+                        paraName = typePara.getParaName();
+                        paraExp = typePara.getParaExp();
+                    } else {
+                        return; // 未知类型,跳过处理
+                    }
+                    if (paraCode.equals("P_uptime")) {
+                        remark = "UPTIME";
+                    } else {
+                        if (paraExp.contains("AVG")) {
+                            remark = "AVG";
+                        } else if (paraExp.contains("SUM")) {
+                            remark = "SUM";
+                        } else if (paraExp.contains("MAX")) {
+                            remark = "MAX";
+                        }
+                    }
+
+                    String processedExp = expProcessor.apply(paraExp, device);
+                    String fieldExp = processedExp + " AS " + key;
+                    fields.add(fieldExp);
+
+                    DyeCalcHour calcHour = new DyeCalcHour();
+                    calcHour.setDeviceId(device.getDeviceId());
+                    calcHour.setDataDate(DateUtils.toDate(start.toLocalDate()));
+                    calcHour.setHour(start.getHour());
+                    calcHour.setParaCode(paraCode);
+                    calcHour.setParaName(paraName);
+                    calcHour.setRemark(remark);
+                    calcMap.put(key, calcHour);
+                });
+            }
+        });
+
+        process(start, end, calcMap, fields);
+    }
+
+    private void process(LocalDateTime start, LocalDateTime end, Map<String, DyeCalcHour> paraMap, List<String> paraFields) {
+        String sql = "select %s from root.tl.suxi group by ((%s,%s],1m)";
+        sql = String.format(sql, String.join(",", paraFields), DateUtils.parseIso(start), DateUtils.parseIso(end));
+        iotService.query(sql);
+        JSONObject jsonObject = iotService.query(sql);
+        JSONObject data = jsonObject.getJSONObject("data");
+        JSONArray values = data.getJSONArray("values");
+        JSONArray columnNames = data.getJSONArray("columnNames");
+        JSONArray timestamps = data.getJSONArray("timestamps");
+        if (values.size() > 0) {
+            for (int j = 0; j < values.size(); j++) {
+                JSONArray da = values.getJSONArray(j);
+                for (int i = 0; i < da.size(); i++) {
+                    String field = columnNames.getStr(i);
+                    long timestamp = timestamps.getLong(j);
+
+                    if (da.getDouble(i) != null) {
+                        Double v = da.getDouble(i);
+                        DyeCalcHour calc = paraMap.get(field);
+                        calc.setNum(da.size());
+                        List<BigDecimal> mValues = calc.getMValues();
+                        List<String> times = calc.getTimes();
+                        if (mValues == null) {
+                            mValues = new ArrayList<>();
+                        }
+                        if (times == null) {
+                            times = new ArrayList<>();
+                        }
+
+                        // 将timestamp转换为LocalDateTime,然后提取分钟数作为字符串添加到times列表中
+                        LocalDateTime dateTime = LocalDateTime.ofInstant(
+                                java.time.Instant.ofEpochMilli(timestamp),
+                                java.time.ZoneId.systemDefault());
+                        times.add(String.valueOf(dateTime.getMinute()));
+
+                        mValues.add(BigDecimal.valueOf(v).setScale(2, RoundingMode.HALF_UP));
+                        calc.setMValues(mValues);
+                        calc.setTimes(times);
+                    }
+                }
+            }
+        }
+        paraMap.forEach((k, v) -> {
+            if (v.getMValues() != null && !v.getMValues().isEmpty() && v.getTimes() != null) {
+                // 创建JSON对象来存储time和value的对应关系
+                JSONArray dataArray = new JSONArray();
+                List<BigDecimal> mValues = v.getMValues();
+                List<String> times = v.getTimes();
+
+                // 确保两个列表的大小相同
+                int size = Math.min(mValues.size(), times.size());
+                for (int i = 0; i < size; i++) {
+                    JSONObject dataObj = new JSONObject();
+                    dataObj.set("time", times.get(i));
+                    dataObj.set("value", mValues.get(i));
+                    dataArray.add(dataObj);
+                }
+
+                // 将JSON数组转换为字符串并存储在paraMValue字段中
+                v.setParaMValue(dataArray.toString());
+
+                BigDecimal sum = v.getMValues().stream().reduce(BigDecimal.ZERO, BigDecimal::add);
+                switch (v.getRemark()) {
+                    case "AVG":
+                        v.setParaValue(sum.divide(new BigDecimal(v.getMValues().size()), 2, RoundingMode.HALF_UP));
+                        break;
+                    case "SUM":
+                        v.setParaValue(sum);
+                        break;
+                    case "MAX":
+                        v.setParaValue(v.getMValues().stream().max(BigDecimal::compareTo).orElse(BigDecimal.ZERO));
+                        break;
+                    case "UPTIME":
+                        //针对稼动率专门处理
+                        v.setParaValue(sum.divide(new BigDecimal(v.getNum()), 2, RoundingMode.HALF_UP));
+                        break;
+                    default:
+                }
+            }
+        });
+        List<DyeCalcHour> list = new ArrayList<>(paraMap.values());
+
+        try (SqlSession sqlSession = factory.openSession(ExecutorType.BATCH, false)) {
+            if (list.size() > 0) {
+                DyeCalcHourMapper mapper = sqlSession.getMapper(DyeCalcHourMapper.class);
+                list.forEach(mapper::insertDyeCalcHour);
+                sqlSession.commit();
+            }
+        }
+    }
+
 }

+ 76 - 38
jjt-biz/src/main/java/com/jjt/dye/service/impl/DyeDeviceServiceImpl.java

@@ -1,16 +1,22 @@
 package com.jjt.dye.service.impl;
 
-import java.util.List;
-import org.springframework.stereotype.Service;
-    import java.util.ArrayList;
-
-    import com.jjt.common.utils.StringUtils;
-    import org.springframework.transaction.annotation.Transactional;
-    import com.jjt.dye.domain.DyeDevicePara;
-import com.jjt.dye.mapper.DyeDeviceMapper;
+import com.jjt.common.utils.StringUtils;
+import com.jjt.common.utils.bean.BeanUtils;
 import com.jjt.dye.domain.DyeDevice;
+import com.jjt.dye.domain.DyeDevicePara;
+import com.jjt.dye.domain.DyeType;
+import com.jjt.dye.mapper.DyeDeviceMapper;
 import com.jjt.dye.service.IDyeDeviceService;
+import com.jjt.dye.service.IDyeTypeService;
+import com.jjt.dye.vo.DyeDeviceVO;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
 import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * 染整线设备管理Service业务层处理
@@ -22,6 +28,8 @@ import javax.annotation.Resource;
 public class DyeDeviceServiceImpl implements IDyeDeviceService {
     @Resource
     private DyeDeviceMapper dyeDeviceMapper;
+    @Resource
+    private IDyeTypeService typeService;
 
     /**
      * 查询染整线设备管理
@@ -51,12 +59,12 @@ public class DyeDeviceServiceImpl implements IDyeDeviceService {
      * @param dyeDevice 染整线设备管理
      * @return 结果
      */
-        @Transactional
+    @Transactional
     @Override
     public int insertDyeDevice(DyeDevice dyeDevice) {
-            int rows = dyeDeviceMapper.insertDyeDevice(dyeDevice);
-            insertDyeDevicePara(dyeDevice);
-            return rows;
+        int rows = dyeDeviceMapper.insertDyeDevice(dyeDevice);
+        insertDyeDevicePara(dyeDevice);
+        return rows;
     }
 
     /**
@@ -65,12 +73,12 @@ public class DyeDeviceServiceImpl implements IDyeDeviceService {
      * @param dyeDevice 染整线设备管理
      * @return 结果
      */
-        @Transactional
+    @Transactional
     @Override
     public int updateDyeDevice(DyeDevice dyeDevice) {
-                dyeDeviceMapper.deleteDyeDeviceParaByDeviceId(dyeDevice.getDeviceId())
-            ;
-            insertDyeDevicePara(dyeDevice);
+        dyeDeviceMapper.deleteDyeDeviceParaByDeviceId(dyeDevice.getDeviceId())
+        ;
+        insertDyeDevicePara(dyeDevice);
         return dyeDeviceMapper.updateDyeDevice(dyeDevice);
     }
 
@@ -80,10 +88,10 @@ public class DyeDeviceServiceImpl implements IDyeDeviceService {
      * @param deviceIds 需要删除的染整线设备管理主键
      * @return 结果
      */
-        @Transactional
+    @Transactional
     @Override
     public int deleteDyeDeviceByDeviceIds(Long[] deviceIds) {
-                dyeDeviceMapper.deleteDyeDeviceParaByDeviceIds(deviceIds);
+        dyeDeviceMapper.deleteDyeDeviceParaByDeviceIds(deviceIds);
         return dyeDeviceMapper.deleteDyeDeviceByDeviceIds(deviceIds);
     }
 
@@ -93,31 +101,61 @@ public class DyeDeviceServiceImpl implements IDyeDeviceService {
      * @param deviceId 染整线设备管理主键
      * @return 结果
      */
-        @Transactional
+    @Transactional
     @Override
     public int deleteDyeDeviceByDeviceId(Long deviceId) {
-                dyeDeviceMapper.deleteDyeDeviceParaByDeviceId(deviceId);
+        dyeDeviceMapper.deleteDyeDeviceParaByDeviceId(deviceId);
         return dyeDeviceMapper.deleteDyeDeviceByDeviceId(deviceId);
     }
 
-        /**
-         * 新增染整线设备参数管理信息
-         *
-         * @param dyeDevice 染整线设备管理对象
-         */
-        public void insertDyeDevicePara(DyeDevice dyeDevice) {
-            List<DyeDevicePara> dyeDeviceParaList = dyeDevice.getDyeDeviceParaList();
-            Long deviceId = dyeDevice.getDeviceId();
-            if (StringUtils.isNotNull(dyeDeviceParaList)) {
-                List<DyeDevicePara> list = new ArrayList<DyeDevicePara>();
-                for (DyeDevicePara dyeDevicePara :dyeDeviceParaList)
-                {
-                    dyeDevicePara.setDeviceId(deviceId);
-                    list.add(dyeDevicePara);
-                }
-                if (list.size() > 0) {
-                        dyeDeviceMapper.batchDyeDevicePara(list);
-                }
+    /**
+     * 根据线别获取设备
+     *
+     * @return 结果
+     */
+    @Override
+    public Map<String, List<DyeDeviceVO>> deviceByLine() {
+        List<DyeDevice> list = selectDyeDeviceList(new DyeDevice());
+        List<DyeDeviceVO> result = new ArrayList<>();
+        for (DyeDevice device : list) {
+            device = dyeDeviceMapper.selectDyeDeviceByDeviceId(device.getDeviceId());
+            DyeDeviceVO vo = new DyeDeviceVO();
+            BeanUtils.copyProperties(device, vo);
+            vo.setEngParas(device.getDyeDeviceParaList());
+            DyeType type = typeService.selectDyeTypeByTypeId(device.getTypeId());
+            vo.setTypeParas(type.getDyeTypeParaList());
+            result.add(vo);
+        }
+        return result.stream().collect(Collectors.groupingBy(DyeDeviceVO::getLine));
+    }
+
+    /**
+     * 新增染整线设备参数管理信息
+     *
+     * @param dyeDevice 染整线设备管理对象
+     */
+    public void insertDyeDevicePara(DyeDevice dyeDevice) {
+        List<DyeDevicePara> dyeDeviceParaList = dyeDevice.getDyeDeviceParaList();
+        Long deviceId = dyeDevice.getDeviceId();
+        if (StringUtils.isNotNull(dyeDeviceParaList)) {
+            List<DyeDevicePara> list = new ArrayList<DyeDevicePara>();
+            for (DyeDevicePara dyeDevicePara : dyeDeviceParaList) {
+                dyeDevicePara.setDeviceId(deviceId);
+                list.add(dyeDevicePara);
+            }
+            if (list.size() > 0) {
+                dyeDeviceMapper.batchDyeDevicePara(list);
             }
         }
+    }
+
+    /**
+     * 获取设备map
+     *
+     * @return 结果
+     */
+    @Override
+    public Map<Long, DyeDevice> deviceMap() {
+        return selectDyeDeviceList(new DyeDevice()).stream().collect(Collectors.toMap(DyeDevice::getDeviceId, dyeDevice -> dyeDevice));
+    }
 }

+ 327 - 0
jjt-biz/src/main/java/com/jjt/dye/service/impl/DyeHourLineServiceImpl.java

@@ -0,0 +1,327 @@
+package com.jjt.dye.service.impl;
+
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.jjt.common.utils.DateUtils;
+import com.jjt.dye.domain.DyeCalcHour;
+import com.jjt.dye.domain.DyeDevice;
+import com.jjt.dye.domain.DyeHourLine;
+import com.jjt.dye.mapper.DyeHourLineMapper;
+import com.jjt.dye.service.IDyeCalcHourService;
+import com.jjt.dye.service.IDyeDeviceService;
+import com.jjt.dye.service.IDyeHourLineService;
+import com.jjt.utils.Tools;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+import java.util.function.BinaryOperator;
+import java.util.stream.Collectors;
+
+/**
+ * 产线小时统计数据Service业务层处理
+ *
+ * @author wukai
+ * @date 2025-11-04
+ */
+@Service
+public class DyeHourLineServiceImpl implements IDyeHourLineService {
+    @Resource
+    private DyeHourLineMapper dyeHourLineMapper;
+    @Resource
+    private IDyeCalcHourService calcHourService;
+    @Resource
+    private IDyeDeviceService deviceService;
+
+    /**
+     * 查询产线小时统计数据
+     *
+     * @param hourLineId 产线小时统计数据主键
+     * @return 产线小时统计数据
+     */
+    @Override
+    public DyeHourLine selectDyeHourLineByHourLineId(Long hourLineId) {
+        return dyeHourLineMapper.selectDyeHourLineByHourLineId(hourLineId);
+    }
+
+    /**
+     * 查询产线小时统计数据列表
+     *
+     * @param dyeHourLine 产线小时统计数据
+     * @return 产线小时统计数据
+     */
+    @Override
+    public List<DyeHourLine> selectDyeHourLineList(DyeHourLine dyeHourLine) {
+        return dyeHourLineMapper.selectDyeHourLineList(dyeHourLine);
+    }
+
+    /**
+     * 新增产线小时统计数据
+     *
+     * @param dyeHourLine 产线小时统计数据
+     * @return 结果
+     */
+    @Override
+    public int insertDyeHourLine(DyeHourLine dyeHourLine) {
+        return dyeHourLineMapper.insertDyeHourLine(dyeHourLine);
+    }
+
+    /**
+     * 修改产线小时统计数据
+     *
+     * @param dyeHourLine 产线小时统计数据
+     * @return 结果
+     */
+    @Override
+    public int updateDyeHourLine(DyeHourLine dyeHourLine) {
+        return dyeHourLineMapper.updateDyeHourLine(dyeHourLine);
+    }
+
+    /**
+     * 批量删除产线小时统计数据
+     *
+     * @param hourLineIds 需要删除的产线小时统计数据主键
+     * @return 结果
+     */
+    @Override
+    public int deleteDyeHourLineByHourLineIds(Long[] hourLineIds) {
+        return dyeHourLineMapper.deleteDyeHourLineByHourLineIds(hourLineIds);
+    }
+
+    /**
+     * 删除产线小时统计数据信息
+     *
+     * @param hourLineId 产线小时统计数据主键
+     * @return 结果
+     */
+    @Override
+    public int deleteDyeHourLineByHourLineId(Long hourLineId) {
+        return dyeHourLineMapper.deleteDyeHourLineByHourLineId(hourLineId);
+    }
+
+    /**
+     * 计算上一小时数据
+     */
+
+    @Override
+    public void calcLastHour() {
+        LocalDateTime end = Tools.currWholeTime();
+        LocalDateTime start = end.minusHours(1);
+        calc(start.toLocalDate(), start.getHour());
+    }
+
+    /**
+     * 计算指定时间指定小时数据
+     *
+     * @param date 时间
+     * @param hour 小时
+     */
+    @Override
+    public void calc(LocalDate date, int hour) {
+        //按设备ID分组的设备信息
+        Map<Long, DyeDevice> deviceMap = deviceService.deviceMap();
+
+        dyeHourLineMapper.deleteByHour(DateUtils.toDate(date), hour);
+        //1.先查询小时统计数据
+        List<DyeCalcHour> calcHours = calcHourService.selectByTime(date, hour);
+        for (DyeCalcHour calcHour : calcHours) {
+            DyeDevice device = deviceMap.get(calcHour.getDeviceId());
+            calcHour.setCreatedBy(device.getLine());
+        }
+        //按生产线分组统计
+        Map<String, List<DyeCalcHour>> lineMap = calcHours.stream()
+                .collect(Collectors.groupingBy(DyeCalcHour::getCreatedBy));
+
+        for (Map.Entry<String, List<DyeCalcHour>> entry : lineMap.entrySet()) {
+            String line = entry.getKey();
+            List<DyeCalcHour> lineCalcHours = entry.getValue();
+            
+            // 计算能耗总和
+            BigDecimal engEnergy = calculateParameterValue(lineCalcHours, "ENG_energy", BigDecimal::add);
+            String combinedEnergyMValue = combineParaMValues(lineCalcHours, "ENG_energy");
+            
+            // 计算电流平均值
+            BigDecimal engAmpA = calculateParameterValue(lineCalcHours, "ENG_amp_a", BigDecimal::add);
+            String avgAmpAMValue = averageParaMValues(lineCalcHours, "ENG_amp_a");
+            BigDecimal avgEngAmpA = lineCalcHours.isEmpty() ? BigDecimal.ZERO : 
+                engAmpA.divide(BigDecimal.valueOf(lineCalcHours.size()), 2, RoundingMode.HALF_UP);
+            
+            // 获取速度值和对应的分钟级数据
+            BigDecimal speed = lineCalcHours.stream()
+                    .filter(item -> item.getParaCode().equals("P_tt051hr93980"))
+                    .findFirst()
+                    .map(DyeCalcHour::getParaValue)
+                    .orElse(BigDecimal.ZERO);
+            
+            String speedMValue = lineCalcHours.stream()
+                    .filter(item -> item.getParaCode().equals("P_tt051hr93980") && item.getParaMValue() != null)
+                    .findFirst()
+                    .map(DyeCalcHour::getParaMValue)
+                    .orElse(null);
+
+            // 创建产线小时统计数据对象
+            DyeHourLine dyeHourLine = new DyeHourLine();
+            dyeHourLine.setLine(line);
+            dyeHourLine.setDataDate(DateUtils.toDate(date));
+            dyeHourLine.setHour(hour);
+            dyeHourLine.setSpeed(speed);
+            dyeHourLine.setEnergy(engEnergy);
+            dyeHourLine.setEnergyM(combinedEnergyMValue);
+            dyeHourLine.setAmpM(avgAmpAMValue);
+            dyeHourLine.setSpeedM(speedMValue);
+            dyeHourLine.setAmp(avgEngAmpA);
+            // 保存产线小时统计数据
+            dyeHourLineMapper.insertDyeHourLine(dyeHourLine);
+        }
+    }
+    
+    /**
+     * 计算指定参数的值
+     * @param lineCalcHours 数据列表
+     * @param paraCode 参数代码
+     * @param operator 计算操作符
+     * @return 计算结果
+     */
+    private BigDecimal calculateParameterValue(List<DyeCalcHour> lineCalcHours, String paraCode, 
+                                              BinaryOperator<BigDecimal> operator) {
+        return lineCalcHours.stream()
+                .filter(item -> item.getParaCode().equals(paraCode))
+                .map(DyeCalcHour::getParaValue)
+                .reduce(BigDecimal.ZERO, operator);
+    }
+    
+    /**
+     * 合并多个paraMValue字段中的JSON数据,保持原有格式
+     * @param lineCalcHours 数据列表
+     * @param paraCode 参数代码
+     * @return 合并后的JSON字符串
+     */
+    private String combineParaMValues(List<DyeCalcHour> lineCalcHours, String paraCode) {
+        List<DyeCalcHour> items = lineCalcHours.stream()
+                .filter(item -> item.getParaCode().equals(paraCode) && item.getParaMValue() != null)
+                .collect(Collectors.toList());
+        
+        if (items.isEmpty()) {
+            return null;
+        }
+        
+        // 创建一个Map来存储time-value对,key为time,value为value的累加值
+        Map<String, BigDecimal> combinedValues = new java.util.HashMap<>();
+        
+        // 遍历所有items中的paraMValue
+        for (DyeCalcHour item : items) {
+            try {
+                JSONArray dataArray = JSONUtil.parseArray(item.getParaMValue());
+                for (int i = 0; i < dataArray.size(); i++) {
+                    JSONObject dataObj = dataArray.getJSONObject(i);
+                    String time = dataObj.getStr("time");
+                    BigDecimal value = dataObj.getBigDecimal("value", BigDecimal.ZERO);
+                    
+                    // 累加相同time的value
+                    combinedValues.merge(time, value, BigDecimal::add);
+                }
+            } catch (Exception e) {
+                // 解析出错时跳过该条数据
+                continue;
+            }
+        }
+        
+
+        // 构建合并后的JSONArray,按数字顺序排序
+        JSONArray combinedArray = new JSONArray();
+        combinedValues.entrySet().stream()
+                .sorted((entry1, entry2) -> {
+                    try {
+                        // 将time转换为整型进行排序
+                        Integer time1 = Integer.valueOf(entry1.getKey());
+                        Integer time2 = Integer.valueOf(entry2.getKey());
+                        return time1.compareTo(time2);
+                    } catch (NumberFormatException e) {
+                        // 如果转换失败,则按字符串排序
+                        return entry1.getKey().compareTo(entry2.getKey());
+                    }
+                })
+                .forEach(entry -> {
+                    JSONObject dataObj = new JSONObject();
+                    dataObj.set("time", entry.getKey());
+                    dataObj.set("value", entry.getValue());
+                    combinedArray.add(dataObj);
+                });
+        
+        return combinedArray.toString();
+    }
+    
+    /**
+     * 对多个paraMValue字段中的JSON数据计算平均值,保持原有格式
+     * @param lineCalcHours 数据列表
+     * @param paraCode 参数代码
+     * @return 平均值后的JSON字符串
+     */
+    private String averageParaMValues(List<DyeCalcHour> lineCalcHours, String paraCode) {
+        List<DyeCalcHour> items = lineCalcHours.stream()
+                .filter(item -> item.getParaCode().equals(paraCode) && item.getParaMValue() != null)
+                .collect(Collectors.toList());
+        
+        if (items.isEmpty()) {
+            return null;
+        }
+        
+        // 创建一个Map来存储time-value对,key为time,value为value的累加值
+        Map<String, BigDecimal> combinedValues = new java.util.HashMap<>();
+        // 创建一个Map来存储time出现的次数,用于计算平均值
+        Map<String, Integer> timeCounts = new java.util.HashMap<>();
+        
+        // 遍历所有items中的paraMValue
+        for (DyeCalcHour item : items) {
+            try {
+                JSONArray dataArray = JSONUtil.parseArray(item.getParaMValue());
+                for (int i = 0; i < dataArray.size(); i++) {
+                    JSONObject dataObj = dataArray.getJSONObject(i);
+                    String time = dataObj.getStr("time");
+                    BigDecimal value = dataObj.getBigDecimal("value", BigDecimal.ZERO);
+                    
+                    // 累加相同time的value
+                    combinedValues.merge(time, value, BigDecimal::add);
+                    // 记录time出现的次数
+                    timeCounts.merge(time, 1, Integer::sum);
+                }
+            } catch (Exception e) {
+                // 解析出错时跳过该条数据
+                continue;
+            }
+        }
+        
+        // 构建平均值后的JSONArray,按数字顺序排序
+        JSONArray averagedArray = new JSONArray();
+        combinedValues.entrySet().stream()
+                .sorted((entry1, entry2) -> {
+                    try {
+                        // 将time转换为整型进行排序
+                        Integer time1 = Integer.valueOf(entry1.getKey());
+                        Integer time2 = Integer.valueOf(entry2.getKey());
+                        return time1.compareTo(time2);
+                    } catch (NumberFormatException e) {
+                        // 如果转换失败,则按字符串排序
+                        return entry1.getKey().compareTo(entry2.getKey());
+                    }
+                })
+                .forEach(entry -> {
+                    String time = entry.getKey();
+                    BigDecimal sum = entry.getValue();
+                    int count = timeCounts.getOrDefault(time, 1);
+                    
+                    JSONObject dataObj = new JSONObject();
+                    dataObj.set("time", time);
+                    // 计算平均值
+                    dataObj.set("value", sum.divide(new BigDecimal(count), 2, RoundingMode.HALF_UP));
+                    averagedArray.add(dataObj);
+                });
+        return averagedArray.toString();
+    }
+}

+ 53 - 0
jjt-biz/src/main/java/com/jjt/dye/vo/DyeDeviceVO.java

@@ -0,0 +1,53 @@
+package com.jjt.dye.vo;
+
+import com.jjt.dye.domain.DyeDevicePara;
+import com.jjt.dye.domain.DyeTypePara;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * DyeDeviceVO$
+ *
+ * @author wukai
+ * @date 2025/11/2 02:33
+ */
+@Data
+public class DyeDeviceVO {
+    @ApiModelProperty("设备ID")
+    private Long deviceId;
+
+    @ApiModelProperty("类型ID")
+    private Long typeId;
+
+    @ApiModelProperty("车间")
+    private String wsName;
+
+    @ApiModelProperty("产线编号")
+    private String line;
+
+    @ApiModelProperty("类型名称")
+    private String typeName;
+
+    @ApiModelProperty("设备编码")
+    private String deviceCode;
+
+    @ApiModelProperty("设备序号")
+    private Integer sortNum;
+
+    @ApiModelProperty("设备名称")
+    private String deviceName;
+
+    @ApiModelProperty("设备路径")
+    private String devicePath;
+
+    /**
+     * 能源参数
+     */
+    private List<DyeDevicePara> engParas;
+    /**
+     * 类型参数
+     */
+    private List<DyeTypePara> typeParas;
+}

+ 72 - 72
jjt-biz/src/main/java/com/jjt/dyeing/service/impl/DyeingHourAvgServiceImpl.java

@@ -129,78 +129,78 @@ public class DyeingHourAvgServiceImpl implements IDyeingHourAvgService {
      */
     @Override
     public void calc(LocalDate date, int hour) {
-        LocalDateTime start = LocalDateTime.of(date, LocalTime.MIN).plusHours(hour);
-        LocalDateTime end = start.plusHours(1);
-        dyeingHourAvgMapper.deleteByHour(DateUtils.toDate(date), hour);
-        Map<String, List<DyeingDevice>> deviceByLine = deviceService.deviceByLine();
-        deviceByLine.forEach((line, devices) -> {
-            Map<Long, DyeingHourAvg> avgMap = new HashMap<>();
-            List<String> fieldList = new ArrayList<>();
-            devices.forEach(device -> {
-                if (StringUtils.isNotEmpty(device.getLengthExp())) {
-                    String tmp = device.getLengthExp().replace("${code}", device.getDeviceCode()) + " AS " + device.getDeviceId() + "_length";
-                    fieldList.add(tmp);
-                }
-                if (StringUtils.isNotEmpty(device.getStatusExp())) {
-                    String statusExp = device.getStatusExp().replace("${code}", device.getDeviceCode()) + " AS " + device.getDeviceId() + "_status";
-                    fieldList.add(statusExp);
-                }
-                if (StringUtils.isNotEmpty(device.getSpeedExp())) {
-                    String speedExp = device.getSpeedExp().replace("${code}", device.getDeviceCode()) + " AS " + device.getDeviceId() + "_speed";
-                    fieldList.add(speedExp);
-                }
-                if (StringUtils.isNotEmpty(device.getTmpExp())) {
-                    String tmp = device.getTmpExp().replace("${code}", device.getDeviceCode()) + " AS " + device.getDeviceId() + "_tmp";
-                    fieldList.add(tmp);
-                }
-                DyeingHourAvg energy = new DyeingHourAvg();
-                energy.setDeviceId(device.getDeviceId());
-                energy.setDataDate(DateUtils.toDate(date));
-                energy.setHour(start.getHour());
-                avgMap.put(device.getDeviceId(), energy);
-            });
-            String sql = "select %s from root.tl.suxi where time>%s and time <=%s";
-            sql = String.format(sql, String.join(",", fieldList), DateUtils.parseIso(start), DateUtils.parseIso(end));
-            iotService.query(sql);
-            JSONObject jsonObject = iotService.query(sql);
-            JSONObject data = jsonObject.getJSONObject("data");
-            JSONArray values = data.getJSONArray("values");
-            JSONArray columnNames = data.getJSONArray("columnNames");
-            if (values.size() == 1) {
-                JSONArray da = values.getJSONArray(0);
-                for (int i = 0; i < da.size(); i++) {
-                    String field = columnNames.getStr(i);
-                    String[] split = field.split("_");
-                    Long id = Long.parseLong(split[0]);
-                    String type = split[1];
-                    if (da.getDouble(i) != null) {
-                        Double v = da.getDouble(i);
-                        DyeingHourAvg energy = avgMap.get(id);
-                        if ("length".equals(type)) {
-                            energy.setLength(BigDecimal.valueOf(v));
-                        }
-                        if ("status".equals(type)) {
-                            energy.setOnline(BigDecimal.valueOf(v).divide(BigDecimal.valueOf(1000), 0, RoundingMode.HALF_UP).longValue());
-                        }
-                        if ("speed".equals(type)) {
-                            energy.setSpeed(BigDecimal.valueOf(v));
-                        }
-                        if ("tmp".equals(type)) {
-                            energy.setTmp(BigDecimal.valueOf(v));
-                        }
-                    }
-                }
-            }
-            List<DyeingHourAvg> dyeingHourEnergies = new ArrayList<>(avgMap.values());
-
-            try (SqlSession sqlSession = factory.openSession(ExecutorType.BATCH, false)) {
-                if (dyeingHourEnergies.size() > 0) {
-                    DyeingHourAvgMapper mapper = sqlSession.getMapper(DyeingHourAvgMapper.class);
-                    dyeingHourEnergies.forEach(mapper::insertDyeingHourAvg);
-                    sqlSession.commit();
-                }
-            }
-        });
+//        LocalDateTime start = LocalDateTime.of(date, LocalTime.MIN).plusHours(hour);
+//        LocalDateTime end = start.plusHours(1);
+//        dyeingHourAvgMapper.deleteByHour(DateUtils.toDate(date), hour);
+//        Map<String, List<DyeingDevice>> deviceByLine = deviceService.deviceByLine();
+//        deviceByLine.forEach((line, devices) -> {
+//            Map<Long, DyeingHourAvg> avgMap = new HashMap<>();
+//            List<String> fieldList = new ArrayList<>();
+//            devices.forEach(device -> {
+//                if (StringUtils.isNotEmpty(device.getLengthExp())) {
+//                    String tmp = device.getLengthExp().replace("${code}", device.getDeviceCode()) + " AS " + device.getDeviceId() + "_length";
+//                    fieldList.add(tmp);
+//                }
+//                if (StringUtils.isNotEmpty(device.getStatusExp())) {
+//                    String statusExp = device.getStatusExp().replace("${code}", device.getDeviceCode()) + " AS " + device.getDeviceId() + "_status";
+//                    fieldList.add(statusExp);
+//                }
+//                if (StringUtils.isNotEmpty(device.getSpeedExp())) {
+//                    String speedExp = device.getSpeedExp().replace("${code}", device.getDeviceCode()) + " AS " + device.getDeviceId() + "_speed";
+//                    fieldList.add(speedExp);
+//                }
+//                if (StringUtils.isNotEmpty(device.getTmpExp())) {
+//                    String tmp = device.getTmpExp().replace("${code}", device.getDeviceCode()) + " AS " + device.getDeviceId() + "_tmp";
+//                    fieldList.add(tmp);
+//                }
+//                DyeingHourAvg energy = new DyeingHourAvg();
+//                energy.setDeviceId(device.getDeviceId());
+//                energy.setDataDate(DateUtils.toDate(date));
+//                energy.setHour(start.getHour());
+//                avgMap.put(device.getDeviceId(), energy);
+//            });
+//            String sql = "select %s from root.tl.suxi where time>%s and time <=%s";
+//            sql = String.format(sql, String.join(",", fieldList), DateUtils.parseIso(start), DateUtils.parseIso(end));
+//            iotService.query(sql);
+//            JSONObject jsonObject = iotService.query(sql);
+//            JSONObject data = jsonObject.getJSONObject("data");
+//            JSONArray values = data.getJSONArray("values");
+//            JSONArray columnNames = data.getJSONArray("columnNames");
+//            if (values.size() == 1) {
+//                JSONArray da = values.getJSONArray(0);
+//                for (int i = 0; i < da.size(); i++) {
+//                    String field = columnNames.getStr(i);
+//                    String[] split = field.split("_");
+//                    Long id = Long.parseLong(split[0]);
+//                    String type = split[1];
+//                    if (da.getDouble(i) != null) {
+//                        Double v = da.getDouble(i);
+//                        DyeingHourAvg energy = avgMap.get(id);
+//                        if ("length".equals(type)) {
+//                            energy.setLength(BigDecimal.valueOf(v));
+//                        }
+//                        if ("status".equals(type)) {
+//                            energy.setOnline(BigDecimal.valueOf(v).divide(BigDecimal.valueOf(1000), 0, RoundingMode.HALF_UP).longValue());
+//                        }
+//                        if ("speed".equals(type)) {
+//                            energy.setSpeed(BigDecimal.valueOf(v));
+//                        }
+//                        if ("tmp".equals(type)) {
+//                            energy.setTmp(BigDecimal.valueOf(v));
+//                        }
+//                    }
+//                }
+//            }
+//            List<DyeingHourAvg> dyeingHourEnergies = new ArrayList<>(avgMap.values());
+//
+//            try (SqlSession sqlSession = factory.openSession(ExecutorType.BATCH, false)) {
+//                if (dyeingHourEnergies.size() > 0) {
+//                    DyeingHourAvgMapper mapper = sqlSession.getMapper(DyeingHourAvgMapper.class);
+//                    dyeingHourEnergies.forEach(mapper::insertDyeingHourAvg);
+//                    sqlSession.commit();
+//                }
+//            }
+//        });
     }
 
     /**

+ 54 - 54
jjt-biz/src/main/java/com/jjt/dyeing/service/impl/DyeingHourEnergyServiceImpl.java

@@ -127,60 +127,60 @@ public class DyeingHourEnergyServiceImpl implements IDyeingHourEnergyService {
      */
     @Override
     public void calc(LocalDate date, int hour) {
-        LocalDateTime start = LocalDateTime.of(date, LocalTime.MIN).plusHours(hour);
-        LocalDateTime end = start.plusHours(1);
-        dyeingHourEnergyMapper.deleteByHour(DateUtils.toDate(date), hour);
-        Map<String, List<DyeingDevice>> deviceByLine = dyeingDeviceService.deviceByLine();
-        deviceByLine.forEach((line, devices) -> {
-            Map<Long, DyeingHourEnergy> energyMap = new HashMap<>();
-            List<String> fieldList = new ArrayList<>();
-            devices.forEach(device -> {
-                String energyExp = device.getEnergyExp() + " AS " + device.getDeviceId() + "_energy";
-                fieldList.add(energyExp);
-                String ampExp = device.getAmpExp() + " AS " + device.getDeviceId() + "_amp";
-                fieldList.add(ampExp);
-                DyeingHourEnergy energy = new DyeingHourEnergy();
-                energy.setDeviceId(device.getDeviceId());
-                energy.setDataDate(DateUtils.toDate(start.toLocalDate()));
-                energy.setHour(start.getHour());
-                energyMap.put(device.getDeviceId(), energy);
-            });
-            String sql = "select %s from root.tl.suxi where time>%s and time <=%s";
-            sql = String.format(sql, String.join(",", fieldList), DateUtils.parseIso(start), DateUtils.parseIso(end));
-            iotService.query(sql);
-            JSONObject jsonObject = iotService.query(sql);
-            JSONObject data = jsonObject.getJSONObject("data");
-            JSONArray values = data.getJSONArray("values");
-            JSONArray columnNames = data.getJSONArray("columnNames");
-            if (values.size() == 1) {
-                JSONArray da = values.getJSONArray(0);
-                for (int i = 0; i < da.size(); i++) {
-                    String field = columnNames.getStr(i);
-                    String[] split = field.split("_");
-                    Long id = Long.parseLong(split[0]);
-                    String type = split[1];
-                    if (da.getDouble(i) != null) {
-                        Double v = da.getDouble(i);
-                        DyeingHourEnergy energy = energyMap.get(id);
-                        if ("energy".equals(type)) {
-                            energy.setEnergy(BigDecimal.valueOf(v));
-                        }
-                        if ("amp".equals(type)) {
-                            energy.setAmp(BigDecimal.valueOf(v));
-                        }
-                    }
-                }
-            }
-            List<DyeingHourEnergy> dyeingHourEnergies = new ArrayList<>(energyMap.values());
-
-            try (SqlSession sqlSession = factory.openSession(ExecutorType.BATCH, false)) {
-                if (dyeingHourEnergies.size() > 0) {
-                    DyeingHourEnergyMapper mapper = sqlSession.getMapper(DyeingHourEnergyMapper.class);
-                    dyeingHourEnergies.forEach(mapper::insertDyeingHourEnergy);
-                    sqlSession.commit();
-                }
-            }
-        });
+//        LocalDateTime start = LocalDateTime.of(date, LocalTime.MIN).plusHours(hour);
+//        LocalDateTime end = start.plusHours(1);
+//        dyeingHourEnergyMapper.deleteByHour(DateUtils.toDate(date), hour);
+//        Map<String, List<DyeingDevice>> deviceByLine = dyeingDeviceService.deviceByLine();
+//        deviceByLine.forEach((line, devices) -> {
+//            Map<Long, DyeingHourEnergy> energyMap = new HashMap<>();
+//            List<String> fieldList = new ArrayList<>();
+//            devices.forEach(device -> {
+//                String energyExp = device.getEnergyExp() + " AS " + device.getDeviceId() + "_energy";
+//                fieldList.add(energyExp);
+//                String ampExp = device.getAmpExp() + " AS " + device.getDeviceId() + "_amp";
+//                fieldList.add(ampExp);
+//                DyeingHourEnergy energy = new DyeingHourEnergy();
+//                energy.setDeviceId(device.getDeviceId());
+//                energy.setDataDate(DateUtils.toDate(start.toLocalDate()));
+//                energy.setHour(start.getHour());
+//                energyMap.put(device.getDeviceId(), energy);
+//            });
+//            String sql = "select %s from root.tl.suxi where time>%s and time <=%s";
+//            sql = String.format(sql, String.join(",", fieldList), DateUtils.parseIso(start), DateUtils.parseIso(end));
+//            iotService.query(sql);
+//            JSONObject jsonObject = iotService.query(sql);
+//            JSONObject data = jsonObject.getJSONObject("data");
+//            JSONArray values = data.getJSONArray("values");
+//            JSONArray columnNames = data.getJSONArray("columnNames");
+//            if (values.size() == 1) {
+//                JSONArray da = values.getJSONArray(0);
+//                for (int i = 0; i < da.size(); i++) {
+//                    String field = columnNames.getStr(i);
+//                    String[] split = field.split("_");
+//                    Long id = Long.parseLong(split[0]);
+//                    String type = split[1];
+//                    if (da.getDouble(i) != null) {
+//                        Double v = da.getDouble(i);
+//                        DyeingHourEnergy energy = energyMap.get(id);
+//                        if ("energy".equals(type)) {
+//                            energy.setEnergy(BigDecimal.valueOf(v));
+//                        }
+//                        if ("amp".equals(type)) {
+//                            energy.setAmp(BigDecimal.valueOf(v));
+//                        }
+//                    }
+//                }
+//            }
+//            List<DyeingHourEnergy> dyeingHourEnergies = new ArrayList<>(energyMap.values());
+//
+//            try (SqlSession sqlSession = factory.openSession(ExecutorType.BATCH, false)) {
+//                if (dyeingHourEnergies.size() > 0) {
+//                    DyeingHourEnergyMapper mapper = sqlSession.getMapper(DyeingHourEnergyMapper.class);
+//                    dyeingHourEnergies.forEach(mapper::insertDyeingHourEnergy);
+//                    sqlSession.commit();
+//                }
+//            }
+//        });
     }
 
     /**

+ 45 - 32
jjt-biz/src/main/resources/mapper/dye/DyeCalcHourMapper.xml

@@ -1,48 +1,53 @@
 <?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.jjt.dye.mapper.DyeCalcHourMapper">
-    
+
     <resultMap type="DyeCalcHour" id="DyeCalcHourResult">
-        <result property="chId"    column="CH_ID"    />
-        <result property="dataDate"    column="DATA_DATE"    />
-        <result property="hour"    column="HOUR"    />
-        <result property="deviceId"    column="DEVICE_ID"    />
-        <result property="paraCode"    column="PARA_CODE"    />
-        <result property="paraName"    column="PARA_NAME"    />
-        <result property="paraValue"    column="PARA_VALUE"    />
-        <result property="paraMValue"    column="PARA_M_VALUE"    />
-        <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="chId" column="CH_ID"/>
+        <result property="dataDate" column="DATA_DATE"/>
+        <result property="hour" column="HOUR"/>
+        <result property="deviceId" column="DEVICE_ID"/>
+        <result property="paraCode" column="PARA_CODE"/>
+        <result property="paraName" column="PARA_NAME"/>
+        <result property="paraValue" column="PARA_VALUE"/>
+        <result property="paraMValue" column="PARA_M_VALUE"/>
+        <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="selectDyeCalcHourVo">
-        select CH_ID, DATA_DATE, HOUR, DEVICE_ID, PARA_CODE, PARA_NAME, PARA_VALUE, PARA_M_VALUE, CREATED_BY, CREATED_TIME, UPDATED_BY, UPDATED_TIME, REMARK from DYE_CALC_HOUR
+        select *
+        from (select a.*, b.device_name
+              from DYE_CALC_HOUR a,
+                   dye_device b
+              where a.device_id = b.device_id) t
     </sql>
 
     <select id="selectDyeCalcHourList" parameterType="DyeCalcHour" resultMap="DyeCalcHourResult">
         <include refid="selectDyeCalcHourVo"/>
-        <where>  
-            <if test="dataDate != null "> and DATA_DATE = #{dataDate}</if>
-            <if test="hour != null "> and HOUR = #{hour}</if>
-            <if test="deviceId != null "> and DEVICE_ID = #{deviceId}</if>
-            <if test="paraCode != null  and paraCode != ''"> and PARA_CODE = #{paraCode}</if>
-            <if test="paraName != null  and paraName != ''"> and PARA_NAME like concat('%', #{paraName}, '%')</if>
-            <if test="paraValue != null "> and PARA_VALUE = #{paraValue}</if>
-            <if test="paraMValue != null  and paraMValue != ''"> and PARA_M_VALUE = #{paraMValue}</if>
+        <where>
+            <if test="dataDate != null ">and DATA_DATE = #{dataDate}</if>
+            <if test="hour != null ">and HOUR = #{hour}</if>
+            <if test="deviceId != null ">and DEVICE_ID = #{deviceId}</if>
+            <if test="deviceName != null  and deviceName != ''">and device_name like concat('%', #{deviceName}, '%')</if>
+            <if test="paraCode != null  and paraCode != ''">and PARA_CODE = #{paraCode}</if>
+            <if test="paraName != null  and paraName != ''">and PARA_NAME like concat('%', #{paraName}, '%')</if>
+            <if test="paraValue != null ">and PARA_VALUE = #{paraValue}</if>
+            <if test="paraMValue != null  and paraMValue != ''">and PARA_M_VALUE = #{paraMValue}</if>
         </where>
     </select>
-    
+
     <select id="selectDyeCalcHourByChId" parameterType="Long" resultMap="DyeCalcHourResult">
         <include refid="selectDyeCalcHourVo"/>
         where CH_ID = #{chId}
     </select>
 
-    <insert id="insertDyeCalcHour" parameterType="DyeCalcHour" useGeneratedKeys="true" keyProperty="chId">
+    <insert id="insertDyeCalcHour" parameterType="DyeCalcHour">
         insert into DYE_CALC_HOUR
         <trim prefix="(" suffix=")" suffixOverrides=",">
             <if test="dataDate != null">DATA_DATE,</if>
@@ -57,7 +62,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <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="dataDate != null">#{dataDate},</if>
             <if test="hour != null">#{hour},</if>
@@ -71,7 +76,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="updatedBy != null">#{updatedBy},</if>
             <if test="updatedTime != null">#{updatedTime},</if>
             <if test="remark != null">#{remark},</if>
-         </trim>
+        </trim>
     </insert>
 
     <update id="updateDyeCalcHour" parameterType="DyeCalcHour">
@@ -94,13 +99,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </update>
 
     <delete id="deleteDyeCalcHourByChId" parameterType="Long">
-        delete from DYE_CALC_HOUR where CH_ID = #{chId}
+        delete
+        from DYE_CALC_HOUR
+        where CH_ID = #{chId}
     </delete>
 
     <delete id="deleteDyeCalcHourByChIds" parameterType="String">
-        delete from DYE_CALC_HOUR where CH_ID in 
+        delete from DYE_CALC_HOUR where CH_ID in
         <foreach item="chId" collection="array" open="(" separator="," close=")">
             #{chId}
         </foreach>
     </delete>
-</mapper>
+    <delete id="deleteByHour">
+        delete
+        from DYE_CALC_HOUR
+        where DATA_DATE = #{date}
+          and HOUR = #{hour}
+    </delete>
+</mapper>

+ 149 - 0
jjt-biz/src/main/resources/mapper/dye/DyeHourLineMapper.xml

@@ -0,0 +1,149 @@
+<?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">
+<mapper namespace="com.jjt.dye.mapper.DyeHourLineMapper">
+
+    <resultMap type="DyeHourLine" id="DyeHourLineResult">
+        <result property="hourLineId" column="HOUR_LINE_ID"/>
+        <result property="dataDate" column="DATA_DATE"/>
+        <result property="hour" column="HOUR"/>
+        <result property="line" column="LINE"/>
+        <result property="uptime" column="UPTIME"/>
+        <result property="length" column="LENGTH"/>
+        <result property="lengthM" column="LENGTH_M"/>
+        <result property="speed" column="SPEED"/>
+        <result property="speedM" column="SPEED_M"/>
+        <result property="energy" column="ENERGY"/>
+        <result property="energyM" column="ENERGY_M"/>
+        <result property="amp" column="AMP"/>
+        <result property="ampM" column="AMP_M"/>
+        <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="selectDyeHourLineVo">
+        select HOUR_LINE_ID,
+               DATA_DATE,
+               HOUR,
+               LINE,
+               UPTIME,
+               LENGTH,
+               LENGTH_M,
+               SPEED,
+               SPEED_M,
+               ENERGY,
+               ENERGY_M,
+               AMP,
+               AMP_M,
+               CREATED_BY,
+               CREATED_TIME,
+               UPDATED_BY,
+               UPDATED_TIME,
+               REMARK
+        from DYE_HOUR_LINE
+    </sql>
+
+    <select id="selectDyeHourLineList" parameterType="DyeHourLine" resultMap="DyeHourLineResult">
+        <include refid="selectDyeHourLineVo"/>
+        <where>
+            <if test="dataDate != null ">and DATA_DATE = #{dataDate}</if>
+            <if test="hour != null ">and HOUR = #{hour}</if>
+            <if test="line != null  and line != ''">and LINE = #{line}</if>
+            <if test="length != null ">and LENGTH = #{length}</if>
+        </where>
+    </select>
+
+    <select id="selectDyeHourLineByHourLineId" parameterType="Long" resultMap="DyeHourLineResult">
+        <include refid="selectDyeHourLineVo"/>
+        where HOUR_LINE_ID = #{hourLineId}
+    </select>
+
+    <insert id="insertDyeHourLine" parameterType="DyeHourLine" useGeneratedKeys="true" keyProperty="hourLineId">
+        insert into DYE_HOUR_LINE
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="dataDate != null">DATA_DATE,</if>
+            <if test="hour != null">HOUR,</if>
+            <if test="line != null">LINE,</if>
+            <if test="uptime != null">UPTIME,</if>
+            <if test="length != null">LENGTH,</if>
+            <if test="lengthM != null">LENGTH_M,</if>
+            <if test="speed != null">SPEED,</if>
+            <if test="speedM != null">SPEED_M,</if>
+            <if test="energy != null">ENERGY,</if>
+            <if test="energyM != null">ENERGY_M,</if>
+            <if test="amp != null">AMP,</if>
+            <if test="ampM != null">AMP_M,</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 prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="dataDate != null">#{dataDate},</if>
+            <if test="hour != null">#{hour},</if>
+            <if test="line != null">#{line},</if>
+            <if test="uptime != null">#{uptime},</if>
+            <if test="length != null">#{length},</if>
+            <if test="lengthM != null">#{lengthM},</if>
+            <if test="speed != null">#{speed},</if>
+            <if test="speedM != null">#{speedM},</if>
+            <if test="energy != null">#{energy},</if>
+            <if test="energyM != null">#{energyM},</if>
+            <if test="amp != null">#{amp},</if>
+            <if test="ampM != null">#{ampM},</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>
+    </insert>
+
+    <update id="updateDyeHourLine" parameterType="DyeHourLine">
+        update DYE_HOUR_LINE
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="dataDate != null">DATA_DATE = #{dataDate},</if>
+            <if test="hour != null">HOUR = #{hour},</if>
+            <if test="line != null">LINE = #{line},</if>
+            <if test="uptime != null">UPTIME = #{uptime},</if>
+            <if test="length != null">LENGTH = #{length},</if>
+            <if test="lengthM != null">LENGTH_M = #{lengthM},</if>
+            <if test="speed != null">SPEED = #{speed},</if>
+            <if test="speedM != null">SPEED_M = #{speedM},</if>
+            <if test="energy != null">ENERGY = #{energy},</if>
+            <if test="energyM != null">ENERGY_M = #{energyM},</if>
+            <if test="amp != null">AMP = #{amp},</if>
+            <if test="ampM != null">AMP_M = #{ampM},</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>
+            <if test="updatedTime != null">UPDATED_TIME = #{updatedTime},</if>
+            <if test="remark != null">REMARK = #{remark},</if>
+        </trim>
+        where HOUR_LINE_ID = #{hourLineId}
+    </update>
+
+    <delete id="deleteDyeHourLineByHourLineId" parameterType="Long">
+        delete
+        from DYE_HOUR_LINE
+        where HOUR_LINE_ID = #{hourLineId}
+    </delete>
+
+    <delete id="deleteDyeHourLineByHourLineIds" parameterType="String">
+        delete from DYE_HOUR_LINE where HOUR_LINE_ID in
+        <foreach item="hourLineId" collection="array" open="(" separator="," close=")">
+            #{hourLineId}
+        </foreach>
+    </delete>
+    <delete id="deleteByHour">
+        delete
+        from DYE_HOUR_LINE
+        where DATA_DATE = #{date}
+          and HOUR = #{hour}
+    </delete>
+</mapper>