From 4f6b209c3de6aa2eb6d5dab0554a2f6e4a1f40cd Mon Sep 17 00:00:00 2001 From: dk <1260500659@qq.com> Date: Sat, 9 May 2026 18:01:42 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E4=BA=A7=E5=93=81=E9=9C=80=E6=B1=82):=20?= =?UTF-8?q?=E5=AE=8C=E5=96=84=E4=BA=A7=E5=93=81=E9=9C=80=E6=B1=82=E7=9A=84?= =?UTF-8?q?=E8=AF=B8=E5=A4=9A=E7=BB=86=E8=8A=82=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/project/ProjectController.java | 9 ++++++ .../dal/mysql/project/ProjectMapper.java | 6 ++++ .../ProductRequirementServiceImpl.java | 10 ++++-- .../service/project/ProjectService.java | 4 +++ .../service/project/ProjectServiceImpl.java | 23 ++++++++++--- .../project/ProjectServiceImplTest.java | 32 +++++++++++++++++++ 6 files changed, 78 insertions(+), 6 deletions(-) diff --git a/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/controller/admin/project/ProjectController.java b/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/controller/admin/project/ProjectController.java index d4974b2..92d36b2 100644 --- a/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/controller/admin/project/ProjectController.java +++ b/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/controller/admin/project/ProjectController.java @@ -21,6 +21,8 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import java.util.List; + import static com.njcn.rdms.framework.common.pojo.CommonResult.success; @Tag(name = "管理后台 - 项目管理") @@ -67,6 +69,13 @@ public class ProjectController { return success(BeanUtils.toBean(pageResult, ProjectRespVO.class)); } + @GetMapping("/list-by-product") + @Operation(summary = "根据产品编号获取该产品下的全部项目") + @Parameter(name = "productId", description = "产品编号", required = true, example = "1024") + public CommonResult> getProjectListByProductId(@RequestParam("productId") Long productId) { + return success(projectService.getProjectListByProductId(productId)); + } + @GetMapping("/overview-summary") @Operation(summary = "获取项目入口页概览统计") public CommonResult getProjectOverviewSummary() { diff --git a/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/dal/mysql/project/ProjectMapper.java b/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/dal/mysql/project/ProjectMapper.java index d77ff46..6e86fde 100644 --- a/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/dal/mysql/project/ProjectMapper.java +++ b/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/dal/mysql/project/ProjectMapper.java @@ -72,6 +72,12 @@ public interface ProjectMapper extends BaseMapperX { .orderByDesc(ProjectDO::getProjectCode)); } + default List selectListByProductId(Long productId) { + return selectList(new LambdaQueryWrapperX() + .eq(ProjectDO::getProductId, productId) + .orderByDesc(BaseDO::getCreateTime)); + } + default int updateStatusByIdAndStatus(Long id, String fromStatus, String toStatus, String lastStatusReason) { ProjectDO update = new ProjectDO(); update.setStatusCode(toStatus); diff --git a/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/service/product/ProductRequirementServiceImpl.java b/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/service/product/ProductRequirementServiceImpl.java index 0659e42..cd02e32 100644 --- a/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/service/product/ProductRequirementServiceImpl.java +++ b/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/service/product/ProductRequirementServiceImpl.java @@ -228,9 +228,15 @@ public class ProductRequirementServiceImpl implements ProductRequirementService rootIds.add(rootId); } - // 第三步:查询根需求详情并按创建时间倒排 + // 第三步:查询根需求详情并按排序值升序、创建时间倒排 List rootRequirements = requirementMapper.selectBatchIds(rootIds); - rootRequirements.sort((a, b) -> b.getCreateTime().compareTo(a.getCreateTime())); + rootRequirements.sort((a, b) -> { + int sortCompare = Integer.compare(a.getSort() != null ? a.getSort() : 0, b.getSort() != null ? b.getSort() : 0); + if (sortCompare != 0) { + return sortCompare; + } + return b.getCreateTime().compareTo(a.getCreateTime()); + }); // 第四步:对根节点列表进行内存分页 int pageNo = pageReqVO.getPageNo() != null ? pageReqVO.getPageNo() : 1; diff --git a/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/service/project/ProjectService.java b/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/service/project/ProjectService.java index 15a1925..7cb40a2 100644 --- a/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/service/project/ProjectService.java +++ b/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/service/project/ProjectService.java @@ -10,6 +10,8 @@ import com.njcn.rdms.module.project.controller.admin.project.vo.project.ProjectS import com.njcn.rdms.module.project.controller.admin.project.vo.project.ProjectStatusActionReqVO; import com.njcn.rdms.module.project.dal.dataobject.project.ProjectDO; +import java.util.List; + /** * 项目 Service 接口 */ @@ -23,6 +25,8 @@ public interface ProjectService { ProjectRespVO getProjectDetail(Long id); + List getProjectListByProductId(Long productId); + ProjectContextRespVO getProjectContext(Long id); PageResult getProjectPage(ProjectPageReqVO pageReqVO); diff --git a/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/service/project/ProjectServiceImpl.java b/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/service/project/ProjectServiceImpl.java index 551e98f..9121a0e 100644 --- a/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/service/project/ProjectServiceImpl.java +++ b/rdms-project/rdms-project-boot/src/main/java/com/njcn/rdms/module/project/service/project/ProjectServiceImpl.java @@ -177,10 +177,15 @@ public class ProjectServiceImpl implements ProjectService { @Override public ProjectRespVO getProjectDetail(Long id) { ProjectDO project = validateProjectExists(id); - ProjectRespVO respVO = BeanUtils.toBean(project, ProjectRespVO.class); - respVO.setProductName(getProductName(project.getProductId())); - respVO.setManagerUserNickname(getManagerNickname(project.getManagerUserId())); - return respVO; + return buildProjectRespVO(project); + } + + @Override + public List getProjectListByProductId(Long productId) { + validateProductUsable(productId); + return projectMapper.selectListByProductId(productId).stream() + .map(this::buildProjectRespVO) + .collect(Collectors.toList()); } @Override @@ -666,6 +671,16 @@ public class ProjectServiceImpl implements ProjectService { return currentProject; } + /** + * 构建项目响应对象,补齐产品名和负责人昵称,避免前端再做二次查询。 + */ + private ProjectRespVO buildProjectRespVO(ProjectDO project) { + ProjectRespVO respVO = BeanUtils.toBean(project, ProjectRespVO.class); + respVO.setProductName(getProductName(project.getProductId())); + respVO.setManagerUserNickname(getManagerNickname(project.getManagerUserId())); + return respVO; + } + private ProjectContextRespVO buildProjectContextWithoutMenus(ProjectDO project, boolean guestFlag) { ProjectContextRespVO respVO = new ProjectContextRespVO(); respVO.setCurrentProject(buildCurrentProject(project)); diff --git a/rdms-project/rdms-project-boot/src/test/java/com/njcn/rdms/module/project/service/project/ProjectServiceImplTest.java b/rdms-project/rdms-project-boot/src/test/java/com/njcn/rdms/module/project/service/project/ProjectServiceImplTest.java index 0649f34..15f3001 100644 --- a/rdms-project/rdms-project-boot/src/test/java/com/njcn/rdms/module/project/service/project/ProjectServiceImplTest.java +++ b/rdms-project/rdms-project-boot/src/test/java/com/njcn/rdms/module/project/service/project/ProjectServiceImplTest.java @@ -114,6 +114,38 @@ class ProjectServiceImplTest extends BaseMockitoUnitTest { assertEquals("张三", result.getManagerUserNickname()); } + @Test + void getProjectListByProductId_shouldReturnProjectsUnderCurrentProduct() { + Long productId = 1001L; + + ProductDO product = new ProductDO(); + product.setId(productId); + product.setName("统一交付平台"); + + ProjectDO project1 = createProject(3001L, productId, "项目A", 2001L, "pending"); + ProjectDO project2 = createProject(3002L, productId, "项目B", 2002L, "active"); + + AdminUserRespDTO manager1 = new AdminUserRespDTO(); + manager1.setId(2001L); + manager1.setNickname("张三"); + AdminUserRespDTO manager2 = new AdminUserRespDTO(); + manager2.setId(2002L); + manager2.setNickname("李四"); + + when(productMapper.selectById(productId)).thenReturn(product); + when(projectMapper.selectListByProductId(productId)).thenReturn(List.of(project1, project2)); + when(adminUserApi.getUser(2001L)).thenReturn(success(manager1)); + when(adminUserApi.getUser(2002L)).thenReturn(success(manager2)); + + List result = projectService.getProjectListByProductId(productId); + + assertEquals(2, result.size()); + assertEquals(productId, result.get(0).getProductId()); + assertEquals("统一交付平台", result.get(0).getProductName()); + assertEquals("张三", result.get(0).getManagerUserNickname()); + assertEquals("李四", result.get(1).getManagerUserNickname()); + } + @Test void createProject_withManualCode_shouldInsertPendingProjectInitManagerAndWriteAudit() { ProjectSaveReqVO reqVO = createReqVO("CNPJ-MANUAL", 1001L, "合同交付项目", 2001L);