// Package shop 提供店铺通知接收人的 PostgreSQL Adapter。 package shop import ( "context" "sort" "gorm.io/gorm" shopapp "github.com/break/junhong_cmp_fiber/internal/application/shop" "github.com/break/junhong_cmp_fiber/internal/model" "github.com/break/junhong_cmp_fiber/pkg/constants" "github.com/break/junhong_cmp_fiber/pkg/errors" ) // RecipientResolver 按店铺当前独立归属解析主账号和可用平台业务员。 type RecipientResolver struct { db *gorm.DB } var _ shopapp.NotificationRecipientResolver = (*RecipientResolver)(nil) // NewRecipientResolver 创建店铺通知接收人解析 Adapter。 func NewRecipientResolver(db *gorm.DB) *RecipientResolver { return &RecipientResolver{db: db} } // ResolveNotificationRecipients 返回启用的店铺主账号和当前可用业务员账号 ID。 // // 解析只读取目标店铺当前保存的业务员 ID,不读取父店铺、祖先店铺或创建人。 func (r *RecipientResolver) ResolveNotificationRecipients(ctx context.Context, shopID uint) ([]uint, error) { if shopID == 0 { return nil, errors.New(errors.CodeInvalidParam) } var target struct { BusinessOwnerAccountID *uint } err := r.db.WithContext(ctx).Model(&model.Shop{}). Select("business_owner_account_id").Where("id = ?", shopID).Take(&target).Error if err == gorm.ErrRecordNotFound { return []uint{}, nil } if err != nil { return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询店铺通知归属失败") } query := r.db.WithContext(ctx).Model(&model.Account{}). Select("id"). Where("status = ? AND shop_id = ? AND is_primary = ? AND user_type = ?", constants.StatusEnabled, shopID, true, constants.UserTypeAgent) if target.BusinessOwnerAccountID != nil { query = query.Or("id = ? AND status = ? AND user_type = ?", *target.BusinessOwnerAccountID, constants.StatusEnabled, constants.UserTypePlatform) } var accounts []model.Account if err := query.Find(&accounts).Error; err != nil { return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询店铺通知接收人失败") } ids := make([]uint, 0, len(accounts)) seen := make(map[uint]struct{}, len(accounts)) for _, account := range accounts { if _, exists := seen[account.ID]; exists { continue } seen[account.ID] = struct{}{} ids = append(ids, account.ID) } sort.Slice(ids, func(i, j int) bool { return ids[i] < ids[j] }) return ids, nil }