Ver código fonte

添加Mu检验和处理数字孪生BUG

wukai 2 meses atrás
pai
commit
0042316efc

+ 7 - 2
jjt-biz/src/main/java/com/jjt/biz/service/impl/ApiAllServiceImpl.java

@@ -193,8 +193,13 @@ public class ApiAllServiceImpl implements IApiAllService {
             vo.setDate(week(localDate));
             vo.setTips(localDate.toString());
             YrProdTradeVO yr = yrMap.get(wd.getTime());
-            vo.setRzLength(yr.getLine().get(0).getLength());
-            vo.setRzWeight(yr.getLine().get(0).getWeight());
+            if (yr != null) {
+                vo.setRzLength(yr.getLine().get(0).getLength());
+                vo.setRzWeight(yr.getLine().get(0).getWeight());
+            } else {
+                vo.setRzLength(BigDecimal.ZERO);
+                vo.setRzWeight(BigDecimal.ZERO);
+            }
             list.add(vo);
         }
 

+ 166 - 38
jjt-biz/src/main/java/com/jjt/dye/controller/DyeCalcHourController.java

@@ -1,28 +1,30 @@
 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.core.page.TableDataInfo;
 import com.jjt.common.enums.BusinessType;
+import com.jjt.common.utils.poi.ExcelUtil;
 import com.jjt.dye.domain.DyeCalcHour;
+import com.jjt.dye.domain.DyeDevicePara;
+import com.jjt.dye.domain.DyeTypePara;
 import com.jjt.dye.service.IDyeCalcHourService;
-import com.jjt.common.utils.poi.ExcelUtil;
-import com.jjt.common.core.page.TableDataInfo;
+import com.jjt.dye.service.IDyeDeviceService;
+import com.jjt.dye.vo.DyeCompareVO;
+import com.jjt.dye.vo.DyeDeviceVO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.math3.stat.inference.MannWhitneyUTest;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * 小时统计数据Controller
@@ -30,35 +32,165 @@ import com.jjt.common.core.page.TableDataInfo;
  * @author wukai
  * @date 2025-11-01
  */
-@Api(tags="小时统计数据")
+@Api(tags = "小时统计数据")
 @RestController
 @RequestMapping("/dye/hour")
