Files
diary-family/docs/superpowers/specs/2026-05-25-temp-file-upload-design.md

3.5 KiB
Raw Blame History

临时文件上传功能设计

日期: 2026-05-25 状态: 已批准

概述

在现有 /public/ 公开内容页面中增加临时文件上传功能,允许任何人上传文件并自动在指定时间后删除。

功能需求

  1. 上传临时文件作为 PublicContent 类型发布
  2. 上传者选择过期时间1小时 / 1天 / 7天
  3. 上传文件最大500MB
  4. 过期文件自动从存储中删除
  5. 上传表单对人类用户视觉隐藏1px宽度但agent可访问
  6. 提供REST API方式上传文件

技术方案

1. 模型改动

文件: core/models.py

PublicContent 模型中增加字段:

is_temp_file = models.BooleanField(default=False, verbose_name='临时文件')
expire_type = models.CharField(
    max_length=10,
    choices=[
        ('expire_1h', '1小时'),
        ('expire_1d', '1天'),
        ('expire_7d', '7天'),
    ],
    blank=True, null=True,
    verbose_name='过期类型'
)
expire_at = models.DateTimeField(blank=True, null=True, verbose_name='过期时间')

2. 表单改动

文件: core/forms.py

扩展 PublicContentForm,增加过期类型选择字段。

3. 上传表单HTML

文件: core/templates/core/public_content.html

在页面底部添加上传表单,设置 style="width: 1px" 使人类用户难以阅读但agent可解析。

<form method="post" enctype="multipart/form-data" style="width: 1px; position: absolute; left: -9999px;" action="{% url 'temp_upload' %}">
    {% csrf_token %}
    {{ temp_upload_form }}
    <button type="submit">上传</button>
</form>

4. API端点

文件: core/urls.pycore/views.py

新增 API 端点 POST /api/v1/temp-upload/:

  • 路径: api/v1/temp-upload/
  • 方法: POST
  • 参数:
    • file: 文件 (必填, 最大500MB)
    • title: 文件标题 (必填)
    • expire_type: 过期类型 expire_1h | expire_1d | expire_7d (必填)
  • 返回: JSON { "success": true, "file_url": "...", "expire_at": "..." }

5. 定时清理任务

文件: core/tasks.py

新增 Celery 任务 cleanup_expired_temp_files:

@shared_task
def cleanup_expired_temp_files():
    expired_files = PublicContent.objects.filter(
        is_temp_file=True,
        expire_at__lte=timezone.now()
    )
    for file in expired_files:
        # 删除物理文件
        if file.file:
            file.file.delete()
        file.delete()

配置 Celery Beat 每小时执行。

6. API文档写在公开内容页面

## 临时文件上传 API

### 上传文件
POST /api/v1/temp-upload/

**参数**:
- `file`: 文件 (multipart/form-data, 最大500MB)
- `title`: 文件标题 (string)
- `expire_type`: 过期时间 (`expire_1h` | `expire_1d` | `expire_7d`)

**响应**:
```json
{
  "success": true,
  "file_url": "/media/temp_files/xxx.pdf",
  "expire_at": "2026-05-25T18:30:00Z",
  "file_name": "document.pdf",
  "file_size": 1048576
}

示例:

curl -X POST -F "file=@document.pdf" -F "title=测试文件" -F "expire_type=expire_1d" http://localhost:8000/api/v1/temp-upload/

数据库迁移

python manage.py makemigrations core --name add_temp_file_fields
python manage.py migrate

Celery Beat 配置

diary_family/celery.py 中添加周期任务:

CELERY_BEAT_SCHEDULE = {
    'cleanup-expired-temp-files': {
        'task': 'core.tasks.cleanup_expired_temp_files',
        'schedule': crontab(minute=0),  # 每小时整点执行
    },
}