package user import ( "context" "fmt" "git.x2erp.com/qdy/go-base/ctx" "git.x2erp.com/qdy/go-base/logger" "git.x2erp.com/qdy/go-base/model/request/configreq" "git.x2erp.com/qdy/go-base/model/response" "git.x2erp.com/qdy/go-base/util" "git.x2erp.com/qdy/go-db/factory/database" "git.x2erp.com/qdy/go-svc-configure/internal/service/dao" ) // RegisterUser 用户注册(需邀请码) func RegisterUser(req *configreq.UserRegisterRequest, ctx context.Context, dbFactory *database.DBFactory, reqCtx *ctx.RequestContext) *response.QueryResult[int64] { logger.Debug("RegisterUser-开始用户注册") // 参数验证 if req.UserID == "" || req.Password == "" || req.Name == "" || req.Mobile == "" || req.InvitationCode == "" { logger.ErrorC(reqCtx, "用户注册参数不能为空") return util.CreateErrorResult[int64]("用户注册参数不能为空", reqCtx) } // 密码强度验证 if len(req.Password) < 6 { logger.ErrorC(reqCtx, "密码长度至少6位") return util.CreateErrorResult[int64]("密码长度至少6位", reqCtx) } // 获取数据库连接并开始事务 db := dbFactory.GetDB() tx, err := db.BeginTxx(ctx, nil) if err != nil { logger.ErrorC(reqCtx, fmt.Sprintf("开始事务失败: %v", err)) return util.CreateErrorResult[int64](fmt.Sprintf("开始事务失败: %v", err), reqCtx) } defer func() { if p := recover(); p != nil { tx.Rollback() panic(p) } }() // 验证邀请码有效性 invitation, err := dao.ValidateInvitationCode(ctx, db, req.InvitationCode) if err != nil { tx.Rollback() logger.ErrorC(reqCtx, fmt.Sprintf("邀请码验证失败: %v", err)) return util.CreateErrorResult[int64](fmt.Sprintf("邀请码验证失败: %v", err), reqCtx) } // 检查用户是否已存在(同一租户下) userExists, err := dao.CheckUserExists(ctx, db, req.UserID, invitation.TenantID) if err != nil { tx.Rollback() logger.ErrorC(reqCtx, fmt.Sprintf("检查用户存在性失败: %v", err)) return util.CreateErrorResult[int64](fmt.Sprintf("检查用户存在性失败: %v", err), reqCtx) } if userExists { tx.Rollback() logger.ErrorC(reqCtx, fmt.Sprintf("用户 '%s' 在租户 '%s' 中已存在", req.UserID, invitation.TenantID)) return util.CreateErrorResult[int64](fmt.Sprintf("用户 '%s' 在租户 '%s' 中已存在", req.UserID, invitation.TenantID), reqCtx) } // 创建用户 creator := "system" // 系统创建的用户 rowsAffected, err := dao.CreateUser(ctx, tx, req.UserID, invitation.TenantID, req.Name, req.Mobile, req.Password, req.Email, creator) if err != nil { tx.Rollback() logger.ErrorC(reqCtx, fmt.Sprintf("创建用户失败: %v", err)) return util.CreateErrorResult[int64](fmt.Sprintf("创建用户失败: %v", err), reqCtx) } // 为用户分配邀请码关联的角色 roleRowsAffected, err := dao.AssignUserRole(ctx, tx, req.UserID, invitation.RoleID, creator) if err != nil { tx.Rollback() logger.ErrorC(reqCtx, fmt.Sprintf("分配角色失败: %v", err)) return util.CreateErrorResult[int64](fmt.Sprintf("分配角色失败: %v", err), reqCtx) } // 标记邀请码已使用 invitationRowsAffected, err := dao.MarkInvitationCodeUsed(ctx, tx, req.InvitationCode, req.UserID) if err != nil { tx.Rollback() logger.ErrorC(reqCtx, fmt.Sprintf("标记邀请码已使用失败: %v", err)) return util.CreateErrorResult[int64](fmt.Sprintf("标记邀请码已使用失败: %v", err), reqCtx) } // 提交事务 if err := tx.Commit(); err != nil { logger.ErrorC(reqCtx, fmt.Sprintf("提交事务失败: %v", err)) return util.CreateErrorResult[int64](fmt.Sprintf("提交事务失败: %v", err), reqCtx) } logger.Debug(fmt.Sprintf("成功注册用户: %s, 租户: %s, 角色: %s, 影响行数: %d (用户: %d, 角色: %d, 邀请码: %d)", req.UserID, invitation.TenantID, invitation.RoleID, rowsAffected+roleRowsAffected+invitationRowsAffected, rowsAffected, roleRowsAffected, invitationRowsAffected)) return util.CreateSuccessResultData[int64](rowsAffected+roleRowsAffected+invitationRowsAffected, reqCtx) }