天天看點

【Go實戰 | 電商平台】(4) 使用者注冊

文章目錄

1. 編寫路由

2. 注冊路由

3. 注冊接口

3.1 service層

3.2 api層

3.2 serializer

4. 注冊服務

用到的包

github.com/gin-contrib/sessions

github.com/gin-contrib/sessions/cookie

github.com/gin-gonic/gin

建立一個WSGI應用程式執行個體。

r := gin.Default()      

設定全局變量store

store := cookie.NewStore([]byte("something-very-secret"))      

在路由中使用中間件調用store

r.Use(sessions.Sessions("mysession", store))      

分一個基礎路由組

v1 := r.Group("api/v1")      

在這個基礎路由編寫使用者注冊路由

v1 := r.Group("api/v1")
{
    //使用者操作
    v1.POST("user/register", api.UserRegister)
}      

在service先建立一個user.go

【Go實戰 | 電商平台】(4) 使用者注冊

再在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方法

【Go實戰 | 電商平台】(4) 使用者注冊
func (service *UserRegisterService) Register() {

}      

在api層建立user.go

【Go實戰 | 電商平台】(4) 使用者注冊

申請一個 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檔案, 進行錯誤的傳回

【Go實戰 | 電商平台】(4) 使用者注冊
//傳回錯誤資訊 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),
    }
}      

建立一個基礎的序列化傳回結構體

// Response 基礎序列化器
type Response struct {
    Status int         `json:"status"`
    Data   interface{} `json:"data"`
    Msg    string      `json:"msg"`
    Error  string      `json:"error"`
}      
【Go實戰 | 電商平台】(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),
    }
}      

下一章中,我們編寫使用者登入的業務邏輯。