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

Coze源码分析-资源库-编辑工作流-后端源码-IDL/API/应用服务层

前言

本文将深入分析Coze Studio项目中用户编辑工作流功能的后端实现。当用户登录Coze平台后,点击"资源库" → 接着在表格中点击要编辑的工作流行,触发的是一个完整的工作流资源编辑流程。工作流作为AI应用开发的核心组件,其编辑操作涉及权限验证、数据更新和多个后端服务层的协同工作。通过源码解读,我们将深入理解工作流编辑功能在整个Coze Studio后端架构中的设计思路和技术实现细节。

项目架构概览

工作流编辑功能架构设计

Coze Studio的工作流编辑功能采用了经典的分层架构模式,专门针对工作流资源的安全编辑进行了优化设计。整个架构围绕工作流的权限验证、数据更新和版本管理展开:

┌─────────────────────────────────────────────────────────────┐
│                    IDL接口定义层                             │
│  ┌─────────────┐  ┌─────────────┐    ┌─────────────┐        │
│  │ base.thrift │  │workflow.    │    │ api.thrift  │        │
│  │             │  │thrift       │    │             │        │
│  │             │                │    │             │        │
│  └─────────────┘  └─────────────┘    └─────────────┘        │
└─────────────────────────────────────────────────────────────┘↓
┌─────────────────────────────────────────────────────────────┐
│                    API网关层                                 │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐          │
│  │   Handler   │  │   Router    │  │ Middleware  │          │
│  │   处理器     │  │   路由      │  │   中间件     │          │
│  └─────────────┘  └─────────────┘  └─────────────┘          │
└─────────────────────────────────────────────────────────────┘↓
┌─────────────────────────────────────────────────────────────┐
│                   应用服务层                                 │
│  ┌─────────────────────────────────────────────────────┐    │
│  │         ApplicationService                          │    │
│  │     SaveWorkflow UpdateWorkflowMeta                 │    │
│  └─────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘↓
┌─────────────────────────────────────────────────────────────┐
│                   领域服务层                                 │
│  ┌─────────────────────────────────────────────────────┐    │
│  │               WorkflowService                        │    │
│  │                ┌─────────────────┐                  │    │
│  │                │Save             │                  │    │
│  │                │UpdateMeta       │                  │    │
│  │                └─────────────────┘                  │    │
│  └─────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘↓
┌─────────────────────────────────────────────────────────────┐
│                   数据访问层                                 │
│  ┌─────────────────────────────────────────────────────┐    │
│  │              WorkflowRepository                      │    │
│  │  ┌──── ─────── ──── ──┐  ┌─────────────────────────┐│    │
│  │  │WorkflowDAO         │  │workflow_draft.gen.go    ││    │
│  │  │UpdateWorkflow      │  │workflow_meta.gen.go     ││    │
│  │  └──── ─────── ─── ───┘  └─────────────────────────┘│    │
│  └─────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘↓
┌─────────────────────────────────────────────────────────────┐
│                   基础设施层                                 │
│              ┌─ ─ ─── ─ ── ── ─ ─ ─┐                        │
│              │       gorm.DB       │                        │
│              │ es.Client redisImpl │                        │
│              └── ─ ── ── ─ ── ── ─ ┘                        │
└─────────────────────────────────────────────────────────────┘↓
┌─────────────────────────────────────────────────────────────┐
│                   存储服务层                                 │
│  ┌─────────────────────────────────────────────────────┐    │
│  │       MySQL数据库       Redis数据库                  │    │
│  │            ElasticSearch数据库                      │    │
│  └─────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘

工作流编辑流程核心组件

API路由映射:

  • POST /api/workflow_api/save - 保存工作流画布内容
  • POST /api/workflow_api/update_meta - 更新工作流元数据
  • POST /api/workflow_api/canvas - 获取工作流画布信息

核心数据模型:

