/** * Dify 对话应用管理 API 模块 * * 提供浏览器端调用对话应用管理 API 的函数 * 注意:这些 API 调用的是前端 Remix 路由(/api/...),不需要后端 baseURL * * @module api/dify-chat-apps/chatAppsApi */ import type { ChatApp, MyChatAppsResponse, DefaultChatAppResponse, } from './types'; /** * API 基础 URL(前端 Remix 路由) */ const API_URL = '/api/v3/dify/chat-apps'; /** * HTTP 状态码对应的友好错误信息 */ const HTTP_ERROR_MESSAGES: Record = { 400: '请求参数错误', 401: '登录已过期,请重新登录', 403: '您没有权限执行此操作', 404: '请求的资源不存在', 409: '数据冲突,该记录可能已存在', 500: '服务器内部错误,请稍后重试', 502: '网关错误,请稍后重试', 503: '服务暂时不可用,请稍后重试', }; /** * 封装 fetch 请求,自动处理 credentials */ async function request(url: string, options: RequestInit = {}): Promise { const response = await fetch(url, { ...options, credentials: 'include', // 包含 cookies headers: { 'Content-Type': 'application/json', ...options.headers, }, }); if (!response.ok) { const errorData = await response.json().catch(() => ({})); // 优先使用后端返回的错误信息,否则使用友好的默认信息 const friendlyMessage = errorData.message || errorData.error || HTTP_ERROR_MESSAGES[response.status] || '操作失败,请稍后重试'; const error = new Error(friendlyMessage); (error as any).response = { status: response.status, data: errorData }; throw error; } return response.json(); } /** * 获取当前实例配置的对话应用列表 * * 根据用户角色自动返回对应数据范围: * - provincial_admin: 全部可用应用 * - admin/common: 本地区可用应用 * * @returns 用户可访问的对话应用列表 */ export async function getMyChatApps(): Promise { const response = await request(`${API_URL}/my`); // 兼容嵌套格式 { data: { data: [], total: ... } } if (response?.data?.data) { return { data: response.data.data, total: response.data.total || 0, page: response.data.page || 1, page_size: response.data.page_size || 10, }; } // 格式 { data: [], total: ... } if (response?.data && Array.isArray(response.data)) { return response as MyChatAppsResponse; } // 直接返回 if (Array.isArray(response?.data)) { return { data: response.data, total: response.data.length, page: 1, page_size: response.data.length, }; } console.warn('[API] getMyChatApps: 无效的响应格式', response); return { data: [], total: 0, page: 1, page_size: 10 }; } /** * 获取默认对话应用 * * 返回配置文件中的第一个应用作为默认应用 * * @returns 默认对话应用 */ export async function getDefaultChatApp(): Promise { const response = await request(`${API_URL}/default`); // 兼容嵌套格式 { data: { data: {...} } } if (response?.data?.data) { return { data: response.data.data, }; } // 格式 { data: {...} } if (response?.data) { return { data: response.data, }; } console.warn('[API] getDefaultChatApp: 无效的响应格式', response); throw new Error('获取默认对话应用失败'); }