package service import ( "context" "errors" "github.com/jinzhu/gorm" "github.com/longjoy/micro-go-course/section08/user/dao" "github.com/longjoy/micro-go-course/section08/user/redis" "log" "time" ) type UserInfoDTO struct { ID int64 `json:"id"` Username string `json:"username"` Email string `json:"email"` } type RegisterUserVO struct { Username string Password string Email string } var ( ErrUserExisted = errors.New("user is existed") ErrPassword = errors.New("email and password are not match") ErrRegistering = errors.New("email is registering") ) type UserService interface { // 登录接口 Login(ctx context.Context, email, password string) (*UserInfoDTO, error) // 注册接口 Register(ctx context.Context, vo *RegisterUserVO) (*UserInfoDTO, error) } type UserServiceImpl struct { userDAO dao.UserDAO } func MakeUserServiceImpl(userDAO dao.UserDAO) UserService { return &UserServiceImpl{ userDAO: userDAO, } } func (userService *UserServiceImpl) Login(ctx context.Context, email, password string) (*UserInfoDTO, error) { user, err := userService.userDAO.SelectByEmail(email) if err == nil { if user.Password == password { return &UserInfoDTO{ ID: user.ID, Username: user.Username, Email: user.Email, }, nil } else { return nil, ErrPassword } } else { log.Printf("err : %s", err) } return nil, err } func (userService UserServiceImpl) Register(ctx context.Context, vo *RegisterUserVO) (*UserInfoDTO, error) { lock := redis.GetRedisLock(vo.Email, time.Duration(5)*time.Second) err := lock.Lock() if err != nil { log.Printf("err : %s", err) return nil, ErrRegistering } defer lock.Unlock() existUser, err := userService.userDAO.SelectByEmail(vo.Email) if (err == nil && existUser == nil) || err == gorm.ErrRecordNotFound { newUser := &dao.UserEntity{ Username: vo.Username, Password: vo.Password, Email: vo.Email, } err = userService.userDAO.Save(newUser) if err == nil { return &UserInfoDTO{ ID: newUser.ID, Username: newUser.Username, Email: newUser.Email, }, nil } } if err == nil { err = ErrUserExisted } return nil, err }