fix(user): move bind-email subscriptions to owner
Build docker and publish / build (20.15.1) (push) Has been cancelled
Build docker and publish / build (20.15.1) (push) Has been cancelled
This commit is contained in:
@@ -2,10 +2,13 @@ package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
modelOrder "github.com/perfect-panel/server/internal/model/order"
|
||||
"github.com/perfect-panel/server/internal/model/user"
|
||||
"github.com/perfect-panel/server/internal/svc"
|
||||
"github.com/perfect-panel/server/pkg/uuidx"
|
||||
"github.com/perfect-panel/server/pkg/xerr"
|
||||
"github.com/pkg/errors"
|
||||
"gorm.io/gorm"
|
||||
@@ -22,6 +25,13 @@ type familyBindingHelper struct {
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
type familySubscribeTransferMode uint8
|
||||
|
||||
const (
|
||||
familySubscribeDiscard familySubscribeTransferMode = iota
|
||||
familySubscribeMoveToOwner
|
||||
)
|
||||
|
||||
func newFamilyBindingHelper(ctx context.Context, svcCtx *svc.ServiceContext) *familyBindingHelper {
|
||||
return &familyBindingHelper{
|
||||
ctx: ctx,
|
||||
@@ -111,6 +121,14 @@ func (h *familyBindingHelper) validateJoinFamily(ownerUserId, memberUserId int64
|
||||
}
|
||||
|
||||
func (h *familyBindingHelper) joinFamily(ownerUserId, memberUserId int64, source string) (*familyJoinResult, error) {
|
||||
return h.joinFamilyWithSubscribeMode(ownerUserId, memberUserId, source, familySubscribeDiscard)
|
||||
}
|
||||
|
||||
func (h *familyBindingHelper) joinFamilyAndMoveSubscribesToOwner(ownerUserId, memberUserId int64, source string) (*familyJoinResult, error) {
|
||||
return h.joinFamilyWithSubscribeMode(ownerUserId, memberUserId, source, familySubscribeMoveToOwner)
|
||||
}
|
||||
|
||||
func (h *familyBindingHelper) joinFamilyWithSubscribeMode(ownerUserId, memberUserId int64, source string, subscribeMode familySubscribeTransferMode) (*familyJoinResult, error) {
|
||||
if ownerUserId == memberUserId {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.FamilyAlreadyBound), "user already bound to this family")
|
||||
}
|
||||
@@ -118,7 +136,7 @@ func (h *familyBindingHelper) joinFamily(ownerUserId, memberUserId int64, source
|
||||
result := &familyJoinResult{
|
||||
OwnerUserId: ownerUserId,
|
||||
}
|
||||
removedSubscribes := make([]user.Subscribe, 0)
|
||||
affectedSubscribes := make([]user.Subscribe, 0)
|
||||
|
||||
err := h.svcCtx.DB.WithContext(h.ctx).Transaction(func(tx *gorm.DB) error {
|
||||
ownerFamily, err := h.getOrCreateOwnerFamily(tx, ownerUserId)
|
||||
@@ -182,9 +200,17 @@ func (h *familyBindingHelper) joinFamily(ownerUserId, memberUserId int64, source
|
||||
}
|
||||
}
|
||||
|
||||
removedSubscribes, err = transferMemberSubscribesToOwner(tx, memberUserId, ownerUserId)
|
||||
if err != nil {
|
||||
return err
|
||||
switch subscribeMode {
|
||||
case familySubscribeMoveToOwner:
|
||||
affectedSubscribes, err = moveMemberSubscribesToOwner(tx, memberUserId, ownerUserId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
affectedSubscribes, err = transferMemberSubscribesToOwner(tx, memberUserId, ownerUserId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
@@ -193,12 +219,56 @@ func (h *familyBindingHelper) joinFamily(ownerUserId, memberUserId int64, source
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = h.clearRemovedMemberSubscribeCache(removedSubscribes); err != nil {
|
||||
return nil, err
|
||||
if subscribeMode == familySubscribeMoveToOwner {
|
||||
if err = h.clearMovedMemberSubscribeCache(affectedSubscribes, ownerUserId); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
if err = h.clearRemovedMemberSubscribeCache(affectedSubscribes); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func moveMemberSubscribesToOwner(tx *gorm.DB, memberUserId, ownerUserId int64) ([]user.Subscribe, error) {
|
||||
var subscribes []user.Subscribe
|
||||
if err := tx.Clauses(clause.Locking{Strength: "UPDATE"}).
|
||||
Model(&user.Subscribe{}).
|
||||
Where("user_id = ?", memberUserId).
|
||||
Find(&subscribes).Error; err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "query member subscribe list failed")
|
||||
}
|
||||
if len(subscribes) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
for _, sub := range subscribes {
|
||||
newToken := uuidx.SubscribeToken(fmt.Sprintf("familyMove:%d:%d:%s", ownerUserId, sub.Id, uuidx.NewUUID().String()))
|
||||
if err := tx.Model(&user.Subscribe{}).
|
||||
Where("id = ? AND user_id = ?", sub.Id, memberUserId).
|
||||
Updates(map[string]interface{}{
|
||||
"user_id": ownerUserId,
|
||||
"token": newToken,
|
||||
"uuid": uuidx.NewUUID().String(),
|
||||
"updated_at": time.Now(),
|
||||
}).Error; err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseUpdateError), "move member subscribe to owner failed")
|
||||
}
|
||||
if sub.OrderId > 0 {
|
||||
if err := tx.Model(&modelOrder.Order{}).
|
||||
Where("id = ? AND subscription_user_id = ?", sub.OrderId, memberUserId).
|
||||
Updates(map[string]interface{}{
|
||||
"subscription_user_id": ownerUserId,
|
||||
"subscribe_token": newToken,
|
||||
}).Error; err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseUpdateError), "move member subscribe order to owner failed")
|
||||
}
|
||||
}
|
||||
}
|
||||
return subscribes, nil
|
||||
}
|
||||
|
||||
func transferMemberSubscribesToOwner(tx *gorm.DB, memberUserId, ownerUserId int64) ([]user.Subscribe, error) {
|
||||
var subscribes []user.Subscribe
|
||||
if err := tx.Model(&user.Subscribe{}).
|
||||
@@ -238,6 +308,37 @@ func (h *familyBindingHelper) clearRemovedMemberSubscribeCache(removedSubscribes
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *familyBindingHelper) clearMovedMemberSubscribeCache(movedSubscribes []user.Subscribe, ownerUserId int64) error {
|
||||
if len(movedSubscribes) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
cacheModels := make([]*user.Subscribe, 0, len(movedSubscribes)*2)
|
||||
ownerCopies := make([]user.Subscribe, len(movedSubscribes))
|
||||
for i := range movedSubscribes {
|
||||
cacheModels = append(cacheModels, &movedSubscribes[i])
|
||||
ownerCopies[i] = movedSubscribes[i]
|
||||
ownerCopies[i].UserId = ownerUserId
|
||||
cacheModels = append(cacheModels, &ownerCopies[i])
|
||||
}
|
||||
|
||||
if err := h.svcCtx.UserModel.ClearSubscribeCache(h.ctx, cacheModels...); err != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "clear moved subscribe cache failed")
|
||||
}
|
||||
|
||||
_, subscribeIDSet := buildRemovedSubscribeCacheMeta(movedSubscribes)
|
||||
for subscribeID := range subscribeIDSet {
|
||||
if err := h.svcCtx.SubscribeModel.ClearCache(h.ctx, subscribeID); err != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "clear subscribe cache failed")
|
||||
}
|
||||
}
|
||||
if err := h.svcCtx.NodeModel.ClearServerAllCache(h.ctx); err != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "clear node cache failed")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func buildRemovedSubscribeCacheMeta(removedSubscribes []user.Subscribe) ([]*user.Subscribe, map[int64]struct{}) {
|
||||
subscribeModels := make([]*user.Subscribe, 0, len(removedSubscribes))
|
||||
subscribeIDSet := make(map[int64]struct{}, len(removedSubscribes))
|
||||
|
||||
Reference in New Issue
Block a user