master
shenzhuan 2 years ago
parent c73d64a442
commit 5721f0619d

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/product-service.iml" filepath="$PROJECT_DIR$/.idea/product-service.iml" />
</modules>
</component>
</project>

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="Go" enabled="true">
<buildTags>
<option name="goVersion" value="go1.17" />
</buildTags>
</component>
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectTasksOptions">
<enabled-global>
<option value="go fmt" />
</enabled-global>
</component>
</project>

@ -0,0 +1,124 @@
package main
import (
"context"
consul "github.com/asim/go-micro/plugins/registry/consul/v4"
opentracing2 "github.com/go-micro/plugins/v4/wrapper/trace/opentracing"
"github.com/opentracing/opentracing-go"
"go-micro.dev/v4/web"
"goproduct/common"
"goproduct/proto"
"log"
"strconv"
"github.com/gin-gonic/gin"
"go-micro.dev/v4"
"go-micro.dev/v4/registry"
)
// 获取远程服务的客户端
func main() {
router := gin.Default()
router.Handle("GET", "toPage", func(context *gin.Context) {
context.String(200, "to toPage ....")
})
//注册到consul
consulReg := consul.NewRegistry(func(options *registry.Options) {
options.Addrs = []string{"192.168.100.131:8500"}
})
//初始化链路追踪的jaeper
t, io, err := common.NewTracer("shop-product-client", "192.168.100.131:6831")
if err != nil {
log.Println(err)
}
defer io.Close()
opentracing.SetGlobalTracer(t)
rpcServer := micro.NewService(
//micro.Name("shop-product-client"),
micro.Registry(consulReg), //服务发现
micro.WrapClient(opentracing2.NewClientWrapper(opentracing.GlobalTracer())),
)
client := proto.NewPageService("shop-product", rpcServer.Client())
//分页查询商品列表
router.GET("/page", func(c *gin.Context) {
//获取远程服务的客户端 client
//获取页面参数
length, _ := strconv.Atoi(c.Request.FormValue("length"))
pageIndex, _ := strconv.Atoi(c.Request.FormValue("pageIndex"))
//拼接请求信息
req := &proto.PageReq{
Length: int32(length),
PageIndex: int32(pageIndex),
}
//远程调用服务
resp, err := client.Page(context.TODO(), req)
log.Println(" /page :", resp)
//根据响应做输出
if err != nil {
log.Println(err.Error())
//c.String(http.StatusBadRequest, "search failed !")
common.RespFail(c.Writer, resp, "请求失败")
return
}
////writer data message row total field
common.RespListOK(c.Writer, resp, "请求成功", resp.Rows, resp.Total, "请求成功")
})
//查询商品详情
clientA := proto.NewShowProductDetailService("shop-product", rpcServer.Client())
router.GET("/showProductDetail", func(c *gin.Context) {
//获取远程服务的客户端 client
//获取页面参数
id, _ := strconv.Atoi(c.Request.FormValue("id"))
//拼接请求信息
req := &proto.ProductDetailReq{
Id: int32(id),
}
//远程调用服务
resp, err := clientA.ShowProductDetail(context.TODO(), req)
log.Println(" /showProductDetail :", resp)
//根据响应做输出
if err != nil {
log.Println(err.Error())
//c.String(http.StatusBadRequest, "search failed !")
common.RespFail(c.Writer, resp, "请求失败")
return
}
////writer data message row total field
common.RespOK(c.Writer, resp, "请求成功")
})
//查询商品SKU
clientSKU := proto.NewShowProductSkuService("shop-product", rpcServer.Client())
router.GET("/sku", func(c *gin.Context) {
//获取远程服务的客户端 client
//获取页面参数
id, _ := strconv.Atoi(c.Request.FormValue("productId"))
//拼接请求信息
req := &proto.ProductSkuReq{
ProductId: int32(id),
}
//远程调用服务
resp, err := clientSKU.ShowProductSku(context.TODO(), req)
log.Println(" /sku :", resp)
//根据响应做输出
if err != nil {
log.Println(err.Error())
//c.String(http.StatusBadRequest, "search failed !")
common.RespFail(c.Writer, resp, "请求失败")
return
}
////writer data message row total field
common.RespListOK(c.Writer, resp, "请求成功", 0, 0, "请求成功")
})
service := web.NewService(
web.Address(":6667"),
web.Name("shop-product-client"),
web.Registry(consulReg),
web.Handler(router),
)
service.Run()
//router.Run(":6666")
}

