Merge remote-tracking branch '惠信/qms/develop' into qms/develop

This commit is contained in:
曹鹏飞 2026-06-13 15:50:23 +08:00
commit e373b39379
4 changed files with 107 additions and 210 deletions

View File

@ -21,7 +21,15 @@ import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
@ -41,7 +49,7 @@ public class QmsPdiComponentBindingControllerService {
private final IFileUploadRecordService fileUploadRecordService;
/**
* 保存PDI部件绑定PDI标准检测规则整单覆盖
* 保存PDI部件绑定当前图片覆盖重建
*/
@Transactional
public void save(QmsPdiComponentBindingSaveQO request) {
@ -49,35 +57,34 @@ public class QmsPdiComponentBindingControllerService {
componentBindingService.lambdaUpdate()
.eq(QmsPdiComponentBinding::getPdiDetectionRulesId, request.getPdiDetectionRulesId())
.eq(QmsPdiComponentBinding::getUploadImageId, request.getUploadImageId())
.remove();
List<QmsPdiComponentBinding> bindings = new ArrayList<>();
for (QmsPdiComponentBindingSaveQO.ImageBindingQO image : request.getItems()) {
boolean hasComponentBinding = false;
if (CollectionUtil.isEmpty(image.getComponents())) {
bindings.add(new QmsPdiComponentBinding()
.setPdiDetectionRulesId(request.getPdiDetectionRulesId())
.setUploadImageId(image.getUploadImageId()));
continue;
}
if (CollectionUtil.isEmpty(request.getComponents())) {
return;
}
for (QmsPdiComponentBindingSaveQO.ComponentBindingQO component : image.getComponents()) {
if (component.getPdiComponentId() == null) {
continue;
}
hasComponentBinding = true;
Set<String> componentNames = request.getComponents().stream()
.map(QmsPdiComponentBindingSaveQO.ComponentBindingQO::getComponentName)
.filter(StrUtil::isNotBlank)
.collect(Collectors.toSet());
Map<String, List<QmsPdiComponentAnagement>> componentMap =
getComponentMapByName(request.getPdiDetectionRulesId(), componentNames);
List<QmsPdiComponentBinding> bindings = new ArrayList<>();
for (QmsPdiComponentBindingSaveQO.ComponentBindingQO component : request.getComponents()) {
List<QmsPdiComponentAnagement> matchedComponents = componentMap.get(component.getComponentName());
if (CollectionUtil.isEmpty(matchedComponents)) {
throw new NflgException(STATE.BusinessError, "部件名称不存在:" + component.getComponentName());
}
for (QmsPdiComponentAnagement matchedComponent : matchedComponents) {
bindings.add(new QmsPdiComponentBinding()
.setPdiDetectionRulesId(request.getPdiDetectionRulesId())
.setUploadImageId(image.getUploadImageId())
.setPdiComponentId(component.getPdiComponentId())
.setUploadImageId(request.getUploadImageId())
.setPdiComponentId(matchedComponent.getId())
.setXCoordinatePoint(component.getXCoordinatePoint())
.setYCoordinatePoint(component.getYCoordinatePoint())
.setStatus(component.getStatus()));
}
if (!hasComponentBinding) {
bindings.add(new QmsPdiComponentBinding()
.setPdiDetectionRulesId(request.getPdiDetectionRulesId())
.setUploadImageId(image.getUploadImageId()));
.setStatus(matchedComponent.getStatus()));
}
}
@ -87,7 +94,7 @@ public class QmsPdiComponentBindingControllerService {
}
/**
* 查询PDI部件绑定
* 查询PDI部件绑定
*/
public QmsPdiComponentBindingSearchVO search(Long pdiDetectionRulesId) {
QmsPdiComponentBindingSearchVO vo = new QmsPdiComponentBindingSearchVO();
@ -156,21 +163,10 @@ public class QmsPdiComponentBindingControllerService {
}
/**
* 分页查询标准检测中已有检测项的部件同名静态/动态部件合并返回
* 分页查询标准检测中已有检测项的部件返回去重后的部件名称
*/
public PageData<QmsPdiComponentBindingComponentVO> searchComponents(QmsPdiComponentBindingComponentSearchQO request) {
List<Long> componentIds = statusItemService.lambdaQuery()
.select(QmsPdiDetectionRulesStatusItem::getComponentsId)
.eq(QmsPdiDetectionRulesStatusItem::getDetectionRulesId, request.getDetectionRulesId())
.in(QmsPdiDetectionRulesStatusItem::getStatus, (int) STATIC_STATUS, (int) DYNAMIC_STATUS)
.isNotNull(QmsPdiDetectionRulesStatusItem::getComponentsId)
.list()
.stream()
.map(QmsPdiDetectionRulesStatusItem::getComponentsId)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
List<Long> componentIds = getUsedComponentIds(request.getDetectionRulesId());
if (CollectionUtil.isEmpty(componentIds)) {
return pageComponents(request, List.of());
}
@ -180,109 +176,79 @@ public class QmsPdiComponentBindingControllerService {
.in(QmsPdiComponentAnagement::getId, componentIds)
.list();
components.sort(Comparator
.comparing(QmsPdiComponentAnagement::getSort, Comparator.nullsLast(Integer::compareTo))
.thenComparing(QmsPdiComponentAnagement::getComponentName, Comparator.nullsLast(String::compareTo))
.thenComparing(QmsPdiComponentAnagement::getStatus, Comparator.nullsLast(Short::compareTo))
.thenComparing(QmsPdiComponentAnagement::getId, Comparator.nullsLast(Long::compareTo)));
Map<String, QmsPdiComponentBindingComponentVO> groupMap = new LinkedHashMap<>();
Map<String, Integer> sortMap = new LinkedHashMap<>();
for (QmsPdiComponentAnagement component : components) {
String componentName = component.getComponentName();
QmsPdiComponentBindingComponentVO groupVO = groupMap.computeIfAbsent(componentName, name -> {
QmsPdiComponentBindingComponentVO vo = new QmsPdiComponentBindingComponentVO();
vo.setComponentName(name);
vo.setSort(component.getSort());
return vo;
});
if (groupVO.getSort() == null
|| (component.getSort() != null && component.getSort() < groupVO.getSort())) {
groupVO.setSort(component.getSort());
Integer currentSort = sortMap.get(componentName);
if (!sortMap.containsKey(componentName)
|| currentSort == null
|| (component.getSort() != null && component.getSort() < currentSort)) {
sortMap.put(componentName, component.getSort());
}
QmsPdiComponentBindingComponentVO.ComponentStatusVO statusVO =
new QmsPdiComponentBindingComponentVO.ComponentStatusVO();
statusVO.setComponentId(component.getId());
statusVO.setStatus(component.getStatus());
statusVO.setStatusName(getStatusName(component.getStatus()));
groupVO.getComponents().add(statusVO);
}
List<QmsPdiComponentBindingComponentVO> groupedComponents = new ArrayList<>(groupMap.values());
groupedComponents.forEach(group -> group.getComponents().sort(Comparator
.comparing(QmsPdiComponentBindingComponentVO.ComponentStatusVO::getStatus, Comparator.nullsLast(Short::compareTo))
.thenComparing(QmsPdiComponentBindingComponentVO.ComponentStatusVO::getComponentId, Comparator.nullsLast(Long::compareTo))));
groupedComponents.sort(Comparator
.comparing(QmsPdiComponentBindingComponentVO::getSort, Comparator.nullsLast(Integer::compareTo))
.thenComparing(QmsPdiComponentBindingComponentVO::getComponentName, Comparator.nullsLast(String::compareTo)));
List<QmsPdiComponentBindingComponentVO> groupedComponents = sortMap.entrySet().stream()
.sorted(Map.Entry.<String, Integer>comparingByValue(Comparator.nullsLast(Integer::compareTo))
.thenComparing(Map.Entry.comparingByKey(Comparator.nullsLast(String::compareTo))))
.map(entry -> {
QmsPdiComponentBindingComponentVO vo = new QmsPdiComponentBindingComponentVO();
vo.setComponentName(entry.getKey());
return vo;
})
.collect(Collectors.toList());
return pageComponents(request, groupedComponents);
}
private void validateSaveRequest(QmsPdiComponentBindingSaveQO request) {
Set<Long> imageIds = request.getItems().stream()
.peek(image -> {
if (image == null) {
throw new NflgException(STATE.BusinessError, "图片绑定对象不能为空");
}
})
.map(QmsPdiComponentBindingSaveQO.ImageBindingQO::getUploadImageId)
.collect(Collectors.toSet());
List<FileUploadRecord> images = fileUploadRecordService.listByIds(imageIds);
if (images.size() != imageIds.size()) {
if (fileUploadRecordService.getById(request.getUploadImageId()) == null) {
throw new NflgException(STATE.BusinessError, "上传图片不存在");
}
Set<Long> componentIds = new HashSet<>();
Map<String, Set<Short>> coordinateStatusMap = new HashMap<>();
for (QmsPdiComponentBindingSaveQO.ImageBindingQO image : request.getItems()) {
if (CollectionUtil.isEmpty(image.getComponents())) {
continue;
}
for (QmsPdiComponentBindingSaveQO.ComponentBindingQO component : image.getComponents()) {
if (component == null) {
throw new NflgException(STATE.BusinessError, "部件绑定对象不能为空");
}
if (component.getPdiComponentId() == null) {
if (hasBindingValue(component)) {
throw new NflgException(STATE.BusinessError, "部件ID为空时不能传入坐标或状态");
}
continue;
}
if (StrUtil.isBlank(component.getXCoordinatePoint()) || StrUtil.isBlank(component.getYCoordinatePoint())) {
throw new NflgException(STATE.BusinessError, "绑定部件时x轴坐标和y轴坐标不能为空");
}
if (!isAllowedStatus(component.getStatus())) {
throw new NflgException(STATE.BusinessError, "状态只能为0静态或1动态");
}
componentIds.add(component.getPdiComponentId());
String coordinateKey = coordinateKey(image.getUploadImageId(), component.getXCoordinatePoint(), component.getYCoordinatePoint());
Set<Short> statuses = coordinateStatusMap.computeIfAbsent(coordinateKey, key -> new HashSet<>());
if (!statuses.add(component.getStatus())) {
throw new NflgException(STATE.BusinessError, "同一图片同一坐标不能重复绑定相同状态");
}
if (statuses.size() > 2) {
throw new NflgException(STATE.BusinessError, "同一图片同一坐标最多绑定一个静态和一个动态部件");
}
}
}
if (CollectionUtil.isEmpty(componentIds)) {
if (CollectionUtil.isEmpty(request.getComponents())) {
return;
}
for (QmsPdiComponentBindingSaveQO.ComponentBindingQO component : request.getComponents()) {
if (component == null) {
throw new NflgException(STATE.BusinessError, "部件绑定对象不能为空");
}
if (StrUtil.isBlank(component.getComponentName())) {
throw new NflgException(STATE.BusinessError, "部件名称不能为空");
}
if (StrUtil.isBlank(component.getXCoordinatePoint()) || StrUtil.isBlank(component.getYCoordinatePoint())) {
throw new NflgException(STATE.BusinessError, "绑定部件时x轴坐标和y轴坐标不能为空");
}
}
}
Set<Long> validComponentIds = componentService.lambdaQuery()
.select(QmsPdiComponentAnagement::getId)
.eq(QmsPdiComponentAnagement::getDetectionRulesId, request.getPdiDetectionRulesId())
private Map<String, List<QmsPdiComponentAnagement>> getComponentMapByName(Long detectionRulesId, Set<String> componentNames) {
if (CollectionUtil.isEmpty(componentNames)) {
return Collections.emptyMap();
}
List<Long> componentIds = getUsedComponentIds(detectionRulesId);
if (CollectionUtil.isEmpty(componentIds)) {
return Collections.emptyMap();
}
return componentService.lambdaQuery()
.eq(QmsPdiComponentAnagement::getDetectionRulesId, detectionRulesId)
.in(QmsPdiComponentAnagement::getId, componentIds)
.in(QmsPdiComponentAnagement::getComponentName, componentNames)
.list()
.stream()
.map(QmsPdiComponentAnagement::getId)
.collect(Collectors.toSet());
if (validComponentIds.size() != componentIds.size()) {
throw new NflgException(STATE.BusinessError, "存在不属于当前PDI标准检测规则的部件");
}
.collect(Collectors.groupingBy(QmsPdiComponentAnagement::getComponentName, LinkedHashMap::new, Collectors.toList()));
}
private List<Long> getUsedComponentIds(Long detectionRulesId) {
return statusItemService.lambdaQuery()
.select(QmsPdiDetectionRulesStatusItem::getComponentsId)
.eq(QmsPdiDetectionRulesStatusItem::getDetectionRulesId, detectionRulesId)
.in(QmsPdiDetectionRulesStatusItem::getStatus, (int) STATIC_STATUS, (int) DYNAMIC_STATUS)
.isNotNull(QmsPdiDetectionRulesStatusItem::getComponentsId)
.list()
.stream()
.map(QmsPdiDetectionRulesStatusItem::getComponentsId)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
}
private Map<Long, FileUploadRecord> getImageMap(List<QmsPdiComponentBinding> bindings) {
@ -361,30 +327,10 @@ public class QmsPdiComponentBindingControllerService {
return status != null && (status == STATIC_STATUS || status == DYNAMIC_STATUS);
}
private boolean hasBindingValue(QmsPdiComponentBindingSaveQO.ComponentBindingQO component) {
return StrUtil.isNotBlank(component.getXCoordinatePoint())
|| StrUtil.isNotBlank(component.getYCoordinatePoint())
|| component.getStatus() != null;
}
private String coordinateKey(Long uploadImageId, String xCoordinatePoint, String yCoordinatePoint) {
return uploadImageId + "|" + xCoordinatePoint + "|" + yCoordinatePoint;
}
private String componentStatusKey(Long componentId, Short status) {
return componentId + "|" + status;
}
private String getStatusName(Short status) {
if (Objects.equals(status, STATIC_STATUS)) {
return "静态";
}
if (Objects.equals(status, DYNAMIC_STATUS)) {
return "动态";
}
return null;
}
private PageData<QmsPdiComponentBindingComponentVO> pageComponents(
QmsPdiComponentBindingComponentSearchQO request,
List<QmsPdiComponentBindingComponentVO> components) {

View File

@ -1,16 +1,15 @@
package com.nflg.wms.common.pojo.qo;
import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.List;
/**
* PDI部件绑定 保存请求参数
* PDI部件绑定保存请求参数
*/
@Data
public class QmsPdiComponentBindingSaveQO {
@ -23,55 +22,39 @@ public class QmsPdiComponentBindingSaveQO {
private Long pdiDetectionRulesId;
/**
* 图片绑定列表
* 上传图片ID
*/
@NotNull(message = "上传图片ID不能为空")
@JsonAlias("upload_image_id")
private Long uploadImageId;
/**
* 部件绑定列表
*/
@Valid
@NotEmpty(message = "图片绑定列表不能为空")
private List<ImageBindingQO> items;
@Data
public static class ImageBindingQO {
/**
* 上传图片的ID
*/
@NotNull(message = "上传图片ID不能为空")
@JsonAlias("upload_image_id")
private Long uploadImageId;
/**
* 部件绑定列表
*/
@Valid
private List<ComponentBindingQO> components;
}
private List<ComponentBindingQO> components;
@Data
public static class ComponentBindingQO {
/**
* 部件ID
* 部件名称
*/
@JsonAlias("pdi_component_id")
private Long pdiComponentId;
@NotBlank(message = "部件名称不能为空")
private String componentName;
/**
* x轴坐标
*/
@JsonProperty("xCoordinatePoint")
@NotBlank(message = "x轴坐标不能为空")
@JsonAlias({"x_coordinate_point", "XCoordinatePoint"})
private String xCoordinatePoint;
/**
* y轴坐标
*/
@JsonProperty("yCoordinatePoint")
@NotBlank(message = "y轴坐标不能为空")
@JsonAlias({"y_coordinate_point", "YCoordinatePoint"})
private String yCoordinatePoint;
/**
* 状态0为静态1为动态
*/
private Short status;
}
}

View File

@ -2,9 +2,6 @@ package com.nflg.wms.common.pojo.vo;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* PDI部件绑定-标准检测部件分页查询返回值
*/
@ -15,33 +12,4 @@ public class QmsPdiComponentBindingComponentVO {
* 部件名称
*/
private String componentName;
/**
* 部件排序
*/
private Integer sort;
/**
* 同名部件下不同检测状态的部件ID
*/
private List<ComponentStatusVO> components = new ArrayList<>();
@Data
public static class ComponentStatusVO {
/**
* 部件ID
*/
private Long componentId;
/**
* 状态0=静态1=动态
*/
private Short status;
/**
* 状态名称
*/
private String statusName;
}
}

View File

@ -12,7 +12,7 @@
t.warehouse_no AS warehouseNo,
r.inspection_type AS inspectionType,
r.inspection_version AS inspectionVersion,
r.model_no AS machineNo,
r.model_no AS modelNo,
t.inspection_enable AS inspectionEnable,
t.inspection_inspection AS inspectionInspection,
ui.user_name AS inspectorName,
@ -75,7 +75,7 @@
t.warehouse_no AS warehouseNo,
r.inspection_type AS inspectionType,
r.inspection_version AS inspectionVersion,
r.model_no AS machineNo,
r.model_no AS modelNo,
t.inspection_enable AS inspectionEnable,
t.inspection_inspection AS inspectionInspection,
ui.user_name AS inspectorName,