Files
lone-services/services/user/internal/logic/mergeUser.go
T
2026-10-20 13:09:55 +08:00

149 lines
4.3 KiB
Go

package logic
import (
"context"
"strconv"
"lone-services/pkg/modelbase"
"lone-services/pkg/utils"
"lone-services/services/user/internal/dao"
"lone-services/services/user/internal/model"
"lone-services/services/user/internal/svc"
"gorm.io/gorm"
)
// mergeUserInto 将 fromUserId 的凭证与端关联合并到 toUserId,并删除 fromUserId。
func mergeUserInto(ctx context.Context, svcCtx *svc.ServiceContext, fromUserId, toUserId int64) error {
if fromUserId < utils.NumberOne || toUserId < utils.NumberOne || fromUserId == toUserId {
return nil
}
return svcCtx.DB.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
if err := mergeCredentials(tx, fromUserId, toUserId); err != nil {
return err
}
if err := mergeUserClients(tx, fromUserId, toUserId); err != nil {
return err
}
if err := deleteUserDetail(tx, fromUserId); err != nil {
return err
}
return deleteUser(tx, fromUserId)
})
}
func mergeCredentials(tx *gorm.DB, fromUserId, toUserId int64) error {
credModel := model.UserCredentialModel{}.Init()
credModel.Base = credModel.Base.WithTX(tx)
var creds []dao.UserCredential
if err := credModel.Items(modelbase.Params{
Eq: map[string]string{"user_id": strconv.FormatInt(fromUserId, utils.NumberTen)},
}, &creds); err != nil {
return err
}
for _, cred := range creds {
var exist dao.UserCredential
if err := credModel.GetOne(modelbase.Params{
Eq: map[string]string{
"credential_type": cred.CredentialType,
"identifier": cred.Identifier,
"subject_type": cred.SubjectType,
},
}, &exist); err != nil {
return err
}
if exist.Id > utils.NumberZero {
// 目标用户(或其他用户)已有相同凭证,丢弃来源侧重复行
if _, err := credModel.Del(modelbase.Params{
Eq: map[string]string{"id": strconv.FormatInt(cred.Id, utils.NumberTen)},
}, &dao.UserCredential{}); err != nil {
return err
}
continue
}
if _, err := credModel.Edit(modelbase.Params{
Eq: map[string]string{"id": strconv.FormatInt(cred.Id, utils.NumberTen)},
}, map[string]interface{}{
"user_id": toUserId,
}); err != nil {
return err
}
}
return nil
}
func mergeUserClients(tx *gorm.DB, fromUserId, toUserId int64) error {
clientModel := model.UserClientModel{}.Init()
clientModel.Base = clientModel.Base.WithTX(tx)
var clients []dao.UserClient
if err := clientModel.Items(modelbase.Params{
Eq: map[string]string{"user_id": strconv.FormatInt(fromUserId, utils.NumberTen)},
}, &clients); err != nil {
return err
}
for _, uc := range clients {
var exist dao.UserClient
if err := clientModel.GetOne(modelbase.Params{
Eq: map[string]string{
"user_id": strconv.FormatInt(toUserId, utils.NumberTen),
"client_code": uc.ClientCode,
},
}, &exist); err != nil {
return err
}
if exist.Id > utils.NumberZero {
updates := map[string]interface{}{}
if exist.BizId < utils.NumberOne && uc.BizId > utils.NumberZero {
updates["biz_id"] = uc.BizId
}
if exist.Status != dao.StatusEnabled {
updates["status"] = dao.StatusEnabled
}
if len(updates) > utils.NumberZero {
if _, err := clientModel.Edit(modelbase.Params{
Eq: map[string]string{"id": strconv.FormatInt(exist.Id, utils.NumberTen)},
}, updates); err != nil {
return err
}
}
if _, err := clientModel.Del(modelbase.Params{
Eq: map[string]string{"id": strconv.FormatInt(uc.Id, utils.NumberTen)},
}, &dao.UserClient{}); err != nil {
return err
}
continue
}
if _, err := clientModel.Edit(modelbase.Params{
Eq: map[string]string{"id": strconv.FormatInt(uc.Id, utils.NumberTen)},
}, map[string]interface{}{
"user_id": toUserId,
}); err != nil {
return err
}
}
return nil
}
func deleteUserDetail(tx *gorm.DB, userId int64) error {
detailModel := model.UserDetailModel{}.Init()
detailModel.Base = detailModel.Base.WithTX(tx)
_, err := detailModel.Del(modelbase.Params{
Eq: map[string]string{"user_id": strconv.FormatInt(userId, utils.NumberTen)},
}, &dao.UserDetail{})
return err
}
func deleteUser(tx *gorm.DB, userId int64) error {
userModel := model.UserModel{}.Init()
userModel.Base = userModel.Base.WithTX(tx)
_, err := userModel.Del(modelbase.Params{
Eq: map[string]string{"id": strconv.FormatInt(userId, utils.NumberTen)},
}, &dao.UserRow{})
return err
}