diff --git a/nflg-qms-admin/src/main/java/com/nflg/qms/admin/controller/QmsIssueTicketController.java b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/controller/QmsIssueTicketController.java index 8ce63c47..f0a997fe 100644 --- a/nflg-qms-admin/src/main/java/com/nflg/qms/admin/controller/QmsIssueTicketController.java +++ b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/controller/QmsIssueTicketController.java @@ -100,6 +100,16 @@ public class QmsIssueTicketController extends BaseController { return ApiResult.success(); } + /** + * 新增PQC检测工单(平板使用) + * 同步创建工单,异步创建工单处理记录 + */ + @PostMapping("addPqcTicket") + public ApiResult addPqcTicket(@Valid @RequestBody QmsIssueTicketPqcAddQO request) { + issueTicketControllerService.addPqcTicket(request); + return ApiResult.success(); + } + /** * PDI新建工单并返回不合格检测项 * 1. 创建工单 diff --git a/nflg-qms-admin/src/main/java/com/nflg/qms/admin/controller/QmsPqcTaskRecordController.java b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/controller/QmsPqcTaskRecordController.java index 82687dda..d4f04985 100644 --- a/nflg-qms-admin/src/main/java/com/nflg/qms/admin/controller/QmsPqcTaskRecordController.java +++ b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/controller/QmsPqcTaskRecordController.java @@ -1,20 +1,19 @@ package com.nflg.qms.admin.controller; +import com.nflg.qms.admin.service.QmsPqcTaskRecordControllerService; import com.nflg.wms.common.constant.STATE; import com.nflg.wms.common.pojo.ApiResult; import com.nflg.wms.common.pojo.PageData; import com.nflg.wms.common.pojo.qo.QmsPqcTaskRecordDraftQO; import com.nflg.wms.common.pojo.qo.QmsPqcTaskRecordSearchQO; import com.nflg.wms.common.pojo.qo.QmsPqcTaskRecordTabletSearchQO; +import com.nflg.wms.common.pojo.qo.QmsPqcTaskRecordUnqualifiedSearchQO; import com.nflg.wms.common.pojo.vo.*; -import com.nflg.qms.admin.service.QmsPqcTaskRecordControllerService; import jakarta.annotation.Resource; import jakarta.validation.Valid; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; -import java.util.List; - /** * PQC任务 * @@ -29,13 +28,21 @@ public class QmsPqcTaskRecordController { private QmsPqcTaskRecordControllerService pqcTaskRecordService; /** - * 查询PQC任务列表(分页) + * 查询PQC任务列表(分页,合格/待复核) */ @PostMapping("/search") public ApiResult> search(@RequestBody QmsPqcTaskRecordSearchQO request) { return ApiResult.success(pqcTaskRecordService.searchPqcTaskList(request)); } + /** + * 查询PQC不合格任务列表(分页) + */ + @PostMapping("/search/unqualified") + public ApiResult> searchUnqualified(@RequestBody QmsPqcTaskRecordUnqualifiedSearchQO request) { + return ApiResult.success(pqcTaskRecordService.searchPqcTaskUnqualifiedList(request)); + } + /** * 查询PQC任务列表(分页,平板使用) */ @@ -89,21 +96,18 @@ public class QmsPqcTaskRecordController { * 提交 * @return 根据提交结果返回不同数据: * 1. 有空值:返回空值明细列表 - * 2. 有不合格项:返回生成的工单编号列表 + * 2. 有不合格项:返回不合格项列表,工单异步生成 * 3. 通过:返回空数据 */ @PostMapping("/submit") public ApiResult submit(@Valid @RequestBody QmsPqcTaskRecordDraftQO request) { QmsPqcTaskRecordControllerService.SubmitResult result = pqcTaskRecordService.submit(request); - + if (result.getType() == 1) { - // 情况1:有空值 return ApiResult.error(STATE.BusinessError, "数据校验失败", result.getEmptyFields()); } else if (result.getType() == 2) { - // 情况2:生成工单 - return ApiResult.success(result.getTicketNos()); + return ApiResult.success(result.getUnqualifiedItems()); } else { - // 情况3:通过 return ApiResult.success(); } } diff --git a/nflg-qms-admin/src/main/java/com/nflg/qms/admin/event/PqcUnqualifiedTaskSubmittedEvent.java b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/event/PqcUnqualifiedTaskSubmittedEvent.java new file mode 100644 index 00000000..89b246ee --- /dev/null +++ b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/event/PqcUnqualifiedTaskSubmittedEvent.java @@ -0,0 +1,39 @@ +package com.nflg.qms.admin.event; + +import org.springframework.context.ApplicationEvent; + +/** + * PQC不合格任务提交成功事件 + */ +public class PqcUnqualifiedTaskSubmittedEvent extends ApplicationEvent { + + private final Long taskId; + private final Long currentUserId; + private final String currentUserName; + private final String traceId; + + public PqcUnqualifiedTaskSubmittedEvent(Object source, Long taskId, Long currentUserId, + String currentUserName, String traceId) { + super(source); + this.taskId = taskId; + this.currentUserId = currentUserId; + this.currentUserName = currentUserName; + this.traceId = traceId; + } + + public Long getTaskId() { + return taskId; + } + + public Long getCurrentUserId() { + return currentUserId; + } + + public String getCurrentUserName() { + return currentUserName; + } + + public String getTraceId() { + return traceId; + } +} diff --git a/nflg-qms-admin/src/main/java/com/nflg/qms/admin/listener/PqcUnqualifiedTaskEventListener.java b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/listener/PqcUnqualifiedTaskEventListener.java new file mode 100644 index 00000000..6cd3f2e5 --- /dev/null +++ b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/listener/PqcUnqualifiedTaskEventListener.java @@ -0,0 +1,29 @@ +package com.nflg.qms.admin.listener; + +import com.nflg.qms.admin.event.PqcUnqualifiedTaskSubmittedEvent; +import com.nflg.qms.admin.service.QmsPqcTaskRecordControllerService; +import jakarta.annotation.Resource; +import org.slf4j.MDC; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; +import org.springframework.transaction.event.TransactionalEventListener; +import org.springframework.transaction.event.TransactionPhase; + +@Component +public class PqcUnqualifiedTaskEventListener { + + @Resource + private QmsPqcTaskRecordControllerService pqcTaskRecordService; + + @Async("ticketTaskExecutor") + @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) + public void handle(PqcUnqualifiedTaskSubmittedEvent event) { + MDC.put("traceId", event.getTraceId()); + try { + pqcTaskRecordService.generateUnqualifiedTicketAsync( + event.getTaskId(), event.getCurrentUserId(), event.getCurrentUserName()); + } finally { + MDC.clear(); + } + } +} diff --git a/nflg-qms-admin/src/main/java/com/nflg/qms/admin/publisher/PqcUnqualifiedTaskEventPublisher.java b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/publisher/PqcUnqualifiedTaskEventPublisher.java new file mode 100644 index 00000000..5b175cf1 --- /dev/null +++ b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/publisher/PqcUnqualifiedTaskEventPublisher.java @@ -0,0 +1,20 @@ +package com.nflg.qms.admin.publisher; + +import com.nflg.qms.admin.event.PqcUnqualifiedTaskSubmittedEvent; +import com.nflg.wms.common.constant.Constant; +import jakarta.annotation.Resource; +import org.slf4j.MDC; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Service; + +@Service +public class PqcUnqualifiedTaskEventPublisher { + + @Resource + private ApplicationEventPublisher eventPublisher; + + public void publish(Long taskId, Long currentUserId, String currentUserName) { + eventPublisher.publishEvent(new PqcUnqualifiedTaskSubmittedEvent( + this, taskId, currentUserId, currentUserName, MDC.get(Constant.TRACE_ID))); + } +} diff --git a/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsIssueTicketControllerService.java b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsIssueTicketControllerService.java index ab782052..038b516c 100644 --- a/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsIssueTicketControllerService.java +++ b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsIssueTicketControllerService.java @@ -1159,6 +1159,118 @@ public class QmsIssueTicketControllerService { } } + /** + * 新增PQC检测工单 + * 工单编号自动生成(序号41),来源类型固定为3(PQC检测任务),状态默认为0(待流转) + * 异步新增工单处理记录 + */ + @Transactional(rollbackFor = Exception.class) + public void addPqcTicket(@Valid QmsIssueTicketPqcAddQO request) { + Long userId = UserUtil.getUserId(); + String userName = UserUtil.getUserName(); + LocalDateTime now = LocalDateTime.now(); + + boolean containsSelf = request.getHandlers().stream() + .anyMatch(h -> userId.equals(h.getHandlerUserId())); + if (containsSelf) { + throw new NflgException(STATE.BusinessError, "不能将工单分配给自己"); + } + + QmsPqcTaskRecord taskRecord = pqcTaskRecordService.getById(request.getTaskRecordId()); + if (Objects.isNull(taskRecord)) { + throw new NflgException(STATE.BusinessError, "PQC检测任务记录不存在"); + } + + if (!Objects.equals(taskRecord.getStatus(), (short) 3)) { + throw new NflgException(STATE.BusinessError, "只有已复核的PQC任务才能创建工单"); + } + + QmsIssueTicket existingTicket = issueTicketService.lambdaQuery() + .eq(QmsIssueTicket::getSourceType, (short) 3) + .eq(QmsIssueTicket::getSourceId, request.getTaskRecordId()) + .one(); + if (existingTicket != null) { + throw new NflgException(STATE.BusinessError, + "该任务已存在工单(工单编号:" + existingTicket.getTicketNo() + "),请使用追加处理记录接口"); + } + + List requestedDetailIds = request.getHandlers().stream() + .map(QmsIssueTicketPqcAddQO.HandlerItem::getTaskResultId) + .filter(Objects::nonNull) + .distinct() + .collect(Collectors.toList()); + if (requestedDetailIds.isEmpty()) { + throw new NflgException(STATE.BusinessError, "不合格项不能为空"); + } + + List detailList = pqcTaskRecordDetailsService.lambdaQuery() + .eq(QmsPqcTaskRecordDetails::getTaskId, request.getTaskRecordId()) + .in(QmsPqcTaskRecordDetails::getId, requestedDetailIds) + .list(); + if (detailList.size() != requestedDetailIds.size()) { + throw new NflgException(STATE.BusinessError, "存在无效的不合格项"); + } + + List unqualifiedDetails = detailList.stream() + .filter(detail -> Boolean.FALSE.equals(detail.getReviewEnable())) + .collect(Collectors.toList()); + if (unqualifiedDetails.isEmpty()) { + throw new NflgException(STATE.BusinessError, "请选择不合格检测项"); + } + + QmsPqcInspectionPoint point = pqcInspectionPointService.getById(taskRecord.getInspectionPointId()); + String stepName = point != null ? StrUtil.blankToDefault(point.getStepName(), "") : ""; + String inspectionPointName = point != null ? StrUtil.blankToDefault(point.getInspectionPointName(), "") : ""; + + String incidentDescription = buildPqcIncidentDescription(unqualifiedDetails); + String ticketNo = basdeSerialNumberControllerService.generateSerialNumber(41); + + QmsIssueTicket entity = new QmsIssueTicket() + .setSourceType((short) 3) + .setSourceId(request.getTaskRecordId()) + .setTicketNo(ticketNo) + .setTicketTitle(taskRecord.getAufnr() + "-" + taskRecord.getNo() + "-" + stepName + "-" + inspectionPointName) + .setProjectNo(taskRecord.getTaskNo()) + .setIncidentType(request.getIncidentType()) + .setIncidentDescription(incidentDescription) + .setRemark(request.getRemark()) + .setUnqualifiedQty(unqualifiedDetails.size()) + .setStatus((short) 0) + .setCreateUserId(userId) + .setCreateUserName(userName) + .setCreateTime(now) + .setUpdateUserId(userId) + .setUpdateUserName(userName) + .setUpdateTime(now); + issueTicketService.save(entity); + + Set unqualifiedDetailIds = unqualifiedDetails.stream() + .map(QmsPqcTaskRecordDetails::getId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + Map> handlerToResultsMap = request.getHandlers().stream() + .collect(Collectors.groupingBy( + QmsIssueTicketPqcAddQO.HandlerItem::getHandlerUserId, + Collectors.mapping(QmsIssueTicketPqcAddQO.HandlerItem::getTaskResultId, Collectors.toList()) + )); + + for (Map.Entry> entry : handlerToResultsMap.entrySet()) { + List filteredTaskResultIds = entry.getValue().stream() + .filter(unqualifiedDetailIds::contains) + .distinct() + .collect(Collectors.toList()); + if (filteredTaskResultIds.isEmpty()) { + continue; + } + issueTicketProcessControllerService.addAsync( + entity.getId(), + entry.getKey(), + filteredTaskResultIds, + ticketNo + ); + } + } + /** * 通过来料检测任务ID发起IQC检测任务类型质量问题工单 * 工单编号自动生成,来源类型固定为0(IQC检测任务),状态默认为0(待流转) @@ -1249,6 +1361,43 @@ public class QmsIssueTicketControllerService { return StrUtil.join("-", args); } + private String buildPqcIncidentDescription(List detailList) { + if (CollectionUtil.isEmpty(detailList)) { + return ""; + } + + List itemIds = detailList.stream() + .map(QmsPqcTaskRecordDetails::getInspectionPointItemId) + .filter(Objects::nonNull) + .distinct() + .collect(Collectors.toList()); + Map itemMap = new HashMap<>(); + if (CollectionUtil.isNotEmpty(itemIds)) { + itemMap = pqcInspectionPointItemsService.listByIds(itemIds).stream() + .collect(Collectors.toMap(QmsPqcInspectionPointItems::getId, item -> item, (a, b) -> a)); + } + + StringBuilder descBuilder = new StringBuilder(); + int index = 1; + for (QmsPqcTaskRecordDetails detail : detailList) { + if (index > 1) { + descBuilder.append(";"); + } + descBuilder.append(index).append(". "); + QmsPqcInspectionPointItems item = itemMap.get(detail.getInspectionPointItemId()); + if (item != null && StrUtil.isNotBlank(item.getInspectionContent())) { + descBuilder.append(item.getInspectionContent()); + } else { + descBuilder.append("PQC不合格项"); + } + if (StrUtil.isNotBlank(detail.getReviewOpinion())) { + descBuilder.append("(").append(detail.getReviewOpinion()).append(")"); + } + index++; + } + return descBuilder.toString(); + } + /** * 查询来料检测任务质量问题工单详情 * 包含图片文件信息、来料检测任务详情、检验记录(含子项和样本数据) diff --git a/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsPqcTaskRecordControllerService.java b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsPqcTaskRecordControllerService.java index d2dd82bf..c3abb253 100644 --- a/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsPqcTaskRecordControllerService.java +++ b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsPqcTaskRecordControllerService.java @@ -9,6 +9,7 @@ import com.nflg.wms.common.pojo.PageData; import com.nflg.wms.common.pojo.qo.QmsPqcTaskRecordDraftQO; import com.nflg.wms.common.pojo.qo.QmsPqcTaskRecordSearchQO; import com.nflg.wms.common.pojo.qo.QmsPqcTaskRecordTabletSearchQO; +import com.nflg.wms.common.pojo.qo.QmsPqcTaskRecordUnqualifiedSearchQO; import com.nflg.wms.common.pojo.vo.*; import com.nflg.wms.common.util.UserUtil; import com.nflg.wms.common.util.VUtil; @@ -69,6 +70,9 @@ public class QmsPqcTaskRecordControllerService { @Resource private IDictionaryItemService dictionaryItemService; + @Resource + private com.nflg.qms.admin.publisher.PqcUnqualifiedTaskEventPublisher pqcUnqualifiedTaskEventPublisher; + /** * 1. 新增PQC任务(仅Service层,供暂存/提交调用) */ @@ -144,27 +148,81 @@ public class QmsPqcTaskRecordControllerService { public PageData searchPqcTaskList(QmsPqcTaskRecordSearchQO request) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - // 条件过滤 + Set unqualifiedTaskIds = getUnqualifiedTaskIds(); + if (StrUtil.isNotBlank(request.getTaskNo())) { queryWrapper.eq(QmsPqcTaskRecord::getTaskNo, request.getTaskNo()); } - if (request.getInspectionPointId() != null) { - queryWrapper.eq(QmsPqcTaskRecord::getInspectionPointId, request.getInspectionPointId()); + if (StrUtil.isNotBlank(request.getAufnr())) { + queryWrapper.eq(QmsPqcTaskRecord::getAufnr, request.getAufnr()); + } + if (StrUtil.isNotBlank(request.getModelNo())) { + queryWrapper.eq(QmsPqcTaskRecord::getModelNo, request.getModelNo()); + } + if (StrUtil.isNotBlank(request.getSelfTesterName())) { + queryWrapper.like(QmsPqcTaskRecord::getSelfTesterName, request.getSelfTesterName()); + } + if (request.getStatus() != null) { + queryWrapper.eq(QmsPqcTaskRecord::getStatus, request.getStatus()); + } + if (request.getCreateStartTime() != null) { + queryWrapper.ge(QmsPqcTaskRecord::getCreateTime, request.getCreateStartTime()); + } + if (request.getCreateEndTime() != null) { + queryWrapper.le(QmsPqcTaskRecord::getCreateTime, request.getCreateEndTime()); + } + + queryWrapper.and(wrapper -> wrapper.isNull(QmsPqcTaskRecord::getEnable) + .or() + .eq(QmsPqcTaskRecord::getEnable, true)); + if (!unqualifiedTaskIds.isEmpty()) { + queryWrapper.notIn(QmsPqcTaskRecord::getId, unqualifiedTaskIds); + } + + queryWrapper.orderByDesc(QmsPqcTaskRecord::getCreateTime); + return buildPqcTaskPageData(request.getPage(), request.getPageSize(), queryWrapper); + } + + public PageData searchPqcTaskUnqualifiedList(QmsPqcTaskRecordUnqualifiedSearchQO request) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + + Set unqualifiedTaskIds = getUnqualifiedTaskIds(); + Set pointIdsByKeyword = findInspectionPointIdsByKeyword(request.getInspectionPointKeyword()); + + if (StrUtil.isNotBlank(request.getTaskNo())) { + queryWrapper.eq(QmsPqcTaskRecord::getTaskNo, request.getTaskNo()); } if (StrUtil.isNotBlank(request.getModelNo())) { queryWrapper.eq(QmsPqcTaskRecord::getModelNo, request.getModelNo()); } if (request.getReviewStartTime() != null) { - queryWrapper.ge(QmsPqcTaskRecord::getCreateTime, request.getReviewStartTime()); + queryWrapper.ge(QmsPqcTaskRecord::getCompleteTime, request.getReviewStartTime()); } if (request.getReviewEndTime() != null) { - queryWrapper.le(QmsPqcTaskRecord::getCreateTime, request.getReviewEndTime()); + queryWrapper.le(QmsPqcTaskRecord::getCompleteTime, request.getReviewEndTime()); + } + if (StrUtil.isNotBlank(request.getInspectionPointKeyword())) { + if (pointIdsByKeyword.isEmpty()) { + queryWrapper.apply("1 = 0"); + } else { + queryWrapper.in(QmsPqcTaskRecord::getInspectionPointId, pointIdsByKeyword); + } } - queryWrapper.orderByDesc(QmsPqcTaskRecord::getCreateTime); + queryWrapper.and(wrapper -> { + wrapper.eq(QmsPqcTaskRecord::getEnable, false); + if (!unqualifiedTaskIds.isEmpty()) { + wrapper.or().in(QmsPqcTaskRecord::getId, unqualifiedTaskIds); + } + }); + queryWrapper.orderByDesc(QmsPqcTaskRecord::getCreateTime); + return buildPqcTaskPageData(request.getPage(), request.getPageSize(), queryWrapper); + } + + private PageData buildPqcTaskPageData(Integer pageNo, Integer pageSize, LambdaQueryWrapper queryWrapper) { Page page = pqcTaskRecordService.page( - new Page<>(request.getPage(), request.getPageSize()), + new Page<>(pageNo, pageSize), queryWrapper ); @@ -206,12 +264,29 @@ public class QmsPqcTaskRecordControllerService { } // 构建VO + Set taskIds = page.getRecords().stream() + .map(QmsPqcTaskRecord::getId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + Map ticketIdMap = new HashMap<>(); + if (!taskIds.isEmpty()) { + ticketIdMap = issueTicketService.lambdaQuery() + .eq(QmsIssueTicket::getSourceType, (short) 3) + .in(QmsIssueTicket::getSourceId, taskIds) + .list() + .stream() + .filter(ticket -> ticket.getSourceId() != null) + .collect(Collectors.toMap(QmsIssueTicket::getSourceId, QmsIssueTicket::getId, (first, second) -> first)); + } + Map finalPointMap = pointMap; Map finalRuleVersionMap = ruleVersionMap; + Map finalTicketIdMap = ticketIdMap; for (QmsPqcTaskRecord record : page.getRecords()) { QmsPqcTaskRecordPageVO vo = new QmsPqcTaskRecordPageVO(); vo.setId(record.getId()); + vo.setTicketId(finalTicketIdMap.get(record.getId())); vo.setTaskNo(record.getTaskNo()); vo.setModelNo(record.getModelNo()); vo.setNo(record.getNo()); @@ -244,6 +319,33 @@ public class QmsPqcTaskRecordControllerService { return pageData; } + private Set getUnqualifiedTaskIds() { + return pqcTaskRecordDetailsService.lambdaQuery() + .eq(QmsPqcTaskRecordDetails::getReviewEnable, false) + .select(QmsPqcTaskRecordDetails::getTaskId) + .list() + .stream() + .map(QmsPqcTaskRecordDetails::getTaskId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + } + + private Set findInspectionPointIdsByKeyword(String inspectionPointKeyword) { + if (StrUtil.isBlank(inspectionPointKeyword)) { + return Collections.emptySet(); + } + return pqcInspectionPointService.lambdaQuery() + .and(wrapper -> wrapper.like(QmsPqcInspectionPoint::getInspectionPointName, inspectionPointKeyword) + .or() + .like(QmsPqcInspectionPoint::getInspectionPointCode, inspectionPointKeyword)) + .select(QmsPqcInspectionPoint::getId) + .list() + .stream() + .map(QmsPqcInspectionPoint::getId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + } + public PageData searchPqcTaskTabletList(QmsPqcTaskRecordTabletSearchQO request) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); @@ -891,15 +993,11 @@ public class QmsPqcTaskRecordControllerService { } // 6. 检查不合格项,生成工单和新任务 - List generatedTicketNos = new ArrayList<>(); if (request.getEnable() != null && !request.getEnable()) { - // 情况2:复核提交且有不合格项,生成工单 - String ticketNo = handleUnqualifiedTask(taskRecord, request, currentUserId, currentUserName, now); - generatedTicketNos.add(ticketNo); - return SubmitResult.generatedTickets(generatedTicketNos); + pqcUnqualifiedTaskEventPublisher.publish(taskRecord.getId(), currentUserId, currentUserName); + return SubmitResult.unqualified(buildUnqualifiedItems(request)); } - // 情况3:通过且没有不合格项 return SubmitResult.success(); } @@ -1061,7 +1159,78 @@ public class QmsPqcTaskRecordControllerService { * 处理不合格任务:生成工单 * @return 生成的工单编号 */ - private String handleUnqualifiedTask(QmsPqcTaskRecord taskRecord, QmsPqcTaskRecordDraftQO request, + @Transactional(rollbackFor = Exception.class) + public void generateUnqualifiedTicketAsync(Long taskRecordId, Long currentUserId, String currentUserName) { + QmsPqcTaskRecord taskRecord = pqcTaskRecordService.getById(taskRecordId); + if (taskRecord == null) { + return; + } + handleUnqualifiedTask(taskRecord, currentUserId, currentUserName, LocalDateTime.now()); + } + + private List buildUnqualifiedItems(QmsPqcTaskRecordDraftQO request) { + List items = new ArrayList<>(); + if (request.getProcessInspections() != null) { + for (QmsPqcTaskRecordDraftQO.ProcessInspectionItem item : request.getProcessInspections()) { + if (Boolean.FALSE.equals(item.getEnable())) { + items.add(buildUnqualifiedItem(item)); + } + } + } + if (request.getProcessInspectionsLevel3() != null) { + for (QmsPqcTaskRecordDraftQO.ProcessInspectionLevel3Item item : request.getProcessInspectionsLevel3()) { + if (Boolean.FALSE.equals(item.getEnable())) { + items.add(buildUnqualifiedItem(item)); + } + } + } + return items; + } + + private QmsPqcUnqualifiedItemVO buildUnqualifiedItem(QmsPqcTaskRecordDraftQO.ProcessInspectionItem item) { + QmsPqcUnqualifiedItemVO vo = new QmsPqcUnqualifiedItemVO(); + vo.setInspectionContent(item.getInspectionContent()); + vo.setInspectionMethods(item.getInspectionMethods()); + vo.setInspectionLevel(item.getInspectionLevel()); + vo.setInspectionExampleImage(item.getInspectionExampleImage()); + vo.setSelfTestData(item.getSelfTestData()); + vo.setReviewData(item.getReviewData()); + vo.setEnable(item.getEnable()); + vo.setReviewOpinion(item.getReviewOpinion()); + vo.setSelfTestFiles(convertFiles(item.getSelfTestFiles())); + vo.setReviewFiles(convertFiles(item.getReviewFiles())); + return vo; + } + + private QmsPqcUnqualifiedItemVO buildUnqualifiedItem(QmsPqcTaskRecordDraftQO.ProcessInspectionLevel3Item item) { + QmsPqcUnqualifiedItemVO vo = new QmsPqcUnqualifiedItemVO(); + vo.setInspectionContent(item.getInspectionContent()); + vo.setInspectionMethods(item.getInspectionMethods()); + vo.setInspectionLevel(item.getInspectionLevel()); + vo.setInspectionExampleImage(item.getInspectionExampleImage()); + vo.setQcTestData(item.getQcTestData()); + vo.setEnable(item.getEnable()); + vo.setQcTestFiles(convertFiles(item.getQcTestFiles())); + return vo; + } + + private List convertFiles(List files) { + if (files == null || files.isEmpty()) { + return Collections.emptyList(); + } + List result = new ArrayList<>(); + for (QmsPqcTaskRecordDraftQO.FileItem file : files) { + QmsPqcTaskRecordDetailVO.FileDetailVO vo = new QmsPqcTaskRecordDetailVO.FileDetailVO(); + vo.setId(file.getId()); + vo.setFileName(file.getFileName()); + vo.setFileType(file.getFileType()); + vo.setUrl(file.getUrl()); + result.add(vo); + } + return result; + } + + private String handleUnqualifiedTask(QmsPqcTaskRecord taskRecord, Long currentUserId, String currentUserName, LocalDateTime now) { // 1. 生成工单(状态为0待流转) String ticketNo = basdeSerialNumberControllerService.generateSerialNumber(41); @@ -1317,7 +1486,7 @@ public class QmsPqcTaskRecordControllerService { */ public static class SubmitResult { /** - * 结果类型:1=空值,2=工单编号,3=成功 + * 结果类型:1=空值,3=成功 */ private Integer type; @@ -1325,12 +1494,12 @@ public class QmsPqcTaskRecordControllerService { * 空值明细列表(type=1时使用) */ private List emptyFields; - - /** - * 生成的工单编号列表(type=2时使用) - */ - private List ticketNos; + /** + * 不合格项列表(type=2时使用) + */ + private List unqualifiedItems; + public static SubmitResult emptyFields(List emptyFields) { SubmitResult result = new SubmitResult(); result.type = 1; @@ -1338,10 +1507,10 @@ public class QmsPqcTaskRecordControllerService { return result; } - public static SubmitResult generatedTickets(List ticketNos) { + public static SubmitResult unqualified(List unqualifiedItems) { SubmitResult result = new SubmitResult(); result.type = 2; - result.ticketNos = ticketNos; + result.unqualifiedItems = unqualifiedItems; return result; } @@ -1359,8 +1528,8 @@ public class QmsPqcTaskRecordControllerService { return emptyFields; } - public List getTicketNos() { - return ticketNos; + public List getUnqualifiedItems() { + return unqualifiedItems; } } } diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/QmsIssueTicketPqcAddQO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/QmsIssueTicketPqcAddQO.java new file mode 100644 index 00000000..052f0cb3 --- /dev/null +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/QmsIssueTicketPqcAddQO.java @@ -0,0 +1,58 @@ +package com.nflg.wms.common.pojo.qo; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.util.List; + +/** + * PQC检测工单新增参数 + */ +@Data +public class QmsIssueTicketPqcAddQO { + + /** + * PQC检测任务记录ID(QmsPqcTaskRecord.ID),存入工单的source_id + */ + @NotNull(message = "PQC检测任务记录ID不能为空") + private Long taskRecordId; + + /** + * 事故类型:0=一般,1=较严重,2=严重 + */ + @NotNull(message = "事故类型不能为空") + private Short incidentType; + + /** + * 备注 + */ + @NotNull(message = "备注不能为空") + private String remark; + + /** + * 处理人列表 + */ + @Valid + @NotEmpty(message = "处理人列表不能为空") + private List handlers; + + /** + * 处理人项 + */ + @Data + public static class HandlerItem { + /** + * PQC任务详情ID(qms_pqc_task_record_details.ID) + */ + @NotNull(message = "任务详情ID不能为空") + private Long taskResultId; + + /** + * 处理人用户ID + */ + @NotNull(message = "处理人用户ID不能为空") + private Long handlerUserId; + } +} diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/QmsPqcTaskRecordSearchQO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/QmsPqcTaskRecordSearchQO.java index c9b819fb..f5451074 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/QmsPqcTaskRecordSearchQO.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/QmsPqcTaskRecordSearchQO.java @@ -16,9 +16,9 @@ public class QmsPqcTaskRecordSearchQO { private String taskNo; /** - * 工序编号(检查点ID) + * 订单编号 */ - private Long inspectionPointId; + private String aufnr; /** * 机型编号 @@ -26,14 +26,24 @@ public class QmsPqcTaskRecordSearchQO { private String modelNo; /** - * 复核开始时间 + * 自检人 */ - private LocalDateTime reviewStartTime; + private String selfTesterName; /** - * 复核结束时间 + * 任务状态 */ - private LocalDateTime reviewEndTime; + private Short status; + + /** + * 创建开始时间 + */ + private LocalDateTime createStartTime; + + /** + * 创建结束时间 + */ + private LocalDateTime createEndTime; /** * 页码 diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/QmsPqcTaskRecordTabletSearchQO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/QmsPqcTaskRecordTabletSearchQO.java index 5a86203e..48c906b0 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/QmsPqcTaskRecordTabletSearchQO.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/QmsPqcTaskRecordTabletSearchQO.java @@ -1,22 +1,20 @@ package com.nflg.wms.common.pojo.qo; -import jakarta.validation.constraints.NotNull; import lombok.Data; /** - * PQC任务平板分页查询参数 + * PQC任务列表查询参数(平板端) */ @Data public class QmsPqcTaskRecordTabletSearchQO { /** - * 是否为复检 + * 是否查询复核任务,true=复核任务,false=返修自检任务 */ - @NotNull(message = "是否为复检不能为空") private Boolean isReview; /** - * 关键字,匹配检验单号或机型编号 + * 关键字,匹配任务编号/机型编号 */ private String key; diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/QmsPqcTaskRecordUnqualifiedSearchQO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/QmsPqcTaskRecordUnqualifiedSearchQO.java new file mode 100644 index 00000000..a6369397 --- /dev/null +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/QmsPqcTaskRecordUnqualifiedSearchQO.java @@ -0,0 +1,47 @@ +package com.nflg.wms.common.pojo.qo; + +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * PQC不合格任务列表查询参数 + */ +@Data +public class QmsPqcTaskRecordUnqualifiedSearchQO { + + /** + * 机型编号 + */ + private String modelNo; + + /** + * 检查点名称/编号 + */ + private String inspectionPointKeyword; + + /** + * 任务编号 + */ + private String taskNo; + + /** + * 复核开始时间 + */ + private LocalDateTime reviewStartTime; + + /** + * 复核结束时间 + */ + private LocalDateTime reviewEndTime; + + /** + * 页码 + */ + private Integer page = 1; + + /** + * 每页条数 + */ + private Integer pageSize = 10; +} diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/QmsPqcTaskRecordPageVO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/QmsPqcTaskRecordPageVO.java index 21c25fb7..bbf0aca9 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/QmsPqcTaskRecordPageVO.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/QmsPqcTaskRecordPageVO.java @@ -13,6 +13,11 @@ public class QmsPqcTaskRecordPageVO { */ private Long id; + /** + * 工单ID + */ + private Long ticketId; + /** * 任务编号 */ diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/QmsPqcTaskRecordTabletPageVO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/QmsPqcTaskRecordTabletPageVO.java index 093a28a7..801eb6a6 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/QmsPqcTaskRecordTabletPageVO.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/QmsPqcTaskRecordTabletPageVO.java @@ -5,7 +5,7 @@ import lombok.Data; import java.time.LocalDateTime; /** - * PQC任务平板分页返回对象 + * PQC任务列表返回对象(平板端) */ @Data public class QmsPqcTaskRecordTabletPageVO { @@ -15,11 +15,6 @@ public class QmsPqcTaskRecordTabletPageVO { */ private Long id; - /** - * 任务状态 - */ - private Short status; - /** * 任务编号 */ @@ -30,21 +25,26 @@ public class QmsPqcTaskRecordTabletPageVO { */ private String modelNo; - /** - * 步装名称 - */ - private String stepName; - /** * 订单编号 */ private String aufnr; + /** + * 步装名称 + */ + private String stepName; + /** * 检测标准版本 */ private Integer ruleVersion; + /** + * 任务状态 + */ + private Short status; + /** * 创建时间 */ diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/QmsPqcUnqualifiedItemVO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/QmsPqcUnqualifiedItemVO.java new file mode 100644 index 00000000..8d0615c2 --- /dev/null +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/QmsPqcUnqualifiedItemVO.java @@ -0,0 +1,72 @@ +package com.nflg.wms.common.pojo.vo; + +import lombok.Data; + +import java.util.List; + +/** + * PQC不合格检测项VO + */ +@Data +public class QmsPqcUnqualifiedItemVO { + + /** + * 检查内容 + */ + private String inspectionContent; + + /** + * 判定类型 + */ + private Integer inspectionMethods; + + /** + * 星级 + */ + private Integer inspectionLevel; + + /** + * 样例图 + */ + private String inspectionExampleImage; + + /** + * 自检数据 + */ + private String selfTestData; + + /** + * 复核数据 + */ + private String reviewData; + + /** + * QC检测数据 + */ + private String qcTestData; + + /** + * 检测结果 + */ + private Boolean enable; + + /** + * 复核意见 + */ + private String reviewOpinion; + + /** + * 自检附件 + */ + private List selfTestFiles; + + /** + * 复核附件 + */ + private List reviewFiles; + + /** + * QC检测附件 + */ + private List qcTestFiles; +}