管控清单危险源数据中心和bug修复

This commit is contained in:
guoshengxiong 2025-06-21 11:59:34 +08:00
parent 62f4aa4096
commit aacfd760a5
13 changed files with 641 additions and 48 deletions

View File

@ -1,6 +1,7 @@
package com.zhgd.xmgl.base.entity.vo;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.zhgd.xmgl.enums.BaseEnum;
import com.zhgd.xmgl.modules.basicdata.entity.DictionaryItem;
@ -27,6 +28,7 @@ public class SectorVo {
@ApiModelProperty("影响天数")
private Integer dayNum;
private List<SectorOneVo> data;
private IPage<SectorOneVo> page;
/**

View File

@ -98,6 +98,11 @@ public class RiskListLibraryController {
})
@GetMapping(value = "/page")
public Result<IPage<RiskListLibraryVo>> queryPageList(@ApiIgnore @RequestParam HashMap<String, Object> param) {
String projectSn = MapUtils.getString(param, "projectSn");
if (StrUtil.isNotBlank(projectSn)) {
String headquartersSn = companyService.getHeadquartersSnByProjectSn(projectSn);
param.put("sn", headquartersSn);
}
return Result.success(riskListLibraryService.queryPageList(param));
}
@ -110,6 +115,11 @@ public class RiskListLibraryController {
@ApiOperation(value = "列表查询风险清单库信息", notes = "列表查询风险清单库信息", httpMethod = "GET")
@GetMapping(value = "/list")
public Result<List<RiskListLibraryVo>> queryList(@ApiIgnore @RequestParam HashMap<String, Object> param) {
String projectSn = MapUtils.getString(param, "projectSn");
if (StrUtil.isNotBlank(projectSn)) {
String headquartersSn = companyService.getHeadquartersSnByProjectSn(projectSn);
param.put("sn", headquartersSn);
}
return Result.success(riskListLibraryService.queryList(param));
}

View File

@ -98,6 +98,8 @@ public class RiskListSourceController {
@ApiImplicitParam(name = "duringTheTask", value = "1是开启任务期间", paramType = "query", required = false, dataType = "Integer"),
@ApiImplicitParam(name = "workable", value = "1已落实0未落实", paramType = "query", required = false, dataType = "Integer"),
@ApiImplicitParam(name = "isInConstruction", value = "1在施", paramType = "query", required = false, dataType = "Integer"),
@ApiImplicitParam(name = "effectiveTimeEnd_begin", value = "开始日期", paramType = "query", required = false, dataType = "Integer"),
@ApiImplicitParam(name = "effectiveTimeBegin_end", value = "结束日期", paramType = "query", required = false, dataType = "Integer"),
})
@GetMapping(value = "/page")
public Result<IPage<RiskListSourceVo>> queryPageList(@ApiIgnore @RequestParam HashMap<String, Object> param) {

View File

@ -1,17 +1,41 @@
package com.zhgd.xmgl.modules.risk.controller;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateRange;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhgd.jeecg.common.api.vo.Result;
import com.zhgd.xmgl.base.entity.vo.SectorOneVo;
import com.zhgd.xmgl.base.entity.vo.SectorVo;
import com.zhgd.xmgl.base.entity.vo.TrendOneVo;
import com.zhgd.xmgl.modules.risk.entity.RiskListSource;
import com.zhgd.xmgl.modules.risk.entity.RiskListSourceUnbuilt;
import com.zhgd.xmgl.modules.risk.entity.bo.RiskByDateBo;
import com.zhgd.xmgl.modules.risk.entity.bo.SourceCheckNumBo;
import com.zhgd.xmgl.modules.risk.entity.vo.CountRisksByLevelVo;
import com.zhgd.xmgl.modules.risk.service.IRegionV2Service;
import com.zhgd.xmgl.modules.risk.service.IRiskListDetailService;
import com.zhgd.xmgl.modules.risk.service.IRiskListPotentialAccidentTypeService;
import com.zhgd.xmgl.modules.risk.service.IRiskListSourceService;
import com.zhgd.xmgl.modules.risk.entity.vo.HighRiskValByType;
import com.zhgd.xmgl.modules.risk.entity.vo.RiskListSourceVo;
import com.zhgd.xmgl.modules.risk.service.*;
import com.zhgd.xmgl.modules.xz.security.entity.XzSecurityQualityInspectionRecord;
import com.zhgd.xmgl.modules.xz.security.service.IXzSecurityQualityInspectionRecordService;
import com.zhgd.xmgl.util.ListUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.GetMapping;
@ -20,8 +44,9 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;
import java.util.HashMap;
import java.util.List;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
/**
@ -48,6 +73,12 @@ public class RiskListSourceDataCenterController {
@Lazy
@Autowired
private IRiskListPotentialAccidentTypeService riskListPotentialAccidentTypeService;
@Lazy
@Autowired
private IRiskListSourceUnbuiltService riskListSourceUnbuiltService;
@Lazy
@Autowired
private IXzSecurityQualityInspectionRecordService xzSecurityQualityInspectionRecordService;
@ApiOperation(value = "统计风险等级数量", notes = "统计风险等级数量", httpMethod = "GET")
@ApiImplicitParams({
@ -63,22 +94,506 @@ public class RiskListSourceDataCenterController {
@ApiOperation(value = "风险走势图(按月统计)", notes = "风险走势图(按月统计)", httpMethod = "GET")
@ApiImplicitParams({
@ApiImplicitParam(name = "projectSn", value = "项目sn", paramType = "query", required = true, dataType = "Integer"),
@ApiImplicitParam(name = "startTime", value = "开始时间yyyy-MM", paramType = "body", required = true, dataType = "String"),
@ApiImplicitParam(name = "endTime", value = "结束时间yyyy-MM", paramType = "body", required = true, dataType = "String"),
@ApiImplicitParam(name = "startTime", value = "开始时间yyyy-MM", paramType = "query", required = true, dataType = "String"),
@ApiImplicitParam(name = "endTime", value = "结束时间yyyy-MM", paramType = "query", required = true, dataType = "String"),
})
@GetMapping(value = "/getRiskTrendChart")
public Result<List<CountRisksByLevelVo>> getRiskTrendChart(@ApiIgnore @RequestParam HashMap<String, Object> param) {
return Result.success(riskListSourceService.getRiskTrendChart(param));
String startTime = MapUtils.getString(param, "startTime");
if (StrUtil.isBlank(startTime)) {
startTime = DateUtil.format(DateUtil.offsetMonth(new Date(), -11), "yyyy-MM");
}
String endTime = MapUtils.getString(param, "endTime");
if (StrUtil.isBlank(endTime)) {
endTime = DateUtil.format(new Date(), "yyyy-MM");
}
endTime = DateUtil.formatDateTime(DateUtil.endOfMonth(DateUtil.parseDate(endTime + "-01")));
startTime = DateUtil.formatDateTime(DateUtil.beginOfMonth(DateUtil.parseDate(startTime + "-01")));
List<RiskListSource> sources = riskListSourceService.list(new LambdaQueryWrapper<RiskListSource>()
.select(RiskListSource::getId, RiskListSource::getEffectiveTimeBegin, RiskListSource::getEffectiveTimeEnd)
.eq(RiskListSource::getProjectSn, MapUtils.getString(param, "projectSn"))
.le(RiskListSource::getEffectiveTimeBegin, endTime)
.ge(RiskListSource::getEffectiveTimeEnd, startTime)
).stream().sorted(Comparator.comparing(RiskListSource::getEffectiveTimeBegin)).collect(Collectors.toList());
List<DateTime> months = DateUtil.rangeToList(DateUtil.parse(startTime), DateUtil.parse(endTime), DateField.MONTH);
ArrayList<CountRisksByLevelVo> vos = new ArrayList<>();
Integer lastTotal = null;
for (DateTime month : months) {
CountRisksByLevelVo vo = new CountRisksByLevelVo();
vo.setZdNum((int) sources.stream().filter(s -> Objects.equals(s.getRiskLevel(), 1) && DateUtil.compare(s.getEffectiveTimeBegin(), month) <= 0 && DateUtil.compare(s.getEffectiveTimeEnd(), month) >= 0).count());
vo.setJdNum((int) sources.stream().filter(s -> Objects.equals(s.getRiskLevel(), 2) && DateUtil.compare(s.getEffectiveTimeBegin(), month) <= 0 && DateUtil.compare(s.getEffectiveTimeEnd(), month) >= 0).count());
vo.setYbNum((int) sources.stream().filter(s -> Objects.equals(s.getRiskLevel(), 3) && DateUtil.compare(s.getEffectiveTimeBegin(), month) <= 0 && DateUtil.compare(s.getEffectiveTimeEnd(), month) >= 0).count());
vo.setDNum((int) sources.stream().filter(s -> Objects.equals(s.getRiskLevel(), 4) && DateUtil.compare(s.getEffectiveTimeBegin(), month) <= 0 && DateUtil.compare(s.getEffectiveTimeEnd(), month) >= 0).count());
vo.setTotal((int) sources.stream().filter(s -> DateUtil.compare(s.getEffectiveTimeBegin(), month) <= 0 && DateUtil.compare(s.getEffectiveTimeEnd(), month) >= 0).count());
vo.setYearMonth(DateUtil.format(month, "yyyy-MM"));
if (lastTotal != null) {
vo.setMoMChange(lastTotal != 0 ? new BigDecimal((vo.getTotal() * 1.0 / lastTotal - 1) * 100).setScale(2, BigDecimal.ROUND_HALF_UP) : null);
}
lastTotal = vo.getTotal();
vos.add(vo);
}
return Result.success(vos);
}
@ApiOperation(value = "(在施)风险类型占比", notes = "(在施)风险类型占比", httpMethod = "GET")
@ApiImplicitParams({
@ApiImplicitParam(name = "projectSn", value = "项目sn", paramType = "query", required = true, dataType = "Integer"),
@ApiImplicitParam(name = "isInConstruction", value = "1在施", paramType = "query", required = false, dataType = "Integer"),
@ApiImplicitParam(name = "projectType", value = "工程类别(字典值)", paramType = "query", required = false, dataType = "Integer"),
@ApiImplicitParam(name = "pageNo", value = "第几页", paramType = "query", required = true, dataType = "Integer"),
@ApiImplicitParam(name = "pageSize", value = "每页显示条数", paramType = "query", required = true, dataType = "Integer"),
})
@GetMapping(value = "/countRisksByLibrary")
public Result<SectorVo> countRisksByLibrary(@RequestParam @ApiIgnore HashMap<String, Object> map) {
return Result.success(riskListSourceService.countRisksByLibrary(map));
List<SectorOneVo> list = riskListSourceService.countRisksByLibrary(map);
SectorVo vo = SectorVo.getSectorVo(list);
int pageNo = Integer.parseInt(map.getOrDefault("pageNo", 1).toString());
int pageSize = Integer.parseInt(map.getOrDefault("pageSize", 10).toString());
if (pageSize < 0) {
pageSize = Integer.MAX_VALUE;
}
List<SectorOneVo> vos = BeanUtil.copyToList(ListUtils.listToTree(JSONArray.parseArray(JSON.toJSONString(list)), "id", "parentRegion", "children"), SectorOneVo.class);
IPage<SectorOneVo> p = new Page<>();
int i = cn.hutool.core.util.PageUtil.getStart(pageNo - 1, pageSize);
p.setTotal(vos.size());
p.setRecords(CollUtil.sub(vos, i, i + pageSize));
p.setCurrent(pageNo);
p.setSize(pageSize);
vo.setPage(p);
return Result.success(vo);
}
@ApiOperation(value = "隐患排查类别执行率TOP10", notes = "隐患排查类别执行率TOP10", httpMethod = "GET")
@ApiImplicitParams({
@ApiImplicitParam(name = "projectSn", value = "项目sn", paramType = "query", required = true, dataType = "Integer"),
@ApiImplicitParam(name = "isInConstruction", value = "1在施", paramType = "query", required = false, dataType = "Integer"),
@ApiImplicitParam(name = "effectiveTimeEnd_begin", value = "开始日期", paramType = "query", required = false, dataType = "Integer"),
@ApiImplicitParam(name = "effectiveTimeBegin_end", value = "结束日期", paramType = "query", required = false, dataType = "Integer"),
@ApiImplicitParam(name = "projectType", value = "工程类别(字典值)", paramType = "query", required = false, dataType = "Integer"),
@ApiImplicitParam(name = "checkPeriod", value = "排查周期1日2周3月4季度5半年", paramType = "query", required = false, dataType = "String"),
})
@GetMapping(value = "/getCategoryExecutionRateTop10")
public Result<List<TrendOneVo>> getCategoryExecutionRateTop10(@ApiIgnore @RequestParam HashMap<String, Object> param) {
param.put("allowGenerateTask", 1);
List<RiskListSourceVo> sourceVos = riskListSourceService.queryList(param).stream().filter(o -> StrUtil.isNotBlank(o.getListLibraryName()) && o.getEffectiveTimeBegin() != null && o.getEffectiveTimeEnd() != null).collect(Collectors.toList());
if (CollUtil.isEmpty(sourceVos)) {
return null;
}
Date begin = StrUtil.isNotBlank(MapUtils.getString(param, "effectiveTimeEnd_begin")) ? DateUtil.parseDateTime(MapUtils.getString(param, "effectiveTimeEnd_begin")) : null;
Date end = StrUtil.isNotBlank(MapUtils.getString(param, "effectiveTimeBegin_end")) ? DateUtil.parseDateTime(MapUtils.getString(param, "effectiveTimeBegin_end")) : null;
List<SourceCheckNumBo> checkNumBos = getSourceCheckNumBo(sourceVos);
//1. 计算有效期内的source的应排查(未施工+已排查)数量
for (RiskListSourceVo sourceVo : sourceVos) {
int shouldCheckedNum = 0;
int checkedNum = 0;
Date b = DateUtil.compare(sourceVo.getEffectiveTimeBegin(), begin) > 0 ? sourceVo.getEffectiveTimeBegin() : begin;
Date e = DateUtil.compare(sourceVo.getEffectiveTimeEnd(), end) < 0 ? sourceVo.getEffectiveTimeEnd() : begin;
if (Objects.equals(sourceVo.getCheckPeriod(), 1)) {
DateRange range = DateUtil.range(b, DateUtil.offsetDay(e, 1), DateField.DAY_OF_YEAR);
for (DateTime time : range) {
shouldCheckedNum += sourceVo.getCheckNum();
long count = checkNumBos.stream().filter(bo -> {
boolean b1 = isSameSourceAndTime(begin, end, sourceVo, bo, time);
return b1 && DateUtil.compare(bo.getDate(), DateUtil.offsetDay(time, 1)) < 0;
}).count();
checkedNum += Math.min(sourceVo.getCheckNum(), count);
}
} else if (Objects.equals(sourceVo.getCheckPeriod(), 2)) {
DateRange range = DateUtil.range(DateUtil.beginOfWeek(b), DateUtil.offsetWeek(e, 1), DateField.DAY_OF_WEEK);
for (DateTime time : range) {
shouldCheckedNum += sourceVo.getCheckNum();
long count = checkNumBos.stream().filter(bo -> {
boolean b1 = isSameSourceAndTime(begin, end, sourceVo, bo, time);
return b1 && DateUtil.compare(bo.getDate(), DateUtil.offsetWeek(time, 1)) < 0;
}).count();
checkedNum += Math.min(sourceVo.getCheckNum(), count);
}
} else if (Objects.equals(sourceVo.getCheckPeriod(), 3)) {
DateRange range = DateUtil.range(DateUtil.beginOfMonth(b), DateUtil.offsetMonth(e, 1), DateField.MONTH);
for (DateTime time : range) {
shouldCheckedNum += sourceVo.getCheckNum();
checkedNum += checkNumBos.stream().filter(bo -> {
boolean b1 = isSameSourceAndTime(begin, end, sourceVo, bo, time);
return b1 && DateUtil.compare(bo.getDate(), DateUtil.offsetMonth(time, 1)) < 0;
}).count();
}
} else if (Objects.equals(sourceVo.getCheckPeriod(), 4)) {
// 获取起始日期所在季度的第一天
DateTime currentQuarterStart = DateUtil.beginOfQuarter(begin);
// 循环直到当前季度的第一天晚于结束日期
// 注意这里需要确保 endDate 所在的季度被包含
// 可以判断 currentQuarterStart 是否在 endDate 所在季度的开始之前或相同
while (!currentQuarterStart.isAfter(DateUtil.endOfQuarter(end))) {
shouldCheckedNum += sourceVo.getCheckNum();
DateTime finalCurrentQuarterStart = currentQuarterStart;
checkedNum += checkNumBos.stream().filter(bo -> {
boolean b1 = isSameSourceAndTime(begin, end, sourceVo, bo, finalCurrentQuarterStart);
return b1 && DateUtil.compare(bo.getDate(), DateUtil.offsetMonth(finalCurrentQuarterStart, 3)) < 0;
}).count();
currentQuarterStart = DateUtil.offsetMonth(currentQuarterStart, 3);
}
} else if (Objects.equals(sourceVo.getCheckPeriod(), 5)) {
// 找到起始日期所在的半年的第一个月的第一天
DateTime currentHalfYearStart;
int startMonth = DateUtil.month(begin) + 1; // 月份是0-11所以+1
if (startMonth >= 1 && startMonth <= 6) { // 上半年 (1月-6月)
currentHalfYearStart = DateUtil.beginOfYear(begin); // 获取年份的开始即1月1日
} else { // 下半年 (7月-12月)
currentHalfYearStart = DateUtil.offsetMonth(DateUtil.beginOfYear(begin), 6); // 获取年份的开始然后偏移6个月即7月1日
}
// 循环直到当前半年的第一天晚于结束日期所在的半年的最后一天
// 或者简单判断 currentHalfYearStart 是否晚于 endDate
while (!currentHalfYearStart.isAfter(DateUtil.endOfYear(end))) { // 确保不超过endDate所在的年末
// 进一步判断是否已经超出了endDate
if (currentHalfYearStart.isAfter(end) && DateUtil.month(currentHalfYearStart) + 1 > 6) { // 避免过度遍历到下一个年份的下半年
break;
}
shouldCheckedNum += sourceVo.getCheckNum();
DateTime finalCurrentHalfYearStart = currentHalfYearStart;
checkedNum += checkNumBos.stream().filter(bo -> {
boolean b1 = isSameSourceAndTime(begin, end, sourceVo, bo, finalCurrentHalfYearStart);
return b1 && DateUtil.compare(bo.getDate(), DateUtil.offsetMonth(DateUtil.beginOfYear(finalCurrentHalfYearStart), 6)) < 0;
}).count();
// 移动到下一个半年的第一个月
currentHalfYearStart = DateUtil.offsetMonth(currentHalfYearStart, 6);
}
}
sourceVo.setShouldCheckedNum(shouldCheckedNum);
sourceVo.setCheckedNum(checkedNum);
}
//2. 统计执行率
// 临时Map存储每个type的应排查总和和已排查总和
Map<String, Map<String, Integer>> sumsByType = sourceVos.stream().collect(Collectors.groupingBy(RiskListSourceVo::getListLibraryName,
Collectors.reducing(
new HashMap<String, Integer>() {{
put("totalShould", 0);
put("totalHave", 0);
}}, // 初始值
vo -> { // 为每个元素创建一个临时的Map
return new HashMap<String, Integer>() {{
put("totalShould", vo.getShouldCheckedNum());
put("totalHave", vo.getCheckedNum());
}};
},
(map1, map2) -> { // 合并函数
map1.merge("totalShould", map2.get("totalShould"), (integer, integer2) -> NumberUtil.add(integer, integer2).intValue());
map1.merge("totalHave", map2.get("totalHave"), (integer, integer2) -> NumberUtil.add(integer, integer2).intValue());
return map1;
}
)));
// 计算比率并转换为目标输出格式
List<TrendOneVo> voList = sumsByType.entrySet().stream()
.map(entry -> {
String type = entry.getKey();
Map<String, Integer> totals = entry.getValue();
double totalHave = totals.get("totalHave");
double totalShould = totals.get("totalShould");
Double sumRatio;
if (totalShould == 0) {
sumRatio = null;
} else {
sumRatio = NumberUtil.div(NumberUtil.mul(totalHave, 100), totalShould, 2);
}
TrendOneVo vo = new TrendOneVo();
vo.setX(type);
vo.setY(Convert.toStr(sumRatio));
return vo;
})
.collect(Collectors.toList());
return Result.success(voList);
}
/**
* 相同source并且在时间范围内
*
* @param begin
* @param end
* @param sourceVo
* @param bo
* @param time
* @return
*/
private boolean isSameSourceAndTime(Date begin, Date end, RiskListSourceVo sourceVo, SourceCheckNumBo bo, Date time) {
return Objects.equals(bo.getSourceId(), sourceVo.getId()) && DateUtil.compare(bo.getDate(), begin) >= 0 && DateUtil.compare(bo.getDate(), end) <= 0
&& DateUtil.compare(bo.getDate(), time) >= 0;
}
/**
* 获取已排查的数量List
*
* @param sourceVos
* @return
*/
private List<SourceCheckNumBo> getSourceCheckNumBo(List<RiskListSourceVo> sourceVos) {
List<Long> sourceIds = sourceVos.stream().map(RiskListSourceVo::getId).collect(Collectors.toList());
List<XzSecurityQualityInspectionRecord> securityList = xzSecurityQualityInspectionRecordService.list(new LambdaQueryWrapper<XzSecurityQualityInspectionRecord>()
.eq(XzSecurityQualityInspectionRecord::getType, 10)
.in(XzSecurityQualityInspectionRecord::getEngineeringId, sourceIds)
);
List<RiskListSourceUnbuilt> unbuilts = riskListSourceUnbuiltService.list(new LambdaQueryWrapper<RiskListSourceUnbuilt>()
.in(RiskListSourceUnbuilt::getSourceId, sourceIds));
List<SourceCheckNumBo> collect = securityList.stream().map(o -> {
SourceCheckNumBo bo = new SourceCheckNumBo();
bo.setSourceId(o.getEngineeringId());
bo.setDate(DateUtil.parseDate(o.getInspectTime()));
return bo;
}).collect(Collectors.toList());
collect.addAll(unbuilts.stream().map(o -> {
SourceCheckNumBo bo = new SourceCheckNumBo();
bo.setSourceId(o.getSourceId());
bo.setDate(o.getInspectionTime());
return bo;
}).collect(Collectors.toList()));
return collect;
}
@ApiOperation(value = "风险类别占比图", notes = "风险类别占比图", httpMethod = "GET")
@ApiImplicitParams({
@ApiImplicitParam(name = "projectSn", value = "项目sn", paramType = "query", required = true, dataType = "Integer"),
@ApiImplicitParam(name = "checkPeriod", value = "排查周期1日2周3月4季度5半年", paramType = "query", required = false, dataType = "String"),
@ApiImplicitParam(name = "effectiveTimeEnd_begin", value = "开始日期", paramType = "query", required = false, dataType = "Integer"),
@ApiImplicitParam(name = "effectiveTimeBegin_end", value = "结束日期", paramType = "query", required = false, dataType = "Integer"),
})
@GetMapping(value = "/getRiskByDate")
public Result<List<TrendOneVo>> getRiskByDate(@ApiIgnore @RequestParam HashMap<String, Object> param) {
param.put("allowGenerateTask", 1);
List<RiskListSourceVo> sourceVos = riskListSourceService.queryList(param).stream().filter(o -> StrUtil.isNotBlank(o.getListLibraryName()) && o.getEffectiveTimeBegin() != null && o.getEffectiveTimeEnd() != null).collect(Collectors.toList());
if (CollUtil.isEmpty(sourceVos)) {
return null;
}
Date begin = StrUtil.isNotBlank(MapUtils.getString(param, "effectiveTimeEnd_begin")) ? DateUtil.parseDateTime(MapUtils.getString(param, "effectiveTimeEnd_begin")) : null;
Date end = StrUtil.isNotBlank(MapUtils.getString(param, "effectiveTimeBegin_end")) ? DateUtil.parseDateTime(MapUtils.getString(param, "effectiveTimeBegin_end")) : null;
List<SourceCheckNumBo> checkNumBos = getSourceCheckNumBo(sourceVos);
//1. 计算有效期内的source的每天的应排查(未施工+已排查)数量
List<RiskByDateBo> sourceDateVos = new ArrayList<>();
for (RiskListSourceVo sourceVo : sourceVos) {
Date b = DateUtil.compare(sourceVo.getEffectiveTimeBegin(), begin) > 0 ? sourceVo.getEffectiveTimeBegin() : begin;
Date e = DateUtil.compare(sourceVo.getEffectiveTimeEnd(), end) < 0 ? sourceVo.getEffectiveTimeEnd() : begin;
if (Objects.equals(sourceVo.getCheckPeriod(), 1)) {
DateRange range = DateUtil.range(b, DateUtil.offsetDay(e, 1), DateField.DAY_OF_YEAR);
for (DateTime time : range) {
addRiskByDateBo(sourceDateVos, time, DateUtil.offsetWeek(time, 1), sourceVo, checkNumBos, begin, end);
}
} else if (Objects.equals(sourceVo.getCheckPeriod(), 2)) {
DateRange range = DateUtil.range(DateUtil.beginOfWeek(b), DateUtil.offsetWeek(e, 1), DateField.DAY_OF_WEEK);
for (DateTime time : range) {
addRiskByDateBo(sourceDateVos, time, DateUtil.offsetWeek(time, 1), sourceVo, checkNumBos, begin, end);
}
} else if (Objects.equals(sourceVo.getCheckPeriod(), 3)) {
DateRange range = DateUtil.range(DateUtil.beginOfMonth(b), DateUtil.offsetMonth(e, 1), DateField.MONTH);
for (DateTime time : range) {
addRiskByDateBo(sourceDateVos, time, DateUtil.offsetMonth(time, 1), sourceVo, checkNumBos, begin, end);
}
} else if (Objects.equals(sourceVo.getCheckPeriod(), 4)) {
// 获取起始日期所在季度的第一天
DateTime currentQuarterStart = DateUtil.beginOfQuarter(begin);
// 循环直到当前季度的第一天晚于结束日期
// 注意这里需要确保 endDate 所在的季度被包含
// 可以判断 currentQuarterStart 是否在 endDate 所在季度的开始之前或相同
while (!currentQuarterStart.isAfter(DateUtil.endOfQuarter(end))) {
addRiskByDateBo(sourceDateVos, currentQuarterStart, DateUtil.offsetMonth(currentQuarterStart, 3), sourceVo, checkNumBos, begin, end);
currentQuarterStart = DateUtil.offsetMonth(currentQuarterStart, 3);
}
} else if (Objects.equals(sourceVo.getCheckPeriod(), 5)) {
// 找到起始日期所在的半年的第一个月的第一天
DateTime currentHalfYearStart;
int startMonth = DateUtil.month(begin) + 1; // 月份是0-11所以+1
if (startMonth >= 1 && startMonth <= 6) { // 上半年 (1月-6月)
currentHalfYearStart = DateUtil.beginOfYear(begin); // 获取年份的开始即1月1日
} else { // 下半年 (7月-12月)
currentHalfYearStart = DateUtil.offsetMonth(DateUtil.beginOfYear(begin), 6); // 获取年份的开始然后偏移6个月即7月1日
}
// 循环直到当前半年的第一天晚于结束日期所在的半年的最后一天
// 或者简单判断 currentHalfYearStart 是否晚于 endDate
while (!currentHalfYearStart.isAfter(DateUtil.endOfYear(end))) { // 确保不超过endDate所在的年末
// 进一步判断是否已经超出了endDate
if (currentHalfYearStart.isAfter(end) && DateUtil.month(currentHalfYearStart) + 1 > 6) { // 避免过度遍历到下一个年份的下半年
break;
}
addRiskByDateBo(sourceDateVos, currentHalfYearStart, DateUtil.offsetMonth(currentHalfYearStart, 6), sourceVo, checkNumBos, begin, end);
// 移动到下一个半年的第一个月
currentHalfYearStart = DateUtil.offsetMonth(currentHalfYearStart, 6);
}
}
}
//2. 统计每日执行率
// 临时Map存储每个type的应排查总和和已排查总和
Map<Date, Map<String, Integer>> sumsByType = sourceDateVos.stream().collect(Collectors.groupingBy(RiskByDateBo::getDate,
Collectors.reducing(
new HashMap<String, Integer>() {{
put("totalShould", 0);
put("totalHave", 0);
}}, // 初始值
vo -> { // 为每个元素创建一个临时的Map
return new HashMap<String, Integer>() {{
put("totalShould", vo.getShouldCheckedNum());
put("totalHave", vo.getCheckedNum());
}};
},
(map1, map2) -> { // 合并函数
map1.merge("totalShould", map2.get("totalShould"), (integer, integer2) -> NumberUtil.add(integer, integer2).intValue());
map1.merge("totalHave", map2.get("totalHave"), (integer, integer2) -> NumberUtil.add(integer, integer2).intValue());
return map1;
}
)));
// 计算比率并转换为目标输出格式
List<TrendOneVo> voList = sumsByType.entrySet().stream()
.sorted(Comparator.comparing(Map.Entry::getKey))
.map(entry -> {
Date type = entry.getKey();
Map<String, Integer> totals = entry.getValue();
double totalHave = totals.get("totalHave");
double totalShould = totals.get("totalShould");
Double sumRatio;
if (totalShould == 0) {
sumRatio = null;
} else {
sumRatio = NumberUtil.div(NumberUtil.mul(totalHave, 100), totalShould, 2);
}
TrendOneVo vo = new TrendOneVo();
vo.setX(DateUtil.formatDate(type));
vo.setY(Convert.toStr(sumRatio));
return vo;
})
.collect(Collectors.toList());
return Result.success(null);
}
/**
* 添加每个周期的每天的应排查(未施工+已排查)数量的对象
*
* @param sourceDateVos
* @param periodBegin 周期开始包含
* @param periodEnd 周期结束不包含
* @param sourceVo
* @param checkNumBos
* @param begin
* @param end
*/
private void addRiskByDateBo(List<RiskByDateBo> sourceDateVos, DateTime periodBegin, DateTime periodEnd, RiskListSourceVo sourceVo, List<SourceCheckNumBo> checkNumBos, Date begin, Date end) {
DateRange range = DateUtil.range(periodBegin, periodEnd, DateField.DAY_OF_YEAR);
for (DateTime time1 : range) {
RiskByDateBo newbo = new RiskByDateBo();
newbo.setDate(time1);
newbo.setShouldCheckedNum(sourceVo.getCheckNum());
int count = (int) checkNumBos.stream().filter(bo -> {
boolean b1 = isSameSourceAndTime(begin, end, sourceVo, bo, periodBegin);
return b1 && DateUtil.compare(bo.getDate(), time1) <= 0;
}).count();
newbo.setCheckedNum(count);
newbo.setSourceId(sourceVo.getId());
sourceDateVos.add(newbo);
}
}
@ApiOperation(value = "作业风险柱状比较图", notes = "作业风险柱状比较图", httpMethod = "GET")
@ApiImplicitParams({
@ApiImplicitParam(name = "projectSn", value = "项目sn", paramType = "query", required = true, dataType = "Integer"),
@ApiImplicitParam(name = "pageNo", value = "第几页", paramType = "query", required = true, dataType = "Integer"),
@ApiImplicitParam(name = "pageSize", value = "每页显示条数", paramType = "query", required = true, dataType = "Integer"),
@ApiImplicitParam(name = "checkPeriod", value = "排查周期1日2周3月4季度5半年", paramType = "query", required = false, dataType = "String"),
@ApiImplicitParam(name = "riskAssessmentCalculator", value = "风险评估计算器1:LECD;2:直接判定法;3:LCD;4:LSR;", paramType = "query", required = false, dataType = "String"),
@ApiImplicitParam(name = "projectType", value = "工程类别(字典值)", paramType = "query", required = false, dataType = "Integer"),
@ApiImplicitParam(name = "libraryId", value = "风险清单库id", paramType = "query", required = false, dataType = "String"),
@ApiImplicitParam(name = "effectiveTimeEnd_begin", value = "开始日期", paramType = "query", required = false, dataType = "Integer"),
@ApiImplicitParam(name = "effectiveTimeBegin_end", value = "结束日期", paramType = "query", required = false, dataType = "Integer"),
})
@GetMapping(value = "/getHighRiskValByType")
public Result<IPage<HighRiskValByType>> getHighRiskValByType(@ApiIgnore @RequestParam HashMap<String, Object> param) {
param.put("allowGenerateTask", 1);
List<RiskListSourceVo> sourceVos = riskListSourceService.queryList(param).stream().filter(o -> StrUtil.isNotBlank(o.getListLibraryName()) && o.getEffectiveTimeBegin() != null && o.getEffectiveTimeEnd() != null).collect(Collectors.toList());
if (CollUtil.isEmpty(sourceVos)) {
return null;
}
Map<String, Map<Integer, Optional<RiskListSourceVo>>> collect = sourceVos.stream()
.peek(vo -> vo.setRiskVal(getRiskVal(vo)))
.collect(Collectors.groupingBy(
RiskListSourceVo::getListLibraryName,
Collectors.groupingBy(
RiskListSourceVo::getRiskLevel,
Collectors.maxBy(Comparator.comparing(RiskListSourceVo::getRiskVal))
)));
List<HighRiskValByType> list = collect
.entrySet().stream()
.map(entry -> {
HighRiskValByType type = new HighRiskValByType();
type.setListLibraryName(entry.getKey());
type.setZdRiskHighVal(BigDecimal.ZERO); // 重大风险 (1)
type.setJdRiskHighVal(BigDecimal.ZERO); // 较大风险 (2)
type.setYbRiskHighVal(BigDecimal.ZERO); // 一般风险 (3)
type.setDRiskHighVal(BigDecimal.ZERO); // 低风险 (4)
entry.getValue().forEach((riskLevel, optionalVo) -> {
if (optionalVo.isPresent()) {
BigDecimal riskValue = optionalVo.get().getRiskVal();
switch (riskLevel) {
case 1:
type.setZdRiskHighVal(riskValue); // 重大风险
break;
case 2:
type.setJdRiskHighVal(riskValue); // 较大风险
break;
case 3:
type.setYbRiskHighVal(riskValue); // 一般风险
break;
case 4:
type.setDRiskHighVal(riskValue); // 低风险
break;
}
type.setLibraryId(optionalVo.get().getLibraryId());
}
});
return type;
})
.collect(Collectors.toList());
int pageNo = Integer.parseInt(param.getOrDefault("pageNo", 1).toString());
int pageSize = Integer.parseInt(param.getOrDefault("pageSize", 10).toString());
if (pageSize < 0) {
pageSize = Integer.MAX_VALUE;
}
List<HighRiskValByType> vos = BeanUtil.copyToList(ListUtils.listToTree(JSONArray.parseArray(JSON.toJSONString(list)), "id", "parentId", "children"), HighRiskValByType.class);
int i = cn.hutool.core.util.PageUtil.getStart(pageNo - 1, pageSize);
List<HighRiskValByType> records = CollUtil.sub(vos, i, i + pageSize);
IPage<HighRiskValByType> p = new Page<>();
p.setTotal(vos.size());
p.setRecords(records);
p.setCurrent(pageNo);
p.setSize(pageSize);
return Result.success(p);
}
/**
* 获取风险值
*
* @param vo
* @return
*/
private BigDecimal getRiskVal(RiskListSourceVo vo) {
if (vo.getRiskAssessmentCalculator() == null) {
return null;
}
BigDecimal decimal = null;
JSONObject jsonObject;
switch (vo.getRiskAssessmentCalculator()) {
case 1:
jsonObject = JSON.parseObject(vo.getLecdData());
decimal = NumberUtil.mul(jsonObject.getDouble("lNumber"), jsonObject.getDouble("eNumber"), jsonObject.getDouble("cNumber"));
break;
case 2:
decimal = Convert.toBigDecimal(vo.getDirectDeterminationMethodData());
break;
case 3:
jsonObject = JSON.parseObject(vo.getLcdData());
decimal = NumberUtil.mul(jsonObject.getDouble("lNumber"), jsonObject.getDouble("cNumber"), 1);
break;
case 4:
jsonObject = JSON.parseObject(vo.getLsrData());
decimal = NumberUtil.mul(jsonObject.getDouble("lNumber"), jsonObject.getDouble("sNumber"), 1);
break;
}
return decimal;
}
}

