yunzer_go/server/docs/FILE_UPLOAD.md
2025-10-28 17:22:27 +08:00

204 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 文件上传功能文档
## 概述
文件上传功能已完整实现,支持将文件保存到本地文件系统并记录到数据库中。
## 功能特性
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`: 用户自定义分类