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 2daba460..27b2046c 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 @@ -13,7 +13,6 @@ import com.njcn.common.pojo.enums.response.CommonResponseEnum; import com.njcn.common.pojo.exception.BusinessException; import com.njcn.common.pojo.response.HttpResult; import com.njcn.common.utils.LogUtil; -import com.njcn.gather.device.service.IPqDevService; import com.njcn.gather.device.pojo.enums.DevResponseEnum; import com.njcn.gather.plan.pojo.param.AdPlanParam; import com.njcn.gather.plan.pojo.vo.AdPlanExcel; @@ -51,7 +50,7 @@ public class AdPlanController extends BaseController { private final IAdPlanService adPlanService; - @OperateInfo + @OperateInfo(info = LogEnum.BUSINESS_COMMON) @PostMapping("/list") @ApiOperation("分页查询检测计划") @ApiImplicitParam(name = "queryParam", value = "查询参数", required = true) @@ -62,7 +61,7 @@ public class AdPlanController extends BaseController { return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe); } - @OperateInfo(operateType = OperateType.ADD) + @OperateInfo(info = LogEnum.BUSINESS_COMMON, operateType = OperateType.ADD) @PostMapping("/add") @ApiOperation("新增检测计划") @ApiImplicitParam(name = "param", value = "检测计划", required = true) @@ -77,7 +76,7 @@ public class AdPlanController extends BaseController { } } - @OperateInfo(operateType = OperateType.UPDATE) + @OperateInfo(info = LogEnum.BUSINESS_COMMON, operateType = OperateType.UPDATE) @PostMapping("/update") @ApiOperation("修改检测计划") @ApiImplicitParam(name = "updateParam", value = "检测计划", required = true) @@ -92,7 +91,7 @@ public class AdPlanController extends BaseController { } } - @OperateInfo(operateType = OperateType.DELETE) + @OperateInfo(info = LogEnum.BUSINESS_COMMON, operateType = OperateType.DELETE) @PostMapping("/delete") @ApiOperation("删除检测计划") @ApiImplicitParam(name = "ids", value = "检测计划id", required = true) @@ -108,7 +107,7 @@ public class AdPlanController extends BaseController { } - @OperateInfo + @OperateInfo(info = LogEnum.BUSINESS_COMMON) @GetMapping("/listByPattern") @ApiOperation("按照模式查询检测计划") @ApiImplicitParam(name = "pattern", value = "模式Id", required = true) @@ -182,7 +181,7 @@ public class AdPlanController extends BaseController { // return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe); // } - @OperateInfo + @OperateInfo(info = LogEnum.BUSINESS_COMMON) @GetMapping("/getBigTestItem") @ApiOperation("获取检测大项数据") @ApiImplicitParam(name = "id", value = "检测计划id", required = true) @@ -193,5 +192,14 @@ public class AdPlanController extends BaseController { return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe); } + @OperateInfo(info = LogEnum.BUSINESS_COMMON, operateType = OperateType.DOWNLOAD) + @GetMapping("/analyse") + @ApiOperation("检测数据分析") + @ApiImplicitParam(name = "planId", value = "检测计划id", required = true) + public void analyse(String planId) { + String methodDescribe = getMethodDescribe("analyse"); + LogUtil.njcnDebug(log, "{},查询数据为:{}", methodDescribe, planId); + adPlanService.analyse(planId); + } } 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 eeb71aa6..768c7bec 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 @@ -110,4 +110,11 @@ public interface IAdPlanService extends IService { boolean updateBackTestState(String planId,List devIds); void finishPlan(String planId); + + /** + * 数据分析 + * + * @param planId + */ + void analyse(String planId); } 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 87e8e012..8240cd8d 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 @@ -2,6 +2,7 @@ package com.njcn.gather.plan.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.Wrapper; @@ -15,7 +16,6 @@ import com.njcn.common.pojo.exception.BusinessException; import com.njcn.gather.device.pojo.enums.*; import com.njcn.gather.device.pojo.param.PqDevParam; import com.njcn.gather.device.pojo.po.PqDev; -import com.njcn.gather.device.pojo.vo.PqDevVO; import com.njcn.gather.device.service.IPqDevService; import com.njcn.gather.err.service.IPqErrSysService; import com.njcn.gather.plan.mapper.AdPlanMapper; @@ -34,17 +34,33 @@ import com.njcn.gather.script.service.IPqScriptService; import com.njcn.gather.source.pojo.po.PqSource; import com.njcn.gather.source.service.IPqSourceService; import com.njcn.gather.storage.service.TableGenService; +import com.njcn.gather.system.config.pojo.po.SysTestConfig; +import com.njcn.gather.system.config.service.ISysTestConfigService; import com.njcn.gather.system.dictionary.pojo.po.DictTree; import com.njcn.gather.system.dictionary.service.IDictDataService; import com.njcn.gather.system.dictionary.service.IDictTreeService; import com.njcn.web.factory.PageFactory; import com.njcn.web.utils.ExcelUtil; +import com.njcn.web.utils.HttpServletUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ObjectUtils; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xddf.usermodel.PresetColor; +import org.apache.poi.xddf.usermodel.XDDFColor; +import org.apache.poi.xddf.usermodel.XDDFSolidFillProperties; +import org.apache.poi.xddf.usermodel.chart.*; +import org.apache.poi.xssf.usermodel.*; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTBarSer; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.net.URLEncoder; import java.util.*; import java.util.stream.Collectors; @@ -66,6 +82,7 @@ public class AdPlanServiceImpl extends ServiceImpl impleme private final IPqScriptDtlsService pqScriptDtlsService; private final IDictTreeService dictTreeService; private final TableGenService tableGenService; + private final ISysTestConfigService sysTestConfigService; @Override public Page listAdPlan(AdPlanParam.QueryParam queryParam) { @@ -162,7 +179,7 @@ public class AdPlanServiceImpl extends ServiceImpl impleme adPlanSourceService.deleteAdPlanSourceByPlanIds(ids); // 删除相关检测表格 - List codeList = this.listByIds(ids).stream().map(plan->String.valueOf(plan.getCode())).collect(Collectors.toList()); + List codeList = this.listByIds(ids).stream().map(plan -> String.valueOf(plan.getCode())).collect(Collectors.toList()); tableGenService.deleteTable(codeList); return this.lambdaUpdate().in(AdPlan::getId, ids).set(AdPlan::getState, DataStateEnum.DELETED.getCode()).update(); @@ -396,6 +413,55 @@ public class AdPlanServiceImpl extends ServiceImpl impleme .set(AdPlan::getTestState, CheckStateEnum.CHECKED.getValue()); } + @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<>(); + + SysTestConfig config = sysTestConfigService.getOneConfig(); + if (ObjectUtil.isNotNull(config)) { + String[] row1 = new String[]{adPlan.getName()}; + rows.add(row1); + + 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] = "/"; + } + } + rows.add(row2); + rows.add(row3); + rows.add(row4); + rows.add(row5); + exportPassRateExcel("分析结果.xlsx", maxTime, rows); + } + + } + } /** * 逆向可视化 @@ -455,4 +521,141 @@ public class AdPlanServiceImpl extends ServiceImpl impleme throw new BusinessException(PlanResponseEnum.PLAN_REPEATED); } } + + private void exportPassRateExcel(String fileName, Integer maxTime, List rows) { + + 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); + + CellStyle commoncellStyle = wb.createCellStyle(); + commoncellStyle.setAlignment(HorizontalAlignment.CENTER); + commoncellStyle.setVerticalAlignment(VerticalAlignment.CENTER); + + 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("合格率(%)"); + + // 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++) { + rateArr[i - 1] = Double.parseDouble(rateStrArr[i].replace("%", "")); + } + XDDFNumericalDataSource rate = XDDFDataSourcesFactory.fromArray(rateArr); + + // bar:条形图, + XDDFBarChartData bar = (XDDFBarChartData) chart.createData(ChartTypes.BAR, bottomAxis, leftAxis); + + leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN); + // 设置为可变颜色 + bar.setVaryColors(true);// 这里可变颜色要设置成true,如果需要设置成自己想要的颜色,则置为false,然后在下面设置颜色 + // 条形图方向,纵向/横向:纵向 + bar.setBarDirection(BarDirection.COL); + + // 图表加载数据,条形图1 + bar.addSeries(checkTimes, rate); + +// 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); + + // 打印图表的xml + //System.out.println(chart.getCTChart()); + + // 绘制 + chart.plot(bar); + wb.write(outputStream); + wb.close(); + } catch (IOException e) { + log.error(">>> 导出数据异常:{}", e.getMessage()); + } + } } diff --git a/system/src/main/java/com/njcn/gather/system/auth/controller/AuthController.java b/system/src/main/java/com/njcn/gather/system/auth/controller/AuthController.java index 2c48f8bd..96a9029e 100644 --- a/system/src/main/java/com/njcn/gather/system/auth/controller/AuthController.java +++ b/system/src/main/java/com/njcn/gather/system/auth/controller/AuthController.java @@ -91,7 +91,6 @@ public class AuthController extends BaseController { CustomCacheUtil customCacheUtil = SpringUtil.getBean(CustomCacheUtil.CACHE_NAME); customCacheUtil.putWithExpireTime(accessToken, JSON.toJSONString(user), DateUnit.DAY.getMillis() * 2); - customCacheUtil.putWithExpireTime(refreshToken, JSON.toJSONString(user), (DateUnit.DAY.getMillis() * 4)); sysLogAuditService.saveAuthLog(user.getName(), 1); return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, token, methodDescribe); @@ -105,13 +104,11 @@ public class AuthController extends BaseController { String methodDescribe = getMethodDescribe("logout"); LogUtil.njcnDebug(log, "{},注销登录", methodDescribe); String accessTokenStr = request.getHeader(SecurityConstants.AUTHORIZATION_KEY); - String refreshToken = request.getHeader(SecurityConstants.REFRESH_TOKEN_KEY); - if (StrUtil.isNotBlank(accessTokenStr) && StrUtil.isNotBlank(refreshToken)) { + if (StrUtil.isNotBlank(accessTokenStr)) { String accessToken = accessTokenStr.replace(SecurityConstants.AUTHORIZATION_PREFIX, Strings.EMPTY); CustomCacheUtil customCacheUtil = SpringUtil.getBean(CustomCacheUtil.CACHE_NAME); customCacheUtil.remove(accessToken); - customCacheUtil.remove(refreshToken); Map map = JwtUtil.parseToken(accessToken); SysUser user = sysUserService.getById((String) map.get(SecurityConstants.USER_ID)); @@ -128,25 +125,24 @@ public class AuthController extends BaseController { public HttpResult refreshToken(HttpServletRequest request) { String methodDescribe = getMethodDescribe("refreshToken"); LogUtil.njcnDebug(log, "{},刷新token", methodDescribe); - String refreshToken = request.getHeader(SecurityConstants.REFRESH_TOKEN_KEY); + String accessTokenStr = request.getHeader(SecurityConstants.AUTHORIZATION_KEY); Token token = new Token(); - if (StrUtil.isNotBlank(refreshToken)) { - Map map = JwtUtil.parseToken(refreshToken); + if (StrUtil.isNotBlank(accessTokenStr)) { + String accessToken = accessTokenStr.replace(SecurityConstants.AUTHORIZATION_PREFIX, Strings.EMPTY); + Map map = JwtUtil.parseToken(accessToken); String userId = (String) map.get(SecurityConstants.USER_ID); SysUser user = sysUserService.getById(userId); - String accessToken = JwtUtil.getAccessToken(userId); + String accessTokenNew = JwtUtil.getAccessToken(userId); + String refreshTokenNew = JwtUtil.getRefreshToken(accessTokenNew); - String refreshTokenNew = JwtUtil.getRefreshToken(accessToken); - - token.setAccessToken(accessToken); + token.setAccessToken(accessTokenNew); token.setRefreshToken(refreshTokenNew); CustomCacheUtil customCacheUtil = SpringUtil.getBean(CustomCacheUtil.CACHE_NAME); - customCacheUtil.remove(refreshToken); - customCacheUtil.putWithExpireTime(accessToken, JSON.toJSONString(user), DateUnit.DAY.getMillis() * 2); - customCacheUtil.putWithExpireTime(refreshTokenNew, JSON.toJSONString(user), (DateUnit.DAY.getMillis() * 4)); + customCacheUtil.remove(accessToken); + customCacheUtil.putWithExpireTime(accessTokenNew, JSON.toJSONString(user), DateUnit.DAY.getMillis() * 2); return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, token, methodDescribe); } else { return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, null, methodDescribe); diff --git a/system/src/main/java/com/njcn/gather/system/auth/filter/AuthGlobalFilter.java b/system/src/main/java/com/njcn/gather/system/auth/filter/AuthGlobalFilter.java index a4c1fabb..15b0a617 100644 --- a/system/src/main/java/com/njcn/gather/system/auth/filter/AuthGlobalFilter.java +++ b/system/src/main/java/com/njcn/gather/system/auth/filter/AuthGlobalFilter.java @@ -22,7 +22,7 @@ import java.util.List; @Slf4j @Component public class AuthGlobalFilter implements Filter, Ordered { - private final static List IGNORE_URI = Arrays.asList("/admin/login", "/report/generateReport", "/admin/refreshToken"); + private final static List IGNORE_URI = Arrays.asList("/admin/login", "/report/generateReport"); @Override public int getOrder() { @@ -66,7 +66,7 @@ public class AuthGlobalFilter implements Filter, Ordered { if ("true".equals(isRefreshToken)) { res.getWriter().write("{\"code\": 4001, \"message\":\"" + SystemValidMessage.TOKEN_EXPIRED + "\"}"); //前端重定向到登录页面 } else { - res.getWriter().write("{\"code\": 401, \"message\":\"" + SystemValidMessage.TOKEN_EXPIRED + "\"}"); //前端发起refreshToken请求 + res.getWriter().write("{\"code\": 401, \"message\":\"" + SystemValidMessage.ACCESS_TOKEN_EXPIRED + "\"}"); //前端发起refreshToken请求 } } else { filterChain.doFilter(req, res); diff --git a/system/src/main/java/com/njcn/gather/system/log/aop/LogAdvice.java b/system/src/main/java/com/njcn/gather/system/log/aop/LogAdvice.java index ec12c6d8..1eeb8fdc 100644 --- a/system/src/main/java/com/njcn/gather/system/log/aop/LogAdvice.java +++ b/system/src/main/java/com/njcn/gather/system/log/aop/LogAdvice.java @@ -65,10 +65,6 @@ public class LogAdvice implements ApplicationListener { String authorization = request.getHeader(SecurityConstants.AUTHORIZATION_KEY); if (StrUtil.isNotBlank(authorization)) { String tokenStr = authorization.replace(SecurityConstants.AUTHORIZATION_PREFIX, Strings.EMPTY); -// CustomCacheUtil customCacheUtil = SpringUtil.getBean(CustomCacheUtil.CACHE_NAME); -// String userjson = customCacheUtil.get(tokenStr, false); -// SysUser user = JSONObject.parseObject(userjson, SysUser.class); -// username = user.getName(); Map map = JwtUtil.parseToken(tokenStr); SysUser user = sysUserService.getById((String) map.get(SecurityConstants.USER_ID)); diff --git a/system/src/main/java/com/njcn/gather/system/pojo/constant/SystemValidMessage.java b/system/src/main/java/com/njcn/gather/system/pojo/constant/SystemValidMessage.java index bf563921..812bde7e 100644 --- a/system/src/main/java/com/njcn/gather/system/pojo/constant/SystemValidMessage.java +++ b/system/src/main/java/com/njcn/gather/system/pojo/constant/SystemValidMessage.java @@ -91,5 +91,7 @@ public interface SystemValidMessage { String TOKEN_EXPIRED = "token已过期,请重新登录"; + String ACCESS_TOKEN_EXPIRED = "access-token已过期"; + String USER_ID_FORMAT_ERROR = "用户id格式错误,请检查userId参数"; }