From e6bd78aa7676e1d9423cf2ddaeff8d3eef0d7c7b Mon Sep 17 00:00:00 2001 From: shanshanzhong Date: Tue, 28 Oct 2025 02:25:40 -0700 Subject: [PATCH] =?UTF-8?q?refactor(auth):=20=E8=B0=83=E6=95=B4=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E6=A0=BC=E5=BC=8F=E5=92=8C=E6=B3=A8=E9=87=8A=E4=BB=A5?= =?UTF-8?q?=E6=8F=90=E9=AB=98=E5=8F=AF=E8=AF=BB=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit style(user): 统一代码缩进和注释格式 fix(user): 修改设备冲突处理逻辑为更新归属而非删除 refactor(user): 移除不必要的用户删除逻辑和缓存清理 --- internal/logic/auth/bindDeviceLogic.go | 44 ++++++++-------- .../user/bindEmailWithVerificationLogic.go | 52 +++++-------------- 2 files changed, 35 insertions(+), 61 deletions(-) diff --git a/internal/logic/auth/bindDeviceLogic.go b/internal/logic/auth/bindDeviceLogic.go index 94b5de6..8606994 100644 --- a/internal/logic/auth/bindDeviceLogic.go +++ b/internal/logic/auth/bindDeviceLogic.go @@ -15,15 +15,16 @@ import ( // 负责处理设备与用户的绑定关系,包括新设备创建、设备重新绑定、数据迁移等核心功能 // 主要解决设备用户与邮箱用户之间的数据合并问题 type BindDeviceLogic struct { - logger.Logger // 日志记录器,用于记录操作过程和错误信息 - ctx context.Context // 上下文,用于传递请求信息和控制超时 - svcCtx *svc.ServiceContext // 服务上下文,包含数据库连接、配置等依赖 + logger.Logger // 日志记录器,用于记录操作过程和错误信息 + ctx context.Context // 上下文,用于传递请求信息和控制超时 + svcCtx *svc.ServiceContext // 服务上下文,包含数据库连接、配置等依赖 } // NewBindDeviceLogic 创建设备绑定逻辑处理器实例 // 参数: // - ctx: 请求上下文,用于传递请求信息和控制超时 // - svcCtx: 服务上下文,包含数据库连接、配置等依赖 +// // 返回: // - *BindDeviceLogic: 设备绑定逻辑处理器实例 func NewBindDeviceLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BindDeviceLogic { @@ -141,10 +142,10 @@ func (l *BindDeviceLogic) createDeviceForUser(identifier, ip, userAgent string, // 第一步:创建设备认证方法记录 // 在auth_methods表中记录该设备的认证信息 authMethod := &user.AuthMethods{ - UserId: userId, // 关联的用户ID - AuthType: "device", // 认证类型为设备认证 - AuthIdentifier: identifier, // 设备标识符 - Verified: true, // 设备认证默认为已验证状态 + UserId: userId, // 关联的用户ID + AuthType: "device", // 认证类型为设备认证 + AuthIdentifier: identifier, // 设备标识符 + Verified: true, // 设备认证默认为已验证状态 } if err := db.Create(authMethod).Error; err != nil { l.Errorw("failed to create device auth method", @@ -158,12 +159,12 @@ func (l *BindDeviceLogic) createDeviceForUser(identifier, ip, userAgent string, // 第二步:创建设备信息记录 // 在device表中记录设备的详细信息 deviceInfo := &user.Device{ - Ip: ip, // 设备IP地址 - UserId: userId, // 关联的用户ID - UserAgent: userAgent, // 设备User-Agent信息 - Identifier: identifier, // 设备唯一标识符 - Enabled: true, // 设备默认启用状态 - Online: false, // 设备默认离线状态 + Ip: ip, // 设备IP地址 + UserId: userId, // 关联的用户ID + UserAgent: userAgent, // 设备User-Agent信息 + Identifier: identifier, // 设备唯一标识符 + Enabled: true, // 设备默认启用状态 + Online: false, // 设备默认离线状态 } if err := db.Create(deviceInfo).Error; err != nil { l.Errorw("failed to create device", @@ -224,11 +225,12 @@ func (l *BindDeviceLogic) createDeviceForUser(identifier, ip, userAgent string, // // 核心判断逻辑: // 1. 如果原用户是"纯设备用户"(只有设备认证,无邮箱等其他认证方式): -// - 执行完整数据迁移(订单、订阅、余额、赠送金额) -// - 禁用原用户账户 +// - 执行完整数据迁移(订单、订阅、余额、赠送金额) +// - 禁用原用户账户 +// // 2. 如果原用户有其他认证方式(如邮箱、手机等): -// - 只转移设备绑定关系 -// - 保留原用户账户和数据 +// - 只转移设备绑定关系 +// - 保留原用户账户和数据 // // 参数: // - deviceInfo: 现有的设备信息记录 @@ -268,7 +270,7 @@ func (l *BindDeviceLogic) rebindDeviceToNewUser(deviceInfo *user.Device, ip, use // 第三步:根据用户类型执行不同的处理逻辑 if nonDeviceAuthCount == 0 { // 原用户是"纯设备用户",执行完整的数据迁移和用户禁用 - + // 3.1 先执行数据迁移(订单、订阅、余额等) if err := l.migrateUserData(db, oldUserId, newUserId); err != nil { l.Errorw("failed to migrate user data", @@ -317,9 +319,9 @@ func (l *BindDeviceLogic) rebindDeviceToNewUser(deviceInfo *user.Device, ip, use // 第五步:更新设备记录信息 // 更新device表中的设备信息,包括用户ID、IP、UserAgent等 deviceInfo.UserId = newUserId // 更新设备归属用户 - deviceInfo.Ip = ip // 更新设备IP + deviceInfo.Ip = ip // 更新设备IP deviceInfo.UserAgent = userAgent // 更新设备UserAgent - deviceInfo.Enabled = true // 确保设备处于启用状态 + deviceInfo.Enabled = true // 确保设备处于启用状态 if err := db.Save(deviceInfo).Error; err != nil { l.Errorw("failed to update device", @@ -468,7 +470,7 @@ func (l *BindDeviceLogic) migrateUserData(db *gorm.DB, oldUserId, newUserId int6 // 只有当原用户有余额或赠送金额时才执行更新操作 if oldUser.Balance > 0 || oldUser.GiftAmount > 0 { if err := db.Model(&user.User{}).Where("id = ?", newUserId).Updates(map[string]interface{}{ - "balance": gorm.Expr("balance + ?", oldUser.Balance), // 累加余额 + "balance": gorm.Expr("balance + ?", oldUser.Balance), // 累加余额 "gift_amount": gorm.Expr("gift_amount + ?", oldUser.GiftAmount), // 累加赠送金额 }).Error; err != nil { l.Errorw("failed to migrate user balance and gift", diff --git a/internal/logic/public/user/bindEmailWithVerificationLogic.go b/internal/logic/public/user/bindEmailWithVerificationLogic.go index dfa81de..213b1b7 100644 --- a/internal/logic/public/user/bindEmailWithVerificationLogic.go +++ b/internal/logic/public/user/bindEmailWithVerificationLogic.go @@ -119,7 +119,8 @@ func (l *BindEmailWithVerificationLogic) transferDeviceToEmailUser(deviceUserId, logger.Field("email_user_id", emailUserId), logger.Field("device_identifier", deviceIdentifier)) - // 1. 先获取当前用户的SessionId,用于后续清理 + // 1. 先获取当前用户的SessionId,用于后续清理 可以不需要 + currentSessionId := "" if sessionIdValue := l.ctx.Value(constant.CtxKeySessionID); sessionIdValue != nil { currentSessionId = sessionIdValue.(string) @@ -149,7 +150,7 @@ func (l *BindEmailWithVerificationLogic) transferDeviceToEmailUser(deviceUserId, l.Errorw("转移ReferCode失败", logger.Field("error", err.Error())) return err } - l.Infow("已转移设备用户的ReferCode到邮箱用户", + l.Infow("已转移设备用户的ReferCode到邮箱用户", logger.Field("device_user_id", deviceUserId), logger.Field("email_user_id", emailUserId), logger.Field("refer_code", deviceUser.ReferCode)) @@ -160,7 +161,7 @@ func (l *BindEmailWithVerificationLogic) transferDeviceToEmailUser(deviceUserId, l.Errorw("生成邮箱用户ReferCode失败", logger.Field("error", err.Error())) return err } - l.Infow("已为邮箱用户生成新的ReferCode", + l.Infow("已为邮箱用户生成新的ReferCode", logger.Field("email_user_id", emailUserId), logger.Field("refer_code", newReferCode)) } @@ -172,7 +173,7 @@ func (l *BindEmailWithVerificationLogic) transferDeviceToEmailUser(deviceUserId, l.Errorw("转移RefererId失败", logger.Field("error", err.Error())) return err } - l.Infow("已转移设备用户的RefererId到邮箱用户", + l.Infow("已转移设备用户的RefererId到邮箱用户", logger.Field("device_user_id", deviceUserId), logger.Field("email_user_id", emailUserId), logger.Field("referer_id", deviceUser.RefererId)) @@ -191,11 +192,11 @@ func (l *BindEmailWithVerificationLogic) transferDeviceToEmailUser(deviceUserId, return nil } - // 6. 处理设备冲突 - 删除目标用户的现有设备记录(如果存在) + // 6. 处理设备冲突 - 将现有设备记录的归属修改为邮箱用户 if existingDevice != nil && existingDevice.UserId != emailUserId { - l.Infow("删除冲突的设备记录", logger.Field("existing_device_id", existingDevice.Id), logger.Field("existing_user_id", existingDevice.UserId)) - if err := db.Where("identifier = ? AND user_id = ?", deviceIdentifier, existingDevice.UserId).Delete(&user.Device{}).Error; err != nil { - l.Errorw("删除冲突设备记录失败", logger.Field("error", err.Error())) + l.Infow("更新冲突设备记录的归属", logger.Field("existing_device_id", existingDevice.Id), logger.Field("old_user_id", existingDevice.UserId), logger.Field("new_user_id", emailUserId)) + if err := db.Model(&user.Device{}).Where("identifier = ? AND user_id = ?", deviceIdentifier, existingDevice.UserId).Update("user_id", emailUserId).Error; err != nil { + l.Errorw("更新冲突设备记录归属失败", logger.Field("error", err.Error())) return err } } @@ -216,35 +217,6 @@ func (l *BindEmailWithVerificationLogic) transferDeviceToEmailUser(deviceUserId, return err } - // 9. 检查原始设备用户是否还有其他认证方式,如果没有则删除该用户 - var remainingAuthMethods []user.AuthMethods - if err := db.Where("user_id = ?", deviceUserId).Find(&remainingAuthMethods).Error; err != nil { - l.Errorw("查询原始用户剩余认证方式失败", logger.Field("error", err.Error()), logger.Field("device_user_id", deviceUserId)) - return err - } - - if len(remainingAuthMethods) == 0 { - // 获取原始用户信息用于清除缓存 - deviceUser, _ := l.svcCtx.UserModel.FindOne(l.ctx, deviceUserId) - - // 原始用户没有其他认证方式,可以安全删除 - if err := db.Where("id = ?", deviceUserId).Delete(&user.User{}).Error; err != nil { - l.Errorw("删除原始设备用户失败", logger.Field("error", err.Error()), logger.Field("device_user_id", deviceUserId)) - return err - } - - // 清除已删除用户的缓存 - if deviceUser != nil { - l.svcCtx.UserModel.ClearUserCache(l.ctx, deviceUser) - } - - l.Infow("已删除原始设备用户", logger.Field("device_user_id", deviceUserId)) - } else { - l.Infow("原始用户还有其他认证方式,保留用户记录", - logger.Field("device_user_id", deviceUserId), - logger.Field("remaining_auth_count", len(remainingAuthMethods))) - } - l.Infow("设备转移成功", logger.Field("device_user_id", deviceUserId), logger.Field("email_user_id", emailUserId), @@ -284,7 +256,7 @@ func (l *BindEmailWithVerificationLogic) transferDeviceToEmailUser(deviceUserId, } // 6. 清除设备相关缓存 - l.clearDeviceRelatedCache(deviceIdentifier, deviceUserId, emailUserId) + // l.clearDeviceRelatedCache(deviceIdentifier, deviceUserId, emailUserId) return &types.BindEmailWithVerificationResponse{ Success: true, @@ -328,7 +300,7 @@ func (l *BindEmailWithVerificationLogic) generateTokenForUser(userId int64) (str func (l *BindEmailWithVerificationLogic) createEmailUser(email string) (int64, error) { // 检查是否启用了强制邀请码 if l.svcCtx.Config.Invite.ForcedInvite { - l.Errorw("邮箱绑定创建新用户时需要邀请码,但当前API不支持邀请码参数", + l.Errorw("邮箱绑定创建新用户时需要邀请码,但当前API不支持邀请码参数", logger.Field("email", email), logger.Field("forced_invite", true)) return 0, xerr.NewErrMsg("创建新用户需要邀请码,请使用支持邀请码的注册方式") @@ -357,7 +329,7 @@ func (l *BindEmailWithVerificationLogic) createEmailUser(email string) (int64, e l.Errorw("更新用户ReferCode失败", logger.Field("error", err.Error())) return err } - l.Infow("设置用户ReferCode成功", + l.Infow("设置用户ReferCode成功", logger.Field("user_id", newUserId), logger.Field("refer_code", newUser.ReferCode))