Skip to content

文件存储

概述

文件管理系统支持多存储后端、分块上传、MD5 秒传、临时令牌访问控制、AI OCR 识别等能力。

存储后端

通过 FILE_STORAGE_TYPE 配置切换存储后端:

类型说明配置项
local本地文件系统FILE_STORAGE_LOCAL_PATH
oss阿里云 OSSOSS_ENDPOINT, OSS_ACCESS_KEY_ID, OSS_ACCESS_KEY_SECRET, OSS_BUCKET_NAME
minioMinIO 对象存储MINIO_ENDPOINT, MINIO_ACCESS_KEY, MINIO_SECRET_KEY, MINIO_BUCKET_NAME
azureAzure Blob StorageAZURE_ACCOUNT_NAME, AZURE_ACCOUNT_KEY, AZURE_CONTAINER_NAME

存储后端抽象

所有存储后端实现统一的 StorageBackend 接口:

python
class StorageBackend:
    def save(self, file_content, filename): ...      # 保存文件
    def delete(self, storage_path): ...               # 删除文件
    def exists(self, storage_path): ...               # 检查是否存在
    def get_url(self, storage_path): ...              # 获取访问 URL
    def get_size(self, storage_path): ...             # 获取文件大小
    def calculate_md5(self, file_content): ...        # 计算 MD5
    def generate_filename(self, original_name): ...   # 生成唯一文件名

通过工厂函数 get_storage_backend(config) 创建实例。

数据模型

FileManager

字段类型说明
nameString文件名
typeStringfile / folder
parent_idString父文件夹 ID(逻辑外键)
pathString完整路径
sizeBigInteger文件大小(字节)
file_extString文件扩展名
mime_typeStringMIME 类型
storage_typeString存储类型
storage_pathString存储路径
md5String文件 MD5
is_publicBoolean是否公开
is_systemBoolean是否系统文件夹
sourceString来源模块(chat/form/avatar 等)

FileAccessToken

字段类型说明
tokenString访问令牌(唯一)
file_idString文件 ID
expires_atDateTime过期时间
user_idString用户 ID

核心功能

文件上传

POST /api/core/file_manager/upload
Content-Type: multipart/form-data

file: <binary>
parent_id: <optional>
is_public: false
source: form

上传流程:

  1. 计算文件 MD5
  2. 检查是否存在相同 MD5(秒传)
  3. 存储到后端
  4. 创建数据库记录

文件自动归类

上传时传入 source 参数,系统自动创建 模块文件夹/年-月 两级系统文件夹:

source文件夹名称
chat聊天文件
form表单附件
avatar头像
workflow工作流附件
announcement公告附件
ai_platformAI平台文件

系统文件夹(is_system=true)受保护,不允许重命名和删除。

分块上传

适用于大文件,流程:

1. POST /chunk/init    → 初始化(秒传检查)→ 返回 uploadId
2. POST /chunk/upload  → 逐块上传到临时目录
3. GET  /chunk/status  → 查询上传进度
4. POST /chunk/merge   → 合并分块 → 存储 → 数据库记录

秒传:初始化时检查 fileHash(MD5),如已存在则直接返回 fileExists=true + fileId

文件访问控制

访问方式适用场景安全性
公开访问 (is_public=true)头像、公告图片无需认证
流式访问 (/stream/{id})预览、下载需要 JWT 或临时令牌
代理访问 (/proxy/{id})内容分发需要 JWT 或临时令牌
临时令牌 (FileAccessToken)限时分享令牌 + 过期时间

临时令牌服务

python
# 创建临时访问令牌(默认 1 小时)
token = await FileAccessTokenService.create_token(
    db, file_id=file_id, expires_in=3600, user_id=user_id
)

# 验证令牌
file_token = await FileAccessTokenService.verify_token(db, token)

# 撤销令牌
await FileAccessTokenService.revoke_token(db, token)

文本提取

从文件中提取文本内容,支持多种格式:

格式说明
txt/md/代码文件直接读取
csv读取文本
pdfPyPDF2 提取
docxpython-docx 提取
xlsxopenpyxl 提取
pptxpython-pptx 提取

AI OCR 识别

POST /api/core/file_manager/ocr/recognize

{
  "fileId": "xxx",
  "outputSchema": [...],   // 结构化输出字段定义
  "prompt": "提取发票信息"  // 可选提示词
}

处理流程:

  • 图片文件:调用 qwen-vl-ocr 模型进行 OCR 识别
  • 文本文件:直接提取文本
  • 结构化输出:使用 Function Calling 提取指定字段

API 列表

方法路径说明
POST/upload上传文件
POST/folder创建文件夹
GET/文件列表(分页)
GET/tree文件夹树
GET/stream/{id}流式获取文件
GET/url/{id}获取文件 URL
PUT/{id}/rename重命名
PUT/move移动文件
DELETE/{id}删除文件
POST/chunk/init初始化分块上传
POST/chunk/upload上传分块
POST/chunk/merge合并分块
POST/access-token创建临时令牌
POST/ocr/recognizeAI OCR 识别

Released under the MIT License.