商品微服务(goods_srv)

四.商品微服务goods_srv

1.1定义表结构
//轮播图
CREATE TABLE `banner` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `add_time` datetime NOT NULL,
 `is_deleted` tinyint(1) DEFAULT NULL,
 `update_time` datetime NOT NULL,
 `image` varchar(200) NOT NULL,
 `url` varchar(200) NOT NULL,
 `index` int(11) NOT NULL,
 PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC

//品牌表
CREATE TABLE `brands` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `name` varchar(50) NOT NULL,
 `logo` varchar(200) DEFAULT NULL,
 `add_time` datetime NOT NULL,
 `is_deleted` tinyint(1) DEFAULT NULL,
 `update_time` datetime NOT NULL,
 PRIMARY KEY (`id`) USING BTREE,
 UNIQUE KEY `brands_name` (`name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1111 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC

//商品分类表
CREATE TABLE `category` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `name` varchar(50) NOT NULL,
 `parent_category_id` int(11) DEFAULT NULL,
 `level` int(11) NOT NULL,
 `is_tab` tinyint(1) NOT NULL,
 `url` varchar(300) NOT NULL,
 `add_time` datetime DEFAULT NULL,
 `is_deleted` tinyint(255) DEFAULT NULL,
 `update_time` datetime DEFAULT NULL,
 PRIMARY KEY (`id`) USING BTREE,
 KEY `category_name` (`name`) USING BTREE,
 KEY `category_parent_category_id` (`parent_category_id`) USING BTREE,
 KEY `category_url` (`url`) USING BTREE,
 CONSTRAINT `category_ibfk_1` FOREIGN KEY (`parent_category_id`) REFERENCES `category` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=238010 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC

//商品表
CREATE TABLE `goods` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `add_time` datetime NOT NULL,
 `is_deleted` tinyint(1) DEFAULT NULL,
 `update_time` datetime NOT NULL,
 `category_id` int(11) NOT NULL,
 `brand_id` int(11) NOT NULL,
 `on_sale` tinyint(1) NOT NULL,
 `goods_sn` varchar(50) NOT NULL,
 `name` varchar(100) NOT NULL,
 `click_num` int(11) NOT NULL,
 `sold_num` int(11) NOT NULL,
 `fav_num` int(11) NOT NULL,
 `stocks` int(11) NOT NULL,
 `market_price` float NOT NULL,
 `shop_price` float NOT NULL,
 `goods_brief` varchar(200) NOT NULL,
 `ship_free` tinyint(1) NOT NULL,
 `images` json NOT NULL,
 `desc_images` json NOT NULL,
 `goods_front_image` varchar(200) NOT NULL,
 `is_new` tinyint(1) NOT NULL,
 `is_hot` tinyint(1) NOT NULL,
 PRIMARY KEY (`id`) USING BTREE,
 KEY `goods2_category_id` (`category_id`) USING BTREE,
 KEY `goods2_brand_id` (`brand_id`) USING BTREE,
 CONSTRAINT `goods_ibfk_1` FOREIGN KEY (`category_id`) REFERENCES `category` (`id`) ON DELETE CASCADE,
 CONSTRAINT `goods_ibfk_2` FOREIGN KEY (`brand_id`) REFERENCES `brands` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=841 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC

//商品分类关联表
CREATE TABLE `goodscategorybrand` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `category_id` int(11) NOT NULL,
 `brand_id` int(11) NOT NULL,
 `add_time` datetime NOT NULL,
 `is_deleted` tinyint(1) DEFAULT NULL,
 `update_time` datetime NOT NULL,
 PRIMARY KEY (`id`) USING BTREE,
 UNIQUE KEY `goodscategorybrand_category_id_brand_id` (`category_id`,`brand_id`) USING BTREE,
 KEY `goodscategorybrand_category_id` (`category_id`) USING BTREE,
 KEY `goodscategorybrand_brand_id` (`brand_id`) USING BTREE,
 CONSTRAINT `goodscategorybrand_ibfk_1` FOREIGN KEY (`category_id`) REFERENCES `category` (`id`),
 CONSTRAINT `goodscategorybrand_ibfk_2` FOREIGN KEY (`brand_id`) REFERENCES `brands` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=25799 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC
1.2定义模型

在goods_srv/model建立base.go,goods.go文件

base.go

package model

import (
	"database/sql/driver"
	"encoding/json"
	"gorm.io/gorm"
	"time"
)

type GormList []string

func (g GormList) Value() (driver.Value, error){
	return json.Marshal(g)
}

// 实现 sql.Scanner 接口,Scan 将 value 扫描至 Jsonb
func (g *GormList) Scan(value interface{}) error {
	return json.Unmarshal(value.([]byte), &g)
}

type BaseModel struct {
	ID int32 `gorm:"primarykey;type:int" json:"id"` //为什么使用int32, bigint
	CreatedAt time.Time `gorm:"column:add_time" json:"-"`
	UpdatedAt time.Time `gorm:"column:update_time" json:"-"`
	DeletedAt gorm.DeletedAt `json:"-"`
	IsDeleted bool `json:"-"`
}

goods.go

package model

import (
	"context"
	"strconv"

	"gorm.io/gorm"

	"mxshop_srvs/goods_srv/global"

)

//类型, 这个字段是否能为null, 这个字段应该设置为可以为null还是设置为空, 0
//实际开发过程中 尽量设置为不为null
//https://zhuanlan.zhihu.com/p/73997266
//这些类型我们使用int32还是int
type Category struct{
	BaseModel
	Name  string `gorm:"type:varchar(20);not null" json:"name"`
	ParentCategoryID int32 `json:"parent"`
	ParentCategory *Category `json:"-"`
	SubCategory []*Category `gorm:"foreignKey:ParentCategoryID;references:ID" json:"sub_category"`
	Level int32 `gorm:"type:int;not null;default:1" json:"level"`
	IsTab bool `gorm:"default:false;not null" json:"is_tab"`
}


type Brands struct {
	BaseModel
	Name  string `gorm:"type:varchar(20);not null"`
	Logo  string `gorm:"type:varchar(200);default:'';not null"`
}

type GoodsCategoryBrand struct {
	BaseModel
	CategoryID int32 `gorm:"type:int;index:idx_category_brand,unique"`
	Category Category

	BrandsID int32 `gorm:"type:int;index:idx_category_brand,unique"`
	Brands Brands
}

func (GoodsCategoryBrand) TableName() string{
	return "goodscategorybrand"
}

type Banner struct {
	BaseModel
	Image string `gorm:"type:varchar(200);not null"`
	Url string `gorm:"type:varchar(200);not null"`
	Index int32 `gorm:"type:int;default:1;not null"`
}

type Goods struct {
	BaseModel

	CategoryID int32 `gorm:"type:int;not null"`
	Category Category
	BrandsID int32 `gorm:"type:int;not null"`
	Brands Brands

	OnSale bool `gorm:"default:false;not null"`
	ShipFree bool `gorm:"default:false;not null"`
	IsNew bool `gorm:"default:false;not null"`
	IsHot bool `gorm:"default:false;not null"`

	Name  string `gorm:"type:varchar(50);not null"`
	GoodsSn string `gorm:"type:varchar(50);not null"`
	ClickNum int32 `gorm:"type:int;default:0;not null"`
	SoldNum int32 `gorm:"type:int;default:0;not null"`
	FavNum int32 `gorm:"type:int;default:0;not null"`
	MarketPrice float32 `gorm:"not null"`
	ShopPrice float32 `gorm:"not null"`
	GoodsBrief string `gorm:"type:varchar(100);not null"`
	Images GormList `gorm:"type:varchar(1000);not null"`
	DescImages GormList `gorm:"type:varchar(100
0);not null"`
	GoodsFrontImage string `gorm:"type:varchar(200);not null"`
}
1.3接口开发
1.3.1品牌列表
func (s *GoodsServer) BrandList(ctx context.Context, req *proto.BrandFilterRequest) (*proto.BrandListResponse, error) {
   brandListResponse := proto.BrandListResponse{}

   var brands []model.Brands
   result := global.DB.Scopes(Paginate(int(req.Pages), int(req.PagePerNums))).Find(&brands)
   if result.Error != nil {
      return nil, result.Error
   }
   var total int64
   global.DB.Model(&model.Brands{}).Count(&total)
   brandListResponse.Total = int32(total)

   var brandResponses []*proto.BrandInfoResponse
   for _, brand := range brands {
      brandResponses = append(brandResponses, &proto.BrandInfoResponse{
         Id:   brand.ID,
         Name: brand.Name,
         Logo: brand.Logo,
      })
   }
   brandListResponse.Data = brandResponses
   return &brandListResponse, nil
}
1.3.2品牌新建,删除、更新
func (s *GoodsServer) CreateBrand(ctx context.Context, req *proto.BrandRequest) (*proto.BrandInfoResponse, error) {
   //新建品牌
   if result := global.DB.Where("name=?", req.Name).First(&model.Brands{}); result.RowsAffected == 1 {
      return nil, status.Errorf(codes.InvalidArgument, "品牌已存在")
   }
   brand := &model.Brands{
      Name: req.Name,
      Logo: req.Logo,
   }
   global.DB.Save(brand)
   return &proto.BrandInfoResponse{Id: brand.ID}, nil
}
func (s *GoodsServer) DeleteBrand(ctx context.Context, req *proto.BrandRequest) (*emptypb.Empty, error) {
   if result := global.DB.Delete(&model.Brands{}, req.Id); result.RowsAffected == 0 {
      return nil, status.Errorf(codes.NotFound, "品牌不存在")
   }
   return &emptypb.Empty{}, nil
}
func (s *GoodsServer) UpdateBrand(ctx context.Context, req *proto.BrandRequest) (*emptypb.Empty, error){
   brands := model.Brands{}
   if result := global.DB.First(&brands); result.RowsAffected == 0 {
      return nil, status.Errorf(codes.InvalidArgument, "品牌不存在")
   }

   if req.Name != "" {
      brands.Name = req.Name
   }
   if req.Logo != "" {
      brands.Logo = req.Logo
   }

   global.DB.Save(&brands)

   return &emptypb.Empty{}, nil
}
1.3.3轮播图的查询、新增、删除和修改
package handler

