|
|
|
@ -14,6 +14,7 @@ import org.dromara.qms.domain.QcInspectionMain;
|
|
|
|
|
import org.dromara.qms.domain.QcInspectionType;
|
|
|
|
|
import org.dromara.qms.domain.bo.QcInspectionMainBo;
|
|
|
|
|
import org.dromara.qms.domain.bo.QcInspectionResultBo;
|
|
|
|
|
import org.dromara.qms.domain.vo.QcInspectionMainVo;
|
|
|
|
|
import org.dromara.qms.domain.vo.QcInspectionResultVo;
|
|
|
|
|
import org.dromara.qms.service.IQcInspectionResultService;
|
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
@ -108,12 +109,12 @@ public class QcUnqualifiedReviewServiceImpl implements IQcUnqualifiedReviewServi
|
|
|
|
|
}
|
|
|
|
|
// 强制设置reviewResult为null,查询待评审记录
|
|
|
|
|
pendingBo.setReviewResult(null);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MPJLambdaWrapper<QcUnqualifiedReview> lqw = buildQueryWrapper(pendingBo);
|
|
|
|
|
// 添加条件:reviewResult为空或null
|
|
|
|
|
lqw.and(wrapper -> wrapper.isNull(QcUnqualifiedReview::getReviewResult)
|
|
|
|
|
.or().eq(QcUnqualifiedReview::getReviewResult, ""));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Page<QcUnqualifiedReviewVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
|
|
|
|
return TableDataInfo.build(result);
|
|
|
|
|
}
|
|
|
|
@ -133,7 +134,7 @@ public class QcUnqualifiedReviewServiceImpl implements IQcUnqualifiedReviewServi
|
|
|
|
|
QcInspectionResultBo resultBo = new QcInspectionResultBo();
|
|
|
|
|
resultBo.setInspectionId(reviewVo.getInspectionId());
|
|
|
|
|
List<QcInspectionResultVo> inspectionResults = qcInspectionResultService.queryList(resultBo);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 可以将检测项结果添加到reviewVo中,但由于QcUnqualifiedReviewVo没有相应字段
|
|
|
|
|
// 这里暂时通过日志记录或者扩展VO类来处理
|
|
|
|
|
// 实际项目中可能需要扩展QcUnqualifiedReviewVo类添加inspectionResults字段
|
|
|
|
@ -152,15 +153,15 @@ public class QcUnqualifiedReviewServiceImpl implements IQcUnqualifiedReviewServi
|
|
|
|
|
public Boolean submitReview(QcUnqualifiedReviewBo bo) {
|
|
|
|
|
// 设置评审时间
|
|
|
|
|
bo.setReviewTime(new Date());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 更新评审结果
|
|
|
|
|
Boolean updated = updateByBo(bo);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (updated) {
|
|
|
|
|
// 根据评审结果触发后续流程
|
|
|
|
|
triggerWorkflowProcess(bo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return updated;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -173,7 +174,7 @@ public class QcUnqualifiedReviewServiceImpl implements IQcUnqualifiedReviewServi
|
|
|
|
|
@Override
|
|
|
|
|
public Map<String, Object> getUnqualifiedSummary(String dateRange) {
|
|
|
|
|
Map<String, Object> summary = new HashMap<>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 解析日期范围
|
|
|
|
|
LocalDate startDate = null;
|
|
|
|
|
LocalDate endDate = null;
|
|
|
|
@ -194,30 +195,30 @@ public class QcUnqualifiedReviewServiceImpl implements IQcUnqualifiedReviewServi
|
|
|
|
|
startDate = LocalDate.now().withDayOfMonth(1);
|
|
|
|
|
endDate = LocalDate.now();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 构建查询条件
|
|
|
|
|
QcUnqualifiedReviewBo bo = new QcUnqualifiedReviewBo();
|
|
|
|
|
Map<String, Object> params = new HashMap<>();
|
|
|
|
|
params.put("beginTime", startDate.toString());
|
|
|
|
|
params.put("endTime", endDate.toString());
|
|
|
|
|
bo.setParams(params);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 查询所有不合格品记录
|
|
|
|
|
List<QcUnqualifiedReviewVo> allRecords = queryList(bo);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 统计总数
|
|
|
|
|
summary.put("totalCount", allRecords.size());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 统计待评审数量
|
|
|
|
|
long pendingCount = allRecords.stream()
|
|
|
|
|
.filter(record -> StringUtils.isBlank(record.getReviewResult()))
|
|
|
|
|
.count();
|
|
|
|
|
summary.put("pendingCount", pendingCount);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 统计已评审数量
|
|
|
|
|
long reviewedCount = allRecords.size() - pendingCount;
|
|
|
|
|
summary.put("reviewedCount", reviewedCount);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 按评审结果分组统计
|
|
|
|
|
Map<String, Long> reviewResultStats = allRecords.stream()
|
|
|
|
|
.filter(record -> StringUtils.isNotBlank(record.getReviewResult()))
|
|
|
|
@ -225,13 +226,13 @@ public class QcUnqualifiedReviewServiceImpl implements IQcUnqualifiedReviewServi
|
|
|
|
|
QcUnqualifiedReviewVo::getReviewResult,
|
|
|
|
|
Collectors.counting()
|
|
|
|
|
));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
summary.put("scrapCount", reviewResultStats.getOrDefault("0", 0L)); // 报废
|
|
|
|
|
summary.put("reworkCount", reviewResultStats.getOrDefault("1", 0L)); // 返工
|
|
|
|
|
summary.put("returnCount", reviewResultStats.getOrDefault("2", 0L)); // 退货
|
|
|
|
|
summary.put("acceptCount", reviewResultStats.getOrDefault("3", 0L)); // 让步接收
|
|
|
|
|
summary.put("transferCount", reviewResultStats.getOrDefault("4", 0L)); // 流转
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 按物料分组统计
|
|
|
|
|
Map<String, Long> materialStats = allRecords.stream()
|
|
|
|
|
.filter(record -> StringUtils.isNotBlank(record.getMaterialName()))
|
|
|
|
@ -240,7 +241,7 @@ public class QcUnqualifiedReviewServiceImpl implements IQcUnqualifiedReviewServi
|
|
|
|
|
Collectors.counting()
|
|
|
|
|
));
|
|
|
|
|
summary.put("materialStats", materialStats);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 按工序分组统计
|
|
|
|
|
Map<String, Long> processStats = allRecords.stream()
|
|
|
|
|
.filter(record -> StringUtils.isNotBlank(record.getProcessName()))
|
|
|
|
@ -249,7 +250,7 @@ public class QcUnqualifiedReviewServiceImpl implements IQcUnqualifiedReviewServi
|
|
|
|
|
Collectors.counting()
|
|
|
|
|
));
|
|
|
|
|
summary.put("processStats", processStats);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return summary;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -266,10 +267,10 @@ public class QcUnqualifiedReviewServiceImpl implements IQcUnqualifiedReviewServi
|
|
|
|
|
log.error("评审结果为空,无法触发工作流程");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
log.info("开始触发工作流程: 评审ID={}, 评审结果={}", bo.getReviewId(), bo.getReviewResult());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 根据评审结果触发不同的后续流程
|
|
|
|
|
switch (bo.getReviewResult()) {
|
|
|
|
|
case "0": // 报废
|
|
|
|
@ -299,19 +300,19 @@ public class QcUnqualifiedReviewServiceImpl implements IQcUnqualifiedReviewServi
|
|
|
|
|
private Boolean handleScrapProcess(QcUnqualifiedReviewBo bo) {
|
|
|
|
|
try {
|
|
|
|
|
log.info("执行报废流程: 评审ID={}", bo.getReviewId());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 1. 更新库存状态为报废
|
|
|
|
|
updateInventoryStatus(bo, "SCRAPPED");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 生成报废单据
|
|
|
|
|
generateScrapDocument(bo);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 更新质检主表状态
|
|
|
|
|
updateInspectionMainStatus(bo, "SCRAPPED");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 4. 记录处理日志
|
|
|
|
|
recordProcessLog(bo, "报废流程执行完成");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
log.info("报废流程执行成功: 评审ID={}", bo.getReviewId());
|
|
|
|
|
return true;
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
@ -327,22 +328,22 @@ public class QcUnqualifiedReviewServiceImpl implements IQcUnqualifiedReviewServi
|
|
|
|
|
private Boolean handleReworkProcess(QcUnqualifiedReviewBo bo) {
|
|
|
|
|
try {
|
|
|
|
|
log.info("执行返工流程: 评审ID={}", bo.getReviewId());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 1. 生成返工工单
|
|
|
|
|
generateReworkOrder(bo);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 分派返工任务给相关人员
|
|
|
|
|
assignReworkTask(bo);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 更新质检主表状态为返工中
|
|
|
|
|
updateInspectionMainStatus(bo, "REWORKING");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 4. 更新库存状态
|
|
|
|
|
updateInventoryStatus(bo, "REWORKING");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 5. 记录处理日志
|
|
|
|
|
recordProcessLog(bo, "返工流程执行完成,已生成返工工单");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
log.info("返工流程执行成功: 评审ID={}", bo.getReviewId());
|
|
|
|
|
return true;
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
@ -358,22 +359,22 @@ public class QcUnqualifiedReviewServiceImpl implements IQcUnqualifiedReviewServi
|
|
|
|
|
private Boolean handleReturnProcess(QcUnqualifiedReviewBo bo) {
|
|
|
|
|
try {
|
|
|
|
|
log.info("执行退货流程: 评审ID={}", bo.getReviewId());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 1. 生成退货单据
|
|
|
|
|
generateReturnDocument(bo);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 通知供应商
|
|
|
|
|
notifySupplier(bo);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 更新库存状态为待退货
|
|
|
|
|
updateInventoryStatus(bo, "RETURNING");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 4. 更新质检主表状态
|
|
|
|
|
updateInspectionMainStatus(bo, "RETURNED");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 5. 记录处理日志
|
|
|
|
|
recordProcessLog(bo, "退货流程执行完成,已通知供应商");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
log.info("退货流程执行成功: 评审ID={}", bo.getReviewId());
|
|
|
|
|
return true;
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
@ -389,22 +390,22 @@ public class QcUnqualifiedReviewServiceImpl implements IQcUnqualifiedReviewServi
|
|
|
|
|
private Boolean handleAcceptProcess(QcUnqualifiedReviewBo bo) {
|
|
|
|
|
try {
|
|
|
|
|
log.info("执行让步接收流程: 评审ID={}", bo.getReviewId());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 1. 更新质检状态为让步合格
|
|
|
|
|
updateInspectionMainStatus(bo, "CONDITIONALLY_ACCEPTED");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 更新库存状态为可用
|
|
|
|
|
updateInventoryStatus(bo, "AVAILABLE");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 生成让步接收单据
|
|
|
|
|
generateAcceptanceDocument(bo);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 4. 触发入库流程
|
|
|
|
|
triggerInboundProcess(bo);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 5. 记录处理日志
|
|
|
|
|
recordProcessLog(bo, "让步接收流程执行完成,产品已入库");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
log.info("让步接收流程执行成功: 评审ID={}", bo.getReviewId());
|
|
|
|
|
return true;
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
@ -420,25 +421,25 @@ public class QcUnqualifiedReviewServiceImpl implements IQcUnqualifiedReviewServi
|
|
|
|
|
private Boolean handleTransferProcess(QcUnqualifiedReviewBo bo) {
|
|
|
|
|
try {
|
|
|
|
|
log.info("执行流转流程: 评审ID={}", bo.getReviewId());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 1. 确定流转目标部门或工序
|
|
|
|
|
String transferTarget = determineTransferTarget(bo);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 生成流转单据
|
|
|
|
|
generateTransferDocument(bo, transferTarget);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 通知目标部门
|
|
|
|
|
notifyTargetDepartment(bo, transferTarget);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 4. 更新质检主表状态
|
|
|
|
|
updateInspectionMainStatus(bo, "TRANSFERRED");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 5. 更新库存状态
|
|
|
|
|
updateInventoryStatus(bo, "TRANSFERRED");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 6. 记录处理日志
|
|
|
|
|
recordProcessLog(bo, "流转流程执行完成,已转移至: " + transferTarget);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
log.info("流转流程执行成功: 评审ID={}, 流转目标={}", bo.getReviewId(), transferTarget);
|
|
|
|
|
return true;
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
@ -619,7 +620,7 @@ public class QcUnqualifiedReviewServiceImpl implements IQcUnqualifiedReviewServi
|
|
|
|
|
.leftJoin(QcInspectionMain.class, QcInspectionMain::getInspectionId, QcUnqualifiedReview::getInspectionId)
|
|
|
|
|
//关联检测类型
|
|
|
|
|
.select(QcInspectionType::getTypeName, QcInspectionType::getQcInspectionType, QcInspectionType::getTypeCode, QcInspectionType::getQcInspectionType)
|
|
|
|
|
.leftJoin(QcInspectionType.class, QcInspectionType::getTypeId, QcInspectionMain::getTypeId)
|
|
|
|
|
.leftJoin(QcInspectionType.class, QcInspectionType::getTypeId, QcUnqualifiedReview::getTypeId)
|
|
|
|
|
|
|
|
|
|
.eq(bo.getReviewId() != null, QcUnqualifiedReview::getReviewId, bo.getReviewId())
|
|
|
|
|
.eq(StringUtils.isNotBlank(bo.getUnqualifiedNo()), QcUnqualifiedReview::getUnqualifiedNo, bo.getUnqualifiedNo())
|
|
|
|
@ -690,4 +691,57 @@ public class QcUnqualifiedReviewServiceImpl implements IQcUnqualifiedReviewServi
|
|
|
|
|
}
|
|
|
|
|
return baseMapper.deleteByIds(ids) > 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Boolean autoGenerateUnqualifiedReview(QcInspectionMainVo inspectionVo, List<QcInspectionResultVo> inspectionResults) {
|
|
|
|
|
// 检查是否有不合格项
|
|
|
|
|
boolean hasUnqualified = inspectionResults.stream()
|
|
|
|
|
.anyMatch(result -> Long.valueOf(1).equals(result.getDetectResult()));
|
|
|
|
|
if (!hasUnqualified) {
|
|
|
|
|
log.info("无不合格项,无需生成评审记录: inspectionId={}", inspectionVo.getInspectionId());
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QcUnqualifiedReviewBo bo = new QcUnqualifiedReviewBo();
|
|
|
|
|
bo.setInspectionId(inspectionVo.getInspectionId());
|
|
|
|
|
// bo.setTypeId(inspectionVo.getTypeId());
|
|
|
|
|
bo.setMaterialCode(inspectionVo.getMaterialCode());
|
|
|
|
|
bo.setMaterialName(inspectionVo.getMaterialName());
|
|
|
|
|
bo.setProcessName(inspectionVo.getProcessName());
|
|
|
|
|
bo.setWorkOrder(inspectionVo.getProductionOrder());
|
|
|
|
|
bo.setBatchNo(inspectionVo.getBatchNo());
|
|
|
|
|
bo.setInspectorResult(inspectionVo.getResult().toString());
|
|
|
|
|
|
|
|
|
|
// 生成唯一的不合格编号
|
|
|
|
|
String unqualifiedNo = generateUnqualifiedNo();
|
|
|
|
|
bo.setUnqualifiedNo(unqualifiedNo);
|
|
|
|
|
|
|
|
|
|
// 设置默认值
|
|
|
|
|
bo.setReviewResult(null); // 待评审
|
|
|
|
|
|
|
|
|
|
Boolean inserted = insertByBo(bo);
|
|
|
|
|
if (inserted) {
|
|
|
|
|
log.info("不合格品评审记录生成成功: reviewId={}, unqualifiedNo={}", bo.getReviewId(), unqualifiedNo);
|
|
|
|
|
} else {
|
|
|
|
|
log.error("不合格品评审记录生成失败: inspectionId={}", inspectionVo.getInspectionId());
|
|
|
|
|
}
|
|
|
|
|
return inserted;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 生成唯一的不合格编号
|
|
|
|
|
* 格式: UNQ-yyyyMMdd-XXXX (XXXX为4位序列号)
|
|
|
|
|
*/
|
|
|
|
|
private String generateUnqualifiedNo() {
|
|
|
|
|
LocalDate today = LocalDate.now();
|
|
|
|
|
String prefix = "UNQ-" + today.format(DateTimeFormatter.ofPattern("yyyyMMdd")) + "-";
|
|
|
|
|
|
|
|
|
|
// 查询当天已生成的记录数
|
|
|
|
|
long count = baseMapper.selectCount(Wrappers.<QcUnqualifiedReview>lambdaQuery()
|
|
|
|
|
.likeRight(QcUnqualifiedReview::getUnqualifiedNo, prefix));
|
|
|
|
|
|
|
|
|
|
// 生成序列号
|
|
|
|
|
String seq = String.format("%04d", count + 1);
|
|
|
|
|
return prefix + seq;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|