# 创建项目功能 - 后端实施计划

> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.

**目标:** 实现创建项目功能的后端接口，包括数据库表、实体类、DTO/VO、Mapper、Service、Controller

**架构:** 基于若依框架 + MyBatis Plus，采用分层架构（Controller -> Service -> Mapper）

**技术栈:** Spring Boot 3.5.8, MyBatis Plus 3.5.10, MySQL 8.2.0, SpringDoc OpenAPI 2.8.14

---

## 前置条件

- MySQL 数据库已启动
- 后端项目已启动
- 已有 admin 账号和测试权限
- 数据库连接配置正确

---

## Task 1: 创建数据库表和字典数据

**文件:**

- Create: `sql/ccdi_project.sql`

**Step 1: 创建 SQL 脚本文件**

创建文件 `sql/ccdi_project.sql`，内容如下：

```sql
-- 创建项目表
CREATE TABLE `ccdi_project` (
  `project_id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '项目ID',
  `project_name` VARCHAR(100) NOT NULL COMMENT '项目名称',
  `project_desc` VARCHAR(500) DEFAULT NULL COMMENT '项目描述',
  `config_type` VARCHAR(20) NOT NULL DEFAULT 'default' COMMENT '配置方式：default-全局默认，custom-自定义',
  `project_status` CHAR(1) NOT NULL DEFAULT '0' COMMENT '项目状态：0-进行中，1-已完成，2-已归档',
  `target_count` INT NOT NULL DEFAULT 0 COMMENT '目标人数',
  `high_risk_count` INT NOT NULL DEFAULT 0 COMMENT '高风险人数',
  `medium_risk_count` INT NOT NULL DEFAULT 0 COMMENT '中风险人数',
  `low_risk_count` INT NOT NULL DEFAULT 0 COMMENT '低风险人数',
  `create_by` VARCHAR(64) DEFAULT '' COMMENT '创建者',
  `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_by` VARCHAR(64) DEFAULT '' COMMENT '更新者',
  `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `remark` VARCHAR(500) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`project_id`),
  INDEX `idx_project_name` (`project_name`),
  INDEX `idx_project_status` (`project_status`),
  INDEX `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='纪检初核项目表';

-- 插入项目状态字典
INSERT INTO sys_dict_type (dict_name, dict_type, status, create_by, create_time, remark)
VALUES ('项目状态', 'ccdi_project_status', '0', 'admin', NOW(), '纪检初核项目状态');

INSERT INTO sys_dict_data (dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time)
VALUES
(1, '进行中', '0', 'ccdi_project_status', '', 'primary', 'Y', '0', 'admin', NOW()),
(2, '已完成', '1', 'ccdi_project_status', '', 'success', 'N', '0', 'admin', NOW()),
(3, '已归档', '2', 'ccdi_project_status', '', 'info', 'N', '0', 'admin', NOW());

-- 插入配置方式字典
INSERT INTO sys_dict_type (dict_name, dict_type, status, create_by, create_time, remark)
VALUES ('配置方式', 'ccdi_config_type', '0', 'admin', NOW(), '项目配置方式');

INSERT INTO sys_dict_data (dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time)
VALUES
(1, '全局默认模型参数配置', 'default', 'ccdi_config_type', '', 'primary', 'Y', '0', 'admin', NOW()),
(2, '自定义项目规则参数配置', 'custom', 'ccdi_config_type', '', 'warning', 'N', '0', 'admin', NOW());

-- 插入菜单权限
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, menu_type, visible, status, perms, icon, create_by, create_time)
VALUES ('纪检初核管理', 0, 1, 'ccdi', NULL, 'M', '0', '0', '', 'monitor', 'admin', NOW());

SET @parent_id = LAST_INSERT_ID();

INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, menu_type, visible, status, perms, icon, create_by, create_time)
VALUES ('项目管理', @parent_id, 1, 'project', 'ccdiProject/index', 'C', '0', '0', 'ccdi:project:list', 'project', 'admin', NOW());

SET @menu_id = LAST_INSERT_ID();

