From b6aad697be5c435e32267b2f3cfc8dbd98d3e383 Mon Sep 17 00:00:00 2001 From: engigu Date: Tue, 31 Mar 2026 18:25:05 +0800 Subject: [PATCH] fix: remove package force #73 --- internal/controllers/dependency_controller.go | 10 ++-- web/src/api/index.ts | 5 +- web/src/views/dependencies/Dependencies.vue | 51 +++++++++++++++---- 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/internal/controllers/dependency_controller.go b/internal/controllers/dependency_controller.go index dea104f..991acc5 100644 --- a/internal/controllers/dependency_controller.go +++ b/internal/controllers/dependency_controller.go @@ -188,6 +188,8 @@ func (c *DependencyController) Uninstall(ctx *gin.Context) { return } + force := ctx.Query("force") == "true" + // 获取依赖信息 deps, _ := c.service.List("", "") var dep *models.Dependency @@ -204,11 +206,13 @@ func (c *DependencyController) Uninstall(ctx *gin.Context) { } if err := c.service.Uninstall(dep); err != nil { - utils.ServerError(ctx, err.Error()) - return + if !force { + utils.ServerError(ctx, err.Error()) + return + } } - // 卸载成功后从数据库删除 + // 卸载成功(或强制删除)后从数据库删除 c.service.Delete(id) utils.SuccessMsg(ctx, "卸载成功") diff --git a/web/src/api/index.ts b/web/src/api/index.ts index 56566ce..e1e75cc 100644 --- a/web/src/api/index.ts +++ b/web/src/api/index.ts @@ -242,7 +242,10 @@ export const api = { delete: (id: string) => request(`/deps/${id}`, { method: 'DELETE' }), install: (data: any) => request('/deps/install', { method: 'POST', body: JSON.stringify(data) }), getInstallCmd: (data: any) => request<{ command: string }>('/deps/install-cmd', { method: 'POST', body: JSON.stringify(data) }), - uninstall: (id: string) => request(`/deps/uninstall/${id}`, { method: 'POST' }), + uninstall: (id: string, force?: boolean) => { + const query = force ? '?force=true' : '' + return request(`/deps/uninstall/${id}${query}`, { method: 'POST' }) + }, reinstall: (id: string) => request(`/deps/reinstall/${id}`, { method: 'POST' }), reinstallAll: (language: string, lang_version?: string) => { const query = new URLSearchParams({ language }) diff --git a/web/src/views/dependencies/Dependencies.vue b/web/src/views/dependencies/Dependencies.vue index 0f4475a..80271a1 100644 --- a/web/src/views/dependencies/Dependencies.vue +++ b/web/src/views/dependencies/Dependencies.vue @@ -10,6 +10,7 @@ import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, import { Trash2, Package, Search, RefreshCw, Loader2, Download, FileText, RotateCw, ChevronLeft } from 'lucide-vue-next' import { api, type Dependency } from '@/api' import TextOverflow from '@/components/TextOverflow.vue' +import { Checkbox } from '@/components/ui/checkbox' import { toast } from 'vue-sonner' const route = useRoute() @@ -32,6 +33,7 @@ const newPkgRemark = ref('') // 删除确认 const showDeleteDialog = ref(false) +const isForce = ref(false) const depToDelete = ref(null) const showLogDialog = ref(false) @@ -116,17 +118,40 @@ async function installPackage() { function confirmDelete(dep: Dependency) { depToDelete.value = dep + isForce.value = false showDeleteDialog.value = true } async function uninstallPackage() { if (!depToDelete.value) return + const id = depToDelete.value.id + const name = depToDelete.value.name + const force = isForce.value try { - await api.deps.uninstall(depToDelete.value.id) - toast.success('卸载成功') + await api.deps.uninstall(id, force) + toast.success(force ? `"${name}" 记录已强制移除` : '卸载成功') await loadDeps() - } catch (e: unknown) { - toast.error((e as Error).message || '卸载失败') + } catch (e: any) { + const errorMsg = e.message || '卸载失败' + toast.error(errorMsg, { + duration: 10000, + action: { + label: '强制删除记录', + onClick: async () => { + try { + await api.deps.uninstall(id, true) + toast.success(`已强制删除 "${name}" 记录`) + await loadDeps() + } catch (err: any) { + toast.error('强制删除失败: ' + err.message) + } + } + }, + actionButtonStyle: { + backgroundColor: '#ef4444', // text-red-500 equivalent for background + color: 'white' + } + }) } finally { showDeleteDialog.value = false depToDelete.value = null @@ -348,11 +373,19 @@ onMounted(async () => { 确定要卸载 "{{ depToDelete?.name }}" 吗? - - 取消 - - 卸载 - + +
+ + +
+
+ 取消 + + {{ isForce ? '强制删除' : '卸载' }} + +