当前位置: 首页 > news >正文

Coze源码分析-资源库-编辑工作流-前端源码-核心组件

概述

本文深入分析Coze Studio中用户创建工作流功能的前端实现。该功能允许用户在资源库中创建、编辑和管理工作流资源,为开发者提供了强大的自动化流程构建和业务逻辑编排能力。通过对源码的详细解析,我们将了解从资源库入口到工作流配置弹窗的完整架构设计、组件实现、状态管理和用户体验优化等核心技术要点。

功能特性

核心功能

  • 工作流创建:支持自定义工作流名称、描述和图标配置
  • 工作流管理:提供工作流列表展示、编辑和删除功能
  • 多种工作流类型:支持Workflow(通用工作流)和ChatFlow(对话流)两种模式
  • 模板支持:支持从模板创建工作流,快速构建业务场景
  • 状态管理:支持工作流启用/禁用状态切换和协作模式

用户体验特性

  • 即时反馈:操作结果实时展示和验证
  • 表单验证:完善的工作流信息验证机制
  • 便捷操作:支持一键创建、快速编辑和复制功能
  • 国际化支持:多语言界面适配

技术架构

整体架构设计

┌─────────────────────────────────────────────────────────────┐
│                      工作流管理模块                          │
├─────────────────────────────────────────────────────────────┤
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────┐  │
│  │ LibraryPage │  │LibraryHeader│  │CreateWorkflow       │  │
│  │ (资源库页面) │  │ (添加按钮)  │  │     Modal           │  │
│  └─────────────┘  └─────────────┘  │  (创建/编辑弹窗)    │  │
│  ┌─────────────┐  ┌─────────────┐  └─────────────────────┘  │
│  │BaseLibrary  │  │   Table     │  ┌─────────────────────┐  │
│  │    Page     │  │ (资源列表)  │  │WorkflowModal        │  │
│  └─────────────┘  └─────────────┘  │(模板选择弹窗)       │  │
│                                    └─────────────────────┘  │
├─────────────────────────────────────────────────────────────┤
│                      状态管理层                             │
│  ┌─────────────────┐  ┌─────────────────────────────────┐  │
│  │useWorkflowConfig │  │    useWorkflowResourceAction    │  │
│  │  (配置逻辑)      │  │       useCreateWorkflowModal    │  │
│  └─────────────────┘  └─────────────────────────────────┘  │
├─────────────────────────────────────────────────────────────┤
│                       API服务层                            │
│  ┌─────────────────────────────────────────────────────────┐
│  │              Workflow API                               │
│  │         工作流创建/删除/更新相关API接口                    │
│  └─────────────────────────────────────────────────────────┘
└────────────────────────────────────────────────────────────┘

核心模块结构

frontend/
├── apps/coze-studio/src/
│   └── pages/
│       ├── library.tsx            # 资源库入口页面
│       ├── plugin/                # 插件相关页面
│       └── develop.tsx            # 开发页面
├── packages/studio/workspace/
│   ├── entry-adapter/src/pages/library/
│   │   └── index.tsx              # LibraryPage适配器组件
│   └── entry-base/src/pages/library/
│       ├── index.tsx              # BaseLibraryPage核心组件
│       ├── components/
│       │   └── library-header.tsx # LibraryHeader头部组件
│       └── hooks/use-entity-configs/
│           └── use-workflow-config.tsx  # 工作流配置Hook
├── packages/workflow/
│   ├── components/src/
│   │   ├── hooks/use-workflow-resource-action/
│   │   │   ├── index.tsx          # useWorkflowResourceAction Hook
│   │   │   └── use-create-workflow-modal.tsx # 创建工作流弹窗Hook
│   │   ├── workflow-modal/        # 工作流模板选择弹窗
│   │   └── workflow-edit/         # 工作流编辑组件(包含CreateWorkflowModal)
│   ├── playground/src/            # 工作流画布和编辑器
│   └── base/src/
│       ├── api/                   # 工作流API定义
│       └── types/                 # 工作流类型定义
├── packages/arch/idl/src/auto-generated/
│   ├── workflow_api/              # 工作流API相关类型
│   └── plugin_develop/            # 插件开发相关类型
└── packages/arch/bot-api/src/└── workflow-api.ts            # WorkflowApi实例定义

