package com.ruoyi.process.service; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.framework.exception.ErrorException; import com.ruoyi.inspect.mapper.InsOrderStateMapper; import com.ruoyi.inspect.pojo.InsOrder; import com.ruoyi.inspect.pojo.InsOrderState; import com.ruoyi.inspect.service.InsOrderPlanService; import com.ruoyi.inspect.vo.QualityMonitorRawContext; import com.ruoyi.process.mapper.QualityMonitorDetailsEvaluateMapper; import com.ruoyi.process.mapper.QualityMonitorDetailsMapper; import com.ruoyi.process.mapper.QualityMonitorEvaluateResultMapper; import com.ruoyi.process.mapper.QualityMonitorMapper; import com.ruoyi.process.pojo.QualityMonitor; import com.ruoyi.process.pojo.QualityMonitorDetails; import com.ruoyi.process.pojo.QualityMonitorDetailsEvaluate; import com.ruoyi.process.pojo.QualityMonitorEvaluateResult; import com.ruoyi.system.mapper.UserMapper; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; @Service public class QualityMonitorInspectionEvaluationService { @Resource private QualityMonitorTaskService taskService; @Resource private QualityMonitorDetailsMapper detailsMapper; @Resource private QualityMonitorMapper monitorMapper; @Resource private QualityMonitorDetailsEvaluateMapper evaluateMapper; @Resource private QualityMonitorEvaluateResultMapper resultMapper; @Resource private InsOrderStateMapper stateMapper; @Resource private UserMapper userMapper; @Resource private InsOrderPlanService insOrderPlanService; public QualityMonitorDetailsEvaluate get(Integer detailId) { QualityMonitorDetails detail = requireDetail(detailId); QualityMonitorDetailsEvaluate evaluation = evaluateMapper.selectOne(Wrappers.lambdaQuery() .eq(QualityMonitorDetailsEvaluate::getQualityMonitorDetailsId, detailId).last("limit 1")); InsOrder task = taskService.getTask(detailId); if (evaluation == null) { evaluation = new QualityMonitorDetailsEvaluate(); evaluation.setQualityMonitorDetailsId(detailId); evaluation.setInspectorUserId(detail.getInspectorUserId()); evaluation.setSampleName(detail.getSampleName()); evaluation.setSampleSpec(detail.getSampleSpec()); } List rows = evaluation.getDetailsEvaluateId() == null ? List.of() : resultMapper.selectList(Wrappers.lambdaQuery() .eq(QualityMonitorEvaluateResult::getDetailsEvaluateId, evaluation.getDetailsEvaluateId()) .orderByAsc(QualityMonitorEvaluateResult::getSortNo, QualityMonitorEvaluateResult::getId)); if (task != null && Integer.valueOf(5).equals(task.getInsState())) { List> rawRows = insOrderPlanService.getQualityMonitorRawResults(task.getId()); fillRawContext(evaluation, insOrderPlanService.getQualityMonitorRawContext(task.getId())); if (!rows.isEmpty() && rows.size() != rawRows.size()) throw new ErrorException("原始记录检测数据已变化,请重新核对评价记录"); if (rows.isEmpty()) { rows = new java.util.ArrayList<>(); for (int i = 0; i < rawRows.size(); i++) { QualityMonitorEvaluateResult row = new QualityMonitorEvaluateResult(); row.setInspectorUserId(detail.getInspectorUserId()); row.setMeasuredValue(rawRows.get(i).get("result")); row.setUnit(rawRows.get(i).get("unit")); row.setSortNo(i); rows.add(row); } } for (int i = 0; i < rows.size(); i++) rows.get(i).setItemName(rawRows.get(i).get("itemName")); } evaluation.setResultRows(rows); evaluation.setInspectionTaskState(task == null ? null : task.getInsState()); if (Integer.valueOf(1).equals(evaluation.getIsFinish())) { evaluation.setEvaluationEditReason("评价已批准归档,只能查看"); } else if (task == null) { evaluation.setEvaluationEditReason("质控检验任务尚未下发,暂不能填写评价"); } else if (!Integer.valueOf(5).equals(task.getInsState())) { evaluation.setEvaluationEditReason("原始记录复核通过后,指定评价人才可以填写"); } else if (detail.getEvaluatorUserId() == null) { evaluation.setEvaluationEditReason("计划项目尚未指定评价人"); } else if (!Integer.valueOf(SecurityUtils.getUserId().intValue()).equals(detail.getEvaluatorUserId())) { var evaluator = userMapper.selectById(detail.getEvaluatorUserId()); evaluation.setEvaluationEditReason("当前账号不是指定评价人(" + (evaluator == null ? "用户ID " + detail.getEvaluatorUserId() : evaluator.getName()) + "),只能查看"); } else { evaluation.setEvaluationEditable(true); } return evaluation; } @Transactional(rollbackFor = Exception.class) public QualityMonitorDetailsEvaluate submit(QualityMonitorDetailsEvaluate input) { if (input == null) throw new ErrorException("评价内容不能为空"); QualityMonitorDetails detail = requireDetail(input.getQualityMonitorDetailsId()); InsOrder task = taskService.getTask(detail.getQualityMonitorDetailsId()); if (task == null || !QualityMonitorTaskService.SOURCE.equals(task.getTaskSource())) throw new ErrorException("质量监控检验任务不存在"); if (!Integer.valueOf(5).equals(task.getInsState())) throw new ErrorException("原始记录复核通过后才能评价"); if (!Integer.valueOf(SecurityUtils.getUserId().intValue()).equals(detail.getEvaluatorUserId())) throw new ErrorException("只有指定评价人可以填写评价"); if (input.getSupervisorUserId() == null || input.getSupervisorUserId().equals(detail.getInspectorUserId()) || input.getSupervisorUserId().equals(detail.getEvaluatorUserId()) || userMapper.selectById(input.getSupervisorUserId()) == null) throw new ErrorException("请选择与检测员、评价人不同的监督员"); Long pendingCount = stateMapper.selectCount(Wrappers.lambdaQuery() .eq(InsOrderState::getInsOrderId, task.getId()).ne(InsOrderState::getInsState, 5)); if (pendingCount > 0) throw new ErrorException("原始记录复核通过后才能评价"); List> rawRows = insOrderPlanService.getQualityMonitorRawResults(task.getId()); QualityMonitorRawContext rawContext = insOrderPlanService.getQualityMonitorRawContext(task.getId()); if (rawContext.getDetectionDates().isEmpty() || rawContext.getDevices().isEmpty()) throw new ErrorException("原始记录缺少检测时间或所用设备,请先补齐并复核"); if (!StringUtils.hasText(input.getEvaluationConclusion()) || input.getResultRows() == null || input.getResultRows().size() != rawRows.size()) throw new ErrorException("请填写评价内容并核对全部原始记录检测数据"); if (!Boolean.TRUE.equals(input.getMeasurementConfirmed())) throw new ErrorException("请先核对已复核原始记录的检测数据"); QualityMonitorDetailsEvaluate existing = evaluateMapper.selectOne(Wrappers.lambdaQuery() .eq(QualityMonitorDetailsEvaluate::getQualityMonitorDetailsId, detail.getQualityMonitorDetailsId()) .last("FOR UPDATE")); if (existing != null && Integer.valueOf(1).equals(existing.getIsFinish())) throw new ErrorException("已批准的评价不可修改"); QualityMonitor plan = monitorMapper.selectById(detail.getQualityMonitorId()); QualityMonitorDetailsEvaluate saved = existing == null ? new QualityMonitorDetailsEvaluate() : existing; saved.setQualityMonitorDetailsId(detail.getQualityMonitorDetailsId()); saved.setInsOrderId(task.getId()); saved.setInspectorUserId(detail.getInspectorUserId()); saved.setImplementUserId(detail.getEvaluatorUserId()); saved.setRatifyUserId(plan.getRatifyUserId()); saved.setSupervisorUserId(input.getSupervisorUserId()); saved.setSampleName(detail.getSampleName()); saved.setSampleSpec(detail.getSampleSpec()); // 时间和设备始终由已复核原始记录读取,评价请求中的同名字段不参与保存。 saved.setImplementCondition(input.getEvaluationConclusion()); saved.setImplementResult(input.getImplementResult()); saved.setEvaluationConclusion(input.getEvaluationConclusion()); saved.setCorrectiveAction(input.getCorrectiveAction()); saved.setVerificationResult(input.getVerificationResult()); saved.setCorrectiveResponsibleUserId(input.getCorrectiveResponsibleUserId()); saved.setCorrectiveDueDate(input.getCorrectiveDueDate()); saved.setVerificationResponsibleUserId(input.getVerificationResponsibleUserId()); saved.setVerificationDate(input.getVerificationDate()); saved.setReviewPurpose(detail.getMonitorPurpose()); saved.setReviewUser(userMapper.selectById(detail.getEvaluatorUserId()).getName()); saved.setReviewTime(LocalDateTime.now().toLocalDate().toString()); if (!StringUtils.hasText(saved.getImplementResult())) { saved.setImplementResult(input.getEvaluationConclusion()); } saved.setIsFinish(0); if (existing == null) evaluateMapper.insert(saved); else evaluateMapper.updateById(saved); resultMapper.delete(Wrappers.lambdaQuery() .eq(QualityMonitorEvaluateResult::getDetailsEvaluateId, saved.getDetailsEvaluateId())); int index = 0; for (QualityMonitorEvaluateResult row : input.getResultRows()) { Map rawRow = rawRows.get(index); if (!Objects.equals(row.getMeasuredValue(), rawRow.get("result"))) throw new ErrorException("检测数据与已复核原始记录不一致,请刷新后重新核对"); if (!StringUtils.hasText(row.getReferenceValue())) throw new ErrorException("请填写盲样值"); row.setId(null); row.setDetailsEvaluateId(saved.getDetailsEvaluateId()); row.setInspectorUserId(detail.getInspectorUserId()); row.setMeasuredValue(rawRow.get("result")); row.setUnit(rawRow.get("unit")); row.setSortNo(index++); resultMapper.insert(row); } return get(detail.getQualityMonitorDetailsId()); } @Transactional(rollbackFor = Exception.class) public void approve(Integer detailId, boolean approved, String opinion) { QualityMonitorDetails detail = requireDetail(detailId); QualityMonitor plan = monitorMapper.selectById(detail.getQualityMonitorId()); int current = SecurityUtils.getUserId().intValue(); if (plan == null || !Integer.valueOf(current).equals(plan.getRatifyUserId()) || Integer.valueOf(current).equals(detail.getInspectorUserId())) throw new ErrorException("只有指定批准人可以审批评价"); QualityMonitorDetailsEvaluate evaluation = evaluateMapper.selectOne(Wrappers.lambdaQuery() .eq(QualityMonitorDetailsEvaluate::getQualityMonitorDetailsId, detailId).last("FOR UPDATE")); if (evaluation == null || Integer.valueOf(1).equals(evaluation.getIsFinish())) throw new ErrorException("评价不存在或已批准"); if (approved && StringUtils.hasText(evaluation.getCorrectiveAction()) && (!StringUtils.hasText(evaluation.getVerificationResult()) || evaluation.getCorrectiveResponsibleUserId() == null || evaluation.getCorrectiveDueDate() == null || evaluation.getVerificationResponsibleUserId() == null || evaluation.getVerificationDate() == null)) throw new ErrorException("请补齐纠正措施责任人、完成日期和验证信息后再批准"); evaluation.setRatifyOpinion(opinion); evaluation.setRatifyTime(LocalDateTime.now()); evaluation.setIsFinish(approved ? 1 : 0); evaluateMapper.updateById(evaluation); } private QualityMonitorDetails requireDetail(Integer detailId) { QualityMonitorDetails detail = detailId == null ? null : detailsMapper.selectById(detailId); if (detail == null || !"INSPECTION".equals(detail.getItemKind())) throw new ErrorException("质量监控检测明细不存在"); return detail; } private void fillRawContext(QualityMonitorDetailsEvaluate evaluation, QualityMonitorRawContext context) { evaluation.setRawInspectionDates(context.getDetectionDates().stream() .map(date -> date.format(DateTimeFormatter.ISO_LOCAL_DATE)).collect(Collectors.toList())); List names = new ArrayList<>(); List specs = new ArrayList<>(); List codes = new ArrayList<>(); for (Map device : context.getDevices()) { names.add(deviceText(device, "device_name", "deviceName")); specs.add(deviceText(device, "specification_model", "specificationModel")); String managementNumber = deviceText(device, "management_number", "managementNumber"); codes.add("-".equals(managementNumber) ? deviceText(device, "factory_no", "factoryNo") : managementNumber); } evaluation.setRawEquipmentDescription(String.join("\n", names)); evaluation.setRawEquipmentSpec(String.join("\n", specs)); evaluation.setRawEquipmentCode(String.join("\n", codes)); } private String deviceText(Map device, String snakeCase, String camelCase) { String value = device.get(snakeCase); if (!StringUtils.hasText(value)) value = device.get(camelCase); return StringUtils.hasText(value) ? value : "-"; } }