mirror of
https://gitee.com/zhijiantianya/ruoyi-vue-pro.git
synced 2026-07-08 22:40:32 +08:00
✨ feat(validation): 增加字段长度限制和必填校验
在多个请求对象中添加了字段长度限制和必填校验,以确保数据的有效性和一致性。具体修改包括: - MesTmToolTypeSaveReqVO 和 MesTmToolSaveReqVO 中的 code 和 name 字段增加长度限制 - MesWmItemConsumeLinePageReqVO 中的 feedbackId 字段增加必填校验 - MesMdWorkstationToolService 中新增获取指定工具类型工装夹具资源数量的方法 - ErrorCodeConstants 中新增工具类型被工作站工装资源引用的错误码 这些改动旨在提升数据的完整性和系统的健壮性
This commit is contained in:
@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.mes.controller.admin.tm.tool.vo;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
@ -16,16 +17,20 @@ public class MesTmToolSaveReqVO {
|
||||
|
||||
@Schema(description = "工具编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "T-001")
|
||||
@NotEmpty(message = "工具编码不能为空")
|
||||
@Size(max = 64, message = "工具编码长度不能超过 64 个字符")
|
||||
private String code;
|
||||
|
||||
@Schema(description = "工具名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "5mm 铣刀")
|
||||
@NotEmpty(message = "工具名称不能为空")
|
||||
@Size(max = 255, message = "工具名称长度不能超过 255 个字符")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "品牌", example = "三菱")
|
||||
@Size(max = 255, message = "品牌长度不能超过 255 个字符")
|
||||
private String brand;
|
||||
|
||||
@Schema(description = "型号规格", example = "M5-100")
|
||||
@Size(max = 255, message = "型号规格长度不能超过 255 个字符")
|
||||
private String spec;
|
||||
|
||||
@Schema(description = "工具类型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
|
||||
@ -36,7 +41,8 @@ public class MesTmToolSaveReqVO {
|
||||
@NotNull(message = "数量不能为空")
|
||||
private Integer quantity;
|
||||
|
||||
@Schema(description = "可用数量", example = "1")
|
||||
@Schema(description = "可用数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "可用数量不能为空")
|
||||
private Integer availableQuantity;
|
||||
|
||||
@Schema(description = "保养维护类型", example = "1")
|
||||
@ -53,6 +59,7 @@ public class MesTmToolSaveReqVO {
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "备注", example = "备注")
|
||||
@Size(max = 500, message = "备注长度不能超过 500 个字符")
|
||||
private String remark;
|
||||
|
||||
}
|
||||
}
|
||||
@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.mes.controller.admin.tm.tool.vo.type;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - MES 工具类型新增/修改 Request VO")
|
||||
@ -14,10 +15,12 @@ public class MesTmToolTypeSaveReqVO {
|
||||
|
||||
@Schema(description = "类型编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "TT-001")
|
||||
@NotEmpty(message = "类型编码不能为空")
|
||||
@Size(max = 64, message = "类型编码长度不能超过 64 个字符")
|
||||
private String code;
|
||||
|
||||
@Schema(description = "类型名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "铣刀")
|
||||
@NotEmpty(message = "类型名称不能为空")
|
||||
@Size(max = 255, message = "类型名称长度不能超过 255 个字符")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "是否编码管理", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||
@ -31,6 +34,7 @@ public class MesTmToolTypeSaveReqVO {
|
||||
private Integer maintenPeriod;
|
||||
|
||||
@Schema(description = "备注", example = "备注")
|
||||
@Size(max = 500, message = "备注长度不能超过 500 个字符")
|
||||
private String remark;
|
||||
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.mes.controller.admin.wm.itemconsume.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
@ -13,6 +14,7 @@ import lombok.ToString;
|
||||
public class MesWmItemConsumeLinePageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "报工记录编号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "报工记录编号不能为空")
|
||||
private Long feedbackId;
|
||||
|
||||
}
|
||||
|
||||
@ -29,4 +29,8 @@ public interface MesMdWorkstationToolMapper extends BaseMapperX<MesMdWorkstation
|
||||
delete(MesMdWorkstationToolDO::getWorkstationId, workstationId);
|
||||
}
|
||||
|
||||
default Long selectCountByToolTypeId(Long toolTypeId) {
|
||||
return selectCount(MesMdWorkstationToolDO::getToolTypeId, toolTypeId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -217,6 +217,7 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode TM_TOOL_TYPE_CODE_DUPLICATE = new ErrorCode(1_040_400_001, "工具类型编码已存在");
|
||||
ErrorCode TM_TOOL_TYPE_NAME_DUPLICATE = new ErrorCode(1_040_400_002, "工具类型名称已存在");
|
||||
ErrorCode TM_TOOL_TYPE_HAS_TOOL = new ErrorCode(1_040_400_003, "该工具类型下存在工具,无法删除");
|
||||
ErrorCode TM_TOOL_TYPE_HAS_WORKSTATION_TOOL = new ErrorCode(1_040_400_004, "该工具类型已被工作站工装资源引用,无法删除");
|
||||
|
||||
// ========== MES 工具管理-工具台账(1-040-401-000) ==========
|
||||
ErrorCode TM_TOOL_NOT_EXISTS = new ErrorCode(1_040_401_000, "工具不存在");
|
||||
@ -362,6 +363,7 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode QC_OQC_QUANTITY_MISMATCH = new ErrorCode(1_040_607_004, "合格品与不合格品数量之和须等于检测数量");
|
||||
ErrorCode QC_OQC_NO_TEMPLATE = new ErrorCode(1_040_607_005, "当前产品未配置 OQC 检测模板");
|
||||
ErrorCode QC_OQC_CHECK_RESULT_EMPTY = new ErrorCode(1_040_607_006, "完成检验单前,检测结果必须填写");
|
||||
|
||||
// ========== MES 质量管理-出货检验行(1-040-607-100) ==========
|
||||
ErrorCode QC_OQC_LINE_NOT_EXISTS = new ErrorCode(1_040_607_100, "出货检验行不存在");
|
||||
|
||||
|
||||
@ -50,4 +50,12 @@ public interface MesMdWorkstationToolService {
|
||||
*/
|
||||
void deleteWorkstationToolByWorkstationId(Long workstationId);
|
||||
|
||||
/**
|
||||
* 获得指定工具类型的工装夹具资源数量
|
||||
*
|
||||
* @param toolTypeId 工具类型编号
|
||||
* @return 数量
|
||||
*/
|
||||
Long getWorkstationToolCountByToolTypeId(Long toolTypeId);
|
||||
|
||||
}
|
||||
|
||||
@ -89,4 +89,9 @@ public class MesMdWorkstationToolServiceImpl implements MesMdWorkstationToolServ
|
||||
workstationToolMapper.deleteByWorkstationId(workstationId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getWorkstationToolCountByToolTypeId(Long toolTypeId) {
|
||||
return workstationToolMapper.selectCountByToolTypeId(toolTypeId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -82,11 +82,14 @@ public class MesQcIndicatorResultServiceImpl implements MesQcIndicatorResultServ
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateIndicatorResult(MesQcIndicatorResultSaveReqVO updateReqVO) {
|
||||
// 1. 校验存在
|
||||
// 1.1 校验存在
|
||||
validateIndicatorResultExists(updateReqVO.getId());
|
||||
// 1.2 校验所有明细的 indicatorId 是否存在
|
||||
validateIndicatorIds(updateReqVO.getItems());
|
||||
|
||||
// 2.1 更新主表
|
||||
// 2.1 更新主表(锁定 qcId/qcType/itemId,不允许改挂到其他质检单)
|
||||
MesQcIndicatorResultDO updateObj = BeanUtils.toBean(updateReqVO, MesQcIndicatorResultDO.class);
|
||||
updateObj.setQcId(null).setQcType(null).setItemId(null);
|
||||
resultMapper.updateById(updateObj);
|
||||
// 2.2 批量更新明细
|
||||
List<MesQcIndicatorResultDetailDO> details = BeanUtils.toBean(updateReqVO.getItems(),
|
||||
|
||||
@ -283,7 +283,7 @@ public class MesQcIpqcServiceImpl implements MesQcIpqcService {
|
||||
* 推导工序 ID
|
||||
*
|
||||
* <p>通过产品 → 工艺路线产品 → 工艺路线 → 校验工位工序是否在该路线中
|
||||
* <p>如果工位的工序在路线中,则返回该 processId;否则返回 null
|
||||
* <p>如果工位的工序在路线中,则返回该 processId;否则返回 null(与 KTG 保持一致)
|
||||
*
|
||||
* @param productId 产品 ID(工单产品)
|
||||
* @param workstationProcessId 工位关联的工序 ID
|
||||
|
||||
@ -221,8 +221,8 @@ public class MesQcOqcServiceImpl implements MesQcOqcService {
|
||||
return null;
|
||||
}
|
||||
if (Objects.equals(sourceDocType, MesBizTypeConstants.WM_PRODUCT_SALES)) {
|
||||
MesWmProductSalesLineDO salesLine = productSalesLineService.getProductSalesLine(sourceLineId);
|
||||
if (salesLine != null && salesLine.getSalesId() != null) {
|
||||
MesWmProductSalesLineDO salesLine = productSalesLineService.validateProductSalesLineExists(sourceLineId);
|
||||
if (salesLine.getSalesId() != null) {
|
||||
MesWmProductSalesDO sales = productSalesService.getProductSales(salesLine.getSalesId());
|
||||
return sales != null ? sales.getCode() : null;
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.mes.controller.admin.tm.tool.vo.type.MesTmToolTyp
|
||||
import cn.iocoder.yudao.module.mes.controller.admin.tm.tool.vo.type.MesTmToolTypeSaveReqVO;
|
||||
import cn.iocoder.yudao.module.mes.dal.dataobject.tm.tool.MesTmToolTypeDO;
|
||||
import cn.iocoder.yudao.module.mes.dal.mysql.tm.tool.MesTmToolTypeMapper;
|
||||
import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationToolService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -37,6 +38,10 @@ public class MesTmToolTypeServiceImpl implements MesTmToolTypeService {
|
||||
@Lazy
|
||||
private MesTmToolService toolService;
|
||||
|
||||
@Resource
|
||||
@Lazy
|
||||
private MesMdWorkstationToolService workstationToolService;
|
||||
|
||||
@Override
|
||||
public Long createToolType(MesTmToolTypeSaveReqVO createReqVO) {
|
||||
// 校验数据
|
||||
@ -75,6 +80,10 @@ public class MesTmToolTypeServiceImpl implements MesTmToolTypeService {
|
||||
if (toolService.getToolCountByToolTypeId(id) > 0) {
|
||||
throw exception(TM_TOOL_TYPE_HAS_TOOL);
|
||||
}
|
||||
// 校验是否被工作站工装资源引用
|
||||
if (workstationToolService.getWorkstationToolCountByToolTypeId(id) > 0) {
|
||||
throw exception(TM_TOOL_TYPE_HAS_WORKSTATION_TOOL);
|
||||
}
|
||||
|
||||
// 删除
|
||||
toolTypeMapper.deleteById(id);
|
||||
|
||||
@ -39,6 +39,11 @@ import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
|
||||
@Slf4j
|
||||
public class MesWmBatchServiceImpl implements MesWmBatchService {
|
||||
|
||||
/**
|
||||
* 批次追溯最大递归深度,防止极端场景下性能问题
|
||||
*/
|
||||
private static final int MAX_TRACE_DEPTH = 20;
|
||||
|
||||
@Resource
|
||||
private MesWmBatchMapper batchMapper;
|
||||
@Resource
|
||||
@ -196,11 +201,11 @@ public class MesWmBatchServiceImpl implements MesWmBatchService {
|
||||
|
||||
@Override
|
||||
public List<MesWmBatchDO> getForwardBatchList(String code) {
|
||||
return getForwardBatchList(code, new HashSet<>());
|
||||
return getForwardBatchList(code, new HashSet<>(), 0);
|
||||
}
|
||||
|
||||
private List<MesWmBatchDO> getForwardBatchList(String code, Set<String> visited) {
|
||||
if (code == null || !visited.add(code)) {
|
||||
private List<MesWmBatchDO> getForwardBatchList(String code, Set<String> visited, int depth) {
|
||||
if (code == null || !visited.add(code) || depth >= MAX_TRACE_DEPTH) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<MesWmBatchDO> list = batchMapper.selectListByForward(code);
|
||||
@ -210,18 +215,18 @@ public class MesWmBatchServiceImpl implements MesWmBatchService {
|
||||
// 继续递归查询下游批次
|
||||
List<MesWmBatchDO> results = new ArrayList<>(list);
|
||||
for (MesWmBatchDO batch : list) {
|
||||
results.addAll(getForwardBatchList(batch.getCode(), visited));
|
||||
results.addAll(getForwardBatchList(batch.getCode(), visited, depth + 1));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MesWmBatchDO> getBackwardBatchList(String code) {
|
||||
return getBackwardBatchList(code, new HashSet<>());
|
||||
return getBackwardBatchList(code, new HashSet<>(), 0);
|
||||
}
|
||||
|
||||
private List<MesWmBatchDO> getBackwardBatchList(String code, Set<String> visited) {
|
||||
if (code == null || !visited.add(code)) {
|
||||
private List<MesWmBatchDO> getBackwardBatchList(String code, Set<String> visited, int depth) {
|
||||
if (code == null || !visited.add(code) || depth >= MAX_TRACE_DEPTH) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<MesWmBatchDO> list = batchMapper.selectListByBackward(code);
|
||||
@ -231,7 +236,7 @@ public class MesWmBatchServiceImpl implements MesWmBatchService {
|
||||
// 继续递归查询上游批次
|
||||
List<MesWmBatchDO> results = new ArrayList<>(list);
|
||||
for (MesWmBatchDO batch : list) {
|
||||
results.addAll(getBackwardBatchList(batch.getCode(), visited));
|
||||
results.addAll(getBackwardBatchList(batch.getCode(), visited, depth + 1));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
@ -68,6 +68,14 @@ public interface MesWmProductSalesLineService {
|
||||
*/
|
||||
PageResult<MesWmProductSalesLineDO> getProductSalesLinePage(MesWmProductSalesLinePageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 校验销售出库单行存在
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 销售出库单行
|
||||
*/
|
||||
MesWmProductSalesLineDO validateProductSalesLineExists(Long id);
|
||||
|
||||
/**
|
||||
* OQC 检验完成后,更新销售出库单行的 OQC 质检状态
|
||||
*
|
||||
|
||||
@ -124,7 +124,8 @@ public class MesWmProductSalesLineServiceImpl implements MesWmProductSalesLineSe
|
||||
return productSalesLineMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
private MesWmProductSalesLineDO validateProductSalesLineExists(Long id) {
|
||||
@Override
|
||||
public MesWmProductSalesLineDO validateProductSalesLineExists(Long id) {
|
||||
MesWmProductSalesLineDO line = productSalesLineMapper.selectById(id);
|
||||
if (line == null) {
|
||||
throw exception(WM_PRODUCT_SALES_LINE_NOT_EXISTS);
|
||||
|
||||
@ -8,6 +8,9 @@ import cn.iocoder.yudao.module.mes.enums.qc.MesQcStatusEnum;
|
||||
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
|
||||
import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService;
|
||||
import cn.iocoder.yudao.module.mes.service.pro.feedback.MesProFeedbackService;
|
||||
import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProcessService;
|
||||
import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProductService;
|
||||
import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService;
|
||||
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
|
||||
import cn.iocoder.yudao.module.mes.service.qc.defectrecord.MesQcDefectRecordService;
|
||||
import cn.iocoder.yudao.module.mes.service.qc.template.MesQcTemplateItemService;
|
||||
@ -54,6 +57,12 @@ public class MesQcIpqcServiceImplTest extends BaseDbUnitTest {
|
||||
private AdminUserApi adminUserApi;
|
||||
@MockitoBean
|
||||
private MesProFeedbackService feedbackService;
|
||||
@MockitoBean
|
||||
private MesProRouteProductService routeProductService;
|
||||
@MockitoBean
|
||||
private MesProRouteProcessService routeProcessService;
|
||||
@MockitoBean
|
||||
private MesProTaskService taskService;
|
||||
|
||||
@Test
|
||||
public void testFinishIpqc_writeBack_feedback() {
|
||||
@ -211,4 +220,153 @@ public class MesQcIpqcServiceImplTest extends BaseDbUnitTest {
|
||||
assertThrows(Exception.class, () -> ipqcService.finishIpqc(ipqc.getId()));
|
||||
}
|
||||
|
||||
// ==================== processId 推导行为测试 ====================
|
||||
|
||||
/**
|
||||
* 工位有工序 + 该工序在产品工艺路线中 → processId 应该被设置为工位工序
|
||||
*/
|
||||
@Test
|
||||
public void testCreateIpqc_processId_workstationHasProcess() {
|
||||
// 准备参数
|
||||
Long workstationId = randomLongId();
|
||||
Long workOrderId = randomLongId();
|
||||
Long productId = randomLongId();
|
||||
Long processId = randomLongId();
|
||||
Long routeId = randomLongId();
|
||||
Long templateId = randomLongId();
|
||||
|
||||
MesQcIpqcSaveReqVO reqVO = new MesQcIpqcSaveReqVO();
|
||||
reqVO.setCode("IPQC-TEST-001");
|
||||
reqVO.setWorkstationId(workstationId);
|
||||
reqVO.setWorkOrderId(workOrderId);
|
||||
reqVO.setInspectorUserId(randomLongId());
|
||||
|
||||
// mock 工位返回有工序
|
||||
MesMdWorkstationDO workstation = new MesMdWorkstationDO();
|
||||
workstation.setId(workstationId);
|
||||
workstation.setProcessId(processId);
|
||||
when(workstationService.validateWorkstationExists(workstationId)).thenReturn(workstation);
|
||||
// mock 工单
|
||||
MesProWorkOrderDO workOrder = new MesProWorkOrderDO();
|
||||
workOrder.setId(workOrderId);
|
||||
workOrder.setProductId(productId);
|
||||
when(workOrderService.validateWorkOrderExists(workOrderId)).thenReturn(workOrder);
|
||||
when(workOrderService.validateWorkOrderConfirmed(workOrderId)).thenReturn(workOrder);
|
||||
// mock 模板匹配
|
||||
MesQcTemplateItemDO templateItem = new MesQcTemplateItemDO();
|
||||
templateItem.setTemplateId(templateId);
|
||||
when(templateItemService.getRequiredTemplateByItemIdAndType(eq(productId), anyInt())).thenReturn(templateItem);
|
||||
// mock 工艺路线
|
||||
MesProRouteProductDO routeProduct = new MesProRouteProductDO();
|
||||
routeProduct.setRouteId(routeId);
|
||||
when(routeProductService.getRouteProductByItemId(productId)).thenReturn(routeProduct);
|
||||
// mock 工序在路线中
|
||||
when(routeProcessService.getRouteProcessByRouteIdAndProcessId(routeId, processId))
|
||||
.thenReturn(new MesProRouteProcessDO());
|
||||
|
||||
// 调用
|
||||
Long ipqcId = ipqcService.createIpqc(reqVO);
|
||||
|
||||
// 断言:processId 应该是工位工序
|
||||
MesQcIpqcDO ipqc = ipqcMapper.selectById(ipqcId);
|
||||
assertEquals(processId, ipqc.getProcessId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 工位没有工序(processId=null)→ processId 应该留 null(与 KTG 对齐,不回退到任务工序)
|
||||
*/
|
||||
@Test
|
||||
public void testCreateIpqc_processId_workstationNoProcess_shouldBeNull() {
|
||||
// 准备参数
|
||||
Long workstationId = randomLongId();
|
||||
Long workOrderId = randomLongId();
|
||||
Long productId = randomLongId();
|
||||
Long taskId = randomLongId();
|
||||
Long templateId = randomLongId();
|
||||
|
||||
MesQcIpqcSaveReqVO reqVO = new MesQcIpqcSaveReqVO();
|
||||
reqVO.setCode("IPQC-TEST-002");
|
||||
reqVO.setWorkstationId(workstationId);
|
||||
reqVO.setWorkOrderId(workOrderId);
|
||||
reqVO.setTaskId(taskId); // 故意传入 taskId,验证不会回退
|
||||
reqVO.setInspectorUserId(randomLongId());
|
||||
|
||||
// mock 工位没有工序
|
||||
MesMdWorkstationDO workstation = new MesMdWorkstationDO();
|
||||
workstation.setId(workstationId);
|
||||
workstation.setProcessId(null); // 无工序
|
||||
when(workstationService.validateWorkstationExists(workstationId)).thenReturn(workstation);
|
||||
// mock 工单
|
||||
MesProWorkOrderDO workOrder = new MesProWorkOrderDO();
|
||||
workOrder.setId(workOrderId);
|
||||
workOrder.setProductId(productId);
|
||||
when(workOrderService.validateWorkOrderExists(workOrderId)).thenReturn(workOrder);
|
||||
when(workOrderService.validateWorkOrderConfirmed(workOrderId)).thenReturn(workOrder);
|
||||
// mock 模板匹配
|
||||
MesQcTemplateItemDO templateItem = new MesQcTemplateItemDO();
|
||||
templateItem.setTemplateId(templateId);
|
||||
when(templateItemService.getRequiredTemplateByItemIdAndType(eq(productId), anyInt())).thenReturn(templateItem);
|
||||
|
||||
// 调用
|
||||
Long ipqcId = ipqcService.createIpqc(reqVO);
|
||||
|
||||
// 断言:processId 应该是 null,即使传入了 taskId 也不应该回退
|
||||
MesQcIpqcDO ipqc = ipqcMapper.selectById(ipqcId);
|
||||
assertNull(ipqc.getProcessId(),
|
||||
"工位无工序时 processId 应为 null(与 KTG 对齐),不应回退到任务工序");
|
||||
// 断言:不应该读取任务的 processId
|
||||
verify(routeProductService, never()).getRouteProductByItemId(any());
|
||||
}
|
||||
|
||||
/**
|
||||
* 工位有工序但该工序不在产品工艺路线中 → processId 应该留 null
|
||||
*/
|
||||
@Test
|
||||
public void testCreateIpqc_processId_processNotInRoute() {
|
||||
// 准备参数
|
||||
Long workstationId = randomLongId();
|
||||
Long workOrderId = randomLongId();
|
||||
Long productId = randomLongId();
|
||||
Long processId = randomLongId();
|
||||
Long routeId = randomLongId();
|
||||
Long templateId = randomLongId();
|
||||
|
||||
MesQcIpqcSaveReqVO reqVO = new MesQcIpqcSaveReqVO();
|
||||
reqVO.setCode("IPQC-TEST-003");
|
||||
reqVO.setWorkstationId(workstationId);
|
||||
reqVO.setWorkOrderId(workOrderId);
|
||||
reqVO.setInspectorUserId(randomLongId());
|
||||
|
||||
// mock 工位有工序
|
||||
MesMdWorkstationDO workstation = new MesMdWorkstationDO();
|
||||
workstation.setId(workstationId);
|
||||
workstation.setProcessId(processId);
|
||||
when(workstationService.validateWorkstationExists(workstationId)).thenReturn(workstation);
|
||||
// mock 工单
|
||||
MesProWorkOrderDO workOrder = new MesProWorkOrderDO();
|
||||
workOrder.setId(workOrderId);
|
||||
workOrder.setProductId(productId);
|
||||
when(workOrderService.validateWorkOrderExists(workOrderId)).thenReturn(workOrder);
|
||||
when(workOrderService.validateWorkOrderConfirmed(workOrderId)).thenReturn(workOrder);
|
||||
// mock 模板匹配
|
||||
MesQcTemplateItemDO templateItem = new MesQcTemplateItemDO();
|
||||
templateItem.setTemplateId(templateId);
|
||||
when(templateItemService.getRequiredTemplateByItemIdAndType(eq(productId), anyInt())).thenReturn(templateItem);
|
||||
// mock 工艺路线存在
|
||||
MesProRouteProductDO routeProduct = new MesProRouteProductDO();
|
||||
routeProduct.setRouteId(routeId);
|
||||
when(routeProductService.getRouteProductByItemId(productId)).thenReturn(routeProduct);
|
||||
// mock 工序不在路线中
|
||||
when(routeProcessService.getRouteProcessByRouteIdAndProcessId(routeId, processId))
|
||||
.thenReturn(null);
|
||||
|
||||
// 调用
|
||||
Long ipqcId = ipqcService.createIpqc(reqVO);
|
||||
|
||||
// 断言:processId 应该是 null
|
||||
MesQcIpqcDO ipqc = ipqcMapper.selectById(ipqcId);
|
||||
assertNull(ipqc.getProcessId());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user