提交 ab967d5c authored 作者: Matrix's avatar Matrix

[核查模块] 修复了初始化自动核查的统计数据异常

上级 1b6a3fa8
......@@ -2,6 +2,7 @@ package com.tykj.dev.device.confirmcheck.controller;
import com.google.common.collect.Lists;
import com.tykj.dev.config.swagger.AutoDocument;
import com.tykj.dev.device.confirmcheck.entity.cache.AreaCache;
import com.tykj.dev.device.confirmcheck.entity.domain.DeviceCheckBillEntity;
import com.tykj.dev.device.confirmcheck.entity.domain.DeviceCheckDetailEntity;
import com.tykj.dev.device.confirmcheck.entity.domain.DeviceCheckStat;
......@@ -24,10 +25,11 @@ import com.tykj.dev.device.user.subject.entity.Area;
import com.tykj.dev.device.user.subject.entity.Units;
import com.tykj.dev.device.user.subject.entity.User;
import com.tykj.dev.device.user.util.AuthenticationUtils;
import com.tykj.dev.config.GlobalMap;
import com.tykj.dev.misc.base.GlobalMap;
import com.tykj.dev.misc.base.ResultObj;
import com.tykj.dev.misc.base.StatusEnum;
import com.tykj.dev.misc.utils.JacksonUtil;
import com.tykj.dev.misc.utils.MapperUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
......@@ -40,13 +42,13 @@ import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;
import static com.tykj.dev.misc.base.BusinessEnum.CONFIRM_CHECK_DETAIL;
import static com.tykj.dev.misc.base.BusinessEnum.CONFIRM_CHECK_STAT;
import static com.tykj.dev.misc.base.StatusEnum.*;
import static com.tykj.dev.misc.utils.TimestampUtil.localDateToDate;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.*;
/**
* @author dengdiyi
......@@ -82,6 +84,9 @@ public class DeviceCheckController {
@Autowired
private AuthenticationUtils AuthenticationUtils;
@Autowired
private AreaCache areaCache;
@GetMapping("/area/{fatherId}")
@ApiOperation(value = "查询指定区域下的所有区域信息")
public ResponseEntity findAreaUnderId(@PathVariable Integer fatherId, HttpServletRequest request) {
......@@ -142,111 +147,147 @@ public class DeviceCheckController {
TaskBto provStatTask = new Task(CHECK_STAT_0.id, "省自动核查", 0, ".0.", CONFIRM_CHECK_STAT.id, provStat.getId(), provUnit.getUnitId())
.parse2Bto();
provStatTask.setInvolveUserIdList(Lists.newArrayList(-1));
provStatTask = taskService.start(provStatTask);
provStatTask = taskService.start(provStatTask).parse2Bto();
resultIds.get("taskId").add(provStatTask.getId());
List<CheckDeviceStatVo> statVoList = new ArrayList<>();
List<DeviceCheckStat> cityStatList = new ArrayList<>();
List<String> countyNames = new ArrayList<>();
List<String> countyAreaNames = new ArrayList<>();
// 构建所有市的统计账单(先不考虑JSON-INFO)
for (Units city : cityUnits) {
List<Integer> areaIds = areaRepo.findAllByFatherId(city.getAreaId()).stream().map(Area::getId).collect(toList());
for (Units cityUnit : cityUnits) {
List<Integer> areaIds = areaRepo.findAllByFatherId(cityUnit.getAreaId()).stream().map(Area::getId).collect(toList());
List<Units> countyUnits = unitsRepo.findByAreaIdIn(areaIds);
// 构建市统账单
DeviceCheckStat cityStatDo = initStatData("自动核查",
DeviceCheckStat cityStatDo = initStatData("系统发起的统计|" + cityUnit.getName() + "|" + cityUnit.getAreaId(),
0,
0,
baseTitle + city.getName() + "自动核查统计",
provUnit.getName(),
baseTitle + cityUnit.getName() + "自动核查统计",
cityUnit.getName(),
countyUnits);
DeviceCheckStat cityStat = statRepo.save(cityStatDo);
cityStatList.add(cityStat);
resultIds.get("statId").add(cityStat.getId());
// 构建市统task 获得id
TaskBto cityStatTask = new Task(CHECK_STAT_0.id, city.getName() + "自动核查统计", provStatTask.getId(), addNode(provStatTask.getNodeIdDetail(), provinceStatDo.getId()), CONFIRM_CHECK_STAT.id, cityStat.getId(), city.getUnitId())
TaskBto cityStatTask = new Task(CHECK_STAT_0.id, cityUnit.getName() + "自动核查统计", provStatTask.getId(), addNode(provStatTask.getNodeIdDetail(), provinceStatDo.getId()), CONFIRM_CHECK_STAT.id, cityStat.getId(), cityUnit.getUnitId())
.parse2Bto();
cityStatTask.setInvolveUserIdList(Lists.newArrayList(-1));
cityStatTask = taskService.start(cityStatTask);
cityStatTask = taskService.start(cityStatTask).parse2Bto();
resultIds.get("taskId").add(cityStatTask.getId());
// 构建市自查账单
DeviceCheckDetailEntity cityDetailDo = DeviceCheckDetailEntity.EmptyWithChecker(
"系统发起的自查|" + city.getName() + "|" + city.getAreaId(),
baseTitle + city.getName() + "核查任务",
"系统发起的自查|" + cityUnit.getName() + "|" + cityUnit.getAreaId(),
baseTitle + cityUnit.getName() + "核查任务",
0, 0, 0, 0,
provUnit.getName(),
devInLib.getOrDefault(city.getName(), new ArrayList<>()),
devNotInLib.getOrDefault(city.getName(), new ArrayList<>()));
devInLib.getOrDefault(cityUnit.getName(), new ArrayList<>()),
devNotInLib.getOrDefault(cityUnit.getName(), new ArrayList<>()));
DeviceCheckDetailEntity cityDetail = detailRepo.save(cityDetailDo);
resultIds.get("detailId").add(cityDetail.getId());
String cityName = areaRepo.findNameById(cityUnit.getAreaId());
List<CheckDeviceStatVo> cityStatVoList = deviceList.stream()
.filter(d -> d.getOwnUnit().equals(city.getName()))
.map(d -> transUtil.device2InitStatVo(d, city.getName(), cityStat.getId(), cityDetail.getId()))
.filter(d -> d.getOwnUnit().equals(cityUnit.getName()))
.map(d -> transUtil.device2InitStatVo(d, cityName, cityStat.getId(), cityDetail.getId()))
.collect(toList());
statVoList.addAll(cityStatVoList);
// 构建市自查TASK
TaskBto cityDetailTask = new TaskBto(CHECK_DETAIL_0.id, city.getName() + "自动核查自查", cityStatTask.getId(), addNode(cityStatTask.getNodeIdDetail(), cityStatTask.getId()), CONFIRM_CHECK_DETAIL.id, cityDetail.getId(), city.getUnitId(), 0);
cityDetailTask = taskService.start(cityDetailTask);
TaskBto cityDetailTask = new TaskBto(CHECK_DETAIL_0.id, cityUnit.getName() + "自动核查自查", cityStatTask.getId(), addNode(cityStatTask.getNodeIdDetail(), cityStatTask.getId()), CONFIRM_CHECK_DETAIL.id, cityDetail.getId(), cityUnit.getUnitId(), 0);
cityDetailTask = taskService.start(cityDetailTask).parse2Bto();
resultIds.get("taskId").add(cityDetailTask.getId());
// 构建县任务
for (Units county : countyUnits) {
countyNames.add(county.getName());
for (Units countyUnit : countyUnits) {
countyAreaNames.add(areaCache.findById(countyUnit.getAreaId()).getName());
//构建县自查账单
DeviceCheckDetailEntity countyDetailDo = DeviceCheckDetailEntity.EmptyWithChecker(
"系统发起的自查|" + county.getName() + "|" + county.getAreaId(),
baseTitle + county.getName() + "核查任务",
"系统发起的自查|" + countyUnit.getName() + "|" + countyUnit.getAreaId(),
baseTitle + countyUnit.getName() + "核查任务",
0, 0, 0, 0,
provUnit.getName(),
devInLib.getOrDefault(city.getName(), new ArrayList<>()),
devNotInLib.getOrDefault(city.getName(), new ArrayList<>()));
devInLib.getOrDefault(cityUnit.getName(), new ArrayList<>()),
devNotInLib.getOrDefault(cityUnit.getName(), new ArrayList<>()));
DeviceCheckDetailEntity countyDetail = detailRepo.save(countyDetailDo);
resultIds.get("detailId").add(countyDetail.getId());
String countyName = areaRepo.findNameById(countyUnit.getAreaId());
List<CheckDeviceStatVo> countyStatVoList = deviceList.stream()
.filter(d -> d.getOwnUnit().equals(city.getName()))
.map(d -> transUtil.device2InitStatVo(d, city.getName(), cityStat.getId(), countyDetail.getId()))
.filter(d -> d.getOwnUnit().equals(countyUnit.getName()))
.map(d -> transUtil.device2InitStatVo(d, countyName, cityStat.getId(), countyDetail.getId()))
.collect(toList());
statVoList.addAll(countyStatVoList);
//构建县自查TASK
TaskBto countyDetailTask = new TaskBto(CHECK_DETAIL_0.id, county.getName() + "自动核查自查", cityStatTask.getId(), addNode(cityStatTask.getNodeIdDetail(), cityStatTask.getId()), CONFIRM_CHECK_DETAIL.id, countyDetail.getId(), county.getUnitId(), 0);
countyDetailTask = taskService.start(countyDetailTask);
TaskBto countyDetailTask = new TaskBto(CHECK_DETAIL_0.id, countyUnit.getName() + "自动核查自查", cityStatTask.getId(), addNode(cityStatTask.getNodeIdDetail(), cityStatTask.getId()), CONFIRM_CHECK_DETAIL.id, countyDetail.getId(), countyUnit.getUnitId(), 0);
countyDetailTask = taskService.start(countyDetailTask).parse2Bto();
resultIds.get("taskId").add(countyDetailTask.getId());
}
// 处理JSON INFO 数据
// 对于省统计来说,需要去掉所有的区地区的数据
CheckDeviceStatVo provStatVo = statVoList.stream()
.filter(stat -> !countyNames.contains(stat.getAreaStatList().get(0).getAreaName()))
.reduce(CheckDeviceStatVo::add)
.get();
provStat.setStatInfo(JacksonUtil.toJSon(provStatVo));
statRepo.save(provStat);
// 对于市统计来说,只需要自己本市以及其下地区的数据
for (DeviceCheckStat csd : cityStatList) {
List<String> cityNames = new ArrayList<>();
if (csd.getRemark().split("\\|").length <= 1) {
continue;
}
String areaName = csd.getRemark().split("\\|")[1];
Integer cityId = Integer.valueOf(csd.getRemark().split("\\|")[2]);
List<String> childNames = areaRepo.findByFatherId(cityId).stream().map(Area::getName).collect(toList());
cityNames.add(areaName);
cityNames.addAll(childNames);
CheckDeviceStatVo cityStatVo = statVoList.stream()
.filter(stat -> cityNames.contains(stat.getAreaStatList().get(0).getAreaName()))
.reduce(CheckDeviceStatVo::add)
.get();
csd.setStatInfo(JacksonUtil.toJSon(cityStatVo));
}
statRepo.saveAll(cityStatList);
}
// 处理JSON INFO 数据
// 对于省统计来说,需要去掉所有的区地区的数据
List<CheckDeviceStatVo> statVoListCopy1 = MapperUtils.mapAll(statVoList, CheckDeviceStatVo.class);
List<CheckDeviceStatVo> statVoListCopy2 = MapperUtils.mapAll(statVoList, CheckDeviceStatVo.class);
//分组 分出区数据 与 非市数据 , 市数据进行分组 - 按照model名分组 model - areaName - Object
Map<Boolean, List<CheckDeviceStatVo>> regionMap = statVoListCopy1.stream()
.collect(partitioningBy(stat -> countyAreaNames.contains(stat.getAreaStatList().get(0).getAreaName())));
List<CheckDeviceStatVo> countyVo = regionMap.get(true);
Map<String, Map<String, List<CheckDeviceStatVo>>> modAreaMap = regionMap.get(false).stream()
.collect(groupingBy(CheckDeviceStatVo::getDeviceModel,
groupingBy(c -> c.getAreaStatList().get(0).getAreaName())));
//查找区域数据内的父级地区(即市),将数据count数据add进去(通过两次get)
for (CheckDeviceStatVo v : countyVo) {
String couName = v.getAreaStatList().get(0).getAreaName();
String fatherName = areaCache.findFatherByName(couName).getName();
modAreaMap.computeIfPresent(v.getDeviceModel(), (k1, v1) -> {
v1.computeIfPresent(fatherName, (k2, v2) -> {
log.warn("发现需要堆叠计算的装备,装备信息为: {}", v2);
v2.get(0).addDeviceCount(1);
v2.get(0).getAreaStatList().get(0).addSuppose(1);
return v2;
});
return v1;
});
}
//将市级Map里的数据全部取出来展平一层并累加
List<CheckDeviceStatVo> filterVoList = new ArrayList<>();
modAreaMap.forEach((model, v1) -> v1.forEach((name, v2) -> filterVoList.addAll(v2)));
//按照model分组并累加然后再次积累成一个checkDeviceStatVo
List<CheckDeviceStatVo> provStatVoList = new ArrayList<>();
filterVoList.stream()
.collect(Collectors.groupingBy(CheckDeviceStatVo::getDeviceModel, reducing(CheckDeviceStatVo::add)))
.forEach((k, v) -> provStatVoList.add(v.get()));
provStat.setStatInfo(JacksonUtil.toJSon(provStatVoList));
statRepo.save(provStat);
// 对于市统计来说,只需要自己本市以及其下地区的数据
for (DeviceCheckStat csd : cityStatList) {
List<String> cityNames = new ArrayList<>();
if (csd.getRemark().split("\\|").length <= 1) {
continue;
}
String areaName = csd.getRemark().split("\\|")[1];
Integer cityId = Integer.valueOf(csd.getRemark().split("\\|")[2]);
List<String> childNames = areaRepo.findByFatherId(cityId).stream().map(Area::getName).collect(toList());
cityNames.add(areaName);
cityNames.addAll(childNames);
//去除其他地区的数据
List<CheckDeviceStatVo> cityStatVo = new ArrayList<>();
statVoListCopy2.stream()
.filter(stat -> cityNames.contains(stat.getAreaStatList().get(0).getAreaName()))
.collect(Collectors.groupingBy(CheckDeviceStatVo::getDeviceModel, reducing(CheckDeviceStatVo::add)))
.forEach((k, v) -> cityStatVo.add(v.get()));
csd.setStatInfo(JacksonUtil.toJSon(cityStatVo));
}
statRepo.saveAll(cityStatList);
return ResponseEntity.ok(new ResultObj(resultIds, "自动核查任务发起成功"));
}
......@@ -281,7 +322,7 @@ public class DeviceCheckController {
provStatTask.getInvolveUserIdList().add(AuthenticationUtils.getAuthentication().getCurrentUserInfo().getUserId());
provStatTask.getInvolveUserIdList().add(-1);
provStatTask.setCurrentPoint(1);
provStatTask = taskService.start(provStatTask);
provStatTask = taskService.start(provStatTask).parse2Bto();
// 3 构建被查单位的 自查账单 与 自查任务
// 获取所有在库装备与不在库装备
......
package com.tykj.dev.device.confirmcheck.entity.cache;
import com.tykj.dev.device.user.subject.entity.Area;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* AreaCache.
*
* @author Matrix <xhyrzldf@gmail.com>
* @since 2020/9/22 at 5:33 下午
*/
public class AreaCache {
private Map<String, Area> nameMap;
private Map<Integer, Area> idMap;
public AreaCache(List<Area> areaList) {
nameMap = areaList.stream().collect(Collectors.toMap(Area::getName, Function.identity()));
idMap = areaList.stream().collect(Collectors.toMap(Area::getId, Function.identity()));
}
public Area findFatherByName(String name) {
Area area = nameMap.get(name);
return idMap.get(area.getFatherId());
}
public Area findByName(String name) {
return nameMap.get(name);
}
public Area findById(Integer id) {
return idMap.get(id);
}
}
package com.tykj.dev.device.confirmcheck.entity.cache;
import com.tykj.dev.device.user.subject.dao.AreaDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* CacheBeanConfig.
*
* @author Matrix <xhyrzldf@gmail.com>
* @since 2020/9/22 at 6:24 下午
*/
@Configuration
public class CacheBeanConfig {
@Autowired
private AreaDao areaRepo;
@Bean
public AreaCache initAreaCache() {
return new AreaCache(areaRepo.findAll());
}
}
......@@ -49,4 +49,9 @@ public class CheckAreaStatVo {
* 该地区对应的详情账单id
*/
private int areaDetailId;
public CheckAreaStatVo addSuppose(int supposeCount) {
this.supposeCount += supposeCount;
return this;
}
}
......@@ -76,4 +76,9 @@ public class CheckDeviceStatVo {
return this;
}
public CheckDeviceStatVo addDeviceCount(int count){
this.deviceCount += count;
return this;
}
}
package com.tykj.dev.misc.utils;
import org.modelmapper.ModelMapper;
import org.modelmapper.convention.MatchingStrategies;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
/**
* ObjectMapperUtils.
*
* @author Matrix <xhyrzldf@gmail.com>
* @since 2020/9/22 at 7:05 下午
*/
public class MapperUtils {
private static ModelMapper modelMapper = new ModelMapper();
/**
* Model mapper property setting are specified in the following block.
* Default property matching strategy is set to Strict see {@link MatchingStrategies}
* Custom mappings are added using {@link ModelMapper#addMappings(PropertyMap)}
*/
static {
modelMapper = new ModelMapper();
modelMapper.getConfiguration().setAmbiguityIgnored(true);
//设置为严格匹配
modelMapper.getConfiguration().setFullTypeMatchingRequired(true);
modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
}
/**
* Hide from public usage.
*/
private MapperUtils() {
}
/**
* <p>Note: outClass object must have default constructor with no arguments</p>
*
* @param <D> type of result object.
* @param <T> type of source object to map from.
* @param entity entity that needs to be mapped.
* @param outClass class of result object.
* @return new object of <code>outClass</code> type.
*/
public static <D, T> D map(final T entity, Class<D> outClass) {
return modelMapper.map(entity, outClass);
}
/**
* <p>Note: outClass object must have default constructor with no arguments</p>
*
* @param entityList list of entities that needs to be mapped
* @param outCLass class of result list element
* @param <D> type of objects in result list
* @param <T> type of entity in <code>entityList</code>
* @return list of mapped object with <code><D></code> type.
*/
public static <D, T> List<D> mapAll(final Collection<T> entityList, Class<D> outCLass) {
return entityList.stream()
.map(entity -> map(entity, outCLass))
.collect(Collectors.toList());
}
/**
* Maps {@code source} to {@code destination}.
*
* @param source object to map from
* @param destination object to map to
*/
public static <S, D> D map(final S source, D destination) {
modelMapper.map(source, destination);
return destination;
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论