1. form
package forms
type CategoryForm struct {
Name string `form:"name" json:"name" binding:"required,min=3,max=20"`
ParentCategory int32 `form:"parent" json:"parent"`
Level int32 `form:"level" json:"level" binding:"required,oneof=1 2 3"`
IsTab *bool `form:"is_tab" json:"is_tab" binding:"required"`
}
type UpdateCategoryForm struct {
Name string `form:"name" json:"name" binding:"required,min=3,max=20"`
IsTab *bool `form:"is_tab" json:"is_tab"`
}
2. handler
package category
import (
"context"
"encoding/json"
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
empty "github.com/golang/protobuf/ptypes/empty"
"go.uber.org/zap"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"mxshop-api/goods-web/forms"
"mxshop-api/goods-web/global"
"mxshop-api/goods-web/proto"
"net/http"
"strconv"
"strings"
)
func removeTopStruct(fileds map[string]string) map[string]string{
rsp := map[string]string{}
for field, err := range fileds {
rsp[field[strings.Index(field, ".")+1:]] = err
}
return rsp
}
func HandleGrpcErrorToHttp(err error, c *gin.Context) {
//将grpc的code转换成http的状态码
if err != nil {
if e, ok := status.FromError(err); ok {
switch e.Code() {
case codes.NotFound:
c.JSON(http.StatusNotFound, gin.H{
"msg": e.Message(),
})
case codes.Internal:
c.JSON(http.StatusInternalServerError, gin.H{
"msg:": "内部错误",
})
case codes.InvalidArgument:
c.JSON(http.StatusBadRequest, gin.H{
"msg": "参数错误",
})
case codes.Unavailable:
c.JSON(http.StatusInternalServerError, gin.H{
"msg": "用户服务不可用",
})
default:
c.JSON(http.StatusInternalServerError, gin.H{
"msg": e.Code(),
})
}
return
}
}
}
func HandleValidatorError(c *gin.Context, err error){
errs, ok := err.(validator.ValidationErrors)
if !ok {
c.JSON(http.StatusOK, gin.H{
"msg":err.Error(),
})
}
c.JSON(http.StatusBadRequest, gin.H{
"error": removeTopStruct(errs.Translate(global.Trans)),
})
return
}
func List(ctx *gin.Context) {
r, err := global.GoodsSrvClient.GetAllCategorysList(context.Background(), &empty.Empty{})
if err != nil {
HandleGrpcErrorToHttp(err, ctx)
return
}
data := make([]interface{}, 0)
err = json.Unmarshal([]byte(r.JsonData), &data)
if err != nil {
zap.S().Errorw("[List] 查询 【分类列表】失败: ", err.Error())
}
ctx.JSON(http.StatusOK, data)
}
func Detail(ctx *gin.Context) {
id := ctx.Param("id")
i, err := strconv.ParseInt(id, 10, 32)
if err != nil {
ctx.Status(http.StatusNotFound)
return
}
reMap := make(map[string]interface{})
subCategorys := make([]interface{}, 0)
if r, err := global.GoodsSrvClient.GetSubCategory(context.Background(), &proto.CategoryListRequest{
Id: int32(i),
});err != nil {
HandleGrpcErrorToHttp(err, ctx)
return
}else{
for _, value := range r.SubCategorys{
subCategorys = append(subCategorys, map[string]interface{}{
"id": value.Id,
"name": value.Name,
"level": value.Level,
"parent_category": value.ParentCategory,
"is_tab": value.IsTab,
})
}
reMap["id"] = r.Info.Id
reMap["name"] = r.Info.Name
reMap["level"] = r.Info.Level
reMap["parent_category"] = r.Info.ParentCategory
reMap["is_tab"] = r.Info.IsTab
reMap["sub_categorys"] = subCategorys
ctx.JSON(http.StatusOK, reMap)
}
return
}
func New(ctx *gin.Context) {
categoryForm := forms.CategoryForm{}
if err := ctx.ShouldBindJSON(&categoryForm); err != nil {
HandleValidatorError(ctx, err)
return
}
rsp, err := global.GoodsSrvClient.CreateCategory(context.Background(), &proto.CategoryInfoRequest{
Name: categoryForm.Name,
IsTab: *categoryForm.IsTab,
Level: categoryForm.Level,
ParentCategory: categoryForm.ParentCategory,
})
if err != nil {
HandleGrpcErrorToHttp(err, ctx)
return
}
request := make(map[string]interface{})
request["id"] = rsp.Id
request["name"] = rsp.Name
request["parent"] = rsp.ParentCategory
request["level"] = rsp.Level
request["is_tab"] = rsp.IsTab
ctx.JSON(http.StatusOK, request)
}
func Delete(ctx *gin.Context) {
id := ctx.Param("id")
i, err := strconv.ParseInt(id, 10, 32)
if err != nil {
ctx.Status(http.StatusNotFound)
return
}
_, err = global.GoodsSrvClient.DeleteCategory(context.Background(), &proto.DeleteCategoryRequest{Id: int32(i)})
if err != nil {
HandleGrpcErrorToHttp(err, ctx)
return
}
ctx.Status(http.StatusOK)
}
func Update(ctx *gin.Context) {
categoryForm := forms.UpdateCategoryForm{}
if err := ctx.ShouldBindJSON(&categoryForm); err != nil {
HandleValidatorError(ctx, err)
return
}
id := ctx.Param("id")
i, err := strconv.ParseInt(id, 10, 32)
if err != nil {
ctx.Status(http.StatusNotFound)
return
}
request := &proto.CategoryInfoRequest{
Id: int32(i),
Name: categoryForm.Name,
}
if categoryForm.IsTab != nil {
request.IsTab = *categoryForm.IsTab
}
_, err = global.GoodsSrvClient.UpdateCategory(context.Background(), request)
if err != nil {
HandleGrpcErrorToHttp(err, ctx)
return
}
ctx.Status(http.StatusOK)
}
3. router
package router
import (
"github.com/gin-gonic/gin"
"mxshop-api/goods-web/api/category"
)
func InitCategoryRouter(Router *gin.RouterGroup) {
CategoryRouter := Router.Group("categorys")
{
CategoryRouter.GET("", category.List) // 商品类别列表页
CategoryRouter.DELETE("/:id", category.Delete) // 删除分类
CategoryRouter.GET("/:id", category.Detail) // 获取分类详情
CategoryRouter.POST("", category.New) //新建分类
CategoryRouter.PUT("/:id", category.Update) //修改分类信息
}
}
4. 将router调用