package user import ( "context" "time" "ycc-server/app/main/api/internal/svc" "ycc-server/app/main/api/internal/types" "ycc-server/app/main/model" "ycc-server/common/xerr" "github.com/google/uuid" "github.com/pkg/errors" ) type AuthLogic struct { ctx context.Context svcCtx *svc.ServiceContext } func NewAuthLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AuthLogic { return &AuthLogic{ctx: ctx, svcCtx: svcCtx} } func (l *AuthLogic) Auth(req *types.AuthReq) (*types.AuthResp, error) { var userID string var userType int64 var authType string var authKey string switch req.Platform { case model.PlatformH5: authType = model.UserAuthTypeUUID authKey = uuid.NewString() user, err := l.findOrCreateUserByAuth(authType, authKey) if err != nil { return nil, err } userID = user.Id userType = l.getUserType(user) case model.PlatformWxH5: openid, err := l.svcCtx.VerificationService.GetWechatH5OpenID(l.ctx, req.Code) if err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取WxH5 OpenID失败: %v", err) } authType = model.UserAuthTypeWxh5OpenID authKey = openid userAuth, err := l.svcCtx.UserAuthModel.FindOneByAuthTypeAuthKey(l.ctx, authType, authKey) if err != nil && !errors.Is(err, model.ErrNotFound) { return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询用户授权失败: %v", err) } if userAuth != nil { user, _ := l.svcCtx.UserModel.FindOne(l.ctx, userAuth.UserId) userID = user.Id userType = l.getUserType(user) } else { user, err := l.createUserWithAuth(authType, authKey) if err != nil { return nil, err } userID = user.Id userType = model.UserTypeTemp } case model.PlatformWxMini: openid, err := l.svcCtx.VerificationService.GetWechatMiniOpenID(l.ctx, req.Code) if err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取WxMini OpenID失败: %v", err) } authType = model.UserAuthTypeWxMiniOpenID authKey = openid userAuth, err := l.svcCtx.UserAuthModel.FindOneByAuthTypeAuthKey(l.ctx, authType, authKey) if err != nil && !errors.Is(err, model.ErrNotFound) { return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询用户授权失败: %v", err) } if userAuth != nil { user, _ := l.svcCtx.UserModel.FindOne(l.ctx, userAuth.UserId) userID = user.Id userType = l.getUserType(user) } else { user, err := l.createUserWithAuth(authType, authKey) if err != nil { return nil, err } userID = user.Id userType = model.UserTypeTemp } default: return nil, errors.Wrapf(xerr.NewErrMsg("不支持的平台类型"), "platform=%s", req.Platform) } token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID, userType) if err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成Token失败: %v", err) } now := time.Now().Unix() user, _ := l.svcCtx.UserModel.FindOne(l.ctx, userID) hasMobile := user.Mobile.Valid isAgent := false if hasMobile { agent, _ := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID) isAgent = agent != nil } return &types.AuthResp{ AccessToken: token, AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire, RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter, UserType: userType, HasMobile: hasMobile, IsAgent: isAgent, }, nil } func (l *AuthLogic) findOrCreateUserByAuth(authType, authKey string) (*model.User, error) { userAuth, err := l.svcCtx.UserAuthModel.FindOneByAuthTypeAuthKey(l.ctx, authType, authKey) if err != nil && !errors.Is(err, model.ErrNotFound) { return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查找用户授权失败: %v", err) } if userAuth != nil { user, err := l.svcCtx.UserModel.FindOne(l.ctx, userAuth.UserId) return user, err } return l.createUserWithAuth(authType, authKey) } func (l *AuthLogic) createUserWithAuth(authType, authKey string) (*model.User, error) { user := &model.User{Id: uuid.NewString()} _, err := l.svcCtx.UserModel.Insert(l.ctx, nil, user) if err != nil { return nil, err } ua := &model.UserAuth{Id: uuid.NewString(), UserId: user.Id, AuthType: authType, AuthKey: authKey} _, err = l.svcCtx.UserAuthModel.Insert(l.ctx, nil, ua) if err != nil { return nil, err } return l.svcCtx.UserModel.FindOne(l.ctx, user.Id) } func (l *AuthLogic) getUserType(user *model.User) int64 { if user.Mobile.Valid { return model.UserTypeNormal } return model.UserTypeTemp }