CLAUDE.md 12 KB

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
  • 自动清理过期内容

开发命令

后端开发

# 进入后端目录
cd backend

# 编译打包
mvn clean package -DskipTests

# 运行应用
java -jar target/snapshot-backend-1.0.0.jar

# 或使用部署脚本(Windows)
deploy.bat

数据库初始化:

# 首次运行前,在MySQL中执行
mysql -uroot -p < backend/src/main/resources/sql/create.sql

前端开发

# 进入前端目录
cd frontend

# 安装依赖(首次)
npm install

# 开发模式运行
npm run serve

# 生产构建
npm run build

# 代码检查
npm run lint

# 或使用部署脚本(Windows)
deploy.bat

测试与验证

# 访问 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)

关键配置项:

# 服务端口
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=<YOUR_MYSQL_PASSWORD>

# 文件存储路径
app.file.upload-dir=./uploads

# ID生成器
app.id.length=8
app.id.charset=0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ

# 过期清理任务(cron表达式)
app.cleanup.cron=0 0 */2 * * ?

前端配置 (config.js)

{
  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级别