View File

@ -0,0 +1,23 @@
package com.zhgd.xmgl.modules.risk.entity.bo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
@Data
public class RiskByDateBo {
/**
* 日期
*/
private Date date;
/**
* 应排查数量
*/
private Integer shouldCheckedNum;
/**
* 已排查数量隐患+排查记录
*/
private java.lang.Integer checkedNum;
private Long sourceId;
}

View File

@ -0,0 +1,11 @@
package com.zhgd.xmgl.modules.risk.entity.bo;
import lombok.Data;
import java.util.Date;
@Data
public class SourceCheckNumBo {
private Date date;
private Long sourceId;
}

View File

@ -0,0 +1,40 @@
package com.zhgd.xmgl.modules.risk.entity.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class HighRiskValByType {
/**
* 重大风险最高值
*/
@ApiModelProperty(value = "重大风险最高值")
private BigDecimal zdRiskHighVal;
/**
* 较大风险最高值
*/
@ApiModelProperty(value = "较大风险最高值")
private BigDecimal jdRiskHighVal;
/**
* 一般风险最高值
*/
@ApiModelProperty(value = "一般风险最高值")
private BigDecimal ybRiskHighVal;
/**
* 低风险最高值
*/
@ApiModelProperty(value = "低风险最高值")
private BigDecimal dRiskHighVal;
/**
* 风险清单库名称
*/
@ApiModelProperty(value = "风险清单库名称")
private java.lang.String listLibraryName;
/**
* 风险清单库id
*/
@ApiModelProperty(value = "风险清单库id")
private java.lang.Long libraryId;
}

