494 lines
14 KiB
TypeScript
494 lines
14 KiB
TypeScript
import { useUserData } from "./useUserData";
|
|
import { useEffect, useState, useCallback } from "react";
|
|
import logger from "@/utils/logger";
|
|
import type { IUserInfo, ISystemStatus } from "@/interfaces/database/user-setting";
|
|
import userService from "@/services/user_service";
|
|
import { rsaPsw } from "../utils/encryption";
|
|
import type { IFactory, IMyLlmModel } from "@/interfaces/database/llm";
|
|
import type { LLMFactory } from "@/constants/llm";
|
|
import type { IMcpServer, IMcpServerListResponse } from "@/interfaces/database/mcp";
|
|
import type { IImportMcpServersRequestBody, ITestMcpRequestBody, ICreateMcpServerRequestBody } from "@/interfaces/request/mcp";
|
|
import type { IPaginationBody } from "@/interfaces/request/base";
|
|
|
|
/**
|
|
* 个人中心设置
|
|
*/
|
|
export function useProfileSetting() {
|
|
const { fetchUserInfo, userInfo } = useUserData();
|
|
|
|
useEffect(() => {
|
|
fetchUserInfo();
|
|
}, [fetchUserInfo]);
|
|
|
|
const updateUserInfo = async (newUserInfo: Partial<IUserInfo>) => {
|
|
try {
|
|
await userService.updateSetting(newUserInfo);
|
|
} catch (error) {
|
|
logger.error('更新用户信息失败:', error);
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
const changeUserPassword = async (data: { password: string; new_password: string }) => {
|
|
try {
|
|
const newPassword = rsaPsw(data.new_password);
|
|
const oldPassword = rsaPsw(data.password);
|
|
const res = await userService.updatePassword({
|
|
password: oldPassword,
|
|
new_password: newPassword,
|
|
});
|
|
} catch (error) {
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
return {
|
|
userInfo,
|
|
updateUserInfo,
|
|
changeUserPassword,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* LLM 模型设置
|
|
*/
|
|
export function useLlmModelSetting() {
|
|
const [llmFactory, setLlmFactory] = useState<IFactory[]>([]);
|
|
const [myLlm, setMyLlm] = useState<Record<LLMFactory, IMyLlmModel>>();
|
|
|
|
const fetchLlmFactory = async () => {
|
|
try {
|
|
const res = await userService.llm_factories_list();
|
|
const arr = res.data.data || [];
|
|
setLlmFactory(arr);
|
|
} catch (error) {
|
|
logger.error('获取模型工厂失败:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
const fetchMyLlm = async () => {
|
|
try {
|
|
const res = await userService.my_llm({include_details: true});
|
|
const llm_dic = res.data.data || {};
|
|
setMyLlm(llm_dic);
|
|
} catch (error) {
|
|
logger.error('获取我的模型失败:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
useEffect(() => {
|
|
fetchLlmFactory();
|
|
fetchMyLlm();
|
|
}, []);
|
|
|
|
const refreshLlmModel = async () => {
|
|
await fetchMyLlm();
|
|
// await fetchLlmFactory();
|
|
logger.info('刷新我的模型成功');
|
|
}
|
|
|
|
return {
|
|
llmFactory,
|
|
myLlm,
|
|
refreshLlmModel,
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 系统状态设置
|
|
*/
|
|
export function useSystemStatus() {
|
|
const [systemStatus, setSystemStatus] = useState<ISystemStatus | null>(null);
|
|
const [loading, setLoading] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
const fetchSystemStatus = useCallback(async () => {
|
|
try {
|
|
setLoading(true);
|
|
setError(null);
|
|
const res = await userService.system_status();
|
|
if (res.data.code === 0) {
|
|
setSystemStatus(res.data.data);
|
|
} else {
|
|
throw new Error(res.data.message || '获取系统状态失败');
|
|
}
|
|
} catch (error: any) {
|
|
const errorMessage = error.response?.data?.message || error.message || '获取系统状态失败';
|
|
setError(errorMessage);
|
|
logger.error('获取系统状态失败:', error);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
return {
|
|
systemStatus,
|
|
loading,
|
|
error,
|
|
fetchSystemStatus,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 团队设置
|
|
*/
|
|
export function useTeamSetting() {
|
|
const { userInfo, tenantInfo, tenantList, refreshUserData } = useUserData();
|
|
const [tenantUsers, setTenantUsers] = useState<any[]>([]);
|
|
const [loading, setLoading] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
// 获取租户用户列表
|
|
const fetchTenantUsers = useCallback(async () => {
|
|
if (!tenantInfo?.tenant_id) return;
|
|
|
|
try {
|
|
const response = await userService.listTenantUser(tenantInfo.tenant_id);
|
|
if (response.data.code === 0) {
|
|
setTenantUsers(response.data.data || []);
|
|
}
|
|
} catch (error) {
|
|
logger.error('获取租户用户失败:', error);
|
|
}
|
|
}, [tenantInfo?.tenant_id]);
|
|
|
|
useEffect(() => {
|
|
if (tenantInfo?.tenant_id) {
|
|
fetchTenantUsers();
|
|
}
|
|
}, [fetchTenantUsers]);
|
|
|
|
const inviteUser = async (email: string) => {
|
|
if (!email.trim() || !tenantInfo?.tenant_id) return;
|
|
|
|
setLoading(true);
|
|
setError(null);
|
|
|
|
try {
|
|
const response = await userService.addTenantUser(tenantInfo.tenant_id, email.trim());
|
|
if (response.data.code === 0) {
|
|
await fetchTenantUsers();
|
|
await refreshUserData();
|
|
return { success: true };
|
|
} else {
|
|
const errorMsg = response.data.message || '邀请失败';
|
|
setError(errorMsg);
|
|
return { success: false, error: errorMsg };
|
|
}
|
|
} catch (error: any) {
|
|
const errorMsg = error.message || '邀请失败';
|
|
setError(errorMsg);
|
|
return { success: false, error: errorMsg };
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
const deleteUser = async (userId: string) => {
|
|
if (!tenantInfo?.tenant_id) return;
|
|
|
|
try {
|
|
const response = await userService.deleteTenantUser({
|
|
tenantId: tenantInfo.tenant_id,
|
|
userId
|
|
});
|
|
if (response.data.code === 0) {
|
|
await fetchTenantUsers();
|
|
return { success: true };
|
|
}
|
|
return { success: false };
|
|
} catch (error) {
|
|
logger.error('删除用户失败:', error);
|
|
return { success: false };
|
|
}
|
|
};
|
|
|
|
const agreeTenant = async (tenantId: string) => {
|
|
try {
|
|
const response = await userService.agreeTenant(tenantId);
|
|
if (response.data.code === 0) {
|
|
await refreshUserData();
|
|
return { success: true };
|
|
}
|
|
return { success: false };
|
|
} catch (error) {
|
|
logger.error('同意加入失败:', error);
|
|
return { success: false };
|
|
}
|
|
};
|
|
|
|
const quitTenant = async (tenantId: string) => {
|
|
if (!userInfo?.id) return;
|
|
|
|
try {
|
|
const response = await userService.deleteTenantUser({
|
|
tenantId,
|
|
userId: userInfo.id
|
|
});
|
|
if (response.data.code === 0) {
|
|
await refreshUserData();
|
|
return { success: true };
|
|
}
|
|
return { success: false };
|
|
} catch (error) {
|
|
logger.error('退出租户失败:', error);
|
|
return { success: false };
|
|
}
|
|
};
|
|
|
|
return {
|
|
userInfo,
|
|
tenantInfo,
|
|
tenantList,
|
|
tenantUsers,
|
|
loading,
|
|
error,
|
|
inviteUser,
|
|
deleteUser,
|
|
agreeTenant,
|
|
quitTenant,
|
|
refreshUserData,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* MCP 设置
|
|
*/
|
|
export function useMcpSetting({ refreshServer }: { refreshServer: (initial?: boolean) => Promise<void> }) {
|
|
const [mcpServers, setMcpServers] = useState<IMcpServer[]>([]);
|
|
const [loading, setLoading] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
const [total, setTotal] = useState(0);
|
|
|
|
// 获取 MCP 服务器列表
|
|
const fetchMcpServers = useCallback(async (params?: IPaginationBody & {
|
|
keyword?: string;
|
|
}) => {
|
|
try {
|
|
setLoading(true);
|
|
setError(null);
|
|
const res = await userService.listMcpServer({
|
|
page: params?.page || 1,
|
|
size: params?.size || 8,
|
|
keyword: params?.keyword,
|
|
});
|
|
if (res.data.code === 0) {
|
|
const data: IMcpServerListResponse = res.data.data;
|
|
setMcpServers(data.mcp_servers || []);
|
|
setTotal(data.total || 0);
|
|
} else {
|
|
throw new Error(res.data.message || '获取 MCP 服务器列表失败');
|
|
}
|
|
} catch (error: any) {
|
|
const errorMessage = error.response?.data?.message || error.message || '获取 MCP 服务器列表失败';
|
|
setError(errorMessage);
|
|
logger.error('获取 MCP 服务器列表失败:', error);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
// 导入 MCP 服务器
|
|
const importMcpServers = useCallback(async (data: IImportMcpServersRequestBody) => {
|
|
try {
|
|
setLoading(true);
|
|
setError(null);
|
|
const res = await userService.importMcpServer(data);
|
|
if (res.data.code === 0) {
|
|
await refreshServer();
|
|
return { success: true };
|
|
} else {
|
|
throw new Error(res.data.message || '导入 MCP 服务器失败');
|
|
}
|
|
} catch (error: any) {
|
|
const errorMessage = error.response?.data?.message || error.message || '导入 MCP 服务器失败';
|
|
setError(errorMessage);
|
|
logger.error('导入 MCP 服务器失败:', error);
|
|
return { success: false, error: errorMessage };
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
// 导出 MCP 服务器
|
|
const exportMcpServers = useCallback(async (mcpIds: string[]) => {
|
|
try {
|
|
setLoading(true);
|
|
setError(null);
|
|
const res = await userService.exportMcpServer(mcpIds);
|
|
if (res.data.code === 0) {
|
|
// 处理导出数据,创建下载
|
|
const exportData = res.data.data;
|
|
const blob = new Blob([JSON.stringify(exportData, null, 2)], { type: 'application/json' });
|
|
const url = URL.createObjectURL(blob);
|
|
const a = document.createElement('a');
|
|
a.href = url;
|
|
a.download = 'mcp-servers.json';
|
|
a.click();
|
|
URL.revokeObjectURL(url);
|
|
return { success: true };
|
|
} else {
|
|
throw new Error(res.data.message || '导出 MCP 服务器失败');
|
|
}
|
|
} catch (error: any) {
|
|
const errorMessage = error.response?.data?.message || error.message || '导出 MCP 服务器失败';
|
|
setError(errorMessage);
|
|
logger.error('导出 MCP 服务器失败:', error);
|
|
return { success: false, error: errorMessage };
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
// 测试 MCP 服务器
|
|
const testMcpServer = useCallback(async (data: ITestMcpRequestBody) => {
|
|
try {
|
|
setLoading(true);
|
|
setError(null);
|
|
const res = await userService.testMcpServer(data);
|
|
if (res.data.code === 0) {
|
|
return { success: true, data: res.data.data };
|
|
} else {
|
|
throw new Error(res.data.message || '测试 MCP 服务器失败');
|
|
}
|
|
} catch (error: any) {
|
|
const errorMessage = error.response?.data?.message || error.message || '测试 MCP 服务器失败';
|
|
setError(errorMessage);
|
|
return { success: false, error: errorMessage };
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
// 获取 MCP 服务器详情
|
|
const getMcpServerDetail = useCallback(async (mcpId: string) => {
|
|
try {
|
|
setLoading(true);
|
|
setError(null);
|
|
const res = await userService.mcpDetail(mcpId);
|
|
if (res.data.code === 0) {
|
|
const detail: IMcpServer = res.data.data;
|
|
return { success: true, data: detail };
|
|
} else {
|
|
throw new Error(res.data.message || '获取 MCP 服务器详情失败');
|
|
}
|
|
} catch (error: any) {
|
|
const errorMessage = error.response?.data?.message || error.message || '获取 MCP 服务器详情失败';
|
|
setError(errorMessage);
|
|
logger.error('获取 MCP 服务器详情失败:', error);
|
|
return { success: false, error: errorMessage };
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
// 创建 MCP 服务器
|
|
const createMcpServer = useCallback(async (data: ICreateMcpServerRequestBody) => {
|
|
try {
|
|
setLoading(true);
|
|
setError(null);
|
|
const res = await userService.createMcpServer(data);
|
|
if (res.data.code === 0) {
|
|
await refreshServer(true); // 重新获取列表
|
|
return { success: true, data: res.data.data };
|
|
} else {
|
|
throw new Error(res.data.message || '创建 MCP 服务器失败');
|
|
}
|
|
} catch (error: any) {
|
|
const errorMessage = error.response?.data?.message || error.message || '创建 MCP 服务器失败';
|
|
setError(errorMessage);
|
|
logger.error('创建 MCP 服务器失败:', error);
|
|
return { success: false, error: errorMessage };
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
// 更新 MCP 服务器
|
|
const updateMcpServer = useCallback(async (data: ICreateMcpServerRequestBody & { mcp_id: string }) => {
|
|
try {
|
|
setLoading(true);
|
|
setError(null);
|
|
const res = await userService.updateMcpServer(data);
|
|
if (res.data.code === 0) {
|
|
await refreshServer(); // 刷新列表
|
|
return { success: true, data: res.data.data };
|
|
} else {
|
|
throw new Error(res.data.message || '更新 MCP 服务器失败');
|
|
}
|
|
} catch (error: any) {
|
|
const errorMessage = error.response?.data?.message || error.message || '更新 MCP 服务器失败';
|
|
setError(errorMessage);
|
|
logger.error('更新 MCP 服务器失败:', error);
|
|
return { success: false, error: errorMessage };
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
// 删除 MCP 服务器
|
|
const deleteMcpServer = useCallback(async (mcpId: string) => {
|
|
try {
|
|
setLoading(true);
|
|
setError(null);
|
|
const res = await userService.removeMcpServer([mcpId]);
|
|
if (res.data.code === 0) {
|
|
await refreshServer(); // 刷新列表
|
|
return { success: true };
|
|
} else {
|
|
throw new Error(res.data.message || '删除 MCP 服务器失败');
|
|
}
|
|
} catch (error: any) {
|
|
const errorMessage = error.response?.data?.message || error.message || '删除 MCP 服务器失败';
|
|
setError(errorMessage);
|
|
logger.error('删除 MCP 服务器失败:', error);
|
|
return { success: false, error: errorMessage };
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
// 批量删除 MCP 服务器
|
|
const batchDeleteMcpServers = useCallback(async (mcpIds: string[]) => {
|
|
try {
|
|
setLoading(true);
|
|
setError(null);
|
|
const res = await userService.removeMcpServer(mcpIds);
|
|
if (res.data.code === 0) {
|
|
await fetchMcpServers(); // 重新获取列表
|
|
return { success: true };
|
|
} else {
|
|
throw new Error(res.data.message || '批量删除 MCP 服务器失败');
|
|
}
|
|
} catch (error: any) {
|
|
const errorMessage = error.response?.data?.message || error.message || '批量删除 MCP 服务器失败';
|
|
setError(errorMessage);
|
|
logger.error('批量删除 MCP 服务器失败:', error);
|
|
return { success: false, error: errorMessage };
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
return {
|
|
// 状态
|
|
mcpServers,
|
|
loading,
|
|
error,
|
|
total,
|
|
|
|
// 方法
|
|
fetchMcpServers,
|
|
importMcpServers,
|
|
exportMcpServers,
|
|
testMcpServer,
|
|
getMcpServerDetail,
|
|
createMcpServer,
|
|
updateMcpServer,
|
|
deleteMcpServer,
|
|
batchDeleteMcpServers,
|
|
};
|
|
}
|
|
|