// 文件位置:backend/domain/workflow/entity/workflow.go
type WorkflowInfo struct {ID            int64WorkflowID    stringName          stringDesc          stringIconURI       stringSpaceID       int64CreatorID     int64Canvas        stringInputParams   stringOutputParams  stringTestRunSuccess boolModified      boolStatus        WorkFlowStatusFlowMode      WorkflowModeUpdateTime    int64CreateTime    int64
}// 文件位置:backend/domain/workflow/internal/repo/dal/model/workflow_draft.gen.go
type WorkflowDraft struct {ID             int64          `gorm:"column:id;primaryKey;comment:workflow ID" json:"id"`Canvas         string         `gorm:"column:canvas;not null;comment:Front end schema" json:"canvas"`InputParams    string         `gorm:"column:input_params;comment:Input schema" json:"input_params"`OutputParams   string         `gorm:"column:output_params;comment:Output parameter schema" json:"output_params"`TestRunSuccess bool           `gorm:"column:test_run_success;not null;comment:0 not running, 1 running successfully" json:"test_run_success"`Modified       bool           `gorm:"column:modified;not null;comment:0 has not been modified, 1 has been modified" json:"modified"`UpdatedAt      int64          `gorm:"column:updated_at;autoUpdateTime:milli;comment:Update Time in Milliseconds" json:"updated_at"`DeletedAt      gorm.DeletedAt `gorm:"column:deleted_at;comment:Delete Time" json:"deleted_at"`CommitID       string         `gorm:"column:commit_id;not null;comment:used to uniquely identify a draft snapshot" json:"commit_id"`
}

1. IDL接口定义层

IDL基础类型定义(base.thrift)

文件位置:idl/base.thrift
核心代码:

namespace py base
namespace go base
namespace java com.bytedance.thrift.basestruct TrafficEnv {1: bool   Open = false,2: string Env  = ""   ,
}struct Base {1:          string             LogID      = "",2:          string             Caller     = "",3:          string             Addr       = "",4:          string             Client     = "",5: optional TrafficEnv         TrafficEnv     ,6: optional map<string,string> Extra          ,
}struct BaseResp {1:          string             StatusMessage = "",2:          i32                StatusCode    = 0 ,3: optional map<string,string> Extra             ,
}

文件作用:
定义了Coze Studio项目中所有接口的基础数据结构,作为其他IDL文件的依赖基础。

工作流接口定义(workflow.thrift)

文件位置:idl/workflow/workflow.thrift

当Coze用户登录平台后点击"资源库" → 接着在表格中点击要编辑的工作流行时,前端会调用工作流编辑相关的接口。该文件定义了工作流编辑的核心数据结构和接口。

