video-flow-b/api/README.md
2025-10-27 15:48:42 +08:00

129 lines
5.2 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.

## video-flow-b API 使用指南(方案一:保持现状,统一规范与示例)
> 目标:在不改动现有代码结构与签名的前提下,提供清晰的一致性用法、错误处理约定与多场景接入示例。
### 目录结构与职责
- 基础配置从 `@/lib/env` 导入 `baseUrl`
- `request.ts`Axios 实例与拦截器、通用 `get/post/put/del``stream`SSE风格下载进度`downloadStream``streamJsonPost`
- `errorHandle.ts`:错误码映射与统一提示、特殊码处理(如 401 跳转登录、402 不弹提示)
- `common.ts`:通用类型与与上传相关的工具(获取七牛 Token、上传
- `resources.ts`:示例资源接口封装(基于 `post`
- 其他业务模块(如 `video_flow.ts``export-adapter.ts` 等)各自封装具体接口/逻辑
### 统一调用规范
1. 使用 `request.ts` 提供的 `get/post/put/del` 包装函数发起请求,返回后端响应体(已通过响应拦截器做业务码检查)。
2. 业务成功码:`code === 0``code === 202`(长任务/排队等需要前端自行处理状态)。若非成功码,拦截器会调用 `errorHandle``Promise.reject`
3. 认证:前端从 `localStorage.token` 注入 `Authorization: Bearer <token>`,请确保登录流程写入 `token`
4. 基础地址:从 `@/lib/env``baseUrl` 获取,统一管理环境变量。
### 错误处理约定
- `errorHandle(code, message?)`统一弹出错误402 除外),并处理特殊码:
- `401`:清除 `localStorage.token` 并跳转 `/login`
- `402`:由 `request.ts` 响应拦截器在收到后端 `402` 且带 `detail` 时触发通知(积分不足),并拒绝请求
- 网络/解析类错误:`handleRequestError` 会降级为通用错误提示并抛出异常
### 常用请求示例
```ts
import { get, post, put, del } from '@/api/request';
type User = { id: number; name: string };
type ApiResponse<T> = { code: number; successful: boolean; message: string; data: T };
// GET
const user = await get<ApiResponse<User>>('/user/detail?id=1');
// POST
const created = await post<ApiResponse<User>>('/user/create', { name: 'Evan' });
// PUT
await put<ApiResponse<null>>('/user/update', { id: 1, name: 'Kent' });
// DELETE
await del<ApiResponse<null>>('/user/remove?id=1');
```
### 流式与下载SSE/文件)
1) SSE/渐进消息(基于 Axios 下载进度事件解析 `data: {}` 行)
```ts
import { stream } from '@/api/request';
await stream<{ type: string; message?: string; progress?: number }>({
url: '/api/video-flow-b/export/ai-clips',
method: 'POST',
data: { /* your body */ },
onMessage: (evt) => {
if (evt.type === 'progress') {
// 更新进度条
}
},
onError: (err) => { /* 兜底错误处理 */ },
onComplete: () => { /* 完成回调 */ }
});
```
2) 文本行分隔的 JSON 流(`fetch` + `ReadableStream`,每行一个 JSON
```ts
import { streamJsonPost } from '@/api/request';
await streamJsonPost('/sse/json', { /* body */ }, (json) => {
// 每次解析到一行 JSON
});
```
3) 文件下载Blob
```ts
import { downloadStream } from '@/api/request';
await downloadStream('/download/file', 'result.mp4');
```
### 多场景接入指南
#### 浏览器前端React/Next.js CSR
- 直接使用 `get/post/put/del`;确保登录后将 `token` 写入 `localStorage`
- 环境变量:在 `.env.local` 配置 `NEXT_PUBLIC_BASE_URL`,通过 `@/lib/env` 统一管理
- 错误提示:由 `errorHandle` 统一处理402 会展示积分不足通知
#### Next.js Route Handler服务端 API
- 如需在 Route Handler 内调用后端接口:建议使用服务端 `fetch` 并自行附加服务端凭证;避免直接依赖 `localStorage`
- 若需要转发到现有后端并复用通知/事件流格式,可参考 `api/export-adapter.ts` 的 SSE 写法
#### Next.js Server Components/SSR
- 服务端不具备 `localStorage`,如需鉴权请改为从 Cookie/Headers 传递 token并在转发时设置 `Authorization`
- 服务器端可直接使用 `fetch(baseUrl + path, { headers })`
#### Node/ServerlessVercel/Cloudflare
- 同 SSR 原则:不使用 `localStorage`;从密钥存储中读取后以请求头传递
- SSE 转发时,按 `text/event-stream` 写入 `ReadableStream` 并传递 `data: <json>\n\n`
### 最佳实践
- 统一通过 `request.ts` 发起请求,不绕过拦截器;对长任务/排队返回 `202` 时在页面层处理轮询或 SSE
- 上传流程:使用 `common.ts/getUploadToken` 获取 token 与 domain再使用 `uploadToQiniu` 上传,监听进度
- 将后端的业务错误码保持为服务端规范在前端只做展示与关键码分支401/402
### 常见问题FAQ
- Q: 为什么拿不到 `localStorage` 中的 token
- A: 服务端渲染或 Route Handler 中无 `localStorage`,需通过 Cookie/Headers 传递。
- Q: 返回 `code !== 0/202` 时如何自定义处理?
- A: 可在业务层 `try/catch` 捕获 `post/get` 的拒绝 Promise并根据 `error.message` 或后端 `data.message` 做分支。
- Q: SSE 收不到事件?
- A: 确认后端使用 `text/event-stream`,每条消息以 `data: <json>\n\n` 输出;前端在 `onDownloadProgress` 中按行解析。
---