3f5c23123b
- 新增对话应用管理模块(dify-chat-apps),支持获取和切换对话应用 - 优化对话应用切换后自动刷新会话列表功能 - 知识库管理页面新增下拉选择器,支持切换不同知识库 - API 层支持 app_id 参数传递,实现多应用会话隔离 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
128 lines
3.6 KiB
TypeScript
128 lines
3.6 KiB
TypeScript
/**
|
|
* 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<number, string> = {
|
|
400: '请求参数错误',
|
|
401: '登录已过期,请重新登录',
|
|
403: '您没有权限执行此操作',
|
|
404: '请求的资源不存在',
|
|
409: '数据冲突,该记录可能已存在',
|
|
500: '服务器内部错误,请稍后重试',
|
|
502: '网关错误,请稍后重试',
|
|
503: '服务暂时不可用,请稍后重试',
|
|
};
|
|
|
|
/**
|
|
* 封装 fetch 请求,自动处理 credentials
|
|
*/
|
|
async function request<T>(url: string, options: RequestInit = {}): Promise<T> {
|
|
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<MyChatAppsResponse> {
|
|
const response = await request<any>(`${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<DefaultChatAppResponse> {
|
|
const response = await request<any>(`${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('获取默认对话应用失败');
|
|
}
|