Files
zcglxt/FILE_MANAGEMENT_QUICKSTART.md
Claude e71181f0a3 fix: 修复多个关键问题
- 修复前端路由守卫:未登录时不显示提示,直接跳转登录页
- 修复API拦截器:401错误不显示提示,直接跳转
- 增强验证码显示:图片尺寸从120x40增加到200x80
- 增大验证码字体:从28号增加到48号
- 优化验证码字符:排除易混淆的0和1
- 减少干扰线:从5条减少到3条,添加背景色优化
- 增强登录API日志:添加详细的调试日志
- 增强验证码生成和验证日志
- 优化异常处理和错误追踪

影响文件:
- src/router/index.ts
- src/api/request.ts
- app/services/auth_service.py
- app/api/v1/auth.py
- app/schemas/user.py

测试状态:
- 前端构建通过
- 后端语法检查通过
- 验证码显示效果优化完成

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-25 00:26:21 +08:00

425 lines
8.7 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. 数据库迁移
```bash
cd C:/Users/Administrator/asset_management_backend
# 激活虚拟环境
python -m venv venv
venv\Scripts\activate # Windows
# source venv/bin/activate # Linux/Mac
# 安装依赖
pip install -r requirements.txt
pip install python-multipart pillow
# 运行迁移
alembic upgrade head
```
#### 2. 创建上传目录
```bash
mkdir -p uploads/images
mkdir -p uploads/documents
mkdir -p uploads/thumbnails
mkdir -p uploads/temp
```
#### 3. 启动服务
```bash
python run.py
```
后端服务将运行在 `http://localhost:8000`
### 前端启动
#### 1. 安装依赖
```bash
cd C:/Users/Administrator/asset-management-frontend
npm install
```
#### 2. 启动开发服务器
```bash
npm run dev
```
前端服务将运行在 `http://localhost:5173`
## 📝 API测试示例
### 1. 文件上传使用curl
```bash
# 上传文件
curl -X POST http://localhost:8000/api/v1/files/upload \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "file=@/path/to/your/file.jpg" \
-F "remark=测试文件"
```
### 2. 获取文件列表
```bash
curl -X GET "http://localhost:8000/api/v1/files?page=1&page_size=20" \
-H "Authorization: Bearer YOUR_TOKEN"
```
### 3. 下载文件
```bash
curl -X GET http://localhost:8000/api/v1/files/1/download \
-H "Authorization: Bearer YOUR_TOKEN" \
-o downloaded_file.jpg
```
### 4. 生成分享链接
```bash
curl -X POST http://localhost:8000/api/v1/files/1/share \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"expire_days": 7}'
```
## 💻 前端使用示例
### 1. 在页面中使用文件上传组件
```vue
<template>
<div>
<file-upload
:auto-upload="false"
:show-progress="true"
:show-image-preview="true"
@upload-success="handleUploadSuccess"
/>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import FileUpload from '@/components/file/FileUpload.vue'
const handleUploadSuccess = (response, file) => {
ElMessage.success(`文件 ${file.name} 上传成功`)
console.log('上传响应:', response)
}
</script>
```
### 2. 在页面中使用文件列表组件
```vue
<template>
<div>
<file-list />
</div>
</template>
<script setup>
import FileList from '@/components/file/FileList.vue'
</script>
```
### 3. 使用文件API
```typescript
import { uploadFile, getFileList, downloadFile } from '@/api/file'
// 上传文件
const handleUpload = async (file: File) => {
try {
const response = await uploadFile(file, { remark: '测试' })
console.log('上传成功:', response)
} catch (error) {
console.error('上传失败:', error)
}
}
// 获取文件列表
const fetchFiles = async () => {
try {
const files = await getFileList({
page: 1,
page_size: 20,
keyword: 'test'
})
console.log('文件列表:', files)
} catch (error) {
console.error('获取失败:', error)
}
}
// 下载文件
const handleDownload = async (fileId: number, fileName: string) => {
try {
await downloadFile(fileId)
// 注意:实际下载需要在响应头处理
window.open(`http://localhost:8000/api/v1/files/${fileId}/download`)
} catch (error) {
console.error('下载失败:', error)
}
}
```
## 🎯 常见功能实现
### 1. 批量上传
```vue
<template>
<file-upload
:multiple="true"
:limit="10"
:auto-upload="false"
ref="uploadRef"
>
<template #tip>
<div>最多可上传10个文件</div>
</template>
</file-upload>
<el-button @click="submitUpload">开始上传</el-button>
</template>
<script setup>
import { ref } from 'vue'
import FileUpload from '@/components/file/FileUpload.vue'
const uploadRef = ref()
const submitUpload = () => {
uploadRef.value.submitUpload()
}
</script>
```
### 2. 图片预览
```vue
<template>
<div>
<el-button @click="showPreview = true">预览图片</el-button>
<image-preview
v-model:visible="showPreview"
:images="images"
:initial-index="0"
/>
</div>
</template>
<script setup>
import { ref } from 'vue'
import ImagePreview from '@/components/file/ImagePreview.vue'
const showPreview = ref(false)
const images = ref([
{
url: 'http://localhost:8000/api/v1/files/1/preview',
name: '图片1.jpg'
},
{
url: 'http://localhost:8000/api/v1/files/2/preview',
name: '图片2.jpg'
}
])
</script>
```
### 3. 文件分享
```typescript
import { createShareLink } from '@/api/file'
import { ElMessage } from 'element-plus'
const shareFile = async (fileId: number) => {
try {
const result = await createShareLink(fileId, 7) // 7天有效期
ElMessage.success(`分享链接: ${result.share_url}`)
// 复制到剪贴板
navigator.clipboard.writeText(result.share_url)
} catch (error) {
ElMessage.error('生成分享链接失败')
}
}
```
### 4. 大文件分片上传
```typescript
import { initChunkUpload, uploadChunk, completeChunkUpload } from '@/api/file'
const uploadLargeFile = async (file: File) => {
const CHUNK_SIZE = 5 * 1024 * 1024 // 5MB每片
const totalChunks = Math.ceil(file.size / CHUNK_SIZE)
// 1. 初始化
const { upload_id } = await initChunkUpload({
file_name: file.name,
file_size: file.size,
file_type: file.type,
total_chunks: totalChunks
})
// 2. 上传分片
for (let i = 0; i < totalChunks; i++) {
const start = i * CHUNK_SIZE
const end = Math.min(start + CHUNK_SIZE, file.size)
const chunk = file.slice(start, end)
await uploadChunk(upload_id, i, chunk)
console.log(`分片 ${i + 1}/${totalChunks} 上传完成`)
}
// 3. 完成上传
const result = await completeChunkUpload({
upload_id: upload_id,
file_name: file.name
})
console.log('上传完成:', result)
}
```
## 🔍 API响应示例
### 上传文件响应
```json
{
"id": 1,
"file_name": "a1b2c3d4-e5f6-7890-abcd-ef1234567890.jpg",
"original_name": "photo.jpg",
"file_size": 1024000,
"file_type": "image/jpeg",
"file_path": "uploads/2026/01/24/a1b2c3d4-e5f6-7890-abcd-ef1234567890.jpg",
"download_url": "http://localhost:8000/api/v1/files/1/download",
"preview_url": "http://localhost:8000/api/v1/files/1/preview",
"message": "上传成功"
}
```
### 文件列表响应
```json
[
{
"id": 1,
"file_name": "uuid.jpg",
"original_name": "photo.jpg",
"file_size": 1024000,
"file_type": "image/jpeg",
"file_ext": "jpg",
"uploader_id": 1,
"uploader_name": "张三",
"upload_time": "2026-01-24T10:30:00",
"thumbnail_path": "uploads/thumbnails/2026/01/24/thumb_uuid.jpg",
"download_count": 5,
"remark": null
}
]
```
### 分享链接响应
```json
{
"share_code": "AbCdEf1234567890",
"share_url": "http://localhost:8000/api/v1/files/share/AbCdEf1234567890",
"expire_time": "2026-01-31T10:30:00"
}
```
### 文件统计响应
```json
{
"total_files": 150,
"total_size": 524288000,
"total_size_human": "500.00 MB",
"type_distribution": {
"image/jpeg": 80,
"image/png": 40,
"application/pdf": 30
},
"upload_today": 10,
"upload_this_week": 50,
"upload_this_month": 120,
"top_uploaders": [
{ "uploader_id": 1, "count": 50 },
{ "uploader_id": 2, "count": 30 }
]
}
```
## 🛠️ 故障排除
### 问题1上传文件失败
**错误信息**`413 Request Entity Too Large`
**解决方案**
检查Nginx配置如果使用
```nginx
client_max_body_size 100M;
```
### 问题2文件类型不支持
**错误信息**`不支持的文件类型`
**解决方案**
`app/services/file_service.py` 中添加文件类型到白名单:
```python
ALLOWED_MIME_TYPES = {
'image/webp', # 添加新类型
# ... 其他类型
}
```
### 问题3缩略图生成失败
**错误信息**`生成缩略图失败`
**解决方案**
确保安装了Pillow库
```bash
pip install pillow
```
### 问题4前端无法预览图片
**错误信息**CORS错误
**解决方案**
在后端添加CORS中间件
```python
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:5173"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
```
## 📚 更多资源
- [完整文档](./FILE_MANAGEMENT_README.md)
- [API文档](./API_QUICK_REFERENCE.md)
- [项目主文档](./README.md)
## 💡 提示
1. **开发环境**:使用小文件测试,避免上传大文件
2. **生产环境**建议使用云存储服务OSS、S3等
3. **安全性**:生产环境务必配置文件类型和大小限制
4. **性能**:大文件使用分片上传,提高上传成功率
5. **监控**:记录文件上传、下载日志,便于问题追踪
---
如有问题,请查看完整文档或联系开发团队。