工作流基本结构定义
enum WorkflowMode {Workflow  = 0   ,  // 标准工作流Imageflow = 1   ,  // 图像工作流SceneFlow = 2   ,  // 场景工作流ChatFlow  = 3   ,  // 对话工作流All       = 100 ,  // 仅用于查询
}enum WorkFlowDevStatus {CanNotSubmit = 1,  // 不可提交(流程未提交且最新的版本未test run成功)CanSubmit = 2,     // 未提交且可提交(流程未提交但最新的版本已经test run成功)HadSubmit = 3,     // 已提交Deleted = 4,       // 删除
}struct Workflow {1 :          string             workflow_id                ,  // 流程id,全局唯一2 :          string             name                       ,  // 流程名称3 :          string             desc                       ,  // 流程描述4 :          string             url                        ,  // 流程URL5 :          string             icon_uri                   ,  // 流程图标URL6 :          WorkFlowDevStatus  status                     ,  // 流程的提交状态7 :          WorkFlowType       type                       ,  // 类型,1:官方模版8 :          string             plugin_id                  ,  // workflow对应的插件id9 :          i64                create_time                ,  // 创建时间10:          i64                update_time                ,  // 更新时间11:          SchemaType         schema_type                ,  // 模式类型17: optional string             space_id                   ,  // 空间ID18: optional string             interface_str              ,  // 流程出入参19: optional string             schema_json                ,  // 新版workflow的定义schema20:          Creator            creator                    ,  // workflow创作者信息21:          PersistenceModel   persistence_model          ,  // 存储模型22:          WorkflowMode       flow_mode                  ,  // workflow or imageflow,默认值为workflow
}
保存工作流接口
struct SaveWorkflowRequest {1: required string workflow_id (api.body="workflow_id", api.js_conv="true")2: required string schema     (api.body="schema")3: optional string space_id   (api.body="space_id", api.js_conv="true")255: optional base.Base Base
}struct SaveWorkflowResponse {1: optional SaveWorkflowData data253: required i64    code254: required string msg255: required base.BaseResp BaseResp
}struct SaveWorkflowData {
}
更新工作流元数据接口
struct UpdateWorkflowMetaRequest {1: required string workflow_id (api.body="workflow_id", api.js_conv="true")2: optional string name        (api.body="name")3: optional string desc        (api.body="desc")4: optional string icon_uri    (api.body="icon_uri")5: optional string space_id    (api.body="space_id", api.js_conv="true")6: optional WorkflowMode flow_mode (api.body="flow_mode")255: optional base.Base Base
}struct UpdateWorkflowMetaResponse {253: required i64    code254: required string msg255: required base.BaseResp BaseResp
}#### 获取画布信息接口
```thrift
struct GetCanvasInfoRequest {1: required string workflow_id (api.body="workflow_id", api.js_conv="true")2: optional string space_id    (api.body="space_id", api.js_conv="true")255: optional base.Base Base
}struct GetCanvasInfoResponse {1: optional GetCanvasInfoData data253: required i64    code254: required string msg255: required base.BaseResp BaseResp
}struct GetCanvasInfoData {1: required string canvas2: required WorkFlowDevStatus status3: required VCSCanvasType vcs_canvas_type4: optional string input_params5: optional string output_params6: optional i64 last_test_run_time
}
工作流服务接口定义
service WorkflowService {// 保存工作流SaveWorkflowResponse SaveWorkflow(1:SaveWorkflowRequest request)(api.post='/api/workflow_api/save', api.category="workflow",agw.preserve_base="true")// 更新工作流元数据UpdateWorkflowMetaResponse UpdateWorkflowMeta(1:UpdateWorkflowMetaRequest request)(api.post='/api/workflow_api/update_meta', api.category="workflow",agw.preserve_base="true")// 获取画布信息GetCanvasInfoResponse GetCanvasInfo(1:GetCanvasInfoRequest request)(api.post='/api/workflow_api/canvas', api.category="workflow",agw.preserve_base="true")// 其他工作流相关接口...
}1  :          i64           code        ,2  :          string        msg         ,3  :          i32           edit_version,255: optional base.BaseResp BaseResp    ,
}
工作流服务接口定义
service WorkflowService {// 保存工作流SaveWorkflowResponse SaveWorkflow(1:SaveWorkflowRequest request)(api.post='/api/workflow_api/save', api.category="workflow",agw.preserve_base="true")// 更新工作流元数据UpdateWorkflowMetaResponse UpdateWorkflowMeta(1:UpdateWorkflowMetaRequest request)(api.post='/api/workflow_api/update_meta', api.category="workflow",agw.preserve_base="true")// 获取画布信息GetCanvasInfoResponse GetCanvasInfo(1:GetCanvasInfoRequest request)(api.post='/api/workflow_api/canvas', api.category="workflow",agw.preserve_base="true")// 其他工作流相关接口...
}### IDL主API服务聚合文件(api.thrift)
文件位置:`idl/api.thrift`该文件是整个Coze项目的API服务聚合入口点,负责将所有业务模块的IDL服务定义统一聚合,为代码生成工具提供完整的服务接口定义。核心代码:
```thriftinclude "./workflow/workflow.thrift"namespace go coze// 工作流核心服务聚合
service WorkflowService extends workflow.WorkflowService {}
// 其他业务服务聚合