import (
   "context"
   "google.golang.org/grpc/codes"
   "google.golang.org/grpc/status"
   "google.golang.org/protobuf/types/known/emptypb"
   "mxshop_srvs/goods_srv/model"
   "mxshop_srvs/goods_srv/proto"
   "mxshop_srvs/user_srv/global"
)

func (s *GoodsServer) BannerList(ctx context.Context, req *emptypb.Empty) (*proto.BannerListResponse, error) {
   bannerListResponse := proto.BannerListResponse{}
   var banners []model.Banner
   result := global.DB.Find(&banners)
   bannerListResponse.Total = int32(result.RowsAffected)
   var bannerResponses []*proto.BannerResponse
   for _, banner := range banners {
      bannerResponses = append(bannerResponses, &proto.BannerResponse{
         Id:    banner.ID,
         Image: banner.Image,
         Index: banner.Index,
         Url:   banner.Url,
      })
   }
   bannerListResponse.Data = bannerResponses
   return &bannerListResponse, nil
}

func (s *GoodsServer) CreateBanner(ctx context.Context, req *proto.BannerRequest) (*proto.BannerResponse, error) {
   banner := model.Banner{}

   banner.Image = req.Image
   banner.Index = req.Index
   banner.Url = req.Url

   global.DB.Save(&banner)

   return &proto.BannerResponse{Id: banner.ID}, nil
}

