暂存一下,防止丢失
This commit is contained in:
100
internal/infrastructure/notification/recipient_resolver.go
Normal file
100
internal/infrastructure/notification/recipient_resolver.go
Normal file
@@ -0,0 +1,100 @@
|
||||
package notification
|
||||
|
||||
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"
|
||||
)
|
||||
|
||||
// DynamicRecipientResolver 按稳定账号、平台角色或店铺解析当前可用后台账号。
|
||||
type DynamicRecipientResolver struct {
|
||||
db *gorm.DB
|
||||
shopResolver shopapp.NotificationRecipientResolver
|
||||
}
|
||||
|
||||
// NewDynamicRecipientResolver 创建后台通知动态接收人解析 Adapter。
|
||||
func NewDynamicRecipientResolver(db *gorm.DB, shopResolver shopapp.NotificationRecipientResolver) *DynamicRecipientResolver {
|
||||
return &DynamicRecipientResolver{db: db, shopResolver: shopResolver}
|
||||
}
|
||||
|
||||
// Resolve 根据受控目标类型返回去重且按账号 ID 排序的当前可用接收人。
|
||||
func (r *DynamicRecipientResolver) Resolve(ctx context.Context, targetKind string, targetID uint) ([]uint, error) {
|
||||
if targetID == 0 {
|
||||
return nil, errors.New(errors.CodeInvalidParam)
|
||||
}
|
||||
var ids []uint
|
||||
var err error
|
||||
switch targetKind {
|
||||
case constants.NotificationTargetKindAccount:
|
||||
ids, err = r.resolveAccount(ctx, targetID)
|
||||
case constants.NotificationTargetKindPlatformRole:
|
||||
ids, err = r.resolvePlatformRole(ctx, targetID)
|
||||
case constants.NotificationTargetKindShop:
|
||||
if r.shopResolver == nil {
|
||||
return nil, errors.New(errors.CodeInternalError, "店铺通知接收人解析器未配置")
|
||||
}
|
||||
ids, err = r.shopResolver.ResolveNotificationRecipients(ctx, targetID)
|
||||
default:
|
||||
return nil, errors.New(errors.CodeInvalidParam, "通知接收目标类型不受支持")
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return uniqueSortedIDs(ids), nil
|
||||
}
|
||||
|
||||
func (r *DynamicRecipientResolver) resolveAccount(ctx context.Context, accountID uint) ([]uint, error) {
|
||||
var account model.Account
|
||||
err := r.db.WithContext(ctx).Select("id").
|
||||
Where("id = ? AND status = ?", accountID, constants.StatusEnabled).Take(&account).Error
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return []uint{}, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询通知申请人失败")
|
||||
}
|
||||
return []uint{account.ID}, nil
|
||||
}
|
||||
|
||||
func (r *DynamicRecipientResolver) resolvePlatformRole(ctx context.Context, roleID uint) ([]uint, error) {
|
||||
var accounts []model.Account
|
||||
err := r.db.WithContext(ctx).Model(&model.Account{}).
|
||||
Select("tb_account.id").
|
||||
Joins("JOIN tb_account_role ar ON ar.account_id = tb_account.id AND ar.deleted_at IS NULL AND ar.status = ?", constants.StatusEnabled).
|
||||
Joins("JOIN tb_role r ON r.id = ar.role_id AND r.deleted_at IS NULL AND r.status = ? AND r.role_type = ?",
|
||||
constants.StatusEnabled, constants.RoleTypePlatform).
|
||||
Where("ar.role_id = ? AND tb_account.status = ? AND tb_account.user_type IN ?",
|
||||
roleID, constants.StatusEnabled, []int{constants.UserTypeSuperAdmin, constants.UserTypePlatform}).
|
||||
Find(&accounts).Error
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询平台角色通知接收人失败")
|
||||
}
|
||||
ids := make([]uint, 0, len(accounts))
|
||||
for _, account := range accounts {
|
||||
ids = append(ids, account.ID)
|
||||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
func uniqueSortedIDs(ids []uint) []uint {
|
||||
seen := make(map[uint]struct{}, len(ids))
|
||||
result := make([]uint, 0, len(ids))
|
||||
for _, id := range ids {
|
||||
if id == 0 {
|
||||
continue
|
||||
}
|
||||
if _, exists := seen[id]; exists {
|
||||
continue
|
||||
}
|
||||
seen[id] = struct{}{}
|
||||
result = append(result, id)
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool { return result[i] < result[j] })
|
||||
return result
|
||||
}
|
||||
Reference in New Issue
Block a user