工作流接口聚合说明:
通过 service WorkflowService extends workflow.WorkflowService {} 聚合定义,api.thrift将workflow.thrift中定义的所有工作流相关接口统一暴露.

2. API网关层

接口定义-workflow.go文件详细分析

文件位置:backend\api\model\workflow\workflow.go
核心代码:

type WorkflowService interface {SaveWorkflow(ctx context.Context, request *SaveWorkflowRequest) (r *SaveWorkflowResponse, err error)UpdateWorkflowMeta(ctx context.Context, request *UpdateWorkflowMetaRequest) (r *UpdateWorkflowMetaResponse, err error)GetCanvasInfo(ctx context.Context, request *GetCanvasInfoRequest) (r *GetCanvasInfoResponse, err error)}
工作流相关接口模型定义

当Coze用户登录平台后点击"资源库" → 接着在表格中点击要编辑的工作流行时,前端会调用工作流编辑相关接口来编辑工作流资源。

SaveWorkflowRequest 保存工作流请求结构体

type SaveWorkflowRequest struct {// 工作流IDWorkflowID string `thrift:"workflow_id,1,required" form:"workflow_id,required" json:"workflow_id,required" query:"workflow_id,required"`// 工作流定义schemaSchema string `thrift:"schema,2,required" form:"schema,required" json:"schema,required" query:"schema,required"`// 空间IDSpaceID string `thrift:"space_id,3" form:"space_id" json:"space_id" query:"space_id"`Base    *base.Base `thrift:"Base,255" form:"Base" json:"Base" query:"Base"`
}

UpdateWorkflowMetaRequest 更新工作流元数据请求结构体

type UpdateWorkflowMetaRequest struct {// 工作流IDWorkflowID string `thrift:"workflow_id,1,required" form:"workflow_id,required" json:"workflow_id,required" query:"workflow_id,required"`// 工作流名称Name string `thrift:"name,2" form:"name" json:"name" query:"name"`// 工作流描述Desc string `thrift:"desc,3" form:"desc" json:"desc" query:"desc"`// 工作流图标URLIconURI string `thrift:"icon_uri,4" form:"icon_uri" json:"icon_uri" query:"icon_uri"`// 空间IDSpaceID string `thrift:"space_id,5" form:"space_id" json:"space_id" query:"space_id"`// 工作流模式FlowMode WorkflowMode `thrift:"flow_mode,6" form:"flow_mode" json:"flow_mode" query:"flow_mode"`Base     *base.Base `thrift:"Base,255" form:"Base" json:"Base" query:"Base"`
}

GetCanvasInfoRequest 获取画布信息请求结构体

type GetCanvasInfoRequest struct {// 工作流IDWorkflowID string `thrift:"workflow_id,1,required" form:"workflow_id,required" json:"workflow_id,required" query:"workflow_id,required"`// 空间IDSpaceID string `thrift:"space_id,2" form:"space_id" json:"space_id" query:"space_id"`Base    *base.Base `thrift:"Base,255" form:"Base" json:"Base" query:"Base"`
}
接口功能说明

业务功能

  • 工作流保存:将用户编辑的工作流定义保存到系统中
  • 工作流元数据更新:根据用户输入更新工作流的名称、描述、图标等基本信息
  • 画布信息获取:获取工作流的画布定义和状态信息
  • 权限验证:确保只有有权限的用户才能编辑特定工作流
  • 数据存储:将更新后的工作流信息持久化存储
  • 版本管理:维护工作流的不同版本状态

技术特性

  • 类型安全:使用强类型定义确保工作流数据的一致性
  • 多格式支持:支持thrift、form、json、query等多种序列化格式
  • 参数验证:通过required标记确保必要参数的完整性
  • 统一响应:遵循统一的响应格式规范

