zhangqian
2023-11-07 9e36cf6dfbd916a1a5fd79d628887972a90d9b5e
Merge branch 'master' of http://192.168.5.5:10010/r/aps/crm
4个文件已添加
12个文件已修改
1686 ■■■■■ 已修改文件
api/v1/product.go 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/v1/salesDetails.go 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
conf/aps-crm.json 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
conf/config.go 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
constvar/salesDetails.go 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main.go 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
model/request/salesDetails.go 42 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
model/salesDetails.go 66 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
proto/product.proto 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
proto/product/product.pb.go 405 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
proto/product/product_grpc.pb.go 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
proto/product_inventory.proto 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
proto/product_inventory/product_inventory.pb.go 672 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
proto/product_inventory/product_inventory_grpc.pb.go 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
router/salesDetails.go 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/timex.go 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/v1/product.go
@@ -9,6 +9,7 @@
    "aps_crm/pkg/ecode"
    "aps_crm/pkg/logx"
    "aps_crm/proto/product"
    "aps_crm/utils"
    "fmt"
    "github.com/gin-gonic/gin"
    "github.com/shopspring/decimal"
@@ -123,3 +124,40 @@
    }
    ctx.OkWithDetailed(getProductInfoResponse.Data)
}
// GetProductOrderInfo
//
// @Tags        产品
// @Summary    获取产品订单信息
// @Produce    application/json
// @Param        number    path        string    true    "明细编码"
// @Success    200    {object}    contextx.Response{data=[]product.WorkOrderInfo}    "成功"
//
//    @Router        /api/product/getProductOrderInfo/{number} [get]
func (ci *ProductApi) GetProductOrderInfo(c *gin.Context) {
    ctx, ok := contextx.NewContext(c, nil)
    if !ok {
        return
    }
    number := c.Param("number")
    first, err := model.NewSalesDetailsSearch().SetNumber(number).SetPreload(true).First()
    if err != nil {
        ctx.FailWithMsg(ecode.UnknownErr, "明细详情查找失败")
        return
    }
    params := make([]*product.Info, 0)
    for _, p := range first.Products {
        var pa *product.Info
        pa.ProductId = p.Number
        pa.Time = utils.TimeToString(first.UpdatedAt)
        params = append(params, pa)
    }
    client := product.NewProductServiceClient(productServiceConn)
    info, err := client.GetProductOrder(ctx.GetCtx(), &product.GetProductOrderRequest{Params: params})
    if err != nil {
        logx.Errorf("GetProductOrder err: %v", err.Error())
        ctx.FailWithMsg(ecode.UnknownErr, "内部错误")
        return
    }
    ctx.OkWithDetailed(info.List)
}
api/v1/salesDetails.go
@@ -1,14 +1,19 @@
package v1
import (
    "aps_crm/conf"
    "aps_crm/constvar"
    "aps_crm/model"
    "aps_crm/model/request"
    "aps_crm/model/response"
    "aps_crm/pkg/contextx"
    "aps_crm/pkg/ecode"
    "aps_crm/pkg/logx"
    "aps_crm/proto/product_inventory"
    "aps_crm/utils"
    "github.com/gin-gonic/gin"
    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials/insecure"
    "strconv"
)
@@ -160,6 +165,8 @@
    salesDetailsModel.CodeStandID = salesDetails.CodeStandID
    salesDetailsModel.DeliverType = salesDetails.DeliverType
    salesDetailsModel.QuotationId = salesDetails.QuotationId
    salesDetailsModel.Status = salesDetails.Status
    salesDetailsModel.Source = salesDetails.Source
    return ecode.OK, salesDetailsModel
}
@@ -196,3 +203,113 @@
        Count: int(total),
    })
}
// UpdateStatus
//
//    @Tags        SalesDetails
//    @Summary    更新销售明细状态
//    @Produce    application/json
//    @Param        object    body        request.UpdateSalesDetails    true    "查询参数"
//    @Success    200        {object}    contextx.Response{}
//    @Router        /api/salesDetails/update [post]
func (s *SalesDetailsApi) UpdateStatus(c *gin.Context) {
    var params request.UpdateSalesDetails
    ctx, ok := contextx.NewContext(c, &params)
    if !ok {
        return
    }
    m := make(map[string]interface{})
    m["status"] = params.SalesDetails.Status
    err := model.NewSalesDetailsSearch().SetId(params.Id).UpdateByMap(m)
    if err != nil {
        ctx.FailWithMsg(ecode.UnknownErr, "更新失败")
        return
    }
    ctx.Ok()
}
var (
    ProductInventoryServiceConn *grpc.ClientConn
)
func InitProductInventoryServiceConn() {
    var err error
    ProductInventoryServiceConn, err = grpc.Dial(conf.Conf.GrpcServiceAddr.WMS, grpc.WithTransportCredentials(insecure.NewCredentials()))
    if err != nil {
        logx.Errorf("grpc dial product service error: %v", err.Error())
        return
    }
}
func CloseProductInventoryServiceConn() {
    if ProductInventoryServiceConn != nil {
        ProductInventoryServiceConn.Close()
    }
}
// GetProductInventoryInfo
//
// @Tags        SalesDetails
// @Summary    获取产品库存信息
// @Produce    application/json
// @Param        number    path        string    true    "明细编码"
// @Success    200    {object}    response.ListResponse
//
//    @Router        /api/salesDetails/getProductInventoryInfo/{number} [get]
func (s *SalesDetailsApi) GetProductInventoryInfo(c *gin.Context) {
    ctx, ok := contextx.NewContext(c, nil)
    if !ok {
        return
    }
    number := c.Param("number")
    client := product_inventory.NewProductInventoryServiceClient(ProductInventoryServiceConn)
    info, err := client.GetInventoryProductInfo(ctx.GetCtx(), &product_inventory.GetInventoryProductInfoRequest{Number: number})
    if err != nil {
        logx.Errorf("GetProductInfo err: %v", err.Error())
        ctx.FailWithMsg(ecode.UnknownErr, "grpc调用错误")
        return
    }
    ctx.OkWithDetailed(info.ProductList)
}
// CreateOperation
//
// @Tags        SalesDetails
// @Summary    创建产品出库信息
// @Produce    application/json
// @Param        object    body        request.SalesDetails    true    "查询参数"
// @Success    200    {object}    response.ListResponse
//
//    @Router        /api/salesDetails/createOperation [post]
func (s *SalesDetailsApi) CreateOperation(c *gin.Context) {
    var params request.SalesDetails
    ctx, ok := contextx.NewContext(c, &params)
    if !ok {
        return
    }
    client := product_inventory.NewProductInventoryServiceClient(ProductInventoryServiceConn)
    products := make([]*product_inventory.InventoryProduct, 0)
    for _, product := range params.Products {
        var p product_inventory.InventoryProduct
        p.Id = product.Number
        p.Amount = product.Amount.String()
        products = append(products, &p)
    }
    _, err := client.CreateOperation(ctx.GetCtx(), &product_inventory.CreateOperationRequest{
        Number:      params.Number,
        Addressee:   params.Addressee,
        Address:     params.Address,
        Phone:       params.Phone,
        DeliverType: int32(params.DeliverType),
        ProductList: products,
    })
    if err != nil {
        logx.Errorf("CreateOperation err: %v", err.Error())
        ctx.FailWithMsg(ecode.UnknownErr, "grpc调用错误")
        return
    }
    ctx.Ok()
}
conf/aps-crm.json
@@ -49,7 +49,8 @@
  },
  "GrpcServiceAddr": {
    "Aps": "192.168.20.119:9091",
    "Admin": "192.168.20.119:50051"
    "Admin": "192.168.20.119:50051",
    "WMS": "192.168.20.118:8006"
  }
}
conf/config.go
@@ -61,6 +61,7 @@
    GrpcServiceAddr struct {
        Aps   string // aps服务地址
        Admin string // admin服务地址
        WMS   string //wms服务地址
    }
    config struct {
@@ -131,7 +132,10 @@
    if len(AdminGrpc) > 0 {
        Conf.GrpcServiceAddr.Admin = AdminGrpc
    }
    GrpcPort := os.Getenv("WMS_GRPC")
    if len(GrpcPort) > 0 {
        Conf.GrpcServiceAddr.WMS = GrpcPort
    }
    ApsGrpc := os.Getenv("GRPC_PORT")
    Host := os.Getenv("HOST")
constvar/salesDetails.go
@@ -9,3 +9,12 @@
    SalesDetailsKeywordTypePrincipal    SalesDetailsKeywordType = "销售负责人"
    SalesDetailsKeywordTypeProductName  SalesDetailsKeywordType = "产品名称"
)
type SalesDetailsStatus int
const (
    WaitConfirmed SalesDetailsStatus = iota + 1 //待确认
    WaitOutbound                                //待出库
    OverOutbound                                //出库完成
    OverCLose                                   //已关闭
)
main.go
@@ -49,6 +49,7 @@
    go v1.InitProductServiceConn()
    go middleware.InitUserConn()
    go v1.InitCodeServiceConn()
    go v1.InitProductInventoryServiceConn()
    //c := cron.New()
    //c.AddFunc("@every 15s", service.SyncUserInfo) // 每15秒同步一次