INSERT INTO sys_menu (menu_name, parent_id, order_num, menu_type, visible, status, perms, create_by, create_time)
VALUES
('创建项目', @menu_id, 1, 'F', '0', '0', 'ccdi:project:add', 'admin', NOW()),
('编辑项目', @menu_id, 2, 'F', '0', '0', 'ccdi:project:edit', 'admin', NOW()),
('删除项目', @menu_id, 3, 'F', '0', '0', 'ccdi:project:remove', 'admin', NOW()),
('查询项目', @menu_id, 4, 'F', '0', '0', 'ccdi:project:query', 'admin', NOW());

-- 为管理员角色分配权限
INSERT INTO sys_role_menu (role_id, menu_id)
SELECT 1, menu_id FROM sys_menu WHERE perms LIKE 'ccdi:project:%' OR perms = 'ccdi:project:list';
```

**Step 2: 执行 SQL 脚本**

运行命令连接数据库并执行脚本：

```bash
mysql -h<host> -u<user> -p<password> ccdi < sql/ccdi_project.sql
```

预期输出：无错误，表创建成功

**Step 3: 验证数据库表**

连接数据库验证表是否创建成功：

```bash
mysql -h<host> -u<user> -p<password> -e "USE ccdi; SHOW TABLES LIKE 'ccdi_project'; DESC ccdi_project;"
```

预期输出：显示 `ccdi_project` 表及其字段结构

**Step 4: 验证字典数据**

验证字典数据是否插入成功：

```bash
mysql -h<host> -u<user> -p<password> -e "USE ccdi; SELECT * FROM sys_dict_type WHERE dict_type IN ('ccdi_project_status', 'ccdi_config_type'); SELECT * FROM sys_dict_data WHERE dict_type IN ('ccdi_project_status', 'ccdi_config_type');"
```

预期输出：显示新插入的字典类型和数据

**Step 5: 提交代码**

```bash
git add sql/ccdi_project.sql
git commit -m "feat: 添加项目表和字典数据SQL脚本"
```

---

## Task 2: 创建实体类 CcdiProject

**文件:**

- Create: `ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/domain/CcdiProject.java`

**Step 1: 创建实体类**

创建文件 `ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/domain/CcdiProject.java`：

```java
package com.ruoyi.info.collection.domain;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.util.Date;

/**
 * 纪检初核项目实体类
 *
 * @author ruoyi
 */
@Data
@TableName("ccdi_project")
public class CcdiProject {
    /** 项目ID */
    @TableId(type = IdType.AUTO)
    private Long projectId;

    /** 项目名称 */
    private String projectName;

    /** 项目描述 */
    private String projectDesc;

    /** 配置方式：default-全局默认，custom-自定义 */
    private String configType;

    /** 项目状态：0-进行中，1-已完成，2-已归档 */
    private String projectStatus;

    /** 目标人数 */
    private Integer targetCount;

    /** 高风险人数 */
    private Integer highRiskCount;

    /** 中风险人数 */
    private Integer mediumRiskCount;

    /** 低风险人数 */
    private Integer lowRiskCount;

    /** 创建者 */
    private String createBy;

    /** 创建时间 */
    private Date createTime;

    /** 更新者 */
    private String updateBy;

    /** 更新时间 */
    private Date updateTime;

    /** 备注 */
    private String remark;
}
```

**Step 2: 验证编译**

```bash
cd ruoyi-info-collection && mvn clean compile
```

预期输出：BUILD SUCCESS

**Step 3: 提交代码**

```bash
git add ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/domain/CcdiProject.java
git commit -m "feat: 添加项目实体类"
```

---

## Task 3: 创建 DTO - CcdiProjectSaveDTO

**文件:**

- Create: `ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiProjectSaveDTO.java`

**Step 1: 创建 DTO 目录（如果不存在）**

```bash
mkdir -p ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto
```

**Step 2: 创建 DTO 类**

创建文件 `ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiProjectSaveDTO.java`：

```java
package com.ruoyi.info.collection.domain.dto;

import lombok.Data;

import jakarta.validation.constraints.NotBlank;
import org.hibernate.validator.constraints.Length;

/**
 * 项目保存DTO
 *
 * @author ruoyi
 */
@Data
public class CcdiProjectSaveDTO {
    /** 项目名称（必填） */
    @NotBlank(message = "项目名称不能为空")
    @Length(max = 100, message = "项目名称长度不能超过100个字符")
    private String projectName;