func (s *GoodsServer) DeleteBanner(ctx context.Context, req *proto.BannerRequest) (*emptypb.Empty, error) {
   if result := global.DB.Delete(&model.Banner{}, req.Id); result.RowsAffected == 0 {
      return nil, status.Errorf(codes.NotFound, "轮播图不存在")
   }
   return &emptypb.Empty{}, nil
}

func (s *GoodsServer) UpdateBanner(ctx context.Context, req *proto.BannerRequest) (*emptypb.Empty, error) {
   var banner model.Banner

   if result := global.DB.First(&banner, req.Id); result.RowsAffected == 0 {
      return nil, status.Errorf(codes.NotFound, "轮播图不存在")
   }

   if req.Url != "" {
      banner.Url = req.Url
   }
   if req.Image != "" {
      banner.Image = req.Image
   }
   if req.Index != 0 {
      banner.Index = req.Index
   }

   global.DB.Save(&banner)

   return &emptypb.Empty{}, nil
}
1.3.4商品分类的列表接口
func (s *GoodsServer) GetAllCategorysList(context.Context, *emptypb.Empty) (*proto.CategoryListResponse, error) {
   var categorys []model.Category
   global.DB.Where(&model.Category{Level: 1}).Preload("SubCategory.SubCategory").Find(&categorys)
   b, _ := json.Marshal(&categorys)
   return &proto.CategoryListResponse{JsonData: string(b)}, nil
}
1.3.5获取商品分类的子分类
// GetSubCategory 商品子分类
func (s *GoodsServer) GetSubCategory(ctx context.Context, req *proto.CategoryListRequest) (*proto.SubCategoryListResponse, error) {
   categoryListResponse := proto.SubCategoryListResponse{}
   var category model.Category

   if result := global.DB.First(&category, req.Id); result.RowsAffected == 0 {
      return nil, status.Errorf(codes.NotFound, "商品分类不存在")
   }
   categoryListResponse.Info = &proto.CategoryInfoResponse{
      Id:             category.ID,
      Name:           category.Name,
      Level:          category.Level,
      IsTab:          category.IsTab,
      ParentCategory: category.ParentCategoryID,
   }

   var subCategorys []model.Category
   var subCategoryResponse []*proto.CategoryInfoResponse
   global.DB.Where(&model.Category{ParentCategoryID: req.Id}).Find(&subCategorys)
   for _, subCategory := range subCategorys {
      subCategoryResponse = append(subCategoryResponse, &proto.CategoryInfoResponse{
         Id:             subCategory.ID,
         Name:           subCategory.Name,
         Level:          subCategory.Level,
         IsTab:          subCategory.IsTab,
         ParentCategory: subCategory.ParentCategoryID,
      })
   }
   categoryListResponse.SubCategorys = subCategoryResponse
   return &categoryListResponse, nil
}
1.3.6商品分类的新建,删除和更新接口
func (s *GoodsServer) CreateCategory(ctx context.Context, req *proto.CategoryInfoRequest) (*proto.CategoryInfoResponse, error) {
   category := model.Category{}
   cMap := map[string]interface{}{}
   cMap["name"] = req.Name
   cMap["level"] = req.Level
   cMap["is_tab"] = req.IsTab
   if req.Level != 1 {
      //去查询父类目是否存在
      cMap["parent_category_id"] = req.ParentCategory
   }
   tx := global.DB.Model(&model.Category{}).Create(cMap)
   fmt.Println(tx)
   return &proto.CategoryInfoResponse{Id:int32(category.ID)}, nil
}

