feat(qms-issue-ticket): 新增发起巡检工单接口及相关逻辑

- 新增QmsIssueTicketDispatchQO请求参数类,包含工单ID及负责人ID
- 在QmsIssueTicketController中添加dispatch接口,实现发起巡检工单功能
- 在QmsIssueTicketControllerService中实现dispatch方法
- dispatch方法校验工单存在且来源类型为巡检,校验负责人存在
- 更新工单状态为处理中,设置审批人信息及审批时间
- 优化工单标题生成逻辑,避免空指针,使用字符串拼接替代StrUtil.join
- 完善PDI检测结果处理中图片及示例图的查询与关联
- 从检测规则状态项中提取部件描述、检查内容及示例图,提升检测结果展示准确性
This commit is contained in:
funny 2026-05-09 18:05:25 +08:00
parent 495d8fa6c2
commit 0a20db31f1
3 changed files with 149 additions and 6 deletions

View File

@ -40,6 +40,16 @@ public class QmsIssueTicketController extends BaseController {
return ApiResult.success();
}
/**
* 发起巡检工单
* 将工单状态改为处理中并设置负责人为审批人
*/
@PostMapping("dispatch")
public ApiResult<Void> dispatch(@Valid @RequestBody QmsIssueTicketDispatchQO request) {
issueTicketControllerService.dispatch(request);
return ApiResult.success();
}
/**
* 新增PDI检测工单(平板使用)
* 同步创建工单异步创建工单处理记录

View File

@ -74,6 +74,41 @@ public class QmsIssueTicketControllerService {
@Resource
private WmsIncomingInspectionTaskCallbackService wmsIncomingInspectionTaskCallbackService;
/**
* 发起巡检工单
* 1. 校验工单存在且来源类型为巡检sourceType=2
* 2. 校验负责人存在
* 3. 更新工单状态为处理中status=1
* 4. 设置审批人ID和姓名
*/
@Transactional(rollbackFor = Exception.class)
public void dispatch(@Valid QmsIssueTicketDispatchQO request) {
// 1. 校验工单存在
QmsIssueTicket ticket = issueTicketService.getById(request.getId());
VUtil.trueThrowBusinessError(Objects.isNull(ticket)).throwMessage("工单不存在");
// 2. 校验工单来源类型为巡检
if (!Objects.equals(ticket.getSourceType(), (short) 2)) {
throw new NflgException(STATE.BusinessError, "只能发起巡检工单");
}
// 3. 校验负责人存在
User handlerUser = userService.getById(request.getHandlerUserId());
VUtil.trueThrowBusinessError(Objects.isNull(handlerUser)).throwMessage("负责人不存在");
// 4. 更新工单状态和审批人信息
issueTicketService.lambdaUpdate()
.eq(QmsIssueTicket::getId, request.getId())
.set(QmsIssueTicket::getStatus, (short) 1) // 状态1=处理中
.set(QmsIssueTicket::getApprovalUserId, request.getHandlerUserId())
.set(QmsIssueTicket::getApprovalUserName, handlerUser.getUserName())
.set(QmsIssueTicket::getApprovalTime, LocalDateTime.now())
.set(QmsIssueTicket::getUpdateUserId, UserUtil.getUserId())
.set(QmsIssueTicket::getUpdateUserName, UserUtil.getUserName())
.set(QmsIssueTicket::getUpdateTime, LocalDateTime.now())
.update();
}
@Resource
private IQmsIssueTicketProcessService issueTicketProcessService;
@ -123,11 +158,18 @@ public class QmsIssueTicketControllerService {
// 4. 生成工单标题
String ticketTitle;
if (Objects.equals(rules.getInspectionType(), 0)) {
ticketTitle = StrUtil.join("-", rules.getMachineNo(), taskRecord.getDeviceNo(),
taskRecord.getOrderNo(), "出厂检验", rules.getInspectionVersion());
// 新机检测机型编号-机台号-订单编号-出厂检验-检测版本号
String machineNo = rules.getMachineNo() != null ? rules.getMachineNo() : "";
String deviceNo = taskRecord.getDeviceNo() != null ? taskRecord.getDeviceNo() : "";
String orderNo = taskRecord.getOrderNo() != null ? taskRecord.getOrderNo() : "";
String version = rules.getInspectionVersion() != null ? rules.getInspectionVersion() : "";
ticketTitle = machineNo + "-" + deviceNo + "-" + orderNo + "-出厂检验-" + version;
} else {
ticketTitle = StrUtil.join("-", rules.getMachineNo(),
taskRecord.getOrderNo(), "库存检验", rules.getInspectionVersion());
// 库存检测机型编号-订单编号-库存检验-检测版本号
String machineNo = rules.getMachineNo() != null ? rules.getMachineNo() : "";
String orderNo = taskRecord.getOrderNo() != null ? taskRecord.getOrderNo() : "";
String version = rules.getInspectionVersion() != null ? rules.getInspectionVersion() : "";
ticketTitle = machineNo + "-" + orderNo + "-库存检验-" + version;
}
// 5. 查询所有不合格项汇总生成incidentDescription
@ -208,7 +250,25 @@ public class QmsIssueTicketControllerService {
return null;
}
// 收集所有图片ID
// 收集所有检验项ID仅查询type=0/1/3的这些有componentsDes等字段
List<Long> statusItemIds = failedItems.stream()
.filter(item -> item.getInspectionItemType() != null && item.getInspectionItemType() != 2)
.map(QmsPdiInspectionResults::getInspectionItemId)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
// 查询检测规则状态项信息
Map<Long, QmsPdiDetectionRulesStatusItem> statusItemMap = new HashMap<>();
if (!statusItemIds.isEmpty()) {
List<QmsPdiDetectionRulesStatusItem> statusItems = pdiStatusItemService.lambdaQuery()
.in(QmsPdiDetectionRulesStatusItem::getId, statusItemIds)
.list();
statusItemMap = statusItems.stream()
.collect(Collectors.toMap(QmsPdiDetectionRulesStatusItem::getId, item -> item, (a, b) -> a));
}
// 收集所有图片ID检测结果图片
Set<Long> imageIds = failedItems.stream()
.map(QmsPdiInspectionResults::getInspectionItemImage)
.filter(StrUtil::isNotBlank)
@ -217,6 +277,18 @@ public class QmsIssueTicketControllerService {
.map(Long::valueOf)
.collect(Collectors.toSet());
// 收集所有示例图ID状态项中的示例图
Set<Long> exampleImageIds = statusItemMap.values().stream()
.map(QmsPdiDetectionRulesStatusItem::getInspectionImage)
.filter(StrUtil::isNotBlank)
.flatMap(imageStr -> Arrays.stream(imageStr.split(",")))
.filter(StrUtil::isNotBlank)
.map(Long::valueOf)
.collect(Collectors.toSet());
// 合并所有图片ID
imageIds.addAll(exampleImageIds);
// 查询图片文件信息
Map<Long, FileUploadRecord> imageMap = new HashMap<>();
if (!imageIds.isEmpty()) {
@ -229,6 +301,8 @@ public class QmsIssueTicketControllerService {
// 构建返回值
final Map<Long, FileUploadRecord> finalImageMap = imageMap;
final Map<Long, QmsPdiDetectionRulesStatusItem> finalStatusItemMap = statusItemMap;
return failedItems.stream().map(item -> {
QmsPdiInspectionResultVO vo = new QmsPdiInspectionResultVO();
vo.setId(item.getId());
@ -242,7 +316,43 @@ public class QmsIssueTicketControllerService {
vo.setInspectionTime(item.getInspectionTime());
vo.setInspectionBy(item.getInspectionBy());
// 解析图片为 FileDetailVO 列表
// 从检测规则状态项中获取部件描述检查核实内容检测示例图
// 仅type=0/1/3有这些字段type=2装车前没有
if (item.getInspectionItemType() != null && item.getInspectionItemType() != 2) {
QmsPdiDetectionRulesStatusItem statusItem = finalStatusItemMap.get(item.getInspectionItemId());
if (statusItem != null) {
vo.setComponentsDes(statusItem.getComponentsDes());
vo.setInspectionContent(statusItem.getInspectionContent());
// 解析检测示例图
if (StrUtil.isNotBlank(statusItem.getInspectionImage())) {
List<QmsPdiTaskRecordDetailVO.FileDetailVO> exampleImageList = Arrays.stream(statusItem.getInspectionImage().split(","))
.filter(StrUtil::isNotBlank)
.map(String::trim)
.map(Long::valueOf)
.map(id -> {
FileUploadRecord record = finalImageMap.get(id);
if (record != null) {
QmsPdiTaskRecordDetailVO.FileDetailVO fileVO = new QmsPdiTaskRecordDetailVO.FileDetailVO();
fileVO.setId(record.getId());
fileVO.setFileName(record.getFileName());
fileVO.setFileType(record.getFileType());
fileVO.setUrl(record.getUrl());
return fileVO;
}
return null;
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
// 取第一张图片的URL作为示例图
if (!exampleImageList.isEmpty()) {
vo.setInspectionExampleImage(exampleImageList.get(0).getUrl());
}
}
}
}
// 解析检验现场图片为 FileDetailVO 列表
if (StrUtil.isNotBlank(item.getInspectionItemImage())) {
List<QmsPdiTaskRecordDetailVO.FileDetailVO> imageList = Arrays.stream(item.getInspectionItemImage().split(","))
.filter(StrUtil::isNotBlank)

View File

@ -0,0 +1,23 @@
package com.nflg.wms.common.pojo.qo;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* 发起巡检工单请求参数
*/
@Data
public class QmsIssueTicketDispatchQO {
/**
* 工单IDqms_issue_ticket.id
*/
@NotNull(message = "工单ID不能为空")
private Long id;
/**
* 负责人IDuser表里的id
*/
@NotNull(message = "负责人ID不能为空")
private Long handlerUserId;
}