Files
TERES_web_frontend/src/hooks/setting-hooks.ts

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,
};
}