    /** 项目描述（可选） */
    @Length(max = 500, message = "项目描述长度不能超过500个字符")
    private String projectDesc;

    /** 配置方式（必填）：default-全局默认，custom-自定义 */
    @NotBlank(message = "配置方式不能为空")
    private String configType;
}
```

**Step 3: 验证编译**

```bash
cd ruoyi-info-collection && mvn clean compile
```

预期输出：BUILD SUCCESS

**Step 4: 提交代码**

```bash
git add ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiProjectSaveDTO.java
git commit -m "feat: 添加项目保存DTO"
```

---

## Task 4: 创建 VO - CcdiProjectVO

**文件:**

- Create: `ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/CcdiProjectVO.java`

**Step 1: 创建 VO 目录（如果不存在）**

```bash
mkdir -p ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo
```

**Step 2: 创建 VO 类**

创建文件 `ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/CcdiProjectVO.java`：

```java
package com.ruoyi.info.collection.domain.vo;

import lombok.Data;

import java.util.Date;

/**
 * 项目VO
 *
 * @author ruoyi
 */
@Data
public class CcdiProjectVO {
    /** 项目ID */
    private Long projectId;

    /** 项目名称 */
    private String projectName;

    /** 项目描述 */
    private String projectDesc;

    /** 配置方式 */
    private String configType;

    /** 项目状态 */
    private String projectStatus;

    /** 目标人数 */
    private Integer targetCount;

    /** 高风险人数 */
    private Integer highRiskCount;

    /** 中风险人数 */
    private Integer mediumRiskCount;

    /** 低风险人数 */
    private Integer lowRiskCount;

    /** 创建时间 */
    private Date createTime;

    /** 创建者 */
    private String createBy;
}
```

**Step 3: 验证编译**

```bash
cd ruoyi-info-collection && mvn clean compile
```

预期输出：BUILD SUCCESS

**Step 4: 提交代码**

```bash
git add ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/CcdiProjectVO.java
git commit -m "feat: 添加项目VO"
```

---

## Task 5: 创建查询 DTO - CcdiProjectQueryDTO

**文件:**

- Create: `ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiProjectQueryDTO.java`

**Step 1: 创建查询 DTO 类**

创建文件 `ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiProjectQueryDTO.java`：

```java
package com.ruoyi.info.collection.domain.dto;

import lombok.Data;

/**
 * 项目查询DTO
 *
 * @author ruoyi
 */
@Data
public class CcdiProjectQueryDTO {
    /** 项目名称 */
    private String projectName;

    /** 项目状态 */
    private String projectStatus;
}
```

**Step 2: 验证编译**

```bash
cd ruoyi-info-collection && mvn clean compile
```

预期输出：BUILD SUCCESS

**Step 3: 提交代码**

```bash
git add ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiProjectQueryDTO.java
git commit -m "feat: 添加项目查询DTO"
```

---

## Task 6: 创建 Mapper 接口

**文件:**

- Create: `ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/mapper/CcdiProjectMapper.java`

**Step 1: 创建 Mapper 接口**

创建文件 `ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/mapper/CcdiProjectMapper.java`：

```java
package com.ruoyi.info.collection.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.info.collection.domain.CcdiProject;
import com.ruoyi.info.collection.domain.dto.CcdiProjectQueryDTO;
import com.ruoyi.info.collection.domain.vo.CcdiProjectVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

/**
 * 项目Mapper接口
 *
 * @author ruoyi
 */
