From 4f3a98f19143865cdc1de4791e8a95d96bd40c65 Mon Sep 17 00:00:00 2001
From: maven <2163098428@qq.com>
Date: 星期五, 01 八月 2025 13:27:59 +0800
Subject: [PATCH] yys 密码已重置

---
 inspect-server/src/main/java/com/ruoyi/inspect/service/impl/DataAnalysisServiceImpl.java |  613 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 613 insertions(+), 0 deletions(-)

diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/DataAnalysisServiceImpl.java b/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/DataAnalysisServiceImpl.java
new file mode 100644
index 0000000..33b9b28
--- /dev/null
+++ b/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/DataAnalysisServiceImpl.java
@@ -0,0 +1,613 @@
+package com.ruoyi.inspect.service.impl;
+
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.ruoyi.basic.dto.IfsInventoryQuantitySupplierDto;
+import com.ruoyi.common.constant.InsOrderTypeConstants;
+import com.ruoyi.framework.exception.ErrorException;
+import com.ruoyi.inspect.dto.DataAnalysisDto;
+import com.ruoyi.inspect.dto.SampleProductRawAnalysisDto;
+import com.ruoyi.inspect.mapper.DataAnalysisMapper;
+import com.ruoyi.inspect.mapper.InsProductMapper;
+import com.ruoyi.inspect.service.DataAnalysisService;
+import com.ruoyi.inspect.vo.DeviationAnalyzeVo;
+import com.ruoyi.inspect.vo.RawMaterialSupplierVo;
+import com.ruoyi.inspect.vo.RawProductAnalysisVo;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.math.MathContext;
+import java.math.RoundingMode;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * 鏁版嵁鍒嗘瀽
+ *
+ * @Author zhuo
+ * @Date 2024/10/16
+ */
+@Service
+@AllArgsConstructor
+public class DataAnalysisServiceImpl implements DataAnalysisService {
+
+    private DataAnalysisMapper dataAnalysisMapper;
+
+    private InsProductMapper insProductMapper;
+
+    /**
+     * 鏌ヨ鍘熸潗鏂欐煴鐘剁粺璁�
+     * @return searchTime  鏃堕棿
+     * @return passRate  鍚堟牸鐜�
+     * @return sum  鎬绘暟
+     */
+    @Override
+    public List<Map<String, Object>> getRawPassRateByBarChart(DataAnalysisDto dataAnalysisDto) {
+        // 鏍煎紡鍖栧瓧娈�, 閬垮厤鎶ラ敊
+        this.formatDataAnalysisDto(dataAnalysisDto);
+        // 鑾峰彇褰撳墠鏃ユ湡
+        DateTime now = DateUtil.date();
+        if (StrUtil.isNotBlank(dataAnalysisDto.getBeginDate()) && StrUtil.isNotBlank(dataAnalysisDto.getEndDate())) {
+            return dataAnalysisMapper.getRawPassRateByBarChartByDay(dataAnalysisDto);
+        } else if (dataAnalysisDto.getDateType().equals("1")) {
+            // 鑾峰彇鏈懆鐨勫紑濮嬫椂闂达紙鍛ㄤ竴 00:00:00锛�
+            DateTime beginOfWeek = DateUtil.beginOfWeek(now);
+            // 鑾峰彇鏈懆鐨勭粨鏉熸椂闂达紙鍛ㄦ棩 23:59:59锛�
+            // 鑾峰彇鏈懆鐨勭粨鏉熸椂闂达紙鍛ㄦ棩 23:59:59锛�
+            DateTime endOfWeek = DateUtil.endOfWeek(now);
+            dataAnalysisDto.setBeginDate(DateUtil.format(beginOfWeek, "yyyy-MM-dd HH:mm:ss"));
+            dataAnalysisDto.setEndDate(DateUtil.format(endOfWeek, "yyyy-MM-dd HH:mm:ss"));
+            return dataAnalysisMapper.getRawPassRateByBarChartByWeek(dataAnalysisDto);
+        } else if (dataAnalysisDto.getDateType().equals("2")) {
+            // 鑾峰彇褰撳墠鏈堢殑寮�濮嬫椂闂达紙姣忔湀1鍙� 00:00:00锛�
+            DateTime beginOfMonth = DateUtil.beginOfMonth(now);
+            // 鑾峰彇褰撳墠鏈堢殑缁撴潫鏃堕棿锛堟湰鏈堟渶鍚庝竴澶� 23:59:59锛�
+            DateTime endOfMonth = DateUtil.endOfMonth(now);
+            dataAnalysisDto.setBeginDate(DateUtil.format(beginOfMonth, "yyyy-MM-dd HH:mm:ss"));
+            dataAnalysisDto.setEndDate(DateUtil.format(endOfMonth, "yyyy-MM-dd HH:mm:ss"));
+            return dataAnalysisMapper.getRawPassRateByBarChartByDay(dataAnalysisDto);
+        } else if (dataAnalysisDto.getDateType().equals("3")) {
+            // 鑾峰彇褰撳墠骞寸殑寮�濮嬫椂闂达紙姣忓勾1鏈�1鏃� 00:00:00锛�
+            DateTime beginOfYear = DateUtil.beginOfYear(now);
+            // 鑾峰彇褰撳墠骞寸殑缁撴潫鏃堕棿锛堟瘡骞�12鏈�31鏃� 23:59:59锛�
+            DateTime endOfYear = DateUtil.endOfYear(now);
+            dataAnalysisDto.setBeginDate(DateUtil.format(beginOfYear, "yyyy-MM-dd HH:mm:ss"));
+            dataAnalysisDto.setEndDate(DateUtil.format(endOfYear, "yyyy-MM-dd HH:mm:ss"));
+            return dataAnalysisMapper.getRawPassRateByBarChartByYear(dataAnalysisDto);
+        }
+
+        return null;
+    }
+
+    /**
+     * 鏌ヨ鍘熸潗鏂欓ゼ鐘跺浘
+     * @param dataAnalysisDto
+     * @return
+     * sum          : 鎬绘暟
+     * unQualified  : 涓嶅悎鏍兼暟閲�
+     * qualified  : 鍚堟牸鏁伴噺
+     * passRate  : 鍚堟牸鐜�
+     */
+    @Override
+    public Map<String, Object> getRawPassRateByCake(DataAnalysisDto dataAnalysisDto) {
+        // 鏍煎紡鍖栧瓧娈�, 閬垮厤鎶ラ敊
+        this.formatDataAnalysisDto(dataAnalysisDto);
+        // 鑾峰彇褰撳墠鏃ユ湡
+        DateTime now = DateUtil.date();
+        if (StrUtil.isNotBlank(dataAnalysisDto.getBeginDate()) && StrUtil.isNotBlank(dataAnalysisDto.getEndDate())) {
+
+        } else if (dataAnalysisDto.getDateType().equals("1")) {
+            // 鑾峰彇鏈懆鐨勫紑濮嬫椂闂达紙鍛ㄤ竴 00:00:00锛�
+            DateTime beginOfWeek = DateUtil.beginOfWeek(now);
+            // 鑾峰彇鏈懆鐨勭粨鏉熸椂闂达紙鍛ㄦ棩 23:59:59锛�
+            DateTime endOfWeek = DateUtil.endOfWeek(now);
+            dataAnalysisDto.setBeginDate(DateUtil.format(beginOfWeek, "yyyy-MM-dd HH:mm:ss"));
+            dataAnalysisDto.setEndDate(DateUtil.format(endOfWeek, "yyyy-MM-dd HH:mm:ss"));
+        } else if (dataAnalysisDto.getDateType().equals("2")) {
+            // 鑾峰彇褰撳墠鏈堢殑寮�濮嬫椂闂达紙姣忔湀1鍙� 00:00:00锛�
+            DateTime beginOfMonth = DateUtil.beginOfMonth(now);
+            // 鑾峰彇褰撳墠鏈堢殑缁撴潫鏃堕棿锛堟湰鏈堟渶鍚庝竴澶� 23:59:59锛�
+            DateTime endOfMonth = DateUtil.endOfMonth(now);
+            dataAnalysisDto.setBeginDate(DateUtil.format(beginOfMonth, "yyyy-MM-dd HH:mm:ss"));
+            dataAnalysisDto.setEndDate(DateUtil.format(endOfMonth, "yyyy-MM-dd HH:mm:ss"));
+        } else if (dataAnalysisDto.getDateType().equals("3")) {
+            // 鑾峰彇褰撳墠骞寸殑寮�濮嬫椂闂达紙姣忓勾1鏈�1鏃� 00:00:00锛�
+            DateTime beginOfYear = DateUtil.beginOfYear(now);
+            // 鑾峰彇褰撳墠骞寸殑缁撴潫鏃堕棿锛堟瘡骞�12鏈�31鏃� 23:59:59锛�
+            DateTime endOfYear = DateUtil.endOfYear(now);
+            dataAnalysisDto.setBeginDate(DateUtil.format(beginOfYear, "yyyy-MM-dd HH:mm:ss"));
+            dataAnalysisDto.setEndDate(DateUtil.format(endOfYear, "yyyy-MM-dd HH:mm:ss"));
+        }
+        return dataAnalysisMapper.getRawPassRateByCake(dataAnalysisDto);
+    }
+
+
+    /**
+     * 鏌ヨ妫�楠岄」鍚嶇О
+     * @param dataAnalysisDto
+     * @return
+     */
+    @Override
+    public List<String> getRawItemNames(DataAnalysisDto dataAnalysisDto) {
+        // 鏍煎紡鍖栧瓧娈�, 閬垮厤鎶ラ敊
+        this.formatDataAnalysisDto(dataAnalysisDto);
+        List<IfsInventoryQuantitySupplierDto> analysisList = dataAnalysisMapper.getRawProductAnalysisAllSample(dataAnalysisDto);
+        // 鏍规嵁鏍峰搧id鏌ヨ妫�娴嬪弬鏁�
+        if (CollectionUtils.isEmpty(analysisList)) {
+            return null;
+        }
+        List<Integer> sampleIds = analysisList.stream().map(IfsInventoryQuantitySupplierDto::getSampleId).collect(Collectors.toList());
+        // 鏌ヨ妫�楠岄」鐩�
+
+        return insProductMapper.selectItemNameBySampleIds(sampleIds);
+    }
+
+    /**
+     * 鏌ヨ鍘熸潗鏂欓」妫�鍒嗘瀽
+     * @param dataAnalysisDto
+     * @return
+     */
+    @Override
+    public RawProductAnalysisVo getRawProductAnalysis(DataAnalysisDto dataAnalysisDto) {
+        // 鏍煎紡鍖栧瓧娈�, 閬垮厤鎶ラ敊
+        this.formatDataAnalysisDto(dataAnalysisDto);
+        List<IfsInventoryQuantitySupplierDto> analysisList = dataAnalysisMapper.getRawProductAnalysisAllSample(dataAnalysisDto);
+        // 鏍规嵁鏍峰搧id鏌ヨ妫�娴嬪弬鏁�
+        if (CollectionUtils.isEmpty(analysisList)) {
+            return null;
+        }
+        List<Integer> sampleIds = analysisList.stream().map(IfsInventoryQuantitySupplierDto::getSampleId).collect(Collectors.toList());
+        // 鏌ヨ妫�楠岄」鐩�
+        List<SampleProductRawAnalysisDto> sampleProductList = insProductMapper.selectListBySampleIds(sampleIds);
+
+        List<String> itemNames = new ArrayList<>();
+        if (CollectionUtils.isNotEmpty(dataAnalysisDto.getItemNames())) {
+            itemNames = dataAnalysisDto.getItemNames();
+        } else {
+            itemNames = insProductMapper.selectItemNameBySampleIds(sampleIds);
+        }
+
+        // 鏍规嵁鏍峰搧鍒嗙粍
+        List<Map<String, Object>> productList = new ArrayList<>();
+
+        Map<Integer, List<SampleProductRawAnalysisDto>> collect = sampleProductList.stream().collect(Collectors.groupingBy(SampleProductRawAnalysisDto::getInsSampleId));
+        List<String> finalItemNames = itemNames;
+        collect.forEach((integer, rawAnalysisDtos) -> {
+            // 妫�楠岄」鐩悕绉拌浆鎹㈡垚map
+            Map<String, Object> itemMap = new HashMap<>();
+            for (String itemName : finalItemNames) {
+                itemMap.put(itemName, null);
+            }
+            // 閬嶅巻妫�楠岄」
+            for (SampleProductRawAnalysisDto rawAnalysisDto : rawAnalysisDtos) {
+                itemMap.put(rawAnalysisDto.getInspectionItem(), rawAnalysisDto.getLastValue());
+            }
+            itemMap.put("product", rawAnalysisDtos.get(0).getSampleCode());
+            productList.add(itemMap);
+        });
+
+        RawProductAnalysisVo rawProductAnalysisVo = new RawProductAnalysisVo();
+        rawProductAnalysisVo.setItemNames(itemNames);
+        rawProductAnalysisVo.setProductList(productList);
+
+        return rawProductAnalysisVo;
+    }
+
+    /**
+     * 鏌ヨ妫�娴嬮」鍒嗘瀽鍒楄〃
+     * @param dataAnalysisDto
+     * @return
+     */
+    @Override
+    public List<IfsInventoryQuantitySupplierDto> getRawProductAnalysisAllList(DataAnalysisDto dataAnalysisDto) {
+        // 鏍煎紡鍖栧瓧娈�, 閬垮厤鎶ラ敊
+        this.formatDataAnalysisDto(dataAnalysisDto);
+        return dataAnalysisMapper.getRawProductAnalysisList(dataAnalysisDto);
+    }
+
+    /**
+     * 鏌ヨ椤规鍒嗘瀽鍚堟牸鐜�
+     * @param dataAnalysisDto
+     * @return
+     */
+    @Override
+    public RawProductAnalysisVo getRawProductAnalysisRawPass(DataAnalysisDto dataAnalysisDto) {
+        // 鏍煎紡鍖栧瓧娈�, 閬垮厤鎶ラ敊
+        this.formatDataAnalysisDto(dataAnalysisDto);
+        List<IfsInventoryQuantitySupplierDto> analysisList = dataAnalysisMapper.getRawProductAnalysisAllSample(dataAnalysisDto);
+        // 鏍规嵁鏍峰搧id鏌ヨ妫�娴嬪弬鏁�
+        if (CollectionUtils.isEmpty(analysisList)) {
+            return null;
+        }
+        List<Integer> sampleIds = analysisList.stream().map(IfsInventoryQuantitySupplierDto::getSampleId).collect(Collectors.toList());
+        // 鏌ヨ妫�楠岄」鐩�
+        List<SampleProductRawAnalysisDto> sampleProductList = insProductMapper.selectListBySampleIds(sampleIds);
+        List<String> itemNames = new ArrayList<>();
+        List<String> finalItemNames = itemNames;
+        if (CollectionUtils.isNotEmpty(dataAnalysisDto.getItemNames())) {
+            itemNames = dataAnalysisDto.getItemNames();
+        } else {
+            itemNames = insProductMapper.selectItemNameBySampleIds(sampleIds);
+        }
+        // 鍒嗙粍
+        List<Map<String, Object>> productList = new ArrayList<>();
+
+        Map<String, List<SampleProductRawAnalysisDto>> groupList = new HashMap<>();
+
+        switch (dataAnalysisDto.getGroupType()) {
+            case "0":  // 榛樿鏍峰搧鍖哄垎
+                groupList = sampleProductList.stream()
+                        .collect(Collectors.groupingBy(SampleProductRawAnalysisDto::getSample));
+
+                break;
+            case "1":  // 鎵规鍙峰尯鍒�
+                groupList = sampleProductList.stream()
+                        .collect(Collectors.groupingBy(SampleProductRawAnalysisDto::getUpdateBatchNo));
+
+                break;
+            case "2":  // 鍘傚鍖哄垎
+                groupList = sampleProductList.stream()
+                        .collect(Collectors.groupingBy(SampleProductRawAnalysisDto::getSupplierName));
+
+                break;
+        }
+
+        groupList.forEach((groupName, rawAnalysisDtos) -> {
+            // 鎸夌収妫�楠岄」鍖哄垎
+            // 妫�楠岄」鐩悕绉拌浆鎹㈡垚map
+            Map<String, Object> itemMap = new HashMap<>();
+
+            for (String itemName : finalItemNames) {
+                itemMap.put(itemName, null);
+            }
+
+            Map<String, List<SampleProductRawAnalysisDto>> groupItemList = rawAnalysisDtos.stream().collect(Collectors.groupingBy(SampleProductRawAnalysisDto::getInspectionItem));
+
+
+            groupItemList.forEach((itemName, dtos) -> {
+                // 缁熻鍚堟牸鎬绘暟
+                long qualifiedCount = dtos.stream()
+                        .filter(dto -> dto.getInsResult() != null && dto.getInsResult().equals(1))
+                        .count();
+                long totalCount = dtos.size();
+                BigDecimal passRate = new BigDecimal(qualifiedCount).divide(new BigDecimal(totalCount), 4, RoundingMode.HALF_UP)
+                        .multiply(new BigDecimal(100))
+                        .setScale(2, RoundingMode.HALF_UP);
+                itemMap.put(itemName, passRate);
+            });
+
+            itemMap.put("product", groupName);
+            productList.add(itemMap);
+        });
+
+
+        RawProductAnalysisVo rawProductAnalysisVo = new RawProductAnalysisVo();
+        rawProductAnalysisVo.setItemNames(itemNames);
+        rawProductAnalysisVo.setProductList(productList);
+
+        return rawProductAnalysisVo;
+    }
+
+    @Override
+    public DeviationAnalyzeVo getRawSupplierCompare(DataAnalysisDto dataAnalysisDto) {
+        // 鍒ゆ柇璁㈠崟id鏄惁鏈変簲涓�
+        if (CollectionUtils.isEmpty(dataAnalysisDto.getOrderIds()) || dataAnalysisDto.getOrderIds().size() != 5) {
+            throw new ErrorException("璇烽�夋嫨浜旀潯鏁版嵁");
+        }
+        if (CollectionUtils.isEmpty(dataAnalysisDto.getItemNames()) || dataAnalysisDto.getItemNames().size() != 1) {
+            throw new ErrorException("璇烽�夋嫨涓�涓楠岄」妫�楠岄」");
+        }
+        if (CollectionUtils.isNotEmpty(dataAnalysisDto.getSupplierDataList())) {
+            if (dataAnalysisDto.getSupplierDataList().size() != 5) {
+                throw new ErrorException("鍘傚鏁版嵁璇疯緭鍏ュ畬鏁�5鏉�");
+            }
+        }
+
+        List<RawMaterialSupplierVo> rawMaterialSupplierVoList = dataAnalysisMapper.getItemValueByOrderIds(dataAnalysisDto.getOrderIds(), dataAnalysisDto.getItemNames().get(0));
+        // 鍒ゆ柇鍘傚鏉愭枡鍚嶇О瑙勬牸鍨嬪彿鏄惁鏄竴鏍风殑
+        RawMaterialSupplierVo rawMaterialSupplierVo = rawMaterialSupplierVoList.get(0);
+        for (RawMaterialSupplierVo materialSupplierVo : rawMaterialSupplierVoList) {
+            if (!materialSupplierVo.getSupplierName().equals(rawMaterialSupplierVo.getSupplierName()) ||
+                    !materialSupplierVo.getSample().equals(rawMaterialSupplierVo.getSample()) ||
+                    !materialSupplierVo.getModel().equals(rawMaterialSupplierVo.getModel())) {
+                throw new ErrorException("閫夋嫨鐨勬楠屼俊鎭笉鍖归厤");
+            }
+        }
+
+        List<String> lastValues = rawMaterialSupplierVoList.stream().map(RawMaterialSupplierVo::getLastValue).collect(Collectors.toList());
+
+        // 璁$畻鏈湴鏁版嵁
+        Map<String, List<Object>> localData = dataCompute(lastValues);
+
+
+        DeviationAnalyzeVo deviationAnalyzeVo = new DeviationAnalyzeVo();
+        deviationAnalyzeVo.setLocalData(localData.get("data"));
+        deviationAnalyzeVo.setLocalULC(localData.get("uclData"));
+        deviationAnalyzeVo.setLocalLCL(localData.get("lclData"));
+        deviationAnalyzeVo.setLocalAverage(localData.get("averageData"));
+        deviationAnalyzeVo.setLocalRange(localData.get("rangeData"));
+
+
+        // 鍒ゆ柇鏄惁鏈夊巶瀹舵暟鎹�
+        if (CollectionUtils.isNotEmpty(dataAnalysisDto.getSupplierDataList())) {
+            List<String> supplierValues = dataAnalysisDto.getSupplierDataList();
+            List<Object> absoluteDeviation = new ArrayList<>();
+            List<Object> averageList = new ArrayList<>();
+
+            for (int i = 0; i < lastValues.size(); i++) {
+                // 鍒ゆ柇鏈夊�兼槸鍚︿负绌�
+                if (StringUtils.isNotBlank(lastValues.get(i)) ||
+                        StringUtils.isNotBlank(supplierValues.get(i))) {
+                    BigDecimal laseValue = new BigDecimal(lastValues.get(i));
+                    BigDecimal supplierValue = new BigDecimal(supplierValues.get(i));
+
+                    // 璁$畻 (B3 - B2)
+                    BigDecimal result = laseValue.subtract(supplierValue)
+                            .divide(laseValue, 10, RoundingMode.HALF_UP)
+                            .abs()
+                            .setScale(2, RoundingMode.HALF_UP);
+
+                    absoluteDeviation.add(result);
+                } else {
+                    absoluteDeviation.add(null);
+                }
+            }
+            // 璁$畻骞冲潎鍊�
+            List<String> stringList = absoluteDeviation.stream()
+                    .map(obj -> obj == null ? "null" : obj.toString())
+                    .collect(Collectors.toList());
+            BigDecimal average = computeAverage(stringList);
+            absoluteDeviation.add(average);
+            for (int i = 0; i < 5; i++) {
+                averageList.add(average);
+            }
+
+            // 璁$畻鍘傚鏁版嵁
+            Map<String, List<Object>> supplierData = dataCompute(supplierValues);
+            deviationAnalyzeVo.setSupplierData(supplierData.get("data"));
+            deviationAnalyzeVo.setSupplierULC(supplierData.get("uclData"));
+            deviationAnalyzeVo.setSupplierLCL(supplierData.get("lclData"));
+            deviationAnalyzeVo.setSupplierAverage(supplierData.get("averageData"));
+            deviationAnalyzeVo.setSupplierRange(supplierData.get("rangeData"));
+            deviationAnalyzeVo.setAbsoluteDeviation(absoluteDeviation);
+            deviationAnalyzeVo.setAverage(averageList);
+        }
+
+
+        return deviationAnalyzeVo;
+    }
+
+    /**
+     * 鏌ヨ鏈湀涓庝笂鏈堝悎鏍肩巼瀵规瘮
+     * @param dataAnalysisDto
+     * @return
+     */
+    @Override
+    public List<Map<String, Object>> getRawUpMonth(DataAnalysisDto dataAnalysisDto) {
+        return dataAnalysisMapper.getRawUpMonth();
+    }
+
+    /**
+     * 鏌ヨ妫�楠岄」绫诲瀷楗煎浘
+     * @param dataAnalysisDto
+     * @return
+     */
+    @Override
+    public Map<String, Object> getOrderTypeCookie(DataAnalysisDto dataAnalysisDto) {
+        return dataAnalysisMapper.getOrderTypeCookie();
+    }
+
+    /**
+     * 璁$畻杩斿洖鏁版嵁
+     * @param lastValues
+     * @return
+     */
+    private static Map<String, List<Object>> dataCompute(List<String> lastValues) {
+        // 骞冲潎鍊�
+        BigDecimal average = computeAverage(lastValues);
+
+        // 鏍囧噯鍋忓樊
+        BigDecimal standardDeviation = computeStandardDeviation(lastValues);
+
+        // 鐩稿鍋忓樊
+        BigDecimal relativeDeviation = standardDeviation.divide(average, 2, RoundingMode.HALF_UP);
+
+        // 骞冲潎鐩稿鍋忓樊
+        BigDecimal sqrt5 = BigDecimal.valueOf(Math.sqrt(5));
+        BigDecimal averageRelativeDeviation = standardDeviation.divide(sqrt5, 2, RoundingMode.HALF_UP);
+
+        // ucl
+        BigDecimal ucl = average.add(new BigDecimal("3").multiply(standardDeviation)).setScale(2, RoundingMode.HALF_UP);
+
+        // lcl
+        BigDecimal lcl = average.subtract(new BigDecimal("3").multiply(standardDeviation)).setScale(2, RoundingMode.HALF_UP);
+
+        // 鏋佸樊
+        BigDecimal range = computeRange(lastValues);
+
+        // 鏁版嵁鎷兼帴
+        // 妫�娴嬫暟鎹�
+        List<Object> data = new ArrayList<>();
+        for (String lastValue : lastValues) {
+            data.add(lastValue);
+        }
+        data.add(average);
+        data.add(standardDeviation);
+        data.add(relativeDeviation);
+        data.add(averageRelativeDeviation);
+
+        //ucl
+        List<Object> uclData = new ArrayList<>();
+
+        //lcl
+        List<Object> lclData = new ArrayList<>();
+
+        //骞冲潎鍊�
+        List<Object> averageData = new ArrayList<>();
+
+        //鏋佸樊
+        List<Object> rangeData = new ArrayList<>();
+        for (int i = 0; i < 5; i++) {
+            uclData.add(ucl);
+            lclData.add(lcl);
+            averageData.add(average);
+            rangeData.add(range);
+        }
+        Map<String, List<Object>> map = new HashMap<>();
+        map.put("data", data);
+        map.put("uclData", uclData);
+        map.put("lclData", lclData);
+        map.put("averageData", averageData);
+        map.put("rangeData", rangeData);
+
+        return map;
+    }
+
+
+    /**
+     * 璁$畻鏋佸樊
+     * @param lastValues
+     * @return
+     */
+    public static BigDecimal computeRange(List<String> lastValues) {
+        int count = 0;
+
+        BigDecimal min = null;
+        BigDecimal max = null;
+
+        for (String value : lastValues) {
+            if (StrUtil.isNotBlank(value)) {
+                BigDecimal bigDecimalValue = new BigDecimal(value);
+
+                if (min == null || bigDecimalValue.compareTo(min) < 0) {
+                    min = bigDecimalValue;
+                }
+
+                if (max == null || bigDecimalValue.compareTo(max) > 0) {
+                    max = bigDecimalValue;
+                }
+                count++;
+            }
+
+        }
+
+        if (count == 0 || min == null || max == null) {
+            return BigDecimal.ZERO;
+        }
+
+        BigDecimal range = max.subtract(min);
+
+        return range.setScale(2, RoundingMode.HALF_UP);
+    }
+
+    /**
+     * 璁$畻骞冲潎鍊�
+     * @param values
+     * @return
+     */
+    private static BigDecimal computeAverage(List<String> values) {
+        BigDecimal sum = BigDecimal.ZERO;
+        int count = 0;
+
+        for (String value : values) {
+            if (StrUtil.isNotBlank(value)) {
+
+                BigDecimal number = new BigDecimal(value);
+                sum = sum.add(number);
+                count++;
+
+            }
+        }
+
+        return count == 0 ? BigDecimal.ZERO : sum.divide(BigDecimal.valueOf(count), 2, BigDecimal.ROUND_HALF_UP);
+    }
+
+    /**
+     * 璁$畻鏍囧噯鍋忓樊
+     * @return
+     */
+    private static BigDecimal computeStandardDeviation(List<String> lastValues) {
+        int count = 0;
+
+        // 灏嗗瓧绗︿覆杞崲涓� BigDecimal 鍒楄〃
+        List<BigDecimal> values = new ArrayList<>();
+        for (String value : lastValues) {
+            if (StrUtil.isNotBlank(value)) {
+                values.add(new BigDecimal(value));
+                count++;
+            }
+        }
+
+        if (count == 0) {
+            return BigDecimal.ZERO;
+        }
+
+        // 璁$畻骞冲潎鍊�
+        BigDecimal sum = BigDecimal.ZERO;
+        for (BigDecimal value : values) {
+            sum = sum.add(value);
+        }
+        BigDecimal mean = sum.divide(new BigDecimal(values.size()), MathContext.DECIMAL128);
+
+        // 璁$畻姣忎釜鏁板�间笌骞冲潎鍊肩殑宸殑骞虫柟
+        BigDecimal squaredDifferenceSum = BigDecimal.ZERO;
+        for (BigDecimal value : values) {
+            BigDecimal difference = value.subtract(mean);
+            BigDecimal squaredDifference = difference.multiply(difference);
+            squaredDifferenceSum = squaredDifferenceSum.add(squaredDifference);
+        }
+
+        // 璁$畻鏍囧噯宸紝娉ㄦ剰杩欓噷浣跨敤鐨勬槸鏍锋湰鏍囧噯宸绠楀叕寮�
+        BigDecimal variance = squaredDifferenceSum.divide(new BigDecimal(values.size() - 1), MathContext.DECIMAL128);
+        BigDecimal stddev = sqrt(variance);
+
+        // 淇濈暀涓や綅灏忔暟
+        return stddev.setScale(2, RoundingMode.HALF_UP);
+    }
+
+    private static BigDecimal sqrt(BigDecimal value) {
+        // 浣跨敤 Heron's method 璁$畻骞虫柟鏍�
+        BigDecimal x = value;
+        BigDecimal tolerance = new BigDecimal("1E-10");
+        BigDecimal guess = value.divide(BigDecimal.valueOf(2), MathContext.DECIMAL128);
+
+        while (x.subtract(guess).abs().compareTo(tolerance) > 0) {
+            x = guess;
+            guess = x.add(value.divide(x, MathContext.DECIMAL128)).divide(new BigDecimal("2"), MathContext.DECIMAL128);
+        }
+
+        return guess;
+    }
+
+    /**
+     * *****鏍煎紡鍖栧瓧娈�****
+     * @param dataAnalysisDto
+     */
+    private void formatDataAnalysisDto(DataAnalysisDto dataAnalysisDto) {
+        // 鏍煎紡璇濆瓧娈�, 閬垮厤鎶ラ敊
+        if (StrUtil.isBlank(dataAnalysisDto.getOrderType())) {
+            dataAnalysisDto.setOrderType("1");
+        }
+        if (dataAnalysisDto.getOrderType().equals("2")) {
+            // 瀛e害妫�楠�
+            dataAnalysisDto.setOrderType(InsOrderTypeConstants.QUARTERLY_TEST);
+        } else {
+            // 杩涘巶妫�楠�
+            dataAnalysisDto.setOrderType(InsOrderTypeConstants.ENTER_THE_FACTORY);
+        }
+        if (StrUtil.isBlank(dataAnalysisDto.getDateType())) {
+            dataAnalysisDto.setDateType("1");
+        }
+        if (StrUtil.isBlank(dataAnalysisDto.getGroupType())) {
+            dataAnalysisDto.setGroupType("0");
+        }
+    }
+
+}

--
Gitblit v1.9.3