From 0aaaf451e8216f11bb603c7d77eb34fb366612e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E9=B9=8F=E9=A3=9E?= Date: Tue, 14 Apr 2026 14:35:58 +0800 Subject: [PATCH] =?UTF-8?q?feat(qms):=20=E6=96=B0=E5=A2=9E=E8=B4=A8?= =?UTF-8?q?=E6=A3=80=E7=89=A9=E6=96=99=E5=88=86=E7=B1=BB=E5=92=8C=E6=A3=80?= =?UTF-8?q?=E9=AA=8C=E6=A0=87=E5=87=86=E6=A8=A1=E5=9D=97=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增质检物料分类服务及其实现,支持按名称和编码模糊查询并构建树形结构 - 添加质检物料分类接口及单元测试,验证类别树查询和条件过滤功能 - 新增检验标准相关实体、服务接口及实现类,实现批量发布和启用/禁用功能 - 增加检验标准分页查询Mapper及XML配置,支持物料编号、类别编码及IQE姓名模糊过滤 - 创建检验标准控制层及对应业务逻辑服务,提供标准的REST接口 - 引入批量ID请求参数类IdsQO及相关启用请求参数支持统一校验 - 完善检验标准VO定义,支持前端展示完整信息 - 规范日志记录和异常处理,确保服务稳定性和代码健壮性 --- .../QmsInspectionStandardController.java | 53 +++ .../QmsQcMaterialCategoryController.java | 33 ++ ...msInspectionStandardControllerService.java | 60 ++++ .../admin/QmsQcMaterialCategoryApiTest.java | 329 ++++++++++++++++++ .../com/nflg/wms/common/pojo/qo/IdsQO.java | 16 + .../qo/QmsInspectionStandardSearchQO.java | 27 ++ .../qo/QmsQcMaterialCategorySearchQO.java | 20 ++ .../pojo/vo/QmsInspectionStandardVO.java | 97 ++++++ .../pojo/vo/QmsQcMaterialCategoryVO.java | 42 +++ .../entity/QmsInspectionStandard.java | 113 ++++++ .../entity/QmsInspectionStandardItem.java | 113 ++++++ .../QmsInspectionStandardItemContent.java | 93 +++++ .../mapper/QmsInspectionStandardMapper.java | 20 ++ .../IQmsInspectionStandardService.java | 25 ++ .../IQmsQcMaterialCategoryService.java | 12 + .../QmsInspectionStandardServiceImpl.java | 57 +++ .../QmsQcMaterialCategoryServiceImpl.java | 79 +++++ .../mapper/QmsInspectionStandardMapper.xml | 50 +++ 18 files changed, 1239 insertions(+) create mode 100644 nflg-qms-admin/src/main/java/com/nflg/qms/admin/controller/QmsInspectionStandardController.java create mode 100644 nflg-qms-admin/src/main/java/com/nflg/qms/admin/controller/QmsQcMaterialCategoryController.java create mode 100644 nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsInspectionStandardControllerService.java create mode 100644 nflg-qms-admin/src/test/java/com/nflg/qms/admin/QmsQcMaterialCategoryApiTest.java create mode 100644 nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/IdsQO.java create mode 100644 nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/QmsInspectionStandardSearchQO.java create mode 100644 nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/QmsQcMaterialCategorySearchQO.java create mode 100644 nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/QmsInspectionStandardVO.java create mode 100644 nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/QmsQcMaterialCategoryVO.java create mode 100644 nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/QmsInspectionStandard.java create mode 100644 nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/QmsInspectionStandardItem.java create mode 100644 nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/QmsInspectionStandardItemContent.java create mode 100644 nflg-wms-repository/src/main/java/com/nflg/wms/repository/mapper/QmsInspectionStandardMapper.java create mode 100644 nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IQmsInspectionStandardService.java create mode 100644 nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/QmsInspectionStandardServiceImpl.java create mode 100644 nflg-wms-repository/src/main/resources/mapper/QmsInspectionStandardMapper.xml diff --git a/nflg-qms-admin/src/main/java/com/nflg/qms/admin/controller/QmsInspectionStandardController.java b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/controller/QmsInspectionStandardController.java new file mode 100644 index 00000000..bcb4507f --- /dev/null +++ b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/controller/QmsInspectionStandardController.java @@ -0,0 +1,53 @@ +package com.nflg.qms.admin.controller; + +import com.nflg.qms.admin.service.QmsInspectionStandardControllerService; +import com.nflg.wms.common.pojo.ApiResult; +import com.nflg.wms.common.pojo.PageData; +import com.nflg.wms.common.pojo.qo.EnableQO; +import com.nflg.wms.common.pojo.qo.IdsQO; +import com.nflg.wms.common.pojo.qo.QmsInspectionStandardSearchQO; +import com.nflg.wms.common.pojo.vo.QmsInspectionStandardVO; +import com.nflg.wms.starter.BaseController; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * 检验标准 + */ +@RestController +@RequestMapping("/inspection-standard") +public class QmsInspectionStandardController extends BaseController { + + @Resource + private QmsInspectionStandardControllerService inspectionStandardControllerService; + + /** + * 分页查询检验标准 + */ + @PostMapping("search") + public ApiResult> search(@Valid @RequestBody QmsInspectionStandardSearchQO request) { + return ApiResult.success(inspectionStandardControllerService.search(request)); + } + + /** + * 批量发布检验标准 + */ + @PostMapping("publish") + public ApiResult publish(@Valid @RequestBody IdsQO request) { + inspectionStandardControllerService.publish(request.getIds()); + return ApiResult.success(); + } + + /** + * 启用/禁用检验标准(单条) + */ + @PostMapping("enable") + public ApiResult enable(@Valid @RequestBody EnableQO request) { + inspectionStandardControllerService.enable(request.getId(), request.getEnable()); + return ApiResult.success(); + } +} diff --git a/nflg-qms-admin/src/main/java/com/nflg/qms/admin/controller/QmsQcMaterialCategoryController.java b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/controller/QmsQcMaterialCategoryController.java new file mode 100644 index 00000000..49e2e5b9 --- /dev/null +++ b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/controller/QmsQcMaterialCategoryController.java @@ -0,0 +1,33 @@ +package com.nflg.qms.admin.controller; + +import com.nflg.wms.common.pojo.ApiResult; +import com.nflg.wms.common.pojo.qo.QmsQcMaterialCategorySearchQO; +import com.nflg.wms.common.pojo.vo.QmsQcMaterialCategoryVO; +import com.nflg.wms.repository.service.IQmsQcMaterialCategoryService; +import com.nflg.wms.starter.BaseController; +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * 质检物料类别管理 + */ +@RestController +@RequestMapping("/qcMaterialCategory") +public class QmsQcMaterialCategoryController extends BaseController { + + @Resource + private IQmsQcMaterialCategoryService qcMaterialCategoryService; + + /** + * 查询质检物料类别树(支持模糊查询,不分页) + */ + @PostMapping("search") + public ApiResult> search(@RequestBody QmsQcMaterialCategorySearchQO request) { + return ApiResult.success(qcMaterialCategoryService.searchTree(request)); + } +} diff --git a/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsInspectionStandardControllerService.java b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsInspectionStandardControllerService.java new file mode 100644 index 00000000..5cc173a0 --- /dev/null +++ b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsInspectionStandardControllerService.java @@ -0,0 +1,60 @@ +package com.nflg.qms.admin.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.nflg.wms.common.pojo.PageData; +import com.nflg.wms.common.pojo.qo.QmsInspectionStandardSearchQO; +import com.nflg.wms.common.pojo.vo.QmsInspectionStandardVO; +import com.nflg.wms.repository.mapper.QmsInspectionStandardMapper; +import com.nflg.wms.repository.service.IQmsInspectionStandardService; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 检验标准业务逻辑 + */ +@Slf4j +@Component +public class QmsInspectionStandardControllerService { + + @Resource + private IQmsInspectionStandardService inspectionStandardService; + + @Resource + private QmsInspectionStandardMapper inspectionStandardMapper; + + /** + * 分页查询检验标准 + */ + public PageData search(QmsInspectionStandardSearchQO request) { + IPage page = inspectionStandardMapper.searchPage( + request, new Page<>(request.getPage(), request.getPageSize())); + + PageData result = new PageData<>(); + result.setPage(request.getPage()); + result.setPageSize(request.getPageSize()); + result.setTotal((int) page.getTotal()); + result.setItems(page.getRecords()); + return result; + } + + /** + * 批量发布检验标准 + * @param ids 检验标准ID列表 + */ + public void publish(List ids) { + inspectionStandardService.publish(ids); + } + + /** + * 启用/禁用检验标准(单条) + * @param id 检验标准ID + * @param enable 是否启用 + */ + public void enable(Long id, Boolean enable) { + inspectionStandardService.enable(id, enable); + } +} diff --git a/nflg-qms-admin/src/test/java/com/nflg/qms/admin/QmsQcMaterialCategoryApiTest.java b/nflg-qms-admin/src/test/java/com/nflg/qms/admin/QmsQcMaterialCategoryApiTest.java new file mode 100644 index 00000000..f2f2af58 --- /dev/null +++ b/nflg-qms-admin/src/test/java/com/nflg/qms/admin/QmsQcMaterialCategoryApiTest.java @@ -0,0 +1,329 @@ +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.QmsQcMaterialCategorySearchQO; +import com.nflg.wms.common.pojo.vo.QmsQcMaterialCategoryVO; +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.util.List; + +/** + * QMS 质检物料类别模块接口测试 + *

+ * 测试前提: + * 1. qms-admin 服务已启动(默认 http://localhost:8105) + * 2. 测试账号已登录,将有效的 token 填入 TOKEN 常量 + * 3. 数据库中已存在质检物料类别数据 + *

+ */ +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class QmsQcMaterialCategoryApiTest { + + // ===================== 配置区 ===================== + /** 服务地址 */ + private static final String BASE_URL = "http://localhost:8105"; + /** 当前登录用户的 token */ + private static final String TOKEN = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOjEsInJuU3RyIjoidVFwSWM2R3RJeUoxcFNSczBadzJzb1hvMUZLZXB3czkiLCJuYW1lIjoi6LaF57qn566h55CG5ZGYIiwiY29kZSI6ImFkbWluIiwicm9sZXMiOlsiU3VwZXJBZG1pbiJdLCJ0eXBlIjoxfQ.FtQ2uVwvuxsjAFbXnB006hV1pODtRhZT0z_9nfuR0So"; + // ===================== 配置区结束 ===================== + + // ==================== HTTP 工具方法 ==================== + + private static ApiResult post(String path, Object body, TypeReference> 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 void assertSuccess(ApiResult result, String msg) { + Assert.isTrue(result != null && result.getCode() == 200, + () -> new RuntimeException(msg + " => " + JSONUtil.toJsonStr(result))); + } + + // ==================== 查询类别树接口测试 ==================== + + /** + * 【查询质检物料类别树】正常查询全部类别 + * 验证点: + * 1. 接口返回成功 + * 2. 返回树形结构数据 + * 3. 根节点的parentCategoryRowId为null或0 + */ + @Test + @Order(1) + public void test01_searchCategory_All() { + QmsQcMaterialCategorySearchQO request = new QmsQcMaterialCategorySearchQO(); + + ApiResult> result = post("/qcMaterialCategory/search", request, new TypeReference<>() {}); + assertSuccess(result, "查询全部类别失败"); + + List categories = result.getResult(); + System.out.println(" ✅ 查询全部类别成功,返回树节点数: " + categories.size()); + + // 验证树形结构 + if (!categories.isEmpty()) { + verifyTreeStructure(categories, "根节点"); + } + } + + /** + * 【查询质检物料类别树】按类别名称模糊查询 + * 验证点: + * 1. 接口返回成功 + * 2. 返回包含匹配名称的类别 + * 3. 匹配节点的祖先节点也被返回(保证树形完整) + */ + @Test + @Order(2) + public void test02_searchCategory_ByCategoryName() { + QmsQcMaterialCategorySearchQO request = new QmsQcMaterialCategorySearchQO(); + request.setCategoryName("测试"); + + ApiResult> result = post("/qcMaterialCategory/search", request, new TypeReference<>() {}); + assertSuccess(result, "按类别名称查询失败"); + + List categories = result.getResult(); + System.out.println(" ✅ 按类别名称查询成功,返回树节点数: " + categories.size()); + + // 验证返回的树中包含名称匹配的节点 + if (!categories.isEmpty()) { + boolean hasMatchedNode = hasNodeMatchedByName(categories, "测试"); + Assert.isTrue(hasMatchedNode, () -> new RuntimeException("未找到名称包含'测试'的节点")); + System.out.println(" ✅ 验证通过:返回结果包含名称匹配的节点"); + } + } + + /** + * 【查询质检物料类别树】按类别编号模糊查询 + * 验证点: + * 1. 接口返回成功 + * 2. 返回包含匹配编号的类别 + * 3. 匹配节点的祖先节点也被返回(保证树形完整) + */ + @Test + @Order(3) + public void test03_searchCategory_ByCategoryCode() { + QmsQcMaterialCategorySearchQO request = new QmsQcMaterialCategorySearchQO(); + request.setCategoryCode("CAT"); + + ApiResult> result = post("/qcMaterialCategory/search", request, new TypeReference<>() {}); + assertSuccess(result, "按类别编号查询失败"); + + List categories = result.getResult(); + System.out.println(" ✅ 按类别编号查询成功,返回树节点数: " + categories.size()); + + // 验证返回的树中包含编号匹配的节点 + if (!categories.isEmpty()) { + boolean hasMatchedNode = hasNodeMatchedCode(categories, "CAT"); + Assert.isTrue(hasMatchedNode, () -> new RuntimeException("未找到编号包含'CAT'的节点")); + System.out.println(" ✅ 验证通过:返回结果包含编号匹配的节点"); + } + } + + /** + * 【查询质检物料类别树】同时按名称和编号模糊查询 + * 验证点: + * 1. 接口返回成功 + * 2. 返回同时满足名称和编号条件的类别 + * 3. 匹配节点的祖先节点也被返回 + */ + @Test + @Order(4) + public void test04_searchCategory_ByNameAndCode() { + QmsQcMaterialCategorySearchQO request = new QmsQcMaterialCategorySearchQO(); + request.setCategoryName("测试"); + request.setCategoryCode("CAT"); + + ApiResult> result = post("/qcMaterialCategory/search", request, new TypeReference<>() {}); + assertSuccess(result, "按名称和编号联合查询失败"); + + List categories = result.getResult(); + System.out.println(" ✅ 按名称和编号联合查询成功,返回树节点数: " + categories.size()); + + // 验证树形结构 + if (!categories.isEmpty()) { + verifyTreeStructure(categories, "根节点"); + } + } + + /** + * 【查询质检物料类别树】查询不存在的类别名称 + * 验证点: + * 1. 接口返回成功 + * 2. 返回空列表 + */ + @Test + @Order(5) + public void test05_searchCategory_NoMatchName() { + QmsQcMaterialCategorySearchQO request = new QmsQcMaterialCategorySearchQO(); + request.setCategoryName("不存在的类别名称_xyz_123"); + + ApiResult> result = post("/qcMaterialCategory/search", request, new TypeReference<>() {}); + assertSuccess(result, "查询不存在的类别名称失败"); + + List categories = result.getResult(); + Assert.isTrue(categories.isEmpty(), () -> new RuntimeException("查询不存在的类别应返回空列表")); + System.out.println(" ✅ 查询不存在的类别名称成功,返回空列表"); + } + + /** + * 【查询质检物料类别树】查询不存在的类别编号 + * 验证点: + * 1. 接口返回成功 + * 2. 返回空列表 + */ + @Test + @Order(6) + public void test06_searchCategory_NoMatchCode() { + QmsQcMaterialCategorySearchQO request = new QmsQcMaterialCategorySearchQO(); + request.setCategoryCode("不存在的编号_XYZ_999"); + + ApiResult> result = post("/qcMaterialCategory/search", request, new TypeReference<>() {}); + assertSuccess(result, "查询不存在的类别编号失败"); + + List categories = result.getResult(); + Assert.isTrue(categories.isEmpty(), () -> new RuntimeException("查询不存在的类别编号应返回空列表")); + System.out.println(" ✅ 查询不存在的类别编号成功,返回空列表"); + } + + /** + * 【查询质检物料类别树】空字符串查询条件 + * 验证点: + * 1. 接口返回成功 + * 2. 返回全部类别树 + */ + @Test + @Order(7) + public void test07_searchCategory_EmptyCondition() { + QmsQcMaterialCategorySearchQO request = new QmsQcMaterialCategorySearchQO(); + request.setCategoryName(""); + request.setCategoryCode(""); + + ApiResult> result = post("/qcMaterialCategory/search", request, new TypeReference<>() {}); + assertSuccess(result, "空条件查询失败"); + + List categories = result.getResult(); + System.out.println(" ✅ 空条件查询成功,返回树节点数: " + categories.size()); + + // 验证树形结构 + if (!categories.isEmpty()) { + verifyTreeStructure(categories, "根节点"); + } + } + + /** + * 【查询质检物料类别树】验证返回的树形结构完整性 + * 验证点: + * 1. 每个节点的children字段正确设置 + * 2. 叶子节点的children为null或空列表 + * 3. 非叶子节点的children包含子节点 + */ + @Test + @Order(8) + public void test08_searchCategory_VerifyTreeIntegrity() { + QmsQcMaterialCategorySearchQO request = new QmsQcMaterialCategorySearchQO(); + + ApiResult> result = post("/qcMaterialCategory/search", request, new TypeReference<>() {}); + assertSuccess(result, "查询类别树失败"); + + List categories = result.getResult(); + System.out.println(" ✅ 开始验证树形结构完整性..."); + + if (!categories.isEmpty()) { + int[] stats = new int[2]; // [0]=总节点数, [1]=叶子节点数 + verifyTreeIntegrity(categories, stats); + System.out.println(" ✅ 树形结构验证通过"); + System.out.println(" 总节点数: " + stats[0]); + System.out.println(" 叶子节点数: " + stats[1]); + } else { + System.out.println(" ⚠️ 数据库中暂无类别数据,跳过验证"); + } + } + + // ==================== 辅助方法 ==================== + + /** + * 递归验证树形结构 + */ + private void verifyTreeStructure(List nodes, String parentName) { + for (QmsQcMaterialCategoryVO node : nodes) { + System.out.println(" - " + parentName + " -> " + node.getCategoryName() + + " (编码: " + node.getCategoryCode() + ", ID: " + node.getId() + ")"); + + if (node.getChildren() != null && !node.getChildren().isEmpty()) { + verifyTreeStructure(node.getChildren(), node.getCategoryName()); + } + } + } + + /** + * 检查树中是否包含名称匹配的节点 + */ + private boolean hasNodeMatchedByName(List nodes, String keyword) { + for (QmsQcMaterialCategoryVO node : nodes) { + if (node.getCategoryName() != null && node.getCategoryName().contains(keyword)) { + return true; + } + if (node.getChildren() != null && !node.getChildren().isEmpty()) { + if (hasNodeMatchedByName(node.getChildren(), keyword)) { + return true; + } + } + } + return false; + } + + /** + * 检查树中是否包含编号匹配的节点 + */ + private boolean hasNodeMatchedCode(List nodes, String keyword) { + for (QmsQcMaterialCategoryVO node : nodes) { + if (node.getCategoryCode() != null && node.getCategoryCode().contains(keyword)) { + return true; + } + if (node.getChildren() != null && !node.getChildren().isEmpty()) { + if (hasNodeMatchedCode(node.getChildren(), keyword)) { + return true; + } + } + } + return false; + } + + /** + * 递归验证树的完整性并统计节点 + */ + private void verifyTreeIntegrity(List nodes, int[] stats) { + for (QmsQcMaterialCategoryVO node : nodes) { + stats[0]++; // 总节点数+1 + + boolean hasChildren = node.getChildren() != null && !node.getChildren().isEmpty(); + + if (hasChildren) { + // 非叶子节点,继续递归验证子节点 + verifyTreeIntegrity(node.getChildren(), stats); + } else { + // 叶子节点 + stats[1]++; // 叶子节点数+1 + Assert.isNull(node.getChildren(), + () -> new RuntimeException("叶子节点的children应该为null,但节点ID=" + node.getId())); + } + } + } +} diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/IdsQO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/IdsQO.java new file mode 100644 index 00000000..ab2b8f84 --- /dev/null +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/IdsQO.java @@ -0,0 +1,16 @@ +package com.nflg.wms.common.pojo.qo; + +import jakarta.validation.constraints.NotEmpty; +import lombok.Data; + +import java.util.List; + +/** + * 批量ID请求参数 + */ +@Data +public class IdsQO { + + @NotEmpty(message = "ID列表不能为空") + private List ids; +} diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/QmsInspectionStandardSearchQO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/QmsInspectionStandardSearchQO.java new file mode 100644 index 00000000..6ecd1d4a --- /dev/null +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/QmsInspectionStandardSearchQO.java @@ -0,0 +1,27 @@ +package com.nflg.wms.common.pojo.qo; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 检验标准搜索请求参数 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class QmsInspectionStandardSearchQO extends PageQO { + + /** + * 物料编号(模糊匹配) + */ + private String materialNo; + + /** + * 物料类别编码(模糊匹配) + */ + private String materialCategoryCode; + + /** + * 所属IQE姓名(模糊匹配) + */ + private String iqeName; +} diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/QmsQcMaterialCategorySearchQO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/QmsQcMaterialCategorySearchQO.java new file mode 100644 index 00000000..87c94033 --- /dev/null +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/QmsQcMaterialCategorySearchQO.java @@ -0,0 +1,20 @@ +package com.nflg.wms.common.pojo.qo; + +import lombok.Data; + +/** + * 查询质检物料分类参数 + */ +@Data +public class QmsQcMaterialCategorySearchQO { + + /** + * 类别名称(模糊匹配) + */ + private String categoryName; + + /** + * 类别编号(模糊匹配) + */ + private String categoryCode; +} diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/QmsInspectionStandardVO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/QmsInspectionStandardVO.java new file mode 100644 index 00000000..03873c4d --- /dev/null +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/QmsInspectionStandardVO.java @@ -0,0 +1,97 @@ +package com.nflg.wms.common.pojo.vo; + +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 检验标准搜索结果VO + */ +@Data +public class QmsInspectionStandardVO { + + /** + * 检验标准ID + */ + private Long id; + + /** + * 物料编号 + */ + private String materialNo; + + /** + * 物料类别 + */ + private String materialCategoryCodePathName; + + /** + * 物料描述 + */ + private String materialDesc; + + /** + * 图号版本号 + */ + private String drawingNoVer; + + /** + * 检测版本号 + */ + private String versionNo; + + /** + * 所属IQE + */ + private String iqeName; + + /** + * 检测周期 + */ + private Integer inspectionCycle; + + /** + * 包装类型ID + */ + private Long packagingMethodId; + + /** + * 启用状态 + */ + private Boolean isEnabled; + + /** + * 发布状态:0-未发布,1-已发布 + */ + private Short publishStatus; + + /** + * 发布人 + */ + private String publishUserName; + + /** + * 发布时间 + */ + private LocalDateTime publishTime; + + /** + * 创建人姓名 + */ + private String createUserName; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新人姓名 + */ + private String updateUserName; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; +} diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/QmsQcMaterialCategoryVO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/QmsQcMaterialCategoryVO.java new file mode 100644 index 00000000..e0c4f850 --- /dev/null +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/QmsQcMaterialCategoryVO.java @@ -0,0 +1,42 @@ +package com.nflg.wms.common.pojo.vo; + +import lombok.Data; + +import java.util.List; + +/** + * 质检物料分类 VO + */ +@Data +public class QmsQcMaterialCategoryVO { + + /** + * 分类ID + */ + private Long id; + + /** + * 分类编码 + */ + private String categoryCode; + + /** + * 分类名称 + */ + private String categoryName; + + /** + * 父级分类ID + */ + private Long parentCategoryRowId; + + /** + * 父级树路径(ltree类型) + */ + private String parentTree; + + /** + * 子节点列表(树形结构) + */ + private List children; +} diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/QmsInspectionStandard.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/QmsInspectionStandard.java new file mode 100644 index 00000000..2d0eab56 --- /dev/null +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/QmsInspectionStandard.java @@ -0,0 +1,113 @@ +package com.nflg.wms.repository.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 检验标准 + */ +@Getter +@Setter +@ToString +@Accessors(chain = true) +@TableName("qms_inspection_standard") +public class QmsInspectionStandard implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 物料ID + */ + private Long materialId; + + /** + * 检验任务项ID + */ + private Long inspectionTaskItemId; + + /** + * 图纸URL + */ + private String drawingUrl; + + /** + * 版本号 + */ + private String versionNo; + + /** + * 是否启用 + */ + private Boolean isEnabled; + + /** + * 包装方式ID + */ + private Long packagingMethodId; + + /** + * 检验周期 + */ + private Integer inspectionCycle; + + /** + * 发布状态:0-未发布,1-已发布 + */ + private Short publishStatus; + + /** + * 发布人ID + */ + private Long publishUserId; + + /** + * 发布人姓名 + */ + private String publishUserName; + + /** + * 发布时间 + */ + private LocalDateTime publishTime; + + /** + * 创建人ID + */ + private Long createUserId; + + /** + * 创建人姓名 + */ + private String createUserName; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新人ID + */ + private Long updateUserId; + + /** + * 更新人姓名 + */ + private String updateUserName; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; +} diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/QmsInspectionStandardItem.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/QmsInspectionStandardItem.java new file mode 100644 index 00000000..0d453e86 --- /dev/null +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/QmsInspectionStandardItem.java @@ -0,0 +1,113 @@ +package com.nflg.wms.repository.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 检验标准项 + */ +@Getter +@Setter +@ToString +@Accessors(chain = true) +@TableName("qms_inspection_standard_item") +public class QmsInspectionStandardItem implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 检验标准ID + */ + private Long inspectionStandardId; + + /** + * 检测项名称 + */ + private String name; + + /** + * 排序号 + */ + private Integer sortNo; + + /** + * 检测方式,关联字典项id(字典编码:InspectionStandardTestingMethod) + */ + private Long testingMethodDictItemId; + + /** + * 抽样方式,关联字典项id(字典编码:InspectionStandardSamplingMethod) + */ + private Long samplingMethodDictItemId; + + /** + * 抽样方案ID + */ + private Long samplingPlanId; + + /** + * 检验水平,关联字典项id(字典编码:SamplingPlanSpecialInspection或SamplingPlanGeneralInspection) + */ + private Long inspectionLevelDictItemId; + + /** + * AQL值,关联AQL优先值预定义表id + */ + private Long aqlPriorityValueId; + + /** + * AQL类型,关联字典项id(字典编码:InspectionStandardSQLType) + */ + private Long aqlTypeDictItemId; + + /** + * 检验标准项类型:0-标准检测项,1-尺寸检测项 + */ + private Short itemType; + + /** + * PDF图纸 + */ + private String pdfDrawing; + + /** + * 创建人ID + */ + private Long createUserId; + + /** + * 创建人姓名 + */ + private String createUserName; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新人ID + */ + private Long updateUserId; + + /** + * 更新人姓名 + */ + private String updateUserName; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; +} diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/QmsInspectionStandardItemContent.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/QmsInspectionStandardItemContent.java new file mode 100644 index 00000000..7d6bdc15 --- /dev/null +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/QmsInspectionStandardItemContent.java @@ -0,0 +1,93 @@ +package com.nflg.wms.repository.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 检验标准项内容 + */ +@Getter +@Setter +@ToString +@Accessors(chain = true) +@TableName("qms_inspection_standard_item_content") +public class QmsInspectionStandardItemContent implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * 检验标准项ID + */ + private Long inspectionStandardItemId; + + /** + * 排序号 + */ + private Integer sortNo; + + /** + * 检测项名称 + */ + private String name; + + /** + * 检测标准 + */ + private String testStandard; + + /** + * 图例 + */ + private String legend; + + /** + * PDF信息 + */ + private String pdfInfo; + + /** + * 判定类型,关联字典项id(字典编码:InspectionStandardJudgmentType) + */ + private Long judgmentTypeDictItemId; + + /** + * 创建人ID + */ + private Long createUserId; + + /** + * 创建人姓名 + */ + private String createUserName; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新人ID + */ + private Long updateUserId; + + /** + * 更新人姓名 + */ + private String updateUserName; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; +} diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/mapper/QmsInspectionStandardMapper.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/mapper/QmsInspectionStandardMapper.java new file mode 100644 index 00000000..1c5030ab --- /dev/null +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/mapper/QmsInspectionStandardMapper.java @@ -0,0 +1,20 @@ +package com.nflg.wms.repository.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.nflg.wms.common.pojo.qo.QmsInspectionStandardSearchQO; +import com.nflg.wms.common.pojo.vo.QmsInspectionStandardVO; +import com.nflg.wms.repository.entity.QmsInspectionStandard; +import org.apache.ibatis.annotations.Param; + +/** + * 检验标准 Mapper + */ +public interface QmsInspectionStandardMapper extends BaseMapper { + + /** + * 分页查询检验标准 + */ + IPage searchPage(@Param("request") QmsInspectionStandardSearchQO request, Page page); +} diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IQmsInspectionStandardService.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IQmsInspectionStandardService.java new file mode 100644 index 00000000..a29428f0 --- /dev/null +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IQmsInspectionStandardService.java @@ -0,0 +1,25 @@ +package com.nflg.wms.repository.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.nflg.wms.repository.entity.QmsInspectionStandard; + +import java.util.List; + +/** + * 检验标准 服务类 + */ +public interface IQmsInspectionStandardService extends IService { + + /** + * 批量发布检验标准 + * @param ids 检验标准ID列表 + */ + void publish(List ids); + + /** + * 启用/禁用检验标准(单条) + * @param id 检验标准ID + * @param enable 是否启用 + */ + void enable(Long id, Boolean enable); +} diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IQmsQcMaterialCategoryService.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IQmsQcMaterialCategoryService.java index 01fa1511..83c2373e 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IQmsQcMaterialCategoryService.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IQmsQcMaterialCategoryService.java @@ -1,10 +1,22 @@ package com.nflg.wms.repository.service; import com.baomidou.mybatisplus.extension.service.IService; +import com.nflg.wms.common.pojo.qo.QmsQcMaterialCategorySearchQO; +import com.nflg.wms.common.pojo.vo.QmsQcMaterialCategoryVO; import com.nflg.wms.repository.entity.QmsQcMaterialCategory; +import java.util.List; + /** * 质检物料分类 服务类 */ public interface IQmsQcMaterialCategoryService extends IService { + + /** + * 查询质检物料分类树(支持模糊查询,不分页) + * + * @param request 查询条件 + * @return 树形结构列表 + */ + List searchTree(QmsQcMaterialCategorySearchQO request); } diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/QmsInspectionStandardServiceImpl.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/QmsInspectionStandardServiceImpl.java new file mode 100644 index 00000000..b41ae28d --- /dev/null +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/QmsInspectionStandardServiceImpl.java @@ -0,0 +1,57 @@ +package com.nflg.wms.repository.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.nflg.wms.common.util.UserUtil; +import com.nflg.wms.repository.entity.QmsInspectionStandard; +import com.nflg.wms.repository.mapper.QmsInspectionStandardMapper; +import com.nflg.wms.repository.service.IQmsInspectionStandardService; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 检验标准 服务实现类 + */ +@Service +public class QmsInspectionStandardServiceImpl extends ServiceImpl + implements IQmsInspectionStandardService { + + @Override + public void publish(List ids) { + if (ids == null || ids.isEmpty()) { + return; + } + Long userId = UserUtil.getUserId(); + String userName = UserUtil.getUserName(); + LocalDateTime now = LocalDateTime.now(); + + lambdaUpdate() + .eq(QmsInspectionStandard::getPublishStatus, (short) 0) + .in(QmsInspectionStandard::getId, ids) + .set(QmsInspectionStandard::getPublishStatus, (short) 1) + .set(QmsInspectionStandard::getPublishUserId, userId) + .set(QmsInspectionStandard::getPublishUserName, userName) + .set(QmsInspectionStandard::getPublishTime, now) + .set(QmsInspectionStandard::getUpdateUserId, userId) + .set(QmsInspectionStandard::getUpdateUserName, userName) + .set(QmsInspectionStandard::getUpdateTime, now) + .update(); + } + + @Override + public void enable(Long id, Boolean enable) { + Long userId = UserUtil.getUserId(); + String userName = UserUtil.getUserName(); + LocalDateTime now = LocalDateTime.now(); + + lambdaUpdate() + .eq(QmsInspectionStandard::getIsEnabled, !enable) + .eq(QmsInspectionStandard::getId, id) + .set(QmsInspectionStandard::getIsEnabled, enable) + .set(QmsInspectionStandard::getUpdateUserId, userId) + .set(QmsInspectionStandard::getUpdateUserName, userName) + .set(QmsInspectionStandard::getUpdateTime, now) + .update(); + } +} diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/QmsQcMaterialCategoryServiceImpl.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/QmsQcMaterialCategoryServiceImpl.java index 6a00f95e..7dd08062 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/QmsQcMaterialCategoryServiceImpl.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/QmsQcMaterialCategoryServiceImpl.java @@ -1,15 +1,94 @@ package com.nflg.wms.repository.service.impl; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.nflg.wms.common.pojo.qo.QmsQcMaterialCategorySearchQO; +import com.nflg.wms.common.pojo.vo.QmsQcMaterialCategoryVO; import com.nflg.wms.repository.entity.QmsQcMaterialCategory; import com.nflg.wms.repository.mapper.QmsQcMaterialCategoryMapper; import com.nflg.wms.repository.service.IQmsQcMaterialCategoryService; import org.springframework.stereotype.Service; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + /** * 质检物料分类 服务实现类 */ @Service public class QmsQcMaterialCategoryServiceImpl extends ServiceImpl implements IQmsQcMaterialCategoryService { + + @Override + public List searchTree(QmsQcMaterialCategorySearchQO request) { + // 查询所有分类 + List all = this.lambdaQuery() + .orderByAsc(QmsQcMaterialCategory::getCategoryCode) + .list(); + + // 按条件过滤 + List filteredList = all; + if (StrUtil.isNotBlank(request.getCategoryName()) || StrUtil.isNotBlank(request.getCategoryCode())) { + // 有条件时,过滤匹配节点并补全祖先 + Map idMap = all.stream() + .collect(Collectors.toMap(QmsQcMaterialCategory::getId, c -> c)); + + List matched = all.stream() + .filter(c -> { + boolean nameMatch = StrUtil.isBlank(request.getCategoryName()) + || c.getCategoryName().contains(request.getCategoryName()); + boolean codeMatch = StrUtil.isBlank(request.getCategoryCode()) + || c.getCategoryCode().contains(request.getCategoryCode()); + return nameMatch && codeMatch; + }) + .collect(Collectors.toList()); + + Set visibleIds = new HashSet<>(); + for (QmsQcMaterialCategory node : matched) { + QmsQcMaterialCategory cur = node; + while (cur != null) { + visibleIds.add(cur.getId()); + cur = cur.getParentCategoryRowId() != null && cur.getParentCategoryRowId() > 0 + ? idMap.get(cur.getParentCategoryRowId()) + : null; + } + } + filteredList = all.stream() + .filter(c -> visibleIds.contains(c.getId())) + .collect(Collectors.toList()); + } + + // 转 VO + List voList = filteredList.stream() + .map(c -> BeanUtil.copyProperties(c, QmsQcMaterialCategoryVO.class)) + .collect(Collectors.toList()); + + // 构建树形结构(根节点的parentCategoryRowId为null或0) + return buildTree(voList, null); + } + + /** + * 递归构建树形结构 + */ + private List buildTree(List all, Long parentId) { + List result = new ArrayList<>(); + for (QmsQcMaterialCategoryVO vo : all) { + boolean isRoot = parentId == null + ? (vo.getParentCategoryRowId() == null || vo.getParentCategoryRowId() == 0) + : Objects.equals(vo.getParentCategoryRowId(), parentId); + + if (isRoot) { + List children = buildTree(all, vo.getId()); + vo.setChildren(children.isEmpty() ? null : children); + result.add(vo); + } + } + return result; + } } diff --git a/nflg-wms-repository/src/main/resources/mapper/QmsInspectionStandardMapper.xml b/nflg-wms-repository/src/main/resources/mapper/QmsInspectionStandardMapper.xml new file mode 100644 index 00000000..af2ab747 --- /dev/null +++ b/nflg-wms-repository/src/main/resources/mapper/QmsInspectionStandardMapper.xml @@ -0,0 +1,50 @@ + + + + + + + +