Fix tool installation and deletion issues
This commit is contained in:
parent
58d44c5291
commit
f1c8054754
@ -1,8 +1,10 @@
|
||||
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
|
||||
@ -19,7 +21,8 @@ export interface Tool {
|
||||
hidden?: boolean
|
||||
// 市场工具相关
|
||||
fromMarketplace?: boolean
|
||||
marketplaceId?: string
|
||||
marketplaceId?: string // 市场的唯一ID(用于识别)
|
||||
toolName?: string // 实际的 tool_name(用于删除文件系统)
|
||||
version?: string
|
||||
author?: string
|
||||
rating?: number
|
||||
@ -155,9 +158,47 @@ export const useToolsStore = defineStore('tools', () => {
|
||||
}
|
||||
|
||||
// 删除用户工具
|
||||
function deleteUserTool(toolId: string, router?: Router) {
|
||||
async function deleteUserTool(toolId: string, router?: Router) {
|
||||
const tool = userTools.value.find(t => t.id === toolId)
|
||||
|
||||
console.log('删除工具:', { toolId, tool, fromMarketplace: tool?.fromMarketplace, marketplaceId: tool?.marketplaceId, toolName: tool?.toolName, componentPath: tool?.componentPath })
|
||||
|
||||
// 确定工具名称(tool_name):优先使用 toolName,否则从 componentPath 提取
|
||||
let toolName: string | null = null
|
||||
|
||||
if (tool) {
|
||||
// 优先使用 toolName(实际的 tool_name,用于文件系统)
|
||||
if (tool.toolName) {
|
||||
toolName = tool.toolName
|
||||
}
|
||||
// 否则从 componentPath 提取工具名称(格式:tools/{tool_name}/{tool_name}.vue)
|
||||
else if (tool.componentPath) {
|
||||
const match = tool.componentPath.match(/tools\/([^\/]+)\//)
|
||||
if (match && match[1]) {
|
||||
toolName = match[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 如果找到了工具名称,尝试删除文件系统
|
||||
if (toolName) {
|
||||
try {
|
||||
console.log('调用后端API删除工具文件,工具名称:', toolName)
|
||||
// 调用后端API删除工具文件
|
||||
const response = await axios.post(`/jingrow/uninstall-tool/${toolName}`, {}, {
|
||||
headers: {
|
||||
...get_session_api_headers()
|
||||
}
|
||||
})
|
||||
console.log('删除工具文件成功:', response.data)
|
||||
} catch (error: any) {
|
||||
console.error('删除工具文件失败:', error.response?.data || error.message || '未知错误')
|
||||
// 即使删除文件失败,也继续删除store中的工具
|
||||
}
|
||||
} else {
|
||||
console.log('无法确定工具名称,跳过文件删除')
|
||||
}
|
||||
|
||||
userTools.value = userTools.value.filter(t => t.id !== toolId)
|
||||
// 重新分配 order
|
||||
const defaultToolsCount = getDefaultTools().filter(
|
||||
|
||||
@ -232,6 +232,11 @@ const hiddenTools = computed(() => toolsStore.hiddenTools)
|
||||
|
||||
onMounted(() => {
|
||||
loading.value = false
|
||||
|
||||
// 监听全局事件,当工具安装后刷新列表
|
||||
window.addEventListener('installedToolsUpdated', () => {
|
||||
// store 会自动更新,computed 属性会自动响应
|
||||
})
|
||||
})
|
||||
|
||||
// 拖拽处理
|
||||
@ -403,10 +408,15 @@ function handleDeleteTool(tool: Tool) {
|
||||
content: `${t('Are you sure you want to delete tool')} "${tool.name}"?`,
|
||||
positiveText: t('Delete'),
|
||||
negativeText: t('Cancel'),
|
||||
onPositiveClick: () => {
|
||||
// 删除工具并移除路由
|
||||
toolsStore.deleteUserTool(tool.id, router)
|
||||
message.success(t('Tool deleted successfully'))
|
||||
onPositiveClick: async () => {
|
||||
try {
|
||||
// 删除工具并移除路由(如果是市场工具,会同时删除文件)
|
||||
await toolsStore.deleteUserTool(tool.id, router)
|
||||
message.success(t('Tool deleted successfully'))
|
||||
} catch (error) {
|
||||
console.error('Delete tool error:', error)
|
||||
message.error(t('Failed to delete tool'))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -134,6 +134,15 @@
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 安装进度弹窗 -->
|
||||
<InstallProgressModal
|
||||
v-model="showProgressModal"
|
||||
:progress="installProgress"
|
||||
:message="installMessage"
|
||||
:status="installStatus"
|
||||
:installing="installing"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -146,6 +155,7 @@ import { Icon } from '@iconify/vue'
|
||||
import axios from 'axios'
|
||||
import { t } from '@/shared/i18n'
|
||||
import { useToolsStore } from '@/shared/stores/tools'
|
||||
import InstallProgressModal from './InstallProgressModal.vue'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
@ -156,6 +166,13 @@ const loading = ref(true)
|
||||
const error = ref('')
|
||||
const tool = ref<any>(null)
|
||||
|
||||
// 安装相关状态
|
||||
const installing = ref(false)
|
||||
const installProgress = ref(0)
|
||||
const installMessage = ref('')
|
||||
const installStatus = ref<'success' | 'error' | 'info'>('info')
|
||||
const showProgressModal = ref(false)
|
||||
|
||||
// 已安装工具集合
|
||||
const installedToolNames = ref<Set<string>>(new Set())
|
||||
|
||||
@ -209,31 +226,138 @@ function goBack() {
|
||||
}
|
||||
|
||||
async function installTool() {
|
||||
if (!tool.value.file_url && !tool.value.repository_url) {
|
||||
message.error(t('工具文件URL或仓库地址不存在'))
|
||||
return
|
||||
}
|
||||
|
||||
performInstall()
|
||||
}
|
||||
|
||||
async function performInstall() {
|
||||
try {
|
||||
// 将工具添加到用户工具列表
|
||||
const toolData = {
|
||||
id: tool.value.name || `tool-${Date.now()}`,
|
||||
name: tool.value.title || tool.value.name,
|
||||
description: tool.value.description,
|
||||
category: tool.value.category,
|
||||
icon: tool.value.icon,
|
||||
color: tool.value.color || '#e5e7eb',
|
||||
type: 'route', // 默认类型为 route
|
||||
routeName: tool.value.route_name, // 可能不存在,会在 addUserTool 中自动生成
|
||||
isDefault: false,
|
||||
fromMarketplace: true,
|
||||
marketplaceId: tool.value.name
|
||||
installing.value = true
|
||||
installProgress.value = 0
|
||||
installMessage.value = t('正在准备安装...')
|
||||
installStatus.value = 'info'
|
||||
showProgressModal.value = true
|
||||
|
||||
let response
|
||||
|
||||
// 优先使用文件URL,否则使用git仓库
|
||||
if (tool.value.file_url) {
|
||||
installMessage.value = t('正在下载工具包...')
|
||||
setTimeout(() => {
|
||||
installProgress.value = 20
|
||||
}, 300)
|
||||
|
||||
installProgress.value = 30
|
||||
installMessage.value = t('正在安装工具...')
|
||||
|
||||
response = await axios.post('/jingrow/install-tool-from-url', new URLSearchParams({
|
||||
url: tool.value.file_url
|
||||
}), {
|
||||
headers: {
|
||||
...get_session_api_headers(),
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
})
|
||||
} else if (tool.value.repository_url) {
|
||||
installMessage.value = t('正在克隆仓库...')
|
||||
setTimeout(() => {
|
||||
installProgress.value = 20
|
||||
}, 300)
|
||||
|
||||
installProgress.value = 30
|
||||
installMessage.value = t('正在安装工具...')
|
||||
|
||||
// 注意:目前后端可能还没有 install-tool-from-git API,需要检查
|
||||
message.warning(t('从Git仓库安装工具功能暂未实现'))
|
||||
installing.value = false
|
||||
installStatus.value = 'error'
|
||||
installMessage.value = t('从Git仓库安装工具功能暂未实现')
|
||||
setTimeout(() => {
|
||||
showProgressModal.value = false
|
||||
}, 3000)
|
||||
return
|
||||
}
|
||||
|
||||
// 传递 router 以便立即注册路由
|
||||
toolsStore.addUserTool(toolData, router)
|
||||
message.success(t('Tool installed successfully'))
|
||||
if (!response) {
|
||||
throw new Error(t('无法确定安装方式'))
|
||||
}
|
||||
|
||||
// 刷新已安装工具列表
|
||||
loadInstalledTools()
|
||||
// 更新进度到安装完成
|
||||
installProgress.value = 100
|
||||
|
||||
if (response.data.success) {
|
||||
// 所有步骤完成后才显示成功
|
||||
installing.value = false
|
||||
installStatus.value = 'success'
|
||||
installMessage.value = t('工具安装成功!')
|
||||
message.success(t('工具安装成功'))
|
||||
|
||||
// 将工具添加到 toolsStore
|
||||
// 重要:tool_name 是实际的工具名称(用于文件夹),tool.value.name 是市场的唯一ID
|
||||
const toolName = response.data.tool_name || tool.value.tool_name // 实际的 tool_name(用于文件夹)
|
||||
const toolTitle = response.data.tool_title || tool.value.title || tool.value.name
|
||||
const marketplaceId = tool.value.name // 市场的唯一ID(用于识别)
|
||||
|
||||
if (!toolName) {
|
||||
console.error('无法获取工具名称 (tool_name)')
|
||||
throw new Error('无法获取工具名称')
|
||||
}
|
||||
|
||||
// 检查工具是否已存在于 store 中(使用市场的唯一ID检查)
|
||||
const existingTool = toolsStore.userTools.find(
|
||||
t => t.marketplaceId === marketplaceId && t.fromMarketplace
|
||||
)
|
||||
|
||||
if (!existingTool) {
|
||||
// 构建工具数据
|
||||
const toolData = {
|
||||
id: marketplaceId || `tool-${Date.now()}`, // 使用市场唯一ID作为id
|
||||
name: toolTitle,
|
||||
description: tool.value.description,
|
||||
category: tool.value.category,
|
||||
icon: tool.value.icon,
|
||||
color: tool.value.color || '#e5e7eb',
|
||||
type: 'route' as const,
|
||||
routeName: tool.value.route_name, // 可能不存在,会在 addUserTool 中自动生成
|
||||
isDefault: false,
|
||||
fromMarketplace: true,
|
||||
marketplaceId: marketplaceId, // 市场的唯一ID
|
||||
toolName: toolName, // 实际的 tool_name(用于删除文件)
|
||||
componentPath: `tools/${toolName}/${toolName}.vue` // 组件路径使用实际的 tool_name
|
||||
}
|
||||
|
||||
// 添加到 store 并注册路由
|
||||
toolsStore.addUserTool(toolData, router, toolData.componentPath)
|
||||
}
|
||||
|
||||
// 刷新已安装工具列表
|
||||
loadInstalledTools()
|
||||
|
||||
// 触发全局事件,通知工具列表页刷新
|
||||
if (typeof window !== 'undefined') {
|
||||
window.dispatchEvent(new Event('installedToolsUpdated'))
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
showProgressModal.value = false
|
||||
}, 2000)
|
||||
} else {
|
||||
throw new Error(response.data.error || t('安装失败'))
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('Failed to install tool:', error)
|
||||
message.error(error.response?.data?.detail || t('Failed to install tool'))
|
||||
console.error('Install tool error:', error)
|
||||
installing.value = false
|
||||
installStatus.value = 'error'
|
||||
installMessage.value = error.response?.data?.detail || error.message || t('安装失败')
|
||||
message.error(error.response?.data?.detail || t('安装失败'))
|
||||
|
||||
setTimeout(() => {
|
||||
showProgressModal.value = false
|
||||
}, 3000)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -137,20 +137,31 @@
|
||||
</n-empty>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 安装进度弹窗 -->
|
||||
<InstallProgressModal
|
||||
v-model="showProgressModal"
|
||||
:progress="installProgress"
|
||||
:message="installMessage"
|
||||
:status="installStatus"
|
||||
:installing="installing"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, computed, watch } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { NInput, NButton, NIcon, NSpin, NEmpty, NSelect, NPagination, useMessage } from 'naive-ui'
|
||||
import { NInput, NButton, NIcon, NSpin, NEmpty, NSelect, NPagination, useMessage, useDialog } from 'naive-ui'
|
||||
import { Icon } from '@iconify/vue'
|
||||
import axios from 'axios'
|
||||
import { t } from '@/shared/i18n'
|
||||
import { get_session_api_headers } from '@/shared/api/auth'
|
||||
import { useToolsStore } from '@/shared/stores/tools'
|
||||
import InstallProgressModal from './InstallProgressModal.vue'
|
||||
|
||||
const message = useMessage()
|
||||
const dialog = useDialog()
|
||||
const router = useRouter()
|
||||
const toolsStore = useToolsStore()
|
||||
|
||||
@ -162,6 +173,13 @@ const page = ref(1)
|
||||
const pageSize = ref(parseInt(localStorage.getItem('itemsPerPage') || '20'))
|
||||
const sortBy = ref('creation desc')
|
||||
|
||||
// 安装相关状态
|
||||
const installing = ref(false)
|
||||
const installProgress = ref(0)
|
||||
const installMessage = ref('')
|
||||
const installStatus = ref<'success' | 'error' | 'info'>('info')
|
||||
const showProgressModal = ref(false)
|
||||
|
||||
// 已安装工具集合
|
||||
const installedToolNames = ref<Set<string>>(new Set())
|
||||
|
||||
@ -225,31 +243,138 @@ function viewToolDetail(tool: any) {
|
||||
}
|
||||
|
||||
async function installTool(tool: any) {
|
||||
if (!tool.file_url && !tool.repository_url) {
|
||||
message.error(t('工具文件URL或仓库地址不存在'))
|
||||
return
|
||||
}
|
||||
|
||||
performInstall(tool)
|
||||
}
|
||||
|
||||
async function performInstall(tool: any) {
|
||||
try {
|
||||
// 将工具添加到用户工具列表
|
||||
const toolData = {
|
||||
id: tool.name || `tool-${Date.now()}`,
|
||||
name: tool.title || tool.name,
|
||||
description: tool.description,
|
||||
category: tool.category,
|
||||
icon: tool.icon,
|
||||
color: tool.color || '#e5e7eb',
|
||||
type: 'route', // 默认类型为 route
|
||||
routeName: tool.route_name, // 可能不存在,会在 addUserTool 中自动生成
|
||||
isDefault: false,
|
||||
fromMarketplace: true,
|
||||
marketplaceId: tool.name
|
||||
installing.value = true
|
||||
installProgress.value = 0
|
||||
installMessage.value = t('正在准备安装...')
|
||||
installStatus.value = 'info'
|
||||
showProgressModal.value = true
|
||||
|
||||
let response
|
||||
|
||||
// 优先使用文件URL,否则使用git仓库
|
||||
if (tool.file_url) {
|
||||
installMessage.value = t('正在下载工具包...')
|
||||
setTimeout(() => {
|
||||
installProgress.value = 20
|
||||
}, 300)
|
||||
|
||||
installProgress.value = 30
|
||||
installMessage.value = t('正在安装工具...')
|
||||
|
||||
response = await axios.post('/jingrow/install-tool-from-url', new URLSearchParams({
|
||||
url: tool.file_url
|
||||
}), {
|
||||
headers: {
|
||||
...get_session_api_headers(),
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
})
|
||||
} else if (tool.repository_url) {
|
||||
installMessage.value = t('正在克隆仓库...')
|
||||
setTimeout(() => {
|
||||
installProgress.value = 20
|
||||
}, 300)
|
||||
|
||||
installProgress.value = 30
|
||||
installMessage.value = t('正在安装工具...')
|
||||
|
||||
// 注意:目前后端可能还没有 install-tool-from-git API,需要检查
|
||||
message.warning(t('从Git仓库安装工具功能暂未实现'))
|
||||
installing.value = false
|
||||
installStatus.value = 'error'
|
||||
installMessage.value = t('从Git仓库安装工具功能暂未实现')
|
||||
setTimeout(() => {
|
||||
showProgressModal.value = false
|
||||
}, 3000)
|
||||
return
|
||||
}
|
||||
|
||||
// 传递 router 以便立即注册路由
|
||||
toolsStore.addUserTool(toolData, router)
|
||||
message.success(t('Tool installed successfully'))
|
||||
if (!response) {
|
||||
throw new Error(t('无法确定安装方式'))
|
||||
}
|
||||
|
||||
// 刷新已安装工具列表
|
||||
loadInstalledTools()
|
||||
// 更新进度到安装完成
|
||||
installProgress.value = 100
|
||||
|
||||
if (response.data.success) {
|
||||
// 所有步骤完成后才显示成功
|
||||
installing.value = false
|
||||
installStatus.value = 'success'
|
||||
installMessage.value = t('工具安装成功!')
|
||||
message.success(t('工具安装成功'))
|
||||
|
||||
// 将工具添加到 toolsStore
|
||||
// 重要:tool_name 是实际的工具名称(用于文件夹),tool.name 是市场的唯一ID
|
||||
const toolName = response.data.tool_name || tool.tool_name // 实际的 tool_name(用于文件夹)
|
||||
const toolTitle = response.data.tool_title || tool.title || tool.name
|
||||
const marketplaceId = tool.name // 市场的唯一ID(用于识别)
|
||||
|
||||
if (!toolName) {
|
||||
console.error('无法获取工具名称 (tool_name)')
|
||||
throw new Error('无法获取工具名称')
|
||||
}
|
||||
|
||||
// 检查工具是否已存在于 store 中(使用实际的 tool_name 检查)
|
||||
const existingTool = toolsStore.userTools.find(
|
||||
t => t.marketplaceId === marketplaceId && t.fromMarketplace
|
||||
)
|
||||
|
||||
if (!existingTool) {
|
||||
// 构建工具数据
|
||||
const toolData = {
|
||||
id: marketplaceId || `tool-${Date.now()}`, // 使用市场唯一ID作为id
|
||||
name: toolTitle,
|
||||
description: tool.description,
|
||||
category: tool.category,
|
||||
icon: tool.icon,
|
||||
color: tool.color || '#e5e7eb',
|
||||
type: 'route' as const,
|
||||
routeName: tool.route_name, // 可能不存在,会在 addUserTool 中自动生成
|
||||
isDefault: false,
|
||||
fromMarketplace: true,
|
||||
marketplaceId: marketplaceId, // 市场的唯一ID
|
||||
toolName: toolName, // 实际的 tool_name(用于删除文件)
|
||||
componentPath: `tools/${toolName}/${toolName}.vue` // 组件路径使用实际的 tool_name
|
||||
}
|
||||
|
||||
// 添加到 store 并注册路由
|
||||
toolsStore.addUserTool(toolData, router, toolData.componentPath)
|
||||
}
|
||||
|
||||
// 刷新已安装工具列表
|
||||
loadInstalledTools()
|
||||
|
||||
// 触发全局事件,通知工具列表页刷新
|
||||
if (typeof window !== 'undefined') {
|
||||
window.dispatchEvent(new Event('installedToolsUpdated'))
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
showProgressModal.value = false
|
||||
}, 2000)
|
||||
} else {
|
||||
throw new Error(response.data.error || t('安装失败'))
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('Failed to install tool:', error)
|
||||
message.error(error.response?.data?.detail || t('Failed to install tool'))
|
||||
console.error('Install tool error:', error)
|
||||
installing.value = false
|
||||
installStatus.value = 'error'
|
||||
installMessage.value = error.response?.data?.detail || error.message || t('安装失败')
|
||||
message.error(error.response?.data?.detail || t('安装失败'))
|
||||
|
||||
setTimeout(() => {
|
||||
showProgressModal.value = false
|
||||
}, 3000)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -235,6 +235,7 @@ def _install_tool_from_file(file_path: str) -> Dict[str, Any]:
|
||||
'success': True,
|
||||
'tool_id': result.get('tool_id'),
|
||||
'tool_name': result.get('tool_name'),
|
||||
'tool_title': result.get('tool_title'),
|
||||
'message': f"工具 {result.get('tool_name')} 安装成功"
|
||||
}
|
||||
else:
|
||||
@ -325,11 +326,29 @@ def _install_single_tool_directory(tool_dir: str) -> Dict[str, Any]:
|
||||
if backend_source.exists() and backend_source.is_dir():
|
||||
backend_target = jingrow_root / "tools" / tool_name
|
||||
backend_target.mkdir(parents=True, exist_ok=True)
|
||||
# 如果目录已存在,先删除
|
||||
if backend_target.exists():
|
||||
shutil.rmtree(backend_target)
|
||||
shutil.copytree(backend_source, backend_target)
|
||||
logger.info(f"复制后端文件: {backend_source} -> {backend_target}")
|
||||
|
||||
# 如果后端目录下有子目录(如 backend/{tool_name}/),复制子目录的内容
|
||||
# 否则直接复制 backend/ 下的所有文件
|
||||
subdirs = [d for d in backend_source.iterdir() if d.is_dir()]
|
||||
if subdirs:
|
||||
# 有子目录,复制第一个子目录的内容
|
||||
source_subdir = subdirs[0]
|
||||
if backend_target.exists():
|
||||
shutil.rmtree(backend_target)
|
||||
shutil.copytree(source_subdir, backend_target)
|
||||
logger.info(f"复制后端文件目录: {source_subdir} -> {backend_target}")
|
||||
else:
|
||||
# 没有子目录,直接复制所有文件
|
||||
if backend_target.exists():
|
||||
shutil.rmtree(backend_target)
|
||||
backend_target.mkdir(parents=True, exist_ok=True)
|
||||
for item in backend_source.iterdir():
|
||||
if item.is_file():
|
||||
shutil.copy2(item, backend_target / item.name)
|
||||
logger.info(f"复制后端文件: {item.name} -> {backend_target}")
|
||||
elif item.is_dir():
|
||||
shutil.copytree(item, backend_target / item.name)
|
||||
logger.info(f"复制后端文件目录: {item.name} -> {backend_target}")
|
||||
|
||||
return {
|
||||
'success': True,
|
||||
@ -342,3 +361,62 @@ def _install_single_tool_directory(tool_dir: str) -> Dict[str, Any]:
|
||||
logger.error(f"安装工具目录失败: {str(e)}")
|
||||
return {'success': False, 'error': str(e)}
|
||||
|
||||
|
||||
@router.post("/jingrow/uninstall-tool/{tool_name}")
|
||||
async def uninstall_tool(tool_name: str):
|
||||
"""卸载工具 - 删除前后端对应的文件夹"""
|
||||
try:
|
||||
logger.info(f"开始卸载工具: {tool_name}")
|
||||
jingrow_root = get_jingrow_root()
|
||||
|
||||
# 前端目录:apps/jingrow/frontend/src/views/tools/{tool_name}
|
||||
frontend_root = jingrow_root.parent / "frontend" / "src"
|
||||
tool_frontend_dir = frontend_root / "views" / "tools" / tool_name
|
||||
|
||||
# 后端目录:apps/jingrow/jingrow/tools/{tool_name}
|
||||
tool_backend_dir = jingrow_root / "tools" / tool_name
|
||||
|
||||
logger.info(f"前端目录路径: {tool_frontend_dir}")
|
||||
logger.info(f"后端目录路径: {tool_backend_dir}")
|
||||
logger.info(f"前端目录存在: {tool_frontend_dir.exists()}")
|
||||
logger.info(f"后端目录存在: {tool_backend_dir.exists()}")
|
||||
|
||||
deleted_paths = []
|
||||
|
||||
# 删除前端目录
|
||||
if tool_frontend_dir.exists():
|
||||
shutil.rmtree(tool_frontend_dir)
|
||||
deleted_paths.append(f"前端: {tool_frontend_dir}")
|
||||
logger.info(f"删除工具前端目录成功: {tool_frontend_dir}")
|
||||
else:
|
||||
logger.warning(f"前端目录不存在: {tool_frontend_dir}")
|
||||
|
||||
# 删除后端目录
|
||||
if tool_backend_dir.exists():
|
||||
shutil.rmtree(tool_backend_dir)
|
||||
deleted_paths.append(f"后端: {tool_backend_dir}")
|
||||
logger.info(f"删除工具后端目录成功: {tool_backend_dir}")
|
||||
else:
|
||||
logger.warning(f"后端目录不存在: {tool_backend_dir}")
|
||||
|
||||
if not deleted_paths:
|
||||
logger.warning(f"工具 {tool_name} 的文件目录不存在")
|
||||
return {
|
||||
'success': False,
|
||||
'error': f'工具 {tool_name} 的文件目录不存在',
|
||||
'frontend_path': str(tool_frontend_dir),
|
||||
'backend_path': str(tool_backend_dir)
|
||||
}
|
||||
|
||||
logger.info(f"工具 {tool_name} 卸载成功,已删除路径: {deleted_paths}")
|
||||
return {
|
||||
'success': True,
|
||||
'message': f'工具 {tool_name} 卸载成功',
|
||||
'deleted_paths': deleted_paths
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"卸载工具失败: {str(e)}")
|
||||
logger.error(f"Traceback: {traceback.format_exc()}")
|
||||
raise HTTPException(status_code=500, detail=f"卸载工具失败: {str(e)}")
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user