@@ -64,6 +65,7 @@
    v1.CloseProductServiceConn()
    v1.CloseCodeServiceConn()
    v1.CloseProductInventoryServiceConn()
    middleware.CloseUserConn()
    logx.Infof("aps-crm exited...")
model/request/salesDetails.go
@@ -10,26 +10,28 @@
}
type SalesDetails struct {
    ClientId            int              `json:"clientId" gorm:"column:client_id;type:int;comment:客户id"`
    Number              string           `json:"number" gorm:"column:number;type:varchar(255);comment:销售明细单号"`
    SaleChanceId        int              `json:"saleChanceId" gorm:"column:sale_chance_id;type:int;comment:销售机会id"`
    SaleType            int              `json:"saleType" gorm:"column:sale_type;type:int;comment:销售类型"`
    SignTime            string           `json:"signTime" gorm:"column:sign_time;type:datetime;comment:签单时间"`
    MemberId            int              `json:"memberId" gorm:"column:member_id;type:int;comment:负责人id"`
    DeliveryDate        string           `json:"deliveryDate" gorm:"column:delivery_date;type:datetime;comment:交货日期"`
    WechatOrderStatusId int              `json:"wechatOrderStatusId" gorm:"column:wechat_order_status_id;type:int;comment:微信订单状态id"`
    Address             string           `json:"address" gorm:"column:address;type:varchar(255);comment:地址"`
    Phone               string           `json:"phone" gorm:"column:phone;type:varchar(255);comment:电话"`
    Addressee           string           `json:"addressee" gorm:"column:addressee;type:varchar(255);comment:收件人"`
    Conditions          string           `json:"conditions" gorm:"column:conditions;type:text;comment:条件"`
    Remark              string           `json:"remark" gorm:"column:remark;type:text;comment:备注"`
    Products            []*model.Product `json:"products" gorm:"many2many:sales_details_product;"`
    LogisticCompany     string           `json:"logisticCompany" gorm:"column:logistic_company;type:varchar(255);comment:物流公司"`
    LogisticNumber      string           `json:"logisticNumber" gorm:"column:logistic_number;type:varchar(255);comment:物流单号"`
    LogisticCost        float64          `json:"logisticCost" gorm:"column:logistic_cost;type:decimal(10,2);comment:物流费用"`
    CodeStandID         string           `json:"codeStandID"` //编码id
    DeliverType         int              `json:"deliverType"` //交付类型:1.一次发货,2.多次发货
    QuotationId         int              `json:"quotationId" gorm:"column:quotation_id;type:int;comment:报价单id"`
    ClientId            int                         `json:"clientId" gorm:"column:client_id;type:int;comment:客户id"`
    Number              string                      `json:"number" gorm:"column:number;type:varchar(255);comment:销售明细单号"`
    SaleChanceId        int                         `json:"saleChanceId" gorm:"column:sale_chance_id;type:int;comment:销售机会id"`
    SaleType            int                         `json:"saleType" gorm:"column:sale_type;type:int;comment:销售类型"`
    SignTime            string                      `json:"signTime" gorm:"column:sign_time;type:datetime;comment:签单时间"`
    MemberId            int                         `json:"memberId" gorm:"column:member_id;type:int;comment:负责人id"`
    DeliveryDate        string                      `json:"deliveryDate" gorm:"column:delivery_date;type:datetime;comment:交货日期"`
    WechatOrderStatusId int                         `json:"wechatOrderStatusId" gorm:"column:wechat_order_status_id;type:int;comment:微信订单状态id"`
    Address             string                      `json:"address" gorm:"column:address;type:varchar(255);comment:地址"`
    Phone               string                      `json:"phone" gorm:"column:phone;type:varchar(255);comment:电话"`
    Addressee           string                      `json:"addressee" gorm:"column:addressee;type:varchar(255);comment:收件人"`
    Conditions          string                      `json:"conditions" gorm:"column:conditions;type:text;comment:条件"`
    Remark              string                      `json:"remark" gorm:"column:remark;type:text;comment:备注"`
    Products            []*model.Product            `json:"products" gorm:"many2many:sales_details_product;"`
    LogisticCompany     string                      `json:"logisticCompany" gorm:"column:logistic_company;type:varchar(255);comment:物流公司"`
    LogisticNumber      string                      `json:"logisticNumber" gorm:"column:logistic_number;type:varchar(255);comment:物流单号"`
    LogisticCost        float64                     `json:"logisticCost" gorm:"column:logistic_cost;type:decimal(10,2);comment:物流费用"`
    CodeStandID         string                      `json:"codeStandID"` //编码id
    DeliverType         int                         `json:"deliverType"` //交付类型:1.一次发货,2.多次发货
    QuotationId         int                         `json:"quotationId" gorm:"column:quotation_id;type:int;comment:报价单id"`
    Status              constvar.SalesDetailsStatus `json:"status" gorm:"column:status;type:int;comment:状态"`
    Source              string                      `json:"source" gorm:"column:source;type:varchar(255);comment:订单来源"`
}
type UpdateSalesDetails struct {
model/salesDetails.go
@@ -11,38 +11,40 @@
type (
    SalesDetails struct {
        Id                  int               `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
        ClientId            int               `json:"clientId" gorm:"column:client_id;type:int;comment:客户id"`
        Client              Client            `json:"client" gorm:"foreignKey:ClientId"`
        Number              string            `json:"number" gorm:"column:number;type:varchar(255);comment:销售明细单号"`
        SaleChanceId        int               `json:"saleChanceId" gorm:"column:sale_chance_id;type:int;comment:销售机会id"`
        SaleChance          SaleChance        `json:"saleChance" gorm:"foreignKey:SaleChanceId"`
        SaleType            int               `json:"saleType" gorm:"column:sale_type;type:int;comment:销售类型"`
        SignTime            string            `json:"signTime" gorm:"column:sign_time;type:varchar(255);comment:签单时间"`
        MemberId            int               `json:"memberId" gorm:"column:member_id;type:int;comment:负责人id"`
        Member              User              `json:"Member"  gorm:"foreignKey:MemberId"`
        DeliveryDate        string            `json:"deliveryDate" gorm:"column:delivery_date;type:varchar(255);comment:交货日期"`
        WechatOrderStatusId int               `json:"wechatOrderStatusId" gorm:"column:wechat_order_status;type:int;comment:微信订单状态"`
        WechatOrderStatus   WechatOrderStatus `json:"wechatOrderStatus" gorm:"foreignKey:WechatOrderStatusId"`
        Address             string            `json:"address" gorm:"column:address;type:varchar(255);comment:地址"`
        Phone               string            `json:"phone" gorm:"column:phone;type:varchar(255);comment:电话"`
        Addressee           string            `json:"addressee" gorm:"column:addressee;type:varchar(255);comment:收件人"`
        Conditions          string            `json:"conditions" gorm:"column:conditions;type:text;comment:条件"`
        CreatorId           int               `json:"creatorId" gorm:"column:creator_id;type:int;comment:创建人id"`
        Remark              string            `json:"remark" gorm:"column:remark;type:text;comment:备注"`
        Products            []*Product        `json:"products" gorm:"many2many:SalesDetails_Product;"`
        LogisticCompany     string            `json:"logisticCompany" gorm:"column:logistic_company;type:varchar(255);comment:物流公司"`
        LogisticNumber      string            `json:"logisticNumber" gorm:"column:logistic_number;type:varchar(255);comment:物流单号"`
        LogisticCost        float64           `json:"logisticCost" gorm:"column:logistic_cost;type:decimal(10,2);comment:物流费用"`
        AmountReceivable    decimal.Decimal   `gorm:"column:amount_receivable;type:decimal(12,2);comment:应收金额" json:"amountReceivable"`    // 应收金额
        AmountReceived      decimal.Decimal   `gorm:"column:amount_received;type:decimal(12,2);comment:已收金额" json:"amountReceived"`        // 已收金额
        AmountInvoiced      decimal.Decimal   `gorm:"column:amount_invoiced;type:decimal(12,2);comment:已开票金额" json:"amountInvoiced"`       // 已开票金额
        AmountUnInvoiced    decimal.Decimal   `gorm:"column:amount_not_invoiced;type:decimal(12,2);comment:未开票金额" json:"amountUnInvoiced"` // 未开票金额
        AmountTotal         decimal.Decimal   `gorm:"column:amount_total;type:decimal(12,2);comment:价税合计" json:"amountTotal"`              // 价税合计
        CodeStandID         string            `json:"codeStandID" gorm:"column:code_stand_id;type:varchar(255);comment:编码id"`
        DeliverType         int               `json:"deliverType" gorm:"column:deliver_type;type:int;comment:交付类型(1.一次发货,2.多次发货)"`
        QuotationId         int               `json:"quotationId" gorm:"column:quotation_id;type:int;comment:报价单id"`
        Quotation           Quotation         `json:"quotation" gorm:"foreignKey:QuotationId"`
        Id                  int                         `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
        ClientId            int                         `json:"clientId" gorm:"column:client_id;type:int;comment:客户id"`
        Client              Client                      `json:"client" gorm:"foreignKey:ClientId"`
        Number              string                      `json:"number" gorm:"column:number;type:varchar(255);comment:销售明细单号"`
        SaleChanceId        int                         `json:"saleChanceId" gorm:"column:sale_chance_id;type:int;comment:销售机会id"`
        SaleChance          SaleChance                  `json:"saleChance" gorm:"foreignKey:SaleChanceId"`
        SaleType            int                         `json:"saleType" gorm:"column:sale_type;type:int;comment:销售类型"`
        SignTime            string                      `json:"signTime" gorm:"column:sign_time;type:varchar(255);comment:签单时间"`
        MemberId            int                         `json:"memberId" gorm:"column:member_id;type:int;comment:负责人id"`
        Member              User                        `json:"Member"  gorm:"foreignKey:MemberId"`
        DeliveryDate        string                      `json:"deliveryDate" gorm:"column:delivery_date;type:varchar(255);comment:交货日期"`
        WechatOrderStatusId int                         `json:"wechatOrderStatusId" gorm:"column:wechat_order_status;type:int;comment:微信订单状态"`
        WechatOrderStatus   WechatOrderStatus           `json:"wechatOrderStatus" gorm:"foreignKey:WechatOrderStatusId"`
        Address             string                      `json:"address" gorm:"column:address;type:varchar(255);comment:地址"`
        Phone               string                      `json:"phone" gorm:"column:phone;type:varchar(255);comment:电话"`
        Addressee           string                      `json:"addressee" gorm:"column:addressee;type:varchar(255);comment:收件人"`
        Conditions          string                      `json:"conditions" gorm:"column:conditions;type:text;comment:条件"`
        CreatorId           int                         `json:"creatorId" gorm:"column:creator_id;type:int;comment:创建人id"`
        Remark              string                      `json:"remark" gorm:"column:remark;type:text;comment:备注"`
        Products            []*Product                  `json:"products" gorm:"many2many:SalesDetails_Product;"`
        LogisticCompany     string                      `json:"logisticCompany" gorm:"column:logistic_company;type:varchar(255);comment:物流公司"`
        LogisticNumber      string                      `json:"logisticNumber" gorm:"column:logistic_number;type:varchar(255);comment:物流单号"`
        LogisticCost        float64                     `json:"logisticCost" gorm:"column:logistic_cost;type:decimal(10,2);comment:物流费用"`
        AmountReceivable    decimal.Decimal             `gorm:"column:amount_receivable;type:decimal(12,2);comment:应收金额" json:"amountReceivable"`    // 应收金额
        AmountReceived      decimal.Decimal             `gorm:"column:amount_received;type:decimal(12,2);comment:已收金额" json:"amountReceived"`        // 已收金额
        AmountInvoiced      decimal.Decimal             `gorm:"column:amount_invoiced;type:decimal(12,2);comment:已开票金额" json:"amountInvoiced"`       // 已开票金额
        AmountUnInvoiced    decimal.Decimal             `gorm:"column:amount_not_invoiced;type:decimal(12,2);comment:未开票金额" json:"amountUnInvoiced"` // 未开票金额
        AmountTotal         decimal.Decimal             `gorm:"column:amount_total;type:decimal(12,2);comment:价税合计" json:"amountTotal"`              // 价税合计
        CodeStandID         string                      `json:"codeStandID" gorm:"column:code_stand_id;type:varchar(255);comment:编码id"`
        DeliverType         int                         `json:"deliverType" gorm:"column:deliver_type;type:int;comment:交付类型(1.一次发货,2.多次发货)"`
        QuotationId         int                         `json:"quotationId" gorm:"column:quotation_id;type:int;comment:报价单id"`
        Quotation           Quotation                   `json:"quotation" gorm:"foreignKey:QuotationId"`
        Status              constvar.SalesDetailsStatus `json:"status" gorm:"column:status;type:int;comment:状态"`
        Source              string                      `json:"source" gorm:"column:source;type:varchar(255);comment:订单来源"`
        CrmModel
    }
proto/product.proto
@@ -5,6 +5,7 @@
service productService {
  rpc GetProductInfo(GetProductInfoRequest) returns(GetProductInfoResponse) {}
  rpc GetProductList(GetProductListRequest) returns(GetProductListResponse) {}
  rpc GetProductOrder(GetProductOrderRequest) returns (GetProductOrderResponse) {}
}
message GetProductInfoRequest{
@@ -44,4 +45,31 @@
  string  Msg = 2;
  repeated Product List = 3;
  int64 Total = 4;
}
//-------------------------------------------------------------
message Info {
  string ProductId = 1;
  string Time = 2;
}
message GetProductOrderRequest {
  repeated Info Params = 1;
}
message WorkOrderInfo{
  string OrderId = 1;
  string ProductName = 2;
  string OrderStatus = 3;
  string WorkOrderId = 4;
  string WorkOrderStatus = 5;
  string StartTime = 6;
  string EndTime = 7;
}
message GetProductOrderResponse{
  int32   Code = 1;
  string  Msg = 2;
  repeated WorkOrderInfo List = 3;
}
proto/product/product.pb.go
@@ -415,6 +415,266 @@
    return 0
}
type Info struct {
    state         protoimpl.MessageState
    sizeCache     protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields
    ProductId string `protobuf:"bytes,1,opt,name=ProductId,proto3" json:"ProductId,omitempty"`
    Time      string `protobuf:"bytes,2,opt,name=Time,proto3" json:"Time,omitempty"`
}
func (x *Info) Reset() {
    *x = Info{}
    if protoimpl.UnsafeEnabled {
        mi := &file_product_proto_msgTypes[5]
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        ms.StoreMessageInfo(mi)
    }
}
func (x *Info) String() string {
    return protoimpl.X.MessageStringOf(x)
}
func (*Info) ProtoMessage() {}
func (x *Info) ProtoReflect() protoreflect.Message {
    mi := &file_product_proto_msgTypes[5]
    if protoimpl.UnsafeEnabled && x != nil {
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        if ms.LoadMessageInfo() == nil {
            ms.StoreMessageInfo(mi)
        }
        return ms
    }
    return mi.MessageOf(x)
}
// Deprecated: Use Info.ProtoReflect.Descriptor instead.
func (*Info) Descriptor() ([]byte, []int) {
    return file_product_proto_rawDescGZIP(), []int{5}
}
func (x *Info) GetProductId() string {
    if x != nil {
        return x.ProductId
    }
    return ""
}
func (x *Info) GetTime() string {
    if x != nil {
        return x.Time
    }
    return ""
}
type GetProductOrderRequest struct {
    state         protoimpl.MessageState
    sizeCache     protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields
    Params []*Info `protobuf:"bytes,1,rep,name=Params,proto3" json:"Params,omitempty"`
}
func (x *GetProductOrderRequest) Reset() {
    *x = GetProductOrderRequest{}
    if protoimpl.UnsafeEnabled {
        mi := &file_product_proto_msgTypes[6]
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        ms.StoreMessageInfo(mi)
    }
}
func (x *GetProductOrderRequest) String() string {
    return protoimpl.X.MessageStringOf(x)
}
func (*GetProductOrderRequest) ProtoMessage() {}
func (x *GetProductOrderRequest) ProtoReflect() protoreflect.Message {
    mi := &file_product_proto_msgTypes[6]
    if protoimpl.UnsafeEnabled && x != nil {
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        if ms.LoadMessageInfo() == nil {
            ms.StoreMessageInfo(mi)
        }
        return ms
    }
    return mi.MessageOf(x)
}
// Deprecated: Use GetProductOrderRequest.ProtoReflect.Descriptor instead.
func (*GetProductOrderRequest) Descriptor() ([]byte, []int) {
    return file_product_proto_rawDescGZIP(), []int{6}
}
func (x *GetProductOrderRequest) GetParams() []*Info {
    if x != nil {
        return x.Params
    }
    return nil
}
type WorkOrderInfo struct {
    state         protoimpl.MessageState
    sizeCache     protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields
    OrderId         string `protobuf:"bytes,1,opt,name=OrderId,proto3" json:"OrderId,omitempty"`
    ProductName     string `protobuf:"bytes,2,opt,name=ProductName,proto3" json:"ProductName,omitempty"`
    OrderStatus     string `protobuf:"bytes,3,opt,name=OrderStatus,proto3" json:"OrderStatus,omitempty"`
    WorkOrderId     string `protobuf:"bytes,4,opt,name=WorkOrderId,proto3" json:"WorkOrderId,omitempty"`
    WorkOrderStatus string `protobuf:"bytes,5,opt,name=WorkOrderStatus,proto3" json:"WorkOrderStatus,omitempty"`
    StartTime       string `protobuf:"bytes,6,opt,name=StartTime,proto3" json:"StartTime,omitempty"`
    EndTime         string `protobuf:"bytes,7,opt,name=EndTime,proto3" json:"EndTime,omitempty"`
}
func (x *WorkOrderInfo) Reset() {
    *x = WorkOrderInfo{}
    if protoimpl.UnsafeEnabled {
        mi := &file_product_proto_msgTypes[7]
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        ms.StoreMessageInfo(mi)
    }
}
func (x *WorkOrderInfo) String() string {
    return protoimpl.X.MessageStringOf(x)
}
func (*WorkOrderInfo) ProtoMessage() {}
func (x *WorkOrderInfo) ProtoReflect() protoreflect.Message {
    mi := &file_product_proto_msgTypes[7]
    if protoimpl.UnsafeEnabled && x != nil {
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        if ms.LoadMessageInfo() == nil {
            ms.StoreMessageInfo(mi)
        }
        return ms
    }
    return mi.MessageOf(x)
}
// Deprecated: Use WorkOrderInfo.ProtoReflect.Descriptor instead.
func (*WorkOrderInfo) Descriptor() ([]byte, []int) {
    return file_product_proto_rawDescGZIP(), []int{7}
}
func (x *WorkOrderInfo) GetOrderId() string {
    if x != nil {
        return x.OrderId
    }
    return ""
}
func (x *WorkOrderInfo) GetProductName() string {
    if x != nil {
        return x.ProductName
    }
    return ""
}
func (x *WorkOrderInfo) GetOrderStatus() string {
    if x != nil {
        return x.OrderStatus
    }
    return ""
}
func (x *WorkOrderInfo) GetWorkOrderId() string {
    if x != nil {
        return x.WorkOrderId
    }
    return ""
}
func (x *WorkOrderInfo) GetWorkOrderStatus() string {
    if x != nil {
        return x.WorkOrderStatus
    }
    return ""
}
func (x *WorkOrderInfo) GetStartTime() string {
    if x != nil {
        return x.StartTime
    }
    return ""
}
func (x *WorkOrderInfo) GetEndTime() string {
    if x != nil {
        return x.EndTime
    }
    return ""
}
type GetProductOrderResponse struct {
    state         protoimpl.MessageState
    sizeCache     protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields
    Code int32            `protobuf:"varint,1,opt,name=Code,proto3" json:"Code,omitempty"`
    Msg  string           `protobuf:"bytes,2,opt,name=Msg,proto3" json:"Msg,omitempty"`
    List []*WorkOrderInfo `protobuf:"bytes,3,rep,name=List,proto3" json:"List,omitempty"`
}
func (x *GetProductOrderResponse) Reset() {
    *x = GetProductOrderResponse{}
    if protoimpl.UnsafeEnabled {
        mi := &file_product_proto_msgTypes[8]
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        ms.StoreMessageInfo(mi)
    }
}
func (x *GetProductOrderResponse) String() string {
    return protoimpl.X.MessageStringOf(x)
}
func (*GetProductOrderResponse) ProtoMessage() {}
func (x *GetProductOrderResponse) ProtoReflect() protoreflect.Message {
    mi := &file_product_proto_msgTypes[8]
    if protoimpl.UnsafeEnabled && x != nil {
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        if ms.LoadMessageInfo() == nil {
            ms.StoreMessageInfo(mi)
        }
        return ms
    }
    return mi.MessageOf(x)
}
// Deprecated: Use GetProductOrderResponse.ProtoReflect.Descriptor instead.
func (*GetProductOrderResponse) Descriptor() ([]byte, []int) {
    return file_product_proto_rawDescGZIP(), []int{8}
}
func (x *GetProductOrderResponse) GetCode() int32 {
    if x != nil {
        return x.Code
    }
    return 0
}
func (x *GetProductOrderResponse) GetMsg() string {
    if x != nil {
        return x.Msg
    }
    return ""
}
func (x *GetProductOrderResponse) GetList() []*WorkOrderInfo {
    if x != nil {
        return x.List
    }
    return nil
}
var File_product_proto protoreflect.FileDescriptor
var file_product_proto_rawDesc = []byte{
@@ -467,18 +727,51 @@
    0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x50,
    0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05,
    0x54, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x54, 0x6f, 0x74,
    0x61, 0x6c, 0x32, 0x9a, 0x01, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x53, 0x65,
    0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x43, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x64,
    0x75, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f,
    0x64, 0x75, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
    0x17, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f,
    0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0e, 0x47, 0x65,
    0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x16, 0x2e, 0x47,
    0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71,
    0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63,
    0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42,
    0x0b, 0x5a, 0x09, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x62, 0x06, 0x70, 0x72,
    0x6f, 0x74, 0x6f, 0x33,
    0x61, 0x6c, 0x22, 0x38, 0x0a, 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x72,
    0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50,
    0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x69, 0x6d, 0x65,
    0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x37, 0x0a, 0x16,
    0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52,
    0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73,
    0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x05, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x50,
    0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0xf1, 0x01, 0x0a, 0x0d, 0x57, 0x6f, 0x72, 0x6b, 0x4f, 0x72,
    0x64, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x4f, 0x72, 0x64, 0x65, 0x72,
    0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x49,
    0x64, 0x12, 0x20, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65,
    0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x4e,
    0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74,
    0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x53,
    0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x57, 0x6f, 0x72, 0x6b, 0x4f, 0x72, 0x64,
    0x65, 0x72, 0x49, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x57, 0x6f, 0x72, 0x6b,
    0x4f, 0x72, 0x64, 0x65, 0x72, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x0f, 0x57, 0x6f, 0x72, 0x6b, 0x4f,
    0x72, 0x64, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09,
    0x52, 0x0f, 0x57, 0x6f, 0x72, 0x6b, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75,
    0x73, 0x12, 0x1c, 0x0a, 0x09, 0x53, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x06,
    0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x53, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12,
    0x18, 0x0a, 0x07, 0x45, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09,
    0x52, 0x07, 0x45, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x63, 0x0a, 0x17, 0x47, 0x65, 0x74,
    0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70,
    0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01,
    0x28, 0x05, 0x52, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x18,
    0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x22, 0x0a, 0x04, 0x4c, 0x69,
    0x73, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x4f,
    0x72, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x32, 0xe2,
    0x01, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
    0x65, 0x12, 0x43, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49,
    0x6e, 0x66, 0x6f, 0x12, 0x16, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74,
    0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x47, 0x65,
    0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70,
    0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f,
    0x64, 0x75, 0x63, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x16, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72,
    0x6f, 0x64, 0x75, 0x63, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
    0x1a, 0x17, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x4c, 0x69, 0x73,
    0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x0f, 0x47,
    0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x17,
    0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x4f, 0x72, 0x64, 0x65, 0x72,
    0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f,
    0x64, 0x75, 0x63, 0x74, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
    0x65, 0x22, 0x00, 0x42, 0x0b, 0x5a, 0x09, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74,
    0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -493,26 +786,34 @@
    return file_product_proto_rawDescData
}
var file_product_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
var file_product_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
var file_product_proto_goTypes = []interface{}{
    (*GetProductInfoRequest)(nil),  // 0: GetProductInfoRequest
    (*GetProductInfoResponse)(nil), // 1: GetProductInfoResponse
    (*Product)(nil),                // 2: Product
    (*GetProductListRequest)(nil),  // 3: GetProductListRequest
    (*GetProductListResponse)(nil), // 4: GetProductListResponse
    (*GetProductInfoRequest)(nil),   // 0: GetProductInfoRequest
    (*GetProductInfoResponse)(nil),  // 1: GetProductInfoResponse
    (*Product)(nil),                 // 2: Product
    (*GetProductListRequest)(nil),   // 3: GetProductListRequest
    (*GetProductListResponse)(nil),  // 4: GetProductListResponse
    (*Info)(nil),                    // 5: Info
    (*GetProductOrderRequest)(nil),  // 6: GetProductOrderRequest
    (*WorkOrderInfo)(nil),           // 7: WorkOrderInfo
    (*GetProductOrderResponse)(nil), // 8: GetProductOrderResponse
}
var file_product_proto_depIdxs = []int32{
    2, // 0: GetProductInfoResponse.Data:type_name -> Product
    2, // 1: GetProductListResponse.List:type_name -> Product
    0, // 2: productService.GetProductInfo:input_type -> GetProductInfoRequest
    3, // 3: productService.GetProductList:input_type -> GetProductListRequest
    1, // 4: productService.GetProductInfo:output_type -> GetProductInfoResponse
    4, // 5: productService.GetProductList:output_type -> GetProductListResponse
    4, // [4:6] is the sub-list for method output_type
    2, // [2:4] is the sub-list for method input_type
    2, // [2:2] is the sub-list for extension type_name
    2, // [2:2] is the sub-list for extension extendee
    0, // [0:2] is the sub-list for field type_name
    5, // 2: GetProductOrderRequest.Params:type_name -> Info
    7, // 3: GetProductOrderResponse.List:type_name -> WorkOrderInfo
    0, // 4: productService.GetProductInfo:input_type -> GetProductInfoRequest
    3, // 5: productService.GetProductList:input_type -> GetProductListRequest
    6, // 6: productService.GetProductOrder:input_type -> GetProductOrderRequest
    1, // 7: productService.GetProductInfo:output_type -> GetProductInfoResponse
    4, // 8: productService.GetProductList:output_type -> GetProductListResponse
    8, // 9: productService.GetProductOrder:output_type -> GetProductOrderResponse
    7, // [7:10] is the sub-list for method output_type
    4, // [4:7] is the sub-list for method input_type
    4, // [4:4] is the sub-list for extension type_name
    4, // [4:4] is the sub-list for extension extendee
    0, // [0:4] is the sub-list for field type_name
}
func init() { file_product_proto_init() }
@@ -581,6 +882,54 @@
                return nil
            }
        }
        file_product_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
            switch v := v.(*Info); i {
            case 0:
                return &v.state
            case 1:
                return &v.sizeCache
            case 2:
                return &v.unknownFields
            default:
                return nil
            }
        }
        file_product_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
            switch v := v.(*GetProductOrderRequest); i {
            case 0:
                return &v.state
            case 1:
                return &v.sizeCache
            case 2:
                return &v.unknownFields
            default:
                return nil
            }
        }
        file_product_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
            switch v := v.(*WorkOrderInfo); i {
            case 0:
                return &v.state
            case 1:
                return &v.sizeCache
            case 2:
                return &v.unknownFields
            default:
                return nil
            }
        }
        file_product_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
            switch v := v.(*GetProductOrderResponse); i {
            case 0:
                return &v.state
            case 1:
                return &v.sizeCache
            case 2:
                return &v.unknownFields
            default:
                return nil
            }
        }
    }
    type x struct{}
    out := protoimpl.TypeBuilder{
@@ -588,7 +937,7 @@
            GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
            RawDescriptor: file_product_proto_rawDesc,
            NumEnums:      0,
            NumMessages:   5,
            NumMessages:   9,
            NumExtensions: 0,
            NumServices:   1,
        },