用户创建工作流流程概述

用户登录Coze Studio↓点击"资源库"菜单↓LibraryPage 组件加载↓点击右上角"+"按钮↓LibraryHeader 显示创建菜单↓点击"工作流"或"对话流"选项↓openCreateModal(WorkflowMode) 触发↓CreateWorkflowModal 弹窗显示↓用户选择工作流模式(Workflow/ChatFlow)↓用户输入工作流名称(name字段)↓用户输入工作流描述(description字段)↓用户选择工作流图标和配置项↓表单验证(名称必填,描述可选)↓用户点击"创建"按钮↓createWorkflow() 触发↓工作流创建API调用↓后端创建新工作流资源↓onSuccess() 处理成功响应↓导航到工作流编辑器页面↓刷新资源库列表

该流程包含多层验证和处理:

  1. 前端表单验证:通过Form组件进行名称等必填字段验证
  2. 工作流类型选择:支持Workflow(通用工作流)和ChatFlow(对话流)两种模式
  3. API调用:通过workflow相关API处理工作流创建
  4. 成功处理:创建成功后直接导航到工作流编辑器页面进行流程设计
  5. 状态管理:通过useWorkflowConfig和useWorkflowResourceAction Hook管理弹窗状态和数据流
    整个流程确保了工作流创建的便捷性和用户体验的流畅性。

核心组件实现

组件层次结构

插件编辑功能涉及多个层次的组件:

  1. LibraryPage组件:资源库主页面
  2. BaseLibraryPage组件:资源库核心逻辑
  3. LibraryHeader组件:包含创建按钮的头部
  4. usePluginConfig Hook:插件配置和状态管理
  5. useBotCodeEditOutPlugin Hook:代码插件编辑弹窗管理
  6. CreateCodePluginModal组件:代码插件编辑弹窗
  7. CreateFormPluginModal组件:表单插件编辑弹窗

1. 资源库入口组件(LibraryPage)

文件位置:frontend/packages/studio/workspace/entry-adapter/src/pages/library/index.tsx

作为资源库的适配器组件,整合各种资源配置,包括插件配置:

import { type FC, useRef } from 'react';import {BaseLibraryPage,useDatabaseConfig,usePluginConfig,useWorkflowConfig,usePromptConfig,useKnowledgeConfig,
} from '@coze-studio/workspace-base/library';export const LibraryPage: FC<{ spaceId: string }> = ({ spaceId }) => {const basePageRef = useRef<{ reloadList: () => void }>(null);const configCommonParams = {spaceId,reloadList: () => {basePageRef.current?.reloadList();},};const { config: pluginConfig, modals: pluginModals } =usePluginConfig(configCommonParams);const { config: workflowConfig, modals: workflowModals } =useWorkflowConfig(configCommonParams);const { config: knowledgeConfig, modals: knowledgeModals } =useKnowledgeConfig(configCommonParams);const { config: promptConfig, modals: promptModals } =usePromptConfig(configCommonParams);const { config: databaseConfig, modals: databaseModals } =useDatabaseConfig(configCommonParams);return (<><BaseLibraryPagespaceId={spaceId}ref={basePageRef}entityConfigs={[pluginConfig,workflowConfig,knowledgeConfig,promptConfig,databaseConfig,]}/>{pluginModals}{workflowModals}{promptModals}{databaseModals}{knowledgeModals}</>);
};

设计亮点

  • 状态集中管理:通过 useWorkflowConfig Hook统一管理组件状态
  • 组件解耦:各子组件职责明确,通过props进行通信
  • 数据流清晰:单向数据流,状态变更可追踪

2. 插件配置Hook(usePluginConfig)

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