func (s *GoodsServer) DeleteCategory(ctx context.Context, req *proto.DeleteCategoryRequest) (*emptypb.Empty, error) {
   if result := global.DB.Delete(&model.Category{}, req.Id); result.RowsAffected == 0 {
      return nil, status.Errorf(codes.NotFound, "商品分类不存在")
   }
   return &emptypb.Empty{}, nil
}

func (s *GoodsServer) UpdateCategory(ctx context.Context, req *proto.CategoryInfoRequest) (*emptypb.Empty, error) {
   var category model.Category

   if result := global.DB.First(&category, req.Id); result.RowsAffected == 0 {
      return nil, status.Errorf(codes.NotFound, "商品分类不存在")
   }

   if req.Name != "" {
      category.Name = req.Name
   }
   if req.ParentCategory != 0 {
      category.ParentCategoryID = req.ParentCategory
   }
   if req.Level != 0 {
      category.Level = req.Level
   }
   if req.IsTab {
      category.IsTab = req.IsTab
   }

   global.DB.Save(&category)

   return &emptypb.Empty{}, nil
}
1.3.7品牌分类相关接口
func (s *GoodsServer) CategoryBrandList(ctx context.Context, req *proto.CategoryBrandFilterRequest) (*proto.CategoryBrandListResponse, error) {
	var categoryBrands []model.GoodsCategoryBrand
	categoryBrandListResponse := proto.CategoryBrandListResponse{}

	var total int64
	global.DB.Model(&model.GoodsCategoryBrand{}).Count(&total)
	categoryBrandListResponse.Total = int32(total)

	var categoryResponses []*proto.CategoryBrandResponse
	for _, categoryBrand := range categoryBrands {
		categoryResponses = append(categoryResponses, &proto.CategoryBrandResponse{
			Category: &proto.CategoryInfoResponse{
				Id:             categoryBrand.Category.ID,
				Name:           categoryBrand.Category.Name,
				Level:          categoryBrand.Category.Level,
				IsTab:          categoryBrand.Category.IsTab,
				ParentCategory: categoryBrand.Category.ParentCategoryID,
			},
			Brand: &proto.BrandInfoResponse{
				Id:   categoryBrand.Brands.ID,
				Name: categoryBrand.Brands.Name,
				Logo: categoryBrand.Brands.Logo,
			},
		})
	}
	categoryBrandListResponse.Data = categoryResponses
	return &categoryBrandListResponse, nil
}
func (s *GoodsServer) GetCategoryBrandList(ctx context.Context, req *proto.CategoryInfoRequest) (*proto.BrandListResponse, error) {
	brandListResponse := proto.BrandListResponse{}

	var category model.Category
	if result := global.DB.Find(&category, req.Id).First(&category); result.RowsAffected == 0 {
		return nil, status.Errorf(codes.InvalidArgument, "商品分类不存在")
	}

	var categoryBrands []model.GoodsCategoryBrand
	if result := global.DB.Preload("Brands").Where(&model.GoodsCategoryBrand{CategoryID: req.Id}).Find(&categoryBrands); result.RowsAffected > 0 {
		brandListResponse.Total = int32(result.RowsAffected)
	}

	var brandInfoResponses []*proto.BrandInfoResponse
	for _, categoryBrand := range categoryBrands {
		brandInfoResponses = append(brandInfoResponses, &proto.BrandInfoResponse{
			Id:   categoryBrand.Brands.ID,
			Name: categoryBrand.Brands.Name,
			Logo: categoryBrand.Brands.Logo,
		})
	}

	brandListResponse.Data = brandInfoResponses

	return &brandListResponse, nil
}

