diff --git a/.env.development b/.env.development index d18552f6..0f8ba8ef 100644 --- a/.env.development +++ b/.env.development @@ -6,9 +6,9 @@ VITE_APP_TITLE=vue3-element-admin VITE_APP_BASE_API=/dev-api # 接口地址 -VITE_APP_API_URL=https://api.youlai.tech # 线上 +# VITE_APP_API_URL=https://api.youlai.tech # 线上 # VITE_APP_API_URL=https://api.youlai.tech/v2 # 线上(多租户) -# VITE_APP_API_URL=http://localhost:8000 # 本地 +VITE_APP_API_URL=http://localhost:8000 # 本地 # WebSocket 端点(不配置则关闭) # 线上: ws://api.youlai.tech/ws diff --git a/src/App.vue b/src/App.vue index 09364fa3..3facc76a 100644 --- a/src/App.vue +++ b/src/App.vue @@ -8,36 +8,23 @@ class="wh-full" > - - - - - diff --git a/src/composables/ai/useAiAction.ts b/src/composables/ai/useAiAction.ts deleted file mode 100644 index 1b505716..00000000 --- a/src/composables/ai/useAiAction.ts +++ /dev/null @@ -1,269 +0,0 @@ -import { useRoute } from "vue-router"; -import { ElMessage, ElMessageBox } from "element-plus"; -import { onMounted, onBeforeUnmount, nextTick } from "vue"; -import AiCommandApi from "@/api/ai"; - -/** - * AI 操作处理器(简化版) - * - * 可以是简单函数,也可以是配置对象 - */ -export type AiActionHandler = - | ((args: T) => Promise | void) - | { - /** 执行函数 */ - execute: (args: T) => Promise | void; - /** 是否需要确认(默认 true) */ - needConfirm?: boolean; - /** 确认消息(支持函数或字符串) */ - confirmMessage?: string | ((args: T) => string); - /** 成功消息(支持函数或字符串) */ - successMessage?: string | ((args: T) => string); - /** 是否调用后端 API(默认 false,如果为 true 则自动调用 executeCommand) */ - callBackendApi?: boolean; - }; - -/** - * AI 操作配置 - */ -export interface UseAiActionOptions { - /** 操作映射表:函数名 -> 处理器 */ - actionHandlers?: Record; - /** 数据刷新函数(操作完成后调用) */ - onRefresh?: () => Promise | void; - /** 自动搜索处理函数 */ - onAutoSearch?: (keywords: string) => void; - /** 当前路由路径(用于执行命令时传递) */ - currentRoute?: string; -} - -/** - * AI 操作 Composable - * - * 统一处理 AI 助手传递的操作,支持: - * - 自动搜索(通过 keywords + autoSearch 参数) - * - 执行 AI 操作(通过 aiAction 参数) - * - 配置化的操作处理器 - */ -export function useAiAction(options: UseAiActionOptions = {}) { - const route = useRoute(); - const { actionHandlers = {}, onRefresh, onAutoSearch, currentRoute = route.path } = options; - - // 用于跟踪是否已卸载,防止在卸载后执行回调 - let isUnmounted = false; - - /** - * 执行 AI 操作(统一处理确认、执行、反馈流程) - */ - async function executeAiAction(action: any) { - if (isUnmounted) return; - - // 兼容两种入参:{ functionName, arguments } 或 { functionCall: { name, arguments } } - const fnCall = action.functionCall ?? { - name: action.functionName, - arguments: action.arguments, - }; - - if (!fnCall?.name) { - ElMessage.warning("未识别的 AI 操作"); - return; - } - - // 查找对应的处理器 - const handler = actionHandlers[fnCall.name]; - if (!handler) { - ElMessage.warning(`暂不支持操作: ${fnCall.name}`); - return; - } - - try { - // 判断处理器类型(函数 or 配置对象) - const isSimpleFunction = typeof handler === "function"; - - if (isSimpleFunction) { - // 简单函数形式:直接执行 - await handler(fnCall.arguments); - } else { - // 配置对象形式:统一处理确认、执行、反馈 - const config = handler; - - // 1. 确认阶段(默认需要确认) - if (config.needConfirm !== false) { - const confirmMsg = - typeof config.confirmMessage === "function" - ? config.confirmMessage(fnCall.arguments) - : config.confirmMessage || "确认执行此操作吗?"; - - await ElMessageBox.confirm(confirmMsg, "AI 助手操作确认", { - confirmButtonText: "确认执行", - cancelButtonText: "取消", - type: "warning", - dangerouslyUseHTMLString: true, - }); - } - - // 2. 执行阶段 - if (config.callBackendApi) { - // 自动调用后端 API - await AiCommandApi.executeCommand({ - originalCommand: action.originalCommand || "", - confirmMode: "manual", - userConfirmed: true, - currentRoute, - functionCall: { - name: fnCall.name, - arguments: fnCall.arguments, - }, - }); - } else { - // 执行自定义函数 - await config.execute(fnCall.arguments); - } - - // 3. 成功反馈 - const successMsg = - typeof config.successMessage === "function" - ? config.successMessage(fnCall.arguments) - : config.successMessage || "操作执行成功"; - ElMessage.success(successMsg); - } - - // 4. 刷新数据 - if (onRefresh) { - await onRefresh(); - } - } catch (error: any) { - // 处理取消操作 - if (error === "cancel") { - ElMessage.info("已取消操作"); - return; - } - - console.error("AI 操作执行失败:", error); - ElMessage.error(error.message || "操作执行失败"); - } - } - - /** - * 执行后端命令(通用方法) - */ - async function executeCommand( - functionName: string, - args: any, - options: { - originalCommand?: string; - confirmMode?: "auto" | "manual"; - needConfirm?: boolean; - confirmMessage?: string; - } = {} - ) { - const { - originalCommand = "", - confirmMode = "manual", - needConfirm = false, - confirmMessage, - } = options; - - // 如果需要确认,先显示确认对话框 - if (needConfirm && confirmMessage) { - try { - await ElMessageBox.confirm(confirmMessage, "AI 助手操作确认", { - confirmButtonText: "确认执行", - cancelButtonText: "取消", - type: "warning", - dangerouslyUseHTMLString: true, - }); - } catch { - ElMessage.info("已取消操作"); - return; - } - } - - try { - await AiCommandApi.executeCommand({ - originalCommand, - confirmMode, - userConfirmed: true, - currentRoute, - functionCall: { - name: functionName, - arguments: args, - }, - }); - - ElMessage.success("操作执行成功"); - } catch (error: any) { - if (error !== "cancel") { - throw error; - } - } - } - - /** - * 处理自动搜索 - */ - function handleAutoSearch(keywords: string) { - if (onAutoSearch) { - onAutoSearch(keywords); - } else { - ElMessage.info(`AI 助手已为您自动搜索:${keywords}`); - } - } - - /** - * 初始化:处理 URL 参数中的 AI 操作 - * - * 注意:此方法只处理 AI 相关参数,不负责页面数据的初始加载 - * 页面数据加载应由组件的 onMounted 钩子自行处理 - */ - async function init() { - if (isUnmounted) return; - - // 检查是否有 AI 助手传递的参数 - const keywords = route.query.keywords as string; - const autoSearch = route.query.autoSearch as string; - const aiActionParam = route.query.aiAction as string; - - // 如果没有任何 AI 参数,直接返回 - if (!keywords && !autoSearch && !aiActionParam) { - return; - } - - // 在 nextTick 中执行,确保页面数据已加载 - nextTick(async () => { - if (isUnmounted) return; - - // 1. 处理自动搜索 - if (autoSearch === "true" && keywords) { - handleAutoSearch(keywords); - } - - // 2. 处理 AI 操作 - if (aiActionParam) { - try { - const aiAction = JSON.parse(decodeURIComponent(aiActionParam)); - await executeAiAction(aiAction); - } catch (error) { - console.error("解析 AI 操作失败:", error); - ElMessage.error("AI 操作参数解析失败"); - } - } - }); - } - - // 组件挂载时自动初始化 - onMounted(() => { - init(); - }); - - // 组件卸载时清理 - onBeforeUnmount(() => { - isUnmounted = true; - }); - - return { - executeAiAction, - executeCommand, - handleAutoSearch, - }; -} diff --git a/src/composables/index.ts b/src/composables/index.ts index f55308da..086f473a 100644 --- a/src/composables/index.ts +++ b/src/composables/index.ts @@ -3,9 +3,5 @@ export { setupWebSocket, cleanupWebSocket } from "./websocket"; export { useStomp, useDictSync, useOnlineCount } from "./websocket"; export type { DictMessage, DictChangeMessage, DictChangeCallback } from "./websocket"; -// AI 相关 -export { useAiAction } from "./ai/useAiAction"; -export type { UseAiActionOptions, AiActionHandler } from "./ai/useAiAction"; - // 表格相关 export { useTableSelection } from "./table/useTableSelection"; diff --git a/src/constants/index.ts b/src/constants/index.ts index 4b287120..fa20dcab 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -51,7 +51,6 @@ export const STORAGE_KEYS = { SHOW_APP_LOGO: `${APP_PREFIX}:ui:show_app_logo`, SHOW_WATERMARK: `${APP_PREFIX}:ui:show_watermark`, PAGE_SWITCHING_ANIMATION: `${APP_PREFIX}:ui:page_switching_animation`, - ENABLE_AI_ASSISTANT: `${APP_PREFIX}:ui:enable_ai_assistant`, LAYOUT: `${APP_PREFIX}:ui:layout`, SIDEBAR_COLOR_SCHEME: `${APP_PREFIX}:ui:sidebar_color_scheme`, THEME: `${APP_PREFIX}:ui:theme`, diff --git a/src/layouts/components/LayoutSettings.vue b/src/layouts/components/LayoutSettings.vue index a1f69e94..edac55a2 100644 --- a/src/layouts/components/LayoutSettings.vue +++ b/src/layouts/components/LayoutSettings.vue @@ -71,11 +71,6 @@ -
- AI 助手 - -
-
{{ t("settings.sidebarColorScheme") }} diff --git a/src/store/modules/settings.ts b/src/store/modules/settings.ts index 1b379b7d..a3e11a0b 100644 --- a/src/store/modules/settings.ts +++ b/src/store/modules/settings.ts @@ -30,10 +30,6 @@ export const useSettingsStore = defineStore("setting", () => { const grayMode = useStorage(STORAGE_KEYS.GRAY_MODE, false); const colorWeak = useStorage(STORAGE_KEYS.COLOR_WEAK, false); - // AI 助手:用户级开关(默认开启) - const userEnableAi = useStorage(STORAGE_KEYS.ENABLE_AI_ASSISTANT, true); - const enableAiAssistant = computed(() => userEnableAi.value); - // 主题变化监听 watch( [theme, themeColor], @@ -71,7 +67,6 @@ export const useSettingsStore = defineStore("setting", () => { showAppLogo.value = defaults.showAppLogo; showWatermark.value = defaults.showWatermark; pageSwitchingAnimation.value = defaults.pageSwitchingAnimation; - userEnableAi.value = false; grayMode.value = false; colorWeak.value = false; sidebarColorScheme.value = defaults.sidebarColorScheme; @@ -86,8 +81,6 @@ export const useSettingsStore = defineStore("setting", () => { showAppLogo, showWatermark, pageSwitchingAnimation, - enableAiAssistant, - userEnableAi, grayMode, colorWeak, sidebarColorScheme, diff --git a/src/types/api/ai.ts b/src/types/api/ai.ts deleted file mode 100644 index f893e7a2..00000000 --- a/src/types/api/ai.ts +++ /dev/null @@ -1,151 +0,0 @@ -/** - * AI 模块类型定义 - */ - -import type { BaseQueryParams } from "./common"; - -/** AI命令请求参数 */ -export interface AiCommandRequest { - /** 用户输入的自然语言命令 */ - command: string; - /** 当前页面路由(用于上下文) */ - currentRoute?: string; - /** 当前激活的组件名称 */ - currentComponent?: string; - /** 额外上下文信息 */ - context?: Record; -} - -/** 函数调用参数 */ -export interface FunctionCall { - /** 函数名称 */ - name: string; - /** 函数描述 */ - description?: string; - /** 参数对象 */ - arguments: Record; -} - -/** AI命令解析响应 */ -export interface AiCommandResponse { - /** 解析日志ID(用于关联执行记录) */ - parseLogId?: string; - /** 是否成功解析 */ - success: boolean; - /** 解析后的函数调用列表 */ - functionCalls: FunctionCall[]; - /** AI的理解和说明 */ - explanation?: string; - /** 置信度(0-1) */ - confidence?: number; - /** 错误信息 */ - error?: string; - /** 原始LLM响应(用于调试) */ - rawResponse?: string; -} - -/** AI命令执行请求 */ -export interface AiExecuteRequest { - /** 关联的解析日志ID */ - parseLogId?: string; - /** 原始命令(用于审计) */ - originalCommand?: string; - /** 要执行的函数调用 */ - functionCall: FunctionCall; - /** 确认模式:auto=自动执行, manual=需要用户确认 */ - confirmMode?: "auto" | "manual"; - /** 用户确认标志 */ - userConfirmed?: boolean; - /** 幂等性令牌(防止重复执行) */ - idempotencyKey?: string; - /** 当前页面路由 */ - currentRoute?: string; -} - -/** AI命令执行响应 */ -export interface AiExecuteResponse { - /** 是否执行成功 */ - success: boolean; - /** 执行结果数据 */ - data?: any; - /** 执行结果说明 */ - message?: string; - /** 影响的记录数 */ - affectedRows?: number; - /** 错误信息 */ - error?: string; - /** 记录ID(用于追踪) */ - recordId?: string; - /** 需要用户确认 */ - requiresConfirmation?: boolean; - /** 确认提示信息 */ - confirmationPrompt?: string; -} - -/** AI命令记录分页查询参数 */ -export interface AiAssistantRecordQueryParams extends BaseQueryParams { - /** 搜索关键字 */ - keywords?: string; - /** 执行状态 */ - status?: string; - /** 执行状态(0:待执行;1:成功;-1:失败) */ - executeStatus?: number; - /** 解析状态 */ - parseStatus?: number; - /** 用户ID */ - userId?: number; - /** AI提供商 */ - aiProvider?: string; - /** AI模型 */ - aiModel?: string; - /** 函数名称 */ - functionName?: string; - /** 创建时间 */ - createTime?: [string, string]; -} - -/** AI命令记录视图对象 */ -export interface AiAssistantRecordItem { - /** 记录ID */ - id: string; - /** 用户ID */ - userId: number; - /** 用户名 */ - username: string; - /** 原始命令 */ - originalCommand: string; - /** AI提供商 */ - aiProvider?: string; - /** AI模型 */ - aiModel?: string; - /** 解析状态 */ - parseStatus?: number; - /** 函数调用列表 */ - functionCalls?: string; - /** 解析说明 */ - explanation?: string; - /** 置信度 */ - confidence?: number; - /** 解析错误信息 */ - parseErrorMessage?: string; - /** 输入Token数 */ - inputTokens?: number; - /** 输出Token数 */ - outputTokens?: number; - /** 解析耗时(毫秒) */ - parseDurationMs?: number; - /** 函数名称 */ - functionName?: string; - /** 函数参数 */ - functionArguments?: string; - /** 执行状态 */ - executeStatus?: number; - /** 执行错误信息 */ - executeErrorMessage?: string; - /** IP地址 */ - ipAddress?: string; - /** 创建时间 */ - createTime?: string; - /** 更新时间 */ - updateTime?: string; -} diff --git a/src/types/api/index.ts b/src/types/api/index.ts index 8bdfec3e..f0f0f07a 100644 --- a/src/types/api/index.ts +++ b/src/types/api/index.ts @@ -19,6 +19,5 @@ export * from "./tenant"; export * from "./tenant-plan"; // 其他模块 -export * from "./ai"; export * from "./file"; export * from "./codegen"; diff --git a/src/types/components.d.ts b/src/types/components.d.ts index 1d7b15de..ea79667a 100644 --- a/src/types/components.d.ts +++ b/src/types/components.d.ts @@ -6,12 +6,11 @@ // Generated by unplugin-vue-components // Read more: https://github.com/vuejs/core/pull/3399 -export {} +export {}; /* prettier-ignore */ declare module 'vue' { export interface GlobalComponents { - AiAssistant: typeof import('./../components/AiAssistant/index.vue')['default'] AppLink: typeof import('./../components/AppLink/index.vue')['default'] Breadcrumb: typeof import('./../components/Breadcrumb/index.vue')['default'] CommandPalette: typeof import('./../components/CommandPalette/index.vue')['default'] diff --git a/src/types/ui/settings.ts b/src/types/ui/settings.ts index 7020e8b2..b4df2368 100644 --- a/src/types/ui/settings.ts +++ b/src/types/ui/settings.ts @@ -18,5 +18,4 @@ export interface AppSettings { showWatermark: boolean; watermarkContent: string; sidebarColorScheme: "classic-blue" | "minimal-white"; - enableAiAssistant: boolean; } diff --git a/src/views/ai/index.vue b/src/views/ai/index.vue deleted file mode 100644 index 5cee8c39..00000000 --- a/src/views/ai/index.vue +++ /dev/null @@ -1,374 +0,0 @@ - - - - - diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue index 8199b12a..e5a0aeb2 100644 --- a/src/views/system/user/index.vue +++ b/src/views/system/user/index.vue @@ -270,7 +270,7 @@ import { useUserStore, useAppStore } from "@/store"; import { DeviceEnum, DialogMode, CommonStatus } from "@/enums"; // ==================== 7. Composables ==================== -import { useAiAction, useTableSelection } from "@/composables"; +import { useTableSelection } from "@/composables"; // ==================== 8. 组件 ==================== import UserDeptTree from "./components/UserDeptTree.vue"; @@ -561,51 +561,6 @@ async function handleExport(): Promise { } } -// ==================== AI 助手相关 ==================== -useAiAction({ - actionHandlers: { - /** - * AI 修改用户昵称 - * 使用配置对象方式:自动处理确认、执行、反馈 - */ - updateUserNickname: { - needConfirm: true, - callBackendApi: true, - confirmMessage: (args: any) => - `AI 助手将执行以下操作:
- 修改用户: ${args.username}
- 新昵称: ${args.nickname}

- 确认执行吗?`, - successMessage: (args: any) => `已将用户 ${args.username} 的昵称修改为 ${args.nickname}`, - execute: async () => { - // callBackendApi=true 时,execute 可以为空 - // Composable 会自动调用后端 API - }, - }, - - /** - * AI 查询用户 - * 使用配置对象方式:查询操作不需要确认 - */ - queryUser: { - needConfirm: false, // 查询操作无需确认 - successMessage: (args: any) => `已搜索:${args.keywords}`, - execute: async (args: any) => { - queryParams.keywords = args.keywords; - await handleQuery(); - }, - }, - }, - onRefresh: fetchUserList, - onAutoSearch: (keywords: string) => { - queryParams.keywords = keywords; - setTimeout(() => { - handleQuery(); - ElMessage.success(`AI 助手已为您自动搜索:${keywords}`); - }, 300); - }, -}); - // ==================== 生命周期 ==================== /**