# 文件管理模块快速开始指南

## 🚀 快速开始

### 后端启动

#### 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. **监控**：记录文件上传、下载日志，便于问题追踪

---

如有问题，请查看完整文档或联系开发团队。
