【Go实战 | 电商平台】(4) 用户注册

这是我参与11月更文挑战的第24天,活动详情查看:2021最后一次更文挑战

用到的包

github.com/gin-contrib/sessions

github.com/gin-contrib/sessions/cookie

github.com/gin-gonic/gin

1. 编写路由

  • 新建一个WSGI应用程序实例。
	r := gin.Default()
复制代码
  • 设置全局变量store
	store := cookie.NewStore([]byte("something-very-secret"))
复制代码
  • 在路由中使用中间件调用store
	r.Use(sessions.Sessions("mysession", store))
复制代码

2. 注册路由

  • 分一个基础路由组
v1 := r.Group("api/v1")
复制代码
  • 在这个基础路由编写用户注册路由
v1 := r.Group("api/v1")
{
	//用户操作
	v1.POST("user/register", api.UserRegister)
}
复制代码

3. 注册接口

3.1 service层

  • service先创建一个user.go

在这里插入图片描述

  • 再在service层上编写用户注册服务的结构体
//UserRegisterService 管理用户注册服务
type UserRegisterService struct {
	Nickname  string `form:"nickname" json:"nickname" binding:"required,min=2,max=10"`
	UserName  string `form:"user_name" json:"user_name" binding:"required,min=5,max=15"`
	Password  string `form:"password" json:"password" binding:"required,min=8,max=16"`
}
复制代码
  • 在service上编写用户注册register方法
func (service *UserRegisterService) Register() {
	
}
复制代码

在这里插入图片描述

3.2 api层

  • api层创建user.go

在这里插入图片描述

  • 申请一个 UserRegisterService用户注册服务对象。
var userRegisterService service.UserRegisterService
复制代码

但是这个服务我们还没有写,先把这个接口写完,再把这个服务补上。

  • 上下文绑定数据
c.ShouldBind(&userRegisterService)
复制代码
  • 调用这个服务的register方法
res := userRegisterService.Register()
复制代码
  • 返回这个服务的处理结果
c.JSON(200, res)
复制代码
  • api 层的用户注册服务全部代码
func UserRegister(c *gin.Context) {
	var userRegisterService service.UserRegisterService 
	//相当于创建了一个UserRegisterService对象
	if err := c.ShouldBind(&userRegisterService); err == nil {
		res := userRegisterService.Register()
		//调用这个对象中的Register方法。
		c.JSON(200, res)
	} else {
		c.JSON(200, ErrorResponse(err))
		logging.Info(err)
	}
}
复制代码
  • 创建一个common.go文件, 进行错误的返回

在这里插入图片描述

//返回错误信息 ErrorResponse
func ErrorResponse(err error) serializer.Response {
	if ve, ok := err.(validator.ValidationErrors); ok {
		for _, e := range ve {
			field := conf.T(fmt.Sprintf("Field.%s", e.Field))
			tag := conf.T(fmt.Sprintf("Tag.Valid.%s", e.Tag))
			return serializer.Response{
				Status: 40001,
				Msg:    fmt.Sprintf("%s%s", field, tag),
				Error:  fmt.Sprint(err),
			}
		}
	}
	if _, ok := err.(*json.UnmarshalTypeError); ok {
		return serializer.Response{
			Status: 40001,
			Msg:    "JSON类型不匹配",
			Error:  fmt.Sprint(err),
		}
	}
	return serializer.Response{
		Status: 40001,
		Msg:    "参数错误",
		Error:  fmt.Sprint(err),
	}
}

复制代码

3.2 serializer

  • 创建一个基础的序列化返回结构体
// Response 基础序列化器
type Response struct {
	Status int         `json:"status"`
	Data   interface{} `json:"data"`
	Msg    string      `json:"msg"`
	Error  string      `json:"error"`
}
复制代码

在这里插入图片描述

4. 注册服务

接下来我们就可以编写register()注册服务了

  • 先对传过来的用户名进行验证,查看是否已经存在了
	model.DB.Model(&model.User{}).Where("user_name=?",service.UserName).Count(&count)
	if count == 1 {
		code = e.ErrorExistUser
		return serializer.Response{
			Status: code,
			Msg:    e.GetMsg(code),
		}
	}
复制代码
  • 再对密码进行加密
	if err := user.SetPassword(service.Password); err != nil {
		logging.Info(err)
		code = e.ErrorFailEncryption
		return serializer.Response{
			Status: code,
			Msg:    e.GetMsg(code),
		}
	}
复制代码

注意: 我们可以直接再model/user.go下编写密码加密方法

const (
	PassWordCost        = 12         //密码加密难度
	Active       string = "active"   //激活用户
)

//SetPassword 设置密码
func (user *User) SetPassword(password string) error {
	bytes, err := bcrypt.GenerateFromPassword([]byte(password), PassWordCost)
	if err != nil {
		return err
	}
	user.PasswordDigest = string(bytes)
	return nil
}
复制代码
  • 确认无误之后对用户进行创建
	if err := model.DB.Create(&user).Error; err != nil {
		logging.Info(err)
		code = e.ErrorDatabase
		return serializer.Response{
			Status: code,
			Msg:    e.GetMsg(code),
		}
	}
复制代码

服务层中用户注册的完整代码

func (service *UserRegisterService) Register() serializer.Response {
	var user model.User
	var count int
	code := e.SUCCESS
	model.DB.Model(&model.User{}).Where("user_name=?",service.UserName).Count(&count)
	if count == 1 {
		code = e.ErrorExistUser
		return serializer.Response{
			Status: code,
			Msg:    e.GetMsg(code),
		}
	}
	user = model.User{
		Nickname: service.Nickname,
		UserName: service.UserName,
		Status:   model.Active,
	}
	//加密密码
	if err := user.SetPassword(service.Password); err != nil {
		logging.Info(err)
		code = e.ErrorFailEncryption
		return serializer.Response{
			Status: code,
			Msg:    e.GetMsg(code),
		}
	}
	user.Avatar = "http://q1.qlogo.cn/g?b=qq&nk=294350394&s=640"
	//创建用户
	if err := model.DB.Create(&user).Error; err != nil {
		logging.Info(err)
		code = e.ErrorDatabase
		return serializer.Response{
			Status: code,
			Msg:    e.GetMsg(code),
		}
	}
	return serializer.Response{
		Status: code,
		Msg:    e.GetMsg(code),
	}
}
复制代码

下一章中,我们编写用户登录的业务逻辑。

Guess you like

Origin juejin.im/post/7034051681809596423