@Mapper
public interface CcdiProjectMapper extends BaseMapper<CcdiProject> {
    /**
     * 分页查询项目列表
     *
     * @param page 分页对象
     * @param queryDTO 查询条件
     * @return 分页结果
     */
    Page<CcdiProjectVO> selectProjectPage(Page<CcdiProjectVO> page, @Param("queryDTO") CcdiProjectQueryDTO queryDTO);
}
```

**Step 2: 验证编译**

```bash
cd ruoyi-info-collection && mvn clean compile
```

预期输出：BUILD SUCCESS

**Step 3: 提交代码**

```bash
git add ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/mapper/CcdiProjectMapper.java
git commit -m "feat: 添加项目Mapper接口"
```

---

## Task 7: 创建 Mapper XML 文件

**文件:**

- Create: `ruoyi-info-collection/src/main/resources/mapper/info/collection/CcdiProjectMapper.xml`

**Step 1: 创建 Mapper 目录（如果不存在）**

```bash
mkdir -p ruoyi-info-collection/src/main/resources/mapper/info/collection
```

**Step 2: 创建 XML 文件**

创建文件 `ruoyi-info-collection/src/main/resources/mapper/info/collection/CcdiProjectMapper.xml`：

```xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.info.collection.mapper.CcdiProjectMapper">

    <resultMap id="ProjectVOResultMap" type="com.ruoyi.info.collection.domain.vo.CcdiProjectVO">
        <id property="projectId" column="project_id"/>
        <result property="projectName" column="project_name"/>
        <result property="projectDesc" column="project_desc"/>
        <result property="configType" column="config_type"/>
        <result property="projectStatus" column="project_status"/>
        <result property="targetCount" column="target_count"/>
        <result property="highRiskCount" column="high_risk_count"/>
        <result property="mediumRiskCount" column="medium_risk_count"/>
        <result property="lowRiskCount" column="low_risk_count"/>
        <result property="createTime" column="create_time"/>
        <result property="createBy" column="create_by"/>
    </resultMap>

    <!-- 分页查询项目列表 -->
    <select id="selectProjectPage" resultMap="ProjectVOResultMap">
        SELECT
            project_id, project_name, project_desc, config_type,
            project_status, target_count, high_risk_count,
            medium_risk_count, low_risk_count, create_time, create_by
        FROM ccdi_project
        <where>
            <if test="queryDTO.projectName != null and queryDTO.projectName != ''">
                AND project_name LIKE CONCAT('%', #{queryDTO.projectName}, '%')
            </if>
            <if test="queryDTO.projectStatus != null and queryDTO.projectStatus != ''">
                AND project_status = #{queryDTO.projectStatus}
            </if>
        </where>
        ORDER BY create_time DESC
    </select>
</mapper>
```

**Step 3: 验证编译**

```bash
cd ruoyi-info-collection && mvn clean compile
```

预期输出：BUILD SUCCESS

**Step 4: 提交代码**

```bash
git add ruoyi-info-collection/src/main/resources/mapper/info/collection/CcdiProjectMapper.xml
git commit -m "feat: 添加项目Mapper XML配置"
```

---

## Task 8: 创建 Service 接口

**文件:**

- Create: `ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/service/ICcdiProjectService.java`

**Step 1: 创建 Service 接口**

创建文件 `ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/service/ICcdiProjectService.java`：

```java
package com.ruoyi.info.collection.service;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.info.collection.domain.dto.CcdiProjectQueryDTO;
import com.ruoyi.info.collection.domain.dto.CcdiProjectSaveDTO;
import com.ruoyi.info.collection.domain.vo.CcdiProjectVO;

/**
 * 项目Service接口
 *
 * @author ruoyi
 */
public interface ICcdiProjectService {
    /**
     * 创建项目
     *
     * @param dto 项目保存DTO
     * @return 项目VO
     */
    CcdiProjectVO createProject(CcdiProjectSaveDTO dto);

    /**
     * 更新项目
     *
     * @param dto 项目更新DTO
     * @return 项目VO
     */
    CcdiProjectVO updateProject(CcdiProjectSaveDTO dto);

    /**
     * 删除项目
     *
     * @param projectId 项目ID
     * @return 是否成功
     */
    boolean deleteProject(Long projectId);

    /**
     * 查询项目详情
     *
     * @param projectId 项目ID
     * @return 项目VO
     */
    CcdiProjectVO getProjectById(Long projectId);

    /**
     * 分页查询项目列表
     *
     * @param page 分页对象
     * @param queryDTO 查询条件
     * @return 分页结果
     */
    Page<CcdiProjectVO> selectProjectPage(Page<CcdiProjectVO> page, CcdiProjectQueryDTO queryDTO);
}
```

**Step 2: 验证编译**

```bash
cd ruoyi-info-collection && mvn clean compile
```

预期输出：BUILD SUCCESS

**Step 3: 提交代码**

```bash
git add ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/service/ICcdiProjectService.java
git commit -m "feat: 添加项目Service接口"
```

---

## Task 9: 创建 Service 实现类

**文件:**

- Create: `ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiProjectServiceImpl.java`

**Step 1: 创建 Service 实现目录（如果不存在）**

```bash
mkdir -p ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl
```

**Step 2: 创建 Service 实现类**

创建文件 `ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiProjectServiceImpl.java`：

```java
package com.ruoyi.info.collection.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.info.collection.domain.CcdiProject;
import com.ruoyi.info.collection.domain.dto.CcdiProjectQueryDTO;
import com.ruoyi.info.collection.domain.dto.CcdiProjectSaveDTO;
import com.ruoyi.info.collection.domain.vo.CcdiProjectVO;
import com.ruoyi.info.collection.mapper.CcdiProjectMapper;
import com.ruoyi.info.collection.service.ICcdiProjectService;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

/**
 * 项目Service实现类
 *
 * @author ruoyi
 */
@Service
public class CcdiProjectServiceImpl implements ICcdiProjectService {

    @Resource
    private CcdiProjectMapper projectMapper;

    @Override
    public CcdiProjectVO createProject(CcdiProjectSaveDTO dto) {
        CcdiProject project = new CcdiProject();
        BeanUtils.copyProperties(dto, project);

        // 设置默认值
        project.setProjectStatus("0"); // 进行中
        project.setTargetCount(0);
        project.setHighRiskCount(0);
        project.setMediumRiskCount(0);
        project.setLowRiskCount(0);

        projectMapper.insert(project);

        CcdiProjectVO vo = new CcdiProjectVO();
        BeanUtils.copyProperties(project, vo);
        return vo;
    }

    @Override
    public CcdiProjectVO updateProject(CcdiProjectSaveDTO dto) {
        // TODO: 实现更新逻辑
        return null;
    }

    @Override
    public boolean deleteProject(Long projectId) {
        return projectMapper.deleteById(projectId) > 0;
    }

    @Override
    public CcdiProjectVO getProjectById(Long projectId) {
        CcdiProject project = projectMapper.selectById(projectId);
        if (project == null) {
            return null;
        }
        CcdiProjectVO vo = new CcdiProjectVO();
        BeanUtils.copyProperties(project, vo);
        return vo;
    }

    @Override
    public Page<CcdiProjectVO> selectProjectPage(Page<CcdiProjectVO> page, CcdiProjectQueryDTO queryDTO) {
        return projectMapper.selectProjectPage(page, queryDTO);
    }
}
```

**Step 3: 验证编译**

```bash
cd ruoyi-info-collection && mvn clean compile
```

预期输出：BUILD SUCCESS

**Step 4: 提交代码**

```bash
git add ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiProjectServiceImpl.java
git commit -m "feat: 添加项目Service实现类"
```

---

## Task 10: 创建 Controller

**文件:**

- Create: `ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiProjectController.java`

**Step 1: 创建 Controller 类**

创建文件 `ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiProjectController.java`：

```java
package com.ruoyi.info.collection.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.controller.BaseController;
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.info.collection.domain.dto.CcdiProjectQueryDTO;
import com.ruoyi.info.collection.domain.dto.CcdiProjectSaveDTO;
import com.ruoyi.info.collection.domain.vo.CcdiProjectVO;
import com.ruoyi.info.collection.service.ICcdiProjectService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

/**
 * 纪检初核项目管理Controller
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/ccdi/project")
@Tag(name = "纪检初核项目管理")
public class CcdiProjectController extends BaseController {

    @Resource
    private ICcdiProjectService projectService;

    /**
     * 创建项目
     */
    @PostMapping
    @Operation(summary = "创建项目")
    @PreAuthorize("@ss.hasPermi('ccdi:project:add')")
    public AjaxResult createProject(@Validated @RequestBody CcdiProjectSaveDTO dto) {
        CcdiProjectVO vo = projectService.createProject(dto);
        return AjaxResult.success("项目创建成功", vo);
    }

    /**
     * 更新项目
     */
    @PutMapping
    @Operation(summary = "更新项目")
    @PreAuthorize("@ss.hasPermi('ccdi:project:edit')")
    public AjaxResult updateProject(@Validated @RequestBody CcdiProjectSaveDTO dto) {
        CcdiProjectVO vo = projectService.updateProject(dto);
        return AjaxResult.success("项目更新成功", vo);
    }

    /**
     * 删除项目
     */
    @DeleteMapping("/{projectId}")
    @Operation(summary = "删除项目")
    @PreAuthorize("@ss.hasPermi('ccdi:project:remove')")
    public AjaxResult deleteProject(@PathVariable Long projectId) {
        boolean success = projectService.deleteProject(projectId);
        return success ? AjaxResult.success("项目删除成功") : AjaxResult.error("项目删除失败");
    }

    /**
     * 查询项目详情
     */
    @GetMapping("/{projectId}")
    @Operation(summary = "查询项目详情")
    @PreAuthorize("@ss.hasPermi('ccdi:project:query')")
    public AjaxResult getProject(@PathVariable Long projectId) {
        CcdiProjectVO vo = projectService.getProjectById(projectId);
        return AjaxResult.success(vo);
    }

    /**
     * 查询项目列表（分页）
     */
    @GetMapping("/list")
    @Operation(summary = "查询项目列表")
    @PreAuthorize("@ss.hasPermi('ccdi:project:list')")
    public TableDataInfo listProject(CcdiProjectQueryDTO queryDTO) {
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Page<CcdiProjectVO> page = new Page<>(pageDomain.getPageNum(), pageDomain.getPageSize());
        Page<CcdiProjectVO> result = projectService.selectProjectPage(page, queryDTO);
        return getDataTable(result.getRecords(), result.getTotal());
    }
}
```

**Step 2: 验证编译**

```bash
cd ruoyi-info-collection && mvn clean compile
```

预期输出：BUILD SUCCESS

**Step 3: 提交代码**

```bash
git add ruoyi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiProjectController.java
git commit -m "feat: 添加项目Controller"
```

---

## Task 11: 启动后端并测试接口

**Step 1: 启动后端服务**

```bash
cd ruoyi-admin && mvn spring-boot:run
```

预期输出：Spring Boot 启动成功日志，端口 8080

**Step 2: 获取测试 Token**

使用测试接口获取 Token：

```bash
curl -X POST "http://localhost:8080/login/test?username=admin&password=admin123"
```

预期输出：返回包含 token 的 JSON 响应

**Step 3: 测试创建项目接口**

使用 Token 测试创建项目接口：

```bash
curl -X POST "http://localhost:8080/ccdi/project" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "projectName": "测试项目1",
    "projectDesc": "这是测试项目描述",
    "configType": "default"
  }'