管理插件资源的配置和编辑状态,是插件编辑功能的核心Hook:

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';export const usePluginConfig: UseEntityConfigHook = ({spaceId,reloadList,getCommonActions,
}) => {const [showFormPluginModel, setShowFormPluginModel] = useState(false);const navigate = useNavigate();const { modal: editPluginCodeModal, open } = useBotCodeEditOutPlugin({modalProps: {onSuccess: reloadList,},});return {modals: (<><CreateFormPluginModalisCreate={true}visible={showFormPluginModel}onSuccess={pluginID => {navigate(`/space/${spaceId}/plugin/${pluginID}`);reloadList();}}onCancel={() => {setShowFormPluginModel(false);}}/>{editPluginCodeModal}</>),config: {typeFilter: {label: I18n.t('library_resource_type_plugin'),value: ResType.Plugin,},renderCreateMenu: () => (<Menu.Itemdata-testid="workspace.library.header.create.plugin"icon={<IconCozPlugin />}onClick={() => {setShowFormPluginModel(true);}}>{I18n.t('library_resource_type_plugin')}</Menu.Item>),target: [ResType.Plugin],onItemClick: (item: ResourceInfo) => {if (item.res_type === ResType.Plugin &&item.res_sub_type === 2 //Plugin:1-Http; 2-App; 6-Local;) {const disable = !item.actions?.find(action => action.key === ActionKey.Delete,)?.enable;open(item.res_id || '', disable);} else {navigate(`/space/${spaceId}/plugin/${item.res_id}`);}},renderItem: item => (<BaseLibraryItemresourceInfo={item}defaultIcon={PluginDefaultIcon}tag={item.res_type === ResType.Plugin &&item.res_sub_type === PluginType.LOCAL ? (<Tagdata-testid="workspace.library.item.tag"color="cyan"size="mini"className="flex-shrink-0 flex-grow-0">{I18n.t('local_plugin_label')}</Tag>) : null}/>),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)}/>);},},};
};

核心功能

  • 插件类型管理:支持不同类型插件的处理逻辑
  • 编辑弹窗集成:集成代码插件编辑弹窗
  • 菜单渲染:在创建菜单中显示插件选项
  • 本地插件标识:为本地开发的插件显示特殊标签
  • 资源操作:集成插件的点击、编辑、删除等操作
  • 权限控制:根据操作权限控制删除功能的可用性

3. 代码插件编辑Hook(useBotCodeEditOutPlugin)

文件位置:frontend/packages/agent-ide/bot-plugin/export/src/component/bot_edit/plugin-edit/index.tsx

管理代码插件编辑弹窗的状态和编辑逻辑:

export const useBotCodeEditOutPlugin = ({modalProps,
}: {modalProps: Pick<CreatePluginProps, 'onSuccess'>;
}) => {const [pluginInfo, setPluginInfo] = useState<PluginInfoProps>({});const [modalVisible, setModalVisible] = useState(false);const [editable, setEditable] = useState(false);const [disableEdit, setDisableEdit] = useState(false);const pluginId = pluginInfo?.plugin_id || '';const action = useMemo(() => {if (disableEdit) {return null;}return (<div className={styles.actions}>{editable ? (<UIButtononClick={() => {setEditable(false);unlockOutPluginContext(pluginId);}}>{I18n.t('Cancel')}</UIButton>) : (<UIButtontheme="solid"onClick={async () => {const isLocked = await checkOutPluginContext(pluginId);if (isLocked) {return;}setEditable(true);}}>{I18n.t('Edit')}</UIButton>)}</div>);}, [editable, pluginId, disableEdit]);useEffect(() => {if (modalVisible) {setEditable(false);}}, [modalVisible]);const modal = (<CreateCodePluginModal{...modalProps}editInfo={pluginInfo}isCreate={false}visible={modalVisible}onCancel={() => {setModalVisible(false);if (!disableEdit) {unlockOutPluginContext(pluginId);}}}disabled={!editable}actions={action}/>);const open = useCallback(async (id: string, disable: boolean) => {const res = await PluginDevelopApi.GetPluginInfo({plugin_id: id || '',});setPluginInfo({plugin_id: id,code_info: {plugin_desc: res.code_info?.plugin_desc,openapi_desc: res.code_info?.openapi_desc,client_id: res.code_info?.client_id,client_secret: res.code_info?.client_secret,service_token: res.code_info?.service_token,},});setDisableEdit(disable);setModalVisible(true);}, []);return { modal, open };
};

核心功能

  • 状态管理:管理插件信息、编辑状态和弹窗可见性
  • 插件锁定机制:编辑前自动检查和锁定插件,防止多人同时编辑
  • 权限控制:根据disableEdit参数控制编辑权限
  • 插件信息加载:通过API获取插件详细信息
  • 弹窗渲染:渲染代码插件编辑弹窗组件
  • 解锁机制:编辑完成或取消时自动解锁插件

4. 插件锁定检查(checkOutPluginContext)

文件位置:frontend/packages/studio/stores/bot-plugin/src/utils/api.ts

负责检查插件的锁定状态,确保编辑安全性:

export const checkOutPluginContext = async (pluginId: string) => {const resp = await PluginDevelopApi.CheckAndLockPluginEdit({plugin_id: pluginId,});if (resp.code !== 0) {return false;}const { data } = resp;const user = data?.user;/*** Someone occupies & not themselves*/if (data?.Occupied && user && !user.self) {UIModal.info({okText: I18n.t('guidance_got_it'),title: I18n.t('plugin_team_edit_tip_unable_to_edit'),content: `${user.name}(${user.space_roly_type}) ${I18n.t('plugin_team_edit_tip_another_user_is_editing')}`,hasCancel: false,});return true;}return false;
};

核心功能

  • 锁定检查:检查插件是否被其他用户锁定
  • 用户提示:当插件被其他用户占用时,显示友好的提示信息
  • 权限验证:确保只有合法用户可以编辑插件
  • 冲突避免:通过锁定机制避免编辑冲突
http://www.dtcms.com/a/438618.html

相关文章:

  • 胡恩全10.3作业
  • 长沙门户网站如何在微信上做小程序
  • Linux网络Socket编程TCP
  • 神卓云监控 K900 在海康 / 大华异地监控场景中的应用实践
  • 深圳专业网站开发上海公司建立网站吗
  • Photoshop - Photoshop 工具栏(1)移动工具
  • 怎么给网站做域名重定向公司网站建设合规吗
  • [创业之路-664]:越是通用的东西,适用的范围越广,解决问题的受众越多,解决方案的提供商越垄断,强者恒强。因此,通用 人工智能的服务是少数大厂的游戏。
  • id创建网站桐乡市城乡规划建设局网站
  • 网站建设谈单情景对话html响应式网页设计代码范文
  • 设计图片免费素材网站做网站运营需要什么资源
  • gas 优化
  • [创业之路-667]:第四次工业革命(智能革命)未来将创造大量的财富,普通人通过哪些方式参与这些财富的创造与分享?
  • New StarsAI1.0.1
  • 青岛高端网站制作培训机构网站建设要求
  • Spring AI 实战:构建智能对话系统
  • Font Awesome 医疗图标
  • 同时显示文件夹大小的其它“免费”方案
  • Vue--Vue基础(二)
  • 高端网站建设搭建服装定制尺寸量身表
  • linux banner 设计
  • WordPress之家
  • php企业网站开发好学么承德网
  • 从技术史看:Unix 从何而来
  • qt 可以做网站吗优化师简历
  • DreamControl——结合扩散模型和RL的全身人形控制:利用在人体运动数据上训练得到的扩散先验,随后在仿真中引导RL策略完成特定任务
  • Spring Boot 实现邮件发送功能:整合 JavaMailSender 与 FreeMarker 模板
  • 新手理解的电子IO口
  • 网站开发完整项目案例做视频网站视频短片
  • 怎样自己做一个网站想创建一个网站