diff --git a/src/main/java/com/zhgd/xmgl/modules/xz/controller/XzRiskPredictionController.java b/src/main/java/com/zhgd/xmgl/modules/xz/controller/XzRiskPredictionController.java index aedb773f4..731c683ca 100644 --- a/src/main/java/com/zhgd/xmgl/modules/xz/controller/XzRiskPredictionController.java +++ b/src/main/java/com/zhgd/xmgl/modules/xz/controller/XzRiskPredictionController.java @@ -1,6 +1,7 @@ package com.zhgd.xmgl.modules.xz.controller; import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.date.DateUtil; import com.alibaba.fastjson.JSONObject; @@ -50,6 +51,7 @@ import com.zhgd.xmgl.modules.xz.security.service.IXzSecurityQualityInspectionRec import com.zhgd.xmgl.util.AqiUtil; import com.zhgd.xmgl.util.MapBuilder; import com.zhgd.xmgl.util.NumberUtils; +import com.zhgd.xmgl.util.PolygonUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; @@ -64,6 +66,7 @@ import springfox.documentation.annotations.ApiIgnore; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.*; +import java.util.function.Function; import java.util.stream.Collectors; @RestController @@ -255,33 +258,44 @@ public class XzRiskPredictionController { List aiAnalyseHardWareAlarmRecordLastMonths = aiAnalyseHardWareAlarmRecordService.list(Wrappers.lambdaQuery() .eq(AiAnalyseHardWareAlarmRecord::getProjectSn, projectSn) .between(AiAnalyseHardWareAlarmRecord::getCreateTime, DateUtil.beginOfMonth(time), DateUtil.endOfMonth(time))); + Result>> workerRiskRs = getWorkerRiskByEnterprise(new MapBuilder() + .put("projectSn", projectSn) + .build()); + Map> enterpriseIdForWorkerRiskMap = new HashMap<>(); + if (workerRiskRs.isSuccess()) { + List> result = workerRiskRs.getResult(); + if (CollUtil.isNotEmpty(result)) { + enterpriseIdForWorkerRiskMap = result.stream().collect(Collectors.toMap(map -> MapUtils.getLong(map, "enterpriseId"), Function.identity())); + } + } for (EnterpriseInfo mainEnterprise : mainEnterprises) { List enterpriseIds = enterpriseInfos.stream().filter(enterpriseInfo -> enterpriseInfo.getAncestors().contains(mainEnterprise.getParentProjectEnterpriseId() + "")).map(EnterpriseInfo::getId).collect(Collectors.toList()); enterpriseIds.add(mainEnterprise.getId()); List hardwareIds = enterpriseIdAndAiAnalyseHardIds.stream().filter(j -> enterpriseIds.contains(j.getLong("enterpriseId"))).map(j -> j.getString("hardwareId")).collect(Collectors.toList()); - RiskTrendByMainEnterpriseVo oneVo = new RiskTrendByMainEnterpriseVo(); - oneVo.setSevereWeatherRate(severeWeatherRate); + RiskTrendByMainEnterpriseVo o = new RiskTrendByMainEnterpriseVo(); + o.setSevereWeatherRate(severeWeatherRate); long specialNotCount = inspectionRecords.stream().filter(r -> enterpriseIds.contains(r.getEnterpriseId()) && r.getStatus() != 6 && r.getStatus() != 5 && r.getType() != null).count(); long specialCount = inspectionRecords.stream().filter(r -> enterpriseIds.contains(r.getEnterpriseId()) && r.getStatus() != 6 && r.getType() != null).count(); - oneVo.setTotalSpecialOperationsRiskRate(NumberUtils.div(specialNotCount, specialCount, 2)); + o.setTotalSpecialOperationsRiskRate(NumberUtils.div(specialNotCount, specialCount, 2)); BigDecimal hiddenDangerScore = this.getHiddenDangerScore(projectSn, date, safeInspectionRecords, enterpriseIds, taskRecords); BigDecimal dangerEngScore = this.getScore(projectSn, date, dangerousEngineeringRecords, enterpriseIds, hiddenDangerInspectRecords, dangerousEngineeringSideStations); BigDecimal riskScore = this.getRiskScore(projectSn, date, enterpriseIds, safeInspections); BigDecimal aiScore = this.getAiScore(projectSn, date, aiAnalyseHardWareAlarmRecords, enterpriseIds, hardwareIds, aiAnalyseHardWareAlarmRecordLastMonths); BigDecimal total = hiddenDangerScore.add(dangerEngScore).add(riskScore).add(aiScore).add(new BigDecimal(30)).setScale(0, RoundingMode.HALF_UP); - oneVo.setMonthlySafetyScoreRate(NumberUtils.div(total.doubleValue(), 100D,2)); + o.setMonthlySafetyScoreRate(NumberUtils.div(total.doubleValue(), 100D, 2)); - oneVo.setTotalPersonnelRiskRate(0.0D); + o.setTotalPersonnelRiskRate(Optional.ofNullable(enterpriseIdForWorkerRiskMap.get(mainEnterprise.getId())).map(map -> NumberUtils.div(MapUtils.getDouble(map, "area"), 100.0, 2)).orElse(0.0)); long inspectionCount = inspectionRecords.stream().filter(r -> enterpriseIds.contains(r.getEnterpriseId()) && r.getStatus() != 6).count(); long inspectionNotCount = inspectionRecords.stream().filter(r -> enterpriseIds.contains(r.getEnterpriseId()) && r.getStatus() != 6 && r.getStatus() != 5).count(); - oneVo.setUnclosedHiddenDangersRate(NumberUtils.div(inspectionNotCount, inspectionCount, 2)); - oneVo.setEnterpriseId(mainEnterprise.getId()); - oneVo.setEnterpriseName(mainEnterprise.getEnterpriseName()); - rtList.add(oneVo); + o.setUnclosedHiddenDangersRate(NumberUtils.div(inspectionNotCount, inspectionCount, 2)); + o.setEnterpriseId(mainEnterprise.getId()); + o.setEnterpriseName(mainEnterprise.getEnterpriseName()); + o.setArea(NumberUtils.percent(PolygonUtil.calRadioArea(1.0, 5, o.getSevereWeatherRate(), o.getUnclosedHiddenDangersRate(), o.getMonthlySafetyScoreRate(), o.getTotalSpecialOperationsRiskRate(), o.getTotalPersonnelRiskRate()), 2)); + rtList.add(o); } return Result.success(rtList); } @@ -436,18 +450,19 @@ public class XzRiskPredictionController { .in(XzSecurityQualityInspectionRecord::getProjectSn, projectSn) ); Double severeWeatherRate = this.getSevereWeatherRate(project); - RiskTrendByMainEnterpriseVo vo = new RiskTrendByMainEnterpriseVo(); - vo.setSevereWeatherRate(severeWeatherRate); - vo.setTotalPersonnelRiskRate(0.0D); + RiskTrendByMainEnterpriseVo o = new RiskTrendByMainEnterpriseVo(); + o.setSevereWeatherRate(severeWeatherRate); + o.setTotalPersonnelRiskRate(0.0D); long specialNotCount = inspectionRecords.stream().filter(r -> r.getStatus() != 6 && r.getStatus() != 5 && r.getType() != null).count(); long specialCount = inspectionRecords.stream().filter(r -> r.getStatus() != 6 && r.getType() != null).count(); - vo.setTotalSpecialOperationsRiskRate(NumberUtils.div(specialNotCount, specialCount, 2)); + o.setTotalSpecialOperationsRiskRate(NumberUtils.div(specialNotCount, specialCount, 2)); JSONObject ssJo = BeanUtil.toBean(securityQualityInspectionRecordController.getStatScore(projectSn), JSONObject.class); - vo.setMonthlySafetyScoreRate(NumberUtils.div(ssJo.getDouble("total"), 100D,2)); + o.setMonthlySafetyScoreRate(NumberUtils.div(ssJo.getDouble("total"), 100D, 2)); long inspectionCount = inspectionRecords.stream().filter(r -> r.getStatus() != 6).count(); long inspectionNotCount = inspectionRecords.stream().filter(r -> r.getStatus() != 6 && r.getStatus() != 5).count(); - vo.setUnclosedHiddenDangersRate(NumberUtils.div(inspectionNotCount, inspectionCount, 2)); - return Result.success(vo); + o.setUnclosedHiddenDangersRate(NumberUtils.div(inspectionNotCount, inspectionCount, 2)); + o.setArea(NumberUtils.percent(PolygonUtil.calRadioArea(1.0, 5, o.getSevereWeatherRate(), o.getUnclosedHiddenDangersRate(), o.getMonthlySafetyScoreRate(), o.getTotalSpecialOperationsRiskRate(), o.getTotalPersonnelRiskRate()), 2)); + return Result.success(o); } @ApiOperation(value = "特殊作业预测趋势(按特殊作业类型分)", notes = "特殊作业预测趋势(按特殊作业类型分)", httpMethod = "POST") @@ -458,7 +473,7 @@ public class XzRiskPredictionController { @PostMapping(value = "/getSpecialTrend") public Result getSpecialTrend(@ApiIgnore @RequestBody Map param) { Integer type = MapUtils.getInteger(param, "type"); - SpecialTrendVo vo = new SpecialTrendVo(); + SpecialTrendVo o = new SpecialTrendVo(); String projectSn = MapUtils.getString(param, "projectSn"); ProjectInfoExtVo project = projectService.getProjectInfoBySn(projectSn); if (Objects.equals(type, 1)) { @@ -510,23 +525,25 @@ public class XzRiskPredictionController { temHighLow++; } } - vo.setSpecialOperationFireSafety(NumberUtils.div(wind + yuLei, 6, 2)); - vo.setHighJobSafe(NumberUtils.div(wind + yuLeiXue, 6, 2)); - vo.setBlindPlatePlugSafe(NumberUtils.div(wind + yuLei, 6, 2)); - vo.setLimitSpaceSafe(NumberUtils.div(yu + temHighLow, 6, 2)); - vo.setOpenCircuitSafe(NumberUtils.div(wind + yuLei, 6, 2)); - vo.setTemporaryElectricitySafe(NumberUtils.div(yuLeiXue, 3, 2)); - vo.setHoistSafetyWork(NumberUtils.div(yuLeiXue, 3, 2)); - vo.setGroundSafet(NumberUtils.div(yu + temHigh, 6, 2)); + o.setSpecialOperationFireSafety(NumberUtils.div(wind + yuLei, 6, 2)); + o.setHighJobSafe(NumberUtils.div(wind + yuLeiXue, 6, 2)); + o.setBlindPlatePlugSafe(NumberUtils.div(wind + yuLei, 6, 2)); + o.setLimitSpaceSafe(NumberUtils.div(yu + temHighLow, 6, 2)); + o.setOpenCircuitSafe(NumberUtils.div(wind + yuLei, 6, 2)); + o.setTemporaryElectricitySafe(NumberUtils.div(yuLeiXue, 3, 2)); + o.setHoistSafetyWork(NumberUtils.div(yuLeiXue, 3, 2)); + o.setGroundSafet(NumberUtils.div(yu + temHigh, 6, 2)); + o.setArea(NumberUtils.percent(PolygonUtil.calRadioArea(1.0, 8, o.getSpecialOperationFireSafety(), o.getGroundSafet(), o.getHoistSafetyWork(), o.getTemporaryElectricitySafe(), o.getOpenCircuitSafe(), o.getLimitSpaceSafe(), o.getBlindPlatePlugSafe(), o.getHighJobSafe()), 2)); } else { - vo.setBlindPlatePlugSafe(0.0D); - vo.setGroundSafet(0.0D); - vo.setHighJobSafe(0.0D); - vo.setHoistSafetyWork(0.0D); - vo.setLimitSpaceSafe(0.0D); - vo.setOpenCircuitSafe(0.0D); - vo.setSpecialOperationFireSafety(0.0D); - vo.setTemporaryElectricitySafe(0.0D); + o.setBlindPlatePlugSafe(0.0D); + o.setGroundSafet(0.0D); + o.setHighJobSafe(0.0D); + o.setHoistSafetyWork(0.0D); + o.setLimitSpaceSafe(0.0D); + o.setOpenCircuitSafe(0.0D); + o.setSpecialOperationFireSafety(0.0D); + o.setTemporaryElectricitySafe(0.0D); + o.setArea(0.0); } } else { List inspectionRecords = xzSecurityQualityInspectionRecordService.list(Wrappers.lambdaQuery() @@ -535,30 +552,31 @@ public class XzRiskPredictionController { .eq(XzSecurityQualityInspectionRecord::getRecordType, 1)); long nc1 = inspectionRecords.stream().filter(r -> !Objects.equals(r.getStatus(), 5) && Objects.equals(r.getType(), 2)).count(); long c1 = inspectionRecords.stream().filter(r -> Objects.equals(r.getType(), 2)).count(); - vo.setSpecialOperationFireSafety(NumberUtils.div(nc1, c1, 2)); + o.setSpecialOperationFireSafety(NumberUtils.div(nc1, c1, 2)); long nc2 = inspectionRecords.stream().filter(r -> !Objects.equals(r.getStatus(), 5) && Objects.equals(r.getType(), 5)).count(); long c2 = inspectionRecords.stream().filter(r -> Objects.equals(r.getType(), 5)).count(); - vo.setHighJobSafe(NumberUtils.div(nc2, c2, 2)); + o.setHighJobSafe(NumberUtils.div(nc2, c2, 2)); long nc3 = inspectionRecords.stream().filter(r -> !Objects.equals(r.getStatus(), 5) && Objects.equals(r.getType(), 4)).count(); long c3 = inspectionRecords.stream().filter(r -> Objects.equals(r.getType(), 4)).count(); - vo.setBlindPlatePlugSafe(NumberUtils.div(nc3, c3, 2)); + o.setBlindPlatePlugSafe(NumberUtils.div(nc3, c3, 2)); long nc4 = inspectionRecords.stream().filter(r -> !Objects.equals(r.getStatus(), 5) && Objects.equals(r.getType(), 3)).count(); long c4 = inspectionRecords.stream().filter(r -> Objects.equals(r.getType(), 3)).count(); - vo.setLimitSpaceSafe(NumberUtils.div(nc4, c4, 2)); + o.setLimitSpaceSafe(NumberUtils.div(nc4, c4, 2)); long nc5 = inspectionRecords.stream().filter(r -> !Objects.equals(r.getStatus(), 5) && Objects.equals(r.getType(), 9)).count(); long c5 = inspectionRecords.stream().filter(r -> Objects.equals(r.getType(), 9)).count(); - vo.setOpenCircuitSafe(NumberUtils.div(nc5, c5, 2)); + o.setOpenCircuitSafe(NumberUtils.div(nc5, c5, 2)); long nc6 = inspectionRecords.stream().filter(r -> !Objects.equals(r.getStatus(), 5) && Objects.equals(r.getType(), 7)).count(); long c6 = inspectionRecords.stream().filter(r -> Objects.equals(r.getType(), 7)).count(); - vo.setTemporaryElectricitySafe(NumberUtils.div(nc6, c6, 2)); + o.setTemporaryElectricitySafe(NumberUtils.div(nc6, c6, 2)); long nc7 = inspectionRecords.stream().filter(r -> !Objects.equals(r.getStatus(), 5) && Objects.equals(r.getType(), 6)).count(); long c7 = inspectionRecords.stream().filter(r -> Objects.equals(r.getType(), 6)).count(); - vo.setHoistSafetyWork(NumberUtils.div(nc7, c7, 2)); + o.setHoistSafetyWork(NumberUtils.div(nc7, c7, 2)); long nc8 = inspectionRecords.stream().filter(r -> !Objects.equals(r.getStatus(), 5) && Objects.equals(r.getType(), 8)).count(); long c8 = inspectionRecords.stream().filter(r -> Objects.equals(r.getType(), 8)).count(); - vo.setGroundSafet(NumberUtils.div(nc8, c8, 2)); + o.setGroundSafet(NumberUtils.div(nc8, c8, 2)); + o.setArea(NumberUtils.percent(PolygonUtil.calRadioArea(1.0, 8, o.getSpecialOperationFireSafety(), o.getGroundSafet(), o.getHoistSafetyWork(), o.getTemporaryElectricitySafe(), o.getOpenCircuitSafe(), o.getLimitSpaceSafe(), o.getBlindPlatePlugSafe(), o.getHighJobSafe()), 2)); } - return Result.success(vo); + return Result.success(o); } private Double getSevereWeatherRate(ProjectInfoExtVo project) { @@ -681,6 +699,7 @@ public class XzRiskPredictionController { resultMap.put("security", 0); } resultMap.put("enterpriseName", enterpriseInfo.getEnterpriseName()); + resultMap.put("enterpriseId", enterpriseInfo.getId()); // 计算面积 BigDecimal base = new BigDecimal(0.43); diff --git a/src/main/java/com/zhgd/xmgl/modules/xz/entity/vo/RiskTrendByMainEnterpriseVo.java b/src/main/java/com/zhgd/xmgl/modules/xz/entity/vo/RiskTrendByMainEnterpriseVo.java index 5d9b03234..f4a23e966 100644 --- a/src/main/java/com/zhgd/xmgl/modules/xz/entity/vo/RiskTrendByMainEnterpriseVo.java +++ b/src/main/java/com/zhgd/xmgl/modules/xz/entity/vo/RiskTrendByMainEnterpriseVo.java @@ -19,18 +19,44 @@ public class RiskTrendByMainEnterpriseVo { //公式:指挥部大屏上的月度安全评分分值按总包(含下面分包)单位计算 // //5、总包(含下面分包)单位未闭合隐患占比 + /** + * 恶劣天气占比 + */ @ApiModelProperty("恶劣天气占比") private Double severeWeatherRate; + /** + * 人员发生风险总概率 + */ @ApiModelProperty("人员发生风险总概率") private Double totalPersonnelRiskRate; + /** + * 特殊作业发生风险总概率 + */ @ApiModelProperty("特殊作业发生风险总概率") private Double totalSpecialOperationsRiskRate; + /** + * 月度安全评分 + */ @ApiModelProperty("月度安全评分") private Double monthlySafetyScoreRate; + /** + * 未闭合隐患占比 + */ @ApiModelProperty("未闭合隐患占比") private Double unclosedHiddenDangersRate; + /** + * 企业名称 + */ @ApiModelProperty("企业名称") private String enterpriseName; + /** + * 企业id + */ @ApiModelProperty("企业id") private Long enterpriseId; + /** + * 占用面积 + */ + @ApiModelProperty("占用面积") + private Double area; } diff --git a/src/main/java/com/zhgd/xmgl/modules/xz/entity/vo/SpecialTrendVo.java b/src/main/java/com/zhgd/xmgl/modules/xz/entity/vo/SpecialTrendVo.java index 83c6f930c..7d5f812e3 100644 --- a/src/main/java/com/zhgd/xmgl/modules/xz/entity/vo/SpecialTrendVo.java +++ b/src/main/java/com/zhgd/xmgl/modules/xz/entity/vo/SpecialTrendVo.java @@ -45,4 +45,7 @@ public class SpecialTrendVo { */ @ApiModelProperty("临时用电安全作业票") private Double temporaryElectricitySafe; + @ApiModelProperty("面积") + private Double area; + } diff --git a/src/main/java/com/zhgd/xmgl/util/NumberUtils.java b/src/main/java/com/zhgd/xmgl/util/NumberUtils.java index 0e619389c..b8476c0b1 100644 --- a/src/main/java/com/zhgd/xmgl/util/NumberUtils.java +++ b/src/main/java/com/zhgd/xmgl/util/NumberUtils.java @@ -289,5 +289,18 @@ public class NumberUtils { return list; } + /** + * 计算百分比 + * + * @param b1 + * @param scale + * @return + */ + public static Double percent(Double b1, Integer scale) { + if (b1 == null) { + return null; + } + return NumberUtil.round(b1 * 100, scale).doubleValue(); + } } diff --git a/src/main/java/com/zhgd/xmgl/util/PolygonUtil.java b/src/main/java/com/zhgd/xmgl/util/PolygonUtil.java new file mode 100644 index 000000000..4b2c98219 --- /dev/null +++ b/src/main/java/com/zhgd/xmgl/util/PolygonUtil.java @@ -0,0 +1,73 @@ +package com.zhgd.xmgl.util; + +import java.util.ArrayList; +import java.util.Optional; + +public class PolygonUtil { + + /** + * 五边形面积 + * + * @param r 从五边形中心到顶点的距离,计算五边形的面积 + * @return + */ + public static double pentagonArea(double r) { + double s = 2 * r * Math.sin(Math.PI / 5); + return (5 * Math.pow(s, 2)) / (4 * Math.tan(Math.PI / 5)); + } + + /** + * 八边形面积 + * + * @param r + * @return + */ + public static double octagonArea(double r) { + double s = 2 * r * Math.sin(Math.PI / 8); + return (8 * Math.pow(s, 2)) / (4 * Math.tan(Math.PI / 8)); + } + + /** + * 多边形面积 + * + * @param r + * @return + */ + public static double polygonArea(double r, int edgeNum) { + double s = 2 * r * Math.sin(Math.PI / edgeNum); + return (edgeNum * Math.pow(s, 2)) / (4 * Math.tan(Math.PI / edgeNum)); + } + + /** + * 计算雷达图面积 + * + * @param r 从多边形中心到顶点的距离 + * @param edgeNum 边数 + * @param data 三角形的边长 + * @return + */ + public static double calRadioArea(double r, int edgeNum, Double... data) { + double sinVal = Math.sin(Math.toRadians(360.0 / edgeNum)); + ArrayList dataList = new ArrayList<>(); + for (Double d : data) { + dataList.add(Optional.ofNullable(d).orElse(0.0)); + } + ArrayList doubles = new ArrayList<>(); + for (int i = 0; i < edgeNum; i++) { + double r1; + if (i == edgeNum - 1) { + r1 = dataList.get(i) * dataList.get(0) * sinVal / 2; + } else { + r1 = dataList.get(i) * dataList.get(i + 1) * sinVal / 2; + } + doubles.add(r1); + } + double sum = doubles.stream().mapToDouble(value -> value).sum(); + return sum / pentagonArea(1); + } + + public static void main(String[] args) { + System.out.println(calRadioArea(1, 5, 1.0, 1.0, 1.0, 1.0, 1.0)); + } + +}