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>
This commit is contained in:
Claude
2026-01-25 00:26:21 +08:00
commit e71181f0a3
150 changed files with 39549 additions and 0 deletions

View File

@@ -0,0 +1,424 @@
# 文件管理模块快速开始指南
## 🚀 快速开始
### 后端启动
#### 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. **监控**:记录文件上传、下载日志,便于问题追踪
---
如有问题,请查看完整文档或联系开发团队。