From 115bd9b51f5d8eade4658f844de37516486c60e7 Mon Sep 17 00:00:00 2001
From: liujiandao <274878379@qq.com>
Date: 星期六, 18 十一月 2023 17:25:25 +0800
Subject: [PATCH] crm获取aps项目模块信息

---
 api/v1/product.go                |   48 +-
 model/request/salesDetails.go    |    3 
 proto/crm_aps/crm_aps.pb.go      |  559 +++++++++++++++++++++++++++++++
 api/v1/code.go                   |   42 +-
 router/salesDetails.go           |   18 
 docs/swagger.yaml                |   15 
 docs/docs.go                     |   22 +
 docs/swagger.json                |   22 +
 model/grpc_init/crm_aps_init.go  |   25 +
 conf/aps-crm.json                |    2 
 model/salesDetails.go            |    1 
 api/v1/salesDetails.go           |   77 ++++
 proto/crm_aps.proto              |   44 ++
 proto/crm_aps/crm_aps_grpc.pb.go |  137 +++++++
 main.go                          |    7 
 15 files changed, 961 insertions(+), 61 deletions(-)

diff --git a/api/v1/code.go b/api/v1/code.go
index a94cb5a..941623b 100644
--- a/api/v1/code.go
+++ b/api/v1/code.go
@@ -1,9 +1,9 @@
 package v1
 
 import (
-	"aps_crm/conf"
 	"aps_crm/constvar"
 	"aps_crm/model"
+	"aps_crm/model/grpc_init"
 	"aps_crm/model/request"
 	"aps_crm/model/response"
 	"aps_crm/pkg/contextx"
@@ -12,30 +12,28 @@
 	"aps_crm/proto/code"
 	"github.com/gin-gonic/gin"
 	"github.com/spf13/cast"
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/credentials/insecure"
 )
 
 type CodeApi struct{}
 
-var (
-	codeServiceConn *grpc.ClientConn
-)
-
-func InitCodeServiceConn() {
-	var err error
-	codeServiceConn, err = grpc.Dial(conf.Conf.GrpcServiceAddr.Aps, grpc.WithTransportCredentials(insecure.NewCredentials()))
-	if err != nil {
-		logx.Errorf("grpc dial product service error: %v", err.Error())
-		return
-	}
-}
-
-func CloseCodeServiceConn() {
-	if codeServiceConn != nil {
-		codeServiceConn.Close()
-	}
-}
+//var (
+//	codeServiceConn *grpc.ClientConn
+//)
+//
+//func InitCodeServiceConn() {
+//	var err error
+//	codeServiceConn, err = grpc.Dial(conf.Conf.GrpcServiceAddr.Aps, grpc.WithTransportCredentials(insecure.NewCredentials()))
+//	if err != nil {
+//		logx.Errorf("grpc dial product service error: %v", err.Error())
+//		return
+//	}
+//}
+//
+//func CloseCodeServiceConn() {
+//	if codeServiceConn != nil {
+//		codeServiceConn.Close()
+//	}
+//}
 
 // GetCodeList
 //
@@ -55,7 +53,7 @@
 	params.CodeStandID = c.Query("codeStandID")
 	params.Name = c.Query("name")
 	params.Type = c.Query("type")
