Compare commits
No commits in common. "b41fbee3628c8b11fc162fbd6b23fd454356b9a0" and "5464981d5f8812187f22891864aaf6fe079115fd" have entirely different histories.
b41fbee362
...
5464981d5f
|
|
@ -21,7 +21,6 @@ import org.springframework.stereotype.Component;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
@ -770,13 +769,7 @@ public class IncomingInspectionTaskControllerService {
|
||||||
return samplingPlanInspection.getCodeLetterId();
|
return samplingPlanInspection.getCodeLetterId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public void submitCheckItem(QmsIncomingInspectionTaskTodoCheckSubmitQO request) {
|
public void submitCheckItem(QmsIncomingInspectionTaskTodoCheckSubmitQO request) {
|
||||||
LocalDateTime now = LocalDateTime.now();
|
|
||||||
Long userId = UserUtil.getUserId();
|
|
||||||
String userName = UserUtil.getUserName();
|
|
||||||
|
|
||||||
// 1. 保存/更新检验记录
|
|
||||||
QmsIncomingInspectionTaskRecord record = new QmsIncomingInspectionTaskRecord()
|
QmsIncomingInspectionTaskRecord record = new QmsIncomingInspectionTaskRecord()
|
||||||
.setId(request.getId())
|
.setId(request.getId())
|
||||||
.setTaskId(request.getTaskId())
|
.setTaskId(request.getTaskId())
|
||||||
|
|
@ -785,70 +778,35 @@ public class IncomingInspectionTaskControllerService {
|
||||||
.setUnqualifiedQty(request.getUnqualifiedQty())
|
.setUnqualifiedQty(request.getUnqualifiedQty())
|
||||||
.setInspectionQty(request.getInspectionQty())
|
.setInspectionQty(request.getInspectionQty())
|
||||||
.setQualified(Objects.equals(request.getQualifiedQty(), request.getInspectionQty()))
|
.setQualified(Objects.equals(request.getQualifiedQty(), request.getInspectionQty()))
|
||||||
.setCreateUserId(userId)
|
.setCreateUserId(UserUtil.getUserId())
|
||||||
.setCreateUserName(userName)
|
.setCreateUserName(UserUtil.getUserName())
|
||||||
.setCreateTime(now);
|
.setCreateTime(LocalDateTime.now());
|
||||||
incomingInspectionTaskRecordService.saveOrUpdate(record);
|
incomingInspectionTaskRecordService.saveOrUpdate(record);
|
||||||
|
request.getItems().forEach(item -> {
|
||||||
// 2. 收集所有检验项实体,区分新增和更新
|
|
||||||
List<QmsIncomingInspectionTaskRecordItem> allItemEntities = new ArrayList<>();
|
|
||||||
List<QmsIncomingInspectionTaskRecordItem> insertItems = new ArrayList<>();
|
|
||||||
List<QmsIncomingInspectionTaskRecordItem> updateItems = new ArrayList<>();
|
|
||||||
|
|
||||||
for (QmsIncomingInspectionTaskTodoCheckSubmitItemQO item : request.getItems()) {
|
|
||||||
QmsIncomingInspectionTaskRecordItem ditem = new QmsIncomingInspectionTaskRecordItem()
|
QmsIncomingInspectionTaskRecordItem ditem = new QmsIncomingInspectionTaskRecordItem()
|
||||||
.setId(item.getId())
|
.setId(item.getId())
|
||||||
.setRecordId(record.getId())
|
.setRecordId(record.getId())
|
||||||
.setRemark(item.getRemark())
|
.setRemark(item.getRemark())
|
||||||
.setInspectionStandardItemContentId(item.getInspectionStandardItemContentId());
|
.setInspectionStandardItemContentId(item.getInspectionStandardItemContentId());
|
||||||
allItemEntities.add(ditem);
|
incomingInspectionTaskRecordItemService.saveOrUpdate(ditem);
|
||||||
if (item.getId() == null) {
|
item.getDatas().forEach(data -> {
|
||||||
insertItems.add(ditem);
|
|
||||||
} else {
|
|
||||||
updateItems.add(ditem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 批量保存/更新检验项
|
|
||||||
if (!insertItems.isEmpty()) {
|
|
||||||
incomingInspectionTaskRecordItemService.saveBatch(insertItems);
|
|
||||||
}
|
|
||||||
if (!updateItems.isEmpty()) {
|
|
||||||
incomingInspectionTaskRecordItemService.updateBatchById(updateItems);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. 收集所有样本数据实体,区分新增和更新
|
|
||||||
List<QmsIncomingInspectionTaskRecordItemData> insertDatas = new ArrayList<>();
|
|
||||||
List<QmsIncomingInspectionTaskRecordItemData> updateDatas = new ArrayList<>();
|
|
||||||
|
|
||||||
List<QmsIncomingInspectionTaskTodoCheckSubmitItemQO> itemQOs = request.getItems();
|
|
||||||
for (int i = 0; i < itemQOs.size(); i++) {
|
|
||||||
QmsIncomingInspectionTaskRecordItem ditem = allItemEntities.get(i);
|
|
||||||
for (QmsIncomingInspectionTaskTodoCheckSubmitItemDataQO data : itemQOs.get(i).getDatas()) {
|
|
||||||
String imageIds = CollectionUtil.isEmpty(data.getImages()) ? null
|
|
||||||
: StrUtil.join(",", data.getImages().stream().map(FileUploadVO::getId).toList());
|
|
||||||
QmsIncomingInspectionTaskRecordItemData ddata = new QmsIncomingInspectionTaskRecordItemData()
|
QmsIncomingInspectionTaskRecordItemData ddata = new QmsIncomingInspectionTaskRecordItemData()
|
||||||
.setId(data.getId())
|
.setId(data.getId())
|
||||||
.setTaskId(record.getTaskId())
|
.setTaskId(record.getTaskId())
|
||||||
.setItemId(ditem.getId())
|
.setItemId(ditem.getId())
|
||||||
.setQualified(data.getQualified())
|
.setQualified(data.getQualified())
|
||||||
.setMeasuredValue(data.getMeasuredValue())
|
.setMeasuredValue(data.getMeasuredValue())
|
||||||
.setImages(imageIds);
|
.setImages(
|
||||||
if (data.getId() == null) {
|
StrUtil.join(",",
|
||||||
insertDatas.add(ddata);
|
data.getImages()
|
||||||
} else {
|
.stream()
|
||||||
updateDatas.add(ddata);
|
.map(FileUploadVO::getId)
|
||||||
}
|
.toList()
|
||||||
}
|
)
|
||||||
}
|
);
|
||||||
|
incomingInspectionTaskRecordItemDataService.saveOrUpdate(ddata);
|
||||||
// 5. 批量保存/更新样本数据
|
});
|
||||||
if (!insertDatas.isEmpty()) {
|
});
|
||||||
incomingInspectionTaskRecordItemDataService.saveBatch(insertDatas);
|
|
||||||
}
|
|
||||||
if (!updateDatas.isEmpty()) {
|
|
||||||
incomingInspectionTaskRecordItemDataService.updateBatchById(updateDatas);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,393 +0,0 @@
|
||||||
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.QmsIncomingInspectionTaskTodoCheckSubmitItemDataQO;
|
|
||||||
import com.nflg.wms.common.pojo.qo.QmsIncomingInspectionTaskTodoCheckSubmitItemQO;
|
|
||||||
import com.nflg.wms.common.pojo.qo.QmsIncomingInspectionTaskTodoCheckSubmitQO;
|
|
||||||
import com.nflg.wms.common.pojo.vo.FileUploadVO;
|
|
||||||
import org.junit.jupiter.api.MethodOrderer;
|
|
||||||
import org.junit.jupiter.api.Order;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.TestMethodOrder;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 提交检测项(addCheckItem)接口测试
|
|
||||||
* <p>
|
|
||||||
* 测试前提:
|
|
||||||
* 1. qms-admin 服务已启动(默认 http://localhost:8105)
|
|
||||||
* 2. 测试账号已登录,将有效的 token 填入 TOKEN 常量
|
|
||||||
* 3. 数据库中存在有效的任务ID(VALID_TASK_ID)和对应的物料唯一编号(VALID_MATERIAL_UNIQUE_NO)
|
|
||||||
* 4. VALID_STANDARD_ITEM_CONTENT_ID 对应数据库中已存在的检验标准项内容ID
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
|
||||||
public class QmsIncomingInspectionTaskApiTest {
|
|
||||||
|
|
||||||
// ===================== 配置区 =====================
|
|
||||||
/** 服务地址 */
|
|
||||||
private static final String BASE_URL = "http://localhost:8105";
|
|
||||||
/** 当前登录用户的 token */
|
|
||||||
private static final String TOKEN = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOjEsInJuU3RyIjoiU0VxNWhlcXdHOERvVTBkeWFLZnZDbW1FTGFuek5jQlMiLCJuYW1lIjoi6LaF57qn566h55CG5ZGYIiwiY29kZSI6ImFkbWluIiwicm9sZXMiOlsiU3VwZXJBZG1pbiJdLCJ0eXBlIjoxfQ.wuEnMU5vJSqh2vr69MKooFUHD04-_-86eeJee_2zir4";
|
|
||||||
/** 有效的任务ID */
|
|
||||||
private static final Long VALID_TASK_ID = 2046829044461977601L;
|
|
||||||
/** 有效的物料唯一编号 */
|
|
||||||
private static final String VALID_MATERIAL_UNIQUE_NO = "MAT_UNIQUE_001";
|
|
||||||
/** 有效的检验标准项内容ID */
|
|
||||||
private static final Long VALID_STANDARD_ITEM_CONTENT_ID = 2047511371773046785L;
|
|
||||||
// ===================== 配置区结束 =====================
|
|
||||||
|
|
||||||
// ==================== 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. inspectionQty == qualifiedQty,记录应标记为合格
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
@Order(1)
|
|
||||||
public void test01_addCheckItem_Success_AllQualified() {
|
|
||||||
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
|
|
||||||
request.setQualifiedQty(5);
|
|
||||||
request.setUnqualifiedQty(0);
|
|
||||||
request.setInspectionQty(5);
|
|
||||||
|
|
||||||
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
|
|
||||||
assertSuccess(result, "提交检测项(全部合格)失败");
|
|
||||||
System.out.println(" ✅ 提交检测项(全部合格)成功");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【提交检测项】正常提交(存在不合格样本)
|
|
||||||
* 验证点:
|
|
||||||
* 1. 接口返回成功
|
|
||||||
* 2. qualifiedQty < inspectionQty,记录应标记为不合格
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
@Order(2)
|
|
||||||
public void test02_addCheckItem_Success_PartialUnqualified() {
|
|
||||||
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
|
|
||||||
request.setQualifiedQty(3);
|
|
||||||
request.setUnqualifiedQty(2);
|
|
||||||
request.setInspectionQty(5);
|
|
||||||
|
|
||||||
// 不合格样本设置 qualified=false
|
|
||||||
QmsIncomingInspectionTaskTodoCheckSubmitItemDataQO unqualifiedData =
|
|
||||||
buildItemData(false, new BigDecimal("9.5"), Collections.emptyList());
|
|
||||||
request.getItems().get(0).getDatas().add(unqualifiedData);
|
|
||||||
|
|
||||||
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
|
|
||||||
assertSuccess(result, "提交检测项(含不合格样本)失败");
|
|
||||||
System.out.println(" ✅ 提交检测项(含不合格样本)成功");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【提交检测项】带图片的样本提交
|
|
||||||
* 验证点:图片ID能正常保存到检验数据记录
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
@Order(3)
|
|
||||||
public void test03_addCheckItem_Success_WithImages() {
|
|
||||||
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
|
|
||||||
|
|
||||||
FileUploadVO image = new FileUploadVO(100L, "test_image.jpg", "http://example.com/test_image.jpg");
|
|
||||||
request.getItems().get(0).getDatas().get(0).setImages(List.of(image));
|
|
||||||
|
|
||||||
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
|
|
||||||
assertSuccess(result, "带图片提交检测项失败");
|
|
||||||
System.out.println(" ✅ 带图片提交检测项成功");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【提交检测项】带备注的检验项提交
|
|
||||||
* 验证点:备注字段能正常保存
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
@Order(4)
|
|
||||||
public void test04_addCheckItem_Success_WithRemark() {
|
|
||||||
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
|
|
||||||
request.getItems().get(0).setRemark("外观轻微划痕,不影响功能");
|
|
||||||
|
|
||||||
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
|
|
||||||
assertSuccess(result, "带备注提交检测项失败");
|
|
||||||
System.out.println(" ✅ 带备注提交检测项成功");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【提交检测项】更新已有检验记录(传入已有ID)
|
|
||||||
* 验证点:当 id 不为 null 时,接口执行 saveOrUpdate 逻辑,更新已有记录
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
@Order(5)
|
|
||||||
public void test05_addCheckItem_Success_UpdateExisting() {
|
|
||||||
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
|
|
||||||
request.setId(1L); // 已存在的记录ID,根据实际环境替换
|
|
||||||
|
|
||||||
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
|
|
||||||
assertSuccess(result, "更新已有检验记录失败");
|
|
||||||
System.out.println(" ✅ 更新已有检验记录成功");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【提交检测项】任务ID为空
|
|
||||||
* 验证点:接口返回参数校验错误(@NotNull 校验)
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
@Order(6)
|
|
||||||
public void test06_addCheckItem_Fail_TaskIdNull() {
|
|
||||||
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
|
|
||||||
request.setTaskId(null);
|
|
||||||
|
|
||||||
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
|
|
||||||
assertFailed(result, "任务ID为空应返回失败");
|
|
||||||
System.out.println(" ✅ 任务ID为空校验通过");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【提交检测项】物料唯一编号为空
|
|
||||||
* 验证点:接口返回参数校验错误(@NotNull 校验)
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
@Order(7)
|
|
||||||
public void test07_addCheckItem_Fail_MaterialUniqueNoNull() {
|
|
||||||
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
|
|
||||||
request.setMaterialUniqueNo(null);
|
|
||||||
|
|
||||||
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
|
|
||||||
assertFailed(result, "物料唯一编号为空应返回失败");
|
|
||||||
System.out.println(" ✅ 物料唯一编号为空校验通过");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【提交检测项】样本数量为空
|
|
||||||
* 验证点:接口返回参数校验错误(@NotNull 校验)
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
@Order(8)
|
|
||||||
public void test08_addCheckItem_Fail_InspectionQtyNull() {
|
|
||||||
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
|
|
||||||
request.setInspectionQty(null);
|
|
||||||
|
|
||||||
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
|
|
||||||
assertFailed(result, "样本数量为空应返回失败");
|
|
||||||
System.out.println(" ✅ 样本数量为空校验通过");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【提交检测项】合格数量为空
|
|
||||||
* 验证点:接口返回参数校验错误(@NotNull 校验)
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
@Order(9)
|
|
||||||
public void test09_addCheckItem_Fail_QualifiedQtyNull() {
|
|
||||||
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
|
|
||||||
request.setQualifiedQty(null);
|
|
||||||
|
|
||||||
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
|
|
||||||
assertFailed(result, "合格数量为空应返回失败");
|
|
||||||
System.out.println(" ✅ 合格数量为空校验通过");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【提交检测项】不合格数量为空
|
|
||||||
* 验证点:接口返回参数校验错误(@NotNull 校验)
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
@Order(10)
|
|
||||||
public void test10_addCheckItem_Fail_UnqualifiedQtyNull() {
|
|
||||||
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
|
|
||||||
request.setUnqualifiedQty(null);
|
|
||||||
|
|
||||||
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
|
|
||||||
assertFailed(result, "不合格数量为空应返回失败");
|
|
||||||
System.out.println(" ✅ 不合格数量为空校验通过");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【提交检测项】检验项列表为空
|
|
||||||
* 验证点:接口返回参数校验错误(@NotEmpty 校验)
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
@Order(11)
|
|
||||||
public void test11_addCheckItem_Fail_ItemsEmpty() {
|
|
||||||
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
|
|
||||||
request.setItems(Collections.emptyList());
|
|
||||||
|
|
||||||
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
|
|
||||||
assertFailed(result, "检验项列表为空应返回失败");
|
|
||||||
System.out.println(" ✅ 检验项列表为空校验通过");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【提交检测项】检验项列表为null
|
|
||||||
* 验证点:接口返回参数校验错误(@NotEmpty 校验)
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
@Order(12)
|
|
||||||
public void test12_addCheckItem_Fail_ItemsNull() {
|
|
||||||
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
|
|
||||||
request.setItems(null);
|
|
||||||
|
|
||||||
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
|
|
||||||
assertFailed(result, "检验项列表为null应返回失败");
|
|
||||||
System.out.println(" ✅ 检验项列表为null校验通过");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【提交检测项】检验项中检验标准项内容ID为空
|
|
||||||
* 验证点:接口返回参数校验错误(@NotNull 级联校验)
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
@Order(13)
|
|
||||||
public void test13_addCheckItem_Fail_ItemContentIdNull() {
|
|
||||||
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
|
|
||||||
request.getItems().get(0).setInspectionStandardItemContentId(null);
|
|
||||||
|
|
||||||
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
|
|
||||||
assertFailed(result, "检验标准项内容ID为空应返回失败");
|
|
||||||
System.out.println(" ✅ 检验标准项内容ID为空校验通过");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【提交检测项】检验项的样本列表为空
|
|
||||||
* 验证点:接口返回参数校验错误(@NotEmpty 级联校验)
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
@Order(14)
|
|
||||||
public void test14_addCheckItem_Fail_ItemDatasEmpty() {
|
|
||||||
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
|
|
||||||
request.getItems().get(0).setDatas(Collections.emptyList());
|
|
||||||
|
|
||||||
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
|
|
||||||
assertFailed(result, "样本列表为空应返回失败");
|
|
||||||
System.out.println(" ✅ 样本列表为空校验通过");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【提交检测项】样本中是否合格字段为空
|
|
||||||
* 验证点:接口返回参数校验错误(@NotNull 级联校验)
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
@Order(15)
|
|
||||||
public void test15_addCheckItem_Fail_DataQualifiedNull() {
|
|
||||||
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
|
|
||||||
request.getItems().get(0).getDatas().get(0).setQualified(null);
|
|
||||||
|
|
||||||
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
|
|
||||||
assertFailed(result, "是否合格字段为空应返回失败");
|
|
||||||
System.out.println(" ✅ 是否合格字段为空校验通过");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【提交检测项】多个检验项提交
|
|
||||||
* 验证点:可以一次提交多个检验项,每项下有多个样本数据
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
@Order(16)
|
|
||||||
public void test16_addCheckItem_Success_MultipleItems() {
|
|
||||||
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
|
|
||||||
|
|
||||||
QmsIncomingInspectionTaskTodoCheckSubmitItemQO item2 = buildItem(VALID_STANDARD_ITEM_CONTENT_ID + 1, null);
|
|
||||||
request.setItems(new ArrayList<>(List.of(request.getItems().get(0), item2)));
|
|
||||||
|
|
||||||
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
|
|
||||||
assertSuccess(result, "多个检验项提交失败");
|
|
||||||
System.out.println(" ✅ 多个检验项提交成功");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【提交检测项】请求体为空(无请求体)
|
|
||||||
* 验证点:接口返回参数解析或校验错误
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
@Order(17)
|
|
||||||
public void test17_addCheckItem_Fail_EmptyBody() {
|
|
||||||
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", null, new TypeReference<>() {});
|
|
||||||
assertFailed(result, "空请求体应返回失败");
|
|
||||||
System.out.println(" ✅ 空请求体校验通过");
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==================== 辅助方法 ====================
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构建一个有效的提交检测项请求
|
|
||||||
*/
|
|
||||||
private QmsIncomingInspectionTaskTodoCheckSubmitQO buildValidRequest() {
|
|
||||||
QmsIncomingInspectionTaskTodoCheckSubmitQO request = new QmsIncomingInspectionTaskTodoCheckSubmitQO();
|
|
||||||
request.setTaskId(VALID_TASK_ID);
|
|
||||||
request.setMaterialUniqueNo(VALID_MATERIAL_UNIQUE_NO);
|
|
||||||
request.setInspectionQty(5);
|
|
||||||
request.setQualifiedQty(5);
|
|
||||||
request.setUnqualifiedQty(0);
|
|
||||||
request.setItems(new ArrayList<>(List.of(buildItem(VALID_STANDARD_ITEM_CONTENT_ID, null))));
|
|
||||||
return request;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构建一个检验项
|
|
||||||
*
|
|
||||||
* @param contentId 检验标准项内容ID
|
|
||||||
* @param remark 备注(可为null)
|
|
||||||
*/
|
|
||||||
private QmsIncomingInspectionTaskTodoCheckSubmitItemQO buildItem(Long contentId, String remark) {
|
|
||||||
QmsIncomingInspectionTaskTodoCheckSubmitItemQO item = new QmsIncomingInspectionTaskTodoCheckSubmitItemQO();
|
|
||||||
item.setInspectionStandardItemContentId(contentId);
|
|
||||||
item.setRemark(remark);
|
|
||||||
item.setDatas(new ArrayList<>(List.of(buildItemData(true, new BigDecimal("10.5"), Collections.emptyList()))));
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构建一个样本数据
|
|
||||||
*
|
|
||||||
* @param qualified 是否合格
|
|
||||||
* @param measuredValue 测量值(可为null)
|
|
||||||
* @param images 图片列表
|
|
||||||
*/
|
|
||||||
private QmsIncomingInspectionTaskTodoCheckSubmitItemDataQO buildItemData(
|
|
||||||
Boolean qualified, BigDecimal measuredValue, List<FileUploadVO> images) {
|
|
||||||
QmsIncomingInspectionTaskTodoCheckSubmitItemDataQO data =
|
|
||||||
new QmsIncomingInspectionTaskTodoCheckSubmitItemDataQO();
|
|
||||||
data.setQualified(qualified);
|
|
||||||
data.setMeasuredValue(measuredValue);
|
|
||||||
data.setImages(images);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
package com.nflg.wms.scheduled.processor;
|
package com.nflg.wms.scheduled.processor;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
|
||||||
import cn.hutool.core.collection.CollectionUtil;
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.nflg.wms.common.pojo.dto.MaterialMainListByDateDTO;
|
import com.nflg.wms.common.pojo.dto.MaterialMainListByDateDTO;
|
||||||
|
|
@ -18,11 +17,8 @@ import tech.powerjob.worker.log.OmsLogger;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从主物料同步物料到QMS
|
* 从主物料同步物料到QMS
|
||||||
|
|
@ -48,120 +44,97 @@ public class QCMaterialSyncProcessor implements BasicProcessor {
|
||||||
|
|
||||||
// 从主物料系统查询指定日期范围的物料列表
|
// 从主物料系统查询指定日期范围的物料列表
|
||||||
List<MaterialMainListByDateDTO> materials = bomMaterialService.getListByDate(startDateTime, endDateTime);
|
List<MaterialMainListByDateDTO> materials = bomMaterialService.getListByDate(startDateTime, endDateTime);
|
||||||
|
|
||||||
if (CollectionUtil.isEmpty(materials)) {
|
if (CollectionUtil.isEmpty(materials)) {
|
||||||
log.info("没有需要同步的物料");
|
log.info("没有需要同步的物料");
|
||||||
return new ProcessResult(true);
|
} else {
|
||||||
}
|
|
||||||
|
|
||||||
Long userId = UserUtil.getUserId();
|
Long userId = UserUtil.getUserId();
|
||||||
String operator = UserUtil.getUserName();
|
String operator = UserUtil.getUserName();
|
||||||
LocalDateTime now = LocalDateTime.now();
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
|
||||||
// 过滤掉物料类别编码为空的记录,并按 materialNo 去重
|
// 过滤掉物料类别编码为空的记录
|
||||||
List<MaterialMainListByDateDTO> validMaterials = materials.stream()
|
List<MaterialMainListByDateDTO> validMaterials = materials.stream()
|
||||||
.filter(dto -> {
|
.filter(dto -> {
|
||||||
if (StrUtil.isBlank(dto.getMaterialCategoryCode())) {
|
if (StrUtil.isBlank(dto.getMaterialCategoryCode())) {
|
||||||
log.warn("物料类别编码为空:{}", dto.getMaterialNo());
|
log.warn("物料类别编码为空:{}", dto.getMaterialNo());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.collect(Collectors.toMap(
|
.collect(java.util.stream.Collectors.toList());
|
||||||
MaterialMainListByDateDTO::getMaterialNo,
|
|
||||||
dto -> dto,
|
|
||||||
(existing, replacement) -> existing))
|
|
||||||
.values()
|
|
||||||
.stream()
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
if (CollectionUtil.isEmpty(validMaterials)) {
|
if (CollectionUtil.isEmpty(validMaterials)) {
|
||||||
log.info("没有需要同步的物料");
|
log.info("没有需要同步的物料");
|
||||||
return new ProcessResult(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 批量查询已存在的物料,构建 materialNo -> QmsQcMaterial 映射(分批查询避免 IN 子句过长)
|
|
||||||
List<String> materialNos = validMaterials.stream()
|
|
||||||
.map(MaterialMainListByDateDTO::getMaterialNo)
|
|
||||||
.toList();
|
|
||||||
Map<String, QmsQcMaterial> existMaterialMap = batchQueryExistMaterials(materialNos);
|
|
||||||
|
|
||||||
List<QmsQcMaterial> insertList = new ArrayList<>();
|
|
||||||
List<QmsQcMaterial> updateList = new ArrayList<>();
|
|
||||||
|
|
||||||
for (MaterialMainListByDateDTO materialDTO : validMaterials) {
|
|
||||||
QmsQcMaterial existMaterial = existMaterialMap.get(materialDTO.getMaterialNo());
|
|
||||||
if (existMaterial == null) {
|
|
||||||
// 待新增
|
|
||||||
QmsQcMaterial newMaterial = new QmsQcMaterial()
|
|
||||||
.setMaterialNo(materialDTO.getMaterialNo())
|
|
||||||
.setMaterialName(materialDTO.getMaterialName())
|
|
||||||
.setMaterialDesc(materialDTO.getMaterialDesc())
|
|
||||||
.setMaterialSpecifications(materialDTO.getMaterialSpecifications())
|
|
||||||
.setDrawingNo(materialDTO.getDrawingNo())
|
|
||||||
.setDrawingNoVer(materialDTO.getDrawingNoVersion())
|
|
||||||
.setMaterialTexture(materialDTO.getMaterialTexture())
|
|
||||||
.setMaterialCategoryCode(materialDTO.getMaterialCategoryCode())
|
|
||||||
.setMaterialCategoryCodePathName(materialDTO.getMaterialCategoryFullName())
|
|
||||||
.setIsStandardMaintained(false)
|
|
||||||
.setMaterialDescIsUpgrade(false)
|
|
||||||
.setCreatedType(1) // 1=系统同步
|
|
||||||
.setCreateBy(userId)
|
|
||||||
.setCreateByName(operator)
|
|
||||||
.setCreateTime(now);
|
|
||||||
insertList.add(newMaterial);
|
|
||||||
} else {
|
} else {
|
||||||
// 待更新
|
|
||||||
boolean descChanged = !StrUtil.equals(existMaterial.getMaterialDesc(), materialDTO.getMaterialDesc());
|
// 批量查询已存在的物料,构建 materialNo -> QmsQcMaterial 映射
|
||||||
existMaterial.setMaterialName(materialDTO.getMaterialName())
|
List<String> materialNos = validMaterials.stream()
|
||||||
.setMaterialDesc(materialDTO.getMaterialDesc())
|
.map(MaterialMainListByDateDTO::getMaterialNo)
|
||||||
.setMaterialDescIsUpgrade(descChanged)
|
.collect(java.util.stream.Collectors.toList());
|
||||||
.setMaterialSpecifications(materialDTO.getMaterialSpecifications())
|
Map<String, QmsQcMaterial> existMaterialMap = qcMaterialService.lambdaQuery()
|
||||||
.setDrawingNo(materialDTO.getDrawingNo())
|
.in(QmsQcMaterial::getMaterialNo, materialNos)
|
||||||
.setDrawingNoVer(materialDTO.getDrawingNoVersion())
|
.list()
|
||||||
.setMaterialTexture(materialDTO.getMaterialTexture())
|
.stream()
|
||||||
.setMaterialCategoryCode(materialDTO.getMaterialCategoryCode())
|
.collect(java.util.stream.Collectors.toMap(QmsQcMaterial::getMaterialNo, m -> m));
|
||||||
.setMaterialCategoryCodePathName(materialDTO.getMaterialCategoryFullName())
|
|
||||||
.setUpdateBy(userId)
|
List<QmsQcMaterial> insertList = new java.util.ArrayList<>();
|
||||||
.setUpdateByName(operator)
|
List<QmsQcMaterial> updateList = new java.util.ArrayList<>();
|
||||||
.setUpdateTime(now);
|
|
||||||
updateList.add(existMaterial);
|
for (MaterialMainListByDateDTO materialDTO : validMaterials) {
|
||||||
|
QmsQcMaterial existMaterial = existMaterialMap.get(materialDTO.getMaterialNo());
|
||||||
|
if (existMaterial == null) {
|
||||||
|
// 待新增
|
||||||
|
QmsQcMaterial newMaterial = new QmsQcMaterial()
|
||||||
|
.setMaterialNo(materialDTO.getMaterialNo())
|
||||||
|
.setMaterialName(materialDTO.getMaterialName())
|
||||||
|
.setMaterialDesc(materialDTO.getMaterialDesc())
|
||||||
|
.setMaterialSpecifications(materialDTO.getMaterialSpecifications())
|
||||||
|
.setDrawingNo(materialDTO.getDrawingNo())
|
||||||
|
.setDrawingNoVer(materialDTO.getDrawingNoVersion())
|
||||||
|
.setMaterialTexture(materialDTO.getMaterialTexture())
|
||||||
|
.setMaterialCategoryCode(materialDTO.getMaterialCategoryCode())
|
||||||
|
.setMaterialCategoryCodePathName(materialDTO.getMaterialCategoryFullName())
|
||||||
|
.setIsStandardMaintained(false)
|
||||||
|
.setMaterialDescIsUpgrade(false)
|
||||||
|
.setCreatedType(1) // 1=系统同步
|
||||||
|
.setCreateBy(userId)
|
||||||
|
.setCreateByName(operator)
|
||||||
|
.setCreateTime(now);
|
||||||
|
insertList.add(newMaterial);
|
||||||
|
} else {
|
||||||
|
// 待更新
|
||||||
|
boolean descChanged = !StrUtil.equals(existMaterial.getMaterialDesc(), materialDTO.getMaterialDesc());
|
||||||
|
existMaterial.setMaterialName(materialDTO.getMaterialName())
|
||||||
|
.setMaterialDesc(materialDTO.getMaterialDesc())
|
||||||
|
.setMaterialDescIsUpgrade(descChanged)
|
||||||
|
.setMaterialSpecifications(materialDTO.getMaterialSpecifications())
|
||||||
|
.setDrawingNo(materialDTO.getDrawingNo())
|
||||||
|
.setDrawingNoVer(materialDTO.getDrawingNoVersion())
|
||||||
|
.setMaterialCategoryCode(materialDTO.getMaterialCategoryCode())
|
||||||
|
.setMaterialCategoryCodePathName(materialDTO.getMaterialCategoryFullName())
|
||||||
|
.setUpdateBy(userId)
|
||||||
|
.setUpdateByName(operator)
|
||||||
|
.setUpdateTime(now);
|
||||||
|
updateList.add(existMaterial);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量新增
|
||||||
|
if (CollectionUtil.isNotEmpty(insertList)) {
|
||||||
|
log.info("开始新增物料,数量:{}", insertList.size());
|
||||||
|
qcMaterialService.saveBatch(insertList);
|
||||||
|
}
|
||||||
|
// 批量更新
|
||||||
|
if (CollectionUtil.isNotEmpty(updateList)) {
|
||||||
|
log.info("开始更新物料,数量:{}", updateList.size());
|
||||||
|
qcMaterialService.updateBatchById(updateList);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 批量新增
|
|
||||||
if (CollectionUtil.isNotEmpty(insertList)) {
|
|
||||||
log.info("开始新增物料,数量:{}", insertList.size());
|
|
||||||
qcMaterialService.saveBatch(insertList);
|
|
||||||
}
|
|
||||||
// 批量更新
|
|
||||||
if (CollectionUtil.isNotEmpty(updateList)) {
|
|
||||||
log.info("开始更新物料,数量:{}", updateList.size());
|
|
||||||
qcMaterialService.updateBatchById(updateList);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ProcessResult(true);
|
return new ProcessResult(true);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
return new ProcessResult(false, "同步物料失败: " + ex.getMessage());
|
return new ProcessResult(false, "同步物料失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 分批查询已存在的物料,避免 IN 子句过长
|
|
||||||
*/
|
|
||||||
private Map<String, QmsQcMaterial> batchQueryExistMaterials(List<String> materialNos) {
|
|
||||||
Map<String, QmsQcMaterial> result = new LinkedHashMap<>();
|
|
||||||
// 每批500条,避免SQL IN子句过长
|
|
||||||
CollUtil.split(materialNos, 500).forEach(batch -> {
|
|
||||||
Map<String, QmsQcMaterial> batchMap = qcMaterialService.lambdaQuery()
|
|
||||||
.in(QmsQcMaterial::getMaterialNo, batch)
|
|
||||||
.list()
|
|
||||||
.stream()
|
|
||||||
.collect(Collectors.toMap(
|
|
||||||
QmsQcMaterial::getMaterialNo,
|
|
||||||
m -> m,
|
|
||||||
(existing, replacement) -> existing));
|
|
||||||
result.putAll(batchMap);
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue