# routers/file.py 接口测试文档 ## 文件功能概述 该文件提供文件管理相关的接口,包括: - OSS 文件上传(通用文件 / 图片 / JSON) - OSS URL 解析(解密) - 获取文件签名链接 所有接口均需要 Token 认证。 路由前缀:`/apiv1`(以 `routers/__init__.py` 中注册为准) > **注意:** 文件末尾注释说明以下接口在其他文件中实现,不在本文件中重复定义: > - `GET /download_file` → `routers/total.py` > - `POST /policy_file_count` → `routers/total.py` > - `POST /save_ppt_outline` → `routers/chat.py` > - `POST /save_edit_document` → `routers/chat.py` --- ## 接口列表 --- ### 1. POST `/apiv1/oss/upload` — OSS 文件上传 **功能说明:** 上传任意文件到 OSS 存储,返回文件访问 URL。 **是否需要认证:** 是 **请求方式:** POST(multipart/form-data) **请求参数:** | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | file | File | 是 | 要上传的文件(multipart/form-data) | **业务逻辑:** - 读取上传文件的二进制内容 - 调用 `oss_service.upload_file(content, filename)` 上传至 OSS - 返回文件的 OSS URL **测试用例:** #### 用例 1:正常上传文件 ``` // 请求 POST /apiv1/oss/upload token: <有效Token> Content-Type: multipart/form-data file: (选择一个文件,如 test.pdf) // 预期响应 (HTTP 200) { "statusCode": 200, "msg": "上传成功", "data": { "file_url": "https://oss.example.com/path/to/test.pdf" } } ``` #### 用例 2:未认证 ``` // 请求(不带 Token) POST /apiv1/oss/upload Content-Type: multipart/form-data file: (选择一个文件) // 预期响应 (HTTP 401) { "statusCode": 401, "msg": "未提供认证Token" } ``` #### 用例 3:未提供文件 ``` // 请求 POST /apiv1/oss/upload token: <有效Token> Content-Type: multipart/form-data (不传 file 字段) // 预期响应 (HTTP 422) { "detail": [ { "loc": ["body", "file"], "msg": "field required", "type": "value_error.missing" } ] } ``` #### 用例 4:OSS 服务异常 ``` // 请求(OSS 配置错误或服务不可用时) POST /apiv1/oss/upload token: <有效Token> Content-Type: multipart/form-data file: (选择一个文件) // 预期响应 (HTTP 200, 业务码 500) { "statusCode": 500, "msg": "上传失败: <具体错误信息>" } ``` --- ### 2. POST `/apiv1/oss/shudao/upload_image` — 上传图片 **功能说明:** 上传图片文件到 OSS 存储(使用图片专用上传方法),返回图片访问 URL。 **是否需要认证:** 是 **请求方式:** POST(multipart/form-data) **请求参数:** | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | file | File | 是 | 要上传的图片文件(multipart/form-data) | **业务逻辑:** - 读取上传文件的二进制内容 - 调用 `oss_service.upload_image(content, filename)` 上传至 OSS - 返回图片的 OSS URL **测试用例:** #### 用例 1:正常上传图片 ``` // 请求 POST /apiv1/oss/shudao/upload_image token: <有效Token> Content-Type: multipart/form-data file: (选择一个图片文件,如 photo.jpg) // 预期响应 (HTTP 200) { "statusCode": 200, "msg": "上传成功", "data": { "image_url": "https://oss.example.com/images/photo.jpg" } } ``` #### 用例 2:未认证 ``` // 请求 POST /apiv1/oss/shudao/upload_image // 预期响应 (HTTP 401) { "statusCode": 401, "msg": "未提供认证Token" } ``` #### 用例 3:上传非图片文件(代码无格式校验,仍可上传成功) ``` // 请求 POST /apiv1/oss/shudao/upload_image token: <有效Token> Content-Type: multipart/form-data file: (选择一个 .txt 文件) // 预期响应 (HTTP 200) { "statusCode": 200, "msg": "上传成功", "data": { "image_url": "https://oss.example.com/images/file.txt" } } ``` > 注意:代码中未对文件类型做校验,非图片文件也能通过此接口上传。 #### 用例 4:OSS 服务异常 ``` // 预期响应 (HTTP 200, 业务码 500) { "statusCode": 500, "msg": "上传失败: <具体错误信息>" } ``` --- ### 3. POST `/apiv1/oss/shudao/upload_json` — 上传 JSON 文件 **功能说明:** 将 JSON 对象序列化为字符串后上传到 OSS,返回文件 URL。用于 PPT JSON 数据等场景。 **是否需要认证:** 是 **请求方式:** POST **请求体(JSON):** | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | filename | string | 是 | 文件名(如 "ppt_data.json") | | content | object | 是 | JSON 对象内容 | **业务逻辑:** - 将 `content` 字典通过 `json.dumps` 序列化为 JSON 字符串(`ensure_ascii=False`) - 调用 `oss_service.upload_json(json_str, filename)` 上传至 OSS - 返回文件 URL **测试用例:** #### 用例 1:正常上传 JSON ```json // 请求 POST /apiv1/oss/shudao/upload_json token: <有效Token> Content-Type: application/json { "filename": "ppt_data.json", "content": { "title": "桥梁施工安全培训", "slides": [ {"title": "概述", "content": "..."}, {"title": "安全要点", "content": "..."} ] } } // 预期响应 (HTTP 200) { "statusCode": 200, "msg": "上传成功", "data": { "file_url": "https://oss.example.com/json/ppt_data.json" } } ``` #### 用例 2:未认证 ```json // 请求 POST /apiv1/oss/shudao/upload_json // 预期响应 (HTTP 401) { "statusCode": 401, "msg": "未提供认证Token" } ``` #### 用例 3:缺少必填字段 ```json // 请求 POST /apiv1/oss/shudao/upload_json token: <有效Token> Content-Type: application/json { "filename": "test.json" } // 预期响应 (HTTP 422) { "detail": [ { "loc": ["body", "content"], "msg": "field required", "type": "value_error.missing" } ] } ``` #### 用例 4:OSS 服务异常 ```json // 预期响应 (HTTP 200, 业务码 500) { "statusCode": 500, "msg": "上传失败: <具体错误信息>" } ``` --- ### 4. GET `/apiv1/oss/parse` — OSS URL 解析 **功能说明:** 解析(解密)OSS URL,返回可直接访问的真实 URL。 **是否需要认证:** 是 **请求方式:** GET **请求参数(Query):** | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | url | string | 是 | 加密的 OSS URL | **业务逻辑:** - 调用 `oss_service.parse_url(url)` 解密 URL - 返回解密后的真实 URL **测试用例:** #### 用例 1:正常解析 ```json // 请求 GET /apiv1/oss/parse?url=encrypted_url_string_here token: <有效Token> // 预期响应 (HTTP 200) { "statusCode": 200, "msg": "success", "data": { "url": "https://oss.example.com/real/path/to/file.pdf" } } ``` #### 用例 2:无效的 URL ```json // 请求 GET /apiv1/oss/parse?url=invalid_url token: <有效Token> // 预期响应 (HTTP 200, 业务码 500) { "statusCode": 500, "msg": "解析失败: <具体错误信息>" } ``` #### 用例 3:未认证 ```json // 请求 GET /apiv1/oss/parse?url=test // 预期响应 (HTTP 401) { "statusCode": 401, "msg": "未提供认证Token" } ``` #### 用例 4:未提供 url 参数 ```json // 请求 GET /apiv1/oss/parse token: <有效Token> // 预期响应 (HTTP 422) { "detail": [ { "loc": ["query", "url"], "msg": "field required", "type": "value_error.missing" } ] } ``` --- ### 5. GET `/apiv1/get_file_link` — 获取文件签名链接 **功能说明:** 根据文件名生成带签名的 OSS 临时访问链接。 **是否需要认证:** 是 **请求方式:** GET **请求参数(Query):** | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | filename | string | 是 | 文件名 | **业务逻辑:** - 调用 `oss_service.get_signed_url(filename)` 生成带签名的临时访问 URL - 返回签名 URL **测试用例:** #### 用例 1:正常获取链接 ```json // 请求 GET /apiv1/get_file_link?filename=report.pdf token: <有效Token> // 预期响应 (HTTP 200) { "statusCode": 200, "msg": "success", "data": { "file_url": "https://oss.example.com/report.pdf?Expires=1700000000&Signature=xxx" } } ``` #### 用例 2:文件不存在(OSS 仍可生成签名 URL,但访问时会 404) ```json // 请求 GET /apiv1/get_file_link?filename=nonexistent.pdf token: <有效Token> // 预期响应 (HTTP 200) { "statusCode": 200, "msg": "success", "data": { "file_url": "https://oss.example.com/nonexistent.pdf?Expires=1700000000&Signature=xxx" } } ``` > 注意:OSS 签名 URL 生成不依赖文件是否存在,即使文件不存在也会返回成功。 #### 用例 3:未认证 ```json // 请求 GET /apiv1/get_file_link?filename=test.pdf // 预期响应 (HTTP 401) { "statusCode": 401, "msg": "未提供认证Token" } ``` #### 用例 4:未提供 filename 参数 ```json // 请求 GET /apiv1/get_file_link token: <有效Token> // 预期响应 (HTTP 422) { "detail": [ { "loc": ["query", "filename"], "msg": "field required", "type": "value_error.missing" } ] } ``` #### 用例 5:OSS 服务异常 ```json // 预期响应 (HTTP 200, 业务码 500) { "statusCode": 500, "msg": "获取失败: <具体错误信息>" } ``` --- ## 依赖说明 | 依赖项 | 说明 | |--------|------| | `database.get_db` | SQLAlchemy 数据库会话(部分接口声明了但实际未使用) | | `models.total.PolicyFile` | 政策文件模型(已导入但本文件接口中未使用) | | `services.oss_service` | OSS 存储服务,封装了上传、解析、签名等操作 | | `request.state.user` | 从中间件注入的用户信息 | ## 代码备注 1. 所有接口的异常处理均为 `try/except Exception`,捕获所有异常后返回 `statusCode: 500`,HTTP 状态码仍为 200。 2. `upload_image` 接口未对文件类型做任何校验,任何文件都可通过此接口上传。 3. `upload_json` 接口使用 `ensure_ascii=False` 序列化 JSON,支持中文字符。 4. `oss_service` 的具体实现(如 OSS provider、bucket 配置等)在 `services/oss_service.py` 中。