View File

@ -1,12 +1,29 @@
package com.zhgd.xmgl.modules.risk.entity.vo;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.zhgd.xmgl.modules.risk.entity.RiskListSource;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class RiskListSourceVo extends RiskListSource {
/**
* 风险清单库id
*/
@ApiModelProperty(value = "风险清单库id")
private java.lang.Long libraryId;
/**
* 风险值
*/
@JsonIgnore
private BigDecimal riskVal;
/**
* 应排查数量
*/
@JsonIgnore
private java.lang.Integer shouldCheckedNum;
/**
* 已排查数量隐患+排查记录
*/

View File

@ -55,4 +55,5 @@ public interface RiskListSourceMapper extends BaseMapper<RiskListSource> {
CountRisksByLevelVo countRisksByLevel(HashMap<String, Object> param);
List<SectorOneVo> countRisksByLibrary(HashMap<String, Object> map);
}

View File

@ -8,6 +8,7 @@
,rlpat.type as accident_type_name
,rll.node_name as list_library_name
,#{param.workable} as workable
,rll.id as library_id
from risk_list_source t
join risk_list_point rlp on rlp.id=t.point_id
left join risk_list_library rll on rll.id=rlp.risk_list_library_id

View File

@ -3,7 +3,7 @@ package com.zhgd.xmgl.modules.risk.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zhgd.xmgl.base.entity.vo.SectorOneVo;
import com.zhgd.xmgl.base.entity.vo.SectorVo;
import com.zhgd.xmgl.base.entity.vo.TrendOneVo;
import com.zhgd.xmgl.modules.risk.entity.RiskListSource;
import com.zhgd.xmgl.modules.risk.entity.vo.CountRisksByLevelVo;
import com.zhgd.xmgl.modules.risk.entity.vo.RiskListSourceVo;
@ -73,7 +73,6 @@ public interface IRiskListSourceService extends IService<RiskListSource> {
CountRisksByLevelVo countRisksByLevel(HashMap<String, Object> param);
List<CountRisksByLevelVo> getRiskTrendChart(HashMap<String, Object> param);
List<SectorOneVo> countRisksByLibrary(HashMap<String, Object> map);
SectorVo countRisksByLibrary(HashMap<String, Object> map);
}

View File

@ -12,6 +12,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhgd.jeecg.common.execption.OpenAlertException;
import com.zhgd.jeecg.common.system.query.QueryGenerator;
import com.zhgd.xmgl.modules.basicdata.service.ICompanyService;
import com.zhgd.xmgl.modules.basicdata.service.impl.DictionaryItemServiceImpl;
import com.zhgd.xmgl.modules.risk.entity.RiskListDetail;
import com.zhgd.xmgl.modules.risk.entity.RiskListLibrary;
@ -40,6 +41,9 @@ import java.util.stream.Collectors;
*/
@Service
public class RiskListLibraryServiceImpl extends ServiceImpl<RiskListLibraryMapper, RiskListLibrary> implements IRiskListLibraryService {
@Lazy
@Autowired
ICompanyService companyService;
@Autowired
private RiskListLibraryMapper riskListLibraryMapper;
@Lazy

View File

@ -2,8 +2,6 @@ package com.zhgd.xmgl.modules.risk.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@ -15,7 +13,6 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhgd.jeecg.common.execption.OpenAlertException;
import com.zhgd.jeecg.common.system.query.QueryGenerator;
import com.zhgd.xmgl.base.entity.vo.SectorOneVo;
import com.zhgd.xmgl.base.entity.vo.SectorVo;
import com.zhgd.xmgl.modules.basicdata.entity.SystemUser;
import com.zhgd.xmgl.modules.basicdata.service.INoticeService;
import com.zhgd.xmgl.modules.basicdata.service.ISystemUserService;
@ -36,7 +33,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@ -286,36 +282,8 @@ public class RiskListSourceServiceImpl extends ServiceImpl<RiskListSourceMapper,
}
@Override
public List<CountRisksByLevelVo> getRiskTrendChart(HashMap<String, Object> param) {
List<RiskListSource> sources = this.list(new LambdaQueryWrapper<RiskListSource>()
.select(RiskListSource::getId, RiskListSource::getEffectiveTimeBegin, RiskListSource::getEffectiveTimeEnd)
.eq(RiskListSource::getProjectSn, MapUtils.getString(param, "projectSn"))
.le(RiskListSource::getEffectiveTimeBegin, MapUtils.getString(param, "endTime") + "-31 23:59:59")
.ge(RiskListSource::getEffectiveTimeEnd, MapUtils.getString(param, "startTime") + "-01 00:00:00")
).stream().sorted(Comparator.comparing(RiskListSource::getEffectiveTimeBegin)).collect(Collectors.toList());
List<DateTime> months = DateUtil.rangeToList(DateUtil.parse(MapUtils.getString(param, "startTime")), DateUtil.parse(MapUtils.getString(param, "endTime")), DateField.MONTH);
ArrayList<CountRisksByLevelVo> vos = new ArrayList<>();
Integer lastTotal = null;
for (DateTime month : months) {
CountRisksByLevelVo vo = new CountRisksByLevelVo();
vo.setZdNum((int) sources.stream().filter(s -> Objects.equals(s.getRiskLevel(), 1) && DateUtil.compare(s.getEffectiveTimeBegin(), month) <= 0 && DateUtil.compare(s.getEffectiveTimeEnd(), month) >= 0).count());
vo.setJdNum((int) sources.stream().filter(s -> Objects.equals(s.getRiskLevel(), 2) && DateUtil.compare(s.getEffectiveTimeBegin(), month) <= 0 && DateUtil.compare(s.getEffectiveTimeEnd(), month) >= 0).count());
vo.setYbNum((int) sources.stream().filter(s -> Objects.equals(s.getRiskLevel(), 3) && DateUtil.compare(s.getEffectiveTimeBegin(), month) <= 0 && DateUtil.compare(s.getEffectiveTimeEnd(), month) >= 0).count());
vo.setDNum((int) sources.stream().filter(s -> Objects.equals(s.getRiskLevel(), 4) && DateUtil.compare(s.getEffectiveTimeBegin(), month) <= 0 && DateUtil.compare(s.getEffectiveTimeEnd(), month) >= 0).count());
vo.setTotal((int) sources.stream().filter(s -> DateUtil.compare(s.getEffectiveTimeBegin(), month) <= 0 && DateUtil.compare(s.getEffectiveTimeEnd(), month) >= 0).count());
vo.setYearMonth(DateUtil.format(month, "yyyy-MM"));
if (lastTotal != null) {
vo.setMoMChange(lastTotal != 0 ? new BigDecimal((vo.getTotal() * 1.0 / lastTotal - 1) * 100).setScale(2, BigDecimal.ROUND_HALF_UP) : null);
}
lastTotal = vo.getTotal();
vos.add(vo);
}
return vos;
public List<SectorOneVo> countRisksByLibrary(HashMap<String, Object> map) {
return baseMapper.countRisksByLibrary(map);
}
@Override
public SectorVo countRisksByLibrary(HashMap<String, Object> map) {
List<SectorOneVo> list = baseMapper.countRisksByLibrary(map);
return SectorVo.getSectorVo(list);
}
}