Coze源碼分析-資源庫-刪除插件-前端源碼-核心邏輯

刪除插件邏輯

1. 刪除操作入口組件

刪除插件操作主要通過 usePluginConfig hook 中的 renderActions 方法實現,該方法返回 TableAction 組件來處理表格行的操作。

文件位置frontend/packages/studio/workspace/entry-base/src/pages/library/hooks/use-entity-configs/use-plugin-config.tsx

核心實現邏輯:

// 在 usePluginConfig hook 中
renderActions: (item: ResourceInfo) => {const deleteDisabled = !item.actions?.find(action => action.key === ActionKey.Delete,)?.enable;const deleteProps = {disabled: deleteDisabled,deleteDesc: I18n.t('library_delete_desc'),handler: async () => {await PluginDevelopApi.DelPlugin({ plugin_id: item.res_id });reloadList();Toast.success(I18n.t('Delete_success'));},};return (<TableActiondeleteProps={deleteProps}actionList={getCommonActions?.(item)}/>);
}

設計亮點

  • 權限控制:基于后端返回的 actions 數組動態控制按鈕狀態
  • 國際化支持:使用 I18n.t() 進行多語言支持
  • 操作集成:同時支持刪除、編輯等多種操作

2. 刪除插件的核心Hook實現

文件位置frontend/packages/studio/workspace/entry-base/src/pages/library/hooks/use-entity-configs/use-plugin-config.tsx

核心代碼:

import { useNavigate } from 'react-router-dom';
import { useState } from 'react';
import {ActionKey,PluginType,ResType,type ResourceInfo,
} from '@coze-arch/idl/plugin_develop';
import { I18n } from '@coze-arch/i18n';
import { PluginDevelopApi } from '@coze-arch/bot-api';
import { useBotCodeEditOutPlugin } from '@coze-agent-ide/bot-plugin/hook';
import { CreateFormPluginModal } from '@coze-agent-ide/bot-plugin/component';
import { IconCozPlugin } from '@coze-arch/coze-design/icons';
import { Menu, Tag, Toast, Table } from '@coze-arch/coze-design';const { TableAction } = Table;export const usePluginConfig: UseEntityConfigHook = ({spaceId,reloadList,getCommonActions,
}) => {const [showFormPluginModel, setShowFormPluginModel] = useState(false);const navigate = useNavigate();const { modal: editPluginCodeModal, open } = useBotCodeEditOutPlugin({modalProps: {onSuccess: reloadList,},});return {config: {renderActions: (item: ResourceInfo) => {const deleteDisabled = !item.actions?.find(action => action.key === ActionKey.Delete,)?.enable;const deleteProps = {disabled: deleteDisabled,deleteDesc: I18n.t('library_delete_desc'),handler: async () => {await PluginDevelopApi.DelPlugin({ plugin_id: item.res_id });reloadList();Toast.success(I18n.t('Delete_success'));},};return (<TableActiondeleteProps={deleteProps}actionList={getCommonActions?.(item)}/>);},},};
};

設計亮點

  • 異步狀態管理:使用 useRequest 管理刪除請求狀態
  • 錯誤處理:完善的成功/失敗回調處理
  • 用戶反饋:及時的Toast提示信息
  • 列表刷新:刪除成功后自動刷新資源列表

3. 刪除確認彈窗邏輯

文件位置frontend/packages/components/bot-semi/src/components/ui-table-action/index.tsx

核心代碼:

// 刪除確認彈窗的實現
<Popconfirmtrigger="click"okType="danger"title={i18n.t('delete_title')}content={i18n.t('plugin_delete_confirm_desc')}okText={i18n.t('confirm')}cancelText={i18n.t('cancel')}style={{ width: 350 }}icon={deleteProps?.popconfirm?.icon ?? <IconWaringRed />}{...deleteProps.popconfirm}onConfirm={deleteProps?.handler}disabled={deleteProps.disabled}
><span><Tooltipspacing={12}content={i18n.t('Delete')}position="top"{...deleteProps.tooltip}><UIIconButtondisabled={deleteProps.disabled}icon={<IconDeleteOutline className={styles.icon} />}style={iconColor('delete')}onClick={deleteProps.handleClick}data-testid="ui.table-action.delete"/></Tooltip></span>
</Popconfirm>

