diff --git a/aucma-base/src/main/java/com/aucma/base/controller/BaseDeviceParamValController.java b/aucma-base/src/main/java/com/aucma/base/controller/BaseDeviceParamValController.java index ded44e2..00bf5a5 100644 --- a/aucma-base/src/main/java/com/aucma/base/controller/BaseDeviceParamValController.java +++ b/aucma-base/src/main/java/com/aucma/base/controller/BaseDeviceParamValController.java @@ -14,6 +14,7 @@ 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.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.aucma.common.annotation.Log; import com.aucma.common.core.controller.BaseController; @@ -147,4 +148,48 @@ public class BaseDeviceParamValController extends BaseController { return success(baseDeviceParamValService.selectDeviceStartTimeList()); } + /** + * 参数追溯列表(分页) + */ + @PreAuthorize("@ss.hasPermi('baseDeviceParamVal:trace:list')" ) + @GetMapping("/trace/list" ) + public TableDataInfo traceList( + @RequestParam("deviceCode") String deviceCode, + @RequestParam(value = "paramCode", required = false) String paramCode, + @RequestParam("startTime") String startTime, + @RequestParam("endTime") String endTime) { + startPage(); + List list = baseDeviceParamValService.selectTraceList(deviceCode, paramCode, startTime, endTime); + return getDataTable(list); + } + + /** + * 导出参数追溯数据 + */ + @PreAuthorize("@ss.hasPermi('baseDeviceParamVal:trace:export')" ) + @Log(title = "参数追溯数据导出" , businessType = BusinessType.EXPORT) + @PostMapping("/trace/export" ) + public void traceExport(HttpServletResponse response, + @RequestParam("deviceCode") String deviceCode, + @RequestParam(value = "paramCode", required = false) String paramCode, + @RequestParam("startTime") String startTime, + @RequestParam("endTime") String endTime) { + List list = baseDeviceParamValService.selectTraceList(deviceCode, paramCode, startTime, endTime); + ExcelUtil util = new ExcelUtil(BaseDeviceParamVal.class); + util.exportExcel(response, list, "参数追溯数据"); + } + + /** + * 获取SPC分析数据 + */ + @PreAuthorize("@ss.hasPermi('baseDeviceParamVal:trace:list')" ) + @GetMapping("/spcData" ) + public AjaxResult getSPCData( + @RequestParam("deviceCode") String deviceCode, + @RequestParam("paramCode") String paramCode, + @RequestParam("startTime") String startTime, + @RequestParam("endTime") String endTime) { + return success(baseDeviceParamValService.getSPCData(deviceCode, paramCode, startTime, endTime)); + } + } diff --git a/aucma-base/src/main/java/com/aucma/base/mapper/BaseDeviceParamValMapper.java b/aucma-base/src/main/java/com/aucma/base/mapper/BaseDeviceParamValMapper.java index dd8bda0..ad478be 100644 --- a/aucma-base/src/main/java/com/aucma/base/mapper/BaseDeviceParamValMapper.java +++ b/aucma-base/src/main/java/com/aucma/base/mapper/BaseDeviceParamValMapper.java @@ -89,4 +89,28 @@ public interface BaseDeviceParamValMapper * @return 设备开机时间列表 */ public List> selectDeviceStartTimeList(); + + /** + * 参数追溯查询(按时间范围) + * + * @param params 查询参数(deviceCode, paramCode, startTime, endTime) + * @return 参数记录列表 + */ + public List selectTraceList(Map params); + + /** + * 查询SPC分析数据(参数历史值) + * + * @param params 查询参数(deviceCode, paramCode, startTime, endTime) + * @return 参数值列表 + */ + public List selectParamHistoryValues(Map params); + + /** + * 查询参数名称 + * + * @param paramCode 参数编号 + * @return 参数名称 + */ + public String selectParamNameByCode(String paramCode); } diff --git a/aucma-base/src/main/java/com/aucma/base/service/IBaseDeviceParamValService.java b/aucma-base/src/main/java/com/aucma/base/service/IBaseDeviceParamValService.java index 8ea6640..4cd98dd 100644 --- a/aucma-base/src/main/java/com/aucma/base/service/IBaseDeviceParamValService.java +++ b/aucma-base/src/main/java/com/aucma/base/service/IBaseDeviceParamValService.java @@ -89,4 +89,26 @@ public interface IBaseDeviceParamValService * @return 设备开机时间列表 */ public List> selectDeviceStartTimeList(); + + /** + * 参数追溯查询(按时间范围) + * + * @param deviceCode 设备编号 + * @param paramCode 参数编号(可选) + * @param startTime 开始时间 + * @param endTime 结束时间 + * @return 参数记录列表 + */ + public List selectTraceList(String deviceCode, String paramCode, String startTime, String endTime); + + /** + * 获取SPC分析数据 + * + * @param deviceCode 设备编号 + * @param paramCode 参数编号 + * @param startTime 开始时间 + * @param endTime 结束时间 + * @return SPC分析结果 + */ + public Map getSPCData(String deviceCode, String paramCode, String startTime, String endTime); } diff --git a/aucma-base/src/main/java/com/aucma/base/service/impl/BaseDeviceParamValServiceImpl.java b/aucma-base/src/main/java/com/aucma/base/service/impl/BaseDeviceParamValServiceImpl.java index 167e859..b5fa116 100644 --- a/aucma-base/src/main/java/com/aucma/base/service/impl/BaseDeviceParamValServiceImpl.java +++ b/aucma-base/src/main/java/com/aucma/base/service/impl/BaseDeviceParamValServiceImpl.java @@ -1,5 +1,6 @@ package com.aucma.base.service.impl; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -193,4 +194,115 @@ public class BaseDeviceParamValServiceImpl implements IBaseDeviceParamValService return Collections.emptyList(); } } + + /** + * 参数追溯查询(按时间范围) + */ + @Override + public List selectTraceList(String deviceCode, String paramCode, String startTime, String endTime) { + try { + Map params = new HashMap<>(); + params.put("deviceCode", deviceCode); + params.put("paramCode", paramCode); + params.put("startTime", startTime); + params.put("endTime", endTime); + List list = baseDeviceParamValMapper.selectTraceList(params); + return list != null ? list : Collections.emptyList(); + } catch (Exception e) { + log.error("参数追溯查询失败: {}", e.getMessage()); + return Collections.emptyList(); + } + } + + /** + * 获取SPC分析数据 + */ + @Override + public Map getSPCData(String deviceCode, String paramCode, String startTime, String endTime) { + Map result = new HashMap<>(); + result.put("deviceCode", deviceCode); + result.put("paramCode", paramCode); + + try { + // 查询参数名称 + String paramName = baseDeviceParamValMapper.selectParamNameByCode(paramCode); + result.put("paramName", paramName != null ? paramName : paramCode); + + // 查询参数历史值 + Map params = new HashMap<>(); + params.put("deviceCode", deviceCode); + params.put("paramCode", paramCode); + params.put("startTime", startTime); + params.put("endTime", endTime); + List values = baseDeviceParamValMapper.selectParamHistoryValues(params); + + if (values == null || values.isEmpty()) { + result.put("values", new ArrayList<>()); + result.put("sampleSize", 0); + result.put("mean", 0.0); + result.put("stdDev", 0.0); + result.put("cpk", 0.0); + result.put("ucl", 0.0); + result.put("lcl", 0.0); + result.put("cl", 0.0); + return result; + } + + result.put("values", values); + result.put("sampleSize", values.size()); + + // 计算统计指标 + double mean = calculateMean(values); + double stdDev = calculateStdDev(values, mean); + double ucl = mean + 3 * stdDev; + double lcl = mean - 3 * stdDev; + + result.put("mean", Math.round(mean * 1000.0) / 1000.0); + result.put("stdDev", Math.round(stdDev * 1000.0) / 1000.0); + result.put("ucl", Math.round(ucl * 1000.0) / 1000.0); + result.put("lcl", Math.round(lcl * 1000.0) / 1000.0); + result.put("cl", Math.round(mean * 1000.0) / 1000.0); + + // 计算CPK(假设规格限为均值±10%) + double usl = mean * 1.1; + double lsl = mean * 0.9; + double cpk = calculateCPK(mean, stdDev, usl, lsl); + result.put("cpk", Math.round(cpk * 100.0) / 100.0); + result.put("usl", Math.round(usl * 1000.0) / 1000.0); + result.put("lsl", Math.round(lsl * 1000.0) / 1000.0); + + return result; + } catch (Exception e) { + log.error("获取SPC分析数据失败: {}", e.getMessage()); + result.put("error", e.getMessage()); + return result; + } + } + + private double calculateMean(List values) { + if (values == null || values.isEmpty()) return 0.0; + double sum = 0.0; + for (Double v : values) { + if (v != null) sum += v; + } + return sum / values.size(); + } + + private double calculateStdDev(List values, double mean) { + if (values == null || values.size() < 2) return 0.0; + double sumSquares = 0.0; + for (Double v : values) { + if (v != null) { + sumSquares += Math.pow(v - mean, 2); + } + } + return Math.sqrt(sumSquares / (values.size() - 1)); + } + + private double calculateCPK(double mean, double stdDev, double usl, double lsl) { + if (stdDev == 0) return 0.0; + double cpupper = (usl - mean) / (3 * stdDev); + double cplower = (mean - lsl) / (3 * stdDev); + return Math.min(cpupper, cplower); + } } diff --git a/aucma-base/src/main/resources/mapper/base/BaseDeviceParamValMapper.xml b/aucma-base/src/main/resources/mapper/base/BaseDeviceParamValMapper.xml index 01c7487..1fbbe7a 100644 --- a/aucma-base/src/main/resources/mapper/base/BaseDeviceParamValMapper.xml +++ b/aucma-base/src/main/resources/mapper/base/BaseDeviceParamValMapper.xml @@ -202,4 +202,43 @@ WHERE d.is_flag = 1 ORDER BY d.product_line_code, d.device_code + + + + + + + + + \ No newline at end of file diff --git a/aucma-common/src/main/java/com/aucma/common/utils/poi/ExcelUtil.java b/aucma-common/src/main/java/com/aucma/common/utils/poi/ExcelUtil.java index 0d9000c..0d0369b 100644 --- a/aucma-common/src/main/java/com/aucma/common/utils/poi/ExcelUtil.java +++ b/aucma-common/src/main/java/com/aucma/common/utils/poi/ExcelUtil.java @@ -356,6 +356,10 @@ public class ExcelUtil Map cellMap = new HashMap(); // 获取表头 Row heard = sheet.getRow(titleNum); + if (heard == null) + { + throw new IOException("Excel文件格式错误:第" + (titleNum + 1) + "行(表头行)为空,请检查Excel文件结构"); + } for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++) { Cell cell = heard.getCell(i);