diff --git a/detection/src/main/java/com/njcn/gather/device/service/IPqDevService.java b/detection/src/main/java/com/njcn/gather/device/service/IPqDevService.java index 5651502e..387d9170 100644 --- a/detection/src/main/java/com/njcn/gather/device/service/IPqDevService.java +++ b/detection/src/main/java/com/njcn/gather/device/service/IPqDevService.java @@ -208,4 +208,12 @@ public interface IPqDevService extends IService { * @param patternId 模式Id */ void importCNDev(List cnDevExcelList, String patternId); + + /** + * 根据计划id列表获取设备列表 + * + * @param planIds + * @return + */ + List listByPlanIds(List planIds); } diff --git a/detection/src/main/java/com/njcn/gather/device/service/impl/PqDevServiceImpl.java b/detection/src/main/java/com/njcn/gather/device/service/impl/PqDevServiceImpl.java index 95d24f1c..3894da14 100644 --- a/detection/src/main/java/com/njcn/gather/device/service/impl/PqDevServiceImpl.java +++ b/detection/src/main/java/com/njcn/gather/device/service/impl/PqDevServiceImpl.java @@ -593,7 +593,7 @@ public class PqDevServiceImpl extends ServiceImpl implements i = pqDev.getReCheckNum(); } else { checkState = CheckStateEnum.CHECKED.getValue(); - i = pqDev.getReCheckNum() + 1; + i = pqDev.getReCheckNum() + 1; } this.update(new LambdaUpdateWrapper() .set(PqDev::getReCheckNum, i) @@ -760,6 +760,12 @@ public class PqDevServiceImpl extends ServiceImpl implements this.saveBatch(newDevList); } + @Override + public List listByPlanIds(List planIds) { + return this.lambdaQuery().in(PqDev::getPlanId, planIds).eq(PqDev::getState, DataStateEnum.ENABLE.getCode()).list(); + } + + /** * 获取检测状态饼状图数据 * diff --git a/detection/src/main/java/com/njcn/gather/plan/controller/AdPlanController.java b/detection/src/main/java/com/njcn/gather/plan/controller/AdPlanController.java index 10682c18..fbaa95ce 100644 --- a/detection/src/main/java/com/njcn/gather/plan/controller/AdPlanController.java +++ b/detection/src/main/java/com/njcn/gather/plan/controller/AdPlanController.java @@ -196,10 +196,10 @@ public class AdPlanController extends BaseController { @PostMapping("/analyse") @ApiOperation("检测数据分析") @ApiImplicitParam(name = "planId", value = "检测计划id", required = true) - public void analyse(String planId) { + public void analyse(@RequestBody List ids) { String methodDescribe = getMethodDescribe("analyse"); - LogUtil.njcnDebug(log, "{},查询数据为:{}", methodDescribe, planId); - adPlanService.analyse(planId); + LogUtil.njcnDebug(log, "{},查询数据为:{}", methodDescribe, String.join(StrUtil.COMMA, ids)); + adPlanService.analyse(ids); } } diff --git a/detection/src/main/java/com/njcn/gather/plan/service/IAdPlanService.java b/detection/src/main/java/com/njcn/gather/plan/service/IAdPlanService.java index 768c7bec..bb75f6cc 100644 --- a/detection/src/main/java/com/njcn/gather/plan/service/IAdPlanService.java +++ b/detection/src/main/java/com/njcn/gather/plan/service/IAdPlanService.java @@ -114,7 +114,7 @@ public interface IAdPlanService extends IService { /** * 数据分析 * - * @param planId + * @param ids */ - void analyse(String planId); + void analyse(List ids); } diff --git a/detection/src/main/java/com/njcn/gather/plan/service/impl/AdPlanServiceImpl.java b/detection/src/main/java/com/njcn/gather/plan/service/impl/AdPlanServiceImpl.java index 230a4cdd..5291dfcb 100644 --- a/detection/src/main/java/com/njcn/gather/plan/service/impl/AdPlanServiceImpl.java +++ b/detection/src/main/java/com/njcn/gather/plan/service/impl/AdPlanServiceImpl.java @@ -414,55 +414,85 @@ public class AdPlanServiceImpl extends ServiceImpl impleme } @Override - public void analyse(String planId) { - AdPlan adPlan = this.getById(planId); - if (ObjectUtil.isNull(adPlan)) { - throw new BusinessException(PlanResponseEnum.PLAN_NOT_EXIST); - } else { - List rows = new ArrayList<>(); + public void analyse(List ids) { + SysTestConfig config = sysTestConfigService.getOneConfig(); + if (ObjectUtil.isNotNull(config)) { + Integer maxTime = config.getMaxTime(); + List planList = this.listByIds(ids); - SysTestConfig config = sysTestConfigService.getOneConfig(); - if (ObjectUtil.isNotNull(config)) { - String[] row1 = new String[]{adPlan.getName()}; - rows.add(row1); + Map> sheets = new HashMap<>(); - Integer maxTime = config.getMaxTime(); - String[] row2 = new String[maxTime + 1]; - row2[0] = "\\"; - PqDevParam.QueryParam param = new PqDevParam.QueryParam(); - param.setPlanId(planId); - List devList = pqDevService.listByPlanId(param); - String[] row3 = new String[maxTime + 1]; - row3[0] = "合格数量"; - String[] row4 = new String[maxTime + 1]; - row4[0] = "总数量"; - String[] row5 = new String[maxTime + 1]; - row5[0] = "合格率"; - for (int i = 1; i <= maxTime; i++) { - row2[i] = i + "次检测"; - int tempI = i; - List tempDevList = devList.stream().filter(dev -> dev.getReCheckNum().equals(tempI)).collect(Collectors.toList()); - long total = tempDevList.stream().filter(dev -> dev.getCheckResult() != CheckResultEnum.UNCHECKED.getValue()).count(); - long passCount = tempDevList.stream().filter(dev -> dev.getCheckResult() == CheckResultEnum.ACCORD.getValue()).count(); - row3[i] = passCount + ""; - row4[i] = total + ""; - - if (total != 0) { - row5[i] = String.format("%.2f%%", (float) passCount / total * 100); - } else { - row5[i] = "/"; - } + if (planList.size() > 1) { + List allDevList = new ArrayList<>(); + for (AdPlan plan : planList) { + PqDevParam.QueryParam queryParam = new PqDevParam.QueryParam(); + queryParam.setPlanId(plan.getId()); + List devList = pqDevService.listByPlanId(queryParam); + devList = devList.stream().filter(x -> !x.getCheckResult().equals(CheckResultEnum.UNCHECKED.getValue())).collect(Collectors.toList()); + allDevList.addAll(devList); + sheets.put(plan.getName(), getRows(plan.getName(), devList, maxTime)); } - rows.add(row2); - rows.add(row3); - rows.add(row4); - rows.add(row5); - exportPassRateExcel("分析结果.xlsx", maxTime, rows); + sheets.put("All", getRows("数据分析结果-所有计划", allDevList, maxTime)); + } else { + AdPlan plan = planList.get(0); + PqDevParam.QueryParam queryParam = new PqDevParam.QueryParam(); + queryParam.setPlanId(plan.getId()); + List devList = pqDevService.listByPlanId(queryParam); + devList = devList.stream().filter(x -> !x.getCheckResult().equals(CheckResultEnum.UNCHECKED.getValue())).collect(Collectors.toList()); + sheets.put(plan.getName(), getRows(plan.getName(), devList, maxTime)); } + exportPassRateExcel("数据分析结果.xlsx", maxTime, sheets); } } + + /** + * 获取行数据 + * + * @param header 表头 + * @param devList 设备列表 + * @param maxTime 最大复检次数 + * @return + */ + private List getRows(String header, List devList, Integer maxTime) { + List rows = new ArrayList<>(); + String[] row1 = new String[]{header}; + + String[] row2 = new String[maxTime + 1]; + row2[0] = "\\"; + String[] row3 = new String[maxTime + 1]; + row3[0] = "合格数量"; + String[] row4 = new String[maxTime + 1]; + row4[0] = "已检数量"; + String[] row5 = new String[maxTime + 1]; + row5[0] = "合格率"; + + long total = devList.size(); + + for (int i = 1; i <= maxTime; i++) { + row2[i] = i + "次检测"; + int tempI = i; + List tempDevList = devList.stream().filter(dev -> dev.getReCheckNum() <= tempI).collect(Collectors.toList()); + long passCount = tempDevList.stream().filter(dev -> dev.getCheckResult() == CheckResultEnum.ACCORD.getValue()).count(); + row3[i] = passCount + ""; + row4[i] = total + ""; + + if (total != 0) { + row5[i] = String.format("%.2f%%", (float) passCount / total * 100); + } else { + row5[i] = "/"; + } + } + rows.add(row1); + rows.add(row2); + rows.add(row3); + rows.add(row4); + rows.add(row5); + + return rows; + } + /** * 逆向可视化 * @@ -522,140 +552,144 @@ public class AdPlanServiceImpl extends ServiceImpl impleme } } - private void exportPassRateExcel(String fileName, Integer maxTime, List rows) { + private void exportPassRateExcel(String fileName, Integer maxTime, Map> sheets) { HttpServletResponse response = HttpServletUtil.getResponse(); XSSFWorkbook wb = new XSSFWorkbook(); - String sheetName = "Sheet1"; + try (ServletOutputStream outputStream = response.getOutputStream()) { fileName = URLEncoder.encode(fileName, CharsetUtil.UTF_8); response.reset(); response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\""); response.setContentType("application/octet-stream;charset=UTF-8"); - XSSFSheet sheet = wb.createSheet(sheetName); - // 数据行 - CellStyle cellStyle = wb.createCellStyle(); - cellStyle.setAlignment(HorizontalAlignment.CENTER); - cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); - XSSFFont headerFont = wb.createFont(); - headerFont.setFontName("Microsoft YaHei"); - headerFont.setBold(true); - headerFont.setFontHeightInPoints((short) 14); - cellStyle.setFont(headerFont); - Row row0 = sheet.createRow(0); - Cell row0Cell0 = row0.createCell(0); - row0Cell0.setCellStyle(cellStyle); - row0Cell0.setCellValue(rows.get(0)[0]); - for (int i = 1; i < maxTime + 1; i++) { - row0.createCell(i); - } - CellRangeAddress mergedRegion = new CellRangeAddress(0, 0, 0, maxTime); - sheet.addMergedRegion(mergedRegion); + sheets.forEach((sheetName, rows) -> { + XSSFSheet sheet = wb.createSheet(sheetName); - CellStyle commoncellStyle = wb.createCellStyle(); - commoncellStyle.setAlignment(HorizontalAlignment.CENTER); - commoncellStyle.setVerticalAlignment(VerticalAlignment.CENTER); + // 数据行 + CellStyle cellStyle = wb.createCellStyle(); + cellStyle.setAlignment(HorizontalAlignment.CENTER); + cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); + XSSFFont headerFont = wb.createFont(); + headerFont.setFontName("Microsoft YaHei"); + headerFont.setBold(true); + headerFont.setFontHeightInPoints((short) 14); + cellStyle.setFont(headerFont); + Row row0 = sheet.createRow(0); + Cell row0Cell0 = row0.createCell(0); + row0Cell0.setCellStyle(cellStyle); + row0Cell0.setCellValue(rows.get(0)[0]); + for (int i = 1; i < maxTime + 1; i++) { + row0.createCell(i); + } + CellRangeAddress mergedRegion = new CellRangeAddress(0, 0, 0, maxTime); + sheet.addMergedRegion(mergedRegion); - for (int i = 1; i < rows.size(); i++) { - String[] row = rows.get(i); - Row createRow = sheet.createRow(i); - for (int j = 0; j < row.length; j++) { - Cell createCell = createRow.createCell(j); - if (j == 0 || i == 1) { - headerFont.setFontHeightInPoints((short) 11); - createCell.setCellStyle(cellStyle); - } else { - createCell.setCellStyle(commoncellStyle); - } - if ("\\".equals(row[j])) { - CreationHelper helper = wb.getCreationHelper(); - XSSFDrawing drawing = sheet.createDrawingPatriarch(); - ClientAnchor anchor = helper.createClientAnchor(); - // 设置斜线的开始位置 - anchor.setCol1(j); - anchor.setRow1(i); - // 设置斜线的结束位置 - anchor.setCol2(j + 1); - anchor.setRow2(i + 1); - XSSFSimpleShape shape = drawing.createSimpleShape((XSSFClientAnchor) anchor); + CellStyle commoncellStyle = wb.createCellStyle(); + commoncellStyle.setAlignment(HorizontalAlignment.CENTER); + commoncellStyle.setVerticalAlignment(VerticalAlignment.CENTER); - // 设置形状类型为线型 - shape.setShapeType(ShapeTypes.LINE); - // 设置线宽 - shape.setLineWidth(0.5); - // 设置线的风格 - shape.setLineStyle(0); - // 设置线的颜色 - shape.setLineStyleColor(0, 0, 0); - } else { - createCell.setCellValue(row[j]); + for (int i = 1; i < rows.size(); i++) { + String[] row = rows.get(i); + Row createRow = sheet.createRow(i); + for (int j = 0; j < row.length; j++) { + Cell createCell = createRow.createCell(j); + if (j == 0 || i == 1) { + headerFont.setFontHeightInPoints((short) 11); + createCell.setCellStyle(cellStyle); + } else { + createCell.setCellStyle(commoncellStyle); + } + if ("\\".equals(row[j])) { + CreationHelper helper = wb.getCreationHelper(); + XSSFDrawing drawing = sheet.createDrawingPatriarch(); + ClientAnchor anchor = helper.createClientAnchor(); + // 设置斜线的开始位置 + anchor.setCol1(j); + anchor.setRow1(i); + // 设置斜线的结束位置 + anchor.setCol2(j + 1); + anchor.setRow2(i + 1); + XSSFSimpleShape shape = drawing.createSimpleShape((XSSFClientAnchor) anchor); + + // 设置形状类型为线型 + shape.setShapeType(ShapeTypes.LINE); + // 设置线宽 + shape.setLineWidth(0.5); + // 设置线的风格 + shape.setLineStyle(0); + // 设置线的颜色 + shape.setLineStyleColor(0, 0, 0); + } else { + createCell.setCellValue(row[j]); + } } } - } - // 条形图 - XSSFDrawing drawing = sheet.createDrawingPatriarch(); - // 前四个默认0,[0,5]:从0列5行开始;[6,16]:到6列16行结束 - // 默认宽度(14-8)*12 - XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, maxTime + 1, 25); - // 创建一个chart对象 - XSSFChart chart = drawing.createChart(anchor); - // 标题 - chart.setTitleText("检测结果分析"); - // 标题覆盖 - chart.setTitleOverlay(false); - // 图例位置 - XDDFChartLegend legend = chart.getOrAddLegend(); - legend.setPosition(LegendPosition.TOP); - // 分类轴标(X轴),标题位置 - XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM); - bottomAxis.setTitle("检测次数"); - // 值(Y轴)轴,标题位置 - XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT); - leftAxis.setTitle("合格率(%)"); + // 条形图 + XSSFDrawing drawing = sheet.createDrawingPatriarch(); + // 前四个默认0,[0,5]:从0列5行开始;[6,16]:到6列16行结束 + // 默认宽度(14-8)*12 + XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, maxTime + 1, 25); + // 创建一个chart对象 + XSSFChart chart = drawing.createChart(anchor); + // 标题 + chart.setTitleText("检测结果分析"); + // 标题覆盖 + chart.setTitleOverlay(false); + // 图例位置 + XDDFChartLegend legend = chart.getOrAddLegend(); + legend.setPosition(LegendPosition.TOP); + // 分类轴标(X轴),标题位置 + XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM); + bottomAxis.setTitle("检测次数"); + // 值(Y轴)轴,标题位置 + XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT); + leftAxis.setTitle("合格率(%)"); - // CellRangeAddress(起始行号,终止行号, 起始列号,终止列号) - // 分类轴标(X轴)数据,单元格范围位置[1, 1]到[1, maxTime] - XDDFDataSource checkTimes = XDDFDataSourcesFactory.fromStringCellRange(sheet, new CellRangeAddress(1, 1, 1, maxTime)); - // 数据 - String[] rateStrArr = rows.get(rows.size() - 1); - Double[] rateArr = new Double[maxTime]; - for (int i = 1; i < rateStrArr.length; i++) { - if("/".equals(rateStrArr[i])){ - rateArr[i - 1] = 0.00; - }else{ - rateArr[i - 1] = Double.parseDouble(rateStrArr[i].replace("%", "")); + // CellRangeAddress(起始行号,终止行号, 起始列号,终止列号) + // 分类轴标(X轴)数据,单元格范围位置[1, 1]到[1, maxTime] + XDDFDataSource checkTimes = XDDFDataSourcesFactory.fromStringCellRange(sheet, new CellRangeAddress(1, 1, 1, maxTime)); + // 数据 + String[] rateStrArr = rows.get(rows.size() - 1); + Double[] rateArr = new Double[maxTime]; + for (int i = 1; i < rateStrArr.length; i++) { + if ("/".equals(rateStrArr[i])) { + rateArr[i - 1] = 0.00; + } else { + rateArr[i - 1] = Double.parseDouble(rateStrArr[i].replace("%", "")); + } } - } - XDDFNumericalDataSource rate = XDDFDataSourcesFactory.fromArray(rateArr); + XDDFNumericalDataSource rate = XDDFDataSourcesFactory.fromArray(rateArr); - // bar:条形图, - XDDFBarChartData bar = (XDDFBarChartData) chart.createData(ChartTypes.BAR, bottomAxis, leftAxis); + // bar:条形图, + XDDFBarChartData bar = (XDDFBarChartData) chart.createData(ChartTypes.BAR, bottomAxis, leftAxis); - leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN); - // 设置为可变颜色 - bar.setVaryColors(true);// 这里可变颜色要设置成true,如果需要设置成自己想要的颜色,则置为false,然后在下面设置颜色 - // 条形图方向,纵向/横向:纵向 - bar.setBarDirection(BarDirection.COL); + leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN); + // 设置为可变颜色 + bar.setVaryColors(true);// 这里可变颜色要设置成true,如果需要设置成自己想要的颜色,则置为false,然后在下面设置颜色 + // 条形图方向,纵向/横向:纵向 + bar.setBarDirection(BarDirection.COL); - // 图表加载数据,条形图1 - bar.addSeries(checkTimes, rate); + // 图表加载数据,条形图1 + bar.addSeries(checkTimes, rate); - CTPlotArea plotArea = chart.getCTChart().getPlotArea(); + CTPlotArea plotArea = chart.getCTChart().getPlotArea(); - CTBarSer serArray = plotArea.getBarChartArray(0).getSerArray(0); - serArray.addNewDLbls(); - serArray.getDLbls().addNewShowVal().setVal(true); - serArray.getDLbls().addNewShowLegendKey().setVal(false); - serArray.getDLbls().addNewShowCatName().setVal(false); - serArray.getDLbls().addNewShowSerName().setVal(false); + CTBarSer serArray = plotArea.getBarChartArray(0).getSerArray(0); + serArray.addNewDLbls(); + serArray.getDLbls().addNewShowVal().setVal(true); + serArray.getDLbls().addNewShowLegendKey().setVal(false); + serArray.getDLbls().addNewShowCatName().setVal(false); + serArray.getDLbls().addNewShowSerName().setVal(false); - // 打印图表的xml - //System.out.println(chart.getCTChart()); + // 打印图表的xml + //System.out.println(chart.getCTChart()); + + // 绘制 + chart.plot(bar); + }); - // 绘制 - chart.plot(bar); wb.write(outputStream); wb.close(); } catch (IOException e) {