文件作用
由thriftgo自动生成的Go代码文件,基于workflow.thrift IDL定义生成对应的Go结构体和接口,提供类型安全的工作流API模型。该文件实现了完整的Thrift RPC通信机制,包括客户端调用、服务端处理、序列化/反序列化等功能,确保了工作流服务间的可靠通信。

工作流接口处理器实现

文件位置:backend/api/handler/coze/workflow_service.go

该文件包含了用户登录后点击"资源库" → 接着在表格中点击要编辑的工作流行功能的核心API接口处理器,主要负责处理工作流资源的编辑功能。

保存工作流处理器
// SaveWorkflow .
// @router /api/workflow_api/save [POST]
func SaveWorkflow(ctx context.Context, c *app.RequestContext) {var err errorvar req workflow.SaveWorkflowRequesterr = c.BindAndValidate(&req)if err != nil {invalidParamRequestResponse(c, err.Error())return}if req.WorkflowID == "" {invalidParamRequestResponse(c, "workflowID is invalid")return}resp, err := workflow.WorkflowApplicationSVC.SaveWorkflow(ctx, &req)if err != nil {internalServerErrorResponse(ctx, c, err)return}c.JSON(consts.StatusOK, resp)
}
更新工作流元数据处理器
// UpdateWorkflowMeta .
// @router /api/workflow_api/update_meta [POST]
func UpdateWorkflowMeta(ctx context.Context, c *app.RequestContext) {var err errorvar req workflow.UpdateWorkflowMetaRequesterr = c.BindAndValidate(&req)if err != nil {invalidParamRequestResponse(c, err.Error())return}if req.WorkflowID == "" {invalidParamRequestResponse(c, "workflowID is invalid")return}resp, err := workflow.WorkflowApplicationSVC.UpdateWorkflowMeta(ctx, &req)if err != nil {internalServerErrorResponse(ctx, c, err)return}c.JSON(consts.StatusOK, resp)
}
获取画布信息处理器
// GetCanvasInfo .
// @router /api/workflow_api/canvas [GET]
func GetCanvasInfo(ctx context.Context, c *app.RequestContext) {var err errorvar req workflow.GetCanvasInfoRequesterr = c.BindAndValidate(&req)if err != nil {invalidParamRequestResponse(c, err.Error())return}if req.WorkflowID == "" {invalidParamRequestResponse(c, "workflowID is invalid")return}resp, err := workflow.WorkflowApplicationSVC.GetCanvasInfo(ctx, &req)if err != nil {internalServerErrorResponse(ctx, c, err)return}c.JSON(consts.StatusOK, resp)
}

实现功能

  1. 参数验证:验证工作流ID等参数的有效性
  2. 业务调用:调用WorkflowApplicationSVC应用服务层的相应方法处理工作流编辑业务逻辑
  3. 错误处理:统一的错误处理机制,包括参数错误和内部服务错误
  4. 响应返回:返回标准化的操作响应结果

参数校验逻辑

  • 工作流ID验证:确保工作流ID不为空,防止无效的编辑操作

路由注册实现-api.go文件详细分析

文件位置:backend/api/router/coze/api.go

该文件是Coze Studio后端的核心路由注册文件,由hertz generator自动生成,负责将所有HTTP API接口路由与对应的处理函数进行绑定和注册。对于工作流编辑功能,构建了专门的路由结构:

/api/workflow_api/save [POST]
├── rootMw() # 根级中间件
├── _apiMw() # API组中间件
├── _workflow_apiMw() # 工作流API组中间件
├── _saveMw() # 保存工作流接口专用中间件
└── coze.SaveWorkflow # 保存工作流处理函数/api/workflow_api/update_meta [POST]
├── rootMw() # 根级中间件
├── _apiMw() # API组中间件
├── _workflow_apiMw() # 工作流API组中间件
├── _updatemetaMw() # 更新工作流元数据接口专用中间件
└── coze.UpdateWorkflowMeta # 更新工作流元数据处理函数/api/workflow_api/canvas [GET]
├── rootMw() # 根级中间件
├── _apiMw() # API组中间件
├── _workflow_apiMw() # 工作流API组中间件
├── _canvasMw() # 获取画布信息接口专用中间件
└── coze.GetCanvasInfo # 获取画布信息处理函数

