# CLAUDE.md 本文件为 Claude Code (claude.ai/code) 在此代码库中工作时提供指导。 ## 项目概述 **Snapshot** 是一个临时文件分享平台,提供文件和文本内容的安全临时分享服务。 - **前端**: Vue 3.3 + Vue Router 4 + Pinia + Axios - **后端**: Spring Boot 2.7.18 + Java 17(注意:原始需求是Java 1.8,但实际使用Java 17) - **数据库**: MySQL 8.0+ (数据库名: snapshot) - **部署平台**: Windows(不使用Docker) ### 核心特性 - 支持多文件上传(单个≤50MB,最多10个) - 文本内容分享(纯文本/Markdown/代码/JSON) - 自定义过期时间(1-24小时)和下载次数限制 - 密码保护功能 - **ID前缀智能匹配**(字典树算法) - 银河星空动态背景UI - 自动清理过期内容 --- ## 开发命令 ### 后端开发 ```bash # 进入后端目录 cd backend # 编译打包 mvn clean package -DskipTests # 运行应用 java -jar target/snapshot-backend-1.0.0.jar # 或使用部署脚本(Windows) deploy.bat ``` **数据库初始化**: ```bash # 首次运行前,在MySQL中执行 mysql -uroot -p < backend/src/main/resources/sql/create.sql ``` ### 前端开发 ```bash # 进入前端目录 cd frontend # 安装依赖(首次) npm install # 开发模式运行 npm run serve # 生产构建 npm run build # 代码检查 npm run lint # 或使用部署脚本(Windows) deploy.bat ``` ### 测试与验证 ```bash # 访问 http://localhost:7626 查看页面 ``` --- ## 项目架构 ### 整体结构 ``` snapshot/ ├── backend/ # Spring Boot后端 │ ├── src/main/java/com/snapshot/ │ │ ├── entity/ # JPA实体类 │ │ ├── repository/ # 数据访问层 │ │ ├── service/ # 业务逻辑层 │ │ ├── controller/ # REST API控制器 │ │ ├── dto/ # 数据传输对象 │ │ ├── config/ # 配置类(CORS、定时任务) │ │ ├── util/ # 工具类(ID生成、密码哈希) │ │ └── exception/ # 全局异常处理 │ ├── src/main/resources/ │ │ ├── sql/create.sql # 数据库初始化脚本 │ │ └── application.properties │ └── pom.xml │ ├── frontend/ # Vue 3前端 │ ├── src/ │ │ ├── api/ # API接口封装(Axios) │ │ ├── stores/ # Pinia状态管理 │ │ ├── router/ # 路由配置 │ │ ├── views/ # 页面组件(Home.vue, Share.vue) │ │ ├── components/ # 可复用组件 │ │ ├── styles/ # 全局样式 │ │ ├── config.js # 前端配置(API地址、限制) │ │ └── main.js │ └── package.json │ └── api/ └── API_DOCUMENT.md # RESTful API接口文档 ``` ### 后端分层架构 1. **Controller层**: 处理HTTP请求,调用Service层 - `UploadController`: 文件/文本上传、删除 - `ShareController`: 内容访问、下载、密码验证 2. **Service层**: 核心业务逻辑 - `UploadRecordService`: 上传记录管理、字典树构建、过期清理 - `FileStorageService`: 文件存储管理(文件读写、删除) 3. **Repository层**: JPA数据访问 - `UploadRecordRepository`: 上传记录CRUD - `FileEntryRepository`: 文件元数据管理 - `TextContentRepository`: 文本内容管理 - `TrieNodeRepository`: 字典树节点管理(前缀查询) 4. **Entity层**: 数据库实体映射 - `UploadRecord`: 上传记录(ID、过期时间、下载次数、密码哈希) - `FileEntry`: 文件元数据(文件名、大小、MIME类型、存储路径) - `TextContent`: 文本内容 - `TrieNode`: 字典树节点(nodeKey、parentId、depth、uploadId) 5. **工具类**: - `IdGenerator`: 随机ID生成(可配置长度和字符集,默认8位) - `PasswordUtil`: 密码SHA-256哈希 ### 前端架构 1. **页面路由** (Vue Router): - `/`: 首页 - 文件上传和文本分享 - `/s/:id`: 分享页面 - 查看和下载内容 - `/*`: 404页面 2. **状态管理** (Pinia): - `uploadStore`: 管理上传状态(文件列表、进度、配置) 3. **API通信**: - 统一使用Axios,baseURL配置在 `config.js` - 响应拦截器处理错误 4. **UI特点**: - 银河星空动态背景(CSS动画) - 左右分栏:左侧文件上传,右侧文本输入 - 底部ID查询(支持前缀自动跳转) --- ## 核心业务逻辑 ### ID前缀智能匹配(字典树算法) **问题**: 用户输入ID前几位时,如何快速定位到完整内容? **解决方案**: 使用字典树(Trie)数据结构 **实现原理**: 1. 每创建一个上传记录(如ID为 "a1b2c3d4"),在后端构建字典树 2. 将ID的每个字符作为树节点:`a → 1 → b → 2 → c → 3 → d → 4` 3. 用户输入前缀 "a1b" 时,查询字典树找到以该路径开头的所有节点 4. 如果只有一个匹配,自动返回完整ID;如果有多个,提示用户提供更多字符 **关键代码**: - `UploadRecordService.buildTrie()`: 构建字典树(创建上传记录时自动调用) - `UploadRecordService.resolveIdByPrefix()`: 前缀解析 - `TrieNodeRepository.findByPrefix()`: 数据库查询前缀匹配节点 **表结构** (trie_nodes): ``` node_id (主键) | node_key | parent_id | depth | upload_id ``` ### 上传流程 1. **初始化上传**: `POST /api/upload/init` - 生成唯一8位ID - 计算过期时间 - 保存密码哈希(如果有) - 构建字典树 2. **上传文件**: `POST /api/upload/{uploadId}/files` - 分片上传支持(chunkIndex、totalChunks) - 验证文件大小(≤50MB)和数量(≤10个) - 保存到 `./uploads` 目录 3. **更新文本**: `PUT /api/upload/{uploadId}/text` - 保存文本内容和类型 4. **完成上传**: `POST /api/upload/{uploadId}/complete` - 返回分享链接 `http://localhost:7626/s/{id}` ### 下载与访问控制 1. **内容访问**: `GET /api/content/{id}` - 检查过期时间 - 检查下载次数限制 - 如有密码保护,返回403要求验证 2. **密码验证**: `POST /api/content/{id}/verify-password` - 使用SHA-256哈希比对 3. **下载文件**: `GET /api/download/file/{fileId}` - 流式传输文件 - 增加下载计数 4. **打包下载**: `GET /api/download/bundle/{uploadId}` - 动态生成ZIP文件(不存储在服务器) - 使用Java ZipOutputStream ### 定时清理任务 **配置**: `app.cleanup.cron=0 0 */2 * * ?`(每2小时执行一次) **逻辑**: `UploadRecordService.cleanupExpiredRecords()` - 删除过期记录(`expirationTime < now`) - 级联删除关联文件、文本内容、字典树节点 - 删除物理文件(`FileStorageService`) --- ## 配置文件 ### 后端配置 (`application.properties`) **关键配置项**: ```properties # 服务端口 server.port=7626 # 文件上传限制 spring.servlet.multipart.max-file-size=50MB spring.servlet.multipart.max-request-size=500MB # 数据库连接 spring.datasource.url=jdbc:mysql://localhost:3306/snapshot spring.datasource.username=root spring.datasource.password= # 文件存储路径 app.file.upload-dir=./uploads # ID生成器 app.id.length=8 app.id.charset=0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ # 过期清理任务(cron表达式) app.cleanup.cron=0 0 */2 * * ? ``` ### 前端配置 (`config.js`) ```javascript { baseURL: 'http://localhost:7626', uploadLimit: 50 * 1024 * 1024, // 50MB maxFiles: 10, expirationOptions: [1, 2, 3, 6, 12, 24] } ``` --- ## 数据库设计 ### 核心表 1. **upload_records**: 上传记录主表 - `id` (主键): 8位随机字符串 - `expiration_time`: 过期时间 - `max_download_count`: 最大下载次数(-1表示无限制) - `current_download_count`: 当前下载次数 - `password_hash`: 密码SHA-256哈希(可选) 2. **file_entries**: 文件元数据 - `file_id`: 文件唯一ID - `upload_id`: 关联上传记录 - `file_name`, `file_size`, `mime_type` - `storage_path`: 服务器文件路径 - `upload_status`: 上传状态(uploading/completed/failed) - `upload_progress`: 上传进度(0-100) 3. **text_contents**: 文本内容 - `upload_id`: 关联上传记录 - `text_content`, `text_type` 4. **trie_nodes**: 字典树节点(用于前缀查询) - `node_key`: 字符 - `parent_id`: 父节点ID - `depth`: 深度(从1开始) - `upload_id`: 完整ID(仅叶子节点存储) **初始化脚本**: `backend/src/main/resources/sql/create.sql` --- ## 安全措施 1. **密码保护**: SHA-256哈希存储(不存储明文) 2. **文件验证**: 文件大小限制、MIME类型检查 3. **SQL注入防护**: 使用JPA参数化查询 4. **XSS防护**: Vue自动转义输出 5. **CORS配置**: 仅允许指定域名跨域访问 6. **文件存储**: 上传文件存储在Web根目录外(`./uploads`) 7. **定期清理**: 自动删除过期内容和文件 --- ## 重要提示 ### Java版本说明 - **原始需求**: Java 1.8 - **实际实现**: Java 17(pom.xml中配置为Java 17) - **注意**: 如果需要使用Java 1.8,需修改pom.xml中的java.version为1.8,并调整代码语法(如不使用var关键字、Text Blocks等) ### 文件存储 - 上传文件默认存储在 `./uploads` 目录(项目根目录下) - 部署时确保该目录有读写权限 ### 字典树性能 - 当前实现为数据库持久化字典树(trie_nodes表) - 每次前缀查询需要多次数据库查询 - 如需高性能,可考虑内存缓存(Redis或本地缓存) ### ID生成策略 - 默认8位长度,字符集包含62个字符(0-9, a-z, A-Z) - 理论上可生成 62^8 ≈ 218万亿个不重复ID - 通过do-while循环确保唯一性(数据库检查) --- ## API接口文档 详细的RESTful API接口文档请参考: `api/API_DOCUMENT.md` **主要接口**: - 上传管理: `POST /api/upload/init`, `POST /api/upload/{id}/files`, `PUT /api/upload/{id}/text` - 内容访问: `GET /api/content/{id}`, `POST /api/content/{id}/verify-password` - 文件下载: `GET /api/download/file/{fileId}`, `GET /api/download/bundle/{id}` - 查询服务: `GET /api/query/lookup?prefix=xxx` --- ## 常见开发任务 ### 添加新的API接口 1. 在 `backend/src/main/java/com/snapshot/controller/` 创建或修改Controller 2. 在 `service/` 实现业务逻辑 3. 在 `repository/` 添加数据访问方法(如需要) 4. 在 `frontend/src/api/` 添加API调用封装 ### 修改数据库表结构 1. 更新 `backend/src/main/resources/sql/create.sql` 2. 修改对应的 `entity/` 实体类 3. 考虑数据迁移方案(已有数据情况) ### 前端添加新页面 1. 在 `frontend/src/views/` 创建Vue组件 2. 在 `router/index.js` 添加路由配置 3. 在 `api/` 添加API调用方法(如需要) ### 调整文件大小限制 - 后端: 修改 `application.properties` 中的 `spring.servlet.multipart.max-file-size` - 前端: 修改 `config.js` 中的 `uploadLimit` - 确保前后端配置一致 --- ## 项目规范 - **后端**: 遵循Spring Boot最佳实践,使用Lombok减少样板代码 - **前端**: 遵循Vue 3 Composition API风格 - **命名**: 实体类使用名词复数(如UploadRecords),方法使用动词开头(如createUploadRecord) - **异常处理**: 全局异常处理器 `GlobalExceptionHandler` 统一处理异常并返回标准格式 - **日志**: 使用SLF4J日志,关键操作记录info级别,异常记录error级别