package service import ( "context" "database/sql" "tydata-server/app/main/api/internal/config" "tydata-server/app/main/model" "tydata-server/common/ctxdata" jwtx "tydata-server/common/jwt" "tydata-server/common/xerr" "github.com/google/uuid" "github.com/pkg/errors" "github.com/zeromicro/go-zero/core/stores/sqlx" ) type UserService struct { Config *config.Config userModel model.UserModel userAuthModel model.UserAuthModel userTempModel model.UserTempModel agentModel model.AgentModel } // NewUserService 创建UserService实例 func NewUserService(config *config.Config, userModel model.UserModel, userAuthModel model.UserAuthModel, userTempModel model.UserTempModel, agentModel model.AgentModel) *UserService { return &UserService{ Config: config, userModel: userModel, userAuthModel: userAuthModel, userTempModel: userTempModel, agentModel: agentModel, } } // GenerateUUIDUserId 生成UUID用户ID func (s *UserService) GenerateUUIDUserId(ctx context.Context) (string, error) { id := uuid.NewString() return id, nil } // RegisterUUIDUser 注册UUID用户,返回用户ID func (s *UserService) RegisterUUIDUser(ctx context.Context) (int64, error) { // 生成UUID uuidStr, err := s.GenerateUUIDUserId(ctx) if err != nil { return 0, err } var userId int64 err = s.userModel.Trans(ctx, func(ctx context.Context, session sqlx.Session) error { // 创建用户记录 user := &model.User{} result, err := s.userModel.Insert(ctx, session, user) if err != nil { return err } userId, err = result.LastInsertId() if err != nil { return err } // 创建用户认证记录 userAuth := &model.UserAuth{ UserId: userId, AuthType: model.UserAuthTypeUUID, AuthKey: uuidStr, } _, err = s.userAuthModel.Insert(ctx, session, userAuth) return err }) if err != nil { return 0, err } return userId, nil } // generalUserToken 生成用户token func (s *UserService) GeneralUserToken(ctx context.Context, userID int64) (string, error) { platform, err := ctxdata.GetPlatformFromCtx(ctx) if err != nil { return "", err } var isAgent int64 var agentID int64 var userType int64 user, err := s.userModel.FindOne(ctx, userID) if err != nil && !errors.Is(err, model.ErrNotFound) { return "", err } if user != nil { userID = user.Id userType = model.UserTypeNormal agent, err := s.agentModel.FindOneByUserId(ctx, userID) if err != nil && !errors.Is(err, model.ErrNotFound) { return "", err } if agent != nil { agentID = agent.Id isAgent = model.AgentStatusYes } } else { userTemp, err := s.userTempModel.FindOne(ctx, userID) if err != nil { return "", err } if userTemp != nil { userID = userTemp.Id userType = model.UserTypeTemp } } token, generaErr := jwtx.GenerateJwtToken(jwtx.JwtClaims{ UserId: userID, AgentId: agentID, Platform: platform, UserType: userType, IsAgent: isAgent, }, s.Config.JwtAuth.AccessSecret, s.Config.JwtAuth.AccessExpire) if generaErr != nil { return "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "更新token, 生成token失败 : %d", userID) } return token, nil } // RegisterUser 注册用户,返回用户ID // 传入手机号,自动注册,如果ctx存在临时用户则临时用户转为正式用户 func (s *UserService) RegisterUser(ctx context.Context, mobile string) (int64, error) { claims, err := ctxdata.GetClaimsFromCtx(ctx) if err != nil && !errors.Is(err, ctxdata.ErrNoInCtx) { return 0, err } user, err := s.userModel.FindOneByMobile(ctx, sql.NullString{String: mobile, Valid: true}) if err != nil && !errors.Is(err, model.ErrNotFound) { return 0, err } if user != nil { return 0, errors.New("用户已注册") } // 普通注册 if claims == nil { var userId int64 err = s.userModel.Trans(ctx, func(ctx context.Context, session sqlx.Session) error { user := &model.User{ Mobile: sql.NullString{String: mobile, Valid: true}, } result, err := s.userModel.Insert(ctx, session, user) if err != nil { return err } userId, err = result.LastInsertId() if err != nil { return err } s.userAuthModel.Insert(ctx, session, &model.UserAuth{ UserId: userId, AuthType: model.UserAuthTypeMobile, AuthKey: mobile, }) return nil }) if err != nil { return 0, err } return userId, nil } // 双重判断是否已经注册 if claims.UserType == model.UserTypeNormal { return 0, errors.New("用户已注册") } var userId int64 // 临时转正式注册 err = s.userModel.Trans(ctx, func(ctx context.Context, session sqlx.Session) error { user := &model.User{ Mobile: sql.NullString{String: mobile, Valid: true}, } result, err := s.userModel.Insert(ctx, session, user) if err != nil { return err } userId, err = result.LastInsertId() if err != nil { return err } _, err = s.userAuthModel.Insert(ctx, session, &model.UserAuth{ UserId: userId, AuthType: model.UserAuthTypeMobile, AuthKey: mobile, }) if err != nil { return err } err = s.TempUserBindUser(ctx, session, userId) if err != nil { return err } return nil }) if err != nil { return 0, err } return userId, nil } // TempUserBindUser 临时用户绑定用户 func (s *UserService) TempUserBindUser(ctx context.Context, session sqlx.Session, normalUserID int64) error { claims, err := ctxdata.GetClaimsFromCtx(ctx) if err != nil && !errors.Is(err, ctxdata.ErrNoInCtx) { return err } if claims == nil || claims.UserType != model.UserTypeTemp { return errors.New("无临时用户") } userTemp, err := s.userTempModel.FindOne(ctx, claims.UserId) if err != nil { return err } userAuth, err := s.userAuthModel.FindOneByAuthTypeAuthKey(ctx, userTemp.AuthType, userTemp.AuthKey) if err != nil && !errors.Is(err, model.ErrNotFound) { return err } if userAuth != nil { return errors.New("临时用户已注册") } if session == nil { err := s.userAuthModel.Trans(ctx, func(ctx context.Context, session sqlx.Session) error { _, err = s.userAuthModel.Insert(ctx, session, &model.UserAuth{ UserId: normalUserID, AuthType: userTemp.AuthType, AuthKey: userTemp.AuthKey, }) if err != nil { return err } err = s.userTempModel.DeleteSoft(ctx, session, userTemp) if err != nil { return err } return nil }) if err != nil { return err } return nil } else { _, err = s.userAuthModel.Insert(ctx, session, &model.UserAuth{ UserId: normalUserID, AuthType: userTemp.AuthType, AuthKey: userTemp.AuthKey, }) if err != nil { return err } err = s.userTempModel.DeleteSoft(ctx, session, userTemp) if err != nil { return err } return nil } } // _bak_RegisterUUIDUser 注册UUID用户,返回用户ID func (s *UserService) _bak_RegisterUUIDUser(ctx context.Context) error { // 生成UUID uuidStr, err := s.GenerateUUIDUserId(ctx) if err != nil { return err } err = s.userTempModel.Trans(ctx, func(ctx context.Context, session sqlx.Session) error { // 创建用户临时记录 userTemp := &model.UserTemp{ AuthType: model.UserAuthTypeUUID, AuthKey: uuidStr, } _, err := s.userTempModel.Insert(ctx, session, userTemp) return err }) if err != nil { return err } return nil }