..
2025-09-22 21:18:08 +08:00
2025-08-29 05:19:54 +08:00
2025-08-30 20:29:21 +08:00
2025-08-29 01:09:46 +08:00
1
2025-09-07 05:20:48 +08:00
2025-09-22 22:49:28 +08:00
2025-08-29 03:18:20 +08:00
2025-08-29 01:09:46 +08:00
2025-09-15 19:15:51 +08:00
2025-09-08 17:53:06 +08:00
2025-08-05 20:45:02 +08:00
2025-09-24 20:57:21 +08:00
2025-09-19 20:33:15 +08:00
2025-09-07 04:54:21 +08:00

Video-Flow API 使用指南(方案一:保持现状,统一规范与示例)

目标:在不改动现有代码结构与签名的前提下,提供清晰的一致性用法、错误处理约定与多场景接入示例。

目录结构与职责

  • constants.ts:基础配置(BASE_URLNEXT_PUBLIC_BASE_URL 注入)
  • request.tsAxios 实例与拦截器、通用 get/post/put/delstreamSSE风格下载进度downloadStreamstreamJsonPost
  • errorHandle.ts:错误码映射与统一提示、特殊码处理(如 401 跳转登录、402 不弹提示)
  • common.ts:通用类型与与上传相关的工具(获取七牛 Token、上传
  • resources.ts:示例资源接口封装(基于 post
  • 其他业务模块(如 video_flow.tsexport-adapter.ts 等)各自封装具体接口/逻辑

统一调用规范

  1. 使用 request.ts 提供的 get/post/put/del 包装函数发起请求,返回后端响应体(已通过响应拦截器做业务码检查)。
  2. 业务成功码:code === 0code === 202(长任务/排队等需要前端自行处理状态)。若非成功码,拦截器会调用 errorHandlePromise.reject
  3. 认证:前端从 localStorage.token 注入 Authorization: Bearer <token>,请确保登录流程写入 token
  4. 基础地址:通过环境变量 NEXT_PUBLIC_BASE_URL 注入,构建前需设置。

错误处理约定

  • errorHandle(code, message?)统一弹出错误402 除外),并处理特殊码:
    • 401:清除 localStorage.token 并跳转 /login
    • 402:由 request.ts 响应拦截器在收到后端 402 且带 detail 时触发通知(积分不足),并拒绝请求
  • 网络/解析类错误:handleRequestError 会降级为通用错误提示并抛出异常

常用请求示例

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: {} 行)
import { stream } from '@/api/request';

await stream<{ type: string; message?: string; progress?: number }>({
    url: '/api/video-flow/export/ai-clips',
    method: 'POST',
    data: { /* your body */ },
    onMessage: (evt) => {
        if (evt.type === 'progress') {
            // 更新进度条
        }
    },
    onError: (err) => { /* 兜底错误处理 */ },
    onComplete: () => { /* 完成回调 */ }
});
  1. 文本行分隔的 JSON 流(fetch + ReadableStream,每行一个 JSON
import { streamJsonPost } from '@/api/request';

await streamJsonPost('/sse/json', { /* body */ }, (json) => {
    // 每次解析到一行 JSON
});
  1. 文件下载Blob
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
  • 错误提示:由 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(BASE_URL + 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 中按行解析。