設計亮點

  • 權限控制:基于后端返回的actions數組動態控制刪除按鈕狀態
  • 確認機制:使用Popconfirm組件提供刪除確認彈窗
  • 錯誤處理:完善的錯誤提示和異常處理
  • 用戶反饋:及時的成功/失敗提示

4. TableAction 組件實現

文件位置@coze-arch/coze-design 包中的 Table.TableAction 組件

核心代碼:

import { Table } from '@coze-arch/coze-design';const { TableAction } = Table;// TableAction 組件的使用方式
<TableActiondeleteProps={{disabled: deleteDisabled,deleteDesc: I18n.t('library_delete_desc'),handler: async () => {await PluginDevelopApi.DelPlugin({ plugin_id: item.res_id });reloadList();Toast.success(I18n.t('Delete_success'));},}}actionList={getCommonActions?.(item)}
/>

設計亮點

  • 組件復用:來自 @coze-arch/coze-design 的統一表格操作組件
  • 配置化:通過 deleteProps 和 actionList 配置操作
  • 權限控制:基于后端返回的 actions 數組控制操作權限
  • 確認機制:內置刪除確認彈窗機制

5. 插件配置Hook(usePluginConfig)完整實現

文件位置frontend/packages/studio/workspace/entry-base/src/pages/library/hooks/use-entity-configs/use-plugin-config.tsx

管理插件的刪除功能和狀態的完整實現:

