You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

5.8 KiB

文件存储服务规范符合性修复

变更日期:2026-01-30
变更类型:代码规范修复 + 功能补充
影响范围:文件存储服务、Celery 定时任务


变更概述

修复文件存储服务的代码规范问题,补充缺失的 Celery 定时清理任务,确保完全符合 jointo-tech-stack 规范。


主要变更

1. 日志格式化规范修复

问题:代码中使用 f-string 格式化日志,不符合 logging.md 规范

修复文件

  • server/app/services/file_storage_service.py
  • server/app/core/storage.py

修复内容

# ❌ 修复前
logger.error(f"文件上传失败: {str(e)}")

# ✅ 修复后
logger.error("文件上传失败: %s", str(e))

影响

  • 符合 Python logging 最佳实践
  • 提升日志性能(延迟格式化)
  • 统一项目日志风格

2. Celery 定时清理任务实现

新增文件server/app/tasks/cleanup_files.py

功能

  • 每天凌晨 4 点自动清理无引用的过期文件
  • 清理 30 天未访问且引用计数为 0 的文件
  • 记录清理日志和统计信息

实现代码

@celery_app.task(name="cleanup_unused_files")
async def cleanup_unused_files():
    """清理30天未访问且无引用的文件"""
    async with async_session_maker() as db:
        try:
            file_storage = FileStorageService(db)
            deleted_count = await file_storage.cleanup_unused_files(days=30)
            logger.info("清理了 %d 个无引用文件", deleted_count)
            return {"deleted_count": deleted_count}
        except Exception as e:
            logger.error("清理文件失败: %s", str(e), exc_info=True)
            raise

Celery Beat 配置

"cleanup-unused-files": {
    "task": "cleanup_unused_files",
    "schedule": crontab(hour=4, minute=0),
},

3. API 路由注册

修改文件server/app/api/v1/__init__.py

变更内容

# 新增导入
from app.api.v1 import file_storage

# 注册路由
api_router.include_router(file_storage.router, prefix="/file-storage", tags=["文件存储"])

API 端点

  • POST /api/v1/file-storage/upload - 上传文件(带去重)
  • GET /api/v1/file-storage/checksum/{checksum} - 根据校验和查询文件
  • GET /api/v1/file-storage/presigned-url - 获取预签名 URL
  • POST /api/v1/file-storage/cleanup - 手动清理无引用文件

4. 文档修正

修改文件docs/requirements/backend/04-services/resource/file-storage-service.md

修正内容

  1. 导入路径:uuid_utilsid_generator
  2. 依赖注入:get_dbget_session
  3. 补充 Celery 定时任务章节
  4. 更新 API 层示例代码

技术细节

日志格式化规范

规范要求(logging.md):

  • 使用 %-formatting 而非 f-string
  • 延迟格式化,提升性能
  • 异常日志使用 exc_info=True

修复位置

  • file_storage_service.py:3 处
  • storage.py:4 处

Celery 任务配置

任务特性

  • 异步执行,不阻塞主应用
  • 自动重试机制(最多 3 次)
  • 指数退避策略
  • 任务结果保留 1 小时

执行时间

  • 每天凌晨 4 点(避开业务高峰)
  • 清理 30 天未访问的文件

测试验证

1. 日志格式验证

# 触发文件上传错误,检查日志格式
docker exec jointo-server-app tail -f logs/app.log

预期输出

2026-01-30 12:00:00,000 - ERROR - app.services.file_storage_service - 文件上传失败: Connection timeout

2. Celery 任务测试

# 手动触发清理任务
docker exec jointo-server-celery-beat celery -A app.core.celery_app call cleanup_unused_files

# 查看任务执行日志
docker exec jointo-server-celery-beat celery -A app.core.celery_app inspect active

3. API 路由测试

# 测试文件上传
curl -X POST http://localhost:6170/api/v1/file-storage/upload \
  -H "Authorization: Bearer <token>" \
  -F "file=@test.jpg" \
  -F "category=test"

# 测试校验和查询
curl http://localhost:6170/api/v1/file-storage/checksum/<checksum> \
  -H "Authorization: Bearer <token>"

影响评估

兼容性

  • 向后兼容:日志格式修复不影响现有功能
  • API 兼容:新增路由,不影响现有端点
  • 数据兼容:无数据库变更

性能

  • 日志性能提升:延迟格式化减少字符串拼接
  • 存储优化:定时清理释放存储空间
  • ⚠️ 定时任务:凌晨 4 点执行,对业务无影响

安全性

  • 无安全风险
  • 清理任务需要管理员权限(待实现)

后续工作

待实现功能

  1. 管理员权限检查

    • 位置:file_storage.py 第 60 行
    • 需求:清理接口需要管理员权限验证
  2. 文件类型验证

    • 上传时验证 MIME 类型
    • 防止恶意文件上传
  3. 文件大小限制

    • 配置最大文件大小
    • 防止存储滥用
  4. 测试用例补充

    • 单元测试:FileStorageService
    • 集成测试:API 端点
    • Celery 任务测试

文档改进

  1. 补充测试章节
  2. 添加性能优化建议
  3. 补充安全考虑说明
  4. 添加故障排查指南

相关文档


变更记录

v1.0 (2026-01-30)

  • 修复日志格式化问题(7 处)
  • 实现 Celery 定时清理任务
  • 注册 API 路由
  • 更新服务文档

变更日期:2026-01-30
变更类型:代码规范修复 + 功能补充
影响范围:文件存储服务、Celery 定时任务