提交 1ae0a3dd authored 作者: Matrix's avatar Matrix

feat(核查模块): 完善了阅知,自动终结任务的机制

上级 723c7806
...@@ -4,7 +4,6 @@ import com.alibaba.fastjson.JSON; ...@@ -4,7 +4,6 @@ import com.alibaba.fastjson.JSON;
import com.github.wenhao.jpa.Specifications; import com.github.wenhao.jpa.Specifications;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.sun.tools.corba.se.idl.StringGen;
import com.tykj.dev.config.GlobalMap; import com.tykj.dev.config.GlobalMap;
import com.tykj.dev.config.swagger.AutoDocument; import com.tykj.dev.config.swagger.AutoDocument;
import com.tykj.dev.device.confirmcheck.common.CcNodeType; import com.tykj.dev.device.confirmcheck.common.CcNodeType;
...@@ -34,6 +33,7 @@ import com.tykj.dev.device.task.subject.bto.TaskBto; ...@@ -34,6 +33,7 @@ import com.tykj.dev.device.task.subject.bto.TaskBto;
import com.tykj.dev.device.task.subject.bto.TaskLogBto; import com.tykj.dev.device.task.subject.bto.TaskLogBto;
import com.tykj.dev.device.task.subject.domin.Task; import com.tykj.dev.device.task.subject.domin.Task;
import com.tykj.dev.device.user.base.enums.AuExample; import com.tykj.dev.device.user.base.enums.AuExample;
import com.tykj.dev.device.user.base.ret.UserShenRe;
import com.tykj.dev.device.user.cache.AreaCache; import com.tykj.dev.device.user.cache.AreaCache;
import com.tykj.dev.device.user.read.service.MessageService; import com.tykj.dev.device.user.read.service.MessageService;
import com.tykj.dev.device.user.read.subject.bto.MessageBto; import com.tykj.dev.device.user.read.subject.bto.MessageBto;
...@@ -237,7 +237,7 @@ public class DeviceCheckController { ...@@ -237,7 +237,7 @@ public class DeviceCheckController {
return ccService.findAllStatTable(checkBillSelectVo); return ccService.findAllStatTable(checkBillSelectVo);
} }
@ApiOperation(value = "根据id查询核查详情数据", notes = "可以通过这个接口查询核查详情数据") @ApiOperation(value = "根据billId查询核查详情数据", notes = "可以通过这个接口查询核查详情数据")
@GetMapping("/detail/{id}") @GetMapping("/detail/{id}")
public ResponseEntity<ResultObj<CheckDetailVo>> findDetail(@PathVariable Integer id) { public ResponseEntity<ResultObj<CheckDetailVo>> findDetail(@PathVariable Integer id) {
CheckDetailVo detailVoList = detailRepo.findById(id) CheckDetailVo detailVoList = detailRepo.findById(id)
...@@ -246,6 +246,20 @@ public class DeviceCheckController { ...@@ -246,6 +246,20 @@ public class DeviceCheckController {
return ResponseEntity.ok(new ResultObj<>(detailVoList)); return ResponseEntity.ok(new ResultObj<>(detailVoList));
} }
@ApiOperation(value = "提供taskId,该接口返回可以跳转到详情页面的数据", notes = "提供taskId,该接口返回可以跳转到详情页面的数据")
@GetMapping("/msgLink")
public ResponseEntity msgLink(@RequestParam Integer taskId) {
// 如果是businessType = 7 走unionLink 否则走detail接口
Task task = taskRepo.findById(taskId).orElseThrow(() -> new ApiException(String.format("没有找到taskId = %d 的任务", taskId)));
if (task.getBusinessType().equals(CONFIRM_CHECK_STAT.id)){
return unionLink(7, task.getBillId());
}else if (task.getBusinessType().equals(CONFIRM_CHECK_DETAIL.id)){
return findDetail(task.getBillId());
}
return ResponseEntity.status(400).body("该businessType不在处理范围内!本接口处理的type = 7 ,8");
}
@ApiOperation(value = "根据id查询核查详情数据", notes = "可以通过这个接口查询核查详情数据") @ApiOperation(value = "根据id查询核查详情数据", notes = "可以通过这个接口查询核查详情数据")
@GetMapping("/detail/unit/{unitId}") @GetMapping("/detail/unit/{unitId}")
public ResponseEntity<ResultObj<List<CheckDetailVo>>> findDetailsByUnitId(@PathVariable Integer unitId) { public ResponseEntity<ResultObj<List<CheckDetailVo>>> findDetailsByUnitId(@PathVariable Integer unitId) {
...@@ -341,43 +355,6 @@ public class DeviceCheckController { ...@@ -341,43 +355,6 @@ public class DeviceCheckController {
return ResponseEntity.ok(new ResultObj<>(cdVo)); return ResponseEntity.ok(new ResultObj<>(cdVo));
} }
/**
* 获得指定单位的在库装备与非在库装备
*
* @param checkUnit 单位名
* @param allDevices 装备列表
* @return true -> 在库装备,false -> 非在库装备
*/
@NotNull
private Map<Boolean, List<DeviceLibrary>> getDevLibMap(String checkUnit, List<DeviceLibrary> allDevices) {
//在库 = A and B & not B 去除掉ls = 10 的装备 把ls = 11 的装备加入到非在库
Map<Boolean, List<DeviceLibrary>> locationMap = allDevices.stream()
.collect(partitioningBy(d -> d.getLocationUnit().equals(checkUnit)));
List<DeviceLibrary> devInLib = locationMap.get(true);
// filter ls == 11 join to 非在库
List<DeviceLibrary> ls11Lib = devInLib.stream().filter(d -> d.getLifeStatus() == 11).collect(toList());
// filter ls == 10
devInLib = devInLib.stream()
.filter(d -> d.getLifeStatus() != 10 && d.getLifeStatus() != 11)
.collect(toList());
// 非在库 = not A and in B
List<DeviceLibrary> devNotInLib = locationMap.get(false)
.stream().filter(d -> d.getOwnUnit().equals(checkUnit))
.collect(toList());
devNotInLib.addAll(ls11Lib);
Map<Boolean, List<DeviceLibrary>> devLib = new HashMap<>();
devLib.put(true, devInLib);
devLib.put(false, devNotInLib);
return devLib;
}
/** /**
* 该接口负责处理以下跳转情况 * 该接口负责处理以下跳转情况
* 1 - 统计跳转 * 1 - 统计跳转
...@@ -422,13 +399,12 @@ public class DeviceCheckController { ...@@ -422,13 +399,12 @@ public class DeviceCheckController {
// key = stat id ,value = LinkVo // key = stat id ,value = LinkVo
if (rootTask.getBillStatus().equals(REVOKEALLOTTASK.id)) { if (rootTask.getBillStatus().equals(REVOKEALLOTTASK.id)) {
// 拿之前保存的缓存 // 拿之前保存的缓存
linkVo = linkRepo.findByStatId(billId) linkVo = linkRepo.findByStatId(billId)
.orElseThrow(() -> new ApiException(String.format("没有找到stat id = %d 的统计缓存,请检查数据", billId))) .orElseThrow(() -> new ApiException(String.format("没有找到stat id = %d 的统计缓存,请检查数据", billId)))
.toVo() .toVo()
.getLinkVo(); .getLinkVo();
linkVo.setShutDown(true); linkVo.setShutDown(true);
} } else {
else {
// 正常处理,即时计算 // 正常处理,即时计算
// checkType = 0 核查,checkType = 1 检查 // checkType = 0 核查,checkType = 1 检查
if (ctVo.getCheckType() == 0) { if (ctVo.getCheckType() == 0) {
...@@ -601,8 +577,8 @@ public class DeviceCheckController { ...@@ -601,8 +577,8 @@ public class DeviceCheckController {
} }
//将此次使用的linkVo更新 //将此次使用的linkVo更新
DeviceCheckLink updateLink = linkRepo.findByStatId(billId) .orElse(new DeviceCheckLink()); DeviceCheckLink updateLink = linkRepo.findByStatId(billId).orElse(new DeviceCheckLink());
updateLink.setLinkText(JSON.toJSONStringWithDateFormat(linkVo,"yyyy-MM-dd")); updateLink.setLinkText(JSON.toJSONStringWithDateFormat(linkVo, "yyyy-MM-dd"));
updateLink.setStatId(billId); updateLink.setStatId(billId);
linkRepo.save(updateLink); linkRepo.save(updateLink);
...@@ -610,379 +586,129 @@ public class DeviceCheckController { ...@@ -610,379 +586,129 @@ public class DeviceCheckController {
} }
@NotNull /**
private LinkExamDetail getLed(LocalDateTime endTime, LocalDateTime updateTime, Task child) { * @param periodId 1-月度 2-季度 3-年度
Integer childBusType = child.getBusinessType(); * @return
Integer childBusId = child.getBillId(); */
@ApiOperation(value = "更新自动核查周期", notes = "更新自动核查周期")
DeviceCheckDetail childDetail = detailRepo.findById(childBusId).get(); @PutMapping("/task/{periodId}")
String unitName = childDetail.getCheckUnit(); public ResponseEntity updateTaskPeriod(
@PathVariable @ApiParam(value = "核查周期,1-月度 2-季度 3-年度", example = "1") Integer periodId) {
if (periodId < 1 || periodId > 3) {
return ResponseEntity.status(400).body(new ResultObj<>("提供了错误的周期参数!应该是 1/2/3 , 您提供的是" + periodId));
}
TaskPeriod period = TaskPeriod.values()[periodId - 1];
List<CheckAreaStatVo> casList = parseStatString2Vo(child.parse2Bto(), childDetail).stream() // 更新最新的周期
.map(CheckDeviceStatVo::getAreaStatList) ccService.updateTaskPeriod(period);
.flatMap(checkAreaStatVos -> checkAreaStatVos.stream()) // 结束当前任务,开启下轮任务
.collect(toList()); ccService.stopAutoCheckCron();
//自查的areaName要从detail里找 boolean startSuccess = ccService.startAutoCheckCron();
String areaName = childDetail.getCheckUnit();
CheckAreaStatVo cas;
if (casList.isEmpty()) { if (startSuccess) {
cas = new CheckAreaStatVo("默认地区", 0, 0, 0, 0, 0, 0); String nextTime = ccService.getNextTaskDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
return ResponseEntity.ok(new ResultObj<>(String.format("更新自动核查周期成功,下一次任务的执行时间为%s", nextTime)));
} else { } else {
cas = casList.get(0); return ResponseEntity.status(400).body("自动核查更新周期失败了!");
} }
}
LinkExamDetail led = cas2led(cas, child, endTime, updateTime); @ApiOperation(value = "获取下一次自动核查任务执行的具体时间", notes = "获取下一次自动核查任务执行的具体时间")
@GetMapping("/task/next")
public Map<String, LocalDate> getNextTaskTime() {
return ImmutableMap.of("nextTaskTime", ccService.getNextTaskDate());
}
led.setCheckUnit(unitName); @ApiOperation(value = "获取当前自动核查的核查周期", notes = "monthly-月度,quarterly-季度,yearly-年度")
return led; @GetMapping("/task/current")
public Map<String, String> getCurrentTaskPeriod() {
String periodName = ccService.getCurrentTaskPeriod().getCronExpression().name();
return ImmutableMap.of("currentTaskPeriod", periodName);
} }
/** /**
* lcd 里的列表都为检查,因此是集合对 * 发起检查时获取核查的标题
* *
* @param examJobId
* @return * @return
*/ */
private LinkCheckDetail cas2lcd(List<CheckAreaStatVo> casList, Task task, List<Task> detailTasks, String finalCityName) { @GetMapping("/title/{examJobId}")
LinkCheckDetail lcd = new LinkCheckDetail(); public ResponseEntity getNames(@PathVariable Integer examJobId) {
lcd.setId(task.getBillId()); // 根据检查的主键id 查询到prov city Stat的title
String finalSituation = ""; Integer provId = taskService.get(examJobId).getParentTaskId();
// 检查的job id 找到 father 进而找到 father的billid 进而找到title Id
// 核查结果的判断具体细节可以查看 docs/confirmCheck.md文档 Integer statId = taskService.get(provId).getBillId();
List<String> situationList = detailTasks.stream() DeviceCheckStat deviceCheckStat = statRepo.findById(statId).get();
.map(this::getDetailSituation) String title = deviceCheckStat.getTitle();
.collect(toList()); String remark = deviceCheckStat.getRemark();
return ResponseEntity.ok(new CheckTitleAndTimeVo(title, deviceCheckStat.getEndTime(), remark));
}
// 如果 size = 0 或全都是 无 ,则无 @ApiOperation(value = "发起自动核查", notes = "发起自动核查")
if (situationList.size() == 0) { @PostMapping("/auto")
finalSituation = "无"; public ResultObj<Map<String, List<Integer>>> startAutoCheck() {
} else { Map<String, List<Integer>> resultIds = ccService.autoCheck();
boolean allIsNothing = situationList.stream().allMatch(s -> s.equals("无")); return new ResultObj<>(resultIds, "自动核查任务发起成功");
if (allIsNothing) { }
finalSituation = "无";
}
//如果 有任意一个区状态是待审核 @ApiOperation(value = "根据地区ID获取下级的单位", notes = "根据地区ID获取下级的单位")
boolean anyIsAudit = situationList.stream().anyMatch(s -> s.equals("等待市审核")); @GetMapping("/under/{areaId}")
if (anyIsAudit) { public ResponseEntity getUnitsUnderAreaId(@PathVariable Integer areaId, @RequestParam(defaultValue = "true") boolean filter) {
finalSituation = "等待市审核"; //1.获取child AreaId List
} List<Integer> areaIds = areaRepo.findAllByFatherId(areaId).stream()
.map(Area::getId)
.collect(toList());
//如果 全都是 完成,那么是完成 //2. 根据childId 获得对应的unit
boolean allIsFinish = situationList.stream().allMatch(s -> s.equals("完成")); List<Units> unitsList = unitsRepo.findAllByAreaIdIn(areaIds);
if (allIsFinish) {
finalSituation = "完成";
}
// 其他情况,则是进行中 // 根据filter 决定是否将没有数据的装备给过滤掉
if (StringUtils.isEmpty(finalSituation)) { if (filter) {
finalSituation = "进行中"; unitsList = unitsList.stream()
} .filter(unit -> deviceRepo.findAllByOwnUnit(unit.getName()).size() != 0)
.collect(toList());
} }
lcd.setCheckSituation(finalSituation); return ResponseEntity.ok(unitsList);
}
// 核查情况 所有子任务都是初始状态 = 无 10=未 @ApiOperation(value = "检查地区是否可以发起核查", notes = "检查地区是否可以发起核查")
String checkReuslt = ""; @PostMapping("/checkPossible")
// Task 先将历史数据给过滤掉 - 方法是按照billId分组排序,跳出主键id最大的即最新的一条 public ResponseEntity checkPossible(@RequestBody UnitIds unitIds) {
detailTasks = detailTasks.stream() List<String> unitNames = unitIds.getIds().stream()
.collect(groupingBy(Task::getTitle, .map(id -> auService.findOne(AuExample.UnitId, id))
collectingAndThen(maxBy(Comparator.comparing(Task::getId)), Optional::get))) .map(AreaUnit::getUnitName)
.values().stream()
.collect(toList()); .collect(toList());
// 不能存在有9999的任务 boolean findEmpty = false;
boolean notExistsEnd = detailTasks.stream() String alertString = "[";
.allMatch(t -> !t.getBillStatus().equals(END.id));
if (notExistsEnd) {
checkReuslt = "无";
} else {
// 任意一个是10则是待审核
boolean waitAudit = casList.stream()
.anyMatch(cas -> cas.getComSituation() == 10);
boolean notPassed = casList.stream()
.anyMatch(cas -> cas.getComSituation() == 13);
// 需要每一个城市都有无误(即12) 才算无误
Map<String, List<CheckAreaStatVo>> map = casList.stream()
.collect(groupingBy(CheckAreaStatVo::getAreaName));
long okCount = 0;
for (List<CheckAreaStatVo> vos : map.values()) {
boolean containsOk = vos.stream()
.anyMatch(checkAreaStatVo -> checkAreaStatVo.getComSituation() == 12);
if (containsOk) {
okCount++;
}
}
boolean allOk = okCount >= map.size();
if (waitAudit) { for (String unitName : unitNames) {
checkReuslt = CHECK_RESULT_WAIT; List<DeviceLibrary> devices = deviceRepo.findAllByOwnUnit(unitName);
} else if (allOk) { if (devices.size() == 0) {
checkReuslt = CHECK_RESULT_DONE; findEmpty = true;
} else if (notPassed) { alertString += unitName + " ";
checkReuslt = "未通过";
} else {
checkReuslt = "进行中";
} }
} }
lcd.setCheckResult(checkReuslt);
lcd.setCheckUnit(finalCityName + "局");
return lcd; alertString += "]";
alertString += "单位没有装备数据,请重新勾选!";
return ResponseEntity.ok(ImmutableMap.of("empty", findEmpty, "msg", alertString));
} }
@GetMapping("/test/test") @ApiOperation(value = "发起核查", notes = "对指定单位发起核查任务")
private String justForTest() { @PostMapping("/startCheck")
CheckChart.taskStatus2Situation.forEach((k, v) -> System.out.println(v)); public ResponseEntity startCheck(@RequestBody CheckCheckVo ccVO) {
return "test"; // 构建省的统计账单
} Integer startUnitId = ccVO.getUnitId();
Units startUnit = unitsRepo.findById(startUnitId).get();
List<Units> checkedUnits = unitsRepo.findAllById(ccVO.getUnitRange());
// 1.发起自己的自查 (市,tpye=2,省 level = 0,1,2)
// 2.发起自己的检查(只是市级别的 level=2)
List<String> checkedUnitNames = checkedUnits.stream().map(Units::getName).collect(toList());
/** log.info("[核查模块]发起核查,发起单位为{},被查单位为{}", startUnit.getName(), checkedUnitNames);
* 获得自查的核查情况
*/
private String getDetailSituation(Task task) {
Integer taskStatus = task.getBillStatus();
String situation = CheckChart.taskStatus2Situation.get(taskStatus);
// 无的情况要分两种 一种是初始的无 一种是重做导致的无 通过判断task的remark
String remark = task.getRemark();
if (situation.equals("无")) {
if (Objects.nonNull(remark) && remark.contains("ROLLBACK")) {
situation = "未通过";
}
}
return situation;
}
/**
* led 里的列表都为自查,因此都是单个对象
*
* @return
*/
private LinkExamDetail cas2led(CheckAreaStatVo cas, Task task, LocalDateTime endTime, LocalDateTime updateTime) {
LinkExamDetail led = new LinkExamDetail();
led.setId(task.getBillId());
int comProgress = cas.getComProgress();
int comSituation = cas.getComSituation();
// 核查情况依照 新的与task status来对应 详情可以查看docs/confirmcheck.md里的对应表 对照表
String situation = getDetailSituation(task);
// 逾期的处理,只在完成的那一步才判断
if (situation.equals("完成") && updateTime.isAfter(endTime)) {
situation = "逾期完成";
}
led.setCheckSituation(situation);
String checkResult = "";
String remark = task.getRemark();
// 核查结果 - 如果省的自查任务,核查情况是完成了之后,核查结果就是无误
String unitName = detailRepo.findById(task.getBillId()).get().getCheckUnit();
Integer areaType = auService.findOne(AuExample.UnitName, unitName).getType();
if (!situation.contains("完成")) {
checkResult = "无";
} else if (comSituation == 10) {
// 再判断一下 是2级结构(检查统计)还是3级结构(核查统计)
Integer rootId = taskService.findByTaskId(task.getParentTaskId()).getParentTaskId();
boolean isTwoLevel = rootId == null || rootId == 0;
// 2级结构 - 检查统计 发起人单位是省,结果为等待省审核,发起人是市则是无
if (isTwoLevel) {
Integer startUnitId = userService.findById(task.getCreateUserId()).getUnitsId();
if (startUnitId != 1) {
checkResult = "无";
} else {
//根据detail userC为省且任务状态是完结状态时 变为无误 否则是等待省审核
Integer detailId = task.getBillId();
Integer userCId = detailRepo.findById(detailId).get().getUserCId();
if (task.getBillStatus().equals(END.id) && userIsProv(userCId)) {
checkResult = CHECK_RESULT_DONE;
} else {
checkResult = CHECK_RESULT_WAIT;
}
}
} else {
checkResult = CHECK_RESULT_WAIT;
}
} else if (comSituation == 12) {
checkResult = CHECK_RESULT_DONE;
} else if (comSituation == 13) {
int redoTime = 1;
if (Objects.nonNull(remark) && remark.contains("ROLLBACK")) {
redoTime = Integer.valueOf(remark.split("-")[1]);
}
checkResult = redoTime + "次未通过";
} else if (comSituation == 0) {
if (task.getBillStatus().equals(END.id)) {
int redoTime = 1;
if (Objects.nonNull(remark) && remark.contains("ROLLBACK")) {
redoTime = Integer.valueOf(remark.split("-")[1]);
}
checkResult = redoTime + "次未通过";
} else {
checkResult = CHECK_RESULT_WAIT;
}
} else {
checkResult = "状态异常";
}
led.setCheckResult(checkResult);
led.setCheckUnit(cas.getAreaName() + "局");
return led;
}
/**
* 判断用户是否是省级用户
*
* @return
*/
private boolean userIsProv(Integer userId) {
if (Objects.isNull(userId) || userId == 0) {
return false;
}
Integer unitsId = userService.findById(userId).getUnitsId();
Integer level = unitsRepo.findById(unitsId).get().getLevel();
return level == 1;
}
/**
* @param periodId 1-月度 2-季度 3-年度
* @return
*/
@ApiOperation(value = "更新自动核查周期", notes = "更新自动核查周期")
@PutMapping("/task/{periodId}")
public ResponseEntity updateTaskPeriod(
@PathVariable @ApiParam(value = "核查周期,1-月度 2-季度 3-年度", example = "1") Integer periodId) {
if (periodId < 1 || periodId > 3) {
return ResponseEntity.status(400).body(new ResultObj<>("提供了错误的周期参数!应该是 1/2/3 , 您提供的是" + periodId));
}
TaskPeriod period = TaskPeriod.values()[periodId - 1];
// 更新最新的周期
ccService.updateTaskPeriod(period);
// 结束当前任务,开启下轮任务
ccService.stopAutoCheckCron();
boolean startSuccess = ccService.startAutoCheckCron();
if (startSuccess) {
String nextTime = ccService.getNextTaskDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
return ResponseEntity.ok(new ResultObj<>(String.format("更新自动核查周期成功,下一次任务的执行时间为%s", nextTime)));
} else {
return ResponseEntity.status(400).body("自动核查更新周期失败了!");
}
}
@ApiOperation(value = "获取下一次自动核查任务执行的具体时间", notes = "获取下一次自动核查任务执行的具体时间")
@GetMapping("/task/next")
public Map<String, LocalDate> getNextTaskTime() {
return ImmutableMap.of("nextTaskTime", ccService.getNextTaskDate());
}
@ApiOperation(value = "获取当前自动核查的核查周期", notes = "monthly-月度,quarterly-季度,yearly-年度")
@GetMapping("/task/current")
public Map<String, String> getCurrentTaskPeriod() {
String periodName = ccService.getCurrentTaskPeriod().getCronExpression().name();
return ImmutableMap.of("currentTaskPeriod", periodName);
}
/**
* 发起检查时获取核查的标题
*
* @param examJobId
* @return
*/
@GetMapping("/title/{examJobId}")
public ResponseEntity getNames(@PathVariable Integer examJobId) {
// 根据检查的主键id 查询到prov city Stat的title
Integer provId = taskService.get(examJobId).getParentTaskId();
// 检查的job id 找到 father 进而找到 father的billid 进而找到title Id
Integer statId = taskService.get(provId).getBillId();
DeviceCheckStat deviceCheckStat = statRepo.findById(statId).get();
String title = deviceCheckStat.getTitle();
String remark = deviceCheckStat.getRemark();
return ResponseEntity.ok(new CheckTitleAndTimeVo(title, deviceCheckStat.getEndTime(), remark));
}
@ApiOperation(value = "发起自动核查", notes = "发起自动核查")
@PostMapping("/auto")
public ResultObj<Map<String, List<Integer>>> startAutoCheck() {
Map<String, List<Integer>> resultIds = ccService.autoCheck();
return new ResultObj<>(resultIds, "自动核查任务发起成功");
}
@ApiOperation(value = "根据地区ID获取下级的单位", notes = "根据地区ID获取下级的单位")
@GetMapping("/under/{areaId}")
public ResponseEntity getUnitsUnderAreaId(@PathVariable Integer areaId, @RequestParam(defaultValue = "true") boolean filter) {
//1.获取child AreaId List
List<Integer> areaIds = areaRepo.findAllByFatherId(areaId).stream()
.map(Area::getId)
.collect(toList());
//2. 根据childId 获得对应的unit
List<Units> unitsList = unitsRepo.findAllByAreaIdIn(areaIds);
// 根据filter 决定是否将没有数据的装备给过滤掉
if (filter) {
unitsList = unitsList.stream()
.filter(unit -> deviceRepo.findAllByOwnUnit(unit.getName()).size() != 0)
.collect(toList());
}
return ResponseEntity.ok(unitsList);
}
@ApiOperation(value = "检查地区是否可以发起核查", notes = "检查地区是否可以发起核查")
@PostMapping("/checkPossible")
public ResponseEntity checkPossible(@RequestBody UnitIds unitIds) {
List<String> unitNames = unitIds.getIds().stream()
.map(id -> auService.findOne(AuExample.UnitId, id))
.map(AreaUnit::getUnitName)
.collect(toList());
boolean findEmpty = false;
String alertString = "[";
for (String unitName : unitNames) {
List<DeviceLibrary> devices = deviceRepo.findAllByOwnUnit(unitName);
if (devices.size() == 0) {
findEmpty = true;
alertString += unitName + " ";
}
}
alertString += "]";
alertString += "单位没有装备数据,请重新勾选!";
return ResponseEntity.ok(ImmutableMap.of("empty", findEmpty, "msg", alertString));
}
private String getUnitDateString(Units units, String title) {
return "[" + units.getUnitDesc() + "]" + title;
}
@ApiOperation(value = "发起核查", notes = "对指定单位发起核查任务")
@PostMapping("/startCheck")
public ResponseEntity startCheck(@RequestBody CheckCheckVo ccVO) {
// 构建省的统计账单
Integer startUnitId = ccVO.getUnitId();
Units startUnit = unitsRepo.findById(startUnitId).get();
List<Units> checkedUnits = unitsRepo.findAllById(ccVO.getUnitRange());
// 1.发起自己的自查 (市,tpye=2,省 level = 0,1,2)
// 2.发起自己的检查(只是市级别的 level=2)
List<String> checkedUnitNames = checkedUnits.stream().map(Units::getName).collect(toList());
log.info("[核查模块]发起核查,发起单位为{},被查单位为{}", startUnit.getName(), checkedUnitNames);
// 构建省的统计账单,所有的checkedUnits都要被包含到统计中去 // 构建省的统计账单,所有的checkedUnits都要被包含到统计中去
DeviceCheckStat provinceCheckStat = initStatData(ccVO.getTitle(), ccVO.getRemark(), 0, 0, startUnit.getName(), checkedUnits, ccVO.getEndTime().atStartOfDay()); DeviceCheckStat provinceCheckStat = initStatData(ccVO.getTitle(), ccVO.getRemark(), 0, 0, startUnit.getName(), checkedUnits, ccVO.getEndTime().atStartOfDay());
...@@ -1304,14 +1030,6 @@ public class DeviceCheckController { ...@@ -1304,14 +1030,6 @@ public class DeviceCheckController {
return ResponseEntity.ok(desBillMap.get(billId)); return ResponseEntity.ok(desBillMap.get(billId));
} }
private TaskBto selectProvTask(Integer taskId) {
TaskBto taskBto = taskService.get(taskId);
if (taskBto.getParentTaskId() == 0) {
return taskBto;
}
return selectProvTask(taskBto.getParentTaskId());
}
/** /**
* 对于专员A来说的逻辑 * 对于专员A来说的逻辑
* 1. 修改detailString * 1. 修改detailString
...@@ -1542,20 +1260,6 @@ public class DeviceCheckController { ...@@ -1542,20 +1260,6 @@ public class DeviceCheckController {
} }
/**
* 尝试自动完结检查任务(市/省的)
* 1. 当且仅当该检查任务的状态等于@link{CHECK_EXAM_STAT_1}时且其下的所有子任务均为完结状态,自动推进
*
* @param exam的taskId
*/
private void advanceExamTask(Integer examTaskId) {
TaskBto parentTask = taskService.findByTaskId(examTaskId);
if (parentTask.getBillStatus().equals(CHECK_EXAM_STAT_1.id) && taskService.TaskTreeIsOver(examTaskId)) {
log.info("[核查模块] 检测到task id = {}的检查任务已经可以自动推进了,自动推进至下一步", examTaskId);
statConfirm(parentTask.getBillId());
}
}
/** /**
* 省专管员审核自查数据的方法 * 省专管员审核自查数据的方法
* *
...@@ -1581,11 +1285,12 @@ public class DeviceCheckController { ...@@ -1581,11 +1285,12 @@ public class DeviceCheckController {
@ApiOperation(value = "终结stat任务,多指核查任务") @ApiOperation(value = "终结stat任务,多指核查任务")
@PutMapping("/stat/shutdown/{statId}") @PutMapping("/stat/shutdown/{statId}")
public ResponseEntity shutDown(@PathVariable Integer statId) { public ResponseEntity shutDown(@PathVariable Integer statId) {
log.info("[核查模块] 终止任务 - 正在终止statId = {} 的统计任务",statId); log.info("[核查模块] 终止任务 - 正在终止statId = {} 的统计任务", statId);
Task checkTask = taskRepo.findByBillIdAndBusinessType(statId, CONFIRM_CHECK_STAT.id).get(); Task checkTask = taskRepo.findByBillIdAndBusinessType(statId, CONFIRM_CHECK_STAT.id).get();
// 将该stat任务置为20000,即终止 // 将该stat任务置为20000,即终止
unionLink(7, statId); unionLink(7, statId);
taskService.moveToSpecial(checkTask.parse2Bto(), REVOKEALLOTTASK); taskService.moveToSpecial(checkTask.parse2Bto(), REVOKEALLOTTASK);
supplyLogMsg(checkTask);
// 检验所有还没有end的节点 // 检验所有还没有end的节点
// 1级节点分为两类 自查类节点&统计数据确认节点 以及 检查类节点 // 1级节点分为两类 自查类节点&统计数据确认节点 以及 检查类节点
...@@ -1595,6 +1300,7 @@ public class DeviceCheckController { ...@@ -1595,6 +1300,7 @@ public class DeviceCheckController {
// c1里的检查节点也shutDown掉 并保存掉 // c1里的检查节点也shutDown掉 并保存掉
unionLink(7, c1.getBillId());//save unionLink(7, c1.getBillId());//save
taskService.moveToSpecial(c1.parse2Bto(), REVOKEALLOTTASK); taskService.moveToSpecial(c1.parse2Bto(), REVOKEALLOTTASK);
supplyLogMsg(c1);
List<Task> c2Childs = taskRepo.findAllByParentTaskId(c1.getId()); List<Task> c2Childs = taskRepo.findAllByParentTaskId(c1.getId());
c2Childs.forEach(c2 -> shutDownNode(c2)); c2Childs.forEach(c2 -> shutDownNode(c2));
} else { } else {
...@@ -1606,16 +1312,422 @@ public class DeviceCheckController { ...@@ -1606,16 +1312,422 @@ public class DeviceCheckController {
} }
/** /**
* 关闭某个节点,该节点下必须没有子节点树了 * @param taskId 待办任务id
* <p>1.将该任务进度推进至9999</> * @param statId 市级统计的STAT ID
* <p>2.手动补充终结日志</> * @return
* <p>3.将终结信息添加阅知列表里面</>
*
* @param node
*/ */
private void shutDownNode(Task node) { @ApiOperation(value = "跟踪任务待办办结确认")
log.info("[核查模块] 终止任务-正在关闭 task id = {} 的任务节点"); @PostMapping("/stat/done")
// 如果是核查类捡点,抛出异常 public ResponseEntity confirmDone(@RequestParam int taskId, @RequestParam int statId) {
log.info("[核查模块] 正在进行办结任务确认,任务id为 : {}", taskId);
TaskBto cityDoneTask = taskService.get(taskId);
//市的task 且statId保持一致 省待办 需要的是 市的统计taskId
Specification<Task> pred = Specifications.<Task>and()
.eq("billId", statId)
.eq("businessType", CONFIRM_CHECK_STAT.id)
.build();
// 找到child任务 -> 市级任务 如果是2级的则直接找自己
List<Task> tasks = taskRepo.findAll(pred);
Task cityTask = tasks.stream()
.filter(task -> task.getParentTaskId() != 0 && task.getParentTaskId() != null)
.findFirst()
.orElse(tasks.get(0));
// 如果没有父统计TASK 则证明是两级
boolean doubleLevel = cityTask.getParentTaskId() == 0 || cityTask.getParentTaskId() == null;
if (doubleLevel) {
log.info("[核查模块] 办结确认两级检查任务");
} else {
log.info("[核查模块] 办结确认三级检查任务");
//1.累加数据 累加市级数据数据到省级
CheckStatVo cityStat = transUtil.checkStatDo2Vo(statRepo.findById(statId).get());
Integer provStatId = taskService.get(cityTask.getParentTaskId()).getBillId();
CheckStatVo provinceStat = transUtil.checkStatDo2Vo(statRepo.findById(provStatId).get());
String cityName = areaCache.findById(unitsRepo.findAreaId(cityTask.getOwnUnit())).getName();
// 将区级信息合并到市中
List<CheckDeviceStatVo> mergedVo = cityStat.getDeviceStatVoList().stream()
.map(vo -> vo.combine(cityName, cityStat.getId()))
.collect(toList());
// 如果是第一个市,则替换,否则累加
boolean firstCity = taskService.TaskTreeIsStart(cityTask.getParentTaskId(), true);
if (firstCity) {
provinceStat.setDeviceStatVoList(mergedVo);
log.info("[核查模块] 检测到该任务的合并状态为第一个市统计任务,因此直接替换省级统计数据");
} else {
provinceStat.cleanReduce(mergedVo);
log.info("[核查模块] 数据累加成功");
}
DeviceCheckStat dcs = provinceStat.toDo();
statRepo.save(dcs);
}
//2.办结待办
taskService.moveToEnd(cityDoneTask);
//3.如果所有省级的子任务都完成了
boolean over = taskService.TaskTreeIsOver(cityTask.getParentTaskId());
if (over) {
log.info("[核查模块] 所有的省级子任务都完成了,将省统计任务变为待办");
TaskBto provTask = taskService.get(cityTask.getParentTaskId());
provTask.getInvolveUserIdList().add(0);
provTask.setCurrentPoint(provTask.getCurrentPoint() + 1);
taskService.update(provTask);
}
log.info("[核查模块] 办结统计待办操作成功");
return ResponseEntity.ok(new ResultObj<>("办结统计待办确认完毕"));
}
/**
* @param statId 统计账单主键id
*/
@ApiOperation(value = "统计数据确认")
@PostMapping("/stat/verify")
public ResponseEntity<ResultObj> statConfirm(@RequestParam int statId) {
log.info("[核查模块] 正在进行统计数据确认,统计账单id为 : {}", statId);
//将当前的统计task办结
TaskBto currentTask = taskService.get(statId, CONFIRM_CHECK_STAT.id);
currentTask = taskService.moveToEnd(currentTask);
Integer parentTaskId = currentTask.getParentTaskId();
boolean hasParent = parentTaskId != 0;
//尝试寻找老的市办结任务,如果有的话就删除加END
//5.需要将上一次市的确认任务给清理掉 统计确认任务关联的是statId 找到billId -> exam Task ->
// 父级的父级,就是省的任务,然后子child里名字包含 统计数据确认任务 的任务给 END 吧
Map<Integer, List<Task>> doneTaskList = taskRepo.findAllByParentTaskId(parentTaskId)
.stream()
.filter(task -> task.getTitle().contains("统计数据确认任务"))
.collect(groupingBy(Task::getBillId));
List<Task> existsDone = doneTaskList.get(statId);
if (Objects.nonNull(existsDone)) {
for (Task d : existsDone) {
log.info("[核查模块] 发现了id = {}市的重复的统计确认任务,将其完结并剔除整个树节点", d.getId());
d.setParentTaskId(0);
taskService.moveToEnd(d.parse2Bto());
}
}
log.info("[核查模块] 统计数据确认操作成功");
return ResponseEntity.ok(new ResultObj<>("统计数据确认完毕"));
}
/**
* 获得指定单位的在库装备与非在库装备
*
* @param checkUnit 单位名
* @param allDevices 装备列表
* @return true -> 在库装备,false -> 非在库装备
*/
@NotNull
private Map<Boolean, List<DeviceLibrary>> getDevLibMap(String checkUnit, List<DeviceLibrary> allDevices) {
//在库 = A and B & not B 去除掉ls = 10 的装备 把ls = 11 的装备加入到非在库
Map<Boolean, List<DeviceLibrary>> locationMap = allDevices.stream()
.collect(partitioningBy(d -> d.getLocationUnit().equals(checkUnit)));
List<DeviceLibrary> devInLib = locationMap.get(true);
// filter ls == 11 join to 非在库
List<DeviceLibrary> ls11Lib = devInLib.stream().filter(d -> d.getLifeStatus() == 11).collect(toList());
// filter ls == 10
devInLib = devInLib.stream()
.filter(d -> d.getLifeStatus() != 10 && d.getLifeStatus() != 11)
.collect(toList());
// 非在库 = not A and in B
List<DeviceLibrary> devNotInLib = locationMap.get(false)
.stream().filter(d -> d.getOwnUnit().equals(checkUnit))
.collect(toList());
devNotInLib.addAll(ls11Lib);
Map<Boolean, List<DeviceLibrary>> devLib = new HashMap<>();
devLib.put(true, devInLib);
devLib.put(false, devNotInLib);
return devLib;
}
@NotNull
private LinkExamDetail getLed(LocalDateTime endTime, LocalDateTime updateTime, Task child) {
Integer childBusType = child.getBusinessType();
Integer childBusId = child.getBillId();
DeviceCheckDetail childDetail = detailRepo.findById(childBusId).get();
String unitName = childDetail.getCheckUnit();
List<CheckAreaStatVo> casList = parseStatString2Vo(child.parse2Bto(), childDetail).stream()
.map(CheckDeviceStatVo::getAreaStatList)
.flatMap(checkAreaStatVos -> checkAreaStatVos.stream())
.collect(toList());
//自查的areaName要从detail里找
String areaName = childDetail.getCheckUnit();
CheckAreaStatVo cas;
if (casList.isEmpty()) {
cas = new CheckAreaStatVo("默认地区", 0, 0, 0, 0, 0, 0);
} else {
cas = casList.get(0);
}
LinkExamDetail led = cas2led(cas, child, endTime, updateTime);
led.setCheckUnit(unitName);
return led;
}
/**
* lcd 里的列表都为检查,因此是集合对
*
* @return
*/
private LinkCheckDetail cas2lcd(List<CheckAreaStatVo> casList, Task task, List<Task> detailTasks, String finalCityName) {
LinkCheckDetail lcd = new LinkCheckDetail();
lcd.setId(task.getBillId());
String finalSituation = "";
// 核查结果的判断具体细节可以查看 docs/confirmCheck.md文档
List<String> situationList = detailTasks.stream()
.map(this::getDetailSituation)
.collect(toList());
// 如果 size = 0 或全都是 无 ,则无
if (situationList.size() == 0) {
finalSituation = "无";
} else {
boolean allIsNothing = situationList.stream().allMatch(s -> s.equals("无"));
if (allIsNothing) {
finalSituation = "无";
}
//如果 有任意一个区状态是待审核
boolean anyIsAudit = situationList.stream().anyMatch(s -> s.equals("等待市审核"));
if (anyIsAudit) {
finalSituation = "等待市审核";
}
//如果 全都是 完成,那么是完成
boolean allIsFinish = situationList.stream().allMatch(s -> s.equals("完成"));
if (allIsFinish) {
finalSituation = "完成";
}
// 其他情况,则是进行中
if (StringUtils.isEmpty(finalSituation)) {
finalSituation = "进行中";
}
}
lcd.setCheckSituation(finalSituation);
// 核查情况 所有子任务都是初始状态 = 无 10=未
String checkReuslt = "";
// Task 先将历史数据给过滤掉 - 方法是按照billId分组排序,跳出主键id最大的即最新的一条
detailTasks = detailTasks.stream()
.collect(groupingBy(Task::getTitle,
collectingAndThen(maxBy(Comparator.comparing(Task::getId)), Optional::get)))
.values().stream()
.collect(toList());
// 不能存在有9999的任务
boolean notExistsEnd = detailTasks.stream()
.allMatch(t -> !t.getBillStatus().equals(END.id));
if (notExistsEnd) {
checkReuslt = "无";
} else {
// 任意一个是10则是待审核
boolean waitAudit = casList.stream()
.anyMatch(cas -> cas.getComSituation() == 10);
boolean notPassed = casList.stream()
.anyMatch(cas -> cas.getComSituation() == 13);
// 需要每一个城市都有无误(即12) 才算无误
Map<String, List<CheckAreaStatVo>> map = casList.stream()
.collect(groupingBy(CheckAreaStatVo::getAreaName));
long okCount = 0;
for (List<CheckAreaStatVo> vos : map.values()) {
boolean containsOk = vos.stream()
.anyMatch(checkAreaStatVo -> checkAreaStatVo.getComSituation() == 12);
if (containsOk) {
okCount++;
}
}
boolean allOk = okCount >= map.size();
if (waitAudit) {
checkReuslt = CHECK_RESULT_WAIT;
} else if (allOk) {
checkReuslt = CHECK_RESULT_DONE;
} else if (notPassed) {
checkReuslt = "未通过";
} else {
checkReuslt = "进行中";
}
}
lcd.setCheckResult(checkReuslt);
lcd.setCheckUnit(finalCityName + "局");
return lcd;
}
private TaskBto selectProvTask(Integer taskId) {
TaskBto taskBto = taskService.get(taskId);
if (taskBto.getParentTaskId() == 0) {
return taskBto;
}
return selectProvTask(taskBto.getParentTaskId());
}
/**
* 获得自查的核查情况
*/
private String getDetailSituation(Task task) {
Integer taskStatus = task.getBillStatus();
String situation = CheckChart.taskStatus2Situation.get(taskStatus);
// 无的情况要分两种 一种是初始的无 一种是重做导致的无 通过判断task的remark
String remark = task.getRemark();
if (situation.equals("无")) {
if (Objects.nonNull(remark) && remark.contains("ROLLBACK")) {
situation = "未通过";
}
}
return situation;
}
/**
* led 里的列表都为自查,因此都是单个对象
*
* @return
*/
private LinkExamDetail cas2led(CheckAreaStatVo cas, Task task, LocalDateTime endTime, LocalDateTime updateTime) {
LinkExamDetail led = new LinkExamDetail();
led.setId(task.getBillId());
int comProgress = cas.getComProgress();
int comSituation = cas.getComSituation();
// 核查情况依照 新的与task status来对应 详情可以查看docs/confirmcheck.md里的对应表 对照表
String situation = getDetailSituation(task);
// 逾期的处理,只在完成的那一步才判断
if (situation.equals("完成") && updateTime.isAfter(endTime)) {
situation = "逾期完成";
}
led.setCheckSituation(situation);
String checkResult = "";
String remark = task.getRemark();
// 核查结果 - 如果省的自查任务,核查情况是完成了之后,核查结果就是无误
String unitName = detailRepo.findById(task.getBillId()).get().getCheckUnit();
Integer areaType = auService.findOne(AuExample.UnitName, unitName).getType();
if (!situation.contains("完成")) {
checkResult = "无";
} else if (comSituation == 10) {
// 再判断一下 是2级结构(检查统计)还是3级结构(核查统计)
Integer rootId = taskService.findByTaskId(task.getParentTaskId()).getParentTaskId();
boolean isTwoLevel = rootId == null || rootId == 0;
// 2级结构 - 检查统计 发起人单位是省,结果为等待省审核,发起人是市则是无
if (isTwoLevel) {
Integer startUnitId = userService.findById(task.getCreateUserId()).getUnitsId();
if (startUnitId != 1) {
checkResult = "无";
} else {
//根据detail userC为省且任务状态是完结状态时 变为无误 否则是等待省审核
Integer detailId = task.getBillId();
Integer userCId = detailRepo.findById(detailId).get().getUserCId();
if (task.getBillStatus().equals(END.id) && userIsProv(userCId)) {
checkResult = CHECK_RESULT_DONE;
} else {
checkResult = CHECK_RESULT_WAIT;
}
}
} else {
checkResult = CHECK_RESULT_WAIT;
}
} else if (comSituation == 12) {
checkResult = CHECK_RESULT_DONE;
} else if (comSituation == 13) {
int redoTime = 1;
if (Objects.nonNull(remark) && remark.contains("ROLLBACK")) {
redoTime = Integer.valueOf(remark.split("-")[1]);
}
checkResult = redoTime + "次未通过";
} else if (comSituation == 0) {
if (task.getBillStatus().equals(END.id)) {
int redoTime = 1;
if (Objects.nonNull(remark) && remark.contains("ROLLBACK")) {
redoTime = Integer.valueOf(remark.split("-")[1]);
}
checkResult = redoTime + "次未通过";
} else {
checkResult = CHECK_RESULT_WAIT;
}
} else {
checkResult = "状态异常";
}
led.setCheckResult(checkResult);
led.setCheckUnit(cas.getAreaName() + "局");
return led;
}
/**
* 判断用户是否是省级用户
*
* @return
*/
private boolean userIsProv(Integer userId) {
if (Objects.isNull(userId) || userId == 0) {
return false;
}
Integer unitsId = userService.findById(userId).getUnitsId();
Integer level = unitsRepo.findById(unitsId).get().getLevel();
return level == 1;
}
private String getUnitDateString(Units units, String title) {
return "[" + units.getUnitDesc() + "]" + title;
}
/**
* 尝试自动完结检查任务(市/省的)
* 1. 当且仅当该检查任务的状态等于@link{CHECK_EXAM_STAT_1}时且其下的所有子任务均为完结状态,自动推进
*
* @param exam的taskId
*/
private void advanceExamTask(Integer examTaskId) {
TaskBto parentTask = taskService.findByTaskId(examTaskId);
if (parentTask.getBillStatus().equals(CHECK_EXAM_STAT_1.id) && taskService.TaskTreeIsOver(examTaskId)) {
log.info("[核查模块] 检测到task id = {}的检查任务已经可以自动推进了,自动推进至下一步", examTaskId);
statConfirm(parentTask.getBillId());
}
}
/**
* 关闭某个节点,该节点下必须没有子节点树了
* <p>1.将该任务进度推进至9999</>
* <p>2.手动补充终结日志</>
* <p>3.将终结信息添加阅知列表里面</>
*
* @param node
*/
private void shutDownNode(Task node) {
log.info("[核查模块] 终止任务-正在关闭 task id = {} 的任务节点");
// 如果是核查类捡点,抛出异常
if (node.getCustomInfo().equals("check") || node.getCustomInfo().equals("exam")) { if (node.getCustomInfo().equals("check") || node.getCustomInfo().equals("exam")) {
throw new ApiException("关闭节点里不处理核查/核查节点...,你提供的任务节点id = " + node.getId()); throw new ApiException("关闭节点里不处理核查/核查节点...,你提供的任务节点id = " + node.getId());
} }
...@@ -1623,15 +1735,34 @@ public class DeviceCheckController { ...@@ -1623,15 +1735,34 @@ public class DeviceCheckController {
// 1.将该任务进度推进至9999 // 1.将该任务进度推进至9999
TaskBto nodeBto = node.parse2Bto(); TaskBto nodeBto = node.parse2Bto();
taskService.moveToEnd(nodeBto); taskService.moveToEnd(nodeBto);
// 2.手动补充终结日志 supplyLogMsg(node);
log.info("[核查模块] 终止任务-task id = {} 成功关闭");
}
/**
* 补充任务的终结日志与阅知信息
*
* @param node
*/
private void supplyLogMsg(Task node) {
// 手动补充终结日志
String adminUser = authenticationUtils.getAuthentication().getCurrentUserInfo().getName(); String adminUser = authenticationUtils.getAuthentication().getCurrentUserInfo().getName();
String shutDownMsg = String.format("专管员[%s]终止了该任务", adminUser); String shutDownMsg = String.format("专管员[%s]终止了该任务", adminUser);
TaskLogBto taskLog = new TaskLogBto(node.getId(), shutDownMsg); TaskLogBto taskLog = new TaskLogBto(node.getId(), shutDownMsg);
taskLogService.addLog(taskLog); taskLogService.addLog(taskLog);
// 3.添加阅知信息 // 添加阅知信息
MessageBto msgBto = new MessageBto(node.getId(), node.getBusinessType(), shutDownMsg, nodeBto.getInvolveUserIdList()); List<Integer> involveUserIds = node.parse2Bto().getInvolveUserIdList();
int lastUserId = involveUserIds.get(involveUserIds.size() - 1) == null ? 0 : involveUserIds.get(involveUserIds.size() - 1);
List<Integer> msgUserIds;
if (lastUserId == 0) {
msgUserIds = userService.findByUniteId(node.getOwnUnit()).stream()
.map(UserShenRe::getUserId)
.collect(toList());
} else {
msgUserIds = new ArrayList<>(lastUserId);
}
MessageBto msgBto = new MessageBto(node.getId(), node.getBusinessType(), shutDownMsg, msgUserIds);
messageService.add(msgBto); messageService.add(msgBto);
log.info("[核查模块] 终止任务-task id = {} 成功关闭");
} }
/** /**
...@@ -1870,112 +2001,6 @@ public class DeviceCheckController { ...@@ -1870,112 +2001,6 @@ public class DeviceCheckController {
} }
/**
* @param taskId 待办任务id
* @param statId 市级统计的STAT ID
* @return
*/
@ApiOperation(value = "跟踪任务待办办结确认")
@PostMapping("/stat/done")
public ResponseEntity confirmDone(@RequestParam int taskId, @RequestParam int statId) {
log.info("[核查模块] 正在进行办结任务确认,任务id为 : {}", taskId);
TaskBto cityDoneTask = taskService.get(taskId);
//市的task 且statId保持一致 省待办 需要的是 市的统计taskId
Specification<Task> pred = Specifications.<Task>and()
.eq("billId", statId)
.eq("businessType", CONFIRM_CHECK_STAT.id)
.build();
// 找到child任务 -> 市级任务 如果是2级的则直接找自己
List<Task> tasks = taskRepo.findAll(pred);
Task cityTask = tasks.stream()
.filter(task -> task.getParentTaskId() != 0 && task.getParentTaskId() != null)
.findFirst()
.orElse(tasks.get(0));
// 如果没有父统计TASK 则证明是两级
boolean doubleLevel = cityTask.getParentTaskId() == 0 || cityTask.getParentTaskId() == null;
if (doubleLevel) {
log.info("[核查模块] 办结确认两级检查任务");
} else {
log.info("[核查模块] 办结确认三级检查任务");
//1.累加数据 累加市级数据数据到省级
CheckStatVo cityStat = transUtil.checkStatDo2Vo(statRepo.findById(statId).get());
Integer provStatId = taskService.get(cityTask.getParentTaskId()).getBillId();
CheckStatVo provinceStat = transUtil.checkStatDo2Vo(statRepo.findById(provStatId).get());
String cityName = areaCache.findById(unitsRepo.findAreaId(cityTask.getOwnUnit())).getName();
// 将区级信息合并到市中
List<CheckDeviceStatVo> mergedVo = cityStat.getDeviceStatVoList().stream()
.map(vo -> vo.combine(cityName, cityStat.getId()))
.collect(toList());
// 如果是第一个市,则替换,否则累加
boolean firstCity = taskService.TaskTreeIsStart(cityTask.getParentTaskId(), true);
if (firstCity) {
provinceStat.setDeviceStatVoList(mergedVo);
log.info("[核查模块] 检测到该任务的合并状态为第一个市统计任务,因此直接替换省级统计数据");
} else {
provinceStat.cleanReduce(mergedVo);
log.info("[核查模块] 数据累加成功");
}
DeviceCheckStat dcs = provinceStat.toDo();
statRepo.save(dcs);
}
//2.办结待办
taskService.moveToEnd(cityDoneTask);
//3.如果所有省级的子任务都完成了
boolean over = taskService.TaskTreeIsOver(cityTask.getParentTaskId());
if (over) {
log.info("[核查模块] 所有的省级子任务都完成了,将省统计任务变为待办");
TaskBto provTask = taskService.get(cityTask.getParentTaskId());
provTask.getInvolveUserIdList().add(0);
provTask.setCurrentPoint(provTask.getCurrentPoint() + 1);
taskService.update(provTask);
}
log.info("[核查模块] 办结统计待办操作成功");
return ResponseEntity.ok(new ResultObj<>("办结统计待办确认完毕"));
}
/**
* @param statId 统计账单主键id
*/
@ApiOperation(value = "统计数据确认")
@PostMapping("/stat/verify")
public ResponseEntity<ResultObj> statConfirm(@RequestParam int statId) {
log.info("[核查模块] 正在进行统计数据确认,统计账单id为 : {}", statId);
//将当前的统计task办结
TaskBto currentTask = taskService.get(statId, CONFIRM_CHECK_STAT.id);
currentTask = taskService.moveToEnd(currentTask);
Integer parentTaskId = currentTask.getParentTaskId();
boolean hasParent = parentTaskId != 0;
//尝试寻找老的市办结任务,如果有的话就删除加END
//5.需要将上一次市的确认任务给清理掉 统计确认任务关联的是statId 找到billId -> exam Task ->
// 父级的父级,就是省的任务,然后子child里名字包含 统计数据确认任务 的任务给 END 吧
Map<Integer, List<Task>> doneTaskList = taskRepo.findAllByParentTaskId(parentTaskId)
.stream()
.filter(task -> task.getTitle().contains("统计数据确认任务"))
.collect(groupingBy(Task::getBillId));
List<Task> existsDone = doneTaskList.get(statId);
if (Objects.nonNull(existsDone)) {
for (Task d : existsDone) {
log.info("[核查模块] 发现了id = {}市的重复的统计确认任务,将其完结并剔除整个树节点", d.getId());
d.setParentTaskId(0);
taskService.moveToEnd(d.parse2Bto());
}
}
// 停止创建省办结任务
log.info("[核查模块] 统计数据确认操作成功");
return ResponseEntity.ok(new ResultObj<>("统计数据确认完毕"));
}
/** /**
* 任务结束后需要将当前城市的统计信息汇总上 * 任务结束后需要将当前城市的统计信息汇总上
* *
......
...@@ -145,16 +145,6 @@ public class ObjTransUtil { ...@@ -145,16 +145,6 @@ public class ObjTransUtil {
List<Task> childTask = taskDao.findAllByParentTaskId(fatherTaskId); List<Task> childTask = taskDao.findAllByParentTaskId(fatherTaskId);
boolean flag = false; boolean flag = false;
boolean confirmTaskisDone = false;
for (Task task : childTask) {
if (task.getTitle().contains("统计数据确认任务")) {
if (task.getBillStatus() != 9999) {
flag = true;
} else {
confirmTaskisDone = true;
}
}
}
// 3/3 -> 统计待确认 -> 省统计任务待完结 // 3/3 -> 统计待确认 -> 省统计任务待完结
...@@ -166,7 +156,7 @@ public class ObjTransUtil { ...@@ -166,7 +156,7 @@ public class ObjTransUtil {
long total = childTask.size(); long total = childTask.size();
long done = childTask.stream() long done = childTask.stream()
.filter(task -> task.getBillStatus().equals(END.id)||task.getBillStatus().equals(REVOKEALLOTTASK.id)) .filter(task -> task.getBillStatus().equals(END.id) || task.getBillStatus().equals(REVOKEALLOTTASK.id))
.count(); .count();
//如果是检查统计的话那么还要看一下他的父节点是不是已经完成了 //如果是检查统计的话那么还要看一下他的父节点是不是已经完成了
...@@ -179,14 +169,10 @@ public class ObjTransUtil { ...@@ -179,14 +169,10 @@ public class ObjTransUtil {
completion = "核查完成待确认"; completion = "核查完成待确认";
} else { } else {
// confirmTaskidDone 为true 代表此时等待最后的father任务 为false代表 flag = false 且isDone为false 代表整个节点里没有确认节点直接完结 // confirmTaskidDone 为true 代表此时等待最后的father任务 为false代表 flag = false 且isDone为false 代表整个节点里没有确认节点直接完结
if (confirmTaskisDone) { if (fatherTask.getBillStatus().equals(END.id) || fatherTask.getBillStatus().equals(REVOKEALLOTTASK.id)) {
if (fatherTask.getBillStatus() == 9999) {
completion = "核查完成";
} else {
completion = "核查完成待办结";
}
} else {
completion = "核查完成"; completion = "核查完成";
} else {
completion = "核查完成待办结";
} }
} }
} }
......
...@@ -36,7 +36,6 @@ public class CacheLibraryServiceImpl implements DeviceLibraryCacheService { ...@@ -36,7 +36,6 @@ public class CacheLibraryServiceImpl implements DeviceLibraryCacheService {
public List<DeviceLibrary> getAllDeviceLibraryList() { public List<DeviceLibrary> getAllDeviceLibraryList() {
long l = System.currentTimeMillis(); long l = System.currentTimeMillis();
List<DeviceLibrary> all = deviceLibraryDao.findAll(); List<DeviceLibrary> all = deviceLibraryDao.findAll();
System.out.println("缓存时间"+(System.currentTimeMillis()-l));
return all; return all;
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论