import { useNavigate } from 'react-router-dom';
import { useRef } from 'react';
import { useRequest } from 'ahooks';
import {ActionKey,ResType,type ResourceInfo,
} from '@coze-arch/idl/plugin_develop';
import { I18n } from '@coze-arch/i18n';
import { IconCozPlugin } from '@coze-arch/coze-design/icons';
import { Table, Menu, Toast } from '@coze-arch/coze-design';
import { EVENT_NAMES, sendTeaEvent } from '@coze-arch/bot-tea';
import { useFlags } from '@coze-arch/bot-flags';
import { PluginDevelopApi } from '@coze-arch/bot-api';
import { usePluginEditorModal } from '@coze-common/plugin-editor-modal';import { type UseEntityConfigHook } from './types';const { TableAction } = Table;export const usePluginConfig: UseEntityConfigHook = ({spaceId,isPersonalSpace = true,reloadList,getCommonActions,
}) => {const navigate = useNavigate();const [FLAGS] = useFlags();const recordRef = useRef<ResourceInfo | null>(null);const { open: openPluginEditor, node: pluginEditorModal } =usePluginEditorModal({spaceId,source: 'resource_library',onUpdateSuccess: reloadList,onPublish: ({ pluginId }) => {recordRef.current = {res_id: pluginId,};// 插件發布后的處理邏輯},});// 刪除插件的核心邏輯const { run: delPlugin } = useRequest((pluginId: string) =>PluginDevelopApi.DelPlugin({plugin_id: pluginId,}),{manual: true,onSuccess: () => {reloadList(); // 刪除成功后刷新列表Toast.success(I18n.t('Delete_success')); // 顯示成功提示},onError: (error) => {Toast.error(I18n.t('Delete_failed')); // 顯示失敗提示console.error('刪除插件失敗:', error);},},);return {modals: (<>{pluginEditorModal}</>),config: {typeFilter: {label: I18n.t('library_resource_type_plugin'),value: ResType.Plugin,},renderCreateMenu: () => (<Menu.Itemdata-testid="workspace.library.header.create.plugin"icon={<IconCozPlugin />}onClick={() => {sendTeaEvent(EVENT_NAMES.widget_create_click, {source: 'menu_bar',workspace_type: isPersonalSpace? 'personal_workspace': 'team_workspace',});openPluginEditor({mode: 'create',});}}>{I18n.t('create_new_plugin')}</Menu.Item>),target: [ResType.Plugin],onItemClick: (record: ResourceInfo) => {recordRef.current = record;const canEdit = record.actions?.find(action => action.key === ActionKey.Edit,)?.enable;openPluginEditor({mode: 'info',canEdit,editId: record.res_id || '',});},// 渲染表格操作列,包含刪除功能renderActions: (libraryResource: ResourceInfo) => (<TableActiondeleteProps={{// 根據權限控制刪除按鈕狀態disabled: !libraryResource.actions?.find(action => action.key === ActionKey.Delete,)?.enable,// 刪除確認描述deleteDesc: I18n.t('plugin_resource_delete_describ'),// 刪除處理函數handler: () => {delPlugin(libraryResource.res_id || '');},}}// 編輯操作editProps={{disabled: !libraryResource.actions?.find(action => action.key === ActionKey.Edit,)?.enable,handler: () => {openPluginEditor({mode: 'edit',editId: libraryResource.res_id || '',});},}}actionList={getCommonActions?.(libraryResource)}/>),},};
};
bot-api/package.json

文件位置frontend/packages/arch/bot-api/package.json

核心代碼:

{"name": "@coze-arch/bot-api","version": "0.0.1","description": "RPC wrapper for bot studio application","author": "fanwenjie.fe@bytedance.com","exports": {".": "./src/index.ts"}
}

代碼作用

  1. 包定義:定義了一個名為 @coze-arch/bot-api 的 npm 包,版本為 0.0.1,這是一個用于 bot studio 應用的 RPC 包裝器。
  2. API導出:在 frontend/packages/arch/bot-api/src/index.ts 中,PluginDevelopApi 被導出:
export { PluginDevelopApi } from './plugin-develop-api';

這允許通過 @coze-arch/bot-api 直接導入 PluginDevelopApi
3. API實現:在 src/plugin-develop-api.ts 中,PluginDevelopApi 是一個配置好的服務實例,它使用了 PluginDevelopService 和 axios 請求配置。

src/plugin-develop-api.ts

文件位置frontend/packages/arch/bot-api/src/plugin-develop-api.ts

核心代碼:

import PluginDevelopApiService from './idl/plugin_develop';
import { axiosInstance, type BotAPIRequestConfig } from './axios';// eslint-disable-next-line @typescript-eslint/naming-convention
export const PluginDevelopApi = new PluginDevelopApiService<BotAPIRequestConfig>({request: (params, config = {}) => {config.headers = Object.assign(config.headers || {}, {'Agw-Js-Conv': 'str',});return axiosInstance.request({ ...params, ...config });},
});
axiosInstance說明
  1. 全局共享:axiosInstance 在整個項目中是全局共享的
  2. bot-api 包中的導入frontend/packages/arch/bot-api/src/axios.ts 直接從 @coze-arch/bot-http 包導入了 axiosInstance
import {axiosInstance,isApiError,type AxiosRequestConfig,
} from '@coze-arch/bot-http';
  1. bot-http 包中的定義frontend/packages/arch/bot-http/src/axios.ts
export const axiosInstance = axios.create();

這里創建了一個全局的 axios 實例,與其他API請求使用的是同一個實例。

PluginDevelopApiService說明
  1. bot-api包中的導入路徑
import PluginDevelopApiService from './idl/plugin_develop';

實際指向 frontend/packages/arch/bot-api/src/idl/plugin_develop.ts
文件內容重新導出了 @coze-arch/idl/plugin_develop 包的所有內容,包括默認導出:

export * from '@coze-arch/idl/plugin_develop';
export { default as default } from '@coze-arch/idl/plugin_develop';
  1. idl包的模塊映射
    文件位置frontend/packages/arch/idl/package.json
{"name": "@coze-arch/idl","version": "0.0.1","description": "IDL files for bot studio application","author": "fanwenjie.fe@bytedance.com","exports": {"./plugin_develop": "./src/auto-generated/plugin_develop/index.ts"}
}

代碼作用:將 @coze-arch/idl/plugin_develop 映射到實際文件路徑 frontend/packages/arch/idl/src/auto-generated/plugin_develop/index.ts

6. 刪除插件操作的完整流程

刪除插件的完整流程如下:

用戶前端界面TableAction組件usePluginConfigPluginDevelopApi后端服務點擊表格行的"..."按鈕渲染操作菜單點擊"刪除"選項顯示確認彈窗確認刪除調用delPlugin函數檢查刪除權限調用DelPlugin接口發送刪除插件請求返回刪除結果返回操作結果顯示成功/失敗提示刷新列表數據(reloadList)用戶前端界面TableAction組件usePluginConfigPluginDevelopApi后端服務

流程說明

  1. 權限檢查:基于后端返回的 actions 數組判斷是否有刪除權限
  2. 確認機制:通過 Popconfirm 組件進行二次確認
  3. API調用:使用 PluginDevelopApi.DelPlugin 執行刪除操作
  4. 狀態更新:刪除成功后自動刷新資源列表
  5. 用戶反饋:通過 Toast 組件顯示操作結果

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/96309.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/96309.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/96309.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

第一代:嵌入式本地狀態(Flink 1.x)

最初的架構將狀態以 JVM Heap 對象的形式存儲在 TaskManager 的內存中。對于小規模數據集&#xff0c;這種方式效果良好&#xff0c;但隨著狀態大小的增長超出內存&#xff0c;將所有狀態保存在內存中變得成本高昂且不穩定。 為了解決狀態規模增長的問題&#xff0c;引入了一種…

跨境金融數據對接實踐:印度NSE/BSE股票行情API集成指南

跨境金融數據對接實踐&#xff1a;印度NSE/BSE股票行情API集成指南 關鍵詞&#xff1a;印度股票數據對接 NSE實時行情 BSE證券接口 金融API開發 Python請求示例一、印度股市數據源技術解析&#xff08;核心價值&#xff09; 印度兩大交易所數據獲取難點&#xff1a; 時區差異&a…

AFSim2.9.0學習筆記 —— 1、AFSim及完整工具介紹(文末附:完整afsim2.9.0源碼、編譯好的完整工具包、中文教材等)

&#x1f514; AFSim2.9.0 相關技術、疑難雜癥文章合集&#xff08;掌握后可自封大俠 ?_?&#xff09;&#xff08;記得收藏&#xff0c;持續更新中…&#xff09; AFSim介紹 AFSim&#xff08;Advanced Framework for Simulation Integration & Modeling【高級仿真集成與…

ArcGIS學習-18 實戰-降雨量空間分布插值分析

設置環境加載要素投影查看要素&#xff0c;發現均不是投影數據&#xff0c;但都是地理坐標都是WGS1984使用工具進行批量投影然后新建空地圖&#xff0c;重新加載確認圖層的投影與柵格數據一致插值樣條法得到反距離權重法插值得到克里金法插值得到

HarmonyOS應用開發:深入理解聲明式UI與彈窗交互的最佳實踐

HarmonyOS應用開發&#xff1a;深入理解聲明式UI與彈窗交互的最佳實踐 引言 隨著HarmonyOS 4.0的發布及后續版本的演進&#xff0c;華為的分布式操作系統已經進入了全新的發展階段。基于API 12及以上的開發環境為開發者提供了更強大、更高效的開發工具和框架。在HarmonyOS應用…

探索Java并發編程--從基礎到高級實踐技巧

Thread&#xff08;線程&#xff09;線程 程序執行的最小單位&#xff08;一個進程至少有一個線程&#xff09;。線程內有自己的執行棧、程序計數器&#xff08;PC&#xff09;&#xff0c;但與同進程內其他線程共享堆內存與進程資源 在java中&#xff0c;線程由java.lang.Thr…

Go語言實戰案例-開發一個Markdown轉HTML工具

這個小工具可以把 .md 文件轉換為 .html 文件&#xff0c;非常適合寫筆記、博客或者快速預覽 Markdown 內容。&#x1f4cc; 案例目標? 讀取一個 Markdown 文件? 使用開源庫將 Markdown 轉換為 HTML? 將 HTML 輸出到新文件中&#x1f4e6; 所需庫我們用 goldmark 這個 Markd…

基于51單片機的太陽能鋰電池充電路燈

基于51單片機的太陽能鋰電池充電路燈系統設計 1 系統功能介紹 本設計以 STC89C52單片機 為核心&#xff0c;構建了一個能夠利用太陽能為鋰電池充電并智能控制LED路燈的系統。系統結合了 光照檢測電路、LED燈電路、按鍵檢測電路、太陽能充電電路 等模塊&#xff0c;實現了節能、…

PAT 1178 File Path

這一題的大意是給出了一個windows的文件夾目錄&#xff0c;讓我們按照所屬的目錄關系&#xff0c;來找相應的目錄是否存在&#xff0c;如果存在&#xff0c;就輸出找到該文件的路徑&#xff0c;如果不存在輸出error 我的思路是用合適的樹形結構保存下來目錄的所屬關系&#xff…

云原生部署_k8s入門

K8S官網文檔&#xff1a;&#xfeff;https://kubernetes.io/zh/docs/home/Kubernetes是什么Kubernetes 是用于自動部署、擴縮和管理容器化應用程序的開源系統。 Kubernetes 源自 &#xff0c;Google 15 年生產環境的運維經驗同時凝聚了社區的最佳創意和實踐。簡稱K8s.Kubernet…

實戰項目-----Python+OpenCV 實現對視頻的椒鹽噪聲注入與實時平滑還原”

實戰項目實現以下功能&#xff1a;功能 1&#xff1a;為視頻每一幀添加椒鹽噪聲作用&#xff1a;模擬真實環境中圖像傳輸或采集時可能出現的噪聲。實現方式&#xff1a;讀取視頻的每一幀。隨機選擇 10000 個像素點&#xff0c;將其設置為黑色&#xff08;0&#xff09;或白色&a…

Day42 PHP(mysql注入、跨庫讀取)

一、sql注入基本原理&#xff1a;沒有對用戶輸入的數據進行限制&#xff0c;導致數據庫語句可以做什么&#xff0c;用戶就可以做什么。取決于不同數據庫的不同查詢語言&#xff0c;所以為什么有mysql注入/orcale注入等等。步驟&#xff1a;【access】表名&#xff08;字典爆破來…

機器人控制器開發(部署——軟件打包備份更新)

文章總覽 為什么做備份更新 為機器人控制器設計一套打包備份更新機制&#xff0c;為控制器的批量生產和產品與項目落地做準備。 當某個模塊出現bug需要升級時&#xff0c;用戶可以快速獲取正確的bak包并導入到控制器中重啟生效。 如果沒有做好軟件的備份更新機制&#xff0c…

LaTeX TeX Live 安裝與 CTAN 國內鏡像配置(Windows / macOS / Linux 全流程)

這是一份面向國內環境的 LaTeX 從零到可編譯 指南&#xff1a;覆蓋 TeX Live / MacTeX 安裝、PATH 配置、CTAN 國內鏡像&#xff08;清華/北外/上交/中科大等&#xff09;一鍵切換與回滾、常見坑位&#xff08;權限、鏡像路徑、版本切換&#xff09;、以及 XeLaTeX/latexmk 的實…

WhoisXML API再次榮登2025年美國Inc. 5000快速成長企業榜單

WhoisXML API非常自豪地宣布&#xff0c;我們再次榮登美國權威榜單——2025年Inc.5000全美成長最快的私營企業之一。今年&#xff0c;公司在地區排名中位列第119名&#xff0c;在全美總體排名中位列第4,271名。Inc. 5000榜單要求參評企業必須保持獨立運營&#xff0c;并在2021至…

Elasticsearch面試精講 Day 9:復合查詢與過濾器優化

【Elasticsearch面試精講 Day 9】復合查詢與過濾器優化 在Elasticsearch的搜索體系中&#xff0c;復合查詢&#xff08;Compound Queries&#xff09;與過濾器&#xff08;Filters&#xff09;優化是構建高效、精準搜索邏輯的核心能力。作為“Elasticsearch面試精講”系列的第…

Android使用ReactiveNetwork監聽網絡連通性

引入庫 implementation com.github.pwittchen:reactivenetwork-rx2:3.0.8監聽網絡連接變更ReactiveNetwork.observeNetworkConnectivity(context).subscribeOn(Schedulers.io())// ... // anything else what you can do with RxJava.observeOn(Schedulers.computation()).subs…

基于阿里云部署 RustDesk 自托管服務器

基于阿里云部署 RustDesk 自托管服務器一、背景與需求場景二、什么是 RustDesk&#xff1f;為什么選擇自托管&#xff1f;2.1 RustDesk 是什么&#xff1f;2.2 為什么選擇自托管&#xff1f;三、環境準備與架構說明四、操作步驟4.1 在阿里云上安裝 RustDesk 服務端4.1.1 下載并…

細說分布式ID

針對高并發寫&#xff0c;分布式ID是其業務基礎&#xff0c;本文從一個面試題細細展開。面試官&#xff1a;1.對于Mysql的InnoDB引擎下&#xff0c;自增ID和UUID作為主鍵各自有什么優劣&#xff0c;對于一張表的主鍵你建議使用哪種ID&#xff1f;2.除了UUID是否還了解其他類型的…

2025年大數據專業證書報考指南:專科學歷必看的8大選擇?

對于大專學歷的同學來說&#xff0c;2025年進入大數據行業是一個充滿機遇的選擇。大數據領域發展迅速&#xff0c;各類證書能夠幫助求職者提升專業能力、增強就業競爭力。其中最推薦的是CDA數據分析師&#xff0c;這個證書適應了未來數字化經濟和AI發展趨勢&#xff0c;難度不高…