func (s *GoodsServer) CreateCategoryBrand(ctx context.Context, req *proto.CategoryBrandRequest) (*proto.CategoryBrandResponse, error) {
	var category model.Category
	if result := global.DB.First(&category, req.CategoryId); result.RowsAffected == 0 {
		return nil, status.Errorf(codes.InvalidArgument, "商品分类不存在")
	}

	var brand model.Brands
	if result := global.DB.First(&brand, req.BrandId); result.RowsAffected == 0 {
		return nil, status.Errorf(codes.InvalidArgument, "品牌不存在")
	}

	categoryBrand := model.GoodsCategoryBrand{
		CategoryID: req.CategoryId,
		BrandsID:   req.BrandId,
	}

	global.DB.Save(&categoryBrand)
	return &proto.CategoryBrandResponse{Id: categoryBrand.ID}, nil
}
func (s *GoodsServer) DeleteCategoryBrand(ctx context.Context, req *proto.CategoryBrandRequest) (*emptypb.Empty, error) {
	if result := global.DB.Delete(&model.GoodsCategoryBrand{}, req.Id); result.RowsAffected == 0 {
		return nil, status.Errorf(codes.NotFound, "品牌分类不存在")
	}
	return &emptypb.Empty{}, nil
}
func (s *GoodsServer) UpdateCategoryBrand(ctx context.Context, req *proto.CategoryBrandRequest) (*emptypb.Empty, error) {
	var categoryBrand model.GoodsCategoryBrand

	if result := global.DB.First(&categoryBrand, req.Id); result.RowsAffected == 0 {
		return nil, status.Errorf(codes.InvalidArgument, "品牌分类不存在")
	}

	var category model.Category
	if result := global.DB.First(&category, req.CategoryId); result.RowsAffected == 0 {
		return nil, status.Errorf(codes.InvalidArgument, "商品分类不存在")
	}

	var brand model.Brands
	if result := global.DB.First(&brand, req.BrandId); result.RowsAffected == 0 {
		return nil, status.Errorf(codes.InvalidArgument, "品牌不存在")
	}

	categoryBrand.CategoryID = req.CategoryId
	categoryBrand.BrandsID = req.BrandId

	global.DB.Save(&categoryBrand)

	return &emptypb.Empty{}, nil
}
1.3.8商品列表页接口
package handler

import (
   "context"
   "fmt"
   "google.golang.org/grpc/codes"
   "google.golang.org/grpc/status"
   "mxshop_srvs/goods_srv/global"
   "mxshop_srvs/goods_srv/model"
   "mxshop_srvs/goods_srv/proto"
)

type GoodsServer struct {
   proto.UnimplementedGoodsServer
}

