github.com/Go-To-Byte/DouSheng/user_center@v0.0.0-20230524130918-ad531c1a3f6a/apps/user/impl/user.go (about)

     1  // @Author: Ciusyan 2023/1/23
     2  package impl
     3  
     4  import (
     5  	"context"
     6  	"github.com/Go-To-Byte/DouSheng/dou_kit/constant"
     7  	"github.com/Go-To-Byte/DouSheng/dou_kit/exception/custom"
     8  	"github.com/Go-To-Byte/DouSheng/user_center/apps/user"
     9  	"google.golang.org/grpc/codes"
    10  	"google.golang.org/grpc/status"
    11  	"sync"
    12  )
    13  
    14  func (s *userServiceImpl) Register(ctx context.Context, req *user.LoginAndRegisterRequest) (*user.TokenResponse, error) {
    15  
    16  	// 1、请求参数校验
    17  	if err := req.Validate(); err != nil {
    18  		return nil, status.Error(codes.InvalidArgument,
    19  			constant.Code2Msg(constant.ERROR_ARGS_VALIDATE))
    20  	}
    21  
    22  	// 2、根据 Username 查询此用户是否已经注册
    23  	userReq := newGetUserReq()
    24  	userReq.Username = req.Username
    25  	po, err := s.getUser(ctx, userReq)
    26  	if err != nil {
    27  		return nil, status.Error(codes.Unavailable,
    28  			constant.Code2Msg(constant.ERROR_ACQUIRE))
    29  	}
    30  
    31  	if po.Id > 0 {
    32  		// 用户已存在
    33  		return nil, status.Error(codes.AlreadyExists,
    34  			constant.Code2Msg(constant.WRONG_EXIST_USERS))
    35  	}
    36  
    37  	// 3、未注册-创建用户,注册-返回提示
    38  	po = user.NewUserPo(req.Hash())
    39  	insertRes, err := s.insert(ctx, po)
    40  
    41  	if err != nil {
    42  		return nil, status.Error(codes.Unknown,
    43  			constant.Code2Msg(constant.ERROR_SAVE))
    44  	}
    45  
    46  	// 4、颁发Token并返回
    47  	response := user.NewTokenResponse(insertRes.Id, s.token(ctx, insertRes))
    48  
    49  	return response, nil
    50  }
    51  
    52  func (s *userServiceImpl) Login(ctx context.Context, req *user.LoginAndRegisterRequest) (
    53  	*user.TokenResponse, error) {
    54  
    55  	// 1、请求参数校验
    56  	if err := req.Validate(); err != nil {
    57  		return nil, status.Error(codes.InvalidArgument,
    58  			constant.Code2Msg(constant.ERROR_ARGS_VALIDATE))
    59  	}
    60  
    61  	// 2、根据用户名查询用户信息
    62  	userReq := newGetUserReq()
    63  	userReq.Username = req.Username
    64  	po, err := s.getUser(ctx, userReq)
    65  	if err != nil {
    66  		return nil, status.Error(codes.Unavailable,
    67  			constant.Code2Msg(constant.ERROR_ACQUIRE))
    68  	}
    69  
    70  	// 若用户名或密码有误,不返回具体的用户名或者密码错误
    71  	if po == nil || !po.CheckHash(req.Password) {
    72  		return nil, status.Error(codes.PermissionDenied,
    73  			constant.Code2Msg(constant.BAD_NAME_PASSWORD))
    74  	}
    75  
    76  	// 3、颁发Token 并返回
    77  	response := user.NewTokenResponse(po.Id, s.token(ctx, po))
    78  
    79  	return response, nil
    80  }
    81  
    82  func (s *userServiceImpl) UserInfo(ctx context.Context, req *user.UserInfoRequest) (*user.UserInfoResponse, error) {
    83  
    84  	// 请求参数校验
    85  	if err := req.Validate(); err != nil {
    86  		s.l.Errorf("user UserInfo:参数校验失败,%s", err.Error())
    87  		return nil, status.Error(codes.InvalidArgument,
    88  			constant.Code2Msg(constant.ERROR_ARGS_VALIDATE))
    89  	}
    90  
    91  	response := user.NewUserInfoResponse()
    92  	response.User = user.NewDefaultUser()
    93  	// get user info, user += userInfo
    94  
    95  	userReq := newGetUserReq()
    96  	userReq.UserId = req.UserId
    97  	po, err := s.getUser(ctx, userReq)
    98  	if err != nil {
    99  		return nil, status.Error(codes.Unavailable,
   100  			constant.Code2Msg(constant.ERROR_ACQUIRE))
   101  	}
   102  	response.User = po.Po2vo()
   103  
   104  	// 将Token放入Ctx
   105  	tkCtx := context.WithValue(ctx, constant.REQUEST_TOKEN, req.Token)
   106  
   107  	return response, s.composeInfo(tkCtx, response.User)
   108  }
   109  
   110  func (s *userServiceImpl) UserMap(ctx context.Context, req *user.UserMapRequest) (*user.UserMapResponse, error) {
   111  
   112  	// 1、获取用户列表 []User
   113  	userPoRes, err := s.userList(ctx, req.UserIds)
   114  
   115  	// 这里为什么不把错误合并在一起返回,因为有可能这里已经报错了。就没必要往后面操作了
   116  	if err != nil {
   117  		switch e := err.(type) {
   118  		case *custom.Exception:
   119  			return nil, status.Error(codes.NotFound, e.Error())
   120  		default:
   121  			return nil, status.Error(codes.Unknown, e.Error())
   122  		}
   123  	}
   124  
   125  	// 将Token放入Ctx
   126  	tkCtx := context.WithValue(ctx, constant.REQUEST_TOKEN, req.Token)
   127  
   128  	// 2、转换为 Map[UserId] = User
   129  	UserMap := make(map[int64]*user.User)
   130  	for _, po := range userPoRes {
   131  		vo := po.Po2vo()
   132  		err = s.composeInfo(tkCtx, vo)
   133  		if err != nil {
   134  			return nil, err
   135  		}
   136  		UserMap[vo.Id] = vo
   137  	}
   138  
   139  	return &user.UserMapResponse{UserMap: UserMap}, nil
   140  }
   141  
   142  func (s *userServiceImpl) composeInfo(ctx context.Context, uResp *user.User) error {
   143  
   144  	var (
   145  		wait = sync.WaitGroup{}
   146  		errs = make([]error, 0)
   147  	)
   148  
   149  	wait.Add(3)
   150  
   151  	// 组合 followListCount、followerListCount、isFollow
   152  	go func() {
   153  		defer wait.Done()
   154  
   155  		errs = append(errs, s.composeRelation(ctx, uResp)...)
   156  	}()
   157  
   158  	// 组合 publishCount
   159  	go func() {
   160  		defer wait.Done()
   161  
   162  		errs = append(errs, s.composeVideo(ctx, uResp)...)
   163  	}()
   164  
   165  	// 组合 favoriteCount
   166  	go func() {
   167  		defer wait.Done()
   168  
   169  		errs = append(errs, s.composeFavorite(ctx, uResp)...)
   170  	}()
   171  
   172  	wait.Wait()
   173  
   174  	// 查看后台调用时,是否有错误产生
   175  	for _, err := range errs {
   176  		if err != nil {
   177  			switch e := err.(type) {
   178  			case *custom.Exception:
   179  				return status.Error(codes.NotFound, e.Error())
   180  			default:
   181  				return status.Error(codes.Unknown, e.Error())
   182  			}
   183  		}
   184  	}
   185  
   186  	return nil
   187  }