-	client := code.NewCodeServiceClient(codeServiceConn)
+	client := code.NewCodeServiceClient(grpc_init.CrmApsGrpcServiceConn)
 	list, err := client.GetCodeList(ctx.GetCtx(), &code.GetCodeListRequest{
 		Page:        cast.ToInt32(params.Page),
 		PageSize:    cast.ToInt32(params.PageSize),
diff --git a/api/v1/product.go b/api/v1/product.go
index 9fb1241..e4fdc19 100644
--- a/api/v1/product.go
+++ b/api/v1/product.go
@@ -1,8 +1,8 @@
 package v1
 
 import (
-	"aps_crm/conf"
 	"aps_crm/model"
+	"aps_crm/model/grpc_init"
 	"aps_crm/model/request"
 	"aps_crm/model/response"
 	"aps_crm/pkg/contextx"
@@ -10,35 +10,31 @@
 	"aps_crm/pkg/logx"
 	"aps_crm/proto/product"
 	"aps_crm/utils"
-	"fmt"
 	"github.com/gin-gonic/gin"
 	"github.com/shopspring/decimal"
 	"github.com/spf13/cast"
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/credentials/insecure"
 )
 
 type ProductApi struct{}
 
-var (
-	productServiceConn *grpc.ClientConn
-)
-
-func InitProductServiceConn() {
-	fmt.Println(conf.Conf.GrpcServiceAddr.Aps)
-	var err error
-	productServiceConn, err = grpc.Dial(conf.Conf.GrpcServiceAddr.Aps, grpc.WithTransportCredentials(insecure.NewCredentials()))
-	if err != nil {
-		logx.Errorf("grpc dial product service error: %v", err.Error())
-		return
-	}
-}
-
-func CloseProductServiceConn() {
-	if productServiceConn != nil {
-		productServiceConn.Close()
-	}
-}
+//var (
+//	productServiceConn *grpc.ClientConn
+//)
+//
+//func InitProductServiceConn() {
+//	var err error
+//	productServiceConn, err = grpc.Dial(conf.Conf.GrpcServiceAddr.Aps, grpc.WithTransportCredentials(insecure.NewCredentials()))
+//	if err != nil {
+//		logx.Errorf("grpc dial product service error: %v", err.Error())
+//		return
+//	}
+//}
+//
+//func CloseProductServiceConn() {
+//	if productServiceConn != nil {
+//		productServiceConn.Close()
+//	}
+//}
 
 // List
 //
@@ -60,7 +56,7 @@
 		return
 	}
 
-	cli := product.NewProductServiceClient(productServiceConn)
+	cli := product.NewProductServiceClient(grpc_init.CrmApsGrpcServiceConn)
 	getProductListResponse, err := cli.GetProductList(ctx.GetCtx(), &product.GetProductListRequest{
 		Page:          cast.ToInt32(params.Page),
 		PageSize:      cast.ToInt32(params.PageSize),
@@ -110,7 +106,7 @@
 
 	// 鑾峰彇浜у搧ID
 	productId := c.Query("productNumber")
-	cli := product.NewProductServiceClient(productServiceConn)
+	cli := product.NewProductServiceClient(grpc_init.CrmApsGrpcServiceConn)
 
 	getProductInfoResponse, err := cli.GetProductInfo(ctx.GetCtx(), &product.GetProductInfoRequest{ProductId: productId})
 	if err != nil {
@@ -158,7 +154,7 @@
 		pa.EndTime = first.DeliveryDate
 		params = append(params, &pa)
 	}
-	client := product.NewProductServiceClient(productServiceConn)
+	client := product.NewProductServiceClient(grpc_init.CrmApsGrpcServiceConn)
 	info, err := client.GetProductOrder(ctx.GetCtx(), &product.GetProductOrderRequest{Params: params})
 	if err != nil {
 		logx.Errorf("GetProductOrder err: %v", err.Error())
diff --git a/api/v1/salesDetails.go b/api/v1/salesDetails.go
index d417eca..6b71e25 100644
--- a/api/v1/salesDetails.go
+++ b/api/v1/salesDetails.go
@@ -4,15 +4,18 @@
 	"aps_crm/conf"
 	"aps_crm/constvar"
 	"aps_crm/model"
+	"aps_crm/model/grpc_init"
 	"aps_crm/model/request"
 	"aps_crm/model/response"
 	"aps_crm/pkg/contextx"
 	"aps_crm/pkg/ecode"
 	"aps_crm/pkg/logx"
 	"aps_crm/pkg/structx"
+	"aps_crm/proto/crm_aps"
 	"aps_crm/proto/product_inventory"
 	"aps_crm/utils"
 	"github.com/gin-gonic/gin"
+	"github.com/shopspring/decimal"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/credentials/insecure"
 	"strconv"
@@ -327,3 +330,77 @@
 	}
 	ctx.Ok()
 }
+
+// GetApsProjectList
+//
+// @Tags		SalesDetails
+// @Summary	    鑾峰彇aps椤圭洰鍒楄〃
+// @Produce	application/json
+// @Success	200	{object}	response.Response
+//
+//	@Router		/api/salesDetails/getApsProjectList [get]
+func (s *SalesDetailsApi) GetApsProjectList(c *gin.Context) {
+	ctx, ok := contextx.NewContext(c, nil)
+	if !ok {
+		return
+	}
+	client := crm_aps.NewCrmAndApsGrpcServiceClient(grpc_init.CrmApsGrpcServiceConn)
+	projectList, err := client.GetApsProjectList(c, &crm_aps.GetApsProjectListRequest{})
+	if err != nil {
+		ctx.FailWithMsg(ecode.UnknownErr, "grpc璋冪敤閿欒: "+err.Error())
+		return
+	}
+	ctx.OkWithDetailed(projectList.List)
+}
+
+// SendSalesDetailsToApsProject
+//
+// @Tags		SalesDetails
+// @Summary	  鎺ㄩ�侀攢鍞槑缁嗕俊鎭埌aps椤圭洰妯″潡
+// @Produce	application/json
+// @Param		object	body		request.SalesDetails	true	"鏌ヨ鍙傛暟"
+// @Success	200	{object}	response.ListResponse
+//
+//	@Router		/api/salesDetails/sendSalesDetailsToApsProject [post]
+func (s *SalesDetailsApi) SendSalesDetailsToApsProject(c *gin.Context) {
+	var params request.SalesDetails
+	ctx, ok := contextx.NewContext(c, &params)
+	if !ok {
+		return
+	}
+	m := make(map[string]interface{})
+	m["status"] = params.Status
+	err := model.NewSalesDetailsSearch().SetNumber(params.Number).UpdateByMap(m)
+	if err != nil {
+		ctx.FailWithMsg(ecode.UnknownErr, "鐘舵�佹洿鏂板け璐�")
+		return
+	}
+
+	products := make([]*crm_aps.SalesDetailsProduct, 0)
+	var total decimal.Decimal
+	for _, product := range params.Products {
+		var sp crm_aps.SalesDetailsProduct
+		sp.ProductId = product.Number
+		sp.Amount = product.Amount.IntPart()
+		products = append(products, &sp)
+		total = total.Add(product.Amount)
+	}
+
+	client := crm_aps.NewCrmAndApsGrpcServiceClient(grpc_init.CrmApsGrpcServiceConn)
+	_, err = client.SendSalesDetailsToApsProject(c, &crm_aps.SendSalesDetailsToApsProjectRequest{
+		Number:       params.Number,
+		ClientName:   params.Client.Name,
+		MemberName:   params.Member.Username,
+		SignTime:     params.SignTime,
+		DeliveryDate: params.DeliveryDate,
+		Source:       params.Source,
+		ProductTotal: total.IntPart(),
+		ProjectId:    params.ProjectId,
+		Products:     products,
+	})
+	if err != nil {
+		ctx.FailWithMsg(ecode.UnknownErr, "grpc璋冪敤閿欒: "+err.Error())
+		return
+	}
+	ctx.Ok()
+}
diff --git a/conf/aps-crm.json b/conf/aps-crm.json
index a56afa5..7ad9ce1 100644
--- a/conf/aps-crm.json
+++ b/conf/aps-crm.json
@@ -49,7 +49,7 @@
     "Issuer": "qmPlus"
   },
   "GrpcServiceAddr": {
-    "Aps": "192.168.20.119:9091",
+    "Aps": "192.168.20.118:9091",
     "Admin": "192.168.20.119:50051",
     "WMS": "192.168.20.118:8006"
   }
diff --git a/docs/docs.go b/docs/docs.go
index 294962d..caf496f 100644
--- a/docs/docs.go
+++ b/docs/docs.go
@@ -5556,6 +5556,15 @@
                         "in": "query"
                     },
                     {
+                        "type": "array",
+                        "items": {
+                            "type": "integer"
+                        },
+                        "collectionFormat": "csv",
+                        "name": "principleIds",
+                        "in": "query"
+                    },
+                    {
                         "type": "integer",
                         "name": "sourceId",
                         "in": "query"
@@ -11832,6 +11841,9 @@
                 },
                 "total": {
                     "type": "number"
+                },
+                "unit": {
+                    "type": "string"
                 }
             }
         },