func ModelToResponse(goods model.Goods) proto.GoodsInfoResponse {
   return proto.GoodsInfoResponse{
      Id:              goods.ID,
      CategoryId:      goods.CategoryID,
      Name:            goods.Name,
      GoodsSn:         goods.GoodsSn,
      ClickNum:        goods.ClickNum,
      SoldNum:         goods.SoldNum,
      FavNum:          goods.FavNum,
      MarketPrice:     goods.MarketPrice,
      ShopPrice:       goods.ShopPrice,
      GoodsBrief:      goods.GoodsBrief,
      ShipFree:        goods.ShipFree,
      GoodsFrontImage: goods.GoodsFrontImage,
      IsNew:           goods.IsNew,
      IsHot:           goods.IsHot,
      OnSale:          goods.OnSale,
      DescImages:      goods.DescImages,
      Images:          goods.Images,
      Category: &proto.CategoryBriefInfoResponse{
         Id:   goods.Category.ID,
         Name: goods.Category.Name,
      },
      Brand: &proto.BrandInfoResponse{
         Id:   goods.Brands.ID,
         Name: goods.Brands.Name,
         Logo: goods.Brands.Logo,
      },
   }
}
func (s *GoodsServer) GoodsList(ctx context.Context, req *proto.GoodsFilterRequest) (*proto.GoodsListResponse, error) {
   //关键词搜索、查询新品、查询热门商品、通过价格区间筛选, 通过商品分类筛选
   goodsListResponse := &proto.GoodsListResponse{}

   var goods []model.Goods
   localDB := global.DB.Model(&model.Goods{})
   if req.KeyWords != "" {
      //搜索
      localDB = localDB.Where("name LIKE ?", "%"+req.KeyWords+"%")
   }
   if req.IsHot {
      localDB = localDB.Where(model.Goods{IsHot: true})
   }
   if req.IsNew {
      localDB = localDB.Where(model.Goods{IsNew: true})
   }
   if req.PriceMin > 0 {
      localDB = localDB.Where("shop_price>=?", req.PriceMin)
   }
   if req.PriceMax > 0 {
      localDB = localDB.Where("shop_price<=?", req.PriceMin)
   }
   if req.Brand > 0 {
      localDB = localDB.Where("brand_id=?", req.Brand)
   }

   //通过category去查询商品
   var subQuery string
   if req.TopCategory > 0 {
      var category model.Category
      if result := global.DB.First(&category, req.TopCategory); result.RowsAffected == 0 {
         return nil, status.Errorf(codes.NotFound, "商品分类不存在")
      }
      if category.Level == 1 {
         subQuery = fmt.Sprintf("select id from category where parent_category_id in (select id from category WHERE parent_category_id=%d)", req.TopCategory)
      } else if category.Level == 2 {
         subQuery = fmt.Sprintf("select id from category WHERE parent_category_id=%d", req.TopCategory)
      } else if category.Level == 3 {
         subQuery = fmt.Sprintf("select id from category WHERE id=%d", req.TopCategory)
      }
      localDB = localDB.Where(fmt.Sprintf("category_id in (%s)", subQuery))

   }
   var count int64
   localDB.Count(&count)
   goodsListResponse.Total = int32(count)

   result := localDB.Preload("Category").Preload("Brands").Scopes(Paginate(int(req.Pages), int(req.PagePerNums))).Find(&goods)
   if result.Error != nil {
      return nil, result.Error
   }
   for _, good := range goods {
      goodsInfoResponse := ModelToResponse(good)
      goodsListResponse.Data = append(goodsListResponse.Data, &goodsInfoResponse)
   }
   return goodsListResponse, nil
}
1.3.9批量获取商品信息、商品详情接口
// BatchGetGoods 现在用户提交订单有多个商品,你得批量查询商品的信息吧
func (s *GoodsServer) BatchGetGoods(ctx context.Context, req *proto.BatchGoodsIdInfo) (*proto.GoodsListResponse, error) {
   goodsListResponse := &proto.GoodsListResponse{}
   var goods []model.Goods
   //调用where并不会真正执行sql 只是用来生成sql的 当调用find, first才会去执行sql,
   result := global.DB.Where(req.Id).Find(&goods)
   for _, good := range goods {
      goodsInfoResponse := ModelToResponse(good)
      goodsListResponse.Data = append(goodsListResponse.Data, &goodsInfoResponse)
   }
   goodsListResponse.Total = int32(result.RowsAffected)
   return goodsListResponse, nil
}
func (s *GoodsServer) GetGoodsDetail(ctx context.Context, req *proto.GoodInfoRequest) (*proto.GoodsInfoResponse, error) {
   var goods model.Goods

   if result := global.DB.Preload("Category").Preload("Brands").First(&goods, req.Id); result.RowsAffected == 0 {
      return nil, status.Errorf(codes.NotFound, "商品不存在")
   }
   goodsInfoResponse := ModelToResponse(goods)
   return &goodsInfoResponse, nil
}
1.3.10新增、修改和删除商品接口
func (s *GoodsServer) CreateGoods(ctx context.Context, req *proto.CreateGoodsInfo) (*proto.GoodsInfoResponse, error) {
   var category model.Category
   if result := global.DB.First(&category, req.CategoryId); result.RowsAffected == 0 {
      return nil, status.Errorf(codes.InvalidArgument, "商品分类不存在")
   }
   var brand model.Brands
   if result := global.DB.First(&brand, req.BrandId); result.RowsAffected == 0 {
      return nil, status.Errorf(codes.InvalidArgument, "品牌不存在")
   }
   //先检查redis中是否有这个token
   //防止同一个token的数据重复插入到数据库中,如果redis中没有这个token则放入redis
   //这里没有看到图片文件是如何上传, 在微服务中 普通的文件上传已经不再使用
   goods := model.Goods{
      Brands:          brand,
      BrandsID:        brand.ID,
      Category:        category,
      CategoryID:      category.ID,
      Name:            req.Name,
      GoodsSn:         req.GoodsSn,
      MarketPrice:     req.MarketPrice,
      ShopPrice:       req.ShopPrice,
      GoodsBrief:      req.GoodsBrief,
      ShipFree:        req.ShipFree,
      Images:          req.Images,
      DescImages:      req.DescImages,
      GoodsFrontImage: req.GoodsFrontImage,
      IsNew:           req.IsNew,
      IsHot:           req.IsHot,
      OnSale:          req.OnSale,
   }

   //srv之间互相调用了
   tx := global.DB.Begin()
   result := tx.Save(&goods)
   if result.Error != nil {
      tx.Rollback()
      return nil, result.Error
   }
   tx.Commit()
   return &proto.GoodsInfoResponse{
      Id: goods.ID,
   }, nil
}
func (s *GoodsServer) DeleteGoods(ctx context.Context, req *proto.DeleteGoodsInfo) (*emptypb.Empty, error) {
   if result := global.DB.Delete(&model.Goods{BaseModel:model.BaseModel{ID:req.Id}}, req.Id); result.Error != nil {
      return nil, status.Errorf(codes.NotFound, "商品不存在")
   }
   return &emptypb.Empty{}, nil
}

