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.<QualityMonitorDetailsEvaluate>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<QualityMonitorEvaluateResult> rows = evaluation.getDetailsEvaluateId() == null
|
? List.of() : resultMapper.selectList(Wrappers.<QualityMonitorEvaluateResult>lambdaQuery()
|
.eq(QualityMonitorEvaluateResult::getDetailsEvaluateId, evaluation.getDetailsEvaluateId())
|
.orderByAsc(QualityMonitorEvaluateResult::getSortNo, QualityMonitorEvaluateResult::getId));
|
if (task != null && Integer.valueOf(5).equals(task.getInsState())) {
|
List<Map<String, String>> 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.<InsOrderState>lambdaQuery()
|
.eq(InsOrderState::getInsOrderId, task.getId()).ne(InsOrderState::getInsState, 5));
|
if (pendingCount > 0) throw new ErrorException("原始记录复核通过后才能评价");
|
List<Map<String, String>> 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.<QualityMonitorDetailsEvaluate>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.<QualityMonitorEvaluateResult>lambdaQuery()
|
.eq(QualityMonitorEvaluateResult::getDetailsEvaluateId, saved.getDetailsEvaluateId()));
|
int index = 0;
|
for (QualityMonitorEvaluateResult row : input.getResultRows()) {
|
Map<String, String> 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.<QualityMonitorDetailsEvaluate>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<String> names = new ArrayList<>();
|
List<String> specs = new ArrayList<>();
|
List<String> codes = new ArrayList<>();
|
for (Map<String, String> 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<String, String> device, String snakeCase, String camelCase) {
|
String value = device.get(snakeCase);
|
if (!StringUtils.hasText(value)) value = device.get(camelCase);
|
return StringUtils.hasText(value) ? value : "-";
|
}
|
}
|