# 项目异步文件上传功能 - 子计划1:数据库和基础组件 > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. **Goal:** 创建文件上传功能的数据库表、实体类、Mapper接口和基础配置 **Architecture:** 使用 MyBatis Plus 进行数据持久化,配置容量100的异步线程池 **Tech Stack:** MySQL 8.0, MyBatis Plus 3.5.10, Spring Boot 3.5.8 --- ## Task 1: 数据库表创建 **Files:** - Create: `sql/ccdi_file_upload_record.sql` **Step 1: 创建SQL脚本文件** 创建文件 `sql/ccdi_file_upload_record.sql`: ```sql -- 项目文件上传记录表 -- 用途:记录项目下所有文件的上传记录和处理状态 -- 作者:系统 -- 日期:2026-03-05 USE ccdi; -- 创建文件上传记录表 CREATE TABLE `ccdi_file_upload_record` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', `project_id` bigint(20) NOT NULL COMMENT '项目ID', `lsfx_project_id` int(11) DEFAULT NULL COMMENT '流水分析平台项目ID', `log_id` int(11) DEFAULT NULL COMMENT '流水分析平台返回的logId', `file_name` varchar(255) NOT NULL COMMENT '文件名称', `file_size` bigint(20) DEFAULT NULL COMMENT '文件大小(字节)', `file_status` varchar(20) NOT NULL COMMENT '文件状态:uploading-上传中,parsing-解析中,parsed_success-解析成功,parsed_failed-解析失败', `enterprise_names` text COMMENT '主体名称(多个用逗号分隔)', `account_nos` text COMMENT '主体账号(多个用逗号分隔)', `error_message` text COMMENT '错误信息(解析失败时记录)', `upload_time` datetime NOT NULL COMMENT '上传时间', `upload_user` varchar(64) NOT NULL COMMENT '上传人', PRIMARY KEY (`id`), KEY `idx_project_id` (`project_id`), KEY `idx_log_id` (`log_id`), KEY `idx_file_status` (`file_status`), KEY `idx_upload_time` (`upload_time`), KEY `idx_project_status` (`project_id`, `file_status`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='项目文件上传记录表'; ``` **Step 2: 执行SQL脚本** ```bash mysql -h 116.62.17.81 -u root -pKfcx@1234 ccdi < sql/ccdi_file_upload_record.sql ``` **Step 3: 验证表创建成功** ```bash mysql -h 116.62.17.81 -u root -pKfcx@1234 ccdi -e "SHOW CREATE TABLE ccdi_file_upload_record\G" ``` Expected: 输出表结构,包含所有字段和索引 **Step 4: 提交SQL脚本** ```bash git add sql/ccdi_file_upload_record.sql git commit -m "feat: 添加文件上传记录表SQL脚本" ``` --- ## Task 2: 实体类创建 **Files:** - Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/entity/CcdiFileUploadRecord.java` **Step 1: 创建实体类** 创建文件 `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/entity/CcdiFileUploadRecord.java`: ```java package com.ruoyi.ccdi.project.domain.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.io.Serial; import java.io.Serializable; import java.util.Date; /** * 文件上传记录实体 * * @author ruoyi * @date 2026-03-05 */ @Data @TableName("ccdi_file_upload_record") public class CcdiFileUploadRecord implements Serializable { @Serial private static final long serialVersionUID = 1L; /** 主键ID */ @TableId(type = IdType.AUTO) private Long id; /** 项目ID */ private Long projectId; /** 流水分析平台项目ID */ private Integer lsfxProjectId; /** 流水分析平台返回的logId */ private Integer logId; /** 文件名称 */ private String fileName; /** 文件大小(字节) */ private Long fileSize; /** 文件状态:uploading-上传中,parsing-解析中,parsed_success-解析成功,parsed_failed-解析失败 */ private String fileStatus; /** 主体名称(多个用逗号分隔) */ private String enterpriseNames; /** 主体账号(多个用逗号分隔) */ private String accountNos; /** 错误信息(解析失败时记录) */ private String errorMessage; /** 上传时间 */ private Date uploadTime; /** 上传人 */ private String uploadUser; } ``` **Step 2: 编译验证** ```bash cd ccdi-project mvn clean compile ``` Expected: BUILD SUCCESS **Step 3: 提交** ```bash git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/entity/CcdiFileUploadRecord.java git commit -m "feat: 添加文件上传记录实体类" ``` --- ## Task 3: Mapper 接口和 XML **Files:** - Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/mapper/CcdiFileUploadRecordMapper.java` - Create: `ccdi-project/src/main/resources/mapper/ccdi/project/CcdiFileUploadRecordMapper.xml` **Step 1: 创建 Mapper 接口** 创建文件 `ccdi-project/src/main/java/com/ruoyi/ccdi/project/mapper/CcdiFileUploadRecordMapper.java`: ```java package com.ruoyi.ccdi.project.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.ccdi.project.domain.entity.CcdiFileUploadRecord; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import java.util.List; /** * 文件上传记录 Mapper 接口 * * @author ruoyi * @date 2026-03-05 */ @Mapper public interface CcdiFileUploadRecordMapper extends BaseMapper { /** * 批量插入文件上传记录 * * @param records 记录列表 * @return 插入条数 */ int insertBatch(@Param("list") List records); /** * 统计各状态文件数量 * * @param projectId 项目ID * @return 统计结果(Map形式,key为状态,value为数量) */ List> countByStatus(@Param("projectId") Long projectId); } ``` **Step 2: 创建 Mapper XML** 创建文件 `ccdi-project/src/main/resources/mapper/ccdi/project/CcdiFileUploadRecordMapper.xml`: ```xml select id, project_id, lsfx_project_id, log_id, file_name, file_size, file_status, enterprise_names, account_nos, error_message, upload_time, upload_user from ccdi_file_upload_record insert into ccdi_file_upload_record ( project_id, lsfx_project_id, file_name, file_size, file_status, upload_time, upload_user ) values ( #{item.projectId}, #{item.lsfxProjectId}, #{item.fileName}, #{item.fileSize}, #{item.fileStatus}, #{item.uploadTime}, #{item.uploadUser} ) ``` **Step 3: 编译验证** ```bash cd ccdi-project mvn clean compile ``` Expected: BUILD SUCCESS **Step 4: 提交** ```bash git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/mapper/CcdiFileUploadRecordMapper.java git add ccdi-project/src/main/resources/mapper/ccdi/project/CcdiFileUploadRecordMapper.xml git commit -m "feat: 添加文件上传记录Mapper接口和XML映射" ``` --- ## Task 4: DTO 和 VO 类 **Files:** - Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/dto/CcdiFileUploadQueryDTO.java` - Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiFileUploadStatisticsVO.java` **Step 1: 创建查询 DTO** 创建文件 `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/dto/CcdiFileUploadQueryDTO.java`: ```java package com.ruoyi.ccdi.project.domain.dto; import lombok.Data; import java.io.Serial; import java.io.Serializable; /** * 文件上传记录查询 DTO * * @author ruoyi * @date 2026-03-05 */ @Data public class CcdiFileUploadQueryDTO implements Serializable { @Serial private static final long serialVersionUID = 1L; /** 项目ID */ private Long projectId; /** 文件状态 */ private String fileStatus; /** 文件名称(模糊查询) */ private String fileName; /** 上传人 */ private String uploadUser; } ``` **Step 2: 创建统计 VO** 创建文件 `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiFileUploadStatisticsVO.java`: ```java package com.ruoyi.ccdi.project.domain.vo; import lombok.Data; import java.io.Serial; import java.io.Serializable; /** * 文件上传统计 VO * * @author ruoyi * @date 2026-03-05 */ @Data public class CcdiFileUploadStatisticsVO implements Serializable { @Serial private static final long serialVersionUID = 1L; /** 上传中数量 */ private Long uploading; /** 解析中数量 */ private Long parsing; /** 解析成功数量 */ private Long parsedSuccess; /** 解析失败数量 */ private Long parsedFailed; /** 总数量 */ private Long total; } ``` **Step 3: 编译验证** ```bash cd ccdi-project mvn clean compile ``` Expected: BUILD SUCCESS **Step 4: 提交** ```bash git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/dto/CcdiFileUploadQueryDTO.java git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiFileUploadStatisticsVO.java git commit -m "feat: 添加文件上传查询DTO和统计VO" ``` --- ## Task 5: 线程池配置 **Files:** - Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/config/AsyncThreadPoolConfig.java` **Step 1: 创建线程池配置类** 创建文件 `ccdi-project/src/main/java/com/ruoyi/ccdi/project/config/AsyncThreadPoolConfig.java`: ```java package com.ruoyi.ccdi.project.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.concurrent.Executor; import java.util.concurrent.ThreadPoolExecutor; /** * 异步线程池配置 * * @author ruoyi * @date 2026-03-05 */ @Configuration @EnableAsync public class AsyncThreadPoolConfig { /** * 文件上传专用线程池 * 容量:100个线程 * 拒绝策略:AbortPolicy(直接拒绝,由调度线程捕获并重试) */ @Bean("fileUploadExecutor") public Executor fileUploadExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); // 核心线程数 executor.setCorePoolSize(100); // 最大线程数 executor.setMaxPoolSize(100); // 队列容量(设为0,不使用队列,直接走拒绝策略) executor.setQueueCapacity(0); // 线程名称前缀 executor.setThreadNamePrefix("file-upload-"); // 拒绝策略:AbortPolicy,抛出 RejectedExecutionException executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy()); // 线程空闲时间(秒) executor.setKeepAliveSeconds(60); // 等待所有任务完成后再关闭 executor.setWaitForTasksToCompleteOnShutdown(true); // 最长等待时间 executor.setAwaitTerminationSeconds(60); executor.initialize(); return executor; } } ``` **Step 2: 编译验证** ```bash cd ccdi-project mvn clean compile ``` Expected: BUILD SUCCESS **Step 3: 提交** ```bash git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/config/AsyncThreadPoolConfig.java git commit -m "feat: 添加异步线程池配置" ``` --- ## 子计划1完成检查清单 - [ ] 数据库表创建成功 - [ ] 实体类编译通过 - [ ] Mapper接口和XML映射正确 - [ ] DTO和VO类创建完成 - [ ] 线程池配置完成 - [ ] 所有代码已提交到git **下一步:** 执行子计划2 - Service层核心实现