Coze源码分析-资源库-删除插件-后端源码-应用和领域服务层

3. 应用服务层

PluginApplicationService初始化

文件位置:backend/application/plugin/plugin.go

PluginApplicationService是插件应用服务层的核心组件,专门负责处理插件资源的删除等业务逻辑,是连接API层和领域层的重要桥梁。在用户点击"资源库" → 在表格中点击要删除的插件行最右边的"..."号 → 最后点击弹出菜单中的"删除"菜单的场景中,该服务承担着核心的删除业务处理职责。

服务结构定义

文件位置:backend/application/plugin/plugin.go

go 复制代码
type PluginApplicationService struct {
	DomainSVC service.PluginService
	toolRepo  repository.ToolRepository
	eventbus  search.ResourceEventBus
}

var PluginSVC = &PluginApplicationService{}
服务初始化实现

文件位置:backend/application/plugin/init.go

go 复制代码
// InitService 初始化插件应用服务,注入领域服务依赖
func InitService(pluginRepo repository.PluginRepository, toolRepo repository.ToolRepository, eventbus ResourceEventBus) *PluginApplicationService {
	// 创建插件领域服务
	pluginDomainSVC := service.NewService(pluginRepo, toolRepo)

	// 初始化应用服务
	service := &PluginApplicationService{
		DomainSVC: pluginDomainSVC,
		toolRepo:  toolRepo,
		eventbus:  eventbus,
	}

	return service
}

服务初始化特点

  1. 依赖注入:通过Repository接口注入数据访问能力,实现依赖倒置
  2. 事件驱动架构:集成资源事件总线,支持异步事件处理和数据同步
  3. 领域服务协调:封装插件领域服务,提供应用层的业务编排
  4. 多仓储支持:同时注入插件和工具仓储,支持复杂的插件管理操作

删除插件核心实现

DelPlugin方法详解

文件位置:backend/application/plugin/plugin.go

当用户在资源库中点击要删除的插件行最右边的"..."号,然后点击弹出菜单中的"删除"菜单时,前端会调用DelPlugin方法来删除指定的插件资源。

go 复制代码
func (p *PluginApplicationService) DelPlugin(ctx context.Context, req *pluginAPI.DelPluginRequest) (resp *pluginAPI.DelPluginResponse, err error) {
	_, err = p.validateDraftPluginAccess(ctx, req.PluginID)
	if err != nil {
		return nil, errorx.Wrapf(err, "validateDelPluginRequest failed")
	}

	err = p.DomainSVC.DeleteDraftPlugin(ctx, req.PluginID)
	if err != nil {
		return nil, errorx.Wrapf(err, "DeleteDraftPlugin failed, pluginID=%d", req.PluginID)
	}

	err = p.eventbus.PublishResources(ctx, &searchEntity.ResourceDomainEvent{
		OpType: searchEntity.Deleted,
		Resource: &searchEntity.ResourceDocument{
			ResType:      resCommon.ResType_Plugin,
			ResID:        req.PluginID,
			UpdateTimeMS: ptr.Of(time.Now().UnixMilli()),
		},
	})
	if err != nil {
		return nil, errorx.Wrapf(err, "publish resource '%d' failed", req.PluginID)
	}

	resp = &pluginAPI.DelPluginResponse{}
	return resp, nil
}

方法功能特点

  1. 权限验证:通过validateDraftPluginAccess验证用户对插件的访问权限
  2. 领域服务调用:调用领域服务层的DeleteDraftPlugin方法执行删除逻辑
  3. 事件发布:删除完成后发布删除事件,支持搜索索引更新等下游处理
  4. 错误处理:完善的错误处理机制,包装错误信息便于调试
  5. 时间戳记录:在事件中记录删除时间,便于审计和追踪
删除插件业务流程

删除插件的完整业务流程包括以下几个关键步骤:

  1. 权限验证:验证用户对要删除插件的访问权限
  2. 执行删除操作:调用领域服务执行实际的删除操作
  3. 事件发布:发布删除事件,通知其他系统组件进行相应处理
  4. 返回响应:返回删除操作的结果

删除操作的安全性保障

  • 权限控制:严格的插件访问权限验证,防止越权删除
  • 数据一致性:通过事务确保删除操作的原子性
  • 事件驱动:异步事件处理,确保相关数据的同步更新
  • 错误处理:完善的错误处理机制,确保系统稳定性

4. 领域服务层

插件领域服务层架构

插件领域服务层是Coze Studio中处理插件业务逻辑的核心层,负责插件资源的删除、管理和业务规则实现。该层采用领域驱动设计(DDD)模式,将业务逻辑与数据访问分离,确保代码的可维护性和可扩展性。

插件领域服务接口定义

文件位置:backend/domain/plugin/service/service.go

插件领域服务接口定义了插件管理的核心业务能力,包括插件资源的完整生命周期管理。