-public class DyeCalcHourController extends BaseController{
+public class DyeCalcHourController extends BaseController {
     @Resource
     private IDyeCalcHourService dyeCalcHourService;
+    @Resource
+    private IDyeDeviceService dyeDeviceService;
 
     /**
      * 查询小时统计数据列表
      */
     @ApiOperation("查询小时统计数据列表")
-   // @PreAuthorize("@ss.hasPermi('dye:hour:list')")
+    // @PreAuthorize("@ss.hasPermi('dye:hour:list')")
     @GetMapping("/list")
-    public TableDataInfo list(DyeCalcHour dyeCalcHour)
-    {
+    public TableDataInfo list(DyeCalcHour dyeCalcHour) {
         startPage();
         List<DyeCalcHour> list = dyeCalcHourService.selectDyeCalcHourList(dyeCalcHour);
         return getDataTable(list);
     }
 
+    @ApiOperation("查询小时统计数据列表")
+    @GetMapping("/calc")
+    public AjaxResult calc(Date date, String line1, String line2) {
+        //1.查询设备列表
+        Map<String, List<DyeDeviceVO>> devices = dyeDeviceService.deviceByLine();
+
+        // 参数校验
+        if (date == null || line1 == null || line2 == null) {
+            return AjaxResult.error("参数不能为空");
+        }
+
+        if (!devices.containsKey(line1) || !devices.containsKey(line2)) {
+            return AjaxResult.error("未找到指定产线");
+        }
+
+        //2.查询参数统计数据
+        DyeCalcHour dyeCalcHour = new DyeCalcHour();
+        dyeCalcHour.setWorkDay(date);
+        List<DyeCalcHour> list = dyeCalcHourService.selectDyeCalcHourList(dyeCalcHour);
+        // 按 deviceId+paraCode 分组放入 MAP 中
+        Map<String, List<DyeCalcHour>> groupedData = list.stream()
+                .collect(Collectors.groupingBy(item -> item.getDeviceId() + "+" + item.getParaCode()));
+
+        Map<Integer, DyeDeviceVO> devices1 = devices.get(line1).stream().collect(Collectors.toMap(DyeDeviceVO::getSortNum, device -> device));
+        Map<Integer, DyeDeviceVO> devices2 = devices.get(line2).stream().collect(Collectors.toMap(DyeDeviceVO::getSortNum, device -> device));
+        List<DyeCompareVO> compareVOList = new ArrayList<>();
+
+        // 确保两个产线具有相同的设备排序编号
+        if (!devices1.keySet().equals(devices2.keySet())) {
+            return AjaxResult.error("两条产线设备配置不一致");
+        }
+
+        devices1.forEach((sortNum, device) -> {
+            DyeDeviceVO d1 = devices1.get(sortNum);
+            DyeDeviceVO d2 = devices2.get(sortNum);
+
+            // 处理类型参数
+            processParameters(d1.getTypeParas(), d1, d2, groupedData, compareVOList);
+            // 处理能源参数
+            processParameters(d1.getEngParas(), d1, d2, groupedData, compareVOList);
+        });
+
+        return success(compareVOList);
+    }
+
+    /**
+     * 处理参数比较的通用方法
+     *
+     * @param paras         参数列表
+     * @param d1            第一个设备
+     * @param d2            第二个设备
+     * @param groupedData   分组数据
+     * @param compareVOList 比较结果列表
+     */
+    private void processParameters(List<? extends Object> paras,
+                                   DyeDeviceVO d1, DyeDeviceVO d2,
+                                   Map<String, List<DyeCalcHour>> groupedData,
+                                   List<DyeCompareVO> compareVOList) {
+        if (paras == null) return;
+
+        paras.forEach(para -> {
+            String paraCode = getParaCode(para);
+            String paraName = getParaName(para);
+            String key1 = d1.getDeviceId() + "+" + paraCode;
+            String key2 = d2.getDeviceId() + "+" + paraCode;
+
+            List<DyeCalcHour> data1 = groupedData.get(key1);
+            List<DyeCalcHour> data2 = groupedData.get(key2);
+
+            //data1和data2进行Mann-Whitney U检验,输出必要结果
+            if (data1 != null && data2 != null && !data1.isEmpty() && !data2.isEmpty()) {
+                // 提取两组数据的值
+                double[] values1 = data1.stream().mapToDouble(item -> item.getParaValue().doubleValue()).toArray();
+                double[] values2 = data2.stream().mapToDouble(item -> item.getParaValue().doubleValue()).toArray();
+
+                // 进行Mann-Whitney U检验
+                MannWhitneyUTest test = new MannWhitneyUTest();
+                double uValue = test.mannWhitneyU(values1, values2);
+                double pValue = test.mannWhitneyUTest(values1, values2);
+
+                // 判断差异是否显著(通常以 p < 0.05 为显著性水平)
+                String significance = pValue < 0.05 ? "显著" : "不显著";
+
+                DyeCompareVO compareVO = new DyeCompareVO();
+                compareVO.setTypeName(d1.getTypeName());
+                compareVO.setParaName(paraName);
+                compareVO.setDeviceName1(d1.getDeviceName());
+                compareVO.setDeviceName2(d2.getDeviceName());
+                compareVO.setDeviceId1(d1.getDeviceId());
+                compareVO.setDeviceId2(d2.getDeviceId());
+                compareVO.setResult(significance);
+                compareVO.setUValue(uValue);
+                compareVO.setPValue(pValue);
+                if (pValue < 0.05) {
+                    compareVOList.add(compareVO);
+                }
+            }
+        });
+    }
+
+    /**
+     * 获取参数编码
+     *
+     * @param para 参数对象
+     * @return 参数编码
+     */
+    private String getParaCode(Object para) {
+        if (para instanceof DyeTypePara) {
+            return ((DyeTypePara) para).getParaCode();
+        } else if (para instanceof DyeDevicePara) {
+            return ((DyeDevicePara) para).getParaCode();
+        }
+        return "";
+    }
+
+    /**
+     * 获取参数名称
+     *
+     * @param para 参数对象
+     * @return 参数名称
+     */
+    private String getParaName(Object para) {
+        if (para instanceof DyeTypePara) {
+            return ((DyeTypePara) para).getParaName();
+        } else if (para instanceof DyeDevicePara) {
+            return ((DyeDevicePara) para).getParaName();
+        }
+        return "";
+    }
+
     /**
      * 导出小时统计数据列表
      */
     @ApiOperation("导出小时统计数据列表")
-   // @PreAuthorize("@ss.hasPermi('dye:hour:export')")
+    // @PreAuthorize("@ss.hasPermi('dye:hour:export')")
     @Log(title = "小时统计数据", businessType = BusinessType.EXPORT)
     @PostMapping("/export")
-    public void export(HttpServletResponse response, DyeCalcHour dyeCalcHour)
-    {
+    public void export(HttpServletResponse response, DyeCalcHour dyeCalcHour) {
         List<DyeCalcHour> list = dyeCalcHourService.selectDyeCalcHourList(dyeCalcHour);
         ExcelUtil<DyeCalcHour> util = new ExcelUtil<DyeCalcHour>(DyeCalcHour.class);
         util.exportExcel(response, list, "小时统计数据数据");
@@ -68,10 +200,9 @@ public class DyeCalcHourController extends BaseController{
      * 获取小时统计数据详细信息
      */
     @ApiOperation("获取小时统计数据详细信息")
-   // @PreAuthorize("@ss.hasPermi('dye:hour:query')")
+    // @PreAuthorize("@ss.hasPermi('dye:hour:query')")
     @GetMapping(value = "/{chId}")
-    public AjaxResult getInfo(@PathVariable("chId") Long chId)
-    {
+    public AjaxResult getInfo(@PathVariable("chId") Long chId) {
         return success(dyeCalcHourService.selectDyeCalcHourByChId(chId));
     }
 
@@ -79,11 +210,10 @@ public class DyeCalcHourController extends BaseController{
      * 新增小时统计数据
      */
     @ApiOperation("新增小时统计数据")
-   // @PreAuthorize("@ss.hasPermi('dye:hour:add')")
+    // @PreAuthorize("@ss.hasPermi('dye:hour:add')")
     @Log(title = "小时统计数据", businessType = BusinessType.INSERT)
     @PostMapping
-    public AjaxResult add(@RequestBody DyeCalcHour dyeCalcHour)
-    {
+    public AjaxResult add(@RequestBody DyeCalcHour dyeCalcHour) {
         return toAjax(dyeCalcHourService.insertDyeCalcHour(dyeCalcHour));
     }
 
@@ -91,11 +221,10 @@ public class DyeCalcHourController extends BaseController{
      * 修改小时统计数据
      */
     @ApiOperation("修改小时统计数据")
-   // @PreAuthorize("@ss.hasPermi('dye:hour:edit')")
+    // @PreAuthorize("@ss.hasPermi('dye:hour:edit')")
     @Log(title = "小时统计数据", businessType = BusinessType.UPDATE)
     @PutMapping
-    public AjaxResult edit(@RequestBody DyeCalcHour dyeCalcHour)
-    {
+    public AjaxResult edit(@RequestBody DyeCalcHour dyeCalcHour) {
         return toAjax(dyeCalcHourService.updateDyeCalcHour(dyeCalcHour));
     }
 
@@ -103,11 +232,10 @@ public class DyeCalcHourController extends BaseController{
      * 删除小时统计数据
      */
     @ApiOperation("删除小时统计数据")
-   // @PreAuthorize("@ss.hasPermi('dye:hour:remove')")
+    // @PreAuthorize("@ss.hasPermi('dye:hour:remove')")
     @Log(title = "小时统计数据", businessType = BusinessType.DELETE)
-	@DeleteMapping("/{chIds}")
-    public AjaxResult remove(@PathVariable Long[] chIds)
-    {
+    @DeleteMapping("/{chIds}")
+    public AjaxResult remove(@PathVariable Long[] chIds) {
         return toAjax(dyeCalcHourService.deleteDyeCalcHourByChIds(chIds));
     }
 }

+ 32 - 0
jjt-biz/src/main/java/com/jjt/dye/vo/DyeCompareVO.java

@@ -0,0 +1,32 @@
+package com.jjt.dye.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * DyeDeviceVO$
+ *
+ * @author wukai
+ * @date 2025/11/2 02:33
+ */
+@Data
+public class DyeCompareVO {
+    @ApiModelProperty("类型名称")
+    private String typeName;
+    @ApiModelProperty("参数名称")
+    private String paraName;
+    @ApiModelProperty("设备ID1")
+    private Long deviceId1;
+    @ApiModelProperty("设备名称1")
+    private String deviceName1;
+    @ApiModelProperty("设备ID2")
+    private Long deviceId2;
+    @ApiModelProperty("设备名称2")
+    private String deviceName2;
+    @ApiModelProperty("U值")
+    private Double uValue;
+    @ApiModelProperty("P值")
+    private Double pValue;
+    @ApiModelProperty("比较结果")
+    private String result;
+}