@@ -13362,6 +13374,10 @@
                     "type": "string"
                 },
                 "realName": {
+                    "type": "string"
+                },
+                "subUserIds": {
+                    "description": "涓嬪睘鍛樺伐鐢ㄦ埛id,鐢ㄩ�楀彿鍒嗗紑",
                     "type": "string"
                 },
                 "userType": {
@@ -15648,6 +15664,12 @@
                     "description": "姣忛〉澶у皬",
                     "type": "integer"
                 },
+                "principalIds": {
+                    "type": "array",
+                    "items": {
+                        "type": "integer"
+                    }
+                },
                 "sourceId": {
                     "type": "integer"
                 },
diff --git a/docs/swagger.json b/docs/swagger.json
index 95efe8d..cbe9c95 100644
--- a/docs/swagger.json
+++ b/docs/swagger.json
@@ -5544,6 +5544,15 @@
                         "in": "query"
                     },
                     {
+                        "type": "array",
+                        "items": {
+                            "type": "integer"
+                        },
+                        "collectionFormat": "csv",
+                        "name": "principleIds",
+                        "in": "query"
+                    },
+                    {
                         "type": "integer",
                         "name": "sourceId",
                         "in": "query"
@@ -11820,6 +11829,9 @@
                 },
                 "total": {
                     "type": "number"
+                },
+                "unit": {
+                    "type": "string"
                 }
             }
         },
@@ -13350,6 +13362,10 @@
                     "type": "string"
                 },
                 "realName": {
+                    "type": "string"
+                },
+                "subUserIds": {
+                    "description": "涓嬪睘鍛樺伐鐢ㄦ埛id,鐢ㄩ�楀彿鍒嗗紑",
                     "type": "string"
                 },
                 "userType": {
@@ -15636,6 +15652,12 @@
                     "description": "姣忛〉澶у皬",
                     "type": "integer"
                 },
+                "principalIds": {
+                    "type": "array",
+                    "items": {
+                        "type": "integer"
+                    }
+                },
                 "sourceId": {
                     "type": "integer"
                 },
diff --git a/docs/swagger.yaml b/docs/swagger.yaml
index aa85bd5..1c70de8 100644
--- a/docs/swagger.yaml
+++ b/docs/swagger.yaml
@@ -1130,6 +1130,8 @@
         type: number
       total:
         type: number
+      unit:
+        type: string
     type: object
   model.Province:
     properties:
@@ -2148,6 +2150,9 @@
       pos:
         type: string
       realName:
+        type: string
+      subUserIds:
+        description: 涓嬪睘鍛樺伐鐢ㄦ埛id,鐢ㄩ�楀彿鍒嗗紑
         type: string
       userType:
         $ref: '#/definitions/constvar.UserType'
@@ -3712,6 +3717,10 @@
       pageSize:
         description: 姣忛〉澶у皬
         type: integer
+      principalIds:
+        items:
+          type: integer
+        type: array
       sourceId:
         type: integer
       sourceType:
@@ -9745,6 +9754,12 @@
         in: query
         name: pageSize
         type: integer
+      - collectionFormat: csv
+        in: query
+        items:
+          type: integer
+        name: principleIds
+        type: array
       - in: query
         name: sourceId
         type: integer
diff --git a/main.go b/main.go
index 9bdf14c..d233483 100644
--- a/main.go
+++ b/main.go
@@ -6,6 +6,7 @@
 	"aps_crm/initialize"
 	"aps_crm/middleware"
 	"aps_crm/model"
+	"aps_crm/model/grpc_init"
 	"aps_crm/pkg/logx"
 	"aps_crm/proto/product_inventory"
 	"aps_crm/router"
@@ -49,10 +50,9 @@
 		WriteTimeout: 5 * time.Second,
 	}
 	//鍚姩grpc瀹㈡埛绔�
-	go v1.InitProductServiceConn()
 	go middleware.InitUserConn()
-	go v1.InitCodeServiceConn()
 	go v1.InitProductInventoryServiceConn()
