204 lines
5.1 KiB
Markdown
204 lines
5.1 KiB
Markdown
# 文件上传功能文档
|
||
|
||
## 概述
|
||
|
||
文件上传功能已完整实现,支持将文件保存到本地文件系统并记录到数据库中。
|
||
|
||
## 功能特性
|
||
|
||
1. **自动目录管理**:按年月日自动创建目录结构(如 `front/uploads/2024/01/15/`)
|
||
2. **唯一文件名**:使用时间戳生成唯一文件名,避免重名冲突
|
||
3. **文件类型识别**:自动识别文件类型(图片、文档、视频、音频、压缩包等)
|
||
4. **数据库记录**:所有文件信息保存到 `yz_files` 表
|
||
5. **用户关联**:自动关联当前登录用户
|
||
6. **异常处理**:文件保存失败时自动清理已上传的文件
|
||
|
||
## 文件结构
|
||
|
||
```
|
||
front/
|
||
└── uploads/
|
||
├── 2024/
|
||
│ ├── 01/
|
||
│ │ ├── 15/
|
||
│ │ │ ├── 20240115143045_example.jpg
|
||
│ │ │ └── 20240115143046_document.pdf
|
||
```
|
||
|
||
## API 接口
|
||
|
||
### 上传文件
|
||
|
||
**POST** `/api/files`
|
||
|
||
**请求头**:
|
||
```
|
||
Authorization: Bearer <token>
|
||
Content-Type: multipart/form-data
|
||
```
|
||
|
||
**请求参数**:
|
||
- `file` (File, required): 上传的文件
|
||
- `category` (String, optional): 文件分类,默认为"未分类"
|
||
- `tenant_id` (String, optional): 租户ID,默认为"default"
|
||
|
||
**响应示例**:
|
||
```json
|
||
{
|
||
"success": true,
|
||
"message": "文件上传成功",
|
||
"data": {
|
||
"id": 1,
|
||
"tenant_id": "default",
|
||
"user_id": 123,
|
||
"file_name": "example",
|
||
"original_name": "example.jpg",
|
||
"file_path": "uploads/2024/01/15/20240115143045_example.jpg",
|
||
"file_url": "/uploads/2024/01/15/20240115143045_example.jpg",
|
||
"file_size": 102400,
|
||
"file_type": "image",
|
||
"file_ext": ".jpg",
|
||
"category": "未分类",
|
||
"upload_by": "username",
|
||
"upload_time": "2024-01-15T14:30:45Z"
|
||
}
|
||
}
|
||
```
|
||
|
||
## 后端实现
|
||
|
||
### 路由配置
|
||
|
||
在 `server/routers/router.go` 中配置:
|
||
|
||
```go
|
||
// 文件管理路由
|
||
beego.Router("/api/files", &controllers.FileController{}, "get:GetAllFiles")
|
||
beego.Router("/api/files", &controllers.FileController{}, "post:Post")
|
||
beego.Router("/api/files/my", &controllers.FileController{}, "get:GetMyFiles")
|
||
beego.Router("/api/files/:id", &controllers.FileController{}, "get:GetFileById")
|
||
beego.Router("/api/files/:id", &controllers.FileController{}, "put:UpdateFile")
|
||
beego.Router("/api/files/:id", &controllers.FileController{}, "delete:DeleteFile")
|
||
```
|
||
|
||
### 控制器实现
|
||
|
||
`Post()` 方法位于 `server/controllers/file.go`:
|
||
|
||
1. 验证用户登录状态
|
||
2. 接收上传的文件
|
||
3. 生成日期路径和唯一文件名
|
||
4. 保存文件到本地
|
||
5. 记录文件信息到数据库
|
||
6. 返回文件信息
|
||
|
||
## 前端使用
|
||
|
||
### 基本用法
|
||
|
||
```typescript
|
||
import { fileAPI } from '@/api/file'
|
||
|
||
// 创建 FormData
|
||
const formData = new FormData()
|
||
formData.append('file', fileObject) // fileObject 是 File 对象
|
||
formData.append('category', '文档')
|
||
formData.append('tenant_id', 'tenant-001')
|
||
|
||
// 上传文件
|
||
try {
|
||
const response = await fileAPI.uploadFile(formData, {
|
||
category: '文档',
|
||
tenantId: 'tenant-001'
|
||
})
|
||
console.log('上传成功:', response.data)
|
||
} catch (error) {
|
||
console.error('上传失败:', error)
|
||
}
|
||
```
|
||
|
||
### Element Plus 上传组件
|
||
|
||
```vue
|
||
<el-upload
|
||
ref="uploadRef"
|
||
drag
|
||
:action="uploadUrl"
|
||
:headers="uploadHeaders"
|
||
:data="{ category: uploadForm.category }"
|
||
:on-success="handleUploadSuccess"
|
||
:on-error="handleUploadError"
|
||
:before-upload="beforeUpload"
|
||
multiple
|
||
>
|
||
<el-icon><upload-filled /></el-icon>
|
||
<div class="el-upload__text">
|
||
将文件拖到此处,或<em>点击上传</em>
|
||
</div>
|
||
</el-upload>
|
||
|
||
<script setup>
|
||
const uploadUrl = computed(() => {
|
||
const baseUrl = import.meta.env.VITE_API_BASE_URL
|
||
return `${baseUrl}/api/files`
|
||
})
|
||
|
||
const uploadHeaders = computed(() => {
|
||
const token = localStorage.getItem('token')
|
||
return {
|
||
'Authorization': `Bearer ${token}`
|
||
}
|
||
})
|
||
|
||
const handleUploadSuccess = (response) => {
|
||
console.log('上传成功:', response)
|
||
}
|
||
|
||
const beforeUpload = (file) => {
|
||
const maxSize = 10 * 1024 * 1024 // 10MB
|
||
if (file.size > maxSize) {
|
||
ElMessage.error('文件大小不能超过 10MB!')
|
||
return false
|
||
}
|
||
return true
|
||
}
|
||
</script>
|
||
```
|
||
|
||
## 文件访问
|
||
|
||
上传后的文件可以通过以下URL访问:
|
||
|
||
```
|
||
http://localhost:8080/uploads/2024/01/15/20240115143045_example.jpg
|
||
```
|
||
|
||
注意:需要配置 Beego 的静态文件服务来提供上传文件的访问。
|
||
|
||
在 `server/conf/app.conf` 中添加:
|
||
|
||
```conf
|
||
# 文件上传目录
|
||
StaticDir = /uploads:../front/uploads
|
||
```
|
||
|
||
## 安全注意事项
|
||
|
||
1. **文件大小限制**:建议在前端和后端都添加文件大小限制
|
||
2. **文件类型验证**:根据业务需求限制允许上传的文件类型
|
||
3. **文件名安全**:避免用户控制文件名造成安全问题
|
||
4. **权限控制**:确保只有授权用户可以上传文件
|
||
5. **存储位置**:考虑使用对象存储服务(如 OSS、S3)替代本地存储
|
||
|
||
## 数据库字段说明
|
||
|
||
`yz_files` 表的主要字段:
|
||
|
||
- `file_path`: 相对路径,用于存储和访问文件
|
||
- `file_url`: 访问URL
|
||
- `original_name`: 用户上传时的原始文件名
|
||
- `file_name`: 去除扩展名的文件名
|
||
- `file_type`: 文件类型(image, document, video, audio, archive, other)
|
||
- `category`: 用户自定义分类
|
||
|