func (s *GoodsServer) UpdateGoods(ctx context.Context, req *proto.CreateGoodsInfo) (*emptypb.Empty, error){
   var goods model.Goods

   if result := global.DB.First(&goods, req.Id); result.RowsAffected == 0 {
      return nil, status.Errorf(codes.NotFound, "商品不存在")
   }

   var category model.Category
   if result := global.DB.First(&category, req.CategoryId); result.RowsAffected == 0 {
      return nil, status.Errorf(codes.InvalidArgument, "商品分类不存在")
   }

   var brand model.Brands
   if result := global.DB.First(&brand, req.BrandId); result.RowsAffected == 0 {
      return nil, status.Errorf(codes.InvalidArgument, "品牌不存在")
   }

   goods.Brands = brand
   goods.BrandsID = brand.ID
   goods.Category = category
   goods.CategoryID = category.ID
   goods.Name = req.Name
   goods.GoodsSn = req.GoodsSn
   goods.MarketPrice= req.MarketPrice
   goods.ShopPrice= req.ShopPrice
   goods.GoodsBrief= req.GoodsBrief
   goods.ShipFree= req.ShipFree
   goods.Images= req.Images
   goods.DescImages= req.DescImages
   goods.GoodsFrontImage= req.GoodsFrontImage
   goods.IsNew= req.IsNew
   goods.IsHot= req.IsHot
   goods.OnSale= req.OnSale

   tx := global.DB.Begin()
   result := tx.Save(&goods)
   if result.Error != nil {
      tx.Rollback()
      return nil, result.Error
   }
   tx.Commit()
   return &emptypb.Empty{}, nil
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值