package com.estate.expert.admin.service.impl; import com.estate.expert.admin.domain.common.EntityRef; import com.estate.expert.admin.domain.common.request.PageReq; import com.estate.expert.admin.domain.common.response.PageResp; import com.estate.expert.admin.domain.exam.record.error.ErrorLevel; import com.estate.expert.admin.domain.exam.record.error.ErrorRecord; import com.estate.expert.admin.domain.exam.record.error.ErrorRecordDto; import com.estate.expert.admin.domain.exam.record.error.ErrorRecordRepository; import com.estate.expert.admin.domain.exam.record.review.ErrorReviewDto; import com.estate.expert.admin.domain.exam.record.review.ErrorReviewMapper; import com.estate.expert.admin.domain.exam.record.review.ErrorReviewState; import com.estate.expert.admin.domain.exam.task.check.CheckTaskState; import com.estate.expert.admin.domain.user.User; import com.estate.expert.admin.enums.BizResultCode; import com.estate.expert.admin.service.CheckTaskService; import com.estate.expert.admin.service.ErrorRecordService; import com.estate.expert.admin.service.ProblemService; import com.estate.expert.admin.service.common.CrudServiceBaseImpl; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.UUID; /** * 问题记录服务实现 */ @Service public class ErrorRecordServiceImpl extends CrudServiceBaseImpl implements ErrorRecordService { @Resource private ErrorRecordRepository errorRecordRepository; @Resource private CheckTaskService checkTaskService; @Resource private ProblemService problemService; @Resource private ErrorReviewMapper errorReviewMapper; private List buildDtos(Integer checkTaskId, List content) { var task = checkTaskService.get(checkTaskId); var dtos = toDto(content); if(task != null ){ dtos.forEach(c -> c.setCheckTaskState(task.getState())); } return dtos; } @Override public PageResp listSystemErrors(Integer checkTaskId, Integer creatorId, PageReq pageReq) { var page = errorRecordRepository.listSystemErrors(checkTaskId, creatorId, pageReq.toPageRequest()); var content = filterRecords(checkTaskId, page.getContent()); var dtos = buildDtos(checkTaskId, content); return PageResp.of(dtos); } private List filterRecords(Integer checkTaskId, List records){ if(records.isEmpty()) return records; var task = checkTaskService.get(checkTaskId); if(task == null) return records; if(task.getState() == CheckTaskState.Reviewing || task.getState() == CheckTaskState.WaitForReview){ var reviewTask = task.getReviewTask(); if(reviewTask!=null){ // records = records.stream().filter(c -> !c.isReformed() && // (reviewTask.getReviewProblems() == null || reviewTask.getReviewProblems().isEmpty() || reviewTask.getReviewProblems().contains(c.getLevel()))).toList(); records = records.stream().filter(c -> (reviewTask.getReviewProblems() == null || reviewTask.getReviewProblems().isEmpty() || reviewTask.getReviewProblems().contains(c.getLevel()))).toList(); } } // 排序,将已经复查的问题排在最后 // Create a modifiable copy of the list List modifiableRecords = new ArrayList<>(records); // 排序,将已经复查的问题排在最后 modifiableRecords.sort((a, b) -> { if(a.isReformed() && !b.isReformed()) return 1; if(!a.isReformed() && b.isReformed()) return -1; return 0; }); return modifiableRecords; } @Override public PageResp listDeviceErrors(Integer checkTaskId, Integer deviceId, Integer creatorId, PageReq pageReq) { var page = errorRecordRepository.listDeviceErrors(checkTaskId, deviceId, creatorId, pageReq.toPageRequest()); var content = filterRecords(checkTaskId, page.getContent()); var dtos = buildDtos(checkTaskId, content); return PageResp.of(dtos); } @Override public List listSystemErrors(Integer clientId, Integer planId, Integer taskId, LocalDate startDate, LocalDate endDate) { return errorRecordRepository.listSystemErrors(clientId, planId, taskId, startDate!= null ? startDate.atTime(0,0,0) : null, endDate != null ? endDate.atTime(23, 59, 59) : null); } @Override public PageResp listSystemErrors(Integer clientId, Integer planId, Integer taskId, LocalDate startDate, LocalDate endDate, PageReq pageReq) { var page = errorRecordRepository.listSystemErrors(clientId, planId, taskId, startDate!= null ? startDate.atTime(0,0,0) : null, endDate != null ? endDate.atTime(23, 59, 59) : null, pageReq.toPageRequest()); return PageResp.of(page, toDto(page.getContent())); } @Override public List listDeviceErrors(Integer clientId, Integer planId, Integer taskId, LocalDate startDate, LocalDate endDate) { return errorRecordRepository.listDeviceErrors(clientId, planId, taskId, startDate!= null ? startDate.atTime(0,0,0) : null, endDate != null ? endDate.atTime(23, 59, 59) : null); } @Override public PageResp listDeviceErrors(Integer clientId, Integer planId, Integer projectId, LocalDate startDate, LocalDate endDate, PageReq pageReq) { var page = errorRecordRepository.listDeviceErrors(clientId, planId, projectId, startDate!= null ? startDate.atTime(0,0,0) : null, endDate != null ? endDate.atTime(23, 59, 59) : null, pageReq.toPageRequest()); return PageResp.of(page, toDto(page.getContent())); } @Override public List listSystemErrors(Integer checkTaskId) { return errorRecordRepository.listSystemErrors(checkTaskId); } @Override public List listDeviceErrors(Integer checkTaskId) { return errorRecordRepository.listDeviceErrors(checkTaskId); } @Transactional @Override public ErrorRecord add(User creator, ErrorRecord entity) { var checkTask = checkTaskService.get(entity.getCheckTask().getId()); BizResultCode.TASK_NOT_FOUND.check(checkTask == null); BizResultCode.TASK_STATUS_ERROR.check( checkTask.getState() != CheckTaskState.Published && checkTask.getState() != CheckTaskState.EXECUTING && checkTask.getState() != CheckTaskState.Rejected); if(checkTask.getState() != CheckTaskState.EXECUTING){ checkTask.setState(CheckTaskState.EXECUTING); checkTaskService.save(checkTask); } var hierarchyNames = problemService.getHierarchyNames(entity.getProblem()); entity.setHierarchyNames(hierarchyNames); if(!hierarchyNames.isEmpty()) entity.setHierarchyName(hierarchyNames.get(0)); entity.setName(UUID.randomUUID().toString()); entity.setLevel(computeErrorLevel(entity)); return super.add(creator, entity); } @Override public ErrorRecord edit(ErrorRecord entity) { var checkTask = checkTaskService.get(entity.getCheckTask().getId()); BizResultCode.TASK_NOT_FOUND.check(checkTask == null); BizResultCode.TASK_STATUS_ERROR.check( checkTask.getState() != CheckTaskState.Published && checkTask.getState() != CheckTaskState.EXECUTING && checkTask.getState() != CheckTaskState.Rejected); entity.setLevel(computeErrorLevel(entity)); return super.edit(entity); } /** * d:系统问题的数值 * c:对应规模系数的数值 * rn:问题数量集合的数值 */ public ErrorLevel computeErrorLevel(ErrorRecord record) { var problem = problemService.get(record.getProblem().getId()); BizResultCode.PROBLEM_NOT_EXIST.check(problem == null); var d = problem.getNumValue(); var numberFactors = problem.getNumberFactors(); BizResultCode.NUMBER_FACTOR_NOT_EXIST.check(numberFactors == null || numberFactors.isEmpty()); BizResultCode.NUMBER_FACTOR_INDEX_ERROR.check(record.getNumberFactorIndex()<0 || record.getNumberFactorIndex()>=numberFactors.size()); var c = numberFactors.get(record.getNumberFactorIndex()).getValue(); var scaleFactors = problem.getScaleFactors(); BizResultCode.SCALE_FACTOR_NOT_EXIST.check(scaleFactors == null || scaleFactors.isEmpty()); BizResultCode.SCALE_FACTOR_INDEX_ERROR.check(record.getScaleFactorIndex()<0 || record.getScaleFactorIndex()>=scaleFactors.size()); var rn = scaleFactors.get(record.getScaleFactorIndex()).getFactor(); BizResultCode.PARAM_ERROR.check (d < 0 || c < 0 || rn < 0); double l = d * c * rn; if (l > 24) { return ErrorLevel.P1; } else if (l > 12) { return ErrorLevel.P2; } else if (l > 4) { return ErrorLevel.P3; } else { return ErrorLevel.P4; } } @Override public ErrorLevel computeErrorLevel(ErrorRecordDto dto) { return computeErrorLevel(toEntity(dto)); } @Override public void addReview(User user, Integer errorRecordId, ErrorReviewDto reviewDto) { var record = getErrorRecord(errorRecordId); // 问题记录已经有复查记录 BizResultCode.RECORD_REVIEW_EXISTED.check(record.getErrorReview()!=null); var task = record.getCheckTask(); BizResultCode.TASK_NOT_FOUND.check(task == null); BizResultCode.TASK_STATUS_ERROR.check(task.getState() != CheckTaskState.Reviewing && task.getState() != CheckTaskState.WaitForReview); // 保存复查记录 var errorReview = errorReviewMapper.toEntity(reviewDto); errorReview.setCreateTime(LocalDateTime.now()); errorReview.setUpdateTime(LocalDateTime.now()); errorReview.setCreator(user); errorReview.setName(record.getName() + "_REVIEW"); // 更新问题记录 record.setErrorReview(errorReview); record.setReformed(reviewDto.getState() == ErrorReviewState.REFORMED); errorRecordRepository.save(record); // 更新任务状态 if(task.getState() != CheckTaskState.Reviewing) { task.setState(CheckTaskState.Reviewing); checkTaskService.save(task); } } @Override public void editReview(Integer errorRecordId, ErrorReviewDto reviewDto) { var record = getErrorRecord(errorRecordId); BizResultCode.REVIEW_ALREADY_REFORMED.check(record.isReformed()); var task = record.getCheckTask(); BizResultCode.TASK_NOT_FOUND.check(task == null); BizResultCode.TASK_STATUS_ERROR.check(task.getState() != CheckTaskState.Reviewing && task.getState() != CheckTaskState.WaitForReview); record.setReformed(reviewDto.getState() == ErrorReviewState.REFORMED); errorRecordRepository.save(record); // 更新复查记录 var review = record.getErrorReview(); errorReviewMapper.partialUpdate(reviewDto, review); review.setUpdateTime(LocalDateTime.now()); errorRecordRepository.save(record); } @Override public ErrorReviewDto getReview(Integer errorRecordId) { return errorReviewMapper.toDto(getErrorRecord(errorRecordId).getErrorReview()); } private ErrorRecord getErrorRecord(Integer errorRecordId) { var record = get(errorRecordId); BizResultCode.RECORD_NOT_FOUND.check(record == null); return record; } /// 测试接口 @Override public void addErrorRecords(User user, Integer checkTaskId) { var problems = checkTaskService.getSystemProblems(checkTaskId, null); // random select a problem if(problems.isEmpty()) return; var problem = problems.get((int)(Math.random() * problems.size())); var problemId = problem.getId(); var record = ErrorRecordDto.builder() .checkTask(EntityRef.builder().id(checkTaskId).build()) .problem(EntityRef.builder().id(problemId).build()) .numberFactorIndex(0) .scaleFactorIndex(0) .level(ErrorLevel.values()[problemId % ErrorLevel.values().length]) .problemPart("问题部位_" + problemId) .suggestion("建议_" + problemId) .remark("备注_" + problemId) .images(List.of(EntityRef.of(1), EntityRef.of(4), EntityRef.of(5))) .build(); add(user, record); } @Override public void addErrorReviews(User user, Integer checkTaskId) { var systemErrors = listSystemErrors(checkTaskId); int hasAdded = 0; for(var error : systemErrors){ if(error.isReformed()) continue; var review = ErrorReviewDto.builder() .state(ErrorReviewState.REFORMED) .content("复查内容_" + error.getId()) .images(List.of(EntityRef.of(1))) .build(); addReview(user, error.getId(), review); hasAdded++; break; } BizResultCode.ERROR_RECORD_ALL_REVIEWD.check(hasAdded == 0); } }