|
|
@ -1,278 +0,0 @@
|
|
|
|
package org.dromara.qms.service.impl;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
|
|
|
import org.dromara.common.core.utils.StringUtils;
|
|
|
|
|
|
|
|
import org.dromara.common.satoken.utils.LoginHelper;
|
|
|
|
|
|
|
|
import org.dromara.qms.domain.bo.QcUnqualifiedReviewBo;
|
|
|
|
|
|
|
|
import org.dromara.qms.domain.vo.QcInspectionMainVo;
|
|
|
|
|
|
|
|
import org.dromara.qms.domain.vo.QcInspectionItemDetailVo;
|
|
|
|
|
|
|
|
import org.dromara.qms.service.IQcUnqualifiedReviewService;
|
|
|
|
|
|
|
|
import org.dromara.qms.utils.QcInspectionResultCalculator;
|
|
|
|
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import java.util.Date;
|
|
|
|
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 不合格品自动生成服务
|
|
|
|
|
|
|
|
* 实现不合格品自动生成逻辑
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @author zch
|
|
|
|
|
|
|
|
* @date 2025-07-18
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
@Slf4j
|
|
|
|
|
|
|
|
@RequiredArgsConstructor
|
|
|
|
|
|
|
|
@Service
|
|
|
|
|
|
|
|
public class QcUnqualifiedGeneratorService {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final IQcUnqualifiedReviewService qcUnqualifiedReviewService;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 根据质检结果自动生成不合格品评审任务
|
|
|
|
|
|
|
|
* 实现质检不合格时自动生成不合格品评审任务
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param inspectionVo 质检主表数据
|
|
|
|
|
|
|
|
* @param inspectionItems 检测项列表
|
|
|
|
|
|
|
|
* @return 是否生成成功
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
public Boolean autoGenerateUnqualifiedReview(QcInspectionMainVo inspectionVo, List<QcInspectionItemDetailVo> inspectionItems) {
|
|
|
|
|
|
|
|
if (inspectionVo == null) {
|
|
|
|
|
|
|
|
log.error("质检主表数据为空,无法生成不合格品评审任务");
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 检查是否存在不合格项
|
|
|
|
|
|
|
|
List<QcInspectionItemDetailVo> unqualifiedItems = getUnqualifiedItems(inspectionItems);
|
|
|
|
|
|
|
|
if (unqualifiedItems.isEmpty()) {
|
|
|
|
|
|
|
|
log.info("质检任务全部合格,无需生成不合格品评审任务: {}", inspectionVo.getInspectionNo());
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
// 生成不合格品评审任务
|
|
|
|
|
|
|
|
QcUnqualifiedReviewBo reviewBo = createUnqualifiedReviewBo(inspectionVo, unqualifiedItems);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 保存不合格品评审任务
|
|
|
|
|
|
|
|
Boolean result = qcUnqualifiedReviewService.insertByBo(reviewBo);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (result) {
|
|
|
|
|
|
|
|
log.info("成功生成不合格品评审任务: 质检单号={}, 不合格项数量={}",
|
|
|
|
|
|
|
|
inspectionVo.getInspectionNo(), unqualifiedItems.size());
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
log.error("生成不合格品评审任务失败: {}", inspectionVo.getInspectionNo());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
|
|
log.error("生成不合格品评审任务异常: {}", inspectionVo.getInspectionNo(), e);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 获取不合格的检测项
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param inspectionItems 检测项列表
|
|
|
|
|
|
|
|
* @return 不合格检测项列表
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
private List<QcInspectionItemDetailVo> getUnqualifiedItems(List<QcInspectionItemDetailVo> inspectionItems) {
|
|
|
|
|
|
|
|
if (inspectionItems == null || inspectionItems.isEmpty()) {
|
|
|
|
|
|
|
|
return List.of();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return inspectionItems.stream()
|
|
|
|
|
|
|
|
.filter(item -> {
|
|
|
|
|
|
|
|
Long resultStatus = QcInspectionResultCalculator.calculateItemResultStatus(item);
|
|
|
|
|
|
|
|
return QcInspectionResultCalculator.RESULT_STATUS_UNQUALIFIED.equals(resultStatus);
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 创建不合格品评审业务对象
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param inspectionVo 质检主表数据
|
|
|
|
|
|
|
|
* @param unqualifiedItems 不合格检测项列表
|
|
|
|
|
|
|
|
* @return 不合格品评审业务对象
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
private QcUnqualifiedReviewBo createUnqualifiedReviewBo(QcInspectionMainVo inspectionVo, List<QcInspectionItemDetailVo> unqualifiedItems) {
|
|
|
|
|
|
|
|
QcUnqualifiedReviewBo reviewBo = new QcUnqualifiedReviewBo();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 生成不合格检测单号
|
|
|
|
|
|
|
|
String unqualifiedNo = generateUnqualifiedNo(inspectionVo.getInspectionNo());
|
|
|
|
|
|
|
|
reviewBo.setUnqualifiedNo(unqualifiedNo);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 设置关联的质检主表ID
|
|
|
|
|
|
|
|
reviewBo.setInspectionId(inspectionVo.getInspectionId());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 设置检测类型
|
|
|
|
|
|
|
|
reviewBo.setTypeId(inspectionVo.getTypeId());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 复制质检主表的基本信息
|
|
|
|
|
|
|
|
// reviewBo.setWorkOrder(inspectionVo.getWorkOrder());
|
|
|
|
|
|
|
|
// reviewBo.setProcessCode(inspectionVo.getProcessCode());
|
|
|
|
|
|
|
|
reviewBo.setProcessName(inspectionVo.getProcessName());
|
|
|
|
|
|
|
|
reviewBo.setBatchNo(inspectionVo.getBatchNo());
|
|
|
|
|
|
|
|
reviewBo.setMaterialName(inspectionVo.getMaterialName());
|
|
|
|
|
|
|
|
reviewBo.setMaterialCode(inspectionVo.getMaterialCode());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 设置质检员检测结果描述
|
|
|
|
|
|
|
|
String inspectorResult = buildInspectorResultDescription(unqualifiedItems);
|
|
|
|
|
|
|
|
reviewBo.setInspectorResult(inspectorResult);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 初始状态:待评审(reviewResult为空)
|
|
|
|
|
|
|
|
reviewBo.setReviewResult(null);
|
|
|
|
|
|
|
|
reviewBo.setReviewer(null);
|
|
|
|
|
|
|
|
reviewBo.setReviewTime(null);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return reviewBo;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 生成不合格检测单号
|
|
|
|
|
|
|
|
* 格式:UQ + 原检测单号 + 时间戳后4位
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param inspectionNo 原检测单号
|
|
|
|
|
|
|
|
* @return 不合格检测单号
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
private String generateUnqualifiedNo(String inspectionNo) {
|
|
|
|
|
|
|
|
String timestamp = String.valueOf(System.currentTimeMillis());
|
|
|
|
|
|
|
|
String suffix = timestamp.substring(timestamp.length() - 4);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (StringUtils.isNotBlank(inspectionNo)) {
|
|
|
|
|
|
|
|
return "UQ" + inspectionNo + suffix;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
return "UQ" + System.currentTimeMillis();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 构建质检员检测结果描述
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param unqualifiedItems 不合格检测项列表
|
|
|
|
|
|
|
|
* @return 检测结果描述
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
private String buildInspectorResultDescription(List<QcInspectionItemDetailVo> unqualifiedItems) {
|
|
|
|
|
|
|
|
if (unqualifiedItems == null || unqualifiedItems.isEmpty()) {
|
|
|
|
|
|
|
|
return "无不合格项";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
StringBuilder description = new StringBuilder();
|
|
|
|
|
|
|
|
description.append("不合格项目:");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < unqualifiedItems.size(); i++) {
|
|
|
|
|
|
|
|
QcInspectionItemDetailVo item = unqualifiedItems.get(i);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (i > 0) {
|
|
|
|
|
|
|
|
description.append(";");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
description.append(item.getItemName());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 添加具体的不合格原因
|
|
|
|
|
|
|
|
if (QcInspectionResultCalculator.DETECT_TYPE_QUANTITATIVE.equals(item.getDetectType())) {
|
|
|
|
|
|
|
|
// 定量检测:显示检测值和限值
|
|
|
|
|
|
|
|
if (item.getValue() != null) {
|
|
|
|
|
|
|
|
description.append("(检测值:").append(item.getValue());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (Boolean.TRUE.equals(item.getIsOutOfControlLimit())) {
|
|
|
|
|
|
|
|
description.append(", 超出控制限");
|
|
|
|
|
|
|
|
if (item.getUpperLimit() != null) {
|
|
|
|
|
|
|
|
description.append(", 上限:").append(item.getUpperLimit());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (item.getLowerLimit() != null) {
|
|
|
|
|
|
|
|
description.append(", 下限:").append(item.getLowerLimit());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
description.append(")");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// 定性检测:显示检测结果
|
|
|
|
|
|
|
|
if (StringUtils.isNotBlank(item.getResult())) {
|
|
|
|
|
|
|
|
description.append("(结果:").append(item.getResult()).append(")");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 限制描述长度,避免过长
|
|
|
|
|
|
|
|
String result = description.toString();
|
|
|
|
|
|
|
|
if (result.length() > 500) {
|
|
|
|
|
|
|
|
result = result.substring(0, 497) + "...";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 检查是否需要生成不合格品评审任务
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param inspectionVo 质检主表数据
|
|
|
|
|
|
|
|
* @param overallResult 整体质检结果
|
|
|
|
|
|
|
|
* @return 是否需要生成
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
public Boolean shouldGenerateUnqualifiedReview(QcInspectionMainVo inspectionVo, Long overallResult) {
|
|
|
|
|
|
|
|
// 如果整体结果合格,不需要生成
|
|
|
|
|
|
|
|
if (QcInspectionResultCalculator.RESULT_STATUS_QUALIFIED.equals(overallResult)) {
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 检查是否已经存在不合格品评审任务
|
|
|
|
|
|
|
|
if (hasExistingUnqualifiedReview(inspectionVo.getInspectionId())) {
|
|
|
|
|
|
|
|
log.info("质检任务已存在不合格品评审任务,跳过生成: {}", inspectionVo.getInspectionNo());
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 检查是否已存在不合格品评审任务
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param inspectionId 质检主表ID
|
|
|
|
|
|
|
|
* @return 是否已存在
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
private Boolean hasExistingUnqualifiedReview(Long inspectionId) {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
// 查询是否已存在该质检任务的不合格品评审记录
|
|
|
|
|
|
|
|
QcUnqualifiedReviewBo queryBo = new QcUnqualifiedReviewBo();
|
|
|
|
|
|
|
|
queryBo.setInspectionId(inspectionId);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return !qcUnqualifiedReviewService.queryList(queryBo).isEmpty();
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
|
|
log.error("检查不合格品评审任务是否存在时发生异常: inspectionId={}", inspectionId, e);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 批量生成不合格品评审任务
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param inspectionList 质检任务列表
|
|
|
|
|
|
|
|
* @return 成功生成的数量
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
public Integer batchGenerateUnqualifiedReviews(List<QcInspectionMainVo> inspectionList) {
|
|
|
|
|
|
|
|
if (inspectionList == null || inspectionList.isEmpty()) {
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int successCount = 0;
|
|
|
|
|
|
|
|
for (QcInspectionMainVo inspection : inspectionList) {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
// 这里需要获取检测项数据,实际实现中可能需要调用其他服务
|
|
|
|
|
|
|
|
// List<QcInspectionItemDetailVo> items = getInspectionItems(inspection.getInspectionId());
|
|
|
|
|
|
|
|
// Boolean result = autoGenerateUnqualifiedReview(inspection, items);
|
|
|
|
|
|
|
|
// if (Boolean.TRUE.equals(result)) {
|
|
|
|
|
|
|
|
// successCount++;
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
|
|
log.error("批量生成不合格品评审任务失败: {}", inspection.getInspectionNo(), e);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
log.info("批量生成不合格品评审任务完成,总数: {}, 成功: {}", inspectionList.size(), successCount);
|
|
|
|
|
|
|
|
return successCount;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|