proto/product/product_grpc.pb.go
@@ -20,6 +20,7 @@
type ProductServiceClient interface {
    GetProductInfo(ctx context.Context, in *GetProductInfoRequest, opts ...grpc.CallOption) (*GetProductInfoResponse, error)
    GetProductList(ctx context.Context, in *GetProductListRequest, opts ...grpc.CallOption) (*GetProductListResponse, error)
    GetProductOrder(ctx context.Context, in *GetProductOrderRequest, opts ...grpc.CallOption) (*GetProductOrderResponse, error)
}
type productServiceClient struct {
@@ -48,12 +49,22 @@
    return out, nil
}
func (c *productServiceClient) GetProductOrder(ctx context.Context, in *GetProductOrderRequest, opts ...grpc.CallOption) (*GetProductOrderResponse, error) {
    out := new(GetProductOrderResponse)
    err := c.cc.Invoke(ctx, "/productService/GetProductOrder", in, out, opts...)
    if err != nil {
        return nil, err
    }
    return out, nil
}
// ProductServiceServer is the server API for ProductService service.
// All implementations must embed UnimplementedProductServiceServer
// for forward compatibility
type ProductServiceServer interface {
    GetProductInfo(context.Context, *GetProductInfoRequest) (*GetProductInfoResponse, error)
    GetProductList(context.Context, *GetProductListRequest) (*GetProductListResponse, error)
    GetProductOrder(context.Context, *GetProductOrderRequest) (*GetProductOrderResponse, error)
    mustEmbedUnimplementedProductServiceServer()
}
@@ -66,6 +77,9 @@
}
func (UnimplementedProductServiceServer) GetProductList(context.Context, *GetProductListRequest) (*GetProductListResponse, error) {
    return nil, status.Errorf(codes.Unimplemented, "method GetProductList not implemented")
}
func (UnimplementedProductServiceServer) GetProductOrder(context.Context, *GetProductOrderRequest) (*GetProductOrderResponse, error) {
    return nil, status.Errorf(codes.Unimplemented, "method GetProductOrder not implemented")
}
func (UnimplementedProductServiceServer) mustEmbedUnimplementedProductServiceServer() {}
@@ -116,6 +130,24 @@
    return interceptor(ctx, in, info, handler)
}
func _ProductService_GetProductOrder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
    in := new(GetProductOrderRequest)
    if err := dec(in); err != nil {
        return nil, err
    }
    if interceptor == nil {
        return srv.(ProductServiceServer).GetProductOrder(ctx, in)
    }
    info := &grpc.UnaryServerInfo{
        Server:     srv,
        FullMethod: "/productService/GetProductOrder",
    }
    handler := func(ctx context.Context, req interface{}) (interface{}, error) {
        return srv.(ProductServiceServer).GetProductOrder(ctx, req.(*GetProductOrderRequest))
    }
    return interceptor(ctx, in, info, handler)
}
// ProductService_ServiceDesc is the grpc.ServiceDesc for ProductService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
@@ -131,6 +163,10 @@
            MethodName: "GetProductList",
            Handler:    _ProductService_GetProductList_Handler,
        },
        {
            MethodName: "GetProductOrder",
            Handler:    _ProductService_GetProductOrder_Handler,
        },
    },
    Streams:  []grpc.StreamDesc{},
    Metadata: "product.proto",
