签入版本
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
# 文件上传
|
||||
|
||||
<!-- Copyright (c) 2021-2026 小蚂蚁云团队 版权所有 -->
|
||||
|
||||
:::tip 说明
|
||||
提供本地文件上传功能,支持图片和通用文件上传,内置扩展名白名单校验。服务层位于 `application/upload/services.py`,视图层位于 `application/upload/views.py`。
|
||||
:::
|
||||
|
||||
## 功能概述
|
||||
|
||||
文件上传模块提供统一的文件上传接口 `upload_file`,支持图片、文档、压缩包等各类文件,通过扩展名列表控制允许上传的格式。
|
||||
|
||||
```
|
||||
POST /upload/uploadFile —— 统一文件上传入口
|
||||
```
|
||||
|
||||
## 配置项
|
||||
|
||||
在 `config/env.py` 中配置上传相关参数:
|
||||
|
||||
```python
|
||||
# 上传文件存储根目录
|
||||
DJANGO_UPLOAD_DIR = os.getenv('DJANGO_UPLOAD_DIR', os.path.join(DJANGO_ROOT_PATH, '/public/uploads'))
|
||||
|
||||
# 临时文件路径
|
||||
DJANGO_TEMP_PATH = DJANGO_UPLOAD_DIR + '/temp'
|
||||
|
||||
# 文件访问域名
|
||||
DJANGO_FILE_URL = os.getenv('DJANGO_FILE_URL', 'http://file.django.elevue')
|
||||
```
|
||||
|
||||
:::tip 温馨提示
|
||||
`DJANGO_FILE_URL` 用于拼接完整的文件访问 URL,生产环境需配置为实际的文件服务域名或 Nginx 代理地址。
|
||||
:::
|
||||
|
||||
## 文件命名规则
|
||||
|
||||
上传文件自动重命名,格式为:`年月日时分秒 + 5位随机数 + 扩展名`
|
||||
|
||||
```python
|
||||
# application/upload/services.py
|
||||
timestamp = time.strftime('%Y%m%d%H%M%S')
|
||||
random_num = f'{random.randint(0, 99999):05d}'
|
||||
generated_name = f"{timestamp}{random_num}{file_ext_with_dot}"
|
||||
```
|
||||
|
||||
文件按日期分目录存储:`{UPLOAD_DIR}/temp/{YYYYMMDD}/{文件名}`
|
||||
|
||||
## 接口调用
|
||||
|
||||
### 上传文件
|
||||
|
||||
```
|
||||
POST /upload/uploadFile
|
||||
Content-Type: multipart/form-data
|
||||
Authorization: Bearer <token>
|
||||
参数: file(文件字段)
|
||||
```
|
||||
|
||||
响应示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"msg": "上传成功",
|
||||
"data": {
|
||||
"originalName": "photo.jpg",
|
||||
"fileExtension": "jpg",
|
||||
"fileType": "image/jpeg",
|
||||
"fileSize": 306995,
|
||||
"fileName": "2025030614302512345.jpg",
|
||||
"filePath": "/temp/20250306/2025030614302512345.jpg",
|
||||
"fileUrl": "http://file.django.elevue/temp/20250306/2025030614302512345.jpg"
|
||||
},
|
||||
"ok": true
|
||||
}
|
||||
```
|
||||
|
||||
## 安全机制
|
||||
|
||||
### 扩展名白名单
|
||||
|
||||
文件上传服务对扩展名进行白名单校验,支持的格式包括:
|
||||
|
||||
```
|
||||
图片:.jpeg, .jpg, .png, .gif, .bmp
|
||||
文档:.doc, .docx, .xls, .xlsx, .ppt, .pptx, .pdf, .txt
|
||||
```
|
||||
|
||||
### 文件类型校验
|
||||
|
||||
通过 `mimetypes` 模块推断文件的 MIME 类型,确保文件内容与扩展名一致。
|
||||
|
||||
### 路径安全
|
||||
|
||||
文件存储在临时目录中,业务提交时通过 `save_file()` 迁移到正式目录,避免路径遍历风险。
|
||||
|
||||
## 临时文件迁移
|
||||
|
||||
上传的文件首先存储在 `temp` 目录,业务数据提交时调用 `save_file()` 迁移到正式目录:
|
||||
|
||||
```python
|
||||
# utils/common.py
|
||||
def save_file(url, directory):
|
||||
"""将临时文件迁移到正式存储目录"""
|
||||
if url.find(DJANGO_FILE_URL) != -1:
|
||||
if url.find("/temp") != -1:
|
||||
# 构建目标目录路径
|
||||
path = DJANGO_UPLOAD_DIR + "/" + directory + "/" + time.strftime('%Y%m%d')
|
||||
mkdir(path)
|
||||
# 移动文件
|
||||
old_path = url.replace(DJANGO_FILE_URL, DJANGO_UPLOAD_DIR)
|
||||
new_path = DJANGO_UPLOAD_DIR + "/" + directory + old_path.replace(DJANGO_TEMP_PATH, "")
|
||||
os.rename(old_path, new_path)
|
||||
return new_path.replace(DJANGO_UPLOAD_DIR, "")
|
||||
```
|
||||
|
||||
## 文件 URL 拼接
|
||||
|
||||
`get_file_url()` 函数将相对路径拼接为完整的文件访问 URL:
|
||||
|
||||
```python
|
||||
# utils/common.py
|
||||
def get_file_url(path):
|
||||
if not path:
|
||||
return None
|
||||
return DJANGO_FILE_URL + path
|
||||
```
|
||||
|
||||
## 前端集成
|
||||
|
||||
前端使用 `Upload` 组件上传,上传成功后将返回的 `fileUrl` 存入业务字段。详见 [文件上传联调](/zh/volume4/integration/upload-sync) 章节。
|
||||
|
||||
## 总结
|
||||
|
||||
文件上传模块通过扩展名白名单、MIME 类型校验、临时目录隔离等安全机制,确保上传功能的安全性。文件自动重命名并按日期分目录存储,避免文件名冲突和信息泄露。统一的 `uploadFile` 接口同时支持图片和各类文件上传。
|
||||
Reference in New Issue
Block a user