Files
junhong_cmp_fiber/internal/infrastructure/shop/recipient_resolver.go
2026-07-24 16:07:18 +08:00

72 lines
2.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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
}