补充历史项目导入接口契约
This commit is contained in:
@@ -6,8 +6,10 @@ import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.page.PageDomain;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.core.page.TableSupport;
|
||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectImportHistoryDTO;
|
||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectQueryDTO;
|
||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectSaveDTO;
|
||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectHistoryListItemVO;
|
||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectStatusCountsVO;
|
||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectVO;
|
||||
import com.ruoyi.ccdi.project.service.ICcdiProjectService;
|
||||
@@ -19,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;
|
||||
|
||||
/**
|
||||
* 纪检初核项目管理Controller
|
||||
*
|
||||
@@ -100,6 +104,28 @@ public class CcdiProjectController extends BaseController {
|
||||
return getDataTable(result.getRecords(), result.getTotal());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询历史项目列表
|
||||
*/
|
||||
@GetMapping("/history")
|
||||
@Operation(summary = "查询历史项目列表")
|
||||
@PreAuthorize("@ss.hasPermi('ccdi:project:list')")
|
||||
public AjaxResult listHistoryProjects(CcdiProjectQueryDTO queryDTO) {
|
||||
List<CcdiProjectHistoryListItemVO> result = projectService.listHistoryProjects(queryDTO);
|
||||
return AjaxResult.success(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从历史项目导入
|
||||
*/
|
||||
@PostMapping("/import")
|
||||
@Operation(summary = "导入历史项目")
|
||||
@PreAuthorize("@ss.hasPermi('ccdi:project:add')")
|
||||
public AjaxResult importFromHistory(@Validated @RequestBody CcdiProjectImportHistoryDTO dto) {
|
||||
CcdiProjectVO vo = projectService.importFromHistory(dto, SecurityUtils.getUsername());
|
||||
return AjaxResult.success("项目创建成功", vo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询项目状态统计
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.ruoyi.ccdi.project.domain.dto;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.Data;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 历史项目导入DTO
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Data
|
||||
public class CcdiProjectImportHistoryDTO {
|
||||
|
||||
/** 新项目名称 */
|
||||
@NotBlank(message = "项目名称不能为空")
|
||||
@Length(max = 200, message = "项目名称长度不能超过200个字符")
|
||||
private String projectName;
|
||||
|
||||
/** 项目描述 */
|
||||
@Length(max = 500, message = "项目描述长度不能超过500个字符")
|
||||
private String description;
|
||||
|
||||
/** 来源项目ID列表 */
|
||||
@NotEmpty(message = "来源项目不能为空")
|
||||
private List<Long> sourceProjectIds;
|
||||
|
||||
/** 流水起始日期 */
|
||||
private String startDate;
|
||||
|
||||
/** 流水结束日期 */
|
||||
private String endDate;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.ruoyi.ccdi.project.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 历史项目列表项VO
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Data
|
||||
public class CcdiProjectHistoryListItemVO {
|
||||
|
||||
/** 项目ID */
|
||||
private Long projectId;
|
||||
|
||||
/** 项目名称 */
|
||||
private String projectName;
|
||||
|
||||
/** 项目描述 */
|
||||
private String description;
|
||||
|
||||
/** 项目状态 */
|
||||
private String status;
|
||||
|
||||
/** 是否归档 */
|
||||
private Integer isArchived;
|
||||
|
||||
/** 创建时间 */
|
||||
private Date createTime;
|
||||
}
|
||||
@@ -1,11 +1,15 @@
|
||||
package com.ruoyi.ccdi.project.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectImportHistoryDTO;
|
||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectQueryDTO;
|
||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectSaveDTO;
|
||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectHistoryListItemVO;
|
||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectStatusCountsVO;
|
||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 项目Service接口
|
||||
*
|
||||
@@ -53,6 +57,23 @@ public interface ICcdiProjectService {
|
||||
*/
|
||||
Page<CcdiProjectVO> selectProjectPage(Page<CcdiProjectVO> page, CcdiProjectQueryDTO queryDTO);
|
||||
|
||||
/**
|
||||
* 查询历史项目列表
|
||||
*
|
||||
* @param queryDTO 查询条件
|
||||
* @return 历史项目列表
|
||||
*/
|
||||
List<CcdiProjectHistoryListItemVO> listHistoryProjects(CcdiProjectQueryDTO queryDTO);
|
||||
|
||||
/**
|
||||
* 从历史项目导入
|
||||
*
|
||||
* @param dto 导入参数
|
||||
* @param operator 操作人
|
||||
* @return 新建项目
|
||||
*/
|
||||
CcdiProjectVO importFromHistory(CcdiProjectImportHistoryDTO dto, String operator);
|
||||
|
||||
/**
|
||||
* 查询各状态的项目总数(不受搜索条件影响)
|
||||
*
|
||||
|
||||
@@ -4,8 +4,10 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.ruoyi.ccdi.project.constants.CcdiProjectStatusConstants;
|
||||
import com.ruoyi.ccdi.project.domain.CcdiProject;
|
||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectImportHistoryDTO;
|
||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectQueryDTO;
|
||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectSaveDTO;
|
||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectHistoryListItemVO;
|
||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectStatusCountsVO;
|
||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectVO;
|
||||
import com.ruoyi.ccdi.project.mapper.CcdiProjectMapper;
|
||||
@@ -21,7 +23,9 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@@ -114,6 +118,20 @@ public class CcdiProjectServiceImpl implements ICcdiProjectService {
|
||||
return projectMapper.selectProjectPage(page, queryDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CcdiProjectHistoryListItemVO> listHistoryProjects(CcdiProjectQueryDTO queryDTO) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CcdiProjectVO importFromHistory(CcdiProjectImportHistoryDTO dto, String operator) {
|
||||
CcdiProjectSaveDTO saveDTO = new CcdiProjectSaveDTO();
|
||||
saveDTO.setProjectName(dto.getProjectName());
|
||||
saveDTO.setDescription(dto.getDescription());
|
||||
saveDTO.setConfigType("default");
|
||||
return createProject(saveDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CcdiProjectStatusCountsVO getStatusCounts() {
|
||||
CcdiProjectStatusCountsVO vo = new CcdiProjectStatusCountsVO();
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package com.ruoyi.ccdi.project.controller;
|
||||
|
||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectImportHistoryDTO;
|
||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectQueryDTO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
@@ -30,4 +33,17 @@ class CcdiProjectControllerContractTest {
|
||||
assertNotNull(operation);
|
||||
assertEquals("归档项目", operation.summary());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldExposeHistoryImportEndpointContracts() throws Exception {
|
||||
Method history = CcdiProjectController.class.getMethod("listHistoryProjects", CcdiProjectQueryDTO.class);
|
||||
GetMapping historyMapping = history.getAnnotation(GetMapping.class);
|
||||
assertNotNull(historyMapping);
|
||||
assertEquals("/history", historyMapping.value()[0]);
|
||||
|
||||
Method importing = CcdiProjectController.class.getMethod("importFromHistory", CcdiProjectImportHistoryDTO.class);
|
||||
PostMapping importMapping = importing.getAnnotation(PostMapping.class);
|
||||
assertNotNull(importMapping);
|
||||
assertEquals("/import", importMapping.value()[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.ruoyi.ccdi.project.controller;
|
||||
|
||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectImportHistoryDTO;
|
||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectVO;
|
||||
import com.ruoyi.ccdi.project.service.ICcdiProjectService;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
@@ -16,7 +18,10 @@ import java.lang.reflect.Method;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mockStatic;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@@ -52,4 +57,26 @@ class CcdiProjectControllerTest {
|
||||
assertNotNull(operation);
|
||||
assertEquals("归档项目", operation.summary());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldImportFromHistoryAndReturnCreatedProject() {
|
||||
CcdiProjectImportHistoryDTO dto = new CcdiProjectImportHistoryDTO();
|
||||
dto.setProjectName("新建项目");
|
||||
|
||||
CcdiProjectVO project = new CcdiProjectVO();
|
||||
project.setProjectId(88L);
|
||||
project.setProjectName("新建项目");
|
||||
when(projectService.importFromHistory(eq(dto), eq("tester"))).thenReturn(project);
|
||||
|
||||
try (MockedStatic<com.ruoyi.common.utils.SecurityUtils> mocked = mockStatic(com.ruoyi.common.utils.SecurityUtils.class)) {
|
||||
mocked.when(com.ruoyi.common.utils.SecurityUtils::getUsername).thenReturn("tester");
|
||||
|
||||
AjaxResult result = controller.importFromHistory(dto);
|
||||
|
||||
assertEquals(200, result.get("code"));
|
||||
assertEquals("项目创建成功", result.get("msg"));
|
||||
assertSame(project, result.get("data"));
|
||||
verify(projectService).importFromHistory(dto, "tester");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,3 +27,10 @@
|
||||
- 调整 `CcdiBankStatementMapper.xml` 详情查询,补充 `fur.source_project_name` 查询痕迹,为后续历史导入来源展示预留字段
|
||||
- 新增 `CcdiBankStatementMapperXmlTest` 断言,先验证缺少来源字段时失败,再验证补齐后通过
|
||||
- 验证命令:`mvn -pl ccdi-project -am -Dtest=CcdiBankStatementMapperXmlTest -Dsurefire.failIfNoSpecifiedTests=false test`
|
||||
|
||||
### 2026-03-29 Task 2 后端接口契约落地
|
||||
|
||||
- 新增 `CcdiProjectImportHistoryDTO` 与 `CcdiProjectHistoryListItemVO`,明确历史导入入参与历史项目列表返回结构
|
||||
- 扩展 `ICcdiProjectService`、`CcdiProjectController` 与 `CcdiProjectServiceImpl`,补齐 `/ccdi/project/history` 和 `/ccdi/project/import` 最小接口骨架
|
||||
- 新增控制器契约测试与导入返回结构测试,锁定真实接口路径和“项目创建成功”返回数据
|
||||
- 验证命令:`mvn -pl ccdi-project -am -Dtest=CcdiProjectControllerContractTest,CcdiProjectControllerTest -Dsurefire.failIfNoSpecifiedTests=false test`
|
||||
|
||||
Reference in New Issue
Block a user