Compare commits
3 Commits
a4878dee0b
...
dbfa45498c
| Author | SHA1 | Date |
|---|---|---|
|
|
dbfa45498c | |
|
|
8f30243721 | |
|
|
70baa07783 |
|
|
@ -4,6 +4,7 @@ import com.nflg.qms.admin.service.QmsIssueTicketControllerService;
|
|||
import com.nflg.wms.common.pojo.ApiResult;
|
||||
import com.nflg.wms.common.pojo.PageData;
|
||||
import com.nflg.wms.common.pojo.qo.QmsIssueTicketAddQO;
|
||||
import com.nflg.wms.common.pojo.qo.QmsIssueTicketAuditQO;
|
||||
import com.nflg.wms.common.pojo.qo.QmsIssueTicketSearchQO;
|
||||
import com.nflg.wms.common.pojo.vo.QmsIssueTicketDetailVO;
|
||||
import com.nflg.wms.common.pojo.vo.QmsIssueTicketVO;
|
||||
|
|
@ -11,11 +12,14 @@ import com.nflg.wms.repository.service.IQmsIssueTicketService;
|
|||
import com.nflg.wms.starter.BaseController;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 质量问题工单管理
|
||||
*/
|
||||
|
|
@ -39,13 +43,32 @@ public class QmsIssueTicketController extends BaseController {
|
|||
return ApiResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 审核质量问题工单
|
||||
* 更新审批状态、审批意见、审批人信息,并根据审批结果更新工单状态
|
||||
*/
|
||||
@PostMapping("audit")
|
||||
public ApiResult<Void> audit(@Valid @RequestBody QmsIssueTicketAuditQO request) {
|
||||
issueTicketControllerService.audit(request);
|
||||
return ApiResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询来料检测任务质量问题工单详情
|
||||
* 含来料检测任务详情及来料检验任务检验记录子项样本列表
|
||||
*/
|
||||
@GetMapping("detail")
|
||||
public ApiResult<QmsIssueTicketDetailVO> detail(@NotNull(message = "ID不能为空") Long id) {
|
||||
return ApiResult.success(issueTicketControllerService.getDetail(id));
|
||||
@GetMapping("detail/incoming-inspection-task")
|
||||
public ApiResult<QmsIssueTicketDetailVO> detailIncomingInspectionTask(@NotNull(message = "ID不能为空") Long id) {
|
||||
return ApiResult.success(issueTicketControllerService.getIncomingInspectionTaskDetail(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除质量问题工单
|
||||
*/
|
||||
@PostMapping("delete")
|
||||
public ApiResult<Void> delete(@RequestBody @NotEmpty(message = "ID列表不能为空") List<Long> ids) {
|
||||
issueTicketService.removeByIds(ids);
|
||||
return ApiResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ public class IncomingInspectionTaskControllerService {
|
|||
private IFileUploadRecordService fileUploadRecordService;
|
||||
|
||||
@Resource
|
||||
private TicketEventPublisher publisher;
|
||||
private QmsIssueTicketControllerService issueTicketControllerService;
|
||||
|
||||
/**
|
||||
* 来料检验申请(对外接口)
|
||||
|
|
@ -952,7 +952,7 @@ public class IncomingInspectionTaskControllerService {
|
|||
|
||||
updateWrapper.update();
|
||||
|
||||
publisher.publishIncomingInspectionTaskFinishEvent(task.getId(), request.getQualified());
|
||||
issueTicketControllerService.initiate(task.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1085,4 +1085,8 @@ public class IncomingInspectionTaskControllerService {
|
|||
public List<QmsIssueTicketInspectionRecordItemSimpleVO> getUnqualifiedRecordItems(Long taskId) {
|
||||
return incomingInspectionTaskRecordItemService.getUnqualifiedRecordItems(taskId);
|
||||
}
|
||||
|
||||
public List<String> getUnqualifiedRecordItemDataImages(Long taskId) {
|
||||
return incomingInspectionTaskRecordItemService.getUnqualifiedRecordItemDataImages(taskId);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,14 +6,12 @@ import cn.hutool.core.util.StrUtil;
|
|||
import com.nflg.wms.common.constant.STATE;
|
||||
import com.nflg.wms.common.exception.NflgException;
|
||||
import com.nflg.wms.common.pojo.qo.QmsIssueTicketAddQO;
|
||||
import com.nflg.wms.common.pojo.qo.QmsIssueTicketAuditQO;
|
||||
import com.nflg.wms.common.pojo.vo.*;
|
||||
import com.nflg.wms.common.util.UserUtil;
|
||||
import com.nflg.wms.common.util.VUtil;
|
||||
import com.nflg.wms.repository.entity.FileUploadRecord;
|
||||
import com.nflg.wms.repository.entity.QmsIssueTicket;
|
||||
import com.nflg.wms.repository.entity.VUser;
|
||||
import com.nflg.wms.repository.service.IFileUploadRecordService;
|
||||
import com.nflg.wms.repository.service.IQmsIssueTicketService;
|
||||
import com.nflg.wms.repository.entity.*;
|
||||
import com.nflg.wms.repository.service.*;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import jakarta.validation.Valid;
|
||||
|
|
@ -24,6 +22,7 @@ import java.time.LocalDateTime;
|
|||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* 质量问题工单 ControllerService
|
||||
|
|
@ -45,6 +44,48 @@ public class QmsIssueTicketControllerService {
|
|||
@Resource
|
||||
private IncomingInspectionTaskControllerService incomingInspectionTaskControllerService;
|
||||
|
||||
@Resource
|
||||
private IUserService userService;
|
||||
|
||||
@Resource
|
||||
private IQmsTodoItemService todoItemService;
|
||||
|
||||
@Resource
|
||||
private IDictionaryItemService dictionaryItemService;
|
||||
|
||||
/**
|
||||
* 审核质量问题工单
|
||||
* 更新审批状态、审批意见、审批人信息、事故类型,并更新工单状态
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void audit(@Valid QmsIssueTicketAuditQO request) {
|
||||
// 校验工单存在
|
||||
QmsIssueTicket entity = issueTicketService.getById(request.getId());
|
||||
VUtil.trueThrowBusinessError(Objects.isNull(entity))
|
||||
.throwMessage("质量问题工单不存在");
|
||||
VUtil.trueThrowBusinessError(Objects.nonNull(entity.getApprovalStatus())).throwMessage("请勿重复审批");
|
||||
|
||||
// 校验审批状态合法性
|
||||
Set<Short> validApprovalStatus = Stream.of((short) 0, (short) 1, (short) 2, (short) 3, (short) 4, (short) 5, (short) 6)
|
||||
.collect(Collectors.toSet());
|
||||
VUtil.trueThrowBusinessError(!validApprovalStatus.contains(request.getApprovalStatus()))
|
||||
.throwMessage("审批状态不合法");
|
||||
|
||||
Long userId = UserUtil.getUserId();
|
||||
String userName = UserUtil.getUserName();
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
entity.setApprovalStatus(request.getApprovalStatus())
|
||||
.setStatus((short) 2)
|
||||
.setApprovalOpinion(request.getApprovalOpinion())
|
||||
.setIncidentType(request.getIncidentType())
|
||||
.setApprovalUserId(userId)
|
||||
.setApprovalUserName(userName)
|
||||
.setApprovalTime(now);
|
||||
|
||||
issueTicketService.updateById(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增质量问题工单
|
||||
* 工单编号自动生成,来源类型固定为2(巡检),状态默认为0(待流转)
|
||||
|
|
@ -131,8 +172,30 @@ public class QmsIssueTicketControllerService {
|
|||
+ "\n"
|
||||
);
|
||||
});
|
||||
|
||||
List<String> images = incomingInspectionTaskControllerService.getUnqualifiedRecordItemDataImages(taskId);
|
||||
images.removeIf(StrUtil::isBlank);
|
||||
entity.setImageIds(StrUtil.join(",", images));
|
||||
issueTicketService.save(entity);
|
||||
|
||||
// 添加待办
|
||||
if (detail.getInspectionType() == 0) {
|
||||
if (StrUtil.isNotBlank(detail.getPurchaseGroup())) {
|
||||
List<User> users = userService.lambdaQuery()
|
||||
.eq(User::getPurchasingGroup, detail.getPurchaseGroup())
|
||||
.list();
|
||||
List<QmsTodoItem> todoItems = users.stream().map(user -> new QmsTodoItem()
|
||||
.setCode(basdeSerialNumberControllerService.generateSerialNumber(32))
|
||||
.setSourceTypeId(dictionaryItemService.getIdByCode("MessageType", "IncomingMaterialInspectionApproval"))
|
||||
.setSourceId(entity.getId())
|
||||
.setCreateUserId(user.getId())
|
||||
.setCreateUserName(user.getUserName())
|
||||
.setCreateTime(LocalDateTime.now())
|
||||
).toList();
|
||||
if (CollectionUtil.isNotEmpty(todoItems)) {
|
||||
todoItemService.saveBatch(todoItems);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String generateTicketTitle(Object... args) {
|
||||
|
|
@ -143,7 +206,7 @@ public class QmsIssueTicketControllerService {
|
|||
* 查询来料检测任务质量问题工单详情
|
||||
* 包含图片文件信息、来料检测任务详情、检验记录(含子项和样本数据)
|
||||
*/
|
||||
public QmsIssueTicketDetailVO getDetail(Long id) {
|
||||
public QmsIssueTicketDetailVO getIncomingInspectionTaskDetail(Long id) {
|
||||
QmsIssueTicket entity = issueTicketService.getById(id);
|
||||
if (Objects.isNull(entity)) {
|
||||
throw new NflgException(STATE.BusinessError, "质量问题工单不存在");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,382 @@
|
|||
package com.nflg.qms.admin;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.lang.TypeReference;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.nflg.wms.common.pojo.ApiResult;
|
||||
import com.nflg.wms.common.pojo.qo.ExternalInventoryInspectionApplyQO;
|
||||
import org.junit.jupiter.api.MethodOrderer;
|
||||
import org.junit.jupiter.api.Order;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestMethodOrder;
|
||||
|
||||
/**
|
||||
* 对外接口-库存检测申请 接口测试
|
||||
* <p>
|
||||
* 测试前提:
|
||||
* 1. qms-admin 服务已启动(默认 http://localhost:8105)
|
||||
* 2. 测试账号已登录,将有效的 token 填入 TOKEN 常量
|
||||
* 3. 数据库中已存在物料编号为 VALID_MATERIAL_NO 的质检物料,且该物料有对应的已发布检验标准
|
||||
* 4. 该物料(或其所属物料类别层级)已绑定 IQE 质检人员(inspection_type = 1)
|
||||
* </p>
|
||||
*/
|
||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||
public class ExternalInventoryInspectionApplyApiTest {
|
||||
|
||||
// ===================== 配置区 =====================
|
||||
/** 服务地址 */
|
||||
private static final String BASE_URL = "http://localhost:8105";
|
||||
/** 当前登录用户的 token(需手动配置) */
|
||||
private static final String TOKEN = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOjEsInJuU3RyIjoidVFwSWM2R3RJeUoxcFNSczBadzJzb1hvMUZLZXB3czkiLCJuYW1lIjoi6LaF57qn566h55CG5ZGYIiwiY29kZSI6ImFkbWluIiwicm9sZXMiOlsiU3VwZXJBZG1pbiJdLCJ0eXBlIjoxfQ.FtQ2uVwvuxsjAFbXnB006hV1pODtRhZT0z_9nfuR0So";
|
||||
/** 有效的物料编号(数据库中已存在,且有已发布检验标准和绑定的IQE) */
|
||||
private static final String VALID_MATERIAL_NO = "2200052100";
|
||||
/** 有效的所属工厂 */
|
||||
private static final String VALID_FACTORY = "1010";
|
||||
/** 有效的所属仓库 */
|
||||
private static final String VALID_WAREHOUSE = "0007";
|
||||
/** 有效的所属储位 */
|
||||
private static final String VALID_STORAGE_LOCATION = "SL01";
|
||||
/** 有效的存储时长(天) */
|
||||
private static final int VALID_STORAGE_DAYS = 30;
|
||||
// ===================== 配置区结束 =====================
|
||||
|
||||
private static final String API_PATH = "/external/incoming-inspection-task/inventory-apply";
|
||||
|
||||
// ==================== HTTP 工具方法 ====================
|
||||
|
||||
private static <T> ApiResult<T> post(String path, Object body, TypeReference<ApiResult<T>> typeRef) {
|
||||
String url = BASE_URL + path;
|
||||
String reqBody = body == null ? "" : JSONUtil.toJsonStr(body);
|
||||
HttpResponse resp = HttpRequest.post(url)
|
||||
.header("authorization", TOKEN)
|
||||
.header("Content-Type", "application/json")
|
||||
.body(reqBody)
|
||||
.execute();
|
||||
String raw = resp.body();
|
||||
System.out.println("[POST] " + path);
|
||||
System.out.println(" 请求: " + reqBody);
|
||||
System.out.println(" 响应: " + raw);
|
||||
return JSONUtil.toBean(raw, typeRef, false);
|
||||
}
|
||||
|
||||
private static <T> void assertSuccess(ApiResult<T> result, String msg) {
|
||||
Assert.isTrue(result != null && result.getCode() == 200,
|
||||
() -> new RuntimeException(msg + " => " + JSONUtil.toJsonStr(result)));
|
||||
}
|
||||
|
||||
private static void assertFailed(ApiResult<?> result, String msg) {
|
||||
Assert.isTrue(result != null && result.getCode() != 200,
|
||||
() -> new RuntimeException(msg + " => 预期失败但实际成功"));
|
||||
}
|
||||
|
||||
// ==================== 正常场景测试 ====================
|
||||
|
||||
/**
|
||||
* 【库存检测申请】正常申请(必填字段完整)
|
||||
* 验证点:
|
||||
* 1. 接口返回成功
|
||||
* 2. 物料编号有效,存在对应的已发布检验标准
|
||||
* 3. 能正常分配到质检人员
|
||||
* 4. 任务 dataType=1, inspectionType=1
|
||||
*/
|
||||
@Test
|
||||
@Order(1)
|
||||
public void test01_inventoryApply_Success() {
|
||||
ExternalInventoryInspectionApplyQO request = buildValidRequest();
|
||||
|
||||
ApiResult<Void> result = post(API_PATH, request, new TypeReference<>() {});
|
||||
assertSuccess(result, "库存检测申请失败");
|
||||
System.out.println(" ✅ 库存检测申请成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 【库存检测申请】最小检验数量(inspectionQty=1)
|
||||
* 验证点:边界值最小合法检验数量
|
||||
*/
|
||||
@Test
|
||||
@Order(2)
|
||||
public void test02_inventoryApply_MinInspectionQty() {
|
||||
ExternalInventoryInspectionApplyQO request = buildValidRequest();
|
||||
request.setInspectionQty(1);
|
||||
|
||||
ApiResult<Void> result = post(API_PATH, request, new TypeReference<>() {});
|
||||
assertSuccess(result, "最小检验数量库存检测申请失败");
|
||||
System.out.println(" ✅ 最小检验数量库存检测申请成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 【库存检测申请】最小存储时长(storageDays=1)
|
||||
* 验证点:边界值最小合法存储时长
|
||||
*/
|
||||
@Test
|
||||
@Order(3)
|
||||
public void test03_inventoryApply_MinStorageDays() {
|
||||
ExternalInventoryInspectionApplyQO request = buildValidRequest();
|
||||
request.setStorageDays(1);
|
||||
|
||||
ApiResult<Void> result = post(API_PATH, request, new TypeReference<>() {});
|
||||
assertSuccess(result, "最小存储时长库存检测申请失败");
|
||||
System.out.println(" ✅ 最小存储时长库存检测申请成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 【库存检测申请】大数量检验(inspectionQty=99999)
|
||||
* 验证点:大数量时能正常处理
|
||||
*/
|
||||
@Test
|
||||
@Order(4)
|
||||
public void test04_inventoryApply_LargeInspectionQty() {
|
||||
ExternalInventoryInspectionApplyQO request = buildValidRequest();
|
||||
request.setInspectionQty(99999);
|
||||
|
||||
ApiResult<Void> result = post(API_PATH, request, new TypeReference<>() {});
|
||||
assertSuccess(result, "大数量检验库存检测申请失败");
|
||||
System.out.println(" ✅ 大数量检验库存检测申请成功");
|
||||
}
|
||||
|
||||
// ==================== 参数校验异常测试 ====================
|
||||
|
||||
/**
|
||||
* 【库存检测申请】物料编号为空
|
||||
* 验证点:@NotBlank 校验,接口返回参数校验错误
|
||||
*/
|
||||
@Test
|
||||
@Order(10)
|
||||
public void test10_inventoryApply_MaterialNoBlank() {
|
||||
ExternalInventoryInspectionApplyQO request = buildValidRequest();
|
||||
request.setMaterialNo(null);
|
||||
|
||||
ApiResult<Void> result = post(API_PATH, request, new TypeReference<>() {});
|
||||
assertFailed(result, "物料编号为空应返回失败");
|
||||
System.out.println(" ✅ 物料编号为空校验通过");
|
||||
}
|
||||
|
||||
/**
|
||||
* 【库存检测申请】物料编号为空字符串
|
||||
* 验证点:@NotBlank 校验,空字符串也应返回失败
|
||||
*/
|
||||
@Test
|
||||
@Order(11)
|
||||
public void test11_inventoryApply_MaterialNoEmpty() {
|
||||
ExternalInventoryInspectionApplyQO request = buildValidRequest();
|
||||
request.setMaterialNo("");
|
||||
|
||||
ApiResult<Void> result = post(API_PATH, request, new TypeReference<>() {});
|
||||
assertFailed(result, "物料编号为空字符串应返回失败");
|
||||
System.out.println(" ✅ 物料编号为空字符串校验通过");
|
||||
}
|
||||
|
||||
/**
|
||||
* 【库存检测申请】所属工厂为空
|
||||
* 验证点:@NotBlank 校验,接口返回参数校验错误
|
||||
*/
|
||||
@Test
|
||||
@Order(12)
|
||||
public void test12_inventoryApply_FactoryBlank() {
|
||||
ExternalInventoryInspectionApplyQO request = buildValidRequest();
|
||||
request.setFactory(null);
|
||||
|
||||
ApiResult<Void> result = post(API_PATH, request, new TypeReference<>() {});
|
||||
assertFailed(result, "所属工厂为空应返回失败");
|
||||
System.out.println(" ✅ 所属工厂为空校验通过");
|
||||
}
|
||||
|
||||
/**
|
||||
* 【库存检测申请】检验数量为空
|
||||
* 验证点:@NotNull 校验,接口返回参数校验错误
|
||||
*/
|
||||
@Test
|
||||
@Order(13)
|
||||
public void test13_inventoryApply_InspectionQtyNull() {
|
||||
ExternalInventoryInspectionApplyQO request = buildValidRequest();
|
||||
request.setInspectionQty(null);
|
||||
|
||||
ApiResult<Void> result = post(API_PATH, request, new TypeReference<>() {});
|
||||
assertFailed(result, "检验数量为空应返回失败");
|
||||
System.out.println(" ✅ 检验数量为空校验通过");
|
||||
}
|
||||
|
||||
/**
|
||||
* 【库存检测申请】检验数量为零
|
||||
* 验证点:@Min(1) 校验,检验数量必须大于0
|
||||
*/
|
||||
@Test
|
||||
@Order(14)
|
||||
public void test14_inventoryApply_InspectionQtyZero() {
|
||||
ExternalInventoryInspectionApplyQO request = buildValidRequest();
|
||||
request.setInspectionQty(0);
|
||||
|
||||
ApiResult<Void> result = post(API_PATH, request, new TypeReference<>() {});
|
||||
assertFailed(result, "检验数量为零应返回失败");
|
||||
System.out.println(" ✅ 检验数量为零校验通过");
|
||||
}
|
||||
|
||||
/**
|
||||
* 【库存检测申请】检验数量为负数
|
||||
* 验证点:@Min(1) 校验,负数应返回失败
|
||||
*/
|
||||
@Test
|
||||
@Order(15)
|
||||
public void test15_inventoryApply_InspectionQtyNegative() {
|
||||
ExternalInventoryInspectionApplyQO request = buildValidRequest();
|
||||
request.setInspectionQty(-1);
|
||||
|
||||
ApiResult<Void> result = post(API_PATH, request, new TypeReference<>() {});
|
||||
assertFailed(result, "检验数量为负数应返回失败");
|
||||
System.out.println(" ✅ 检验数量为负数校验通过");
|
||||
}
|
||||
|
||||
/**
|
||||
* 【库存检测申请】所属仓库为空
|
||||
* 验证点:@NotBlank 校验,库存检测必填仓库
|
||||
*/
|
||||
@Test
|
||||
@Order(16)
|
||||
public void test16_inventoryApply_WarehouseBlank() {
|
||||
ExternalInventoryInspectionApplyQO request = buildValidRequest();
|
||||
request.setWarehouse(null);
|
||||
|
||||
ApiResult<Void> result = post(API_PATH, request, new TypeReference<>() {});
|
||||
assertFailed(result, "所属仓库为空应返回失败");
|
||||
System.out.println(" ✅ 所属仓库为空校验通过");
|
||||
}
|
||||
|
||||
/**
|
||||
* 【库存检测申请】所属储位为空
|
||||
* 验证点:@NotBlank 校验,库存检测必填储位
|
||||
*/
|
||||
@Test
|
||||
@Order(17)
|
||||
public void test17_inventoryApply_StorageLocationBlank() {
|
||||
ExternalInventoryInspectionApplyQO request = buildValidRequest();
|
||||
request.setStorageLocation(null);
|
||||
|
||||
ApiResult<Void> result = post(API_PATH, request, new TypeReference<>() {});
|
||||
assertFailed(result, "所属储位为空应返回失败");
|
||||
System.out.println(" ✅ 所属储位为空校验通过");
|
||||
}
|
||||
|
||||
/**
|
||||
* 【库存检测申请】存储时长为空
|
||||
* 验证点:@NotNull 校验,库存检测必填存储时长
|
||||
*/
|
||||
@Test
|
||||
@Order(18)
|
||||
public void test18_inventoryApply_StorageDaysNull() {
|
||||
ExternalInventoryInspectionApplyQO request = buildValidRequest();
|
||||
request.setStorageDays(null);
|
||||
|
||||
ApiResult<Void> result = post(API_PATH, request, new TypeReference<>() {});
|
||||
assertFailed(result, "存储时长为空应返回失败");
|
||||
System.out.println(" ✅ 存储时长为空校验通过");
|
||||
}
|
||||
|
||||
/**
|
||||
* 【库存检测申请】存储时长为零
|
||||
* 验证点:@Min(1) 校验,存储时长必须大于0
|
||||
*/
|
||||
@Test
|
||||
@Order(19)
|
||||
public void test19_inventoryApply_StorageDaysZero() {
|
||||
ExternalInventoryInspectionApplyQO request = buildValidRequest();
|
||||
request.setStorageDays(0);
|
||||
|
||||
ApiResult<Void> result = post(API_PATH, request, new TypeReference<>() {});
|
||||
assertFailed(result, "存储时长为零应返回失败");
|
||||
System.out.println(" ✅ 存储时长为零校验通过");
|
||||
}
|
||||
|
||||
/**
|
||||
* 【库存检测申请】存储时长为负数
|
||||
* 验证点:@Min(1) 校验,负数应返回失败
|
||||
*/
|
||||
@Test
|
||||
@Order(20)
|
||||
public void test20_inventoryApply_StorageDaysNegative() {
|
||||
ExternalInventoryInspectionApplyQO request = buildValidRequest();
|
||||
request.setStorageDays(-5);
|
||||
|
||||
ApiResult<Void> result = post(API_PATH, request, new TypeReference<>() {});
|
||||
assertFailed(result, "存储时长为负数应返回失败");
|
||||
System.out.println(" ✅ 存储时长为负数校验通过");
|
||||
}
|
||||
|
||||
// ==================== 业务校验异常测试 ====================
|
||||
|
||||
/**
|
||||
* 【库存检测申请】物料编号不存在
|
||||
* 验证点:接口返回业务错误(物料编号不存在于质检物料表中)
|
||||
*/
|
||||
@Test
|
||||
@Order(30)
|
||||
public void test30_inventoryApply_MaterialNotExist() {
|
||||
ExternalInventoryInspectionApplyQO request = buildValidRequest();
|
||||
request.setMaterialNo("NOT_EXIST_MATERIAL_999");
|
||||
|
||||
ApiResult<Void> result = post(API_PATH, request, new TypeReference<>() {});
|
||||
assertFailed(result, "物料编号不存在应返回失败");
|
||||
System.out.println(" ✅ 物料编号不存在校验通过");
|
||||
}
|
||||
|
||||
/**
|
||||
* 【库存检测申请】物料存在但无对应的检验标准
|
||||
* 验证点:接口返回业务错误(该物料不存在对应的检验标准)
|
||||
* 注意:需要一个存在于质检物料表但没有已发布检验标准的物料编号
|
||||
*/
|
||||
@Test
|
||||
@Order(31)
|
||||
public void test31_inventoryApply_NoInspectionStandard() {
|
||||
ExternalInventoryInspectionApplyQO request = buildValidRequest();
|
||||
request.setMaterialNo("MATERIAL_NO_STANDARD_999");
|
||||
|
||||
ApiResult<Void> result = post(API_PATH, request, new TypeReference<>() {});
|
||||
assertFailed(result, "物料无检验标准应返回失败");
|
||||
System.out.println(" ✅ 物料无检验标准校验通过");
|
||||
}
|
||||
|
||||
/**
|
||||
* 【库存检测申请】物料及标准均存在但无绑定的质检人员
|
||||
* 验证点:接口返回业务错误(该物料未绑定质检人员,无法自动分配)
|
||||
* 注意:需要一个有物料和标准但物料/类别层级均未绑定IQE的物料编号
|
||||
*/
|
||||
@Test
|
||||
@Order(32)
|
||||
public void test32_inventoryApply_NoInspectorBound() {
|
||||
ExternalInventoryInspectionApplyQO request = buildValidRequest();
|
||||
request.setMaterialNo("MATERIAL_NO_INSPECTOR_999");
|
||||
|
||||
ApiResult<Void> result = post(API_PATH, request, new TypeReference<>() {});
|
||||
assertFailed(result, "物料未绑定质检人员应返回失败");
|
||||
System.out.println(" ✅ 物料未绑定质检人员校验通过");
|
||||
}
|
||||
|
||||
/**
|
||||
* 【库存检测申请】请求体为空
|
||||
* 验证点:传入空 body 时接口返回失败
|
||||
*/
|
||||
@Test
|
||||
@Order(33)
|
||||
public void test33_inventoryApply_EmptyBody() {
|
||||
ApiResult<Void> result = post(API_PATH, null, new TypeReference<>() {});
|
||||
assertFailed(result, "空请求体应返回失败");
|
||||
System.out.println(" ✅ 空请求体校验通过");
|
||||
}
|
||||
|
||||
// ==================== 辅助方法 ====================
|
||||
|
||||
/**
|
||||
* 构建一个有效的库存检测申请请求参数(所有必填字段)
|
||||
*/
|
||||
private ExternalInventoryInspectionApplyQO buildValidRequest() {
|
||||
ExternalInventoryInspectionApplyQO request = new ExternalInventoryInspectionApplyQO();
|
||||
request.setMaterialNo(VALID_MATERIAL_NO);
|
||||
request.setFactory(VALID_FACTORY);
|
||||
request.setInspectionQty(100);
|
||||
request.setWarehouse(VALID_WAREHOUSE);
|
||||
request.setStorageLocation(VALID_STORAGE_LOCATION);
|
||||
request.setStorageDays(VALID_STORAGE_DAYS);
|
||||
return request;
|
||||
}
|
||||
}
|
||||
|
|
@ -24,9 +24,4 @@ public class QmsIncomingInspectionTaskAqlRuleSearchQO extends PageQO {
|
|||
* 物料编码(模糊匹配)
|
||||
*/
|
||||
private String materialNo;
|
||||
|
||||
/**
|
||||
* 检测项id(精确匹配)
|
||||
*/
|
||||
private Long inspectionItemId;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
package com.nflg.wms.common.pojo.qo;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 质量问题工单 审核参数
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class QmsIssueTicketAuditQO {
|
||||
|
||||
/**
|
||||
* 工单ID
|
||||
*/
|
||||
@NotNull(message = "工单ID不能为空")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 审批状态:0=通过,1=驳回,2=重检,3=报废,4=维修,5=挑选使用,6=让渡使用
|
||||
*/
|
||||
@NotNull(message = "审批状态不能为空")
|
||||
private Short approvalStatus;
|
||||
|
||||
/**
|
||||
* 审批意见
|
||||
*/
|
||||
private String approvalOpinion;
|
||||
|
||||
/**
|
||||
* 事故类型:0=一般,1=较严重,2=严重
|
||||
*/
|
||||
@NotNull(message = "事故类型不能为空")
|
||||
@Min(value = 0, message = "事故类型不能小于0")
|
||||
@Min(value = 2, message = "事故类型不能大于2")
|
||||
private Short incidentType;
|
||||
}
|
||||
|
|
@ -41,14 +41,9 @@ public class QmsIncomingInspectionTaskAqlRuleVO {
|
|||
private String materialDesc;
|
||||
|
||||
/**
|
||||
* 检测项id,关联检验标准项表
|
||||
* 检测标准版本号
|
||||
*/
|
||||
private Long inspectionItemId;
|
||||
|
||||
/**
|
||||
* 检测项名称
|
||||
*/
|
||||
private String inspectionItemName;
|
||||
private String version;
|
||||
|
||||
/**
|
||||
* 计算的AQL类型(字典项id)
|
||||
|
|
|
|||
|
|
@ -162,6 +162,11 @@ public class QmsIncomingInspectionTaskVO {
|
|||
*/
|
||||
private Long relatedTaskNo;
|
||||
|
||||
/**
|
||||
* 采购组
|
||||
*/
|
||||
private String purchaseGroup;
|
||||
|
||||
/**
|
||||
* 最近更新人id
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.nflg.wms.repository.entity;
|
|||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
|
@ -157,4 +158,10 @@ public class QmsIssueTicket implements Serializable {
|
|||
* 更新时间
|
||||
*/
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 逻辑删除:0=未删除,1=已删除
|
||||
*/
|
||||
@TableLogic
|
||||
private Integer deleted;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,4 +20,6 @@ public interface QmsIncomingInspectionTaskRecordItemMapper extends BaseMapper<Qm
|
|||
List<QmsIssueTicketInspectionRecordItemVO> getNonconformanceDataGroups(Long recordId);
|
||||
|
||||
List<QmsIssueTicketInspectionRecordItemSimpleVO> getUnqualifiedRecordItems(Long taskId);
|
||||
|
||||
List<String> getUnqualifiedRecordItemDataImages(Long taskId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,4 +20,6 @@ public interface IQmsIncomingInspectionTaskRecordItemService extends IService<Qm
|
|||
List<QmsIssueTicketInspectionRecordItemVO> getNonconformanceDataGroups(Long recordId);
|
||||
|
||||
List<QmsIssueTicketInspectionRecordItemSimpleVO> getUnqualifiedRecordItems(Long taskId);
|
||||
|
||||
List<String> getUnqualifiedRecordItemDataImages(Long taskId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import java.util.List;
|
|||
@Service
|
||||
public class QmsIncomingInspectionTaskRecordItemServiceImpl extends ServiceImpl<QmsIncomingInspectionTaskRecordItemMapper, QmsIncomingInspectionTaskRecordItem>
|
||||
implements IQmsIncomingInspectionTaskRecordItemService {
|
||||
|
||||
@Override
|
||||
public List<QmsIssueTicketInspectionRecordItemVO> getNonconformanceDataGroups(Long recordId) {
|
||||
return baseMapper.getNonconformanceDataGroups(recordId);
|
||||
|
|
@ -30,4 +31,9 @@ public class QmsIncomingInspectionTaskRecordItemServiceImpl extends ServiceImpl<
|
|||
public List<QmsIssueTicketInspectionRecordItemSimpleVO> getUnqualifiedRecordItems(Long taskId) {
|
||||
return baseMapper.getUnqualifiedRecordItems(taskId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getUnqualifiedRecordItemDataImages(Long taskId) {
|
||||
return baseMapper.getUnqualifiedRecordItemDataImages(taskId);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@
|
|||
m.material_no,
|
||||
m.material_name,
|
||||
m.material_desc,
|
||||
r.inspection_item_id,
|
||||
si.name AS inspection_item_name,
|
||||
s.version,
|
||||
r.calculated_aql_type,
|
||||
r.used_aql_type,
|
||||
r.trigger_category,
|
||||
|
|
@ -26,7 +25,7 @@
|
|||
FROM qms_incoming_inspection_task_aql_rule r
|
||||
INNER JOIN qms_incoming_inspection_task t ON r.task_id = t.id
|
||||
INNER JOIN qms_qc_material m ON t.material_id = m.id
|
||||
LEFT JOIN qms_inspection_standard_item si ON r.inspection_item_id = si.id
|
||||
LEFT JOIN qms_inspection_standard s ON r.inspection_standard_id = s.id
|
||||
<where>
|
||||
t.inspection_status IN (0, 1)
|
||||
<if test="request.supplierCode != null and request.supplierCode != ''">
|
||||
|
|
@ -38,9 +37,6 @@
|
|||
<if test="request.materialNo != null and request.materialNo != ''">
|
||||
AND m.material_no ilike concat('%', #{request.materialNo}, '%')
|
||||
</if>
|
||||
<if test="request.inspectionItemId != null">
|
||||
AND r.inspection_item_id = #{request.inspectionItemId}
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY t.id ASC, r.id ASC
|
||||
</select>
|
||||
|
|
|
|||
|
|
@ -205,7 +205,8 @@
|
|||
t2.task_no as related_task_no,
|
||||
t.update_user_id,
|
||||
t.update_user_name,
|
||||
t.update_time
|
||||
t.update_time,
|
||||
t.purchase_group
|
||||
FROM qms_incoming_inspection_task t
|
||||
LEFT JOIN qms_qc_material m ON t.material_id = m.id
|
||||
LEFT JOIN qms_inspection_standard s ON t.inspection_standard_id = s.id
|
||||
|
|
|
|||
|
|
@ -17,6 +17,16 @@
|
|||
INNER JOIN qms_incoming_inspection_task_record_item iitri ON iitr."id"=iitri.record_id
|
||||
INNER JOIN qms_inspection_standard_item_content isic ON isic."id"=iitri.inspection_standard_item_content_id
|
||||
INNER JOIN qms_inspection_standard_item isi ON isic.inspection_standard_item_id=isi."id"
|
||||
WHERE iitr.task_id=#{taskId}
|
||||
WHERE iitr.task_id=#{taskId} and iitri.unqualified_qty>0
|
||||
</select>
|
||||
|
||||
<select id="getUnqualifiedRecordItemDataImages" resultType="java.lang.String">
|
||||
SELECT iitrid.image_ids
|
||||
FROM qms_incoming_inspection_task_record iitr
|
||||
INNER JOIN qms_incoming_inspection_task_record_item iitri ON iitr."id"=iitri.record_id
|
||||
INNER JOIN qms_incoming_inspection_task_record_item_data iitrid ON iitrid.item_id=iitri."id"
|
||||
INNER JOIN qms_inspection_standard_item_content isic ON isic."id"=iitri.inspection_standard_item_content_id
|
||||
INNER JOIN qms_inspection_standard_item isi ON isic.inspection_standard_item_id=isi."id"
|
||||
WHERE iitr.task_id=#{taskId} and iitri.unqualified_qty>0
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
|
|||
Loading…
Reference in New Issue