web/console/src/api/readme.md
本文档介绍 53AIHub-console 项目的 API 架构设计,包括核心配置文件和模块开发规范。
src/api/
├── index.ts # 模块统一导出入口
├── config.ts # Axios 配置和拦截器
├── errorHandler.ts # 统一错误处理
├── code.ts # 响应状态码和错误码定义
├── signature.ts # 签名生成工具
├── types.ts # 基础类型定义
├── readme.md # 本文档
└── modules/ # 业务模块目录
├── banner/ # Banner 模块示例
├── user/ # 用户管理模块
├── agent/ # 代理管理模块
└── ... # 其他业务模块
config.ts - Axios 配置和拦截器负责创建和配置 Axios 实例,包含请求和响应拦截器。
主要功能:
关键特性:
// 自动添加认证 token
const access_token = localStorage.getItem("access_token") || ""
if (access_token) config.headers.set("Authorization", `Bearer ${access_token}`)
// 支持 ibos 签名
if (config.ibos_sign) {
const { token, platform, createtime } = generateIbosSignParams()
config.headers.set("token", token)
config.headers.set("platform", platform)
config.headers.set("createtime", createtime)
}
// 支持验证码签名
if (config.code_sign) config.params = generateSignParams(config.params)
使用方式:
import service from "@/api/config"
// 基础请求
const response = await service.get("/api/endpoint")
// 带签名的请求
const response = await service.get("/api/endpoint", { ibos_sign: true })
// 带重试的请求
const response = await service.get("/api/endpoint", {
retryConfig: { retry: 3, retryDelay: 1000 },
})
errorHandler.ts - 统一错误处理提供统一的错误处理机制,包括错误消息国际化、token 过期处理等。
主要功能:
错误处理流程:
export function handleError(error: ErrorResponse): Promise<never> {
// 1. 解析错误状态和响应数据
const status = error.response?.status || 500
const code = resData?.code
const message = resData?.message
// 2. 根据错误类型获取对应消息
const messageMatch = RESPONSE_MESSAGE_MAP.get(message || "")
// 3. 特殊错误处理(如 token 过期)
if (code === ResponseCode.TOKEN_EXPIRED_ERROR) {
localStorage.removeItem("access_token")
window.location.reload(true)
}
// 4. 显示错误消息
if (message) ElMessage.warning(message)
return Promise.reject(error)
}
使用方式:
import { handleError } from "@/api/errorHandler"
// 在所有 API 调用中使用
service
.get("/api/endpoint")
.then(res => res.data)
.catch(handleError)
code.ts - 响应状态码和错误码定义定义系统中使用的所有响应状态码、业务错误码和对应的消息映射。
包含内容:
错误码分类:
export enum ResponseCode {
SUCCESS = 0, // 成功
PARAM_ERROR = 1, // 参数错误
DATABASE_ERROR = 2, // 数据库错误
NETWORK_ERROR = 3, // 网络错误
SYSTEM_ERROR = 4, // 系统错误
AUTH_ERROR = 5, // 认证错误
NOT_FOUND_ERROR = 6, // 资源不存在
UNAUTHORIZED_ERROR = 7, // 未授权
FILE_ERROR = 8, // 文件错误
FORBIDDEN_ERROR = 9, // 禁止访问
AGENT_ERROR = 10, // 代理错误
TOKEN_EXPIRED_ERROR = 11, // Token 过期
VERIFICATION_CODE_ERROR = -14, // 验证码错误
}
消息映射:
export const RESPONSE_CODE_MESSAGE_MAP = new Map([
[ResponseCode.SUCCESS, "response_code.success"],
[ResponseCode.PARAM_ERROR, "response_code.param_error"],
// ... 其他映射
])
signature.ts - 签名生成工具提供两种签名生成方式:普通签名和 ibos 签名。
普通签名 (generateSignParams):
export function generateSignParams(params = {}) {
const authkey = "c3a39e4eeacf4542d6a488e19037fa45"
params = Object.assign({}, params, {
timestamp: Math.floor(Date.now() / 1000),
platform: "web",
})
const strForSign = serialize(params)
const sign = md5(strForSign + authkey)
return { sign, method: "md5", ...params }
}
ibos 签名 (generateIbosSignParams):
export function generateIbosSignParams() {
const authkey = "c3a39e4eeacf4542d6a488e19037fa45"
const platform = "web"
const createtime = Math.floor(Date.now() / 1000)
const token = md5(authkey + createtime)
return { token, platform, createtime }
}
使用方式:
import { generateSignParams, generateIbosSignParams } from "@/api/signature"
// 在请求配置中使用
const config = {
ibos_sign: true, // 自动添加 ibos 签名
code_sign: true, // 自动添加普通签名
}
types.ts - 基础类型定义定义 API 响应的基础类型结构。
export interface BaseResponse<T = any> {
code: number // 响应状态码
message: string // 响应消息
data: T // 响应数据
}
index.ts - 模块统一导出统一导出所有业务模块,方便在项目中引入使用。
export * from "./modules/common"
export * from "./modules/setting"
export * from "./modules/domain"
export * from "./modules/channel"
export * from "./modules/order"
export * from "./modules/provider"
export * from "./modules/subscription"
export * from "./modules/agent"
export * from "./modules/ai-link"
export * from "./modules/auth"
export * from "./modules/template-style"
export * from "./modules/user"
export * from "./modules/department"
使用方式:
// 统一导入所有模块
import { userApi, agentApi, bannerApi } from "@/api"
// 或者单独导入特定模块
import { userApi } from "@/api/modules/user"
本文档介绍如何基于现有架构开发新的 API 模块,参考 modules/banner 模块的实现模式。
每个新模块应包含以下文件:
src/api/modules/your-module/
├── index.ts # 主要 API 方法
├── your-module.d.ts # TypeScript 类型定义
└── transform.ts # 数据转换工具(可选)
your-module.d.ts)// 定义模块的主要数据类型
export interface YourModule {
id: string
name: string
// ... 其他属性
}
// 定义原始数据格式(如果需要转换)
export type RawYourModule = string | object
// 定义创建/更新时的数据类型
export interface CreateYourModuleRequest {
name: string
// ... 其他必填属性
}
export interface UpdateYourModuleRequest
extends Partial<CreateYourModuleRequest> {
id: string
}
index.ts)import service from "@/api/config"
import { handleError } from "@/api/errorHandler"
import type {
YourModule,
CreateYourModuleRequest,
UpdateYourModuleRequest,
} from "./your-module.d"
export const yourModuleApi = {
// 获取列表
getList(params?: Record<string, unknown>): Promise<YourModule[]> {
return service
.get("/api/your-module", { params })
.then(res => res.data.list)
.catch(handleError)
},
// 获取单个项目
getById(id: string): Promise<YourModule> {
return service
.get(`/api/your-module/${id}`)
.then(res => res.data)
.catch(handleError)
},
// 创建
create(data: CreateYourModuleRequest): Promise<YourModule> {
return service
.post("/api/your-module", data)
.then(res => res.data)
.catch(handleError)
},
// 更新
update(id: string, data: UpdateYourModuleRequest): Promise<YourModule> {
return service
.put(`/api/your-module/${id}`, data)
.then(res => res.data)
.catch(handleError)
},
// 删除
delete(id: string): Promise<void> {
return service
.delete(`/api/your-module/${id}`)
.then(() => {})
.catch(handleError)
},
}
export default yourModuleApi
transform.ts) - 可选当需要处理复杂的数据转换时使用:
import { YOUR_MODULE_CONFIG } from "@/constants/your-module"
import type { YourModule, RawYourModule } from "./your-module.d"
// 获取默认值
export const getDefaultYourModule = (): YourModule => ({
id: "",
name: "",
// ... 其他默认值
})
// 转换原始数据
export function transformYourModule(rawData: RawYourModule): YourModule {
try {
if (typeof rawData === "string") {
const parsed = JSON.parse(rawData)
return {
id: parsed.id || "",
name: parsed.name || "",
// ... 转换其他字段
}
}
return rawData as YourModule
} catch (error) {
console.warn("Failed to transform your module data:", error)
return getDefaultYourModule()
}
}
your-module.ts)yourModuleApi)YourModule)YOUR_MODULE_CONFIG)handleError 进行错误处理.catch(handleError) 捕获并统一处理错误any 类型.then(res => res.data) 提取响应数据res.data.list)Record<string, unknown> 处理动态查询参数import { yourModuleApi } from "@/api/modules/your-module"
// 在 setup 中使用
const {
data: yourModules,
pending,
error,
} = await useAsyncData("your-modules", () => yourModuleApi.getList())
// 创建新项目
const handleCreate = async (formData: CreateYourModuleRequest) => {
try {
const result = await yourModuleApi.create(formData)
ElMessage.success("创建成功")
// 刷新列表
await refresh()
} catch (error) {
// 错误已在 handleError 中处理
console.error("创建失败:", error)
}
}
// stores/modules/your-module.ts
import { yourModuleApi } from "@/api/modules/your-module"
export const useYourModuleStore = defineStore("yourModule", () => {
const yourModules = ref<YourModule[]>([])
const fetchYourModules = async () => {
try {
const data = await yourModuleApi.getList()
yourModules.value = data
} catch (error) {
console.error("获取数据失败:", error)
}
}
return {
yourModules,
fetchYourModules,
}
})
handleError 处理所有错误transform.ts 中constants 目录下通过遵循这些规范,可以确保新模块与现有架构保持一致,提高代码质量和可维护性。