@ -0,0 +1,29 @@
package common
import (
"github.com/opentracing/opentracing-go"
jaeger "github.com/uber/jaeger-client-go"
"github.com/uber/jaeger-client-go/config"
"io"
"time"
)
/*
@Auth:ShenZ
@Description: Jaeger
*/
func NewTracer(serviceName string, addr string) (opentracing.Tracer, io.Closer, error) {
cfg := &config.Configuration{
ServiceName: serviceName,
Sampler: &config.SamplerConfig{
Type: jaeger.SamplerTypeConst,
Param: 1,
},
Reporter: &config.ReporterConfig{
BufferFlushInterval: 1 * time.Second,
LogSpans: true,
LocalAgentHostPort: addr,
},
}
return cfg.NewTracer()
}

@ -0,0 +1,86 @@
package repository
import (
"errors"
"fmt"
"goproduct/domain/model"
"gorm.io/gorm"
)
/**
int32 clientId = 1;
string phone = 2;
int32 systemId = 3;
string verificationCode = 4;
**/
//接口
type IProductRepository interface {
Page(int32, int32) (int64, *[]model.Product, error)
ShowProductDetail(int32) (*model.ProductDetail, error)
ShowProductSku(int32) (*[]model.ProductSku, error)
CountNum() int64
}
// 创建实例
func NewProductRepository(db *gorm.DB) IProductRepository {
return &ProductRepository{mysqlDB: db}
}
// 数据DB
type ProductRepository struct {
mysqlDB *gorm.DB
}
// 重写接口方法
// product/app/product/page?length=15&pageIndex=1
func (u *ProductRepository) Page(length int32, pageIndex int32) (coun int64, products *[]model.Product, err error) {
arr := make([]model.Product, length)
var count int64
//u.mysqlDB.Model(&model.Product{}).Count(&count)
if length > 0 && pageIndex > 0 {
u.mysqlDB = u.mysqlDB.Limit(int(length)).Offset((int(pageIndex) - 1) * int(length))
if err := u.mysqlDB.Find(&arr).Error; err != nil {
fmt.Println("query product err :", err)
}
u.mysqlDB.Model(&model.Product{}).Offset(-1).Limit(-1).Count(&count)
return count, &arr, nil
}
return count, &arr, errors.New("参数不匹配")
}
func (u *ProductRepository) ShowProductDetail(id int32) (product *model.ProductDetail, err error) {
sql := "select p.`id` , p.`name`, p.product_type,p.category_id ,p.starting_price,\n " +
" pd.detail as detail ,GROUP_CONCAT(pp.picture SEPARATOR ',') as picture_list\n" +
"FROM `product` p\n" +
" left join product_detail pd on p.id = pd.product_id\n " +
" left join product_picture pp on p.id = pp.product_id\n " +
" where p.`id` = ?"
var productDetails []model.ProductDetail
u.mysqlDB.Raw(sql, id).Scan(&productDetails)
fmt.Println("repository ShowProductDetail >>>> ", productDetails)
return &productDetails[0], nil
}
func (u *ProductRepository) CountNum() int64 {
var count int64
u.mysqlDB.Model(&model.Product{}).Offset(-1).Limit(-1).Count(&count)
return count
}
/*
SkuId int32 `gorm:"column:id" json:"skuId"`
Name string
AttributeSymbolList string `gorm:"column:attribute_symbolList" json:"attributeSymbolList"`
SellPrice float32 `gorm:"column:sell_price" json:"sellPrice"`
Stock int32 `gorm:"default:1"`
*/
func (u *ProductRepository) ShowProductSku(id int32) (product *[]model.ProductSku, err error) {
sql := "select id ,name ,attribute_symbol_list,sell_price,stock from product_sku where product_id= ?"
var productSku []model.ProductSku
u.mysqlDB.Raw(sql, id).Scan(&productSku)
fmt.Println("repository ShowProductSku >>>> ", productSku)
return &productSku, nil
}

