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 }