1. form

  1. package forms
  2. type CategoryForm struct {
  3. Name string `form:"name" json:"name" binding:"required,min=3,max=20"`
  4. ParentCategory int32 `form:"parent" json:"parent"`
  5. Level int32 `form:"level" json:"level" binding:"required,oneof=1 2 3"`
  6. IsTab *bool `form:"is_tab" json:"is_tab" binding:"required"`
  7. }
  8. type UpdateCategoryForm struct {
  9. Name string `form:"name" json:"name" binding:"required,min=3,max=20"`
  10. IsTab *bool `form:"is_tab" json:"is_tab"`
  11. }

2. handler

  1. package category
  2. import (
  3. "context"
  4. "encoding/json"
  5. "github.com/gin-gonic/gin"
  6. "github.com/go-playground/validator/v10"
  7. empty "github.com/golang/protobuf/ptypes/empty"
  8. "go.uber.org/zap"
  9. "google.golang.org/grpc/codes"
  10. "google.golang.org/grpc/status"
  11. "mxshop-api/goods-web/forms"
  12. "mxshop-api/goods-web/global"
  13. "mxshop-api/goods-web/proto"
  14. "net/http"
  15. "strconv"
  16. "strings"
  17. )
  18. func removeTopStruct(fileds map[string]string) map[string]string{
  19. rsp := map[string]string{}
  20. for field, err := range fileds {
  21. rsp[field[strings.Index(field, ".")+1:]] = err
  22. }
  23. return rsp
  24. }
  25. func HandleGrpcErrorToHttp(err error, c *gin.Context) {
  26. //将grpc的code转换成http的状态码
  27. if err != nil {
  28. if e, ok := status.FromError(err); ok {
  29. switch e.Code() {
  30. case codes.NotFound:
  31. c.JSON(http.StatusNotFound, gin.H{
  32. "msg": e.Message(),
  33. })
  34. case codes.Internal:
  35. c.JSON(http.StatusInternalServerError, gin.H{
  36. "msg:": "内部错误",
  37. })
  38. case codes.InvalidArgument:
  39. c.JSON(http.StatusBadRequest, gin.H{
  40. "msg": "参数错误",
  41. })
  42. case codes.Unavailable:
  43. c.JSON(http.StatusInternalServerError, gin.H{
  44. "msg": "用户服务不可用",
  45. })
  46. default:
  47. c.JSON(http.StatusInternalServerError, gin.H{
  48. "msg": e.Code(),
  49. })
  50. }
  51. return
  52. }
  53. }
  54. }
  55. func HandleValidatorError(c *gin.Context, err error){
  56. errs, ok := err.(validator.ValidationErrors)
  57. if !ok {
  58. c.JSON(http.StatusOK, gin.H{
  59. "msg":err.Error(),
  60. })
  61. }
  62. c.JSON(http.StatusBadRequest, gin.H{
  63. "error": removeTopStruct(errs.Translate(global.Trans)),
  64. })
  65. return
  66. }
  67. func List(ctx *gin.Context) {
  68. r, err := global.GoodsSrvClient.GetAllCategorysList(context.Background(), &empty.Empty{})
  69. if err != nil {
  70. HandleGrpcErrorToHttp(err, ctx)
  71. return
  72. }
  73. data := make([]interface{}, 0)
  74. err = json.Unmarshal([]byte(r.JsonData), &data)
  75. if err != nil {
  76. zap.S().Errorw("[List] 查询 【分类列表】失败: ", err.Error())
  77. }
  78. ctx.JSON(http.StatusOK, data)
  79. }
  80. func Detail(ctx *gin.Context) {
  81. id := ctx.Param("id")
  82. i, err := strconv.ParseInt(id, 10, 32)
  83. if err != nil {
  84. ctx.Status(http.StatusNotFound)
  85. return
  86. }
  87. reMap := make(map[string]interface{})
  88. subCategorys := make([]interface{}, 0)
  89. if r, err := global.GoodsSrvClient.GetSubCategory(context.Background(), &proto.CategoryListRequest{
  90. Id: int32(i),
  91. });err != nil {
  92. HandleGrpcErrorToHttp(err, ctx)
  93. return
  94. }else{
  95. for _, value := range r.SubCategorys{
  96. subCategorys = append(subCategorys, map[string]interface{}{
  97. "id": value.Id,
  98. "name": value.Name,
  99. "level": value.Level,
  100. "parent_category": value.ParentCategory,
  101. "is_tab": value.IsTab,
  102. })
  103. }
  104. reMap["id"] = r.Info.Id
  105. reMap["name"] = r.Info.Name
  106. reMap["level"] = r.Info.Level
  107. reMap["parent_category"] = r.Info.ParentCategory
  108. reMap["is_tab"] = r.Info.IsTab
  109. reMap["sub_categorys"] = subCategorys
  110. ctx.JSON(http.StatusOK, reMap)
  111. }
  112. return
  113. }
  114. func New(ctx *gin.Context) {
  115. categoryForm := forms.CategoryForm{}
  116. if err := ctx.ShouldBindJSON(&categoryForm); err != nil {
  117. HandleValidatorError(ctx, err)
  118. return
  119. }
  120. rsp, err := global.GoodsSrvClient.CreateCategory(context.Background(), &proto.CategoryInfoRequest{
  121. Name: categoryForm.Name,
  122. IsTab: *categoryForm.IsTab,
  123. Level: categoryForm.Level,
  124. ParentCategory: categoryForm.ParentCategory,
  125. })
  126. if err != nil {
  127. HandleGrpcErrorToHttp(err, ctx)
  128. return
  129. }
  130. request := make(map[string]interface{})
  131. request["id"] = rsp.Id
  132. request["name"] = rsp.Name
  133. request["parent"] = rsp.ParentCategory
  134. request["level"] = rsp.Level
  135. request["is_tab"] = rsp.IsTab
  136. ctx.JSON(http.StatusOK, request)
  137. }
  138. func Delete(ctx *gin.Context) {
  139. id := ctx.Param("id")
  140. i, err := strconv.ParseInt(id, 10, 32)
  141. if err != nil {
  142. ctx.Status(http.StatusNotFound)
  143. return
  144. }
  145. _, err = global.GoodsSrvClient.DeleteCategory(context.Background(), &proto.DeleteCategoryRequest{Id: int32(i)})
  146. if err != nil {
  147. HandleGrpcErrorToHttp(err, ctx)
  148. return
  149. }
  150. ctx.Status(http.StatusOK)
  151. }
  152. func Update(ctx *gin.Context) {
  153. categoryForm := forms.UpdateCategoryForm{}
  154. if err := ctx.ShouldBindJSON(&categoryForm); err != nil {
  155. HandleValidatorError(ctx, err)
  156. return
  157. }
  158. id := ctx.Param("id")
  159. i, err := strconv.ParseInt(id, 10, 32)
  160. if err != nil {
  161. ctx.Status(http.StatusNotFound)
  162. return
  163. }
  164. request := &proto.CategoryInfoRequest{
  165. Id: int32(i),
  166. Name: categoryForm.Name,
  167. }
  168. if categoryForm.IsTab != nil {
  169. request.IsTab = *categoryForm.IsTab
  170. }
  171. _, err = global.GoodsSrvClient.UpdateCategory(context.Background(), request)
  172. if err != nil {
  173. HandleGrpcErrorToHttp(err, ctx)
  174. return
  175. }
  176. ctx.Status(http.StatusOK)
  177. }

3. router

  1. package router
  2. import (
  3. "github.com/gin-gonic/gin"
  4. "mxshop-api/goods-web/api/category"
  5. )
  6. func InitCategoryRouter(Router *gin.RouterGroup) {
  7. CategoryRouter := Router.Group("categorys")
  8. {
  9. CategoryRouter.GET("", category.List) // 商品类别列表页
  10. CategoryRouter.DELETE("/:id", category.Delete) // 删除分类
  11. CategoryRouter.GET("/:id", category.Detail) // 获取分类详情
  12. CategoryRouter.POST("", category.New) //新建分类
  13. CategoryRouter.PUT("/:id", category.Update) //修改分类信息
  14. }
  15. }

4. 将router调用