核心代码:

{_workflow_api := _api.Group("/workflow_api", _workflow_apiMw()...)_workflow_api.POST("/save", append(_saveMw(), coze.SaveWorkflow)...)_workflow_api.POST("/update_meta", append(_updatemetaMw(), coze.UpdateWorkflowMeta)...)_workflow_api.GET("/canvas", append(_canvasMw(), coze.GetCanvasInfo)...)// 其他工作流相关路由...
}

3. 应用服务层

WorkflowApplicationService 应用服务层概述

WorkflowApplicationService是工作流编辑功能的核心应用服务层组件,负责协调各个领域服务和数据访问层,处理工作流编辑的业务逻辑。该服务实现了WorkflowService接口,为API网关层提供具体的业务处理能力。

保存工作流实现

保存工作流是用户编辑工作流画布内容的核心操作,负责将前端提交的工作流定义schema保存到后端系统。

func (w *WorkflowApplicationService) SaveWorkflow(ctx context.Context, req *workflow.SaveWorkflowRequest) (resp *workflow.SaveWorkflowResponse, err error) {// 初始化响应结构体resp = &workflow.SaveWorkflowResponse{}// 验证用户权限和授权信息authInfo, err := w.getSaveAuthInfo(ctx, req)if err != nil {// 处理权限错误return nil, err}// 构建保存请求saveReq := &domain.SaveWorkflowRequest{WorkflowID:    req.WorkflowID,Schema:        req.Schema,SpaceID:       authInfo.SpaceID,UserID:        authInfo.UserID,EditVersion:   authInfo.EditVersion,}// 调用领域服务保存工作流err = w.domainSVC.SaveWorkflow(ctx, saveReq)if err != nil {// 处理保存错误return nil, err}// 发布工作流变更事件w.publishWorkflowEvent(ctx, req.WorkflowID, common.WorkflowEventType_Save)// 设置响应信息resp.Code = 0resp.Msg = ""resp.Data = &workflow.SaveWorkflowData{}return resp, nil
}

更新工作流元数据实现

更新工作流元数据是工作流编辑的重要操作,负责根据用户提交的信息更新工作流的基本属性。

func (w *WorkflowApplicationService) UpdateWorkflowMeta(ctx context.Context, req *workflow.UpdateWorkflowMetaRequest) (resp *workflow.UpdateWorkflowMetaResponse, err error) {// 初始化响应结构体resp = &workflow.UpdateWorkflowMetaResponse{}// 验证用户权限和授权信息authInfo, err := w.getUpdateMetaAuthInfo(ctx, req)if err != nil {// 处理权限错误return nil, err}// 构建更新请求updateReq := &domain.UpdateWorkflowMetaRequest{WorkflowID:    req.WorkflowID,Name:          req.Name,Description:   req.Desc,IconURI:       req.IconURI,FlowMode:      req.FlowMode,SpaceID:       authInfo.SpaceID,UserID:        authInfo.UserID,EditVersion:   authInfo.EditVersion,}// 调用领域服务更新工作流元数据err = w.domainSVC.UpdateWorkflowMeta(ctx, updateReq)if err != nil {// 处理更新错误return nil, err}// 发布工作流变更事件w.publishWorkflowEvent(ctx, req.WorkflowID, common.WorkflowEventType_UpdateMeta)// 设置响应信息resp.Code = 0resp.Msg = ""resp.EditVersion = authInfo.EditVersionreturn resp, nil
}

解锁工作流编辑实现

解锁工作流编辑是用户完成编辑后释放编辑锁的操作,允许其他用户对工作流进行编辑。

