import { defineStore } from 'pinia' import { computed, ref } from 'vue' import type { Router } from 'vue-router' import axios from 'axios' import { t } from '../i18n' import { registerToolRoute, unregisterToolRoute, registerAllToolRoutes, ensureToolRoutes } from '../utils/dynamicRoutes' import { get_session_api_headers } from '../api/auth' export interface Tool { id: string name: string description?: string category?: string icon?: string color?: string type?: 'route' | 'url' routeName?: string url?: string order?: number isDefault?: boolean hidden?: boolean // 市场工具相关 fromMarketplace?: boolean marketplaceId?: string // 市场的唯一ID(用于识别) toolName?: string // 实际的 tool_name(用于删除文件系统) version?: string author?: string rating?: number downloads?: number // 路由相关(可选,用于动态路由注册) componentPath?: string // 组件路径(相对于 src/views) routePath?: string // 路由路径(如 'tools/my-tool') } const STORAGE_KEY = 'tools.userItems' const DELETED_DEFAULT_TOOLS_KEY = 'tools.deletedDefaultTools' // 默认工具列表(硬编码,一行一个,方便添加) function getDefaultTools(): Tool[] { return [ { id: 'remove-background', name: t('Remove Background'), description: t('Remove background from images using AI technology'), category: 'Image Processing', icon: 'photo-edit', color: '#e5e7eb', type: 'route', routeName: 'RemoveBackground', order: 1, isDefault: true, toolName: 'remove_background' }, // 在这里添加更多默认工具,每行一个: // { // id: 'tool-id-2', // name: t('Tool Name'), // description: t('Tool description'), // category: 'Category', // icon: 'icon-name', // color: '#e5e7eb', // type: 'route', // routeName: 'RouteName', // order: 2, // isDefault: true, // toolName: 'tool_name' // }, ] } function loadUserTools(): Tool[] { try { const raw = localStorage.getItem(STORAGE_KEY) if (!raw) return [] const parsed = JSON.parse(raw) if (Array.isArray(parsed)) return parsed return [] } catch { return [] } } function saveUserTools(tools: Tool[]) { const userTools = tools.filter(t => !t.isDefault) localStorage.setItem(STORAGE_KEY, JSON.stringify(userTools)) } function loadDeletedDefaultTools(): string[] { try { const raw = localStorage.getItem(DELETED_DEFAULT_TOOLS_KEY) if (!raw) return [] return JSON.parse(raw) } catch { return [] } } function saveDeletedDefaultTools(deletedIds: string[]) { localStorage.setItem(DELETED_DEFAULT_TOOLS_KEY, JSON.stringify(deletedIds)) } export const useToolsStore = defineStore('tools', () => { const userTools = ref(loadUserTools()) const deletedDefaultToolIds = ref(loadDeletedDefaultTools()) const allTools = computed(() => { const defaultTools = getDefaultTools() .filter(tool => !deletedDefaultToolIds.value.includes(tool.id)) .map(tool => ({ ...tool, isDefault: true })) const userToolsList = [...userTools.value] .map(tool => ({ ...tool, isDefault: false })) return [ ...defaultTools.sort((a, b) => (a.order ?? 0) - (b.order ?? 0)), ...userToolsList.sort((a, b) => (a.order ?? 0) - (b.order ?? 0)) ] }) // 添加用户工具 function addUserTool(tool: Tool, router?: Router, componentPath?: string) { const defaultToolsCount = getDefaultTools().filter( t => !deletedDefaultToolIds.value.includes(t.id) ).length // 确保工具具有 routeName 和 routePath(如果缺失则自动生成) // 这样保存到 localStorage 的数据也会包含这些字段 const toolWithRoutes = ensureToolRoutes({ ...tool }) toolWithRoutes.order = defaultToolsCount + userTools.value.length + 1 toolWithRoutes.isDefault = false userTools.value.push(toolWithRoutes) saveUserTools(userTools.value) // 注册路由(如果提供了 router) if (router) { registerToolRoute(router, toolWithRoutes, componentPath) } } function updateUserTool(toolId: string, updates: Partial) { const index = userTools.value.findIndex(t => t.id === toolId) if (index >= 0) { userTools.value[index] = { ...userTools.value[index], ...updates, isDefault: false } saveUserTools(userTools.value) } } // 删除工具(支持用户工具和默认工具) async function deleteUserTool(toolId: string, router?: Router) { // 查找用户工具 let tool = userTools.value.find(t => t.id === toolId) let isDefaultTool = false // 如果不是用户工具,查找默认工具 if (!tool) { tool = getDefaultTools().find(t => t.id === toolId) isDefaultTool = true } let toolName: string | null = null if (tool) { if (tool.toolName) { toolName = tool.toolName } else if (tool.componentPath) { const match = tool.componentPath.match(/tools\/([^\/]+)\//) if (match && match[1]) { toolName = match[1] } } } if (toolName) { try { await axios.post(`/jingrow/uninstall-tool/${toolName}`, {}, { headers: { ...get_session_api_headers() } }) } catch (error: any) { console.error('删除工具文件失败:', error.response?.data || error.message || '未知错误') } } if (isDefaultTool) { // 删除默认工具:添加到已删除列表 if (!deletedDefaultToolIds.value.includes(toolId)) { deletedDefaultToolIds.value.push(toolId) saveDeletedDefaultTools(deletedDefaultToolIds.value) } } else { // 删除用户工具:从列表中移除 userTools.value = userTools.value.filter(t => t.id !== toolId) const defaultToolsCount = getDefaultTools().filter( t => !deletedDefaultToolIds.value.includes(t.id) ).length userTools.value.forEach((t, index) => { t.order = defaultToolsCount + index + 1 }) saveUserTools(userTools.value) } if (tool && tool.routeName && router) { unregisterToolRoute(router, tool.routeName) } } function updateUserToolsOrder(newOrder: Tool[]) { const defaultToolsCount = getDefaultTools().filter( t => !deletedDefaultToolIds.value.includes(t.id) ).length newOrder.forEach((tool, index) => { tool.order = defaultToolsCount + index + 1 }) userTools.value = newOrder saveUserTools(userTools.value) } function initToolRoutes(router: Router) { const defaultTools = getDefaultTools() .filter(tool => !deletedDefaultToolIds.value.includes(tool.id)) .map(tool => ({ ...tool, isDefault: true })) const allToolsToRegister = [...defaultTools, ...userTools.value] registerAllToolRoutes(router, allToolsToRegister) } return { userTools, allTools, addUserTool, updateUserTool, deleteUserTool, updateUserToolsOrder, getDefaultTools, initToolRoutes } })