go 复制代码
type PluginService interface {
	// 删除草稿插件
	DeleteDraftPlugin(ctx context.Context, pluginID int64) error
	
	// 其他插件管理方法
	CreateDraftPlugin(ctx context.Context, req *CreateDraftPluginRequest) (*CreateDraftPluginResponse, error)
	GetDraftPlugin(ctx context.Context, pluginID int64) (*entity.PluginInfo, bool, error)
	UpdateDraftPlugin(ctx context.Context, req *UpdateDraftPluginRequest) error
}

核心接口功能

  1. 插件资源管理:创建、获取、更新、删除用户自定义的插件资源
  2. 删除操作核心:DeleteDraftPlugin方法是删除插件的核心业务接口
  3. 草稿管理:专门处理草稿状态的插件,支持开发过程中的迭代
  4. 业务规则封装:封装插件相关的业务逻辑和验证规则
  5. 数据一致性:确保插件数据的完整性和一致性
插件领域服务实现

文件位置:backend/domain/plugin/service/plugin_draft.go

插件服务实现类包含了所有插件相关业务逻辑的具体实现,依赖于仓储层进行数据持久化。

go 复制代码
type pluginServiceImpl struct {
	pluginRepo repository.PluginRepository
	toolRepo   repository.ToolRepository
}

func NewService(pluginRepo repository.PluginRepository, toolRepo repository.ToolRepository) PluginService {
	return &pluginServiceImpl{
		pluginRepo: pluginRepo,
		toolRepo:   toolRepo,
	}
}

// DeleteDraftPlugin 删除草稿插件
func (p *pluginServiceImpl) DeleteDraftPlugin(ctx context.Context, pluginID int64) (err error) {
	return p.pluginRepo.DeleteDraftPlugin(ctx, pluginID)
}

删除操作实现特点

  1. 依赖注入:通过Repository接口注入数据访问能力,实现松耦合
  2. 仓储模式:使用Repository模式进行数据访问抽象,隔离业务逻辑与数据层
  3. 简洁删除:DeleteDraftPlugin方法实现简洁,直接调用仓储层删除操作
  4. 错误传播:统一的错误处理和传播机制,确保删除异常的正确处理
  5. 业务隔离:领域服务层专注于业务逻辑,数据操作委托给仓储层
  6. 多仓储协调:同时管理插件和工具仓储,支持复杂的插件删除操作

DeleteDraftPlugin方法详解

  • 参数简洁:只需要pluginID参数,通过ID精确定位要删除的插件
  • 错误处理:直接传播仓储层的错误,保持错误信息的完整性
  • 返回值:删除成功返回nil,失败返回具体错误信息
  • 业务纯净:不包含权限验证等应用层逻辑,专注于领域层的删除操作
插件实体定义

文件位置:backend/domain/plugin/entity/plugin.go

插件实体定义了插件资源的核心数据结构,包含了插件的所有关键属性。

go 复制代码
type PluginInfo struct {
	ID          int64                    // 插件唯一标识
	PluginType  common.PluginType        // 插件类型(本地/远程)
	SpaceID     int64                    // 所属空间ID,支持多租户隔离
	DeveloperID int64                    // 开发者ID
	APPID       *int64                   // 关联应用ID
	IconURI     *string                  // 插件图标URI
	ServerURL   *string                  // 服务器URL
	Manifest    *model.PluginManifest    // 插件清单信息
	OpenapiDoc  *model.Openapi3T         // OpenAPI文档
	CreatedAt   int64                    // 创建时间戳
	UpdatedAt   int64                    // 更新时间戳
}

实体设计特点

  1. 基础信息:包含ID、类型、空间等基本属性,满足插件的基本信息需求
  2. 类型支持:PluginType字段支持本地和远程插件类型,灵活适配不同场景
  3. 多租户支持:SpaceID字段支持多租户和空间隔离,确保数据安全
  4. 开发者管理:DeveloperID字段支持开发者权限控制和资源归属管理
  5. 应用关联:APPID字段支持插件与应用的关联关系
  6. 配置管理:Manifest和OpenapiDoc字段存储插件的配置和API文档
  7. 时间追踪:CreatedAt和UpdatedAt支持创建和更新时间追踪,便于审计和版本管理
相关推荐
RoyLin12 小时前
C++ 原生扩展、node-gyp 与 CMake.js
前端·后端·node.js
Fency咖啡12 小时前
Spring Boot 3.x 开发 Starter 快速上手体验,通过实践理解自动装配原理
java·spring boot·后端
南方者12 小时前
【JAVA】【BUG】Java 开发中常见问题的具体示例,结合代码片段说明问题场景及原因
java·后端·debug
寻月隐君12 小时前
Rust 泛型编程基石:AsRef 和 AsMut 的核心作用与实战应用
后端·github
Java水解13 小时前
100道互联网大厂面试题+答案
java·后端·面试
用户83562907805113 小时前
使用Python自动化移除Excel公式,保留纯净数值
后端·python
Java水解13 小时前
SpringBoot 线程池 配置使用详解
spring boot·后端
karry_k13 小时前
生产者-消费者问题
后端
QZQ5418813 小时前
go中channel通信的底层实现
后端
方圆想当图灵14 小时前
深入浅出 gRPC
java·后端·github