Pārlūkot izejas kodu

搞定工艺模型

wukai 2 mēneši atpakaļ
vecāks
revīzija
b57430361b

+ 71 - 0
jjt-admin/src/test/java/com/jjt/dye/LeanFanTest.java

@@ -0,0 +1,71 @@
+package com.jjt.dye;
+
+import com.jjt.JjtApplication;
+import com.jjt.dye.service.IDyeCalcHourService;
+import com.jjt.dye.service.IDyeHourLineService;
+import com.jjt.lean.service.ILeanFanService;
+import com.jjt.utils.IotService;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+
+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)
+//@ActiveProfiles("devp")
+public class LeanFanTest {
+    @Resource
+    private IotService iotService;
+    @Resource
+    private ILeanFanService leanFanService;
+    @Resource
+    private IDyeHourLineService hourLineService;
+    String st = "2025-12-01";
+    String ed = "2025-12-04";
+    LocalDate localDate = LocalDate.parse(st);
+    LocalDate endDate = LocalDate.parse(ed);
+    LocalDateTime start = LocalDateTime.of(localDate, LocalTime.MIN).plusHours(0);
+
+    @Test
+    public void calc() {
+        iotService.setToken();
+//        leanFanService.calc(start.toLocalDate(), 15);
+        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);
+            leanFanService.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));
+    }
+}

+ 5 - 0
jjt-admin/src/test/java/com/jjt/rziot/Test.java

