@@ -2,44 +2,13 @@ import axios from "axios";
22import { pinyin } from "pinyin-pro" ;
33import { useCommonStore } from "@/stores/common" ;
44import { useI18n , useModuleI18n } from "@/i18n/composables" ;
5- import defaultPluginIcon from "@/assets/images/plugin_icon.png" ;
65import { getPlatformDisplayName } from "@/utils/platformUtils" ;
6+ import { useTimedMessage } from "@/composables/useTimedMessage" ;
7+ import { resolveErrorMessage } from "@/utils/errorUtils" ;
78import { ref , computed , onMounted , onUnmounted , reactive , watch } from "vue" ;
89import { useRoute , useRouter } from "vue-router" ;
910import { useDisplay } from "vuetify" ;
1011
11- const useTimedMessage = ( initialType = "success" ) => {
12- const state = reactive ( {
13- message : "" ,
14- type : initialType ,
15- } ) ;
16- let timer = null ;
17-
18- const clearTimer = ( ) => {
19- if ( timer ) {
20- clearTimeout ( timer ) ;
21- timer = null ;
22- }
23- } ;
24-
25- const setMessage = ( message , type = initialType , duration = 4000 ) => {
26- state . message = message || "" ;
27- state . type = type ;
28- clearTimer ( ) ;
29- if ( duration > 0 && state . message ) {
30- timer = setTimeout ( ( ) => {
31- state . message = "" ;
32- } , duration ) ;
33- }
34- } ;
35-
36- return {
37- state,
38- setMessage,
39- clearTimer,
40- } ;
41- } ;
42-
4312export const useExtensionPage = ( ) => {
4413
4514
@@ -171,6 +140,7 @@ export const useExtensionPage = () => {
171140 const {
172141 state : reloadFeedback ,
173142 setMessage : setReloadFeedback ,
143+ clearMessage : clearReloadFeedback ,
174144 clearTimer : clearReloadFeedbackTimer ,
175145 } = useTimedMessage ( ) ;
176146
@@ -461,14 +431,6 @@ export const useExtensionPage = () => {
461431 snack_show . value = true ;
462432 snack_success . value = success ;
463433 } ;
464- const resolveErrorMessage = ( err , fallbackMessage = "" ) => {
465- return (
466- err ?. response ?. data ?. message ||
467- err ?. message ||
468- String ( err ) ||
469- fallbackMessage
470- ) ;
471- } ;
472434
473435 const resetLoadingDialog = ( ) => {
474436 loadingDialog . show = false ;
@@ -549,7 +511,7 @@ export const useExtensionPage = () => {
549511
550512 const reloadFailedPlugin = async ( dirName ) => {
551513 // Reset stale inline feedback before each retry attempt
552- setReloadFeedback ( "" , "success" , 0 ) ;
514+ clearReloadFeedback ( ) ;
553515
554516 if ( ! dirName ) {
555517 return ;
@@ -571,47 +533,67 @@ export const useExtensionPage = () => {
571533 }
572534 } ;
573535
574- const requestUninstallPlugin = ( name ) => {
575- if ( ! name ) return ;
576- uninstallTarget . value = { type : "normal" , id : name } ;
536+ const requestUninstall = ( kind , id ) => {
537+ if ( ! id ) return ;
538+ uninstallTarget . value = { kind , id } ;
577539 showUninstallDialog . value = true ;
578540 } ;
579541
542+ const requestUninstallPlugin = ( name ) => {
543+ requestUninstall ( "normal" , name ) ;
544+ } ;
545+
580546 const requestUninstallFailedPlugin = ( dirName ) => {
581- if ( ! dirName ) return ;
582- uninstallTarget . value = { type : "failed" , id : dirName } ;
583- showUninstallDialog . value = true ;
547+ requestUninstall ( "failed" , dirName ) ;
584548 } ;
585549
586- const uninstallFailedPlugin = async ( dirName , options = { } ) => {
587- const {
588- deleteConfig = false ,
589- deleteData = false ,
590- skipConfirm = false ,
591- } = options ;
550+ const performUninstall = async ( target , options = { } ) => {
551+ if ( ! target ?. id ) return ;
592552
593- if ( ! skipConfirm ) {
594- requestUninstallFailedPlugin ( dirName ) ;
595- return ;
596- }
553+ const { deleteConfig = false , deleteData = false } = options || { } ;
554+ toast ( `${ tm ( "messages.uninstalling" ) } ${ target . id } ` , "primary" ) ;
597555
598- toast ( tm ( "messages.uninstalling" ) + " " + dirName , "primary" ) ;
599556 try {
600- const res = await axios . post ( "/api/plugin/uninstall-failed" , {
601- dir_name : dirName ,
557+ if ( target . kind === "failed" ) {
558+ const res = await axios . post ( "/api/plugin/uninstall-failed" , {
559+ dir_name : target . id ,
560+ delete_config : deleteConfig ,
561+ delete_data : deleteData ,
562+ } ) ;
563+ if ( res . data . status === "error" ) {
564+ toast ( res . data . message , "error" ) ;
565+ return ;
566+ }
567+ toast ( res . data . message , "success" ) ;
568+ await getExtensions ( ) ;
569+ return ;
570+ }
571+
572+ const res = await axios . post ( "/api/plugin/uninstall" , {
573+ name : target . id ,
602574 delete_config : deleteConfig ,
603575 delete_data : deleteData ,
604576 } ) ;
605577 if ( res . data . status === "error" ) {
606578 toast ( res . data . message , "error" ) ;
607579 return ;
608580 }
581+ Object . assign ( extension_data , res . data ) ;
609582 toast ( res . data . message , "success" ) ;
610583 await getExtensions ( ) ;
611584 } catch ( err ) {
612585 toast ( resolveErrorMessage ( err ) , "error" ) ;
613586 }
614587 } ;
588+
589+ const uninstallFailedPlugin = async ( dirName , options = null ) => {
590+ if ( ! dirName ) return ;
591+ if ( ! options || typeof options !== "object" ) {
592+ requestUninstallFailedPlugin ( dirName ) ;
593+ return ;
594+ }
595+ await performUninstall ( { kind : "failed" , id : dirName } , options ) ;
596+ } ;
615597
616598 const checkUpdate = ( ) => {
617599 const onlinePluginsMap = new Map ( ) ;
@@ -642,69 +624,36 @@ export const useExtensionPage = () => {
642624 } ) ;
643625 } ;
644626
645- const uninstallExtension = async (
646- extension_name ,
647- optionsOrSkipConfirm = false ,
648- ) => {
649- let deleteConfig = false ;
650- let deleteData = false ;
651- let skipConfirm = false ;
652-
653- // 处理参数:可能是布尔值(旧的 skipConfirm)或对象(新的选项)
627+ const uninstallExtension = async ( extensionName , optionsOrSkipConfirm = false ) => {
628+ if ( ! extensionName ) return ;
629+
654630 if ( typeof optionsOrSkipConfirm === "boolean" ) {
655- skipConfirm = optionsOrSkipConfirm ;
656- } else if (
657- typeof optionsOrSkipConfirm === "object" &&
658- optionsOrSkipConfirm !== null
659- ) {
660- deleteConfig = optionsOrSkipConfirm . deleteConfig || false ;
661- deleteData = optionsOrSkipConfirm . deleteData || false ;
662- skipConfirm = true ; // 如果传递了选项对象,说明已经确认过了
663- }
664-
665- // 如果没有跳过确认且没有传递选项对象,显示自定义卸载对话框
666- if ( ! skipConfirm ) {
667- requestUninstallPlugin ( extension_name ) ;
668- return ; // 等待对话框回调
669- }
670-
671- // 执行卸载
672- toast ( tm ( "messages.uninstalling" ) + " " + extension_name , "primary" ) ;
673- try {
674- const res = await axios . post ( "/api/plugin/uninstall" , {
675- name : extension_name ,
676- delete_config : deleteConfig ,
677- delete_data : deleteData ,
678- } ) ;
679- if ( res . data . status === "error" ) {
680- toast ( res . data . message , "error" ) ;
631+ if ( ! optionsOrSkipConfirm ) {
632+ requestUninstallPlugin ( extensionName ) ;
681633 return ;
682634 }
683- Object . assign ( extension_data , res . data ) ;
684- toast ( res . data . message , "success" ) ;
685- getExtensions ( ) ;
686- } catch ( err ) {
687- toast ( err , "error" ) ;
635+ await performUninstall ( { kind : "normal" , id : extensionName } ) ;
636+ return ;
688637 }
638+
639+ const options =
640+ typeof optionsOrSkipConfirm === "object" && optionsOrSkipConfirm !== null
641+ ? optionsOrSkipConfirm
642+ : { } ;
643+ await performUninstall ( { kind : "normal" , id : extensionName } , options ) ;
689644 } ;
690645
691646 // 处理卸载确认对话框的确认事件
692- const handleUninstallConfirm = ( options ) => {
647+ const handleUninstallConfirm = async ( options ) => {
693648 const target = uninstallTarget . value ;
694649 if ( ! target ) return ;
695650
696- if ( target . type === "failed" ) {
697- uninstallFailedPlugin ( target . id , {
698- deleteConfig : options ?. deleteConfig || false ,
699- deleteData : options ?. deleteData || false ,
700- skipConfirm : true ,
701- } ) ;
702- } else if ( target . type === "normal" ) {
703- uninstallExtension ( target . id , options ) ;
651+ try {
652+ await performUninstall ( target , options ) ;
653+ } finally {
654+ uninstallTarget . value = null ;
655+ showUninstallDialog . value = false ;
704656 }
705-
706- uninstallTarget . value = null ;
707- showUninstallDialog . value = false ;
708657 } ;
709658
710659 const updateExtension = async ( extension_name , forceUpdate = false ) => {
@@ -908,7 +857,7 @@ export const useExtensionPage = () => {
908857
909858 const reloadPlugin = async ( plugin_name ) => {
910859 try {
911- reloadFeedback . message = "" ;
860+ clearReloadFeedback ( ) ;
912861 const res = await axios . post ( "/api/plugin/reload" , { name : plugin_name } ) ;
913862 if ( res . data . status === "error" ) {
914863 toast ( res . data . message || tm ( "messages.reloadFailed" ) , "error" ) ;
0 commit comments