func (w *WorkflowApplicationService) UnlockWorkflowEdit(ctx context.Context, req *workflowAPI.UnlockWorkflowEditRequest) (resp *workflowAPI.UnlockWorkflowEditResponse, err error) {// 初始化响应结构体并设置释放状态为已释放resp = &workflowAPI.UnlockWorkflowEditResponse{Code:     0,Msg:      "",Released: true,}return resp, nil
}

应用服务层工作流程

工作流编辑功能的完整工作流程如下:

  1. 编辑准备阶段

    • 用户点击要编辑的工作流
    • 前端调用CheckAndLockWorkflowEdit接口
    • 应用服务层验证权限并获取编辑锁
    • 返回工作流当前信息给前端进行展示
  2. 编辑进行阶段

    • 用户在前端界面修改工作流信息(元数据、画布内容等)
    • 完成修改后点击保存
    • 前端调用SaveWorkflowUpdateWorkflowMeta接口
    • 应用服务层验证权限、检查锁定状态
    • 调用领域服务更新工作流数据
    • 返回更新结果
  3. 编辑完成阶段

    • 用户完成所有编辑操作
    • 前端调用UnlockWorkflowEdit接口
    • 应用服务层释放编辑锁
    • 工作流可以被其他用户编辑

核心业务逻辑与协作

应用服务层在工作流编辑过程中主要负责以下核心业务逻辑:

  1. 权限验证:确保只有有权限的用户才能编辑特定工作流
  2. 并发控制:通过编辑锁定机制防止并发编辑冲突
  3. 数据验证:验证用户提交的数据符合业务规则和约束
  4. 事务管理:确保工作流数据更新的原子性和一致性
  5. 版本管理:维护工作流的编辑版本号,用于冲突检测
  6. 领域协调:协调调用各个领域服务完成完整的编辑流程

应用服务层作为API网关层和领域服务层之间的桥梁,将复杂的业务流程分解为可管理的步骤,确保工作流编辑功能的正确性和可靠性。

http://www.dtcms.com/a/430640.html

相关文章:

  • 网站建设与维护课程设计报告书wordpress 多媒体管理系统
  • 一文了解国产算子编程语言 TileLang,TileLang 对国产开源生态的影响与启示
  • C#和Java正则表达式开发
  • 从零开始:MCP数据库助手(一)- 基础搭建
  • ORB_SLAM2原理及代码解析:SetPose() 函数
  • 蚌埠市建设学校网站网站排名权重怎么做
  • Android android.util.LruCache源码阅读
  • 安卓基础组件020-页面跳转传递数据001
  • Postman 学习笔记 IV:Workflow、Newman 与 Mock Server 实战技巧
  • 安卓基础组件016--第三方Toasty组件
  • ESNP LAB 笔记:配置静态BFD检测MPLS LDP LSP
  • Day30 | Java集合框架之Collections工具类
  • 【STM32项目开源】基于STM32的智能养殖场环境监测系统
  • 【Java并发】揭秘Lock体系 -- condition等待通知机制
  • 计算机网络-网络边缘网络核心
  • 安卓13_ROM修改定制化-----修改固件 去除主题防止恢复 破解主题等操作解析
  • 怎么做网站301重定向可口可乐公司的企业网站建设
  • NS4168输出音频通过ESP32C3测试
  • 24.使用 HTML 和 CSS 实现无限旋转正方形动画效果
  • 音频降噪技术:从原理到工具的完整指南(scipy librosa noisereduce soundfile pedalboard)
  • 网站建设构成技术要求wordpress书籍推荐
  • CoCoSim(2020): 连接Simulink与Lustre生态的模型检测框架
  • 第2篇|风机设计的基本原则:从“会弯的高楼”到“会自救的系统”
  • SpringSecurity详解
  • [linux仓库]深入解析Linux动态链接与动态库加载:理解背后的原理与技巧
  • 异步日志系统
  • 自监督学习在医疗AI中的技术实现路径分析(中)
  • QoS之拥塞管理两种配置方法
  • tp框架做网站的优点郑州品牌策划设计公司
  • 浅析 AC 自动机