@@ -8,6 +8,11 @@ package com.jjt.rziot;
  */
 public class Test {
     public static void main(String[] args) {
+
+        for (int i = 0; i < 54; i++) {
+            System.err.println(i+": "+i/6);
+
+        }
         for (String machineName : machineNames) {
             String[] tmp = machineName.split("_");
             String line = tmp[1].replace("线", "");

+ 14 - 3
jjt-biz/src/main/java/com/jjt/calc/service/ITwinCalcHourSpecService.java

@@ -1,10 +1,11 @@
 package com.jjt.calc.service;
 
-import java.util.Date;
-import java.util.List;
 import com.jjt.calc.domain.TwinCalcHourSpec;
 import com.jjt.calc.vo.SpecVO;
 
+import java.util.Date;
+import java.util.List;
+
 /**
  * 按配方1小时统计数据Service接口
  *
@@ -59,6 +60,7 @@ public interface ITwinCalcHourSpecService {
      * @return 结果
      */
     public int deleteTwinCalcHourSpecById(Long id);
+
     /**
      * 根据日期获取统计数据
      *
@@ -66,10 +68,19 @@ public interface ITwinCalcHourSpecService {
      * @return 结果
      */
     List<TwinCalcHourSpec> selectTwinCalcHourSpecListByDate(Date date);
+    /**
+     * 根据日期获取统计数据
+     *
+     * @param start 开始时间
+     * @param end 结束时间
+     * @return 结果
+     */
+    List<TwinCalcHourSpec> selectTwinCalcHourSpecListByDate(Date start, Date end);
 
     /**
      * 根据毛高查询月月数据
-     * @param month 时间
+     *
+     * @param month  时间
      * @param height 毛高
      * @return 结果
      */

+ 19 - 2
jjt-biz/src/main/java/com/jjt/calc/service/impl/TwinCalcHourSpecServiceImpl.java

@@ -115,14 +115,31 @@ public class TwinCalcHourSpecServiceImpl implements ITwinCalcHourSpecService {
     }
 
     /**
+     * 根据日期获取统计数据
+     *
+     * @param start 开始时间
+     * @param end 结束时间
+     * @return 结果
+     */
+    @Override
+    public List<TwinCalcHourSpec> selectTwinCalcHourSpecListByDate(Date start, Date end) {
+        TwinCalcHourSpec hour = new TwinCalcHourSpec();
+        Map<String, Object> params = new HashMap<>(16);
+        params.put("sTime", start);
+        params.put("eTime", end);
+        hour.setParams(params);
+        return selectTwinCalcHourSpecList(hour);
+    }
+
+    /**
      * 根据毛高查询月月数据
      *
-     * @param month   时间
+     * @param month  时间
      * @param height 毛高
      * @return 结果
      */
     @Override
     public List<SpecVO> selectSpec(String month, Float height) {
-        return twinCalcHourSpecMapper.selectSpec(month,height);
+        return twinCalcHourSpecMapper.selectSpec(month, height);
     }
 }

+ 113 - 0
jjt-biz/src/main/java/com/jjt/lean/controller/LeanFanController.java

@@ -0,0 +1,113 @@
+package com.jjt.lean.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.lean.domain.LeanFan;
+import com.jjt.lean.service.ILeanFanService;
+import com.jjt.common.utils.poi.ExcelUtil;
+import com.jjt.common.core.page.TableDataInfo;
+
+/**
+ * 空气压力数据Controller
+ *
+ * @author wukai
+ * @date 2025-12-04
+ */
+@Api(tags="空气压力数据")
+@RestController
+@RequestMapping("/lean/fan")
+public class LeanFanController extends BaseController{
+    @Resource
+    private ILeanFanService leanFanService;
+
+    /**
+     * 查询空气压力数据列表
+     */
+    @ApiOperation("查询空气压力数据列表")
+    //@PreAuthorize("@ss.hasPermi('lean:fan:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LeanFan leanFan)
+    {
+        startPage();
+        List<LeanFan> list = leanFanService.selectLeanFanList(leanFan);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出空气压力数据列表
+     */
+    @ApiOperation("导出空气压力数据列表")
+    //@PreAuthorize("@ss.hasPermi('lean:fan:export')")
+    @Log(title = "空气压力数据", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, LeanFan leanFan)
+    {
+        List<LeanFan> list = leanFanService.selectLeanFanList(leanFan);
+        ExcelUtil<LeanFan> util = new ExcelUtil<LeanFan>(LeanFan.class);
+        util.exportExcel(response, list, "空气压力数据数据");
+    }
+
+    /**
+     * 获取空气压力数据详细信息
+     */
+    @ApiOperation("获取空气压力数据详细信息")
+    //@PreAuthorize("@ss.hasPermi('lean:fan:query')")
+    @GetMapping(value = "/{recordId}")
+    public AjaxResult getInfo(@PathVariable("recordId") Long recordId)
+    {
+        return success(leanFanService.selectLeanFanByRecordId(recordId));
+    }
+
+    /**
+     * 新增空气压力数据
+     */
+    @ApiOperation("新增空气压力数据")
+    //@PreAuthorize("@ss.hasPermi('lean:fan:add')")
+    @Log(title = "空气压力数据", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LeanFan leanFan)
+    {
+        return toAjax(leanFanService.insertLeanFan(leanFan));
+    }
+
+    /**
+     * 修改空气压力数据
+     */
+    @ApiOperation("修改空气压力数据")
+    //@PreAuthorize("@ss.hasPermi('lean:fan:edit')")
+    @Log(title = "空气压力数据", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LeanFan leanFan)
+    {
+        return toAjax(leanFanService.updateLeanFan(leanFan));
+    }
+
+    /**
+     * 删除空气压力数据
+     */
+    @ApiOperation("删除空气压力数据")
+    //@PreAuthorize("@ss.hasPermi('lean:fan:remove')")
+    @Log(title = "空气压力数据", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{recordIds}")
+    public AjaxResult remove(@PathVariable Long[] recordIds)
+    {
+        return toAjax(leanFanService.deleteLeanFanByRecordIds(recordIds));
+    }
+}

+ 207 - 0
jjt-biz/src/main/java/com/jjt/lean/controller/LeanMaoGaoController.java

@@ -0,0 +1,207 @@
+package com.jjt.lean.controller;
+
+import com.jjt.calc.domain.TwinCalcHour;
+import com.jjt.calc.domain.TwinCalcHourSpec;
+import com.jjt.calc.service.ITwinCalcHourService;
+import com.jjt.calc.service.ITwinCalcHourSpecService;
+import com.jjt.common.core.controller.BaseController;
+import com.jjt.common.core.page.TableDataInfo;
+import com.jjt.lean.vo.MaogaoVO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.YearMonth;
+import java.util.*;
+
+/**
+ * 查询毛高能耗关系Controller
+ *
+ * @author wukai
+ * @date 2025-12-04
+ */
+@Api(tags = "查询毛高能耗关系")
+@RestController
+@RequestMapping("/lean/maogao")
+public class LeanMaoGaoController extends BaseController {
+    @Resource
+    private ITwinCalcHourService calcService;
+    @Resource
+    private ITwinCalcHourSpecService specService;
+
+    @ApiOperation("查询毛高能耗关系")
+    @GetMapping("/list")
+    public TableDataInfo list(MaogaoVO maogao) {
+        startPage();
+
+        // 将Date转换为LocalDate以获取年月信息
+        LocalDate localDate = maogao.getDataDate().toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDate();
+        YearMonth yearMonth = YearMonth.from(localDate);
+
+        // 设置start为当月第一天的0点
+        LocalDate firstDay = yearMonth.atDay(1);
+        LocalDateTime startDateTime = LocalDateTime.of(firstDay, LocalTime.MIDNIGHT);
+        Date start = Date.from(startDateTime.atZone(java.time.ZoneId.systemDefault()).toInstant());
+
+        // 设置end为当月最后一天的23:59:59
+        LocalDate lastDay = yearMonth.atEndOfMonth();
+        LocalDateTime endDateTime = LocalDateTime.of(lastDay, LocalTime.MAX);
+        Date end = Date.from(endDateTime.atZone(java.time.ZoneId.systemDefault()).toInstant());
+        Map<String, Object> params = new HashMap<>(16);
+        params.put("sTime", start);
+        params.put("eTime", end);
+        List<MaogaoVO> list = new ArrayList<>();
+        TwinCalcHour query = new TwinCalcHour();
+        query.setDeviceId(maogao.getDeviceId());
+        query.setParams(params);
+        List<TwinCalcHour> hourList = calcService.selectTwinCalcHourList(query);
+        TwinCalcHourSpec querySpec = new TwinCalcHourSpec();
+        querySpec.setDeviceId(maogao.getDeviceId());
+        querySpec.setParams(params);
+        List<TwinCalcHourSpec> specList = specService.selectTwinCalcHourSpecList(querySpec);
+
+        // 创建一个Map来存储specList,以(dataDate,hour,deviceId)作为key,提高查找效率
+        Map<String, TwinCalcHourSpec> specMap = new HashMap<>();
+        for (TwinCalcHourSpec spec : specList) {
+            String key = spec.getDataDate().toString() + "_" + spec.getHour() + "_" + spec.getDeviceId();
+            specMap.put(key, spec);
+        }
+
+        // 以hourList为准,遍历构建MaogaoVO列表
+        for (TwinCalcHour hour : hourList) {
+            if (hour.getKwh().compareTo(BigDecimal.ZERO) == 0) {
+                continue;
+            }
+            MaogaoVO vo = new MaogaoVO();
+            // 从hourList设置基础属性
+            vo.setDataDate(hour.getDataDate());
+            vo.setHour(hour.getHour());
+            vo.setDeviceId(hour.getDeviceId());
+            vo.setLength(hour.getLength());
+            vo.setKwh(hour.getKwh());
+
+            // 从specMap中直接查找匹配的记录,获取毛高和密度
+            String key = hour.getDataDate().toString() + "_" + hour.getHour() + "_" + hour.getDeviceId();
+            TwinCalcHourSpec spec = specMap.get(key);
+            if (spec != null) {
+                vo.setHeight(spec.getHeight());
+                vo.setDensity(spec.getDensity());
+            }
+            list.add(vo);
+        }
+        //结果需要按dataDate和hour倒序
+        list.sort(Comparator.comparing(MaogaoVO::getDataDate).reversed()
+                .thenComparing(Comparator.comparing(MaogaoVO::getHour).reversed()));
+        return getDataTable(list);
+    }
+
+    @ApiOperation("查询毛高能耗关系")
+    @GetMapping("/calc")
+    public TableDataInfo calc(MaogaoVO maogao) {
+        // 将Date转换为LocalDate以获取年月信息
+        LocalDate localDate = maogao.getDataDate().toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDate();
+        YearMonth yearMonth = YearMonth.from(localDate);
+
+        // 设置start为当月第一天的0点
+        LocalDate firstDay = yearMonth.atDay(1);
+        LocalDateTime startDateTime = LocalDateTime.of(firstDay, LocalTime.MIDNIGHT);
+        Date start = Date.from(startDateTime.atZone(java.time.ZoneId.systemDefault()).toInstant());
+
+        // 设置end为当月最后一天的23:59:59
+        LocalDate lastDay = yearMonth.atEndOfMonth();
+        LocalDateTime endDateTime = LocalDateTime.of(lastDay, LocalTime.MAX);
+        Date end = Date.from(endDateTime.atZone(java.time.ZoneId.systemDefault()).toInstant());
+
+        List<MaogaoVO> list = new ArrayList<>();
+        List<TwinCalcHour> hourList = calcService.selectTwinCalcHourListByDate(start, end);
+        List<TwinCalcHourSpec> specList = specService.selectTwinCalcHourSpecListByDate(start, end);
+
+        // 创建一个Map来存储specList,以(dataDate,hour,deviceId)作为key,提高查找效率
+        Map<String, TwinCalcHourSpec> specMap = new HashMap<>();
+        for (TwinCalcHourSpec spec : specList) {
+            String key = spec.getDataDate().toString() + "_" + spec.getHour() + "_" + spec.getDeviceId();
+            specMap.put(key, spec);
+        }
+
+        // 以hourList为准,遍历构建MaogaoVO列表
+        for (TwinCalcHour hour : hourList) {
+            MaogaoVO vo = new MaogaoVO();
+            // 从hourList设置基础属性
+            vo.setDataDate(hour.getDataDate());
+            vo.setHour(hour.getHour());
+            vo.setDeviceId(hour.getDeviceId());
+            vo.setLength(hour.getLength());
+            vo.setKwh(hour.getKwh());
+
+            // 从specMap中直接查找匹配的记录,获取毛高和密度
+            String key = hour.getDataDate().toString() + "_" + hour.getHour() + "_" + hour.getDeviceId();
+            TwinCalcHourSpec spec = specMap.get(key);
+            if (spec != null) {
+                vo.setHeight(spec.getHeight());
+                vo.setDensity(spec.getDensity());
+            }
+
+            list.add(vo);
+        }
+
+        // 按照dataDate、hour和height分组,统计每小时的电量kwh和织造米数
+        Map<String, Double> groupedKwh = new HashMap<>();
+        Map<String, Double> groupedLength = new HashMap<>();
+        Map<String, MaogaoVO> groupedData = new HashMap<>();
+
+        for (MaogaoVO vo : list) {
+            // 过滤掉height为0的记录
+            if (vo.getHeight() == null || vo.getHeight().compareTo(BigDecimal.ZERO) == 0) {
+                continue;
+            }
+
+            // 创建分组key: dataDate_hour_height
+            String groupKey = vo.getDataDate().toString() + "_" + vo.getHour() + "_" + vo.getHeight();
+
+            // 累计kwh值
+            groupedKwh.merge(groupKey, vo.getKwh() != null ? vo.getKwh().doubleValue() : 0.0, Double::sum);
+
+            // 累计织造米数
+            groupedLength.merge(groupKey, vo.getLength() != null ? vo.getLength().doubleValue() : 0.0, Double::sum);
+
+            // 保存该分组的一个代表对象
+            groupedData.put(groupKey, vo);
+        }
+
+        // 形成一个新的list
+        List<MaogaoVO> resultList = new ArrayList<>();
+        for (Map.Entry<String, Double> entry : groupedKwh.entrySet()) {
+            String groupKey = entry.getKey();
+            Double totalKwh = entry.getValue();
+            Double totalLength = groupedLength.get(groupKey);
+            // 获取累计的织造米数
+            // 获取分组代表对象并更新kwh值
+            MaogaoVO originalVo = groupedData.get(groupKey);
+            MaogaoVO newVo = new MaogaoVO();
+            newVo.setDataDate(originalVo.getDataDate());
+            newVo.setHour(originalVo.getHour());
+            newVo.setDeviceId(originalVo.getDeviceId());
+            newVo.setLength(BigDecimal.valueOf(totalLength));
+            // 使用累计的织造米数
+            newVo.setHeight(originalVo.getHeight());
+            newVo.setDensity(originalVo.getDensity());
+            newVo.setKwh(BigDecimal.valueOf(totalKwh));
+            // 使用累计的kwh值
+            if (newVo.getKwh().compareTo(BigDecimal.ZERO) > 0) {
+                resultList.add(newVo);
+            }
+        }
+
+        //结果需要按dataDate和hour倒序
+        resultList.sort(Comparator.comparing(MaogaoVO::getDataDate).reversed()
+                .thenComparing(Comparator.comparing(MaogaoVO::getHour).reversed()));
+        return getDataTable(resultList);
+    }
+}

+ 103 - 0
jjt-biz/src/main/java/com/jjt/lean/domain/LeanFan.java

@@ -0,0 +1,103 @@
+package com.jjt.lean.domain;
+
+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 java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 空气压力数据对象 LEAN_FAN
+ *
+ * @author wukai
+ * @date 2025-12-04
+ */
+@ApiModel(value = "LeanFan", description = "空气压力数据")
+@Data
+public class LeanFan extends BaseEntity {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * ID
+     */
+    @ApiModelProperty("ID")
+    @TableId
+    private Long recordId;
+
+    /**
+     * 记录时间
+     */
+    @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 type;
+
+    /**
+     * 空压机ID
+     */
+    @ApiModelProperty("空压机ID")
+    @Excel(name = "空压机ID")
+    private Integer fanId;
+
+    /**
+     * 排气压力
+     */
+    @ApiModelProperty("排气压力")
+    @Excel(name = "排气压力")
+    private BigDecimal press;
+
+    /**
+     * 排气温度
+     */
+    @ApiModelProperty("排气温度")
+    @Excel(name = "排气温度")
+    private BigDecimal temp;
+
+    /**
+     * 风机功率
+     */
+    @ApiModelProperty("风机功率")
+    @Excel(name = "风机功率")
+    private BigDecimal power;
+
+    /**
+     * 风机电流
+     */
+    @ApiModelProperty("风机电流")
+    @Excel(name = "风机电流")
+    private BigDecimal amp;
+
+    /**
+     * 风机电压
+     */
+    @ApiModelProperty("风机电压")
+    @Excel(name = "风机电压")
+    private BigDecimal voltage;
+
+    /**
+     * 电量
+     */
+    @ApiModelProperty("电量")
+    @Excel(name = "电量")
+    private BigDecimal energy;
+
+}

+ 71 - 0
jjt-biz/src/main/java/com/jjt/lean/mapper/LeanFanMapper.java

@@ -0,0 +1,71 @@
+package com.jjt.lean.mapper;
+
+import java.util.Date;
+import java.util.List;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.jjt.lean.domain.LeanFan;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * 空气压力数据Mapper接口
+ *
+ * @author wukai
+ * @date 2025-12-04
+ */
+public interface LeanFanMapper extends BaseMapper<LeanFan>
+{
+    /**
+     * 查询空气压力数据
+     *
+     * @param recordId 空气压力数据主键
+     * @return 空气压力数据
+     */
+    public LeanFan selectLeanFanByRecordId(Long recordId);
+
+    /**
+     * 查询空气压力数据列表
+     *
+     * @param leanFan 空气压力数据
+     * @return 空气压力数据集合
+     */
+    public List<LeanFan> selectLeanFanList(LeanFan leanFan);
+
+    /**
+     * 新增空气压力数据
+     *
+     * @param leanFan 空气压力数据
+     * @return 结果
+     */
+    public int insertLeanFan(LeanFan leanFan);
+
+    /**
+     * 修改空气压力数据
+     *
+     * @param leanFan 空气压力数据
+     * @return 结果
+     */
+    public int updateLeanFan(LeanFan leanFan);
+
+    /**
+     * 删除空气压力数据
+     *
+     * @param recordId 空气压力数据主键
+     * @return 结果
+     */
+    public int deleteLeanFanByRecordId(Long recordId);
+
+    /**
+     * 批量删除空气压力数据
+     *
+     * @param recordIds 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteLeanFanByRecordIds(Long[] recordIds);
+    /**
+     * 删除指定日期指定时段数据
+     *
+     * @param date 指定日期
+     * @param hour   时段
+     */
+    void deleteLeanFan(@Param("date") Date date, @Param("hour") int hour);
+}

+ 84 - 0
jjt-biz/src/main/java/com/jjt/lean/service/ILeanFanService.java

@@ -0,0 +1,84 @@
+package com.jjt.lean.service;
+
+import com.jjt.lean.domain.LeanFan;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 空气压力数据Service接口
+ *
+ * @author wukai
+ * @date 2025-12-04
+ */
+public interface ILeanFanService {
+    /**
+     * 查询空气压力数据
+     *
+     * @param recordId 空气压力数据主键
+     * @return 空气压力数据
+     */
+    public LeanFan selectLeanFanByRecordId(Long recordId);
+
+    /**
+     * 查询空气压力数据列表
+     *
+     * @param leanFan 空气压力数据
+     * @return 空气压力数据集合
+     */
+    public List<LeanFan> selectLeanFanList(LeanFan leanFan);
+
+    /**
+     * 新增空气压力数据
+     *
+     * @param leanFan 空气压力数据
+     * @return 结果
+     */
+    public int insertLeanFan(LeanFan leanFan);
+
+    /**
+     * 修改空气压力数据
+     *
+     * @param leanFan 空气压力数据
+     * @return 结果
+     */
+    public int updateLeanFan(LeanFan leanFan);
+
+    /**
+     * 批量删除空气压力数据
+     *
+     * @param recordIds 需要删除的空气压力数据主键集合
+     * @return 结果
+     */
+    public int deleteLeanFanByRecordIds(Long[] recordIds);
+
+    /**
+     * 删除空气压力数据信息
+     *
+     * @param recordId 空气压力数据主键
+     * @return 结果
+     */
+    public int deleteLeanFanByRecordId(Long recordId);
+
+    /**
+     * 统计指定日期指定时段数据
+     *
+     * @param date   指定日期 yyyy-mm-dd
+     * @param period 时段
+     */
+    void calc(LocalDate date, int period);
+
+    /**
+     * 统计上一时段数据
+     */
+    void last();
+
+    /**
+     * 按指定时间统计
+     *
+     * @param start 开始时间
+     * @param end   结束时间
+     */
+    void calc(LocalDateTime start, LocalDateTime end);
+}

+ 272 - 0
jjt-biz/src/main/java/com/jjt/lean/service/impl/LeanFanServiceImpl.java

@@ -0,0 +1,272 @@
+package com.jjt.lean.service.impl;
+
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
+import com.jjt.common.utils.DateUtils;
+import com.jjt.lean.domain.LeanFan;
+import com.jjt.lean.mapper.LeanFanMapper;
+import com.jjt.lean.service.ILeanFanService;
+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.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.*;
+
+/**
+ * 空气压力数据Service业务层处理
+ *
+ * @author wukai
+ * @date 2025-12-04
+ */
+@Service
+public class LeanFanServiceImpl implements ILeanFanService {
+    @Resource
+    private LeanFanMapper leanFanMapper;
+    @Resource
+    private SqlSessionFactory factory;
+    @Resource
+    private IotService iotService;
+
+    /**
+     * 查询空气压力数据
+     *
+     * @param recordId 空气压力数据主键
+     * @return 空气压力数据
+     */
+    @Override
+    public LeanFan selectLeanFanByRecordId(Long recordId) {
+        return leanFanMapper.selectLeanFanByRecordId(recordId);
+    }
+
+    /**
+     * 查询空气压力数据列表
+     *
+     * @param leanFan 空气压力数据
+     * @return 空气压力数据
+     */
+    @Override
+    public List<LeanFan> selectLeanFanList(LeanFan leanFan) {
+        return leanFanMapper.selectLeanFanList(leanFan);
+    }
+
+    /**
+     * 新增空气压力数据
+     *
+     * @param leanFan 空气压力数据
+     * @return 结果
+     */
+    @Override
+    public int insertLeanFan(LeanFan leanFan) {
+        leanFan.setCreateTime(DateUtils.getNowDate());
+        return leanFanMapper.insertLeanFan(leanFan);
+    }
+
+    /**
+     * 修改空气压力数据
+     *
+     * @param leanFan 空气压力数据
+     * @return 结果
+     */
+    @Override
+    public int updateLeanFan(LeanFan leanFan) {
+        leanFan.setUpdateTime(DateUtils.getNowDate());
+        return leanFanMapper.updateLeanFan(leanFan);
+    }
+
+    /**
+     * 批量删除空气压力数据
+     *
+     * @param recordIds 需要删除的空气压力数据主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLeanFanByRecordIds(Long[] recordIds) {
+        return leanFanMapper.deleteLeanFanByRecordIds(recordIds);
+    }
+
+    /**
+     * 删除空气压力数据信息
+     *
+     * @param recordId 空气压力数据主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLeanFanByRecordId(Long recordId) {
+        return leanFanMapper.deleteLeanFanByRecordId(recordId);
+    }
+
+    /**
+     * 统计指定日期指定时段数据
+     *
+     * @param date   指定日期 yyyy-mm-dd
+     * @param period 时段
+     */
+    @Override
+    public void calc(LocalDate date, int period) {
+        LocalDateTime ldt = LocalDateTime.of(date, LocalTime.MIN);
+        LocalDateTime start = ldt.plusHours(period);
+        LocalDateTime end = start.plusHours(1);
+        calc(start, end);
+    }
+
+    /**
+     * 统计上一时段数据
+     */
+    @Override
+    public void last() {
+        LocalDateTime ldt = Tools.currWholeTime();
+        //上一个小时
+        ldt = ldt.minusHours(1);
+        LocalDateTime start = ldt;
+        LocalDateTime end = ldt.plusHours(1);
+        calc(start, end);
+    }
+
+    /**
+     * 按指定时间统计
+     *
+     * @param start 开始时间
+     * @param end   结束时间
+     */
+    @Override
+    public void calc(LocalDateTime start, LocalDateTime end) {
+        //先删除当前时段的统计数据
+        deleteLeanFan(DateUtils.toDate(start.toLocalDate()), start.getHour());
+        process(start, end);
+    }
+
+    /**
+     * 删除指定日期指定时段数据
+     *
+     * @param date 指定日期
+     * @param hour 时段
+     */
+    private void deleteLeanFan(Date date, int hour) {
+        leanFanMapper.deleteLeanFan(date, hour);
+    }
+
+    private void process(LocalDateTime start, LocalDateTime end) {
+        List<String> paraFields = new ArrayList<>();
+        paraFields.add("AVG(aircompressorwLowF2_totalControl.Capacity_data_7) AS low_1_1");
+        paraFields.add("AVG(aircompressorwLowF2_totalControl.Capacity_data_10) AS low_1_2");
+        paraFields.add("AVG(aircompressorwLowF2_totalControl.Capacity_data_5) AS low_1_3");
+        paraFields.add("AVG(aircompressorwLowF2_totalControl.Capacity_data_4) AS low_1_4");
+        paraFields.add("AVG(aircompressorwLowF2_totalControl.Capacity_data_12) AS low_1_5");
+        paraFields.add("SUM(DIFF(aircompressorwLowF2_totalControl.Capacity_data_15)) AS low_1_6");
+        paraFields.add("AVG(aircompressorwLowF2_totalControl.Capacity_data_24) AS low_2_1");
+        paraFields.add("AVG(aircompressorwLowF2_totalControl.Capacity_data_27) AS low_2_2");
+        paraFields.add("AVG(aircompressorwLowF2_totalControl.Capacity_data_22) AS low_2_3");
+        paraFields.add("AVG(aircompressorwLowF2_totalControl.Capacity_data_21) AS low_2_4");
+        paraFields.add("AVG(aircompressorwLowF2_totalControl.Capacity_data_29) AS low_2_5");
+        paraFields.add("SUM(DIFF(aircompressorwLowF2_totalControl.Capacity_data_32)) AS low_2_6");
+        paraFields.add("AVG(aircompressorwLowF2_totalControl.Capacity_data_41) AS low_3_1");
+        paraFields.add("AVG(aircompressorwLowF2_totalControl.Capacity_data_44) AS low_3_2");
+        paraFields.add("AVG(aircompressorwLowF2_totalControl.Capacity_data_39) AS low_3_3");
+        paraFields.add("AVG(aircompressorwLowF2_totalControl.Capacity_data_38) AS low_3_4");
+        paraFields.add("AVG(aircompressorwLowF2_totalControl.Capacity_data_46) AS low_3_5");
+        paraFields.add("SUM(DIFF(aircompressorwLowF2_totalControl.Capacity_data_49)) AS low_3_6");
+        paraFields.add("AVG(aircompressorwLowF2_totalControl.Capacity_data_58) AS low_4_1");
+        paraFields.add("AVG(aircompressorwLowF2_totalControl.Capacity_data_61) AS low_4_2");
+        paraFields.add("AVG(aircompressorwLowF2_totalControl.Capacity_data_56) AS low_4_3");
+        paraFields.add("AVG(aircompressorwLowF2_totalControl.Capacity_data_55) AS low_4_4");
+        paraFields.add("AVG(aircompressorwLowF2_totalControl.Capacity_data_63) AS low_4_5");
+        paraFields.add("SUM(DIFF(aircompressorwLowF2_totalControl.Capacity_data_66)) AS low_4_6");
+        paraFields.add("AVG(aircompressorwF3_totalControl.Capacity_data_21) AS mid_1_1");
+        paraFields.add("AVG(aircompressorwF3_totalControl.Capacity_data_26) AS mid_1_2");
+        paraFields.add("AVG(aircompressorwF3_totalControl.Capacity_data_46) AS mid_1_3");
+        paraFields.add("AVG(aircompressorwF3_totalControl.Capacity_data_36) AS mid_1_4");
+        paraFields.add("AVG(aircompressorwF3_totalControl.Capacity_data_41) AS mid_1_5");
+        paraFields.add("SUM(DIFF(aircompressorwF3_totalControl.Capacity_data_86)) AS mid_1_6");
+        paraFields.add("AVG(aircompressorwF3_totalControl.Capacity_data_22) AS mid_2_1");
+        paraFields.add("AVG(aircompressorwF3_totalControl.Capacity_data_27) AS mid_2_2");
+        paraFields.add("AVG(aircompressorwF3_totalControl.Capacity_data_47) AS mid_2_3");
+        paraFields.add("AVG(aircompressorwF3_totalControl.Capacity_data_37) AS mid_2_4");
+        paraFields.add("AVG(aircompressorwF3_totalControl.Capacity_data_42) AS mid_2_5");
+        paraFields.add("SUM(DIFF(aircompressorwF3_totalControl.Capacity_data_87)) AS mid_2_6");
+        paraFields.add("AVG(aircompressorwF3_totalControl.Capacity_data_23) AS mid_3_1");
+        paraFields.add("AVG(aircompressorwF3_totalControl.Capacity_data_28) AS mid_3_2");
+        paraFields.add("AVG(aircompressorwF3_totalControl.Capacity_data_48) AS mid_3_3");
+        paraFields.add("AVG(aircompressorwF3_totalControl.Capacity_data_38) AS mid_3_4");
+        paraFields.add("AVG(aircompressorwF3_totalControl.Capacity_data_43) AS mid_3_5");
+        paraFields.add("SUM(DIFF(aircompressorwF3_totalControl.Capacity_data_88)) AS mid_3_6");
+        paraFields.add("AVG(aircompressorwF3_totalControl.Capacity_data_24) AS mid_4_1");
+        paraFields.add("AVG(aircompressorwF3_totalControl.Capacity_data_29) AS mid_4_2");
+        paraFields.add("AVG(aircompressorwF3_totalControl.Capacity_data_49) AS mid_4_3");
+        paraFields.add("AVG(aircompressorwF3_totalControl.Capacity_data_39) AS mid_4_4");
+        paraFields.add("AVG(aircompressorwF3_totalControl.Capacity_data_44) AS mid_4_5");
+        paraFields.add("SUM(DIFF(aircompressorwF3_totalControl.Capacity_data_89)) AS mid_4_6");
+        paraFields.add("AVG(aircompressorwF3_totalControl.Capacity_data_25) AS mid_5_1");
+        paraFields.add("AVG(aircompressorwF3_totalControl.Capacity_data_30) AS mid_5_2");
+        paraFields.add("AVG(aircompressorwF3_totalControl.Capacity_data_50) AS mid_5_3");
+        paraFields.add("AVG(aircompressorwF3_totalControl.Capacity_data_40) AS mid_5_4");
+        paraFields.add("AVG(aircompressorwF3_totalControl.Capacity_data_45) AS mid_5_5");
+        paraFields.add("SUM(DIFF(aircompressorwF3_totalControl.Capacity_data_90)) AS mid_5_6");
+        String sql = "select %s from root.tl.suxi where time>=%s and time <=%s";
+        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) {
+            Map<String, LeanFan> map = new HashMap<>();
+            JSONArray da = values.getJSONArray(0);
+            for (int i = 0; i < da.size(); i++) {
+                String field = columnNames.getStr(i);
+                String[] tmp = field.split("_");
+                String key = tmp[0] + "_" + tmp[1];
+                LeanFan fan = map.get(key);
+                if (fan == null) {
+                    fan = new LeanFan();
+                    fan.setType(tmp[0]);
+                    fan.setDataDate(DateUtils.toDate(start.toLocalDate()));
+                    fan.setHour(start.getHour());
+                    fan.setFanId(Integer.parseInt(tmp[1]));
+                    map.put(key, fan);
+                }
+                switch (tmp[2]) {
+                    case "1":
+                        fan.setPress(da.getBigDecimal(i));
+                        break;
+                    case "2":
+                        fan.setTemp(da.getBigDecimal(i));
+                        break;
+                    case "3":
+                        fan.setPower(da.getBigDecimal(i));
+                        break;
+                    case "4":
+                        fan.setAmp(da.getBigDecimal(i));
+                        break;
+                    case "5":
+                        fan.setVoltage(da.getBigDecimal(i));
+                        break;
+                    case "6":
+                        fan.setEnergy(da.getBigDecimal(i));
+                        break;
+                    default:
+                        break;
+                }
+            }
+
+            List<LeanFan> list = new ArrayList<>(map.values());
+
+            try (SqlSession sqlSession = factory.openSession(ExecutorType.BATCH, false)) {
+                if (list.size() > 0) {
+                    LeanFanMapper mapper = sqlSession.getMapper(LeanFanMapper.class);
+                    list.forEach(mapper::insertLeanFan);
+                    sqlSession.commit();
+                }
+            }
+        }
+    }
+}
+
+

+ 38 - 0
jjt-biz/src/main/java/com/jjt/lean/vo/MaogaoVO.java

@@ -0,0 +1,38 @@
+package com.jjt.lean.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.jjt.common.annotation.Excel;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.*;
+
+/**
+ * 污水监测数据
+ *
+ * @author wukai
+ */
+@ApiModel("污水监测数据")
+@Data
+public class MaogaoVO {
+    private static final long serialVersionUID = 1L;
+    @ApiModelProperty("日期")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date dataDate;
+    @ApiModelProperty("小时")
+    private Integer hour;
+    @ApiModelProperty("设备ID")
+    @Excel(name = "设备ID")
+    private Long deviceId;
+    @ApiModelProperty("织造米数")
+    private BigDecimal length;
+    @ApiModelProperty("毛高")
+    private BigDecimal height;
+    @ApiModelProperty("密度")
+    private BigDecimal density;
+    @ApiModelProperty("电量")
+    private BigDecimal kwh;
+}

+ 151 - 0
jjt-biz/src/main/resources/mapper/lean/LeanFanMapper.xml

@@ -0,0 +1,151 @@
+<?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.lean.mapper.LeanFanMapper">
+
+    <resultMap type="LeanFan" id="LeanFanResult">
+        <result property="recordId" column="RECORD_ID"/>
+        <result property="dataDate" column="DATA_DATE"/>
+        <result property="hour" column="HOUR"/>
+        <result property="type" column="TYPE"/>
+        <result property="fanId" column="FAN_ID"/>
+        <result property="press" column="PRESS"/>
+        <result property="temp" column="TEMP"/>
+        <result property="power" column="POWER"/>
+        <result property="amp" column="AMP"/>
+        <result property="voltage" column="VOLTAGE"/>
+        <result property="energy" column="ENERGY"/>
+        <result property="createBy" column="CREATE_BY"/>
+        <result property="createTime" column="CREATE_TIME"/>
+        <result property="updateBy" column="UPDATE_BY"/>
+        <result property="updateTime" column="UPDATE_TIME"/>
+        <result property="remark" column="REMARK"/>
+    </resultMap>
+
+    <sql id="selectLeanFanVo">
+        select RECORD_ID,
+               DATA_DATE,
+               HOUR,
+               TYPE,
+               FAN_ID,
+               PRESS,
+               TEMP,
+               POWER,
+               AMP,
+               VOLTAGE,
+               ENERGY,
+               CREATE_BY,
+               CREATE_TIME,
+               UPDATE_BY,
+               UPDATE_TIME,
+               REMARK
+        from LEAN_FAN
+    </sql>
+
+    <select id="selectLeanFanList" parameterType="LeanFan" resultMap="LeanFanResult">
+        <include refid="selectLeanFanVo"/>
+        <where>
+            <if test="dataDate != null ">and FORMAT(DATA_DATE, 'yyyy-MM') = FORMAT(#{dataDate}, 'yyyy-MM')</if>
+            <if test="hour != null ">and HOUR = #{hour}</if>
+            <if test="type != null  and type != ''">and TYPE = #{type}</if>
+            <if test="fanId != null ">and FAN_ID = #{fanId}</if>
+            <if test="press != null ">and PRESS = #{press}</if>
+            <if test="temp != null ">and TEMP = #{temp}</if>
+            <if test="power != null ">and POWER = #{power}</if>
+            <if test="amp != null ">and AMP = #{amp}</if>
+            <if test="voltage != null ">and VOLTAGE = #{voltage}</if>
+            <if test="energy != null ">and ENERGY = #{energy}</if>
+            <if test="createBy != null  and createBy != ''">and CREATE_BY = #{createBy}</if>
+            <if test="createTime != null ">and CREATE_TIME = #{createTime}</if>
+            <if test="updateBy != null  and updateBy != ''">and UPDATE_BY = #{updateBy}</if>
+            <if test="updateTime != null ">and UPDATE_TIME = #{updateTime}</if>
+            <if test="remark != null  and remark != ''">and REMARK = #{remark}</if>
+        </where>
+        order by data_date desc,hour desc
+    </select>
+
+    <select id="selectLeanFanByRecordId" parameterType="Long" resultMap="LeanFanResult">
+        <include refid="selectLeanFanVo"/>
+        where RECORD_ID = #{recordId}
+    </select>
+
+    <insert id="insertLeanFan" parameterType="LeanFan">
+        insert into LEAN_FAN
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="dataDate != null">DATA_DATE,</if>
+            <if test="hour != null">HOUR,</if>
+            <if test="type != null">TYPE,</if>
+            <if test="fanId != null">FAN_ID,</if>
+            <if test="press != null">PRESS,</if>
+            <if test="temp != null">TEMP,</if>
+            <if test="power != null">POWER,</if>
+            <if test="amp != null">AMP,</if>
+            <if test="voltage != null">VOLTAGE,</if>
+            <if test="energy != null">ENERGY,</if>
+            <if test="createBy != null">CREATE_BY,</if>
+            <if test="createTime != null">CREATE_TIME,</if>
+            <if test="updateBy != null">UPDATE_BY,</if>
+            <if test="updateTime != null">UPDATE_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="type != null">#{type},</if>
+            <if test="fanId != null">#{fanId},</if>
+            <if test="press != null">#{press},</if>
+            <if test="temp != null">#{temp},</if>
+            <if test="power != null">#{power},</if>
+            <if test="amp != null">#{amp},</if>
+            <if test="voltage != null">#{voltage},</if>
+            <if test="energy != null">#{energy},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateBy != null">#{updateBy},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+            <if test="remark != null">#{remark},</if>
+        </trim>
+    </insert>
+
+    <update id="updateLeanFan" parameterType="LeanFan">
+        update LEAN_FAN
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="dataDate != null">DATA_DATE = #{dataDate},</if>
+            <if test="hour != null">HOUR = #{hour},</if>
+            <if test="type != null">TYPE = #{type},</if>
+            <if test="fanId != null">FAN_ID = #{fanId},</if>
+            <if test="press != null">PRESS = #{press},</if>
+            <if test="temp != null">TEMP = #{temp},</if>
+            <if test="power != null">POWER = #{power},</if>
+            <if test="amp != null">AMP = #{amp},</if>
+            <if test="voltage != null">VOLTAGE = #{voltage},</if>
+            <if test="energy != null">ENERGY = #{energy},</if>
+            <if test="createBy != null">CREATE_BY = #{createBy},</if>
+            <if test="createTime != null">CREATE_TIME = #{createTime},</if>
+            <if test="updateBy != null">UPDATE_BY = #{updateBy},</if>
+            <if test="updateTime != null">UPDATE_TIME = #{updateTime},</if>
+            <if test="remark != null">REMARK = #{remark},</if>
+        </trim>
+        where RECORD_ID = #{recordId}
+    </update>
+
+    <delete id="deleteLeanFanByRecordId" parameterType="Long">
+        delete
+        from LEAN_FAN
+        where RECORD_ID = #{recordId}
+    </delete>
+
+    <delete id="deleteLeanFanByRecordIds" parameterType="String">
+        delete from LEAN_FAN where RECORD_ID in
+        <foreach item="recordId" collection="array" open="(" separator="," close=")">
+            #{recordId}
+        </foreach>
+    </delete>
+    <delete id="deleteLeanFan">
+        delete
+        from LEAN_FAN
+        where DATA_DATE = #{date}
+          and HOUR = #{hour}
+    </delete>
+</mapper>