@ -0,0 +1,40 @@
package service
import (
"goproduct/domain/model"
"goproduct/domain/repository"
)
type IProductDataService interface {
Page(int32, int32) (count int64, products *[]model.Product, err error)
ShowProductDetail(int32) (obj *model.ProductDetail, err error)
ShowProductSku(int32) (obj *[]model.ProductSku, err error)
CountNum() int64
}
type ProductDataService struct {
productRepository repository.IProductRepository
}
func NewProductDataService(productRepository repository.IProductRepository) IProductDataService {
return &ProductDataService{productRepository: productRepository}
}
// 重写接口方法
func (u *ProductDataService) Page(length int32, pageIndex int32) (count int64, products *[]model.Product, err error) {
return u.productRepository.Page(length, pageIndex)
}
func (u *ProductDataService) CountNum() int64 {
return u.productRepository.CountNum()
}
func (u *ProductDataService) ShowProductDetail(id int32) (product *model.ProductDetail, err error) {
return u.productRepository.ShowProductDetail(id)
}
func (u *ProductDataService) ShowProductSku(id int32) (product *[]model.ProductSku, err error) {
return u.productRepository.ShowProductSku(id)
}

@ -0,0 +1,98 @@
package handler
import (
"context"
"fmt"
"goproduct/common"
"goproduct/domain/model"
"goproduct/domain/service"
"goproduct/proto"
)
type ProductHandler struct {
ProductDataService service.IProductDataService
}
// 查询商品列表
func (u *ProductHandler) Page(ctx context.Context, req *proto.PageReq, resp *proto.PageResp) error {
//count := u.ProductDataService.CountNum()
count, obj, err := u.ProductDataService.Page(req.GetLength(), req.GetPageIndex())
if err != nil {
println("page product err :", err)
}
//count = u.ProductDataService.CountNum()
resp.Rows = int64(req.GetLength())
resp.Total = count
//fmt.Println(">>>>>>>>>>>>> page product success :", obj)
ObjForResp(obj, resp)
return nil
}
/*
*
"id": 115,
"name": "马歇尔MARSHALL STANMOREⅡ无线蓝牙音响家用复古重低音小音箱",
"startingPrice": 3300,
"mainPicture": "https://msb-edu-prod.oss-cn-beijing.aliyuncs.com/mall-product/product/d4f1f19e-2e90-4ac5-bbe3-1eba02085a0f.jpg",
"labelList": [ ],
"singleBuyLimit": null,
"isEnable": null,
"productType": null
*
*/
func ObjForResp(obj *[]model.Product, resp *proto.PageResp) (err error) {
for _, v := range *obj {
product := &proto.Product{}
err := common.SwapToStruct(v, product)
if err != nil {
return err
}
fmt.Println(">>>>>>>>>>>>> ", product)
resp.Product = append(resp.Product, product)
}
return nil
}
// 商品详情
func (u *ProductHandler) ShowProductDetail(ctx context.Context, req *proto.ProductDetailReq, resp *proto.ProductDetailResp) error {
//count := u.ProductDataService.CountNum()
obj, err := u.ProductDataService.ShowProductDetail(req.GetId())
if err != nil {
println("ShowProductDetail err :", err)
}
productDetail := &proto.ProductDetail{}
err1 := common.SwapToStruct(obj, productDetail)
if err1 != nil {
println("ShowProductDetail SwapToStruct err :", err1)
}
resp.ProductDetail = append(resp.ProductDetail, productDetail)
return nil
}
// 商品SKU
func (u *ProductHandler) ShowProductSku(ctx context.Context, req *proto.ProductSkuReq, resp *proto.ProductSkuResp) error {
//count := u.ProductDataService.CountNum()
obj, err := u.ProductDataService.ShowProductSku(req.GetProductId())
if err != nil {
println("ShowProductSku err :", err)
}
err1 := ObjSkuForResp(obj, resp)
if err1 != nil {
println("ShowProductSku SwapToStruct err :", err1)
}
return nil
}
func ObjSkuForResp(obj *[]model.ProductSku, resp *proto.ProductSkuResp) (err error) {
for _, v := range *obj {
product := &proto.ProductSku{}
err := common.SwapToStruct(v, product)
if err != nil {
return err
}
resp.ProductSku = append(resp.ProductSku, product)
}
return nil
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,211 @@
// Code generated by protoc-gen-micro. DO NOT EDIT.
// source: product.proto
package proto
import (
fmt "fmt"
proto "google.golang.org/protobuf/proto"
math "math"
)
import (
context "context"
api "go-micro.dev/v4/api"
client "go-micro.dev/v4/client"
server "go-micro.dev/v4/server"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// Reference imports to suppress errors if they are not otherwise used.
var _ api.Endpoint
var _ context.Context
var _ client.Option
var _ server.Option
// Api Endpoints for Page service
func NewPageEndpoints() []*api.Endpoint {
return []*api.Endpoint{}
}
// Client API for Page service
type PageService interface {
//rpc 服务
Page(ctx context.Context, in *PageReq, opts ...client.CallOption) (*PageResp, error)
}
type pageService struct {
c client.Client
name string
}
func NewPageService(name string, c client.Client) PageService {
return &pageService{
c: c,
name: name,
}
}
func (c *pageService) Page(ctx context.Context, in *PageReq, opts ...client.CallOption) (*PageResp, error) {
req := c.c.NewRequest(c.name, "Page.Page", in)
out := new(PageResp)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for Page service
type PageHandler interface {
//rpc 服务
Page(context.Context, *PageReq, *PageResp) error
}
func RegisterPageHandler(s server.Server, hdlr PageHandler, opts ...server.HandlerOption) error {
type page interface {
Page(ctx context.Context, in *PageReq, out *PageResp) error
}
type Page struct {
page
}
h := &pageHandler{hdlr}
return s.Handle(s.NewHandler(&Page{h}, opts...))
}
type pageHandler struct {
PageHandler
}
func (h *pageHandler) Page(ctx context.Context, in *PageReq, out *PageResp) error {
return h.PageHandler.Page(ctx, in, out)
}
// Api Endpoints for ShowProductDetail service
func NewShowProductDetailEndpoints() []*api.Endpoint {
return []*api.Endpoint{}
}
// Client API for ShowProductDetail service
type ShowProductDetailService interface {
//rpc 服务
ShowProductDetail(ctx context.Context, in *ProductDetailReq, opts ...client.CallOption) (*ProductDetailResp, error)
}
type showProductDetailService struct {
c client.Client
name string
}
func NewShowProductDetailService(name string, c client.Client) ShowProductDetailService {
return &showProductDetailService{
c: c,
name: name,
}
}
func (c *showProductDetailService) ShowProductDetail(ctx context.Context, in *ProductDetailReq, opts ...client.CallOption) (*ProductDetailResp, error) {
req := c.c.NewRequest(c.name, "ShowProductDetail.ShowProductDetail", in)
out := new(ProductDetailResp)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for ShowProductDetail service
type ShowProductDetailHandler interface {
//rpc 服务
ShowProductDetail(context.Context, *ProductDetailReq, *ProductDetailResp) error
}
func RegisterShowProductDetailHandler(s server.Server, hdlr ShowProductDetailHandler, opts ...server.HandlerOption) error {
type showProductDetail interface {
ShowProductDetail(ctx context.Context, in *ProductDetailReq, out *ProductDetailResp) error
}
type ShowProductDetail struct {
showProductDetail
}
h := &showProductDetailHandler{hdlr}
return s.Handle(s.NewHandler(&ShowProductDetail{h}, opts...))
}
type showProductDetailHandler struct {
ShowProductDetailHandler
}
func (h *showProductDetailHandler) ShowProductDetail(ctx context.Context, in *ProductDetailReq, out *ProductDetailResp) error {
return h.ShowProductDetailHandler.ShowProductDetail(ctx, in, out)
}
// Api Endpoints for ShowProductSku service
func NewShowProductSkuEndpoints() []*api.Endpoint {
return []*api.Endpoint{}
}
// Client API for ShowProductSku service
type ShowProductSkuService interface {
//rpc 服务
ShowProductSku(ctx context.Context, in *ProductSkuReq, opts ...client.CallOption) (*ProductSkuResp, error)
}
type showProductSkuService struct {
c client.Client
name string
}
func NewShowProductSkuService(name string, c client.Client) ShowProductSkuService {
return &showProductSkuService{
c: c,
name: name,
}
}
func (c *showProductSkuService) ShowProductSku(ctx context.Context, in *ProductSkuReq, opts ...client.CallOption) (*ProductSkuResp, error) {
req := c.c.NewRequest(c.name, "ShowProductSku.ShowProductSku", in)
out := new(ProductSkuResp)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for ShowProductSku service
type ShowProductSkuHandler interface {
//rpc 服务
ShowProductSku(context.Context, *ProductSkuReq, *ProductSkuResp) error
}
func RegisterShowProductSkuHandler(s server.Server, hdlr ShowProductSkuHandler, opts ...server.HandlerOption) error {
type showProductSku interface {
ShowProductSku(ctx context.Context, in *ProductSkuReq, out *ProductSkuResp) error
}
type ShowProductSku struct {
showProductSku
}
h := &showProductSkuHandler{hdlr}
return s.Handle(s.NewHandler(&ShowProductSku{h}, opts...))
}
type showProductSkuHandler struct {
ShowProductSkuHandler
}
func (h *showProductSkuHandler) ShowProductSku(ctx context.Context, in *ProductSkuReq, out *ProductSkuResp) error {
return h.ShowProductSkuHandler.ShowProductSku(ctx, in, out)
}

@ -0,0 +1,146 @@
/**
* @Auth:ShenZ
* @Description:
*/
syntax = "proto3"; //
option go_package="./;proto"; //1 2 package
package proto ; //
//
/**
"id": 115,
"name": "马歇尔MARSHALL STANMOREⅡ无线蓝牙音响家用复古重低音小音箱",
"startingPrice": 3300,
"mainPicture": "https://msb-edu-prod.oss-cn-beijing.aliyuncs.com/mall-product/product/d4f1f19e-2e90-4ac5-bbe3-1eba02085a0f.jpg",
"labelList": [ ],
"singleBuyLimit": null,
"isEnable": null,
"productType": null
**/
message Product {
int32 id = 1;
string name = 2;
int32 startingPrice =3;
string mainPicture = 4;
map<string,string> labelList = 5;
int32 singleBuyLimit = 6;
string token = 7;
bool isEnable = 8;
int32 productType = 9;
}
/**
{
"clientId": 0,
"phone": "",
"systemId": 0,
"verificationCode": ""
}
**/
// request struct
message PageReq {
int32 length = 1;
int32 pageIndex = 2;
}
// resp struct
/**
**/
message PageResp{
repeated Product product = 1;
int64 total =2;
int64 rows = 3;
}
//RPC
service Page {
//rpc
rpc Page (PageReq) returns (PageResp){}
}
/**
ID int32 `json:"id"`
Name string `json:"name"`
ProductType int32 `gorm:"default:1" json:"productType"`
CategoryId int32 `json:"categoryId"`
StartingPrice float32 `json:"startingPrice"`
TotalStock int32 `gorm:"default:1234" json:"totalStock"`
MainPicture string `gorm:"default:1" json:"mainPicture"`
RemoteAreaPostage float32 `json:"remoteAreaPostage"`
SingleBuyLimit int32 `json:"singleBuyLimit"`
IsEnable bool `json:"isEnable"`
Remark string `gorm:"default:1" json:"remark"`
CreateUser int32 `gorm:"default:1" json:"createUser"`
CreateTime time.Time `json:"createTime"`
UpdateUser int32 `json:"updateUser"`
UpdateTime time.Time `json:"updateTime"`
IsDeleted bool `json:"isDeleted"`
Detail string `gorm:"dtail" json:"detail"` //
PictureList []string `gorm:"pictureList" json:"pictureList"` //
*/
message ProductDetail {
int32 id = 1;
string name = 2;
int32 productType =3;
int32 categoryId = 4;
float startingPrice =5;
int32 totalStock = 6;
string mainPicture =7;
float remoteAreaPostage = 8;
int32 singleBuyLimit =9;
bool isEnable =10;
string remark =11;
int32 createUser =12 ;
string createTime = 13; //go get google.golang.org/protobuf/ptypes/timestamp
int32 updateUser =14;
string updateTime =15;
bool IsDeleted =16;
string detail =17;
string pictureList =18;
}
// request struct
message ProductDetailReq {
int32 id = 1;
}
// resp struct
/**
**/
message ProductDetailResp{
repeated ProductDetail productDetail = 1;
}
//RPC
service ShowProductDetail {
//rpc
rpc ShowProductDetail (ProductDetailReq) returns (ProductDetailResp){}
}
/*
SkuId int32 `gorm:"column:id" json:"skuId"`
Name string
AttributeSymbolList string `gorm:"column:attribute_symbolList" json:"attributeSymbolList"`
SellPrice float32 `gorm:"column:sell_price" json:"sellPrice"`
Stock int32 `gorm:"default:1"`
*/
message ProductSku {
int32 skuId = 1;
string name = 2;
string attributeSymbolList =3;
float sellPrice = 4;
int32 stock =5;
}
// request struct
message ProductSkuReq {
int32 productId = 1;
}
// resp struct
/**
**/
message ProductSkuResp{
repeated ProductSku productSku = 1;
}
//RPC
service ShowProductSku {
//rpc
rpc ShowProductSku (ProductSkuReq) returns (ProductSkuResp){}
}

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/user-service.iml" filepath="$PROJECT_DIR$/.idea/user-service.iml" />
</modules>
</component>
</project>

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="Go" enabled="true" />
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>
Loading…
Cancel
Save