proto/product_inventory.proto
New file
@@ -0,0 +1,54 @@
syntax = "proto3";
option go_package = "./product_inventory";
service productInventoryService {
  rpc CreateOperation(CreateOperationRequest) returns(CreateOperationResponse) {}
  rpc GetInventoryProductInfo(GetInventoryProductInfoRequest) returns (GetInventoryProductInfoResponse) {}
}
message CreateOperationRequest{
  string Number = 1;//明细单编码
  string Addressee = 2;//收货人
  string Address = 3;//收货地址
  string Phone = 4;
  int32 DeliverType = 5;//交付类型
  repeated InventoryProduct ProductList = 6;
}
message InventoryProduct{
  string Id = 1;
  string Amount = 2;
}
message CreateOperationResponse{
  int32   Code = 1;
  string  Msg = 2;
}
//-------------------------------------------------------
message GetInventoryProductInfoRequest {
  string Number = 1;//明细单编码
}
message ProductInfo{
  string Id = 1;
  string Name = 2;
  string OrderAmount = 3;//订单数量
  string Unit = 4;
  string Invoice = 5;//发货单
  string Carrier = 6;//承运商
  string Waybill = 7;//运单号
  string SalePrice = 8;//销售单价
  string Valorem = 9;//价税合计
  string Warehouse = 10;
  string Amount = 11;//在库数量
  string AvailableNumber = 12;//可用库存
}
message GetInventoryProductInfoResponse{
  int32   Code = 1;
  string  Msg = 2;
  repeated ProductInfo ProductList = 3;
}
proto/product_inventory/product_inventory.pb.go
New file
@@ -0,0 +1,672 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
//     protoc-gen-go v1.26.0
//     protoc        v4.24.0
// source: product_inventory.proto
package product_inventory
import (
    protoreflect "google.golang.org/protobuf/reflect/protoreflect"
    protoimpl "google.golang.org/protobuf/runtime/protoimpl"
    reflect "reflect"
    sync "sync"
)
const (
    // Verify that this generated code is sufficiently up-to-date.
    _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
    // Verify that runtime/protoimpl is sufficiently up-to-date.
    _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type CreateOperationRequest struct {
    state         protoimpl.MessageState
    sizeCache     protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields
    Number      string              `protobuf:"bytes,1,opt,name=Number,proto3" json:"Number,omitempty"`       //明细单编码
    Addressee   string              `protobuf:"bytes,2,opt,name=Addressee,proto3" json:"Addressee,omitempty"` //收货人
    Address     string              `protobuf:"bytes,3,opt,name=Address,proto3" json:"Address,omitempty"`     //收货地址
    Phone       string              `protobuf:"bytes,4,opt,name=Phone,proto3" json:"Phone,omitempty"`
    DeliverType int32               `protobuf:"varint,5,opt,name=DeliverType,proto3" json:"DeliverType,omitempty"` //交付类型
    ProductList []*InventoryProduct `protobuf:"bytes,6,rep,name=ProductList,proto3" json:"ProductList,omitempty"`
}
func (x *CreateOperationRequest) Reset() {
    *x = CreateOperationRequest{}
    if protoimpl.UnsafeEnabled {
        mi := &file_product_inventory_proto_msgTypes[0]
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        ms.StoreMessageInfo(mi)
    }
}
func (x *CreateOperationRequest) String() string {
    return protoimpl.X.MessageStringOf(x)
}
func (*CreateOperationRequest) ProtoMessage() {}
func (x *CreateOperationRequest) ProtoReflect() protoreflect.Message {
    mi := &file_product_inventory_proto_msgTypes[0]
    if protoimpl.UnsafeEnabled && x != nil {
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        if ms.LoadMessageInfo() == nil {
            ms.StoreMessageInfo(mi)
        }
        return ms
    }
    return mi.MessageOf(x)
}
// Deprecated: Use CreateOperationRequest.ProtoReflect.Descriptor instead.
func (*CreateOperationRequest) Descriptor() ([]byte, []int) {
    return file_product_inventory_proto_rawDescGZIP(), []int{0}
}
func (x *CreateOperationRequest) GetNumber() string {
    if x != nil {
        return x.Number
    }
    return ""
}
func (x *CreateOperationRequest) GetAddressee() string {
    if x != nil {
        return x.Addressee
    }
    return ""
}
func (x *CreateOperationRequest) GetAddress() string {
    if x != nil {
        return x.Address
    }
    return ""
}
func (x *CreateOperationRequest) GetPhone() string {
    if x != nil {
        return x.Phone
    }
    return ""
}
func (x *CreateOperationRequest) GetDeliverType() int32 {
    if x != nil {
        return x.DeliverType
    }
    return 0
}
func (x *CreateOperationRequest) GetProductList() []*InventoryProduct {
    if x != nil {
        return x.ProductList
    }
    return nil
}
type InventoryProduct struct {
    state         protoimpl.MessageState
    sizeCache     protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields
    Id     string `protobuf:"bytes,1,opt,name=Id,proto3" json:"Id,omitempty"`
    Amount string `protobuf:"bytes,2,opt,name=Amount,proto3" json:"Amount,omitempty"`
}
func (x *InventoryProduct) Reset() {
    *x = InventoryProduct{}
    if protoimpl.UnsafeEnabled {
        mi := &file_product_inventory_proto_msgTypes[1]
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        ms.StoreMessageInfo(mi)
    }
}
func (x *InventoryProduct) String() string {
    return protoimpl.X.MessageStringOf(x)
}
func (*InventoryProduct) ProtoMessage() {}
func (x *InventoryProduct) ProtoReflect() protoreflect.Message {
    mi := &file_product_inventory_proto_msgTypes[1]
    if protoimpl.UnsafeEnabled && x != nil {
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        if ms.LoadMessageInfo() == nil {
            ms.StoreMessageInfo(mi)
        }
        return ms
    }
    return mi.MessageOf(x)
}
// Deprecated: Use InventoryProduct.ProtoReflect.Descriptor instead.
func (*InventoryProduct) Descriptor() ([]byte, []int) {
    return file_product_inventory_proto_rawDescGZIP(), []int{1}
}
func (x *InventoryProduct) GetId() string {
    if x != nil {
        return x.Id
    }
    return ""
}
func (x *InventoryProduct) GetAmount() string {
    if x != nil {
        return x.Amount
    }
    return ""
}
type CreateOperationResponse struct {
    state         protoimpl.MessageState
    sizeCache     protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields
    Code int32  `protobuf:"varint,1,opt,name=Code,proto3" json:"Code,omitempty"`
    Msg  string `protobuf:"bytes,2,opt,name=Msg,proto3" json:"Msg,omitempty"`
}
func (x *CreateOperationResponse) Reset() {
    *x = CreateOperationResponse{}
    if protoimpl.UnsafeEnabled {
        mi := &file_product_inventory_proto_msgTypes[2]
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        ms.StoreMessageInfo(mi)
    }
}
func (x *CreateOperationResponse) String() string {
    return protoimpl.X.MessageStringOf(x)
}
func (*CreateOperationResponse) ProtoMessage() {}
func (x *CreateOperationResponse) ProtoReflect() protoreflect.Message {
    mi := &file_product_inventory_proto_msgTypes[2]
    if protoimpl.UnsafeEnabled && x != nil {
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        if ms.LoadMessageInfo() == nil {
            ms.StoreMessageInfo(mi)
        }
        return ms
    }
    return mi.MessageOf(x)
}
// Deprecated: Use CreateOperationResponse.ProtoReflect.Descriptor instead.
func (*CreateOperationResponse) Descriptor() ([]byte, []int) {
    return file_product_inventory_proto_rawDescGZIP(), []int{2}
}
func (x *CreateOperationResponse) GetCode() int32 {
    if x != nil {
        return x.Code
    }
    return 0
}
func (x *CreateOperationResponse) GetMsg() string {
    if x != nil {
        return x.Msg
    }
    return ""
}
type GetInventoryProductInfoRequest struct {
    state         protoimpl.MessageState
    sizeCache     protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields
    Number string `protobuf:"bytes,1,opt,name=Number,proto3" json:"Number,omitempty"` //明细单编码
}
func (x *GetInventoryProductInfoRequest) Reset() {
    *x = GetInventoryProductInfoRequest{}
    if protoimpl.UnsafeEnabled {
        mi := &file_product_inventory_proto_msgTypes[3]
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        ms.StoreMessageInfo(mi)
    }
}
func (x *GetInventoryProductInfoRequest) String() string {
    return protoimpl.X.MessageStringOf(x)
}
func (*GetInventoryProductInfoRequest) ProtoMessage() {}
func (x *GetInventoryProductInfoRequest) ProtoReflect() protoreflect.Message {
    mi := &file_product_inventory_proto_msgTypes[3]
    if protoimpl.UnsafeEnabled && x != nil {
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        if ms.LoadMessageInfo() == nil {
            ms.StoreMessageInfo(mi)
        }
        return ms
    }
    return mi.MessageOf(x)
}
// Deprecated: Use GetInventoryProductInfoRequest.ProtoReflect.Descriptor instead.
func (*GetInventoryProductInfoRequest) Descriptor() ([]byte, []int) {
    return file_product_inventory_proto_rawDescGZIP(), []int{3}
}
func (x *GetInventoryProductInfoRequest) GetNumber() string {
    if x != nil {
        return x.Number
    }
    return ""
}
type ProductInfo struct {
    state         protoimpl.MessageState
    sizeCache     protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields
    Id              string `protobuf:"bytes,1,opt,name=Id,proto3" json:"Id,omitempty"`
    Name            string `protobuf:"bytes,2,opt,name=Name,proto3" json:"Name,omitempty"`
    OrderAmount     string `protobuf:"bytes,3,opt,name=OrderAmount,proto3" json:"OrderAmount,omitempty"` //订单数量
    Unit            string `protobuf:"bytes,4,opt,name=Unit,proto3" json:"Unit,omitempty"`
    Invoice         string `protobuf:"bytes,5,opt,name=Invoice,proto3" json:"Invoice,omitempty"`     //发货单
    Carrier         string `protobuf:"bytes,6,opt,name=Carrier,proto3" json:"Carrier,omitempty"`     //承运商
    Waybill         string `protobuf:"bytes,7,opt,name=Waybill,proto3" json:"Waybill,omitempty"`     //运单号
    SalePrice       string `protobuf:"bytes,8,opt,name=SalePrice,proto3" json:"SalePrice,omitempty"` //销售单价
    Valorem         string `protobuf:"bytes,9,opt,name=Valorem,proto3" json:"Valorem,omitempty"`     //价税合计
    Warehouse       string `protobuf:"bytes,10,opt,name=Warehouse,proto3" json:"Warehouse,omitempty"`
    Amount          string `protobuf:"bytes,11,opt,name=Amount,proto3" json:"Amount,omitempty"`                   //在库数量
    AvailableNumber string `protobuf:"bytes,12,opt,name=AvailableNumber,proto3" json:"AvailableNumber,omitempty"` //可用库存
}
func (x *ProductInfo) Reset() {
    *x = ProductInfo{}
    if protoimpl.UnsafeEnabled {
        mi := &file_product_inventory_proto_msgTypes[4]
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        ms.StoreMessageInfo(mi)
    }
}
func (x *ProductInfo) String() string {
    return protoimpl.X.MessageStringOf(x)
}
func (*ProductInfo) ProtoMessage() {}
func (x *ProductInfo) ProtoReflect() protoreflect.Message {
    mi := &file_product_inventory_proto_msgTypes[4]
    if protoimpl.UnsafeEnabled && x != nil {
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        if ms.LoadMessageInfo() == nil {
            ms.StoreMessageInfo(mi)
        }
        return ms
    }
    return mi.MessageOf(x)
}
// Deprecated: Use ProductInfo.ProtoReflect.Descriptor instead.
func (*ProductInfo) Descriptor() ([]byte, []int) {
    return file_product_inventory_proto_rawDescGZIP(), []int{4}
}
func (x *ProductInfo) GetId() string {
    if x != nil {
        return x.Id
    }
    return ""
}
func (x *ProductInfo) GetName() string {
    if x != nil {
        return x.Name
    }
    return ""
}
func (x *ProductInfo) GetOrderAmount() string {
    if x != nil {
        return x.OrderAmount
    }
    return ""
}
func (x *ProductInfo) GetUnit() string {
    if x != nil {
        return x.Unit
    }
    return ""
}
func (x *ProductInfo) GetInvoice() string {
    if x != nil {
        return x.Invoice
    }
    return ""
}
func (x *ProductInfo) GetCarrier() string {
    if x != nil {
        return x.Carrier
    }
    return ""
}
func (x *ProductInfo) GetWaybill() string {
    if x != nil {
        return x.Waybill
    }
    return ""
}
func (x *ProductInfo) GetSalePrice() string {
    if x != nil {
        return x.SalePrice
    }
    return ""
}
func (x *ProductInfo) GetValorem() string {
    if x != nil {
        return x.Valorem
    }
    return ""
}
func (x *ProductInfo) GetWarehouse() string {
    if x != nil {
        return x.Warehouse
    }
    return ""
}
func (x *ProductInfo) GetAmount() string {
    if x != nil {
        return x.Amount
    }
    return ""
}
func (x *ProductInfo) GetAvailableNumber() string {
    if x != nil {
        return x.AvailableNumber
    }
    return ""
}
type GetInventoryProductInfoResponse struct {
    state         protoimpl.MessageState
    sizeCache     protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields
    Code        int32          `protobuf:"varint,1,opt,name=Code,proto3" json:"Code,omitempty"`
    Msg         string         `protobuf:"bytes,2,opt,name=Msg,proto3" json:"Msg,omitempty"`
    ProductList []*ProductInfo `protobuf:"bytes,3,rep,name=ProductList,proto3" json:"ProductList,omitempty"`
}
func (x *GetInventoryProductInfoResponse) Reset() {
    *x = GetInventoryProductInfoResponse{}
    if protoimpl.UnsafeEnabled {
        mi := &file_product_inventory_proto_msgTypes[5]
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        ms.StoreMessageInfo(mi)
    }
}
func (x *GetInventoryProductInfoResponse) String() string {
    return protoimpl.X.MessageStringOf(x)
}
func (*GetInventoryProductInfoResponse) ProtoMessage() {}
func (x *GetInventoryProductInfoResponse) ProtoReflect() protoreflect.Message {
    mi := &file_product_inventory_proto_msgTypes[5]
    if protoimpl.UnsafeEnabled && x != nil {
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        if ms.LoadMessageInfo() == nil {
            ms.StoreMessageInfo(mi)
        }
        return ms
    }
    return mi.MessageOf(x)
}
// Deprecated: Use GetInventoryProductInfoResponse.ProtoReflect.Descriptor instead.
func (*GetInventoryProductInfoResponse) Descriptor() ([]byte, []int) {
    return file_product_inventory_proto_rawDescGZIP(), []int{5}
}
func (x *GetInventoryProductInfoResponse) GetCode() int32 {
    if x != nil {
        return x.Code
    }
    return 0
}
func (x *GetInventoryProductInfoResponse) GetMsg() string {
    if x != nil {
        return x.Msg
    }
    return ""
}
func (x *GetInventoryProductInfoResponse) GetProductList() []*ProductInfo {
    if x != nil {
        return x.ProductList
    }
    return nil
}
var File_product_inventory_proto protoreflect.FileDescriptor
var file_product_inventory_proto_rawDesc = []byte{
    0x0a, 0x17, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x5f, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74,
    0x6f, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd5, 0x01, 0x0a, 0x16, 0x43, 0x72,
    0x65, 0x61, 0x74, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71,
    0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01,
    0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09,
    0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
    0x09, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x41, 0x64,
    0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x41, 0x64, 0x64,
    0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x18, 0x04, 0x20,
    0x01, 0x28, 0x09, 0x52, 0x05, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x44, 0x65,
    0x6c, 0x69, 0x76, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52,
    0x0b, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x33, 0x0a, 0x0b,
    0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x06, 0x20, 0x03, 0x28,
    0x0b, 0x32, 0x11, 0x2e, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x50, 0x72, 0x6f,
    0x64, 0x75, 0x63, 0x74, 0x52, 0x0b, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x4c, 0x69, 0x73,
    0x74, 0x22, 0x3a, 0x0a, 0x10, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x50, 0x72,
    0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
    0x09, 0x52, 0x02, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18,
    0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3f, 0x0a,
    0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
    0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x43, 0x6f, 0x64, 0x65,
    0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03,
    0x4d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x4d, 0x73, 0x67, 0x22, 0x38,
    0x0a, 0x1e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x50, 0x72,
    0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
    0x12, 0x16, 0x0a, 0x06, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
    0x52, 0x06, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0xcd, 0x02, 0x0a, 0x0b, 0x50, 0x72, 0x6f,
    0x64, 0x75, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01,
    0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65,
    0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b,
    0x4f, 0x72, 0x64, 0x65, 0x72, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28,
    0x09, 0x52, 0x0b, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12,
    0x0a, 0x04, 0x55, 0x6e, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x55, 0x6e,
    0x69, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x18, 0x05, 0x20,
    0x01, 0x28, 0x09, 0x52, 0x07, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07,
    0x43, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x43,
    0x61, 0x72, 0x72, 0x69, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x57, 0x61, 0x79, 0x62, 0x69, 0x6c,
    0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x57, 0x61, 0x79, 0x62, 0x69, 0x6c, 0x6c,
    0x12, 0x1c, 0x0a, 0x09, 0x53, 0x61, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x63, 0x65, 0x18, 0x08, 0x20,
    0x01, 0x28, 0x09, 0x52, 0x09, 0x53, 0x61, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x18,
    0x0a, 0x07, 0x56, 0x61, 0x6c, 0x6f, 0x72, 0x65, 0x6d, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52,
    0x07, 0x56, 0x61, 0x6c, 0x6f, 0x72, 0x65, 0x6d, 0x12, 0x1c, 0x0a, 0x09, 0x57, 0x61, 0x72, 0x65,
    0x68, 0x6f, 0x75, 0x73, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x57, 0x61, 0x72,
    0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74,
    0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x28,
    0x0a, 0x0f, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65,
    0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62,
    0x6c, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x77, 0x0a, 0x1f, 0x47, 0x65, 0x74, 0x49,
    0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49,
    0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x43,
    0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x12,
    0x10, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x4d, 0x73,
    0x67, 0x12, 0x2e, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x4c, 0x69, 0x73, 0x74,
    0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74,
    0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x4c, 0x69, 0x73,
    0x74, 0x32, 0xc1, 0x01, 0x0a, 0x17, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6e, 0x76,
    0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x46, 0x0a,
    0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
    0x12, 0x17, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69,
    0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x43, 0x72, 0x65, 0x61,
    0x74, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
    0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5e, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x76, 0x65,
    0x6e, 0x74, 0x6f, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f,
    0x12, 0x1f, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x50,
    0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
    0x74, 0x1a, 0x20, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79,
    0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f,
    0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x15, 0x5a, 0x13, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x64, 0x75,
    0x63, 0x74, 0x5f, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x62, 0x06, 0x70, 0x72,
    0x6f, 0x74, 0x6f, 0x33,
}
var (
    file_product_inventory_proto_rawDescOnce sync.Once
    file_product_inventory_proto_rawDescData = file_product_inventory_proto_rawDesc
)
func file_product_inventory_proto_rawDescGZIP() []byte {
    file_product_inventory_proto_rawDescOnce.Do(func() {
        file_product_inventory_proto_rawDescData = protoimpl.X.CompressGZIP(file_product_inventory_proto_rawDescData)
    })
    return file_product_inventory_proto_rawDescData
}
var file_product_inventory_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
var file_product_inventory_proto_goTypes = []interface{}{
    (*CreateOperationRequest)(nil),          // 0: CreateOperationRequest
    (*InventoryProduct)(nil),                // 1: InventoryProduct
    (*CreateOperationResponse)(nil),         // 2: CreateOperationResponse
    (*GetInventoryProductInfoRequest)(nil),  // 3: GetInventoryProductInfoRequest
    (*ProductInfo)(nil),                     // 4: ProductInfo
    (*GetInventoryProductInfoResponse)(nil), // 5: GetInventoryProductInfoResponse
}
var file_product_inventory_proto_depIdxs = []int32{
    1, // 0: CreateOperationRequest.ProductList:type_name -> InventoryProduct
    4, // 1: GetInventoryProductInfoResponse.ProductList:type_name -> ProductInfo
    0, // 2: productInventoryService.CreateOperation:input_type -> CreateOperationRequest
    3, // 3: productInventoryService.GetInventoryProductInfo:input_type -> GetInventoryProductInfoRequest
    2, // 4: productInventoryService.CreateOperation:output_type -> CreateOperationResponse
    5, // 5: productInventoryService.GetInventoryProductInfo:output_type -> GetInventoryProductInfoResponse
    4, // [4:6] is the sub-list for method output_type
    2, // [2:4] is the sub-list for method input_type
    2, // [2:2] is the sub-list for extension type_name
    2, // [2:2] is the sub-list for extension extendee
    0, // [0:2] is the sub-list for field type_name
}
func init() { file_product_inventory_proto_init() }
func file_product_inventory_proto_init() {
    if File_product_inventory_proto != nil {
        return
    }
    if !protoimpl.UnsafeEnabled {
        file_product_inventory_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
            switch v := v.(*CreateOperationRequest); i {
            case 0:
                return &v.state
            case 1:
                return &v.sizeCache
            case 2:
                return &v.unknownFields
            default:
                return nil
            }
        }
        file_product_inventory_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
            switch v := v.(*InventoryProduct); i {
            case 0:
                return &v.state
            case 1:
                return &v.sizeCache
            case 2:
                return &v.unknownFields
            default:
                return nil
            }
        }
        file_product_inventory_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
            switch v := v.(*CreateOperationResponse); i {
            case 0:
                return &v.state
            case 1:
                return &v.sizeCache
            case 2:
                return &v.unknownFields
            default:
                return nil
            }
        }
        file_product_inventory_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
            switch v := v.(*GetInventoryProductInfoRequest); i {
            case 0:
                return &v.state
            case 1:
                return &v.sizeCache
            case 2:
                return &v.unknownFields
            default:
                return nil
            }
        }
        file_product_inventory_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
            switch v := v.(*ProductInfo); i {
            case 0:
                return &v.state
            case 1:
                return &v.sizeCache
            case 2:
                return &v.unknownFields
            default:
                return nil
            }
        }
        file_product_inventory_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
            switch v := v.(*GetInventoryProductInfoResponse); i {
            case 0:
                return &v.state
            case 1:
                return &v.sizeCache
            case 2:
                return &v.unknownFields
            default:
                return nil
            }
        }
    }
    type x struct{}
    out := protoimpl.TypeBuilder{
        File: protoimpl.DescBuilder{
            GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
            RawDescriptor: file_product_inventory_proto_rawDesc,
            NumEnums:      0,
            NumMessages:   6,
            NumExtensions: 0,
            NumServices:   1,
        },
        GoTypes:           file_product_inventory_proto_goTypes,
        DependencyIndexes: file_product_inventory_proto_depIdxs,
        MessageInfos:      file_product_inventory_proto_msgTypes,
    }.Build()
    File_product_inventory_proto = out.File
    file_product_inventory_proto_rawDesc = nil
    file_product_inventory_proto_goTypes = nil
    file_product_inventory_proto_depIdxs = nil
}
proto/product_inventory/product_inventory_grpc.pb.go
New file
@@ -0,0 +1,138 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
package product_inventory
import (
    context "context"
    grpc "google.golang.org/grpc"
    codes "google.golang.org/grpc/codes"
    status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
// ProductInventoryServiceClient is the client API for ProductInventoryService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type ProductInventoryServiceClient interface {
    CreateOperation(ctx context.Context, in *CreateOperationRequest, opts ...grpc.CallOption) (*CreateOperationResponse, error)
    GetInventoryProductInfo(ctx context.Context, in *GetInventoryProductInfoRequest, opts ...grpc.CallOption) (*GetInventoryProductInfoResponse, error)
}
type productInventoryServiceClient struct {
    cc grpc.ClientConnInterface
}
func NewProductInventoryServiceClient(cc grpc.ClientConnInterface) ProductInventoryServiceClient {
    return &productInventoryServiceClient{cc}
}
func (c *productInventoryServiceClient) CreateOperation(ctx context.Context, in *CreateOperationRequest, opts ...grpc.CallOption) (*CreateOperationResponse, error) {
    out := new(CreateOperationResponse)
    err := c.cc.Invoke(ctx, "/productInventoryService/CreateOperation", in, out, opts...)
    if err != nil {
        return nil, err
    }
    return out, nil
}
func (c *productInventoryServiceClient) GetInventoryProductInfo(ctx context.Context, in *GetInventoryProductInfoRequest, opts ...grpc.CallOption) (*GetInventoryProductInfoResponse, error) {
    out := new(GetInventoryProductInfoResponse)
    err := c.cc.Invoke(ctx, "/productInventoryService/GetInventoryProductInfo", in, out, opts...)
    if err != nil {
        return nil, err
    }
    return out, nil
}
// ProductInventoryServiceServer is the server API for ProductInventoryService service.
// All implementations must embed UnimplementedProductInventoryServiceServer
// for forward compatibility
type ProductInventoryServiceServer interface {
    CreateOperation(context.Context, *CreateOperationRequest) (*CreateOperationResponse, error)
    GetInventoryProductInfo(context.Context, *GetInventoryProductInfoRequest) (*GetInventoryProductInfoResponse, error)
    mustEmbedUnimplementedProductInventoryServiceServer()
}
// UnimplementedProductInventoryServiceServer must be embedded to have forward compatible implementations.
type UnimplementedProductInventoryServiceServer struct {
}
func (UnimplementedProductInventoryServiceServer) CreateOperation(context.Context, *CreateOperationRequest) (*CreateOperationResponse, error) {
    return nil, status.Errorf(codes.Unimplemented, "method CreateOperation not implemented")
}
func (UnimplementedProductInventoryServiceServer) GetInventoryProductInfo(context.Context, *GetInventoryProductInfoRequest) (*GetInventoryProductInfoResponse, error) {
    return nil, status.Errorf(codes.Unimplemented, "method GetInventoryProductInfo not implemented")
}
func (UnimplementedProductInventoryServiceServer) mustEmbedUnimplementedProductInventoryServiceServer() {
}
// UnsafeProductInventoryServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to ProductInventoryServiceServer will
// result in compilation errors.
type UnsafeProductInventoryServiceServer interface {
    mustEmbedUnimplementedProductInventoryServiceServer()
}
func RegisterProductInventoryServiceServer(s grpc.ServiceRegistrar, srv ProductInventoryServiceServer) {
    s.RegisterService(&ProductInventoryService_ServiceDesc, srv)
}
func _ProductInventoryService_CreateOperation_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
    in := new(CreateOperationRequest)
    if err := dec(in); err != nil {
        return nil, err
    }
    if interceptor == nil {
        return srv.(ProductInventoryServiceServer).CreateOperation(ctx, in)
    }
    info := &grpc.UnaryServerInfo{
        Server:     srv,
        FullMethod: "/productInventoryService/CreateOperation",
    }
    handler := func(ctx context.Context, req interface{}) (interface{}, error) {
        return srv.(ProductInventoryServiceServer).CreateOperation(ctx, req.(*CreateOperationRequest))
    }
    return interceptor(ctx, in, info, handler)
}
func _ProductInventoryService_GetInventoryProductInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
    in := new(GetInventoryProductInfoRequest)
    if err := dec(in); err != nil {
        return nil, err
    }
    if interceptor == nil {
        return srv.(ProductInventoryServiceServer).GetInventoryProductInfo(ctx, in)
    }
    info := &grpc.UnaryServerInfo{
        Server:     srv,
        FullMethod: "/productInventoryService/GetInventoryProductInfo",
    }
    handler := func(ctx context.Context, req interface{}) (interface{}, error) {
        return srv.(ProductInventoryServiceServer).GetInventoryProductInfo(ctx, req.(*GetInventoryProductInfoRequest))
    }
    return interceptor(ctx, in, info, handler)
}
// ProductInventoryService_ServiceDesc is the grpc.ServiceDesc for ProductInventoryService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var ProductInventoryService_ServiceDesc = grpc.ServiceDesc{
    ServiceName: "productInventoryService",
    HandlerType: (*ProductInventoryServiceServer)(nil),
    Methods: []grpc.MethodDesc{
        {
            MethodName: "CreateOperation",
            Handler:    _ProductInventoryService_CreateOperation_Handler,
        },
        {
            MethodName: "GetInventoryProductInfo",
            Handler:    _ProductInventoryService_GetInventoryProductInfo_Handler,
        },
    },
    Streams:  []grpc.StreamDesc{},
    Metadata: "product_inventory.proto",
}
router/salesDetails.go
@@ -11,10 +11,12 @@
    salesDetailsRouter := router.Group("salesDetails")
    salesDetailsApi := v1.ApiGroup.SalesDetailsApi
    {
        salesDetailsRouter.POST("add", salesDetailsApi.Add)              // 添加销售明细
        salesDetailsRouter.DELETE("delete/:id", salesDetailsApi.Delete)  // 删除销售明细
        salesDetailsRouter.DELETE("delete", salesDetailsApi.BatchDelete) // 批量删除销售明细
        salesDetailsRouter.PUT("update", salesDetailsApi.Update)         // 更新销售明细
        salesDetailsRouter.POST("list", salesDetailsApi.List)            // 获取销售明细单列表
        salesDetailsRouter.POST("add", salesDetailsApi.Add)                                                // 添加销售明细
        salesDetailsRouter.DELETE("delete/:id", salesDetailsApi.Delete)                                    // 删除销售明细
        salesDetailsRouter.DELETE("delete", salesDetailsApi.BatchDelete)                                   // 批量删除销售明细
        salesDetailsRouter.PUT("update", salesDetailsApi.Update)                                           // 更新销售明细
        salesDetailsRouter.POST("list", salesDetailsApi.List)                                              // 获取销售明细单列表
        salesDetailsRouter.GET("getProductInventoryInfo/:number", salesDetailsApi.GetProductInventoryInfo) // 获取产品库存信息
        salesDetailsRouter.POST("createOperation", salesDetailsApi.CreateOperation)                        // 创建产品出库信息
    }
}
utils/timex.go
New file
@@ -0,0 +1,58 @@
package utils
import (
    "time"
)
func StringToTime(timeStr string) (time.Time, error) {
    return time.ParseInLocation("2006-01-02 15:04:05", timeStr, time.Local)
}
func StringToTime2(timeStr string) (time.Time, error) {
    return time.ParseInLocation("2006-01-02", timeStr, time.Local)
}
func StringToTime3(timeStr string) (time.Time, error) {
    return time.ParseInLocation("2006-01-02 15:04", timeStr, time.Local)
}
func StringToClock(timeStr string) (time.Time, error) {
    return time.ParseInLocation("15:04", timeStr, time.Local)
}
func TimeToString(time time.Time) string {
    return time.Format("2006-01-02 15:04:05")
}
func TimeToString2(time time.Time) string {
    return time.Format("2006-01-02")
}
func TimeToString3(time time.Time) string {
    return time.Format("15:04")
}
func UnixTimeToString(_t int64) string {
    return time.Unix(_t, 0).In(time.Local).Format("2006-01-02 15:04:05")
}
func UnixTimeToDate(_t int64) string {
    return time.Unix(_t, 0).In(time.Local).Format("2006-01-02")
}
func DayStartTime(_t int64) int64 {
    l := time.Unix(_t, 0).In(time.Local)
    k := time.Date(l.Year(), l.Month(), l.Day(), 0, 0, 0, 0, time.Local).Unix()
    return k
}
func DayStartTimeDateStr(_t int64) string {
    l := time.Unix(_t, 0).In(time.Local)
    k := time.Date(l.Year(), l.Month(), l.Day(), 0, 0, 0, 0, time.Local)
    return TimeToString2(k)
}
const timeLayout = "2006-01-02 15:04:05"
func GetCurrentTime() string {
    return time.Now().Format(timeLayout)
}