package com.estate.expert.admin.service.impl;
|
|
import com.alibaba.excel.util.StringUtils;
|
import com.estate.expert.admin.domain.business.device.Device;
|
import com.estate.expert.admin.domain.business.device.DeviceType;
|
import com.estate.expert.admin.domain.common.mapper.EntityRefMapper;
|
import com.estate.expert.admin.domain.exam.eval.fuzzy.EvalFuzzyResultRepository;
|
import com.estate.expert.admin.domain.exam.eval.score.EvalScoreResultRepository;
|
import com.estate.expert.admin.domain.exam.record.error.ErrorRecord;
|
import com.estate.expert.admin.domain.exam.record.error.ErrorRecordRepository;
|
import com.estate.expert.admin.domain.exam.record.warning.WarningRecordRepository;
|
import com.estate.expert.admin.domain.exam.task.check.CheckTask;
|
import com.estate.expert.admin.domain.exam.task.check.CheckTaskDto;
|
import com.estate.expert.admin.domain.exam.task.check.CheckTaskRepository;
|
import com.estate.expert.admin.domain.exam.task.check.CheckTaskState;
|
import com.estate.expert.admin.domain.exam.task.pass.ByPassInfoDto;
|
import com.estate.expert.admin.domain.exam.task.pass.ByPassInfoMapper;
|
import com.estate.expert.admin.domain.exam.task.review.ReviewTaskDto;
|
import com.estate.expert.admin.domain.exam.task.review.ReviewTaskMapper;
|
import com.estate.expert.admin.domain.plan.Plan;
|
import com.estate.expert.admin.domain.project.Project;
|
import com.estate.expert.admin.domain.standard.hierachy.HierarchyData;
|
import com.estate.expert.admin.domain.standard.model.device.DeviceModel;
|
import com.estate.expert.admin.domain.standard.model.system.SysModel;
|
import com.estate.expert.admin.domain.standard.problem.Problem;
|
import com.estate.expert.admin.domain.user.User;
|
import com.estate.expert.admin.domain.user.UserDto;
|
import com.estate.expert.admin.enums.BizResultCode;
|
import com.estate.expert.admin.service.*;
|
import com.estate.expert.admin.service.common.CrudServiceBaseImpl;
|
import com.estate.expert.admin.service.expert.DeviceExpertService;
|
import com.estate.expert.admin.service.expert.SysExpertService;
|
import com.estate.expert.admin.service.model.DeviceModelService;
|
import com.estate.expert.admin.service.model.SystemModelService;
|
import com.estate.expert.admin.utils.tree.SimpleTreeRoot;
|
import com.estate.expert.admin.utils.tree.TreeNode;
|
import com.estate.expert.admin.utils.tree.TreeRoot;
|
import com.estate.expert.admin.utils.tree.helper.TreeHelper;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.stereotype.Service;
|
|
import javax.annotation.Resource;
|
import javax.lang.model.type.NullType;
|
import java.time.LocalDateTime;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
|
/**
|
* 项目检查任务服务实现
|
* 这里面主要分为几个部分
|
* 1. 检查任务的增删改查
|
* 2. 任务的状态变更
|
* 3. 复查任务的增删改查
|
* 4. 检查记录创建时的相关数据获取(系统模型、设备模型、团队成员)
|
*/
|
@Service
|
public class CheckTaskServiceImpl extends CrudServiceBaseImpl<CheckTask, CheckTaskDto> implements CheckTaskService {
|
|
private static final Logger log = LoggerFactory.getLogger(CheckTaskServiceImpl.class);
|
@Resource
|
private CheckTaskRepository repository;
|
|
@Resource
|
private PlanService planService;
|
|
@Resource
|
private ProjectService projectService;
|
|
@Resource
|
private SysExpertService sysExpertService;
|
|
@Resource
|
private DeviceExpertService deviceExpertService;
|
|
@Resource
|
private DeviceUsageService deviceUsageService;
|
|
@Resource
|
private SystemModelService systemModelService;
|
|
@Resource
|
private DeviceModelService deviceModelService;
|
|
@Resource
|
private ByPassInfoMapper byPassInfoMapper;
|
|
@Resource
|
private UserService userService;
|
|
@Resource
|
private ReviewTaskMapper reviewTaskMapper;
|
|
@Resource
|
private EntityRefMapper entityRefMapper;
|
|
@Resource
|
private ErrorRecordRepository errorRecordRepository;
|
|
@Resource
|
private WarningRecordRepository warningRecordRepository;
|
|
@Resource
|
private ProjectInfoService projectInfoService;
|
|
@Resource
|
private EvalScoreResultRepository evalScoreResultRepository;
|
|
@Resource
|
private EvalFuzzyResultRepository evalFuzzyResultRepository;
|
|
@Override
|
public CheckTaskDto toDto(CheckTask entity) {
|
var dto = super.toDto(entity);
|
dto.setClient(entityRefMapper.toReference(entity.getProject().getClient()));
|
return dto;
|
}
|
|
@Override
|
public List<CheckTaskDto> listAvailableTasks(Integer planId, String keyword) {
|
var plan = planService.get(planId);
|
BizResultCode.PLAN_NOT_FOUND.check(plan == null);
|
|
var checkTasks = repository.findAllByPlanIdAndDeleted(planId, false);
|
|
var newTasks = new ArrayList<CheckTask>();
|
var projects = projectService.listByClient(plan.getClient().getId());
|
for(var project : projects) {
|
var checkTask = createTask(plan, project, checkTasks);
|
if(checkTask != null) {
|
newTasks.add(checkTask);
|
}
|
}
|
checkTasks.addAll(newTasks);
|
|
if(StringUtils.isNotBlank(keyword)) {
|
checkTasks = checkTasks.stream().filter(task -> task.getProject().getName().contains(keyword)).collect(Collectors.toList());
|
}
|
return toDto(checkTasks);
|
}
|
|
@Override
|
public List<CheckTaskDto> myTasks(Integer userId, Integer planId) {
|
var checkTasks = repository.listMyTasks(userId, planId);
|
return toDto(checkTasks);
|
}
|
|
@Override
|
public List<CheckTaskDto> myTodoTasks(Integer userId) {
|
var checkTasks = repository.listMyToDoTasks(userId);
|
return toDto(checkTasks);
|
}
|
|
@Override
|
public List<CheckTask> listExistTasks(Integer planId) {
|
return repository.findAllByPlanIdAndDeleted(planId, false);
|
}
|
|
@Override
|
public CheckTask save(CheckTask entity) {
|
var res = super.save(entity);
|
// 保存任务后更新计划状态
|
planService.updateState(res.getPlan().getId());
|
return res;
|
}
|
|
// 检查计划和项目已经有任务
|
// 如果没有则创建一个任务
|
private CheckTask createTask(Plan plan, Project project, List<CheckTask> checkTasks) {
|
for(var checkTask : checkTasks) {
|
if(checkTask.getPlan().getId().equals(plan.getId()) && checkTask.getProject().getId().equals(project.getId())) {
|
return null;
|
}
|
}
|
|
var checkTask = new CheckTask();
|
checkTask.setId(-Math.abs(UUID.randomUUID().hashCode()));
|
checkTask.setPlan(plan);
|
checkTask.setProject(project);
|
checkTask.setState(CheckTaskState.Init);
|
return checkTask;
|
}
|
|
@Override
|
public List<CheckTask> listClosedTasks(Integer planId) {
|
return repository.listClosedTasks(planId);
|
}
|
|
@Override
|
public List<CheckTask> listClosedTasks(List<Integer> planIds) {
|
return repository.listClosedTasks(planIds);
|
}
|
|
@Override
|
public CheckTask add(User creator, CheckTask entity) {
|
var task = repository.getFirstByPlanIdAndProjectIdAndDeleted(entity.getPlan().getId(), entity.getProject().getId(), false);
|
BizResultCode.TASK_ALREADY_EXIST.check(task != null);
|
BizResultCode.DRIVER_CAR_NOT_MATCH.check(
|
entity.getDrivers() != null && entity.getCars() != null
|
&& entity.getDrivers().size() != entity.getCars().size());
|
entity.setState(CheckTaskState.Published);
|
entity.setName(UUID.randomUUID().toString());
|
return super.add(creator, entity);
|
}
|
|
@Override
|
public CheckTask edit(CheckTask entity) {
|
BizResultCode.TASK_STATUS_ERROR.check(entity.getState() != CheckTaskState.Init
|
&& entity.getState() != CheckTaskState.Rejected
|
&& entity.getState() != CheckTaskState.EXECUTING
|
&& entity.getState() != CheckTaskState.Published);
|
return super.edit(entity);
|
}
|
|
@Override
|
public CheckTask edit(CheckTaskDto dto) {
|
// 如果传了projectId和addressInfo,更新项目地址
|
if (dto.getProjectId() != null && dto.getAddressInfo() != null) {
|
var project = projectService.get(dto.getProjectId());
|
if (project != null) {
|
project.setAddressInfo(dto.getAddressInfo());
|
projectService.edit(project);
|
}
|
}
|
return super.edit(dto);
|
}
|
|
@Override
|
public void close(Integer id) {
|
var checkTask = get(id);
|
BizResultCode.TASK_NOT_FOUND.check(checkTask == null);
|
BizResultCode.TASK_STATUS_ERROR.check(checkTask.getState() != CheckTaskState.EXECUTING
|
&& checkTask.getState() != CheckTaskState.Rejected
|
&& checkTask.getState() != CheckTaskState.Published);
|
checkTask.setState(CheckTaskState.Finished);
|
|
//关闭项目的时候,关联项目最后一条信息到检查任务上,不管是谁添加的,用于出报告
|
checkTask.setProjectInfo(projectInfoService.latest(checkTask.getProject().getId()));
|
save(checkTask);
|
}
|
|
@Override
|
protected void beforeDelete(CheckTask entity) {
|
// 删除任务的时候,删除所有的检查记录
|
var systemErrors = errorRecordRepository.listSystemErrors(entity.getId());
|
|
var deviceErrors = errorRecordRepository.listDeviceErrors(entity.getId());
|
systemErrors.addAll(deviceErrors);
|
|
systemErrors.forEach(errorRecord -> {
|
errorRecord.setDeleted(true);
|
});
|
|
if(!systemErrors.isEmpty())
|
errorRecordRepository.saveAll(systemErrors);
|
|
// 删除任务的时候,删除所有的正确做法
|
var warnings = warningRecordRepository.list(entity.getId());
|
warnings.forEach(warningRecord -> {
|
warningRecord.setDeleted(true);
|
});
|
if(!warnings.isEmpty())
|
warningRecordRepository.saveAll(warnings);
|
|
// 删除任务的时候,删除评分结果
|
var srs = evalScoreResultRepository.listByCheckTask(entity.getId());
|
srs.forEach(evalScoreResult -> {
|
evalScoreResult.setDeleted(true);
|
});
|
if(!srs.isEmpty()) {
|
evalScoreResultRepository.saveAll(srs);
|
}
|
|
// 删除任务的时候,删除模糊评分结果
|
var frs = evalFuzzyResultRepository.listByCheckTask(entity.getId());
|
frs.forEach(evalFuzzyResult -> {
|
evalFuzzyResult.setDeleted(true);
|
});
|
if(!frs.isEmpty())
|
evalFuzzyResultRepository.saveAll(frs);
|
}
|
|
@Override
|
public void deleteAllById(Iterable<Integer> request) {
|
super.deleteAllById(request);
|
}
|
|
@Override
|
public void reject(Integer id) {
|
var checkTask = get(id);
|
BizResultCode.TASK_NOT_FOUND.check(checkTask == null);
|
BizResultCode.TASK_STATUS_ERROR.check(checkTask.getState() != CheckTaskState.Finished);
|
checkTask.setState(CheckTaskState.Rejected);
|
save(checkTask);
|
}
|
|
@Override
|
public ByPassInfoDto getByPassInfo(Integer checkTaskId) {
|
var checkTask = get(checkTaskId);
|
BizResultCode.TASK_NOT_FOUND.check(checkTask == null);
|
return byPassInfoMapper.toDto(checkTask.getByPassInfo());
|
}
|
|
@Override
|
public void setByPassInfo(Integer checkTaskId, ByPassInfoDto byPassInfo) {
|
var checkTask = get(checkTaskId);
|
BizResultCode.TASK_NOT_FOUND.check(checkTask == null);
|
BizResultCode.TASK_STATUS_ERROR.check(checkTask.getState() != CheckTaskState.Published
|
&& checkTask.getState() != CheckTaskState.Rejected
|
&& checkTask.getState() != CheckTaskState.EXECUTING);
|
|
var oldByPassInfo = checkTask.getByPassInfo();
|
if(oldByPassInfo != null) {
|
byPassInfoMapper.partialUpdate(byPassInfo, oldByPassInfo);
|
}else{
|
oldByPassInfo = byPassInfoMapper.toEntity(byPassInfo);
|
checkTask.setByPassInfo(oldByPassInfo);
|
}
|
save(checkTask);
|
}
|
|
@Override
|
public TreeNode<NullType> getSystemTree(Integer checkTaskId) {
|
var modelTree = sysExpertService.getModelTree(getSystemModel(checkTaskId));
|
return buildHierarchyTree(modelTree.root(), null, List.of(2, 3, 4, 6), false,6);
|
}
|
|
// @Override
|
// public TreeNode<NullType> getByPassSystemTree(Integer checkTaskId) {
|
// var modelTree = sysExpertService.getModelTree(getSystemModel(checkTaskId));
|
// return buildHierarchyTree(modelTree.root(), null, List.of(2, 3, 4, 6), true, 6);
|
// }
|
|
@Override
|
public TreeNode<NullType> getByPassSystemTree(Integer checkTaskId) {
|
var modelTree = sysExpertService.getModelTree(getSystemModel(checkTaskId));
|
// 需要过滤掉提过问题的层
|
var records = errorRecordRepository.listSystemErrors(checkTaskId);
|
var newRoot = pruneTreeWithRecords(modelTree.root(), 6, records);
|
return buildHierarchyTree(newRoot, null, List.of(2, 3, 4, 6), true, 6);
|
}
|
|
private TreeNode<HierarchyData> pruneTreeWithRecords(TreeNode<HierarchyData> root, int leafLevel, List<ErrorRecord> records) {
|
// 先过滤掉所有提过问题的叶子节点
|
var newRoot = TreeHelper.pruneTree(root, (node) -> {
|
if(node.getDepth() == leafLevel) {
|
for(var record : records) {
|
if(record.getProblem().getHierarchyPath().equals(node.getPath())) {
|
return false;
|
}
|
}
|
}
|
return true;
|
});
|
var sr = new SimpleTreeRoot<>(newRoot);
|
sr.buildTree();
|
|
// 再过滤掉所有没有子节点的节点
|
newRoot = TreeHelper.pruneTree(newRoot, (node) -> {
|
if(node.getDepth() == leafLevel) {
|
return true;
|
}
|
return !node.getChildren().isEmpty();
|
});
|
|
// 返回树
|
sr = new SimpleTreeRoot<>(newRoot);
|
sr.buildTree();
|
return sr.root();
|
}
|
|
@Override
|
public List<Problem> getSystemProblems(Integer checkTaskId, String hierarchyPath) {
|
var model = getSystemModel(checkTaskId);
|
return systemModelService.listProblems(model, hierarchyPath == null ? "/" : hierarchyPath);
|
}
|
|
@Override
|
public TreeNode<NullType> getDeviceTree(Integer checkTaskId, DeviceType deviceType) {
|
var modelTree = deviceExpertService.getModelTree(getDeviceModel(checkTaskId));
|
return buildHierarchyTree(modelTree.root(), deviceType, List.of(2, 4), false,4);
|
}
|
|
@Override
|
public TreeNode<NullType> getByPassDeviceTree(Integer checkTaskId, DeviceType deviceType) {
|
var modelTree = deviceExpertService.getModelTree(getDeviceModel(checkTaskId));
|
var records = errorRecordRepository.listDeviceErrors(checkTaskId);
|
var newRoot = pruneTreeWithRecords(modelTree.root(), 4, records);
|
return buildHierarchyTree(newRoot, deviceType, List.of(1, 2, 3, 4), false,4);
|
}
|
|
@Override
|
public TreeNode<NullType> getByPassDeviceTree(Integer checkTaskId) {
|
var checkTask = getCheckTask(checkTaskId);
|
var deviceUsages = deviceUsageService.listUsages(checkTask.getProject().getId(), null);
|
if(deviceUsages.isEmpty()) {
|
return null;
|
}
|
|
var modelTree = deviceExpertService.getModelTree(getDeviceModel(checkTaskId));
|
var records = errorRecordRepository.listDeviceErrors(checkTaskId);
|
var treeRoot = new TreeNode<NullType>();
|
deviceUsages.forEach(deviceUsage -> {
|
var device = deviceUsage.getDevice();
|
var dt = buildDeviceHierarchyTree(modelTree, records, device);
|
dt.setId(device.getId());
|
dt.setName(device.getManufacturerNumber());
|
treeRoot.addChild(dt);
|
});
|
return treeRoot;
|
}
|
|
private TreeNode<NullType> buildDeviceHierarchyTree(TreeRoot<HierarchyData> modelTree, List<ErrorRecord> records,
|
Device device){
|
var sr = records.stream().filter( r -> r.getDevice().getId().equals(device.getId())).toList();
|
var newRoot = pruneTreeWithRecords(modelTree.root(), 4, sr);
|
var deviceTree = buildHierarchyTree(newRoot, device.getType(), List.of(2, 3, 4), false,4);
|
TreeHelper.travel(deviceTree, (node) -> {
|
node.setPath(String.format("%d%s", device.getId(), node.getPath()));
|
});
|
return deviceTree;
|
}
|
|
private TreeNode<NullType> buildHierarchyTree(TreeNode<HierarchyData> root,
|
DeviceType deviceType,
|
List<Integer> levels,
|
boolean mergeName,
|
int levelCnt){
|
var newRoot = TreeHelper.<HierarchyData, NullType> convertTree(root, (node, newNode) -> {
|
// 对于综合问题树,由于第五层不显示,所以第六层的名称需要加上父节点的名称
|
if(mergeName && node.getDepth() == 6) {
|
newNode.setName(node.getName() + "[" + node.getParent().getName() + "]");
|
}
|
return null;
|
}, (node) -> {
|
int depth = node.getDepth();
|
// 对于设备问题树,如果指定了设备类型,则只显示该设备类型的问题
|
if(deviceType!=null && depth == 1) {
|
return node.getName().equals(deviceType.getDesc());
|
}
|
// 如果该分支的深度等于指定的深度,则保留
|
if(node.getDepth() == levelCnt)
|
return true;
|
return !node.getChildren().isEmpty();
|
});
|
return TreeHelper.pruneTreeByLevels(newRoot, levels);
|
}
|
|
@Override
|
public List<Problem> getDeviceProblems(Integer checkTaskId, String hierarchyPath) {
|
var model = getDeviceModel(checkTaskId);
|
return deviceModelService.listProblems(model, hierarchyPath);
|
}
|
|
@Override
|
public Map<String, List<UserDto>> getTeamMembers(Integer id) {
|
var checkTask = get(id);
|
BizResultCode.TASK_NOT_FOUND.check(checkTask == null);
|
var result = new LinkedHashMap<String, List<UserDto>>();
|
if(checkTask.getDrivers() != null) {
|
result.put("drivers", userService.toDto(checkTask.getDrivers()));
|
}
|
|
if(checkTask.getGroupLeaders() != null) {
|
result.put("groupLeaders", userService.toDto(checkTask.getGroupLeaders().stream().toList()));
|
}
|
|
if(checkTask.getGroupMembers() != null) {
|
result.put("groupMembers", userService.toDto(checkTask.getGroupMembers().stream().toList()));
|
}
|
return result;
|
}
|
|
private SysModel getSystemModel(Integer checkTaskId) {
|
var checkTask = get(checkTaskId);
|
BizResultCode.TASK_NOT_FOUND.check(checkTask == null);
|
var plan = checkTask.getPlan();
|
BizResultCode.PLAN_NOT_FOUND.check(plan == null);
|
var expert = plan.getSystemFuzzyExpert();
|
BizResultCode.EXPERT_NOT_FOUND.check(expert == null);
|
var model = plan.getSystemModel();
|
BizResultCode.EXPERT_MODEL_NOT_EXIST.check(model == null);
|
return model;
|
}
|
|
private DeviceModel getDeviceModel(Integer checkTaskId) {
|
var checkTask = get(checkTaskId);
|
BizResultCode.TASK_NOT_FOUND.check(checkTask == null);
|
var plan = checkTask.getPlan();
|
BizResultCode.PLAN_NOT_FOUND.check(plan == null);
|
var expert = plan.getDeviceFuzzyExpert();
|
BizResultCode.EXPERT_NOT_FOUND.check(expert == null);
|
var model = plan.getDeviceModel();
|
BizResultCode.EXPERT_MODEL_NOT_EXIST.check(model == null);
|
return model;
|
}
|
|
//////////// 复核任务相关 ////////////
|
|
@Override
|
public ReviewTaskDto getReviewTask(Integer checkTaskId) {
|
var checkTask = get(checkTaskId);
|
BizResultCode.TASK_NOT_FOUND.check(checkTask == null);
|
var reviewTask = checkTask.getReviewTask();
|
if(reviewTask == null)
|
return null;
|
return reviewTaskMapper.toDto(reviewTask);
|
}
|
|
private CheckTask getCheckTask(Integer checkTaskId) {
|
var checkTask = get(checkTaskId);
|
BizResultCode.TASK_NOT_FOUND.check(checkTask == null);
|
return checkTask;
|
}
|
|
@Override
|
public void addReviewTask(User user, Integer checkTaskId, ReviewTaskDto reviewTaskDto) {
|
var checkTask = getCheckTask(checkTaskId);
|
BizResultCode.TASK_STATUS_ERROR.check( checkTask.getState() != CheckTaskState.Finished
|
&& checkTask.getState() != CheckTaskState.Reviewed);
|
var reviewTask = checkTask.getReviewTask();
|
if(reviewTask != null) {
|
reviewTaskMapper.partialUpdate(reviewTaskDto, reviewTask);
|
}else{
|
var newReviewTask = reviewTaskMapper.toEntity(reviewTaskDto);
|
newReviewTask.setName(UUID.randomUUID().toString());
|
checkTask.setReviewTask(newReviewTask);
|
}
|
|
checkTask.getReviewTask().setCreator(user);
|
checkTask.getReviewTask().setCreateTime(LocalDateTime.now());
|
checkTask.getReviewTask().setUpdateTime(LocalDateTime.now());
|
checkTask.setState(CheckTaskState.WaitForReview);
|
save(checkTask);
|
}
|
|
@Override
|
public void editReviewTask(Integer checkTaskId, ReviewTaskDto reviewTaskDto) {
|
var checkTask = getCheckTask(checkTaskId);
|
BizResultCode.TASK_STATUS_ERROR.check( checkTask.getState() != CheckTaskState.WaitForReview
|
&& checkTask.getState() != CheckTaskState.Reviewing);
|
var reviewTask = checkTask.getReviewTask();
|
BizResultCode.REVIEW_TASK_NOT_EXIST.check(reviewTask == null);
|
reviewTaskMapper.partialUpdate(reviewTaskDto, reviewTask);
|
save(checkTask);
|
}
|
|
@Override
|
public void closeReviewTask(Integer checkTaskId) {
|
var checkTask = getCheckTask(checkTaskId);
|
BizResultCode.TASK_STATUS_ERROR.check( checkTask.getState() != CheckTaskState.Reviewing
|
&& checkTask.getState() != CheckTaskState.WaitForReview);
|
var reviewTask = checkTask.getReviewTask();
|
BizResultCode.REVIEW_TASK_NOT_EXIST.check(reviewTask == null);
|
checkTask.setState(CheckTaskState.Reviewed);
|
save(checkTask);
|
}
|
|
@Override
|
public void deleteReviewTask(Integer checkTaskId) {
|
var checkTask = getCheckTask(checkTaskId);
|
var reviewTask = checkTask.getReviewTask();
|
BizResultCode.REVIEW_TASK_NOT_EXIST.check(reviewTask == null);
|
checkTask.setReviewTask(null);
|
checkTask.setState(CheckTaskState.Finished);
|
save(checkTask);
|
}
|
|
}
|