# 员工采购交易信息管理功能实施计划 > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. **目标:** 构建完整的员工采购交易信息管理模块,支持CRUD操作、分页查询、异步导入导出、批量删除等功能 **架构:** 基于若依框架前后端分离架构,后端使用MyBatis Plus + EasyExcel + Redis实现异步导入,前端使用Vue 2 + Element UI **技术栈:** - 后端: Spring Boot 3.5.8, MyBatis Plus 3.5.10, EasyExcel, Redis - 前端: Vue 2.6.12, Element UI 2.15.14, Axios - 数据库: MySQL 8.2.0 --- ## 前置条件 ### 参考文档 - 员工招聘信息模块: `ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/**/CcdiStaffRecruitment*` - 员工异步导入实现: `ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/impl/CcdiEmployeeImportServiceImpl.java` - 数据库表定义: `doc/docs/ccdi_purchase_transaction.csv` ### 数据库表结构 ```sql CREATE TABLE `ccdi_purchase_transaction` ( `purchase_id` VARCHAR(32) NOT NULL COMMENT '采购事项ID', `purchase_category` VARCHAR(50) NOT NULL COMMENT '采购类别', `project_name` VARCHAR(200) DEFAULT NULL COMMENT '项目名称', `subject_name` VARCHAR(200) NOT NULL COMMENT '标的物名称', `subject_desc` TEXT COMMENT '标的物描述', `purchase_qty` DECIMAL(12,4) NOT NULL DEFAULT 1 COMMENT '采购数量', `budget_amount` DECIMAL(18,2) NOT NULL COMMENT '预算金额', `bid_amount` DECIMAL(18,2) DEFAULT NULL COMMENT '中标金额', `actual_amount` DECIMAL(18,2) DEFAULT NULL COMMENT '实际采购金额', `contract_amount` DECIMAL(18,2) DEFAULT NULL COMMENT '合同金额', `settlement_amount` DECIMAL(18,2) DEFAULT NULL COMMENT '结算金额', `purchase_method` VARCHAR(50) NOT NULL COMMENT '采购方式', `supplier_name` VARCHAR(200) DEFAULT NULL COMMENT '中标供应商名称', `contact_person` VARCHAR(50) DEFAULT NULL COMMENT '供应商联系人', `contact_phone` VARCHAR(20) DEFAULT NULL COMMENT '供应商联系电话', `supplier_uscc` VARCHAR(18) DEFAULT NULL COMMENT '供应商统一信用代码', `supplier_bank_account` VARCHAR(50) DEFAULT NULL COMMENT '供应商银行账户', `apply_date` DATE NOT NULL COMMENT '采购申请日期', `plan_approve_date` DATE DEFAULT NULL COMMENT '采购计划批准日期', `announce_date` DATE DEFAULT NULL COMMENT '采购公告发布日期', `bid_open_date` DATE DEFAULT NULL COMMENT '开标日期', `contract_sign_date` DATE DEFAULT NULL COMMENT '合同签订日期', `expected_delivery_date` DATE DEFAULT NULL COMMENT '预计交货日期', `actual_delivery_date` DATE DEFAULT NULL COMMENT '实际交货日期', `acceptance_date` DATE DEFAULT NULL COMMENT '验收日期', `settlement_date` DATE DEFAULT NULL COMMENT '结算日期', `applicant_id` VARCHAR(7) NOT NULL COMMENT '申请人工号', `applicant_name` VARCHAR(50) NOT NULL COMMENT '申请人姓名', `apply_department` VARCHAR(100) NOT NULL COMMENT '申请部门', `purchase_leader_id` VARCHAR(7) DEFAULT NULL COMMENT '采购负责人工号', `purchase_leader_name` VARCHAR(50) DEFAULT NULL COMMENT '采购负责人姓名', `purchase_department` VARCHAR(100) DEFAULT NULL COMMENT '采购部门', `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `created_by` VARCHAR(50) NOT NULL COMMENT '创建人', `updated_by` VARCHAR(50) DEFAULT NULL COMMENT '更新人', PRIMARY KEY (`purchase_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='员工采购交易信息表'; ``` --- ## Task 1: 创建数据库表 **Files:** - Modify: 执行SQL创建表 **Step 1: 连接数据库并创建表** 使用MCP连接MySQL数据库: ```bash # 使用 mcp__mysql__connect_db 连接到数据库 # 然后执行上面的CREATE TABLE语句 ``` **Step 2: 验证表创建** ```sql SHOW CREATE TABLE ccdi_purchase_transaction; ``` Expected: 表结构正确创建 **Step 3: Commit** ```bash git add sql/ git commit -m "feat: 添加员工采购交易信息表" ``` --- ## Task 2: 创建实体类 **Files:** - Create: `ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/domain/CcdiPurchaseTransaction.java` **Step 1: 创建实体类** ```java package com.ruoyi.ccdi.domain; import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import lombok.Data; import java.io.Serial; import java.io.Serializable; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; /** * 员工采购交易信息对象 ccdi_purchase_transaction * * @author ruoyi * @date 2026-02-06 */ @Data public class CcdiPurchaseTransaction implements Serializable { @Serial private static final long serialVersionUID = 1L; /** 采购事项ID */ @TableId(type = IdType.INPUT) private String purchaseId; /** 采购类别 */ private String purchaseCategory; /** 项目名称 */ private String projectName; /** 标的物名称 */ private String subjectName; /** 标的物描述 */ private String subjectDesc; /** 采购数量 */ private BigDecimal purchaseQty; /** 预算金额 */ private BigDecimal budgetAmount; /** 中标金额 */ private BigDecimal bidAmount; /** 实际采购金额 */ private BigDecimal actualAmount; /** 合同金额 */ private BigDecimal contractAmount; /** 结算金额 */ private BigDecimal settlementAmount; /** 采购方式 */ private String purchaseMethod; /** 中标供应商名称 */ private String supplierName; /** 供应商联系人 */ private String contactPerson; /** 供应商联系电话 */ private String contactPhone; /** 供应商统一信用代码 */ private String supplierUscc; /** 供应商银行账户 */ private String supplierBankAccount; /** 采购申请日期 */ private LocalDate applyDate; /** 采购计划批准日期 */ private LocalDate planApproveDate; /** 采购公告发布日期 */ private LocalDate announceDate; /** 开标日期 */ private LocalDate bidOpenDate; /** 合同签订日期 */ private LocalDate contractSignDate; /** 预计交货日期 */ private LocalDate expectedDeliveryDate; /** 实际交货日期 */ private LocalDate actualDeliveryDate; /** 验收日期 */ private LocalDate acceptanceDate; /** 结算日期 */ private LocalDate settlementDate; /** 申请人工号 */ private String applicantId; /** 申请人姓名 */ private String applicantName; /** 申请部门 */ private String applyDepartment; /** 采购负责人工号 */ private String purchaseLeaderId; /** 采购负责人姓名 */ private String purchaseLeaderName; /** 采购部门 */ private String purchaseDepartment; /** 创建时间 */ @TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; /** 更新时间 */ @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; /** 创建人 */ @TableField(fill = FieldFill.INSERT) private String createdBy; /** 更新人 */ @TableField(fill = FieldFill.INSERT_UPDATE) private String updatedBy; } ``` **Step 2: 验证编译** ```bash cd ruoyi-ccdi mvn compile -pl . -am ``` Expected: 编译成功,无错误 **Step 3: Commit** ```bash git add ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/domain/CcdiPurchaseTransaction.java git commit -m "feat: 添加采购交易信息实体类" ``` --- ## Task 3: 创建查询DTO **Files:** - Create: `ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/domain/dto/CcdiPurchaseTransactionQueryDTO.java` **Step 1: 创建查询DTO** ```java package com.ruoyi.ccdi.domain.dto; import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.io.Serial; import java.io.Serializable; import java.time.LocalDate; /** * 采购交易信息查询DTO * * @author ruoyi * @date 2026-02-06 */ @Data @Schema(description = "采购交易信息查询条件") public class CcdiPurchaseTransactionQueryDTO implements Serializable { @Serial private static final long serialVersionUID = 1L; /** 项目名称 */ @Schema(description = "项目名称") private String projectName; /** 标的物名称 */ @Schema(description = "标的物名称") private String subjectName; /** 申请人姓名 */ @Schema(description = "申请人姓名") private String applicantName; /** 申请人工号 */ @Schema(description = "申请人工号") private String applicantId; /** 申请日期-开始 */ @Schema(description = "申请日期-开始") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate applyDateStart; /** 申请日期-结束 */ @Schema(description = "申请日期-结束") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate applyDateEnd; } ``` **Step 2: Commit** ```bash git add ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/domain/dto/CcdiPurchaseTransactionQueryDTO.java git commit -m "feat: 添加采购交易查询DTO" ``` --- ## Task 4: 创建新增DTO **Files:** - Create: `ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/domain/dto/CcdiPurchaseTransactionAddDTO.java` **Step 1: 创建新增DTO(包含验证注解)** ```java package com.ruoyi.ccdi.domain.dto; import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.*; import lombok.Data; import java.io.Serial; import java.io.Serializable; import java.math.BigDecimal; import java.time.LocalDate; /** * 采购交易信息新增DTO * * @author ruoyi * @date 2026-02-06 */ @Data @Schema(description = "采购交易信息新增") public class CcdiPurchaseTransactionAddDTO implements Serializable { @Serial private static final long serialVersionUID = 1L; @Schema(description = "采购事项ID") @NotBlank(message = "采购事项ID不能为空") @Size(max = 32, message = "采购事项ID长度不能超过32个字符") private String purchaseId; @Schema(description = "采购类别") @NotBlank(message = "采购类别不能为空") @Size(max = 50, message = "采购类别长度不能超过50个字符") private String purchaseCategory; @Schema(description = "项目名称") @Size(max = 200, message = "项目名称长度不能超过200个字符") private String projectName; @Schema(description = "标的物名称") @NotBlank(message = "标的物名称不能为空") @Size(max = 200, message = "标的物名称长度不能超过200个字符") private String subjectName; @Schema(description = "标的物描述") private String subjectDesc; @Schema(description = "采购数量") @NotNull(message = "采购数量不能为空") @DecimalMin(value = "0.0001", message = "采购数量必须大于0") private BigDecimal purchaseQty; @Schema(description = "预算金额") @NotNull(message = "预算金额不能为空") @DecimalMin(value = "0.01", message = "预算金额必须大于0") private BigDecimal budgetAmount; @Schema(description = "中标金额") @DecimalMin(value = "0", message = "中标金额不能为负数") private BigDecimal bidAmount; @Schema(description = "实际采购金额") @DecimalMin(value = "0", message = "实际采购金额不能为负数") private BigDecimal actualAmount; @Schema(description = "合同金额") @DecimalMin(value = "0", message = "合同金额不能为负数") private BigDecimal contractAmount; @Schema(description = "结算金额") @DecimalMin(value = "0", message = "结算金额不能为负数") private BigDecimal settlementAmount; @Schema(description = "采购方式") @NotBlank(message = "采购方式不能为空") @Size(max = 50, message = "采购方式长度不能超过50个字符") private String purchaseMethod; @Schema(description = "中标供应商名称") @Size(max = 200, message = "中标供应商名称长度不能超过200个字符") private String supplierName; @Schema(description = "供应商联系人") @Size(max = 50, message = "供应商联系人长度不能超过50个字符") private String contactPerson; @Schema(description = "供应商联系电话") @Size(max = 20, message = "供应商联系电话长度不能超过20个字符") private String contactPhone; @Schema(description = "供应商统一信用代码") @Size(max = 18, message = "供应商统一信用代码长度不能超过18个字符") private String supplierUscc; @Schema(description = "供应商银行账户") @Size(max = 50, message = "供应商银行账户长度不能超过50个字符") private String supplierBankAccount; @Schema(description = "采购申请日期") @NotNull(message = "采购申请日期不能为空") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate applyDate; @Schema(description = "采购计划批准日期") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate planApproveDate; @Schema(description = "采购公告发布日期") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate announceDate; @Schema(description = "开标日期") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate bidOpenDate; @Schema(description = "合同签订日期") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate contractSignDate; @Schema(description = "预计交货日期") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate expectedDeliveryDate; @Schema(description = "实际交货日期") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate actualDeliveryDate; @Schema(description = "验收日期") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate acceptanceDate; @Schema(description = "结算日期") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate settlementDate; @Schema(description = "申请人工号") @NotBlank(message = "申请人工号不能为空") @Pattern(regexp = "^\\d{7}$", message = "申请人工号必须为7位数字") private String applicantId; @Schema(description = "申请人姓名") @NotBlank(message = "申请人姓名不能为空") @Size(max = 50, message = "申请人姓名长度不能超过50个字符") private String applicantName; @Schema(description = "申请部门") @NotBlank(message = "申请部门不能为空") @Size(max = 100, message = "申请部门长度不能超过100个字符") private String applyDepartment; @Schema(description = "采购负责人工号") @Pattern(regexp = "^\\d{7}$", message = "采购负责人工号必须为7位数字") private String purchaseLeaderId; @Schema(description = "采购负责人姓名") @Size(max = 50, message = "采购负责人姓名长度不能超过50个字符") private String purchaseLeaderName; @Schema(description = "采购部门") @Size(max = 100, message = "采购部门长度不能超过100个字符") private String purchaseDepartment; } ``` **Step 2: Commit** ```bash git add ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/domain/dto/CcdiPurchaseTransactionAddDTO.java git commit -m "feat: 添加采购交易新增DTO" ``` --- ## Task 5: 创建编辑DTO **Files:** - Create: `ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/domain/dto/CcdiPurchaseTransactionEditDTO.java` **Step 1: 创建编辑DTO** 复制AddDTO的内容,修改类名和类注释,所有验证注解保持不变。 **Step 2: Commit** ```bash git add ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/domain/dto/CcdiPurchaseTransactionEditDTO.java git commit -m "feat: 添加采购交易编辑DTO" ``` --- ## Task 6: 创建VO类 **Files:** - Create: `ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/domain/vo/CcdiPurchaseTransactionVO.java` **Step 1: 创建VO类** ```java package com.ruoyi.ccdi.domain.vo; import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.io.Serial; import java.io.Serializable; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; /** * 采购交易信息VO * * @author ruoyi * @date 2026-02-06 */ @Data @Schema(description = "采购交易信息") public class CcdiPurchaseTransactionVO implements Serializable { @Serial private static final long serialVersionUID = 1L; @Schema(description = "采购事项ID") private String purchaseId; @Schema(description = "采购类别") private String purchaseCategory; @Schema(description = "项目名称") private String projectName; @Schema(description = "标的物名称") private String subjectName; @Schema(description = "标的物描述") private String subjectDesc; @Schema(description = "采购数量") private BigDecimal purchaseQty; @Schema(description = "预算金额") private BigDecimal budgetAmount; @Schema(description = "中标金额") private BigDecimal bidAmount; @Schema(description = "实际采购金额") private BigDecimal actualAmount; @Schema(description = "合同金额") private BigDecimal contractAmount; @Schema(description = "结算金额") private BigDecimal settlementAmount; @Schema(description = "采购方式") private String purchaseMethod; @Schema(description = "中标供应商名称") private String supplierName; @Schema(description = "供应商联系人") private String contactPerson; @Schema(description = "供应商联系电话") private String contactPhone; @Schema(description = "供应商统一信用代码") private String supplierUscc; @Schema(description = "供应商银行账户") private String supplierBankAccount; @Schema(description = "采购申请日期") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate applyDate; @Schema(description = "采购计划批准日期") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate planApproveDate; @Schema(description = "采购公告发布日期") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate announceDate; @Schema(description = "开标日期") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate bidOpenDate; @Schema(description = "合同签订日期") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate contractSignDate; @Schema(description = "预计交货日期") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate expectedDeliveryDate; @Schema(description = "实际交货日期") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate actualDeliveryDate; @Schema(description = "验收日期") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate acceptanceDate; @Schema(description = "结算日期") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate settlementDate; @Schema(description = "申请人工号") private String applicantId; @Schema(description = "申请人姓名") private String applicantName; @Schema(description = "申请部门") private String applyDepartment; @Schema(description = "采购负责人工号") private String purchaseLeaderId; @Schema(description = "采购负责人姓名") private String purchaseLeaderName; @Schema(description = "采购部门") private String purchaseDepartment; @Schema(description = "创建时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime createTime; @Schema(description = "更新时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime updateTime; @Schema(description = "创建人") private String createdBy; @Schema(description = "更新人") private String updatedBy; } ``` **Step 2: Commit** ```bash git add ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/domain/vo/CcdiPurchaseTransactionVO.java git commit -m "feat: 添加采购交易VO类" ``` --- ## Task 7: 创建Excel导入导出类 **Files:** - Create: `ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/domain/excel/CcdiPurchaseTransactionExcel.java` **Step 1: 创建Excel类** 参考 `CcdiStaffRecruitmentExcel.java`,为36个字段添加 `@ExcelProperty`、`@ColumnWidth`、`@Required` 注解。必填字段:purchaseId, purchaseCategory, subjectName, purchaseQty, budgetAmount, purchaseMethod, applyDate, applicantId, applicantName, applyDepartment。 **Step 2: Commit** ```bash git add ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/domain/excel/CcdiPurchaseTransactionExcel.java git commit -m "feat: 添加采购交易Excel类" ``` --- ## Task 8: 创建Mapper接口 **Files:** - Create: `ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/mapper/CcdiPurchaseTransactionMapper.java` **Step 1: 创建Mapper接口** ```java package com.ruoyi.ccdi.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.ccdi.domain.CcdiPurchaseTransaction; import com.ruoyi.ccdi.domain.dto.CcdiPurchaseTransactionQueryDTO; import com.ruoyi.ccdi.domain.vo.CcdiPurchaseTransactionVO; import org.apache.ibatis.annotations.Param; import java.util.List; /** * 采购交易信息 数据层 * * @author ruoyi * @date 2026-02-06 */ public interface CcdiPurchaseTransactionMapper extends BaseMapper { /** * 分页查询采购交易列表 */ Page selectTransactionPage(@Param("page") Page page, @Param("query") CcdiPurchaseTransactionQueryDTO queryDTO); /** * 查询采购交易详情 */ CcdiPurchaseTransactionVO selectTransactionById(@Param("purchaseId") String purchaseId); /** * 批量插入 */ int insertBatch(@Param("list") List list); /** * 批量更新(先删除再插入) */ int insertOrUpdateBatch(@Param("list") List list); } ``` **Step 2: Commit** ```bash git add ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/mapper/CcdiPurchaseTransactionMapper.java git commit -m "feat: 添加采购交易Mapper接口" ``` --- ## Task 9: 创建Mapper XML文件 **Files:** - Create: `ruoyi-ccdi/src/main/resources/mapper/ccdi/CcdiPurchaseTransactionMapper.xml` **Step 1: 创建XML映射文件** 参考 `CcdiStaffRecruitmentMapper.xml`,编写SQL映射: - selectTransactionPage: 分页查询,支持项目名称、标的物名称、申请人、日期范围查询 - selectTransactionById: 根据ID查询详情 - insertBatch: 批量插入 - insertOrUpdateBatch: 批量更新(先删除再插入) **Step 2: Commit** ```bash git add ruoyi-ccdi/src/main/resources/mapper/ccdi/CcdiPurchaseTransactionMapper.xml git commit -m "feat: 添加采购交易Mapper XML" ``` --- ## Task 10: 创建Service接口 **Files:** - Create: `ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/ICcdiPurchaseTransactionService.java` **Step 1: 创建Service接口** 参考 `ICcdiStaffRecruitmentService.java`,定义以下方法: - selectTransactionList - selectTransactionPage - selectTransactionListForExport - selectTransactionById - insertTransaction - updateTransaction - deleteTransactionByIds - importTransaction (返回taskId) **Step 2: Commit** ```bash git add ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/ICcdiPurchaseTransactionService.java git commit -m "feat: 添加采购交易Service接口" ``` --- ## Task 11: 创建异步导入Service接口 **Files:** - Create: `ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/ICcdiPurchaseTransactionImportService.java` **Step 1: 创建异步导入Service接口** 参考 `ICcdiEmployeeImportService.java`,定义方法: - importTransactionAsync - getImportStatus - getImportFailures **Step 2: Commit** ```bash git add ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/ICcdiPurchaseTransactionImportService.java git commit -m "feat: 添加采购交易异步导入Service接口" ``` --- ## Task 12: 创建Service实现类 **Files:** - Create: `ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/impl/CcdiPurchaseTransactionServiceImpl.java` **Step 1: 创建Service实现** 参考 `CcdiStaffRecruitmentServiceImpl.java`,实现所有CRUD方法和importTransaction方法(初始化Redis状态,调用异步服务)。 **Step 2: Commit** ```bash git add ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/impl/CcdiPurchaseTransactionServiceImpl.java git commit -m "feat: 添加采购交易Service实现" ``` --- ## Task 13: 创建异步导入Service实现类 **Files:** - Create: `ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/impl/CcdiPurchaseTransactionImportServiceImpl.java` **Step 1: 创建异步导入实现** 参考 `CcdiEmployeeImportServiceImpl.java`,实现: - @Async + @Transactional 注解 - importTransactionAsync方法(接收userName参数) - 数据分类(新记录/更新记录/失败记录) - 批量插入和更新 - Redis状态管理 - 数据验证逻辑 **Step 2: Commit** ```bash git add ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/impl/CcdiPurchaseTransactionImportServiceImpl.java git commit -m "feat: 添加采购交易异步导入Service实现" ``` --- ## Task 14: 创建Controller控制器 **Files:** - Create: `ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/controller/CcdiPurchaseTransactionController.java` **Step 1: 创建Controller** 参考 `CcdiStaffRecruitmentController.java` 和 `CcdiEmployeeController.java`,实现接口: - GET /list - 分页查询 - GET /{purchaseId} - 查询详情 - POST / - 新增 - PUT / - 修改 - DELETE /{purchaseIds} - 删除 - POST /export - 导出 - POST /importTemplate - 下载模板 - POST /importData - 异步导入 - GET /importStatus/{taskId} - 查询导入状态 - GET /importFailures/{taskId} - 查询失败记录 添加完整的Swagger注解。 **Step 2: Commit** ```bash git add ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/controller/CcdiPurchaseTransactionController.java git commit -m "feat: 添加采购交易Controller" ``` --- ## Task 15: 创建前端API文件 **Files:** - Create: `ruoyi-ui/src/api/ccdiPurchaseTransaction.js` **Step 1: 创建API定义** ```javascript import request from '@/utils/request' // 查询采购交易列表 export function listTransaction(query) { return request({ url: '/ccdi/purchaseTransaction/list', method: 'get', params: query }) } // 查询采购交易详情 export function getTransaction(purchaseId) { return request({ url: '/ccdi/purchaseTransaction/' + purchaseId, method: 'get' }) } // 新增采购交易 export function addTransaction(data) { return request({ url: '/ccdi/purchaseTransaction', method: 'post', data: data }) } // 修改采购交易 export function updateTransaction(data) { return request({ url: '/ccdi/purchaseTransaction', method: 'put', data: data }) } // 删除采购交易 export function delTransaction(purchaseIds) { return request({ url: '/ccdi/purchaseTransaction/' + purchaseIds, method: 'delete' }) } // 导出采购交易 export function exportTransaction(query) { return request({ url: '/ccdi/purchaseTransaction/export', method: 'post', params: query }) } // 下载导入模板 export function importTemplate() { return request({ url: '/ccdi/purchaseTransaction/importTemplate', method: 'post' }) } // 导入采购交易 export function importData(file, updateSupport) { const formData = new FormData() formData.append('file', file) formData.append('updateSupport', updateSupport) return request({ url: '/ccdi/purchaseTransaction/importData', method: 'post', data: formData }) } // 查询导入状态 export function getImportStatus(taskId) { return request({ url: '/ccdi/purchaseTransaction/importStatus/' + taskId, method: 'get' }) } // 查询导入失败记录 export function getImportFailures(taskId, pageNum, pageSize) { return request({ url: '/ccdi/purchaseTransaction/importFailures/' + taskId, method: 'get', params: { pageNum, pageSize } }) } ``` **Step 2: Commit** ```bash git add ruoyi-ui/src/api/ccdiPurchaseTransaction.js git commit -m "feat: 添加采购交易前端API" ``` --- ## Task 16: 创建前端页面组件 **Files:** - Create: `ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue` **Step 1: 创建页面组件** 参考 `ruoyi-ui/src/views/ccdiStaffRecruitment/index.vue`,实现: - 查询表单(项目名称、标的物名称、申请人、日期范围) - 列表表格(13个字段 + 操作列) - 新增/编辑对话框 - 导入对话框(支持异步导入状态轮询) - 删除确认 **Step 2: Commit** ```bash git add ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue git commit -m "feat: 添加采购交易管理页面" ``` --- ## Task 17: 配置菜单和权限 **Files:** - Modify: 数据库菜单表 **Step 1: 添加菜单数据** 执行SQL: ```sql -- 添加采购交易管理菜单 INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark) VALUES ('采购交易管理', (SELECT menu_id FROM sys_menu WHERE menu_name='CCDI管理' AND parent_id=0), 5, 'purchaseTransaction', 'ccdiPurchaseTransaction/index', 1, 0, 'C', '0', '0', 'ccdi:purchaseTransaction:list', 'shopping', 'admin', NOW(), '', NULL, '采购交易信息管理菜单'); -- 获取刚插入的菜单ID SET @menu_id = LAST_INSERT_ID(); -- 添加按钮权限 INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark) VALUES ('采购交易查询', @menu_id, 1, '', '', 1, 0, 'F', '0', '0', 'ccdi:purchaseTransaction:query', '#', 'admin', NOW(), ''), ('采购交易新增', @menu_id, 2, '', '', 1, 0, 'F', '0', '0', 'ccdi:purchaseTransaction:add', '#', 'admin', NOW(), ''), ('采购交易修改', @menu_id, 3, '', '', 1, 0, 'F', '0', '0', 'ccdi:purchaseTransaction:edit', '#', 'admin', NOW(), ''), ('采购交易删除', @menu_id, 4, '', '', 1, 0, 'F', '0', '0', 'ccdi:purchaseTransaction:remove', '#', 'admin', NOW(), ''), ('采购交易导出', @menu_id, 5, '', '', 1, 0, 'F', '0', '0', 'ccdi:purchaseTransaction:export', '#', 'admin', NOW(), ''), ('采购交易导入', @menu_id, 6, '', '', 1, 0, 'F', '0', '0', 'ccdi:purchaseTransaction:import', '#', 'admin', NOW(), ''); ``` **Step 2: Commit** ```bash git add sql/ git commit -m "feat: 配置采购交易管理菜单和权限" ``` --- ## Task 18: 生成测试脚本 **Files:** - Create: `test/test_purchase_transaction_api.ps1` **Step 1: 创建测试脚本** 参考 `test/test_employee_api.ps1`,编写完整的测试脚本: - 登录获取token - 测试分页查询 - 测试新增 - 测试查询详情 - 测试修改 - 测试删除 - 测试导入 - 测试导出 **Step 2: Commit** ```bash git add test/test_purchase_transaction_api.ps1 git commit -m "test: 添加采购交易API测试脚本" ``` --- ## Task 19: 运行测试并生成报告 **Step 1: 运行测试脚本** ```powershell cd test ./test_purchase_transaction_api.ps1 > test_report_$(Get-Date -Format 'yyyyMMdd_HHmmss').txt ``` **Step 2: 验证所有接口正常** Expected: 所有测试用例通过 **Step 3: 保存测试报告** 将测试报告保存到 `doc/test-data/purchase_transaction/` 目录。 **Step 4: Commit** ```bash git add doc/test-data/purchase_transaction/ git commit -m "test: 添加采购交易测试报告" ``` --- ## Task 20: 生成API文档 **Files:** - Create: `doc/api/ccdi_purchase_transaction_api.md` **Step 1: 导出Swagger API文档** 访问 http://localhost:8080/swagger-ui/index.html,导出采购交易管理的API文档。 **Step 2: 整理为Markdown格式** 整理所有接口的请求参数、响应格式、示例。 **Step 3: Commit** ```bash git add doc/api/ccdi_purchase_transaction_api.md git commit -m "docs: 添加采购交易API文档" ``` --- ## Task 21: 最终验证和清理 **Step 1: 完整功能测试** 1. 启动后端服务 2. 启动前端服务 3. 登录系统 4. 导航到采购交易管理菜单 5. 测试所有功能: - 列表查询 - 新增记录 - 编辑记录 - 删除记录 - 批量删除 - 导入功能(含异步状态轮询) - 导出功能 **Step 2: 代码审查** 检查: - 所有DTO验证注解完整 - 所有Swagger注解完整 - 异常处理完善 - 日志记录完整 - 审计字段正确填充 **Step 3: 性能测试** 测试批量导入1000条数据的性能。 **Step 4: 最终Commit** ```bash git add . git commit -m "feat: 完成采购交易信息管理功能开发" ``` --- ## 实施注意事项 1. **必填字段**: purchaseId, purchaseCategory, subjectName, purchaseQty, budgetAmount, purchaseMethod, applyDate, applicantId, applicantName, applyDepartment 2. **异步导入**: 使用@Async + @Transactional + Redis 3. **批量操作**: 每批500条记录 4. **更新策略**: 先批量删除,再批量插入 5. **数据验证**: Jakarta Validation + 自定义业务验证 6. **审计字段**: 使用@TableField(fill = FieldFill.INSERT/INSERT_UPDATE) 7. **错误处理**: 只返回失败记录,不返回成功记录 8. **导入轮询**: 每2秒轮询一次状态 ## 参考文件 - 员工招聘信息模块: `ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/**/CcdiStaffRecruitment*` - 员工异步导入: `ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/impl/CcdiEmployeeImportServiceImpl.java` - 前端页面: `ruoyi-ui/src/views/ccdiStaffRecruitment/index.vue` - 测试脚本: `test/test_employee_api.ps1`