```

预期输出：返回成功响应，包含项目 ID 和创建的项目信息

**Step 4: 测试查询项目列表接口**

```bash
curl -X GET "http://localhost:8080/ccdi/project/list?pageNum=1&pageSize=10" \
  -H "Authorization: Bearer <token>"
```

预期输出：返回分页数据，包含刚才创建的项目

**Step 5: 使用 Swagger 测试**

访问 Swagger UI 进行接口测试：

```bash
# 浏览器打开
http://localhost:8080/swagger-ui/index.html
```

预期结果：在 Swagger UI 中可以看到项目管理的所有接口，并进行测试

---

## Task 12: 提交最终代码

**Step 1: 检查所有文件**

```bash
git status
```

预期输出：所有后端文件已提交

**Step 2: 推送到远程仓库**

```bash
git push origin dev
```

预期输出：推送成功

---

## 完成检查清单

- [ ] 数据库表 `ccdi_project` 创建成功
- [ ] 字典数据 `ccdi_project_status` 和 `ccdi_config_type` 插入成功
- [ ] 菜单权限配置成功
- [ ] 实体类 `CcdiProject` 创建并编译通过
- [ ] DTO `CcdiProjectSaveDTO` 创建并编译通过
- [ ] VO `CcdiProjectVO` 创建并编译通过
- [ ] Mapper 接口和 XML 创建并编译通过
- [ ] Service 接口和实现类创建并编译通过
- [ ] Controller 创建并编译通过
- [ ] 后端服务启动成功
- [ ] 创建项目接口测试通过
- [ ] 查询项目列表接口测试通过
- [ ] Swagger 文档显示正确
- [ ] 所有代码已提交到 git

---

**后端实施计划完成！**