+	go grpc_init.InitCrmApsGrpcServiceConn()
 	//鍚姩grpc鏈嶅姟
 	go func() {
 		ln, err := net.Listen("tcp", ":"+conf.Conf.System.GrpcPort)
@@ -82,10 +82,9 @@
 	<-quit
 
 	middleware.StopRefreshUser()
-	v1.CloseProductServiceConn()
-	v1.CloseCodeServiceConn()
 	v1.CloseProductInventoryServiceConn()
 	middleware.CloseUserConn()
+	grpc_init.CloseCrmApsGrpcServiceConn()
 
 	logx.Infof("aps-crm exited...")
 	os.Exit(0)
diff --git a/model/grpc_init/crm_aps_init.go b/model/grpc_init/crm_aps_init.go
new file mode 100644
index 0000000..6e82ec6
--- /dev/null
+++ b/model/grpc_init/crm_aps_init.go
@@ -0,0 +1,25 @@
+package grpc_init
+
+import (
+	"aps_crm/conf"
+	"aps_crm/pkg/logx"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/credentials/insecure"
+)
+
+var CrmApsGrpcServiceConn *grpc.ClientConn
+
+func InitCrmApsGrpcServiceConn() {
+	var err error
+	CrmApsGrpcServiceConn, err = grpc.Dial(conf.Conf.GrpcServiceAddr.Aps, grpc.WithTransportCredentials(insecure.NewCredentials()))
+	if err != nil {
+		logx.Errorf("grpc dial InitCrmApsGrpcServiceConn service error: %v", err.Error())
+		return
+	}
+}
+
+func CloseCrmApsGrpcServiceConn() {
+	if CrmApsGrpcServiceConn != nil {
+		CrmApsGrpcServiceConn.Close()
+	}
+}
diff --git a/model/request/salesDetails.go b/model/request/salesDetails.go
index 4915b69..ed2b4b6 100644
--- a/model/request/salesDetails.go
+++ b/model/request/salesDetails.go
@@ -11,11 +11,13 @@
 
 type SalesDetails struct {
 	ClientId            int                         `json:"clientId" gorm:"column:client_id;type:int;comment:瀹㈡埛id"`
+	Client              model.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:閿�鍞満浼歩d"`
 	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:璐熻矗浜篿d"`
+	Member              model.User                  `json:"Member"  gorm:"foreignKey:MemberId"`
 	DeliveryDate        string                      `json:"deliveryDate" gorm:"column:delivery_date;type:datetime;comment:浜よ揣鏃ユ湡"`
 	WechatOrderStatusId int                         `json:"wechatOrderStatusId" gorm:"column:wechat_order_status_id;type:int;comment:寰俊璁㈠崟鐘舵�乮d"`
 	Address             string                      `json:"address" gorm:"column:address;type:varchar(255);comment:鍦板潃"`
@@ -32,6 +34,7 @@
 	QuotationId         int                         `json:"quotationId" gorm:"column:quotation_id;type:int;comment:鎶ヤ环鍗昳d"`
 	Status              constvar.SalesDetailsStatus `json:"status" gorm:"column:status;type:int;comment:鐘舵��"`
 	Source              string                      `json:"source" gorm:"column:source;type:varchar(255);comment:璁㈠崟鏉ユ簮"`
+	ProjectId           string                      `json:"projectId" gorm:"column:project_id;type:varchar(255);comment:aps椤圭洰id"`
 }
 
 type UpdateSalesDetails struct {
diff --git a/model/salesDetails.go b/model/salesDetails.go
index d45be06..5ae20b0 100644
--- a/model/salesDetails.go
+++ b/model/salesDetails.go
@@ -45,6 +45,7 @@
 		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:璁㈠崟鏉ユ簮"`
+		ProjectId           string                      `json:"projectId" gorm:"column:project_id;type:varchar(255);comment:aps椤圭洰id"`
 		CrmModel
 	}
 
diff --git a/proto/crm_aps.proto b/proto/crm_aps.proto
new file mode 100644
index 0000000..17577db
--- /dev/null
+++ b/proto/crm_aps.proto
@@ -0,0 +1,44 @@
+syntax = "proto3";
+
+option go_package = "./crm_aps";
+
+service CrmAndApsGrpcService {
+  rpc GetApsProjectList(GetApsProjectListRequest) returns(GetApsProjectListResponse) {}
+  rpc SendSalesDetailsToApsProject(SendSalesDetailsToApsProjectRequest) returns(SendSalesDetailsToApsProjectResponse) {}
+}
+
+//-----------------------------------------------------GetApsProjectList--------------------------------------
+
+message GetApsProjectListRequest{
+}
+
+message ApsProject{
+  string projectId = 1;
+  string projectName = 2;
+}
+
+message GetApsProjectListResponse{
+  repeated ApsProject List = 1;
+}
+
+//-----------------------------------------------------SendSalesDetailsToApsProject---------------------------------------
+
+message SalesDetailsProduct {
+  string ProductId = 1;
+  int64 Amount = 2;
+}
+
+message SendSalesDetailsToApsProjectRequest{
+  string Number = 1;//閿�鍞槑缁嗗崟鍙�
+  string ClientName = 2;
+  string MemberName = 3;//閿�鍞礋璐d汉
+  string SignTime = 4;//绛惧崟鏃堕棿
+  string DeliveryDate = 5;//浜よ揣鏃ユ湡
+  string Source = 6;//璁㈠崟鏉ユ簮
+  int64 ProductTotal = 7;//浜у搧鎬绘暟
+  string ProjectId = 8;//椤圭洰id
+  repeated SalesDetailsProduct Products = 9;
+}
+
+message SendSalesDetailsToApsProjectResponse{
+}
\ No newline at end of file
diff --git a/proto/crm_aps/crm_aps.pb.go b/proto/crm_aps/crm_aps.pb.go
new file mode 100644
index 0000000..02b3c6e
--- /dev/null
+++ b/proto/crm_aps/crm_aps.pb.go
@@ -0,0 +1,559 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.26.0
+// 	protoc        v4.24.0
+// source: crm_aps.proto
+
+package crm_aps
+
+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 GetApsProjectListRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *GetApsProjectListRequest) Reset() {
+	*x = GetApsProjectListRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_crm_aps_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetApsProjectListRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetApsProjectListRequest) ProtoMessage() {}
+
+func (x *GetApsProjectListRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_crm_aps_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 GetApsProjectListRequest.ProtoReflect.Descriptor instead.
+func (*GetApsProjectListRequest) Descriptor() ([]byte, []int) {
+	return file_crm_aps_proto_rawDescGZIP(), []int{0}
+}
+
+type ApsProject struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ProjectId   string `protobuf:"bytes,1,opt,name=projectId,proto3" json:"projectId,omitempty"`
+	ProjectName string `protobuf:"bytes,2,opt,name=projectName,proto3" json:"projectName,omitempty"`
+}
+
+func (x *ApsProject) Reset() {
+	*x = ApsProject{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_crm_aps_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ApsProject) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ApsProject) ProtoMessage() {}
+
+func (x *ApsProject) ProtoReflect() protoreflect.Message {
+	mi := &file_crm_aps_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 ApsProject.ProtoReflect.Descriptor instead.
+func (*ApsProject) Descriptor() ([]byte, []int) {
+	return file_crm_aps_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *ApsProject) GetProjectId() string {
+	if x != nil {
+		return x.ProjectId
+	}
+	return ""
+}
+
+func (x *ApsProject) GetProjectName() string {
+	if x != nil {
+		return x.ProjectName
+	}
+	return ""
+}
+
+type GetApsProjectListResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	List []*ApsProject `protobuf:"bytes,1,rep,name=List,proto3" json:"List,omitempty"`
+}
+
+func (x *GetApsProjectListResponse) Reset() {
+	*x = GetApsProjectListResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_crm_aps_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetApsProjectListResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetApsProjectListResponse) ProtoMessage() {}
+
+func (x *GetApsProjectListResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_crm_aps_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 GetApsProjectListResponse.ProtoReflect.Descriptor instead.
+func (*GetApsProjectListResponse) Descriptor() ([]byte, []int) {
+	return file_crm_aps_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *GetApsProjectListResponse) GetList() []*ApsProject {
+	if x != nil {
+		return x.List
+	}
+	return nil
+}
+
+type SalesDetailsProduct struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ProductId string `protobuf:"bytes,1,opt,name=ProductId,proto3" json:"ProductId,omitempty"`
+	Amount    int64  `protobuf:"varint,2,opt,name=Amount,proto3" json:"Amount,omitempty"`
+}
+
+func (x *SalesDetailsProduct) Reset() {
+	*x = SalesDetailsProduct{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_crm_aps_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SalesDetailsProduct) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SalesDetailsProduct) ProtoMessage() {}
+
+func (x *SalesDetailsProduct) ProtoReflect() protoreflect.Message {
+	mi := &file_crm_aps_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 SalesDetailsProduct.ProtoReflect.Descriptor instead.
+func (*SalesDetailsProduct) Descriptor() ([]byte, []int) {
+	return file_crm_aps_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *SalesDetailsProduct) GetProductId() string {
+	if x != nil {
+		return x.ProductId
+	}
+	return ""
+}
+
+func (x *SalesDetailsProduct) GetAmount() int64 {
+	if x != nil {
+		return x.Amount
+	}
+	return 0
+}
+
+type SendSalesDetailsToApsProjectRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Number       string                 `protobuf:"bytes,1,opt,name=Number,proto3" json:"Number,omitempty"` //閿�鍞槑缁嗗崟鍙�
+	ClientName   string                 `protobuf:"bytes,2,opt,name=ClientName,proto3" json:"ClientName,omitempty"`
+	MemberName   string                 `protobuf:"bytes,3,opt,name=MemberName,proto3" json:"MemberName,omitempty"`      //閿�鍞礋璐d汉
+	SignTime     string                 `protobuf:"bytes,4,opt,name=SignTime,proto3" json:"SignTime,omitempty"`          //绛惧崟鏃堕棿
+	DeliveryDate string                 `protobuf:"bytes,5,opt,name=DeliveryDate,proto3" json:"DeliveryDate,omitempty"`  //浜よ揣鏃ユ湡
+	Source       string                 `protobuf:"bytes,6,opt,name=Source,proto3" json:"Source,omitempty"`              //璁㈠崟鏉ユ簮
+	ProductTotal int64                  `protobuf:"varint,7,opt,name=ProductTotal,proto3" json:"ProductTotal,omitempty"` //浜у搧鎬绘暟
+	ProjectId    string                 `protobuf:"bytes,8,opt,name=ProjectId,proto3" json:"ProjectId,omitempty"`        //椤圭洰id
+	Products     []*SalesDetailsProduct `protobuf:"bytes,9,rep,name=Products,proto3" json:"Products,omitempty"`
+}
+
+func (x *SendSalesDetailsToApsProjectRequest) Reset() {
+	*x = SendSalesDetailsToApsProjectRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_crm_aps_proto_msgTypes[4]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SendSalesDetailsToApsProjectRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SendSalesDetailsToApsProjectRequest) ProtoMessage() {}
+
+func (x *SendSalesDetailsToApsProjectRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_crm_aps_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 SendSalesDetailsToApsProjectRequest.ProtoReflect.Descriptor instead.
+func (*SendSalesDetailsToApsProjectRequest) Descriptor() ([]byte, []int) {
+	return file_crm_aps_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *SendSalesDetailsToApsProjectRequest) GetNumber() string {
+	if x != nil {
+		return x.Number
+	}
+	return ""
+}
+
+func (x *SendSalesDetailsToApsProjectRequest) GetClientName() string {
+	if x != nil {
+		return x.ClientName
+	}
+	return ""
+}
+
+func (x *SendSalesDetailsToApsProjectRequest) GetMemberName() string {
+	if x != nil {
+		return x.MemberName
+	}
+	return ""
+}
+
+func (x *SendSalesDetailsToApsProjectRequest) GetSignTime() string {
+	if x != nil {
+		return x.SignTime
+	}
+	return ""
+}
+
+func (x *SendSalesDetailsToApsProjectRequest) GetDeliveryDate() string {
+	if x != nil {
+		return x.DeliveryDate
+	}
+	return ""
+}
+
+func (x *SendSalesDetailsToApsProjectRequest) GetSource() string {
+	if x != nil {
+		return x.Source
+	}
+	return ""
+}
+
+func (x *SendSalesDetailsToApsProjectRequest) GetProductTotal() int64 {
+	if x != nil {
+		return x.ProductTotal
+	}
+	return 0
+}
+
+func (x *SendSalesDetailsToApsProjectRequest) GetProjectId() string {
+	if x != nil {
+		return x.ProjectId
+	}
+	return ""
+}
+
+func (x *SendSalesDetailsToApsProjectRequest) GetProducts() []*SalesDetailsProduct {
+	if x != nil {
+		return x.Products
+	}
+	return nil
+}
+
+type SendSalesDetailsToApsProjectResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *SendSalesDetailsToApsProjectResponse) Reset() {
+	*x = SendSalesDetailsToApsProjectResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_crm_aps_proto_msgTypes[5]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SendSalesDetailsToApsProjectResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SendSalesDetailsToApsProjectResponse) ProtoMessage() {}
+
+func (x *SendSalesDetailsToApsProjectResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_crm_aps_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 SendSalesDetailsToApsProjectResponse.ProtoReflect.Descriptor instead.
+func (*SendSalesDetailsToApsProjectResponse) Descriptor() ([]byte, []int) {
+	return file_crm_aps_proto_rawDescGZIP(), []int{5}
+}
+
+var File_crm_aps_proto protoreflect.FileDescriptor
+
+var file_crm_aps_proto_rawDesc = []byte{
+	0x0a, 0x0d, 0x63, 0x72, 0x6d, 0x5f, 0x61, 0x70, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22,
+	0x1a, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x41, 0x70, 0x73, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
+	0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x4c, 0x0a, 0x0a, 0x41,
+	0x70, 0x73, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, 0x6f,
+	0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72,
+	0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65,
+	0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72,
+	0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x3c, 0x0a, 0x19, 0x47, 0x65, 0x74,
+	0x41, 0x70, 0x73, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x01,
+	0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x41, 0x70, 0x73, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63,
+	0x74, 0x52, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x4b, 0x0a, 0x13, 0x53, 0x61, 0x6c, 0x65, 0x73,
+	0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 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, 0x16, 0x0a, 0x06,
+	0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x41, 0x6d,
+	0x6f, 0x75, 0x6e, 0x74, 0x22, 0xc9, 0x02, 0x0a, 0x23, 0x53, 0x65, 0x6e, 0x64, 0x53, 0x61, 0x6c,
+	0x65, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x54, 0x6f, 0x41, 0x70, 0x73, 0x50, 0x72,
+	0x6f, 0x6a, 0x65, 0x63, 0x74, 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, 0x1e, 0x0a, 0x0a, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4e, 0x61,
+	0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74,
+	0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4e, 0x61,
+	0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72,
+	0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x53, 0x69, 0x67, 0x6e, 0x54, 0x69, 0x6d, 0x65,
+	0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x53, 0x69, 0x67, 0x6e, 0x54, 0x69, 0x6d, 0x65,
+	0x12, 0x22, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x44, 0x61, 0x74, 0x65,
+	0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79,
+	0x44, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x06,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x22, 0x0a, 0x0c,
+	0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x07, 0x20, 0x01,
+	0x28, 0x03, 0x52, 0x0c, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x54, 0x6f, 0x74, 0x61, 0x6c,
+	0x12, 0x1c, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x18, 0x08, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x30,
+	0x0a, 0x08, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b,
+	0x32, 0x14, 0x2e, 0x53, 0x61, 0x6c, 0x65, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x50,
+	0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73,
+	0x22, 0x26, 0x0a, 0x24, 0x53, 0x65, 0x6e, 0x64, 0x53, 0x61, 0x6c, 0x65, 0x73, 0x44, 0x65, 0x74,
+	0x61, 0x69, 0x6c, 0x73, 0x54, 0x6f, 0x41, 0x70, 0x73, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xd3, 0x01, 0x0a, 0x14, 0x43, 0x72, 0x6d,
+	0x41, 0x6e, 0x64, 0x41, 0x70, 0x73, 0x47, 0x72, 0x70, 0x63, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
+	0x65, 0x12, 0x4c, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x41, 0x70, 0x73, 0x50, 0x72, 0x6f, 0x6a, 0x65,
+	0x63, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x19, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x70, 0x73, 0x50,
+	0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x1a, 0x1a, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x70, 0x73, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63,
+	0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
+	0x6d, 0x0a, 0x1c, 0x53, 0x65, 0x6e, 0x64, 0x53, 0x61, 0x6c, 0x65, 0x73, 0x44, 0x65, 0x74, 0x61,
+	0x69, 0x6c, 0x73, 0x54, 0x6f, 0x41, 0x70, 0x73, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12,
+	0x24, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x53, 0x61, 0x6c, 0x65, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69,
+	0x6c, 0x73, 0x54, 0x6f, 0x41, 0x70, 0x73, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x53, 0x61, 0x6c, 0x65,
+	0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x54, 0x6f, 0x41, 0x70, 0x73, 0x50, 0x72, 0x6f,
+	0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x0b,
+	0x5a, 0x09, 0x2e, 0x2f, 0x63, 0x72, 0x6d, 0x5f, 0x61, 0x70, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x33,
+}
+
+var (
+	file_crm_aps_proto_rawDescOnce sync.Once
+	file_crm_aps_proto_rawDescData = file_crm_aps_proto_rawDesc
+)
+
+func file_crm_aps_proto_rawDescGZIP() []byte {
+	file_crm_aps_proto_rawDescOnce.Do(func() {
+		file_crm_aps_proto_rawDescData = protoimpl.X.CompressGZIP(file_crm_aps_proto_rawDescData)
+	})
+	return file_crm_aps_proto_rawDescData
+}
+
+var file_crm_aps_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
+var file_crm_aps_proto_goTypes = []interface{}{
+	(*GetApsProjectListRequest)(nil),             // 0: GetApsProjectListRequest
+	(*ApsProject)(nil),                           // 1: ApsProject
+	(*GetApsProjectListResponse)(nil),            // 2: GetApsProjectListResponse
+	(*SalesDetailsProduct)(nil),                  // 3: SalesDetailsProduct
+	(*SendSalesDetailsToApsProjectRequest)(nil),  // 4: SendSalesDetailsToApsProjectRequest
+	(*SendSalesDetailsToApsProjectResponse)(nil), // 5: SendSalesDetailsToApsProjectResponse
+}
+var file_crm_aps_proto_depIdxs = []int32{
+	1, // 0: GetApsProjectListResponse.List:type_name -> ApsProject
+	3, // 1: SendSalesDetailsToApsProjectRequest.Products:type_name -> SalesDetailsProduct
+	0, // 2: CrmAndApsGrpcService.GetApsProjectList:input_type -> GetApsProjectListRequest
+	4, // 3: CrmAndApsGrpcService.SendSalesDetailsToApsProject:input_type -> SendSalesDetailsToApsProjectRequest
+	2, // 4: CrmAndApsGrpcService.GetApsProjectList:output_type -> GetApsProjectListResponse
+	5, // 5: CrmAndApsGrpcService.SendSalesDetailsToApsProject:output_type -> SendSalesDetailsToApsProjectResponse
+	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_crm_aps_proto_init() }
+func file_crm_aps_proto_init() {
+	if File_crm_aps_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_crm_aps_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetApsProjectListRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_crm_aps_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ApsProject); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_crm_aps_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetApsProjectListResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_crm_aps_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SalesDetailsProduct); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_crm_aps_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SendSalesDetailsToApsProjectRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_crm_aps_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SendSalesDetailsToApsProjectResponse); 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_crm_aps_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   6,
+			NumExtensions: 0,
+			NumServices:   1,
+		},
+		GoTypes:           file_crm_aps_proto_goTypes,
+		DependencyIndexes: file_crm_aps_proto_depIdxs,
+		MessageInfos:      file_crm_aps_proto_msgTypes,
+	}.Build()
+	File_crm_aps_proto = out.File
+	file_crm_aps_proto_rawDesc = nil
+	file_crm_aps_proto_goTypes = nil
+	file_crm_aps_proto_depIdxs = nil
+}
diff --git a/proto/crm_aps/crm_aps_grpc.pb.go b/proto/crm_aps/crm_aps_grpc.pb.go
new file mode 100644
index 0000000..2c32de6
--- /dev/null
+++ b/proto/crm_aps/crm_aps_grpc.pb.go
@@ -0,0 +1,137 @@
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+
+package crm_aps
+
+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
+
+// CrmAndApsGrpcServiceClient is the client API for CrmAndApsGrpcService 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 CrmAndApsGrpcServiceClient interface {
+	GetApsProjectList(ctx context.Context, in *GetApsProjectListRequest, opts ...grpc.CallOption) (*GetApsProjectListResponse, error)
+	SendSalesDetailsToApsProject(ctx context.Context, in *SendSalesDetailsToApsProjectRequest, opts ...grpc.CallOption) (*SendSalesDetailsToApsProjectResponse, error)
+}
+
+type crmAndApsGrpcServiceClient struct {
+	cc grpc.ClientConnInterface
+}
+
+func NewCrmAndApsGrpcServiceClient(cc grpc.ClientConnInterface) CrmAndApsGrpcServiceClient {
+	return &crmAndApsGrpcServiceClient{cc}
+}
+
+func (c *crmAndApsGrpcServiceClient) GetApsProjectList(ctx context.Context, in *GetApsProjectListRequest, opts ...grpc.CallOption) (*GetApsProjectListResponse, error) {
+	out := new(GetApsProjectListResponse)
+	err := c.cc.Invoke(ctx, "/CrmAndApsGrpcService/GetApsProjectList", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *crmAndApsGrpcServiceClient) SendSalesDetailsToApsProject(ctx context.Context, in *SendSalesDetailsToApsProjectRequest, opts ...grpc.CallOption) (*SendSalesDetailsToApsProjectResponse, error) {
+	out := new(SendSalesDetailsToApsProjectResponse)
+	err := c.cc.Invoke(ctx, "/CrmAndApsGrpcService/SendSalesDetailsToApsProject", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// CrmAndApsGrpcServiceServer is the server API for CrmAndApsGrpcService service.
+// All implementations must embed UnimplementedCrmAndApsGrpcServiceServer
+// for forward compatibility
+type CrmAndApsGrpcServiceServer interface {
+	GetApsProjectList(context.Context, *GetApsProjectListRequest) (*GetApsProjectListResponse, error)
+	SendSalesDetailsToApsProject(context.Context, *SendSalesDetailsToApsProjectRequest) (*SendSalesDetailsToApsProjectResponse, error)
+	mustEmbedUnimplementedCrmAndApsGrpcServiceServer()
+}
+
+// UnimplementedCrmAndApsGrpcServiceServer must be embedded to have forward compatible implementations.
+type UnimplementedCrmAndApsGrpcServiceServer struct {
+}
+
+func (UnimplementedCrmAndApsGrpcServiceServer) GetApsProjectList(context.Context, *GetApsProjectListRequest) (*GetApsProjectListResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetApsProjectList not implemented")
+}
+func (UnimplementedCrmAndApsGrpcServiceServer) SendSalesDetailsToApsProject(context.Context, *SendSalesDetailsToApsProjectRequest) (*SendSalesDetailsToApsProjectResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method SendSalesDetailsToApsProject not implemented")
+}
+func (UnimplementedCrmAndApsGrpcServiceServer) mustEmbedUnimplementedCrmAndApsGrpcServiceServer() {}
+
+// UnsafeCrmAndApsGrpcServiceServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to CrmAndApsGrpcServiceServer will
+// result in compilation errors.
+type UnsafeCrmAndApsGrpcServiceServer interface {
+	mustEmbedUnimplementedCrmAndApsGrpcServiceServer()
+}
+
+func RegisterCrmAndApsGrpcServiceServer(s grpc.ServiceRegistrar, srv CrmAndApsGrpcServiceServer) {
+	s.RegisterService(&CrmAndApsGrpcService_ServiceDesc, srv)
+}
+
+func _CrmAndApsGrpcService_GetApsProjectList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GetApsProjectListRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(CrmAndApsGrpcServiceServer).GetApsProjectList(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/CrmAndApsGrpcService/GetApsProjectList",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(CrmAndApsGrpcServiceServer).GetApsProjectList(ctx, req.(*GetApsProjectListRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _CrmAndApsGrpcService_SendSalesDetailsToApsProject_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(SendSalesDetailsToApsProjectRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(CrmAndApsGrpcServiceServer).SendSalesDetailsToApsProject(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/CrmAndApsGrpcService/SendSalesDetailsToApsProject",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(CrmAndApsGrpcServiceServer).SendSalesDetailsToApsProject(ctx, req.(*SendSalesDetailsToApsProjectRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+// CrmAndApsGrpcService_ServiceDesc is the grpc.ServiceDesc for CrmAndApsGrpcService service.
+// It's only intended for direct use with grpc.RegisterService,
+// and not to be introspected or modified (even as a copy)
+var CrmAndApsGrpcService_ServiceDesc = grpc.ServiceDesc{
+	ServiceName: "CrmAndApsGrpcService",
+	HandlerType: (*CrmAndApsGrpcServiceServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "GetApsProjectList",
+			Handler:    _CrmAndApsGrpcService_GetApsProjectList_Handler,
+		},
+		{
+			MethodName: "SendSalesDetailsToApsProject",
+			Handler:    _CrmAndApsGrpcService_SendSalesDetailsToApsProject_Handler,
+		},
+	},
+	Streams:  []grpc.StreamDesc{},
+	Metadata: "crm_aps.proto",
+}
diff --git a/router/salesDetails.go b/router/salesDetails.go
index 3ce17bd..7da3a2d 100644
--- a/router/salesDetails.go
+++ b/router/salesDetails.go
@@ -11,13 +11,15 @@
 	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("updateStatus", salesDetailsApi.UpdateStatus)                              // 鏇存柊閿�鍞槑缁嗙姸鎬�
-		salesDetailsRouter.POST("list", salesDetailsApi.List)                                              // 鑾峰彇閿�鍞槑缁嗗崟鍒楄〃
-		salesDetailsRouter.GET("getProductInventoryInfo/:number", salesDetailsApi.GetProductInventoryInfo) // 鑾峰彇浜у搧搴撳瓨淇℃伅
-		salesDetailsRouter.POST("createOperation", salesDetailsApi.CreateOperation)                        // 鍒涘缓浜у搧鍑哄簱淇℃伅
+		salesDetailsRouter.POST("add", salesDetailsApi.Add)                                                   // 娣诲姞閿�鍞槑缁�
+		salesDetailsRouter.DELETE("delete/:id", salesDetailsApi.Delete)                                       // 鍒犻櫎閿�鍞槑缁�
+		salesDetailsRouter.DELETE("delete", salesDetailsApi.BatchDelete)                                      // 鎵归噺鍒犻櫎閿�鍞槑缁�
+		salesDetailsRouter.PUT("update", salesDetailsApi.Update)                                              // 鏇存柊閿�鍞槑缁�
+		salesDetailsRouter.POST("updateStatus", salesDetailsApi.UpdateStatus)                                 // 鏇存柊閿�鍞槑缁嗙姸鎬�
+		salesDetailsRouter.POST("list", salesDetailsApi.List)                                                 // 鑾峰彇閿�鍞槑缁嗗崟鍒楄〃
+		salesDetailsRouter.GET("getProductInventoryInfo/:number", salesDetailsApi.GetProductInventoryInfo)    // 鑾峰彇浜у搧搴撳瓨淇℃伅
+		salesDetailsRouter.POST("createOperation", salesDetailsApi.CreateOperation)                           // 鍒涘缓浜у搧鍑哄簱淇℃伅
+		salesDetailsRouter.GET("getApsProjectList", salesDetailsApi.GetApsProjectList)                        // 鑾峰彇aps椤圭洰鍒楄〃
+		salesDetailsRouter.POST("sendSalesDetailsToApsProject", salesDetailsApi.SendSalesDetailsToApsProject) // 鎺ㄩ�侀攢鍞槑缁嗕俊鎭埌aps椤圭洰妯″潡                    // 鍒涘缓浜у搧鍑哄簱淇℃伅
 	}
 }

--
Gitblit v1.8.0