feat(qms): 新增制程品质异常记录查询功能
- 在制程品质任务记录中,新增不合格项查询请求处理逻辑 - 同步更新质量管理系统后台对应控制器与服务层
This commit is contained in:
parent
0568d11adc
commit
1062ce5136
|
|
@ -100,6 +100,16 @@ public class QmsIssueTicketController extends BaseController {
|
|||
return ApiResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增PQC检测工单(平板使用)
|
||||
* 同步创建工单,异步创建工单处理记录
|
||||
*/
|
||||
@PostMapping("addPqcTicket")
|
||||
public ApiResult<Void> addPqcTicket(@Valid @RequestBody QmsIssueTicketPqcAddQO request) {
|
||||
issueTicketControllerService.addPqcTicket(request);
|
||||
return ApiResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* PDI新建工单并返回不合格检测项
|
||||
* 1. 创建工单
|
||||
|
|
|
|||
|
|
@ -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<PageData<QmsPqcTaskRecordPageVO>> search(@RequestBody QmsPqcTaskRecordSearchQO request) {
|
||||
return ApiResult.success(pqcTaskRecordService.searchPqcTaskList(request));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询PQC不合格任务列表(分页)
|
||||
*/
|
||||
@PostMapping("/search/unqualified")
|
||||
public ApiResult<PageData<QmsPqcTaskRecordPageVO>> 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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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)));
|
||||
}
|
||||
}
|
||||
|
|
@ -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<Long> requestedDetailIds = request.getHandlers().stream()
|
||||
.map(QmsIssueTicketPqcAddQO.HandlerItem::getTaskResultId)
|
||||
.filter(Objects::nonNull)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
if (requestedDetailIds.isEmpty()) {
|
||||
throw new NflgException(STATE.BusinessError, "不合格项不能为空");
|
||||
}
|
||||
|
||||
List<QmsPqcTaskRecordDetails> detailList = pqcTaskRecordDetailsService.lambdaQuery()
|
||||
.eq(QmsPqcTaskRecordDetails::getTaskId, request.getTaskRecordId())
|
||||
.in(QmsPqcTaskRecordDetails::getId, requestedDetailIds)
|
||||
.list();
|
||||
if (detailList.size() != requestedDetailIds.size()) {
|
||||
throw new NflgException(STATE.BusinessError, "存在无效的不合格项");
|
||||
}
|
||||
|
||||
List<QmsPqcTaskRecordDetails> 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<Long> unqualifiedDetailIds = unqualifiedDetails.stream()
|
||||
.map(QmsPqcTaskRecordDetails::getId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
Map<Long, List<Long>> handlerToResultsMap = request.getHandlers().stream()
|
||||
.collect(Collectors.groupingBy(
|
||||
QmsIssueTicketPqcAddQO.HandlerItem::getHandlerUserId,
|
||||
Collectors.mapping(QmsIssueTicketPqcAddQO.HandlerItem::getTaskResultId, Collectors.toList())
|
||||
));
|
||||
|
||||
for (Map.Entry<Long, List<Long>> entry : handlerToResultsMap.entrySet()) {
|
||||
List<Long> 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<QmsPqcTaskRecordDetails> detailList) {
|
||||
if (CollectionUtil.isEmpty(detailList)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
List<Long> itemIds = detailList.stream()
|
||||
.map(QmsPqcTaskRecordDetails::getInspectionPointItemId)
|
||||
.filter(Objects::nonNull)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
Map<Long, QmsPqcInspectionPointItems> 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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询来料检测任务质量问题工单详情
|
||||
* 包含图片文件信息、来料检测任务详情、检验记录(含子项和样本数据)
|
||||
|
|
|
|||
|
|
@ -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<QmsPqcTaskRecordPageVO> searchPqcTaskList(QmsPqcTaskRecordSearchQO request) {
|
||||
LambdaQueryWrapper<QmsPqcTaskRecord> queryWrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
// 条件过滤
|
||||
Set<Long> 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<QmsPqcTaskRecordPageVO> searchPqcTaskUnqualifiedList(QmsPqcTaskRecordUnqualifiedSearchQO request) {
|
||||
LambdaQueryWrapper<QmsPqcTaskRecord> queryWrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
Set<Long> unqualifiedTaskIds = getUnqualifiedTaskIds();
|
||||
Set<Long> 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<QmsPqcTaskRecordPageVO> buildPqcTaskPageData(Integer pageNo, Integer pageSize, LambdaQueryWrapper<QmsPqcTaskRecord> queryWrapper) {
|
||||
Page<QmsPqcTaskRecord> page = pqcTaskRecordService.page(
|
||||
new Page<>(request.getPage(), request.getPageSize()),
|
||||
new Page<>(pageNo, pageSize),
|
||||
queryWrapper
|
||||
);
|
||||
|
||||
|
|
@ -206,12 +264,29 @@ public class QmsPqcTaskRecordControllerService {
|
|||
}
|
||||
|
||||
// 构建VO
|
||||
Set<Long> taskIds = page.getRecords().stream()
|
||||
.map(QmsPqcTaskRecord::getId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
Map<Long, Long> 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<Long, QmsPqcInspectionPoint> finalPointMap = pointMap;
|
||||
Map<String, Integer> finalRuleVersionMap = ruleVersionMap;
|
||||
Map<Long, Long> 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<Long> getUnqualifiedTaskIds() {
|
||||
return pqcTaskRecordDetailsService.lambdaQuery()
|
||||
.eq(QmsPqcTaskRecordDetails::getReviewEnable, false)
|
||||
.select(QmsPqcTaskRecordDetails::getTaskId)
|
||||
.list()
|
||||
.stream()
|
||||
.map(QmsPqcTaskRecordDetails::getTaskId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
private Set<Long> 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<QmsPqcTaskRecordTabletPageVO> searchPqcTaskTabletList(QmsPqcTaskRecordTabletSearchQO request) {
|
||||
LambdaQueryWrapper<QmsPqcTaskRecord> queryWrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
|
|
@ -891,15 +993,11 @@ public class QmsPqcTaskRecordControllerService {
|
|||
}
|
||||
|
||||
// 6. 检查不合格项,生成工单和新任务
|
||||
List<String> 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<QmsPqcUnqualifiedItemVO> buildUnqualifiedItems(QmsPqcTaskRecordDraftQO request) {
|
||||
List<QmsPqcUnqualifiedItemVO> 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<QmsPqcTaskRecordDetailVO.FileDetailVO> convertFiles(List<QmsPqcTaskRecordDraftQO.FileItem> files) {
|
||||
if (files == null || files.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<QmsPqcTaskRecordDetailVO.FileDetailVO> 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<String> emptyFields;
|
||||
|
||||
/**
|
||||
* 生成的工单编号列表(type=2时使用)
|
||||
*/
|
||||
private List<String> ticketNos;
|
||||
|
||||
/**
|
||||
* 不合格项列表(type=2时使用)
|
||||
*/
|
||||
private List<QmsPqcUnqualifiedItemVO> unqualifiedItems;
|
||||
|
||||
public static SubmitResult emptyFields(List<String> emptyFields) {
|
||||
SubmitResult result = new SubmitResult();
|
||||
result.type = 1;
|
||||
|
|
@ -1338,10 +1507,10 @@ public class QmsPqcTaskRecordControllerService {
|
|||
return result;
|
||||
}
|
||||
|
||||
public static SubmitResult generatedTickets(List<String> ticketNos) {
|
||||
public static SubmitResult unqualified(List<QmsPqcUnqualifiedItemVO> 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<String> getTicketNos() {
|
||||
return ticketNos;
|
||||
public List<QmsPqcUnqualifiedItemVO> getUnqualifiedItems() {
|
||||
return unqualifiedItems;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<HandlerItem> 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
||||
/**
|
||||
* 页码
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -13,6 +13,11 @@ public class QmsPqcTaskRecordPageVO {
|
|||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 工单ID
|
||||
*/
|
||||
private Long ticketId;
|
||||
|
||||
/**
|
||||
* 任务编号
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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<QmsPqcTaskRecordDetailVO.FileDetailVO> selfTestFiles;
|
||||
|
||||
/**
|
||||
* 复核附件
|
||||
*/
|
||||
private List<QmsPqcTaskRecordDetailVO.FileDetailVO> reviewFiles;
|
||||
|
||||
/**
|
||||
* QC检测附件
|
||||
*/
|
||||
private List<QmsPqcTaskRecordDetailVO.FileDetailVO> qcTestFiles;
|
||||
}
|
||||
Loading…
Reference in New Issue