Files
tyapi-server/internal/domains/user/services/contract_aggregate_service.go

266 lines
9.0 KiB
Go
Raw Normal View History

2025-07-28 01:46:39 +08:00
package services
import (
"context"
"fmt"
"tyapi-server/internal/domains/user/entities"
"tyapi-server/internal/domains/user/repositories"
"go.uber.org/zap"
)
// ContractAggregateService 合同信息聚合服务接口
type ContractAggregateService interface {
// 聚合根生命周期管理
CreateContract(ctx context.Context, enterpriseInfoID, userID, contractName string, contractType entities.ContractType, contractFileID, contractFileURL string) (*entities.ContractInfo, error)
LoadContract(ctx context.Context, contractID string) (*entities.ContractInfo, error)
SaveContract(ctx context.Context, contract *entities.ContractInfo) error
DeleteContract(ctx context.Context, contractID string) error
// 查询方法
FindByEnterpriseInfoID(ctx context.Context, enterpriseInfoID string) ([]*entities.ContractInfo, error)
FindByUserID(ctx context.Context, userID string) ([]*entities.ContractInfo, error)
FindByContractType(ctx context.Context, enterpriseInfoID string, contractType entities.ContractType) ([]*entities.ContractInfo, error)
ExistsByContractFileID(ctx context.Context, contractFileID string) (bool, error)
// 业务规则验证
ValidateBusinessRules(ctx context.Context, contract *entities.ContractInfo) error
}
// ContractAggregateServiceImpl 合同信息聚合服务实现
type ContractAggregateServiceImpl struct {
contractRepo repositories.ContractInfoRepository
logger *zap.Logger
}
// NewContractAggregateService 创建合同信息聚合服务
func NewContractAggregateService(
contractRepo repositories.ContractInfoRepository,
logger *zap.Logger,
) ContractAggregateService {
return &ContractAggregateServiceImpl{
contractRepo: contractRepo,
logger: logger,
}
}
// ================ 聚合根生命周期管理 ================
// CreateContract 创建合同信息
func (s *ContractAggregateServiceImpl) CreateContract(
ctx context.Context,
enterpriseInfoID, userID, contractName string,
contractType entities.ContractType,
contractFileID, contractFileURL string,
) (*entities.ContractInfo, error) {
s.logger.Debug("创建合同信息",
zap.String("enterprise_info_id", enterpriseInfoID),
zap.String("user_id", userID),
zap.String("contract_name", contractName),
zap.String("contract_type", string(contractType)))
// 1. 检查合同文件ID是否已存在
exists, err := s.ExistsByContractFileID(ctx, contractFileID)
if err != nil {
return nil, fmt.Errorf("检查合同文件ID失败: %w", err)
}
if exists {
return nil, fmt.Errorf("合同文件ID已存在")
}
// 2. 创建合同信息聚合根
contract, err := entities.NewContractInfo(enterpriseInfoID, userID, contractName, contractType, contractFileID, contractFileURL)
if err != nil {
return nil, fmt.Errorf("创建合同信息失败: %w", err)
}
// 3. 验证业务规则
if err := s.ValidateBusinessRules(ctx, contract); err != nil {
return nil, fmt.Errorf("业务规则验证失败: %w", err)
}
// 4. 保存聚合根
err = s.SaveContract(ctx, contract)
if err != nil {
return nil, fmt.Errorf("保存合同信息失败: %w", err)
}
s.logger.Info("合同信息创建成功",
zap.String("contract_id", contract.ID),
zap.String("enterprise_info_id", enterpriseInfoID),
zap.String("contract_name", contractName))
return contract, nil
}
// LoadContract 加载合同信息
func (s *ContractAggregateServiceImpl) LoadContract(ctx context.Context, contractID string) (*entities.ContractInfo, error) {
s.logger.Debug("加载合同信息", zap.String("contract_id", contractID))
contract, err := s.contractRepo.FindByID(ctx, contractID)
if err != nil {
s.logger.Error("加载合同信息失败", zap.Error(err))
return nil, fmt.Errorf("加载合同信息失败: %w", err)
}
if contract == nil {
return nil, fmt.Errorf("合同信息不存在")
}
return contract, nil
}
// SaveContract 保存合同信息
func (s *ContractAggregateServiceImpl) SaveContract(ctx context.Context, contract *entities.ContractInfo) error {
s.logger.Debug("保存合同信息", zap.String("contract_id", contract.ID))
// 1. 验证业务规则
if err := s.ValidateBusinessRules(ctx, contract); err != nil {
return fmt.Errorf("业务规则验证失败: %w", err)
}
// 2. 保存聚合根
err := s.contractRepo.Save(ctx, contract)
if err != nil {
s.logger.Error("保存合同信息失败", zap.Error(err))
return fmt.Errorf("保存合同信息失败: %w", err)
}
// 3. 发布领域事件
// TODO: 实现领域事件发布机制
// 4. 清除领域事件
contract.ClearDomainEvents()
s.logger.Info("合同信息保存成功", zap.String("contract_id", contract.ID))
return nil
}
// DeleteContract 删除合同信息
func (s *ContractAggregateServiceImpl) DeleteContract(ctx context.Context, contractID string) error {
s.logger.Debug("删除合同信息", zap.String("contract_id", contractID))
// 1. 加载合同信息
contract, err := s.LoadContract(ctx, contractID)
if err != nil {
return fmt.Errorf("加载合同信息失败: %w", err)
}
// 2. 调用聚合根方法删除
err = contract.DeleteContract()
if err != nil {
return fmt.Errorf("删除合同信息失败: %w", err)
}
// 3. 保存聚合根(软删除)
err = s.SaveContract(ctx, contract)
if err != nil {
return fmt.Errorf("保存删除状态失败: %w", err)
}
s.logger.Info("合同信息删除成功", zap.String("contract_id", contractID))
return nil
}
// ================ 查询方法 ================
// FindByEnterpriseInfoID 根据企业信息ID查找合同
func (s *ContractAggregateServiceImpl) FindByEnterpriseInfoID(ctx context.Context, enterpriseInfoID string) ([]*entities.ContractInfo, error) {
s.logger.Debug("根据企业信息ID查找合同", zap.String("enterprise_info_id", enterpriseInfoID))
contracts, err := s.contractRepo.FindByEnterpriseInfoID(ctx, enterpriseInfoID)
if err != nil {
s.logger.Error("查找合同失败", zap.Error(err))
return nil, fmt.Errorf("查找合同失败: %w", err)
}
return contracts, nil
}
// FindByUserID 根据用户ID查找合同
func (s *ContractAggregateServiceImpl) FindByUserID(ctx context.Context, userID string) ([]*entities.ContractInfo, error) {
s.logger.Debug("根据用户ID查找合同", zap.String("user_id", userID))
contracts, err := s.contractRepo.FindByUserID(ctx, userID)
if err != nil {
s.logger.Error("查找合同失败", zap.Error(err))
return nil, fmt.Errorf("查找合同失败: %w", err)
}
return contracts, nil
}
// FindByContractType 根据合同类型查找合同
func (s *ContractAggregateServiceImpl) FindByContractType(ctx context.Context, enterpriseInfoID string, contractType entities.ContractType) ([]*entities.ContractInfo, error) {
s.logger.Debug("根据合同类型查找合同",
zap.String("enterprise_info_id", enterpriseInfoID),
zap.String("contract_type", string(contractType)))
contracts, err := s.contractRepo.FindByContractType(ctx, enterpriseInfoID, contractType)
if err != nil {
s.logger.Error("查找合同失败", zap.Error(err))
return nil, fmt.Errorf("查找合同失败: %w", err)
}
return contracts, nil
}
// ExistsByContractFileID 检查合同文件ID是否存在
func (s *ContractAggregateServiceImpl) ExistsByContractFileID(ctx context.Context, contractFileID string) (bool, error) {
s.logger.Debug("检查合同文件ID是否存在", zap.String("contract_file_id", contractFileID))
exists, err := s.contractRepo.ExistsByContractFileID(ctx, contractFileID)
if err != nil {
s.logger.Error("检查合同文件ID失败", zap.Error(err))
return false, fmt.Errorf("检查合同文件ID失败: %w", err)
}
return exists, nil
}
// ================ 业务规则验证 ================
// ValidateBusinessRules 验证业务规则
func (s *ContractAggregateServiceImpl) ValidateBusinessRules(ctx context.Context, contract *entities.ContractInfo) error {
// 1. 实体级验证
if err := contract.ValidateBusinessRules(); err != nil {
return fmt.Errorf("实体级验证失败: %w", err)
}
// 2. 跨聚合根级验证
if err := s.validateCrossAggregateRules(ctx, contract); err != nil {
return fmt.Errorf("跨聚合根级验证失败: %w", err)
}
// 3. 领域级验证
if err := s.validateDomainRules(ctx, contract); err != nil {
return fmt.Errorf("领域级验证失败: %w", err)
}
return nil
}
// validateCrossAggregateRules 跨聚合根级验证
func (s *ContractAggregateServiceImpl) validateCrossAggregateRules(ctx context.Context, contract *entities.ContractInfo) error {
// 检查合同文件ID唯一性排除当前合同
if contract.ID != "" {
exists, err := s.contractRepo.ExistsByContractFileIDExcludeID(ctx, contract.ContractFileID, contract.ID)
if err != nil {
return fmt.Errorf("检查合同文件ID唯一性失败: %w", err)
}
if exists {
return fmt.Errorf("合同文件ID已存在")
}
}
return nil
}
// validateDomainRules 领域级验证
func (s *ContractAggregateServiceImpl) validateDomainRules(ctx context.Context, contract *entities.ContractInfo) error {
// 可以添加领域级别的业务规则验证
// 例如:检查企业是否已认证、检查用户权限等
return nil
}