From e5c9327d1b659cd6bf9c3adc3ae81146630511a0 Mon Sep 17 00:00:00 2001
From: zhangqian <zhangqian@123.com>
Date: 星期二, 29 八月 2023 14:51:21 +0800
Subject: [PATCH] Merge branch 'purchase'

---
 proto/quality_inspect.proto                     |   82 ++
 model/purchase/purchase.go                      |   30 
 model/purchase/request/purchase.go              |   21 
 initialize/rpc.go                               |   11 
 proto/qualityinspect/quality_inspect.pb.go      |  872 ++++++++++++++++++++++++
 docs/swagger.yaml                               |  163 ++++
 docs/docs.go                                    |  250 ++++++
 docs/swagger.json                               |  250 ++++++
 api/v1/purchase/purchase.go                     |   97 ++
 service/test/product.go                         |   13 
 model/purchase/purchase_type.go                 |   13 
 router/purchase/purchase.go                     |   14 
 proto/qualityinspect/quality_inspect_grpc.pb.go |  146 ++++
 main.go                                         |    2 
 proto/qualityinspect/client.go                  |   25 
 model/purchase/request/purchase_type.go         |   12 
 service/purchase/purchase.go                    |  128 ++
 17 files changed, 2,065 insertions(+), 64 deletions(-)

diff --git a/api/v1/purchase/purchase.go b/api/v1/purchase/purchase.go
index d68781c..68f16d9 100644
--- a/api/v1/purchase/purchase.go
+++ b/api/v1/purchase/purchase.go
@@ -2,12 +2,16 @@
 
 import (
 	"github.com/gin-gonic/gin"
+	"github.com/mitchellh/mapstructure"
 	"go.uber.org/zap"
+	"gorm.io/gorm"
 	"srm/global"
 	"srm/model/common/request"
 	"srm/model/common/response"
+	"srm/model/purchase"
 	purchaserequest "srm/model/purchase/request"
 	"strconv"
+	"strings"
 
 	//"srm/model/purchase"
 
@@ -35,8 +39,22 @@
 		response.FailWithMessage(err.Error(), c)
 		return
 	}
-	err = service.NewPurchaseService().CreatePurchase(params)
+
+	var purchaseRecord purchase.Purchase
+	if err := mapstructure.Decode(params.Purchase, &purchaseRecord); err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+
+	purchaseRecord.ID = 0
+	purchaseRecord.Status = purchase.OrderStatusConfirmed
+	err = service.NewPurchaseService().CreatePurchase(&purchaseRecord, params.ProductList)
+
 	if err != nil {
+		if err == gorm.ErrDuplicatedKey || strings.Contains(err.Error(), "Duplicate entry") {
+			response.FailWithMessage("缂栧彿閲嶅", c)
+			return
+		}
 		global.GVA_LOG.Error("鍒涘缓澶辫触!", zap.Error(err))
 		response.FailWithMessage("鍒涘缓澶辫触", c)
 		return
@@ -74,22 +92,24 @@
 // @Security  ApiKeyAuth
 // @accept    application/json
 // @Produce   application/json
-// @Param     data  body      purchaserequest.AddPurchase            true  "閲囪喘鍗旾D, 閲囪喘鍗曚俊鎭�"
+// @Param     data  body      purchaserequest.UpdatePurchase            true  "閲囪喘鍗旾D, 閲囪喘鍗曚俊鎭�"
 // @Success   200   {object}  response.Response{msg=string}  "鏇存柊閲囪喘鍗曚俊鎭�"
 // @Router    /purchase/purchase [put]
 func (e *PurchaseApi) UpdatePurchase(c *gin.Context) {
-	var params purchaserequest.AddPurchase
+	var params purchaserequest.UpdatePurchase
 	err := c.ShouldBindJSON(&params)
 	if err != nil {
 		response.FailWithMessage(err.Error(), c)
 		return
 	}
-	err = utils.Verify(params.Purchase.GVA_MODEL, utils.IdVerify)
-	if err != nil {
+
+	var purchaseRecord purchase.Purchase
+	if err := mapstructure.Decode(params.Purchase, &purchaseRecord); err != nil {
 		response.FailWithMessage(err.Error(), c)
 		return
 	}
-	err = service.NewPurchaseService().UpdatePurchase(&params)
+
+	err = service.NewPurchaseService().UpdatePurchase(&purchaseRecord, params.ProductList)
 	if err != nil {
 		global.GVA_LOG.Error("鏇存柊澶辫触!", zap.Error(err))
 		response.FailWithMessage("鏇存柊澶辫触", c)
@@ -173,18 +193,12 @@
 // @Success   200   {object}  response.Response{msg=string}  "鎻愪氦閲囪喘鍗�"
 // @Router    /purchase/submit/{id} [post]
 func (e *PurchaseApi) Submit(c *gin.Context) {
-	var params purchaserequest.AddPurchase
-	err := c.ShouldBindJSON(&params)
-	if err != nil {
-		response.FailWithMessage(err.Error(), c)
+	id, _ := strconv.Atoi(c.Param("id"))
+	if id == 0 {
+		response.FailWithMessage("鍙傛暟缂哄け", c)
 		return
 	}
-	err = utils.Verify(params.Purchase.GVA_MODEL, utils.IdVerify)
-	if err != nil {
-		response.FailWithMessage(err.Error(), c)
-		return
-	}
-	err = service.NewPurchaseService().UpdatePurchase(&params)
+	err := service.NewPurchaseService().Submit(uint(id))
 	if err != nil {
 		global.GVA_LOG.Error("鏇存柊澶辫触!", zap.Error(err))
 		response.FailWithMessage("鏇存柊澶辫触", c)
@@ -192,3 +206,54 @@
 	}
 	response.OkWithMessage("鏇存柊鎴愬姛", c)
 }
+
+// SavePurchaseType
+// @Tags      Purchase
+// @Summary   鍒涘缓閲囪喘绫诲瀷
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body     []purchaserequest.PurchaseType   true  "閲囪喘绫诲瀷list"
+// @Success   200   {object}  response.Response{msg=string}  "鍒涘缓閲囪喘绫诲瀷"
+// @Router    /purchase/purchaseType [post]
+func (e *PurchaseApi) SavePurchaseType(c *gin.Context) {
+	var params []*purchaserequest.PurchaseType
+	err := c.ShouldBindJSON(&params)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+
+	purchaseTypeList := make([]*purchase.PurchaseType, 0, len(params))
+	if err := mapstructure.Decode(params, &purchaseTypeList); err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+
+	err = service.NewPurchaseService().SavePurchaseType(purchaseTypeList)
+
+	if err != nil {
+		global.GVA_LOG.Error("鍒涘缓澶辫触!", zap.Error(err))
+		response.FailWithMessage("鍒涘缓澶辫触", c)
+		return
+	}
+	response.OkWithMessage("鍒涘缓鎴愬姛", c)
+}
+
+// GetPurchaseTypeList
+// @Tags      Purchase
+// @Summary   鑾峰彇閲囪喘绫诲瀷鍒楄〃
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Success   200   {object}  response.Response{data=[]purchase.PurchaseType,msg=string}  "鑾峰彇閲囪喘绫诲瀷鍒楄〃"
+// @Router    /purchase/purchaseTypeList [get]
+func (e *PurchaseApi) GetPurchaseTypeList(c *gin.Context) {
+	list, err := service.NewPurchaseService().GetPurchaseTypeList()
+	if err != nil {
+		global.GVA_LOG.Error("鑾峰彇澶辫触!", zap.Error(err))
+		response.FailWithMessage("鑾峰彇澶辫触"+err.Error(), c)
+		return
+	}
+	response.OkWithDetailed(list, "鑾峰彇鎴愬姛", c)
+}
diff --git a/docs/docs.go b/docs/docs.go
index 064a083..92af44b 100644
--- a/docs/docs.go
+++ b/docs/docs.go
@@ -4586,7 +4586,7 @@
                         "in": "body",
                         "required": true,
                         "schema": {
-                            "$ref": "#/definitions/purchaserequest.AddPurchase"
+                            "$ref": "#/definitions/purchaserequest.UpdatePurchase"
                         }
                     }
                 ],
@@ -4807,6 +4807,104 @@
                                     "properties": {
                                         "data": {
                                             "$ref": "#/definitions/response.PageResult"
+                                        },
+                                        "msg": {
+                                            "type": "string"
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                }
+            }
+        },
+        "/purchase/purchaseType": {
+            "post": {
+                "security": [
+                    {
+                        "ApiKeyAuth": []
+                    }
+                ],
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "Purchase"
+                ],
+                "summary": "鍒涘缓閲囪喘绫诲瀷",
+                "parameters": [
+                    {
+                        "description": "閲囪喘绫诲瀷list",
+                        "name": "data",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "type": "array",
+                            "items": {
+                                "$ref": "#/definitions/purchaserequest.PurchaseType"
+                            }
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "鍒涘缓閲囪喘绫诲瀷",
+                        "schema": {
+                            "allOf": [
+                                {
+                                    "$ref": "#/definitions/response.Response"
+                                },
+                                {
+                                    "type": "object",
+                                    "properties": {
+                                        "msg": {
+                                            "type": "string"
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                }
+            }
+        },
+        "/purchase/purchaseTypeList": {
+            "get": {
+                "security": [
+                    {
+                        "ApiKeyAuth": []
+                    }
+                ],
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "Purchase"
+                ],
+                "summary": "鑾峰彇閲囪喘绫诲瀷鍒楄〃",
+                "responses": {
+                    "200": {
+                        "description": "鑾峰彇閲囪喘绫诲瀷鍒楄〃",
+                        "schema": {
+                            "allOf": [
+                                {
+                                    "$ref": "#/definitions/response.Response"
+                                },
+                                {
+                                    "type": "object",
+                                    "properties": {
+                                        "data": {
+                                            "type": "array",
+                                            "items": {
+                                                "$ref": "#/definitions/purchase.PurchaseType"
+                                            }
                                         },
                                         "msg": {
                                             "type": "string"
@@ -8295,6 +8393,27 @@
                 }
             }
         },
+        "purchase.OrderStatus": {
+            "type": "integer",
+            "enum": [
+                1,
+                2,
+                3,
+                4
+            ],
+            "x-enum-comments": {
+                "OrderStatusCompleted": "宸插畬鎴�",
+                "OrderStatusConfirmed": "宸蹭笅鍗�",
+                "OrderStatusReceived": "宸插埌璐�",
+                "OrderStatusStored": "宸插叆搴�"
+            },
+            "x-enum-varnames": [
+                "OrderStatusConfirmed",
+                "OrderStatusReceived",
+                "OrderStatusStored",
+                "OrderStatusCompleted"
+            ]
+        },
         "purchase.Purchase": {
             "type": "object",
             "properties": {
@@ -8318,9 +8437,16 @@
                     "description": "閲囪喘鍚嶇О",
                     "type": "string"
                 },
+                "number": {
+                    "description": "閲囪喘缂栧彿",
+                    "type": "string"
+                },
                 "phone": {
                     "description": "鑱旂郴浜虹數璇�",
                     "type": "string"
+                },
+                "purchaseType": {
+                    "$ref": "#/definitions/purchase.PurchaseType"
                 },
                 "purchaseTypeId": {
                     "description": "閲囪喘绫诲瀷id",
@@ -8333,6 +8459,17 @@
                 "signingDate": {
                     "description": "绛剧害鏃ユ湡",
                     "type": "string"
+                },
+                "status": {
+                    "description": "鐘舵��",
+                    "allOf": [
+                        {
+                            "$ref": "#/definitions/purchase.OrderStatus"
+                        }
+                    ]
+                },
+                "supplier": {
+                    "$ref": "#/definitions/test.Supplier"
                 },
                 "supplierId": {
                     "description": "渚涘簲鍟唅d",
@@ -8377,6 +8514,27 @@
                 }
             }
         },
+        "purchase.PurchaseType": {
+            "type": "object",
+            "properties": {
+                "id": {
+                    "description": "涓婚敭ID",
+                    "type": "integer"
+                },
+                "name": {
+                    "description": "閲囪喘绫诲瀷",
+                    "type": "string"
+                },
+                "pin": {
+                    "description": "鏄惁缃《",
+                    "type": "boolean"
+                },
+                "sort": {
+                    "description": "鎺掑簭",
+                    "type": "integer"
+                }
+            }
+        },
         "purchaserequest.AddPurchase": {
             "type": "object",
             "properties": {
@@ -8387,7 +8545,95 @@
                     }
                 },
                 "purchase": {
-                    "$ref": "#/definitions/purchase.Purchase"
+                    "$ref": "#/definitions/purchaserequest.Purchase"
+                }
+            }
+        },
+        "purchaserequest.Purchase": {
+            "type": "object",
+            "properties": {
+                "contact": {
+                    "description": "鑱旂郴浜�",
+                    "type": "string"
+                },
+                "deliveryDate": {
+                    "description": "浜や粯鏃ユ湡",
+                    "type": "string"
+                },
+                "id": {
+                    "description": "涓婚敭ID",
+                    "type": "integer"
+                },
+                "name": {
+                    "description": "閲囪喘鍚嶇О",
+                    "type": "string"
+                },
+                "number": {
+                    "description": "閲囪喘缂栧彿",
+                    "type": "string"
+                },
+                "phone": {
+                    "description": "鑱旂郴浜虹數璇�",
+                    "type": "string"
+                },
+                "purchaseTypeId": {
+                    "description": "閲囪喘绫诲瀷id",
+                    "type": "integer"
+                },
+                "remark": {
+                    "description": "澶囨敞",
+                    "type": "string"
+                },
+                "signingDate": {
+                    "description": "绛剧害鏃ユ湡",
+                    "type": "string"
+                },
+                "status": {
+                    "description": "鐘舵��",
+                    "allOf": [
+                        {
+                            "$ref": "#/definitions/purchase.OrderStatus"
+                        }
+                    ]
+                },
+                "supplierId": {
+                    "description": "渚涘簲鍟唅d",
+                    "type": "integer"
+                }
+            }
+        },
+        "purchaserequest.PurchaseType": {
+            "type": "object",
+            "properties": {
+                "id": {
+                    "description": "涓婚敭ID",
+                    "type": "integer"
+                },
+                "name": {
+                    "description": "閲囪喘绫诲瀷",
+                    "type": "string"
+                },
+                "pin": {
+                    "description": "鏄惁缃《",
+                    "type": "boolean"
+                },
+                "sort": {
+                    "description": "鎺掑簭",
+                    "type": "integer"
+                }
+            }
+        },
+        "purchaserequest.UpdatePurchase": {
+            "type": "object",
+            "properties": {
+                "productList": {
+                    "type": "array",
+                    "items": {
+                        "$ref": "#/definitions/purchase.PurchaseProducts"
+                    }
+                },
+                "purchase": {
+                    "$ref": "#/definitions/purchaserequest.Purchase"
                 }
             }
         },
diff --git a/docs/swagger.json b/docs/swagger.json
index cdd6ea3..864a908 100644
--- a/docs/swagger.json
+++ b/docs/swagger.json
@@ -4577,7 +4577,7 @@
                         "in": "body",
                         "required": true,
                         "schema": {
-                            "$ref": "#/definitions/purchaserequest.AddPurchase"
+                            "$ref": "#/definitions/purchaserequest.UpdatePurchase"
                         }
                     }
                 ],
@@ -4798,6 +4798,104 @@
                                     "properties": {
                                         "data": {
                                             "$ref": "#/definitions/response.PageResult"
+                                        },
+                                        "msg": {
+                                            "type": "string"
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                }
+            }
+        },
+        "/purchase/purchaseType": {
+            "post": {
+                "security": [
+                    {
+                        "ApiKeyAuth": []
+                    }
+                ],
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "Purchase"
+                ],
+                "summary": "鍒涘缓閲囪喘绫诲瀷",
+                "parameters": [
+                    {
+                        "description": "閲囪喘绫诲瀷list",
+                        "name": "data",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "type": "array",
+                            "items": {
+                                "$ref": "#/definitions/purchaserequest.PurchaseType"
+                            }
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "鍒涘缓閲囪喘绫诲瀷",
+                        "schema": {
+                            "allOf": [
+                                {
+                                    "$ref": "#/definitions/response.Response"
+                                },
+                                {
+                                    "type": "object",
+                                    "properties": {
+                                        "msg": {
+                                            "type": "string"
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                }
+            }
+        },
+        "/purchase/purchaseTypeList": {
+            "get": {
+                "security": [
+                    {
+                        "ApiKeyAuth": []
+                    }
+                ],
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "Purchase"
+                ],
+                "summary": "鑾峰彇閲囪喘绫诲瀷鍒楄〃",
+                "responses": {
+                    "200": {
+                        "description": "鑾峰彇閲囪喘绫诲瀷鍒楄〃",
+                        "schema": {
+                            "allOf": [
+                                {
+                                    "$ref": "#/definitions/response.Response"
+                                },
+                                {
+                                    "type": "object",
+                                    "properties": {
+                                        "data": {
+                                            "type": "array",
+                                            "items": {
+                                                "$ref": "#/definitions/purchase.PurchaseType"
+                                            }
                                         },
                                         "msg": {
                                             "type": "string"
@@ -8286,6 +8384,27 @@
                 }
             }
         },
+        "purchase.OrderStatus": {
+            "type": "integer",
+            "enum": [
+                1,
+                2,
+                3,
+                4
+            ],
+            "x-enum-comments": {
+                "OrderStatusCompleted": "宸插畬鎴�",
+                "OrderStatusConfirmed": "宸蹭笅鍗�",
+                "OrderStatusReceived": "宸插埌璐�",
+                "OrderStatusStored": "宸插叆搴�"
+            },
+            "x-enum-varnames": [
+                "OrderStatusConfirmed",
+                "OrderStatusReceived",
+                "OrderStatusStored",
+                "OrderStatusCompleted"
+            ]
+        },
         "purchase.Purchase": {
             "type": "object",
             "properties": {
@@ -8309,9 +8428,16 @@
                     "description": "閲囪喘鍚嶇О",
                     "type": "string"
                 },
+                "number": {
+                    "description": "閲囪喘缂栧彿",
+                    "type": "string"
+                },
                 "phone": {
                     "description": "鑱旂郴浜虹數璇�",
                     "type": "string"
+                },
+                "purchaseType": {
+                    "$ref": "#/definitions/purchase.PurchaseType"
                 },
                 "purchaseTypeId": {
                     "description": "閲囪喘绫诲瀷id",
@@ -8324,6 +8450,17 @@
                 "signingDate": {
                     "description": "绛剧害鏃ユ湡",
                     "type": "string"
+                },
+                "status": {
+                    "description": "鐘舵��",
+                    "allOf": [
+                        {
+                            "$ref": "#/definitions/purchase.OrderStatus"
+                        }
+                    ]
+                },
+                "supplier": {
+                    "$ref": "#/definitions/test.Supplier"
                 },
                 "supplierId": {
                     "description": "渚涘簲鍟唅d",
@@ -8368,6 +8505,27 @@
                 }
             }
         },
+        "purchase.PurchaseType": {
+            "type": "object",
+            "properties": {
+                "id": {
+                    "description": "涓婚敭ID",
+                    "type": "integer"
+                },
+                "name": {
+                    "description": "閲囪喘绫诲瀷",
+                    "type": "string"
+                },
+                "pin": {
+                    "description": "鏄惁缃《",
+                    "type": "boolean"
+                },
+                "sort": {
+                    "description": "鎺掑簭",
+                    "type": "integer"
+                }
+            }
+        },
         "purchaserequest.AddPurchase": {
             "type": "object",
             "properties": {
@@ -8378,7 +8536,95 @@
                     }
                 },
                 "purchase": {
-                    "$ref": "#/definitions/purchase.Purchase"
+                    "$ref": "#/definitions/purchaserequest.Purchase"
+                }
+            }
+        },
+        "purchaserequest.Purchase": {
+            "type": "object",
+            "properties": {
+                "contact": {
+                    "description": "鑱旂郴浜�",
+                    "type": "string"
+                },
+                "deliveryDate": {
+                    "description": "浜や粯鏃ユ湡",
+                    "type": "string"
+                },
+                "id": {
+                    "description": "涓婚敭ID",
+                    "type": "integer"
+                },
+                "name": {
+                    "description": "閲囪喘鍚嶇О",
+                    "type": "string"
+                },
+                "number": {
+                    "description": "閲囪喘缂栧彿",
+                    "type": "string"
+                },
+                "phone": {
+                    "description": "鑱旂郴浜虹數璇�",
+                    "type": "string"
+                },
+                "purchaseTypeId": {
+                    "description": "閲囪喘绫诲瀷id",
+                    "type": "integer"
+                },
+                "remark": {
+                    "description": "澶囨敞",
+                    "type": "string"
+                },
+                "signingDate": {
+                    "description": "绛剧害鏃ユ湡",
+                    "type": "string"
+                },
+                "status": {
+                    "description": "鐘舵��",
+                    "allOf": [
+                        {
+                            "$ref": "#/definitions/purchase.OrderStatus"
+                        }
+                    ]
+                },
+                "supplierId": {
+                    "description": "渚涘簲鍟唅d",
+                    "type": "integer"
+                }
+            }
+        },
+        "purchaserequest.PurchaseType": {
+            "type": "object",
+            "properties": {
+                "id": {
+                    "description": "涓婚敭ID",
+                    "type": "integer"
+                },
+                "name": {
+                    "description": "閲囪喘绫诲瀷",
+                    "type": "string"
+                },
+                "pin": {
+                    "description": "鏄惁缃《",
+                    "type": "boolean"
+                },
+                "sort": {
+                    "description": "鎺掑簭",
+                    "type": "integer"
+                }
+            }
+        },
+        "purchaserequest.UpdatePurchase": {
+            "type": "object",
+            "properties": {
+                "productList": {
+                    "type": "array",
+                    "items": {
+                        "$ref": "#/definitions/purchase.PurchaseProducts"
+                    }
+                },
+                "purchase": {
+                    "$ref": "#/definitions/purchaserequest.Purchase"
                 }
             }
         },
diff --git a/docs/swagger.yaml b/docs/swagger.yaml
index e4d4b7f..6547ff2 100644
--- a/docs/swagger.yaml
+++ b/docs/swagger.yaml
@@ -677,6 +677,23 @@
         description: 鏂囦欢鍦板潃
         type: string
     type: object
+  purchase.OrderStatus:
+    enum:
+    - 1
+    - 2
+    - 3
+    - 4
+    type: integer
+    x-enum-comments:
+      OrderStatusCompleted: 宸插畬鎴�
+      OrderStatusConfirmed: 宸蹭笅鍗�
+      OrderStatusReceived: 宸插埌璐�
+      OrderStatusStored: 宸插叆搴�
+    x-enum-varnames:
+    - OrderStatusConfirmed
+    - OrderStatusReceived
+    - OrderStatusStored
+    - OrderStatusCompleted
   purchase.Purchase:
     properties:
       contact:
@@ -694,9 +711,14 @@
       name:
         description: 閲囪喘鍚嶇О
         type: string
+      number:
+        description: 閲囪喘缂栧彿
+        type: string
       phone:
         description: 鑱旂郴浜虹數璇�
         type: string
+      purchaseType:
+        $ref: '#/definitions/purchase.PurchaseType'
       purchaseTypeId:
         description: 閲囪喘绫诲瀷id
         type: integer
@@ -706,6 +728,12 @@
       signingDate:
         description: 绛剧害鏃ユ湡
         type: string
+      status:
+        allOf:
+        - $ref: '#/definitions/purchase.OrderStatus'
+        description: 鐘舵��
+      supplier:
+        $ref: '#/definitions/test.Supplier'
       supplierId:
         description: 渚涘簲鍟唅d
         type: integer
@@ -737,6 +765,21 @@
         description: 閲囪喘鎬讳环
         type: number
     type: object
+  purchase.PurchaseType:
+    properties:
+      id:
+        description: 涓婚敭ID
+        type: integer
+      name:
+        description: 閲囪喘绫诲瀷
+        type: string
+      pin:
+        description: 鏄惁缃《
+        type: boolean
+      sort:
+        description: 鎺掑簭
+        type: integer
+    type: object
   purchaserequest.AddPurchase:
     properties:
       productList:
@@ -744,7 +787,68 @@
           $ref: '#/definitions/purchase.PurchaseProducts'
         type: array
       purchase:
-        $ref: '#/definitions/purchase.Purchase'
+        $ref: '#/definitions/purchaserequest.Purchase'
+    type: object
+  purchaserequest.Purchase:
+    properties:
+      contact:
+        description: 鑱旂郴浜�
+        type: string
+      deliveryDate:
+        description: 浜や粯鏃ユ湡
+        type: string
+      id:
+        description: 涓婚敭ID
+        type: integer
+      name:
+        description: 閲囪喘鍚嶇О
+        type: string
+      number:
+        description: 閲囪喘缂栧彿
+        type: string
+      phone:
+        description: 鑱旂郴浜虹數璇�
+        type: string
+      purchaseTypeId:
+        description: 閲囪喘绫诲瀷id
+        type: integer
+      remark:
+        description: 澶囨敞
+        type: string
+      signingDate:
+        description: 绛剧害鏃ユ湡
+        type: string
+      status:
+        allOf:
+        - $ref: '#/definitions/purchase.OrderStatus'
+        description: 鐘舵��
+      supplierId:
+        description: 渚涘簲鍟唅d
+        type: integer
+    type: object
+  purchaserequest.PurchaseType:
+    properties:
+      id:
+        description: 涓婚敭ID
+        type: integer
+      name:
+        description: 閲囪喘绫诲瀷
+        type: string
+      pin:
+        description: 鏄惁缃《
+        type: boolean
+      sort:
+        description: 鎺掑簭
+        type: integer
+    type: object
+  purchaserequest.UpdatePurchase:
+    properties:
+      productList:
+        items:
+          $ref: '#/definitions/purchase.PurchaseProducts'
+        type: array
+      purchase:
+        $ref: '#/definitions/purchaserequest.Purchase'
     type: object
   request.AddMenuAuthorityInfo:
     properties:
@@ -4436,7 +4540,7 @@
         name: data
         required: true
         schema:
-          $ref: '#/definitions/purchaserequest.AddPurchase'
+          $ref: '#/definitions/purchaserequest.UpdatePurchase'
       produces:
       - application/json
       responses:
@@ -4545,6 +4649,61 @@
       summary: 鍒嗛〉鑾峰彇閲囪喘鍗曞垪琛�
       tags:
       - Purchase
+  /purchase/purchaseType:
+    post:
+      consumes:
+      - application/json
+      parameters:
+      - description: 閲囪喘绫诲瀷list
+        in: body
+        name: data
+        required: true
+        schema:
+          items:
+            $ref: '#/definitions/purchaserequest.PurchaseType'
+          type: array
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: 鍒涘缓閲囪喘绫诲瀷
+          schema:
+            allOf:
+            - $ref: '#/definitions/response.Response'
+            - properties:
+                msg:
+                  type: string
+              type: object
+      security:
+      - ApiKeyAuth: []
+      summary: 鍒涘缓閲囪喘绫诲瀷
+      tags:
+      - Purchase
+  /purchase/purchaseTypeList:
+    get:
+      consumes:
+      - application/json
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: 鑾峰彇閲囪喘绫诲瀷鍒楄〃
+          schema:
+            allOf:
+            - $ref: '#/definitions/response.Response'
+            - properties:
+                data:
+                  items:
+                    $ref: '#/definitions/purchase.PurchaseType'
+                  type: array
+                msg:
+                  type: string
+              type: object
+      security:
+      - ApiKeyAuth: []
+      summary: 鑾峰彇閲囪喘绫诲瀷鍒楄〃
+      tags:
+      - Purchase
   /purchase/submit/{id}:
     post:
       consumes:
diff --git a/initialize/rpc.go b/initialize/rpc.go
new file mode 100644
index 0000000..02e2611
--- /dev/null
+++ b/initialize/rpc.go
@@ -0,0 +1,11 @@
+package initialize
+
+import "srm/proto/qualityinspect"
+
+func InitRpcClient() {
+	qualityinspect.InitConn()
+}
+
+func CloseRpcClient() {
+	qualityinspect.CloseConn()
+}
diff --git a/main.go b/main.go
index 266e282..40c86a2 100644
--- a/main.go
+++ b/main.go
@@ -37,6 +37,8 @@
 	}
 
 	go test.InitProductServiceConn()
+	initialize.InitRpcClient()
+	defer initialize.CloseRpcClient()
 
 	core.RunWindowsServer()
 }
diff --git a/model/purchase/purchase.go b/model/purchase/purchase.go
index 2c08f7f..0163640 100644
--- a/model/purchase/purchase.go
+++ b/model/purchase/purchase.go
@@ -2,26 +2,30 @@
 
 import (
 	"srm/global"
+	"srm/model/test"
 )
 
 type Purchase struct {
 	global.GVA_MODEL
-	PurchaseTypeId int    `json:"purchaseTypeId" form:"purchaseType" gorm:"type:int(11);not null;default 0;comment:閲囪喘绫诲瀷id"`   // 閲囪喘绫诲瀷id
-	SupplierId     int    `json:"supplierId" form:"supplierId" gorm:"type:int(11);not null;default 0;comment:渚涘簲鍟唅d"`          // 渚涘簲鍟唅d
-	Name           string `json:"name" form:"name" gorm:"type:varchar(255);not null;default '';comment:閲囪喘鍚嶇О"`                 // 閲囪喘鍚嶇О
-	Contact        string `json:"contact" form:"contact" gorm:"type:varchar(255);not null;default '';comment:鑱旂郴浜�"`            // 鑱旂郴浜�
-	Phone          string `json:"phone" form:"phone" gorm:"type:varchar(255);not null;default '';comment:鑱旂郴浜虹數璇�"`              // 鑱旂郴浜虹數璇�
-	SigningDate    string `json:"signingDate" form:"signingDate" gorm:"type:varchar(255);not null;default '';comment:绛剧害鏃ユ湡"`   // 绛剧害鏃ユ湡
-	DeliveryDate   string `json:"deliveryDate" form:"deliveryDate" gorm:"type:varchar(255);not null;default '';comment:浜や粯鏃ユ湡"` //浜や粯鏃ユ湡
-	Remark         string `json:"remark" form:"remark" gorm:"type:varchar(1000);not null;default '';comment:澶囨敞"`              //澶囨敞
-	Status         string `json:"remark" form:"remark" gorm:"type:varchar(1000);not null;default '';comment:澶囨敞"`              //澶囨敞
+	PurchaseTypeId int           `json:"purchaseTypeId" form:"purchaseType" gorm:"type:int(11);not null;default 0;comment:閲囪喘绫诲瀷id"` // 閲囪喘绫诲瀷id
+	PurchaseType   PurchaseType  `json:"purchaseType" gorm:"foreignKey:PurchaseTypeId"`
+	SupplierId     int           `json:"supplierId" form:"supplierId" gorm:"type:int(11);not null;default 0;comment:渚涘簲鍟唅d"` // 渚涘簲鍟唅d
+	Supplier       test.Supplier `json:"supplier" gorm:"foreignKey:SupplierId"`
+	Number         string        `json:"number" form:"number" gorm:"unique;type:varchar(255);not null;default '';comment:閲囪喘缂栧彿"`      // 閲囪喘缂栧彿
+	Name           string        `json:"name" form:"name" gorm:"type:varchar(255);not null;default '';comment:閲囪喘鍚嶇О"`                 // 閲囪喘鍚嶇О
+	Contact        string        `json:"contact" form:"contact" gorm:"type:varchar(255);not null;default '';comment:鑱旂郴浜�"`            // 鑱旂郴浜�
+	Phone          string        `json:"phone" form:"phone" gorm:"type:varchar(255);not null;default '';comment:鑱旂郴浜虹數璇�"`              // 鑱旂郴浜虹數璇�
+	SigningDate    string        `json:"signingDate" form:"signingDate" gorm:"type:varchar(255);not null;default '';comment:绛剧害鏃ユ湡"`   // 绛剧害鏃ユ湡
+	DeliveryDate   string        `json:"deliveryDate" form:"deliveryDate" gorm:"type:varchar(255);not null;default '';comment:浜や粯鏃ユ湡"` //浜や粯鏃ユ湡
+	Remark         string        `json:"remark" form:"remark" gorm:"type:varchar(1000);not null;default '';comment:澶囨敞"`              //澶囨敞
+	Status         OrderStatus   `json:"status" form:"status" gorm:"type:tinyint(1);not null;default 0;comment:鐘舵��"`                  //鐘舵��
 }
 
 type OrderStatus int
 
 const (
-// PurchaseOrderStatusConfirmed OrderStatus = 1 //宸蹭笅鍗�
-// PurchaseOrderStatusReceived  OrderStatus = 2 //宸插埌璐�
-// PurchaseOrderStatus          OrderStatus = 3 //宸插叆搴�
-// PurchaseOrderStatusReceived  OrderStatus = 4 //宸插畬鎴�
+	OrderStatusConfirmed OrderStatus = 1 //宸蹭笅鍗�
+	OrderStatusReceived  OrderStatus = 2 //宸插埌璐�
+	OrderStatusStored    OrderStatus = 3 //宸插叆搴�
+	OrderStatusCompleted OrderStatus = 4 //宸插畬鎴�
 )
diff --git a/model/purchase/purchase_type.go b/model/purchase/purchase_type.go
new file mode 100644
index 0000000..4803067
--- /dev/null
+++ b/model/purchase/purchase_type.go
@@ -0,0 +1,13 @@
+package purchase
+
+import (
+	"srm/global"
+)
+
+type PurchaseType struct {
+	global.GVA_MODEL
+	ID   uint   `gorm:"primarykey"`                                                                 // 涓婚敭ID
+	Name string `json:"name" form:"name" gorm:"type:varchar(255);not null;default '';comment:閲囪喘绫诲瀷"` // 閲囪喘绫诲瀷
+	Sort int    `json:"sort" form:"sort" gorm:"type:int(11);not null;default 0;comment:鎺掑簭"`         // 鎺掑簭
+	Pin  bool   `json:"pin" form:"pin" gorm:"type:tinyint(1);not null;default 0;comment:閲囪喘鍚嶇О"`      // 鏄惁缃《
+}
diff --git a/model/purchase/request/purchase.go b/model/purchase/request/purchase.go
index d0dad8c..a99c0b8 100644
--- a/model/purchase/request/purchase.go
+++ b/model/purchase/request/purchase.go
@@ -13,6 +13,25 @@
 }
 
 type AddPurchase struct {
-	Purchase    purchase.Purchase
+	Purchase    Purchase                     `json:"purchase"`
 	ProductList []*purchase.PurchaseProducts `json:"productList"`
 }
+
+type UpdatePurchase struct {
+	Purchase    Purchase                     `json:"purchase"`
+	ProductList []*purchase.PurchaseProducts `json:"productList"`
+}
+
+type Purchase struct {
+	ID             uint                 `gorm:"primarykey"`                                                                                 // 涓婚敭ID
+	PurchaseTypeId int                  `json:"purchaseTypeId" form:"purchaseType" gorm:"type:int(11);not null;default 0;comment:閲囪喘绫诲瀷id"`   // 閲囪喘绫诲瀷id
+	SupplierId     int                  `json:"supplierId" form:"supplierId" gorm:"type:int(11);not null;default 0;comment:渚涘簲鍟唅d"`          // 渚涘簲鍟唅d
+	Number         string               `json:"number" form:"number" gorm:"unique;type:varchar(255);not null;default '';comment:閲囪喘缂栧彿"`      // 閲囪喘缂栧彿
+	Name           string               `json:"name" form:"name" gorm:"type:varchar(255);not null;default '';comment:閲囪喘鍚嶇О"`                 // 閲囪喘鍚嶇О
+	Contact        string               `json:"contact" form:"contact" gorm:"type:varchar(255);not null;default '';comment:鑱旂郴浜�"`            // 鑱旂郴浜�
+	Phone          string               `json:"phone" form:"phone" gorm:"type:varchar(255);not null;default '';comment:鑱旂郴浜虹數璇�"`              // 鑱旂郴浜虹數璇�
+	SigningDate    string               `json:"signingDate" form:"signingDate" gorm:"type:varchar(255);not null;default '';comment:绛剧害鏃ユ湡"`   // 绛剧害鏃ユ湡
+	DeliveryDate   string               `json:"deliveryDate" form:"deliveryDate" gorm:"type:varchar(255);not null;default '';comment:浜や粯鏃ユ湡"` //浜や粯鏃ユ湡
+	Remark         string               `json:"remark" form:"remark" gorm:"type:varchar(1000);not null;default '';comment:澶囨敞"`              //澶囨敞
+	Status         purchase.OrderStatus `json:"status" form:"status" gorm:"type:tinyint(1);not null;default 0;comment:鐘舵��"`                  //鐘舵��
+}
diff --git a/model/purchase/request/purchase_type.go b/model/purchase/request/purchase_type.go
new file mode 100644
index 0000000..26956c6
--- /dev/null
+++ b/model/purchase/request/purchase_type.go
@@ -0,0 +1,12 @@
+package purchaserequest
+
+type SavePurchaseType struct {
+	List []*PurchaseType `json:"purchase"`
+}
+
+type PurchaseType struct {
+	ID   uint   `gorm:"primarykey"`                                                                 // 涓婚敭ID
+	Name string `json:"name" form:"name" gorm:"type:varchar(255);not null;default '';comment:閲囪喘绫诲瀷"` // 閲囪喘绫诲瀷
+	Sort int    `json:"sort" form:"sort" gorm:"type:int(11);not null;default 0;comment:鎺掑簭"`         // 鎺掑簭
+	Pin  bool   `json:"pin" form:"pin" gorm:"type:tinyint(1);not null;default 0;comment:閲囪喘鍚嶇О"`      // 鏄惁缃《
+}
diff --git a/proto/quality_inspect.proto b/proto/quality_inspect.proto
new file mode 100644
index 0000000..3d8c695
--- /dev/null
+++ b/proto/quality_inspect.proto
@@ -0,0 +1,82 @@
+syntax = "proto3";
+
+option go_package = "./qualityinspect";
+
+service QualityInspectService {
+  rpc SendPurchaseInspect(SendPurchaseInspectRequest) returns(SendPurchaseInspectResponse) {}
+  rpc GetInspectList(GetInspectListRequest) returns(GetInspectListResponse) {}
+}
+message SendPurchaseInspectRequest {
+  repeated QualityInspect list = 1;
+}
+
+message QualityInspect {
+  string id = 1; //妫�楠屽崟id
+  InspectType inspect_type = 2; // 妫�楠岀被鍨�
+  string send_inspector_id = 3; // 閫佹鍛業D
+  MaterialType material_type = 4; // 鐗╂枡绫诲瀷(鏁板瓧)
+  string material_name = 5; // 鐗╂枡鍚嶇О
+  string material_id = 6; // 鐗╂枡缂栫爜
+  string material_tp = 7; // 鐗╂枡鍨嬪彿
+  string material_unit = 8; // 鐗╂枡鍗曚綅
+  string supplier = 9; // 渚涘簲鍟�
+  string batch_id = 10; // 鎵瑰彿
+  string warehouse_name = 11; // 鏀舵枡浠撳簱
+  string warehouse_pos = 12; // 浠撲綅
+  double report_amount = 13; // 鎶ユ鏁伴噺
+  InspectMethod inspect_method = 14; // 妫�楠屾柟寮�
+  double inspect_amount = 15; // 妫�楠屾暟閲�
+  int32 status = 16; // 鐘舵��
+  string submit_id = 17; // 鎻愪氦浜篒D
+  double reject_amount = 18; // 閫�璐ф暟閲�
+  double exchange_amount = 19; // 鎹㈣揣鏁伴噺
+  double repair_amount = 20; // 濮斿淇暟閲�
+  int32 inspect_delete = 21; // 璐ㄩ噺妫�楠屽垹闄� 1-鏈垹闄� 2-宸插垹闄�
+  string purchase_order_id = 22; // 閲囪喘鍗曞彿
+
+}
+
+enum InspectType
+{
+  DefaultInspectType = 0;
+  InspectTypeIncome    = 1;  // 鏉ユ枡妫�楠�
+  InspectTypePurchase  = 2;  // 閲囪喘璐ㄦ
+  InspectTypeOutsource = 3;  // 濮斿妫�楠�
+  InspectTypeReject    = 4;  // 瀹㈡埛閫�璐ф楠�
+}
+
+enum MaterialType {
+  DefaultMaterialType = 0;
+  MaterialTypeRaw      =  1; // 鍘熸潗鏂�
+  MaterialTypeSemi     =2;           // 鍗婃垚鍝�
+  MaterialTypeFinished   =3;         // 鎴愬搧
+}
+
+enum InspectMethod
+{
+  DefaultInspectMethod = 0;
+  InspectMethodAll  = 1; // 鍏ㄦ
+  InspectMethodSpot = 2; //鎶芥
+}
+
+
+
+message SendPurchaseInspectResponse {
+  int32   Code  = 1;
+  string  Msg   = 2;
+}
+
+
+message GetInspectListRequest{
+  int32 page = 1;
+  int32 pageSize = 2;
+  string keyword = 3;
+}
+
+message GetInspectListResponse{
+  int32   Code  = 1;
+  string  Msg   = 2;
+  repeated QualityInspect List = 3;
+  int64 Total = 4;
+}
+
diff --git a/proto/qualityinspect/client.go b/proto/qualityinspect/client.go
new file mode 100644
index 0000000..25f2e2e
--- /dev/null
+++ b/proto/qualityinspect/client.go
@@ -0,0 +1,25 @@
+package qualityinspect
+
+import (
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/credentials/insecure"
+	"srm/global"
+)
+
+var (
+	Conn *grpc.ClientConn
+)
+
+func InitConn() {
+	var err error
+	Conn, err = grpc.Dial(global.GVA_CONFIG.System.GrpcUrl, grpc.WithTransportCredentials(insecure.NewCredentials()))
+	if err != nil {
+		return
+	}
+}
+
+func CloseConn() {
+	if Conn != nil {
+		Conn.Close()
+	}
+}
diff --git a/proto/qualityinspect/quality_inspect.pb.go b/proto/qualityinspect/quality_inspect.pb.go
new file mode 100644
index 0000000..7d05402
--- /dev/null
+++ b/proto/qualityinspect/quality_inspect.pb.go
@@ -0,0 +1,872 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.31.0
+// 	protoc        v3.19.0
+// source: quality_inspect.proto
+
+package qualityinspect
+
+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 InspectType int32
+
+const (
+	InspectType_DefaultInspectType   InspectType = 0
+	InspectType_InspectTypeIncome    InspectType = 1 // 鏉ユ枡妫�楠�
+	InspectType_InspectTypePurchase  InspectType = 2 // 閲囪喘璐ㄦ
+	InspectType_InspectTypeOutsource InspectType = 3 // 濮斿妫�楠�
+	InspectType_InspectTypeReject    InspectType = 4 // 瀹㈡埛閫�璐ф楠�
+)
+
+// Enum value maps for InspectType.
+var (
+	InspectType_name = map[int32]string{
+		0: "DefaultInspectType",
+		1: "InspectTypeIncome",
+		2: "InspectTypePurchase",
+		3: "InspectTypeOutsource",
+		4: "InspectTypeReject",
+	}
+	InspectType_value = map[string]int32{
+		"DefaultInspectType":   0,
+		"InspectTypeIncome":    1,
+		"InspectTypePurchase":  2,
+		"InspectTypeOutsource": 3,
+		"InspectTypeReject":    4,
+	}
+)
+
+func (x InspectType) Enum() *InspectType {
+	p := new(InspectType)
+	*p = x
+	return p
+}
+
+func (x InspectType) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (InspectType) Descriptor() protoreflect.EnumDescriptor {
+	return file_quality_inspect_proto_enumTypes[0].Descriptor()
+}
+
+func (InspectType) Type() protoreflect.EnumType {
+	return &file_quality_inspect_proto_enumTypes[0]
+}
+
+func (x InspectType) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use InspectType.Descriptor instead.
+func (InspectType) EnumDescriptor() ([]byte, []int) {
+	return file_quality_inspect_proto_rawDescGZIP(), []int{0}
+}
+
+type MaterialType int32
+
+const (
+	MaterialType_DefaultMaterialType  MaterialType = 0
+	MaterialType_MaterialTypeRaw      MaterialType = 1 // 鍘熸潗鏂�
+	MaterialType_MaterialTypeSemi     MaterialType = 2 // 鍗婃垚鍝�
+	MaterialType_MaterialTypeFinished MaterialType = 3 // 鎴愬搧
+)
+
+// Enum value maps for MaterialType.
+var (
+	MaterialType_name = map[int32]string{
+		0: "DefaultMaterialType",
+		1: "MaterialTypeRaw",
+		2: "MaterialTypeSemi",
+		3: "MaterialTypeFinished",
+	}
+	MaterialType_value = map[string]int32{
+		"DefaultMaterialType":  0,
+		"MaterialTypeRaw":      1,
+		"MaterialTypeSemi":     2,
+		"MaterialTypeFinished": 3,
+	}
+)
+
+func (x MaterialType) Enum() *MaterialType {
+	p := new(MaterialType)
+	*p = x
+	return p
+}
+
+func (x MaterialType) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (MaterialType) Descriptor() protoreflect.EnumDescriptor {
+	return file_quality_inspect_proto_enumTypes[1].Descriptor()
+}
+
+func (MaterialType) Type() protoreflect.EnumType {
+	return &file_quality_inspect_proto_enumTypes[1]
+}
+
+func (x MaterialType) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use MaterialType.Descriptor instead.
+func (MaterialType) EnumDescriptor() ([]byte, []int) {
+	return file_quality_inspect_proto_rawDescGZIP(), []int{1}
+}
+
+type InspectMethod int32
+
+const (
+	InspectMethod_DefaultInspectMethod InspectMethod = 0
+	InspectMethod_InspectMethodAll     InspectMethod = 1 // 鍏ㄦ
+	InspectMethod_InspectMethodSpot    InspectMethod = 2 //鎶芥
+)
+
+// Enum value maps for InspectMethod.
+var (
+	InspectMethod_name = map[int32]string{
+		0: "DefaultInspectMethod",
+		1: "InspectMethodAll",
+		2: "InspectMethodSpot",
+	}
+	InspectMethod_value = map[string]int32{
+		"DefaultInspectMethod": 0,
+		"InspectMethodAll":     1,
+		"InspectMethodSpot":    2,
+	}
+)
+
+func (x InspectMethod) Enum() *InspectMethod {
+	p := new(InspectMethod)
+	*p = x
+	return p
+}
+
+func (x InspectMethod) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (InspectMethod) Descriptor() protoreflect.EnumDescriptor {
+	return file_quality_inspect_proto_enumTypes[2].Descriptor()
+}
+
+func (InspectMethod) Type() protoreflect.EnumType {
+	return &file_quality_inspect_proto_enumTypes[2]
+}
+
+func (x InspectMethod) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use InspectMethod.Descriptor instead.
+func (InspectMethod) EnumDescriptor() ([]byte, []int) {
+	return file_quality_inspect_proto_rawDescGZIP(), []int{2}
+}
+
+type SendPurchaseInspectRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	List []*QualityInspect `protobuf:"bytes,1,rep,name=list,proto3" json:"list,omitempty"`
+}
+
+func (x *SendPurchaseInspectRequest) Reset() {
+	*x = SendPurchaseInspectRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_quality_inspect_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SendPurchaseInspectRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SendPurchaseInspectRequest) ProtoMessage() {}
+
+func (x *SendPurchaseInspectRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_quality_inspect_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 SendPurchaseInspectRequest.ProtoReflect.Descriptor instead.
+func (*SendPurchaseInspectRequest) Descriptor() ([]byte, []int) {
+	return file_quality_inspect_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *SendPurchaseInspectRequest) GetList() []*QualityInspect {
+	if x != nil {
+		return x.List
+	}
+	return nil
+}
+
+type QualityInspect struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Id              string        `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`                                                                 //妫�楠屽崟id
+	InspectType     InspectType   `protobuf:"varint,2,opt,name=inspect_type,json=inspectType,proto3,enum=InspectType" json:"inspect_type,omitempty"`          // 妫�楠岀被鍨�
+	SendInspectorId string        `protobuf:"bytes,3,opt,name=send_inspector_id,json=sendInspectorId,proto3" json:"send_inspector_id,omitempty"`              // 閫佹鍛業D
+	MaterialType    MaterialType  `protobuf:"varint,4,opt,name=material_type,json=materialType,proto3,enum=MaterialType" json:"material_type,omitempty"`      // 鐗╂枡绫诲瀷(鏁板瓧)
+	MaterialName    string        `protobuf:"bytes,5,opt,name=material_name,json=materialName,proto3" json:"material_name,omitempty"`                         // 鐗╂枡鍚嶇О
+	MaterialId      string        `protobuf:"bytes,6,opt,name=material_id,json=materialId,proto3" json:"material_id,omitempty"`                               // 鐗╂枡缂栫爜
+	MaterialTp      string        `protobuf:"bytes,7,opt,name=material_tp,json=materialTp,proto3" json:"material_tp,omitempty"`                               // 鐗╂枡鍨嬪彿
+	MaterialUnit    string        `protobuf:"bytes,8,opt,name=material_unit,json=materialUnit,proto3" json:"material_unit,omitempty"`                         // 鐗╂枡鍗曚綅
+	Supplier        string        `protobuf:"bytes,9,opt,name=supplier,proto3" json:"supplier,omitempty"`                                                     // 渚涘簲鍟�
+	BatchId         string        `protobuf:"bytes,10,opt,name=batch_id,json=batchId,proto3" json:"batch_id,omitempty"`                                       // 鎵瑰彿
+	WarehouseName   string        `protobuf:"bytes,11,opt,name=warehouse_name,json=warehouseName,proto3" json:"warehouse_name,omitempty"`                     // 鏀舵枡浠撳簱
+	WarehousePos    string        `protobuf:"bytes,12,opt,name=warehouse_pos,json=warehousePos,proto3" json:"warehouse_pos,omitempty"`                        // 浠撲綅
+	ReportAmount    float64       `protobuf:"fixed64,13,opt,name=report_amount,json=reportAmount,proto3" json:"report_amount,omitempty"`                      // 鎶ユ鏁伴噺
+	InspectMethod   InspectMethod `protobuf:"varint,14,opt,name=inspect_method,json=inspectMethod,proto3,enum=InspectMethod" json:"inspect_method,omitempty"` // 妫�楠屾柟寮�
+	InspectAmount   float64       `protobuf:"fixed64,15,opt,name=inspect_amount,json=inspectAmount,proto3" json:"inspect_amount,omitempty"`                   // 妫�楠屾暟閲�
+	Status          int32         `protobuf:"varint,16,opt,name=status,proto3" json:"status,omitempty"`                                                       // 鐘舵��
+	SubmitId        string        `protobuf:"bytes,17,opt,name=submit_id,json=submitId,proto3" json:"submit_id,omitempty"`                                    // 鎻愪氦浜篒D
+	RejectAmount    float64       `protobuf:"fixed64,18,opt,name=reject_amount,json=rejectAmount,proto3" json:"reject_amount,omitempty"`                      // 閫�璐ф暟閲�
+	ExchangeAmount  float64       `protobuf:"fixed64,19,opt,name=exchange_amount,json=exchangeAmount,proto3" json:"exchange_amount,omitempty"`                // 鎹㈣揣鏁伴噺
+	RepairAmount    float64       `protobuf:"fixed64,20,opt,name=repair_amount,json=repairAmount,proto3" json:"repair_amount,omitempty"`                      // 濮斿淇暟閲�
+	InspectDelete   int32         `protobuf:"varint,21,opt,name=inspect_delete,json=inspectDelete,proto3" json:"inspect_delete,omitempty"`                    // 璐ㄩ噺妫�楠屽垹闄� 1-鏈垹闄� 2-宸插垹闄�
+	PurchaseOrderId string        `protobuf:"bytes,22,opt,name=purchase_order_id,json=purchaseOrderId,proto3" json:"purchase_order_id,omitempty"`             // 閲囪喘鍗曞彿
+}
+
+func (x *QualityInspect) Reset() {
+	*x = QualityInspect{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_quality_inspect_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *QualityInspect) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*QualityInspect) ProtoMessage() {}
+
+func (x *QualityInspect) ProtoReflect() protoreflect.Message {
+	mi := &file_quality_inspect_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 QualityInspect.ProtoReflect.Descriptor instead.
+func (*QualityInspect) Descriptor() ([]byte, []int) {
+	return file_quality_inspect_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *QualityInspect) GetId() string {
+	if x != nil {
+		return x.Id
+	}
+	return ""
+}
+
+func (x *QualityInspect) GetInspectType() InspectType {
+	if x != nil {
+		return x.InspectType
+	}
+	return InspectType_DefaultInspectType
+}
+
+func (x *QualityInspect) GetSendInspectorId() string {
+	if x != nil {
+		return x.SendInspectorId
+	}
+	return ""
+}
+
+func (x *QualityInspect) GetMaterialType() MaterialType {
+	if x != nil {
+		return x.MaterialType
+	}
+	return MaterialType_DefaultMaterialType
+}
+
+func (x *QualityInspect) GetMaterialName() string {
+	if x != nil {
+		return x.MaterialName
+	}
+	return ""
+}
+
+func (x *QualityInspect) GetMaterialId() string {
+	if x != nil {
+		return x.MaterialId
+	}
+	return ""
+}
+
+func (x *QualityInspect) GetMaterialTp() string {
+	if x != nil {
+		return x.MaterialTp
+	}
+	return ""
+}
+
+func (x *QualityInspect) GetMaterialUnit() string {
+	if x != nil {
+		return x.MaterialUnit
+	}
+	return ""
+}
+
+func (x *QualityInspect) GetSupplier() string {
+	if x != nil {
+		return x.Supplier
+	}
+	return ""
+}
+
+func (x *QualityInspect) GetBatchId() string {
+	if x != nil {
+		return x.BatchId
+	}
+	return ""
+}
+
+func (x *QualityInspect) GetWarehouseName() string {
+	if x != nil {
+		return x.WarehouseName
+	}
+	return ""
+}
+
+func (x *QualityInspect) GetWarehousePos() string {
+	if x != nil {
+		return x.WarehousePos
+	}
+	return ""
+}
+
+func (x *QualityInspect) GetReportAmount() float64 {
+	if x != nil {
+		return x.ReportAmount
+	}
+	return 0
+}
+
+func (x *QualityInspect) GetInspectMethod() InspectMethod {
+	if x != nil {
+		return x.InspectMethod
+	}
+	return InspectMethod_DefaultInspectMethod
+}
+
+func (x *QualityInspect) GetInspectAmount() float64 {
+	if x != nil {
+		return x.InspectAmount
+	}
+	return 0
+}
+
+func (x *QualityInspect) GetStatus() int32 {
+	if x != nil {
+		return x.Status
+	}
+	return 0
+}
+
+func (x *QualityInspect) GetSubmitId() string {
+	if x != nil {
+		return x.SubmitId
+	}
+	return ""
+}
+
+func (x *QualityInspect) GetRejectAmount() float64 {
+	if x != nil {
+		return x.RejectAmount
+	}
+	return 0
+}
+
+func (x *QualityInspect) GetExchangeAmount() float64 {
+	if x != nil {
+		return x.ExchangeAmount
+	}
+	return 0
+}
+
+func (x *QualityInspect) GetRepairAmount() float64 {
+	if x != nil {
+		return x.RepairAmount
+	}
+	return 0
+}
+
+func (x *QualityInspect) GetInspectDelete() int32 {
+	if x != nil {
+		return x.InspectDelete
+	}
+	return 0
+}
+
+func (x *QualityInspect) GetPurchaseOrderId() string {
+	if x != nil {
+		return x.PurchaseOrderId
+	}
+	return ""
+}
+
+type SendPurchaseInspectResponse 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 *SendPurchaseInspectResponse) Reset() {
+	*x = SendPurchaseInspectResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_quality_inspect_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SendPurchaseInspectResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SendPurchaseInspectResponse) ProtoMessage() {}
+
+func (x *SendPurchaseInspectResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_quality_inspect_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 SendPurchaseInspectResponse.ProtoReflect.Descriptor instead.
+func (*SendPurchaseInspectResponse) Descriptor() ([]byte, []int) {
+	return file_quality_inspect_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *SendPurchaseInspectResponse) GetCode() int32 {
+	if x != nil {
+		return x.Code
+	}
+	return 0
+}
+
+func (x *SendPurchaseInspectResponse) GetMsg() string {
+	if x != nil {
+		return x.Msg
+	}
+	return ""
+}
+
+type GetInspectListRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Page     int32  `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"`
+	PageSize int32  `protobuf:"varint,2,opt,name=pageSize,proto3" json:"pageSize,omitempty"`
+	Keyword  string `protobuf:"bytes,3,opt,name=keyword,proto3" json:"keyword,omitempty"`
+}
+
+func (x *GetInspectListRequest) Reset() {
+	*x = GetInspectListRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_quality_inspect_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetInspectListRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetInspectListRequest) ProtoMessage() {}
+
+func (x *GetInspectListRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_quality_inspect_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 GetInspectListRequest.ProtoReflect.Descriptor instead.
+func (*GetInspectListRequest) Descriptor() ([]byte, []int) {
+	return file_quality_inspect_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *GetInspectListRequest) GetPage() int32 {
+	if x != nil {
+		return x.Page
+	}
+	return 0
+}
+
+func (x *GetInspectListRequest) GetPageSize() int32 {
+	if x != nil {
+		return x.PageSize
+	}
+	return 0
+}
+
+func (x *GetInspectListRequest) GetKeyword() string {
+	if x != nil {
+		return x.Keyword
+	}
+	return ""
+}
+
+type GetInspectListResponse 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  []*QualityInspect `protobuf:"bytes,3,rep,name=List,proto3" json:"List,omitempty"`
+	Total int64             `protobuf:"varint,4,opt,name=Total,proto3" json:"Total,omitempty"`
+}
+
+func (x *GetInspectListResponse) Reset() {
+	*x = GetInspectListResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_quality_inspect_proto_msgTypes[4]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetInspectListResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetInspectListResponse) ProtoMessage() {}
+
+func (x *GetInspectListResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_quality_inspect_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 GetInspectListResponse.ProtoReflect.Descriptor instead.
+func (*GetInspectListResponse) Descriptor() ([]byte, []int) {
+	return file_quality_inspect_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *GetInspectListResponse) GetCode() int32 {
+	if x != nil {
+		return x.Code
+	}
+	return 0
+}
+
+func (x *GetInspectListResponse) GetMsg() string {
+	if x != nil {
+		return x.Msg
+	}
+	return ""
+}
+
+func (x *GetInspectListResponse) GetList() []*QualityInspect {
+	if x != nil {
+		return x.List
+	}
+	return nil
+}
+
+func (x *GetInspectListResponse) GetTotal() int64 {
+	if x != nil {
+		return x.Total
+	}
+	return 0
+}
+
+var File_quality_inspect_proto protoreflect.FileDescriptor
+
+var file_quality_inspect_proto_rawDesc = []byte{
+	0x0a, 0x15, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63,
+	0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x41, 0x0a, 0x1a, 0x53, 0x65, 0x6e, 0x64, 0x50,
+	0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20,
+	0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x51, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x73,
+	0x70, 0x65, 0x63, 0x74, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x22, 0xbe, 0x06, 0x0a, 0x0e, 0x51,
+	0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x12, 0x0e, 0x0a,
+	0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2f, 0x0a,
+	0x0c, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x0e, 0x32, 0x0c, 0x2e, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70,
+	0x65, 0x52, 0x0b, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2a,
+	0x0a, 0x11, 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x6f, 0x72,
+	0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x65, 0x6e, 0x64, 0x49,
+	0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x32, 0x0a, 0x0d, 0x6d, 0x61,
+	0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28,
+	0x0e, 0x32, 0x0d, 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65,
+	0x52, 0x0c, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x12, 0x23,
+	0x0a, 0x0d, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18,
+	0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x4e,
+	0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x5f,
+	0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69,
+	0x61, 0x6c, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c,
+	0x5f, 0x74, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x61, 0x74, 0x65, 0x72,
+	0x69, 0x61, 0x6c, 0x54, 0x70, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61,
+	0x6c, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6d, 0x61,
+	0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x55, 0x6e, 0x69, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x75,
+	0x70, 0x70, 0x6c, 0x69, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x75,
+	0x70, 0x70, 0x6c, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f,
+	0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x61, 0x74, 0x63, 0x68, 0x49,
+	0x64, 0x12, 0x25, 0x0a, 0x0e, 0x77, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x5f, 0x6e,
+	0x61, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x77, 0x61, 0x72, 0x65, 0x68,
+	0x6f, 0x75, 0x73, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x77, 0x61, 0x72, 0x65,
+	0x68, 0x6f, 0x75, 0x73, 0x65, 0x5f, 0x70, 0x6f, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x0c, 0x77, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x50, 0x6f, 0x73, 0x12, 0x23, 0x0a,
+	0x0d, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0d,
+	0x20, 0x01, 0x28, 0x01, 0x52, 0x0c, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x41, 0x6d, 0x6f, 0x75,
+	0x6e, 0x74, 0x12, 0x35, 0x0a, 0x0e, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x5f, 0x6d, 0x65,
+	0x74, 0x68, 0x6f, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x49, 0x6e, 0x73,
+	0x70, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x0d, 0x69, 0x6e, 0x73, 0x70,
+	0x65, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e, 0x73,
+	0x70, 0x65, 0x63, 0x74, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28,
+	0x01, 0x52, 0x0d, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74,
+	0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x05,
+	0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x75, 0x62, 0x6d,
+	0x69, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x75, 0x62,
+	0x6d, 0x69, 0x74, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x5f,
+	0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0c, 0x72, 0x65,
+	0x6a, 0x65, 0x63, 0x74, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x65, 0x78,
+	0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x13, 0x20,
+	0x01, 0x28, 0x01, 0x52, 0x0e, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x41, 0x6d, 0x6f,
+	0x75, 0x6e, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x70, 0x61, 0x69, 0x72, 0x5f, 0x61, 0x6d,
+	0x6f, 0x75, 0x6e, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0c, 0x72, 0x65, 0x70, 0x61,
+	0x69, 0x72, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e, 0x73, 0x70,
+	0x65, 0x63, 0x74, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x15, 0x20, 0x01, 0x28, 0x05,
+	0x52, 0x0d, 0x69, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12,
+	0x2a, 0x0a, 0x11, 0x70, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x5f, 0x6f, 0x72, 0x64, 0x65,
+	0x72, 0x5f, 0x69, 0x64, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x75, 0x72, 0x63,
+	0x68, 0x61, 0x73, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x49, 0x64, 0x22, 0x43, 0x0a, 0x1b, 0x53,
+	0x65, 0x6e, 0x64, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x73, 0x70, 0x65,
+	0x63, 0x74, 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, 0x61, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x4c, 0x69,
+	0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x67,
+	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x12, 0x1a, 0x0a,
+	0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52,
+	0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6b, 0x65, 0x79,
+	0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x77,
+	0x6f, 0x72, 0x64, 0x22, 0x79, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63,
+	0x74, 0x4c, 0x69, 0x73, 0x74, 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, 0x23, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28,
+	0x0b, 0x32, 0x0f, 0x2e, 0x51, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x73, 0x70, 0x65,
+	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, 0x2a, 0x86,
+	0x01, 0x0a, 0x0b, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16,
+	0x0a, 0x12, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74,
+	0x54, 0x79, 0x70, 0x65, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63,
+	0x74, 0x54, 0x79, 0x70, 0x65, 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x65, 0x10, 0x01, 0x12, 0x17, 0x0a,
+	0x13, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x50, 0x75, 0x72, 0x63,
+	0x68, 0x61, 0x73, 0x65, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63,
+	0x74, 0x54, 0x79, 0x70, 0x65, 0x4f, 0x75, 0x74, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x10, 0x03,
+	0x12, 0x15, 0x0a, 0x11, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52,
+	0x65, 0x6a, 0x65, 0x63, 0x74, 0x10, 0x04, 0x2a, 0x6c, 0x0a, 0x0c, 0x4d, 0x61, 0x74, 0x65, 0x72,
+	0x69, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x44, 0x65, 0x66, 0x61, 0x75,
+	0x6c, 0x74, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x10, 0x00,
+	0x12, 0x13, 0x0a, 0x0f, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65,
+	0x52, 0x61, 0x77, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61,
+	0x6c, 0x54, 0x79, 0x70, 0x65, 0x53, 0x65, 0x6d, 0x69, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x4d,
+	0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x46, 0x69, 0x6e, 0x69, 0x73,
+	0x68, 0x65, 0x64, 0x10, 0x03, 0x2a, 0x56, 0x0a, 0x0d, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74,
+	0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x18, 0x0a, 0x14, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c,
+	0x74, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x10, 0x00,
+	0x12, 0x14, 0x0a, 0x10, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f,
+	0x64, 0x41, 0x6c, 0x6c, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63,
+	0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x53, 0x70, 0x6f, 0x74, 0x10, 0x02, 0x32, 0xb0, 0x01,
+	0x0a, 0x15, 0x51, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74,
+	0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x52, 0x0a, 0x13, 0x53, 0x65, 0x6e, 0x64, 0x50,
+	0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x12, 0x1b,
+	0x2e, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x73,
+	0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x53, 0x65,
+	0x6e, 0x64, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63,
+	0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0e, 0x47,
+	0x65, 0x74, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x16, 0x2e,
+	0x47, 0x65, 0x74, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x73, 0x70, 0x65,
+	0x63, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
+	0x42, 0x12, 0x5a, 0x10, 0x2e, 0x2f, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x69, 0x6e, 0x73,
+	0x70, 0x65, 0x63, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_quality_inspect_proto_rawDescOnce sync.Once
+	file_quality_inspect_proto_rawDescData = file_quality_inspect_proto_rawDesc
+)
+
+func file_quality_inspect_proto_rawDescGZIP() []byte {
+	file_quality_inspect_proto_rawDescOnce.Do(func() {
+		file_quality_inspect_proto_rawDescData = protoimpl.X.CompressGZIP(file_quality_inspect_proto_rawDescData)
+	})
+	return file_quality_inspect_proto_rawDescData
+}
+
+var file_quality_inspect_proto_enumTypes = make([]protoimpl.EnumInfo, 3)
+var file_quality_inspect_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
+var file_quality_inspect_proto_goTypes = []interface{}{
+	(InspectType)(0),                    // 0: InspectType
+	(MaterialType)(0),                   // 1: MaterialType
+	(InspectMethod)(0),                  // 2: InspectMethod
+	(*SendPurchaseInspectRequest)(nil),  // 3: SendPurchaseInspectRequest
+	(*QualityInspect)(nil),              // 4: QualityInspect
+	(*SendPurchaseInspectResponse)(nil), // 5: SendPurchaseInspectResponse
+	(*GetInspectListRequest)(nil),       // 6: GetInspectListRequest
+	(*GetInspectListResponse)(nil),      // 7: GetInspectListResponse
+}
+var file_quality_inspect_proto_depIdxs = []int32{
+	4, // 0: SendPurchaseInspectRequest.list:type_name -> QualityInspect
+	0, // 1: QualityInspect.inspect_type:type_name -> InspectType
+	1, // 2: QualityInspect.material_type:type_name -> MaterialType
+	2, // 3: QualityInspect.inspect_method:type_name -> InspectMethod
+	4, // 4: GetInspectListResponse.List:type_name -> QualityInspect
+	3, // 5: QualityInspectService.SendPurchaseInspect:input_type -> SendPurchaseInspectRequest
+	6, // 6: QualityInspectService.GetInspectList:input_type -> GetInspectListRequest
+	5, // 7: QualityInspectService.SendPurchaseInspect:output_type -> SendPurchaseInspectResponse
+	7, // 8: QualityInspectService.GetInspectList:output_type -> GetInspectListResponse
+	7, // [7:9] is the sub-list for method output_type
+	5, // [5:7] is the sub-list for method input_type
+	5, // [5:5] is the sub-list for extension type_name
+	5, // [5:5] is the sub-list for extension extendee
+	0, // [0:5] is the sub-list for field type_name
+}
+
+func init() { file_quality_inspect_proto_init() }
+func file_quality_inspect_proto_init() {
+	if File_quality_inspect_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_quality_inspect_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SendPurchaseInspectRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_quality_inspect_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*QualityInspect); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_quality_inspect_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SendPurchaseInspectResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_quality_inspect_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetInspectListRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_quality_inspect_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetInspectListResponse); 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_quality_inspect_proto_rawDesc,
+			NumEnums:      3,
+			NumMessages:   5,
+			NumExtensions: 0,
+			NumServices:   1,
+		},
+		GoTypes:           file_quality_inspect_proto_goTypes,
+		DependencyIndexes: file_quality_inspect_proto_depIdxs,
+		EnumInfos:         file_quality_inspect_proto_enumTypes,
+		MessageInfos:      file_quality_inspect_proto_msgTypes,
+	}.Build()
+	File_quality_inspect_proto = out.File
+	file_quality_inspect_proto_rawDesc = nil
+	file_quality_inspect_proto_goTypes = nil
+	file_quality_inspect_proto_depIdxs = nil
+}
diff --git a/proto/qualityinspect/quality_inspect_grpc.pb.go b/proto/qualityinspect/quality_inspect_grpc.pb.go
new file mode 100644
index 0000000..37d520b
--- /dev/null
+++ b/proto/qualityinspect/quality_inspect_grpc.pb.go
@@ -0,0 +1,146 @@
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+// versions:
+// - protoc-gen-go-grpc v1.3.0
+// - protoc             v3.19.0
+// source: quality_inspect.proto
+
+package qualityinspect
+
+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
+
+const (
+	QualityInspectService_SendPurchaseInspect_FullMethodName = "/QualityInspectService/SendPurchaseInspect"
+	QualityInspectService_GetInspectList_FullMethodName      = "/QualityInspectService/GetInspectList"
+)
+
+// QualityInspectServiceClient is the client API for QualityInspectService 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 QualityInspectServiceClient interface {
+	SendPurchaseInspect(ctx context.Context, in *SendPurchaseInspectRequest, opts ...grpc.CallOption) (*SendPurchaseInspectResponse, error)
+	GetInspectList(ctx context.Context, in *GetInspectListRequest, opts ...grpc.CallOption) (*GetInspectListResponse, error)
+}
+
+type qualityInspectServiceClient struct {
+	cc grpc.ClientConnInterface
+}
+
+func NewQualityInspectServiceClient(cc grpc.ClientConnInterface) QualityInspectServiceClient {
+	return &qualityInspectServiceClient{cc}
+}
+
+func (c *qualityInspectServiceClient) SendPurchaseInspect(ctx context.Context, in *SendPurchaseInspectRequest, opts ...grpc.CallOption) (*SendPurchaseInspectResponse, error) {
+	out := new(SendPurchaseInspectResponse)
+	err := c.cc.Invoke(ctx, QualityInspectService_SendPurchaseInspect_FullMethodName, in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *qualityInspectServiceClient) GetInspectList(ctx context.Context, in *GetInspectListRequest, opts ...grpc.CallOption) (*GetInspectListResponse, error) {
+	out := new(GetInspectListResponse)
+	err := c.cc.Invoke(ctx, QualityInspectService_GetInspectList_FullMethodName, in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// QualityInspectServiceServer is the server API for QualityInspectService service.
+// All implementations must embed UnimplementedQualityInspectServiceServer
+// for forward compatibility
+type QualityInspectServiceServer interface {
+	SendPurchaseInspect(context.Context, *SendPurchaseInspectRequest) (*SendPurchaseInspectResponse, error)
+	GetInspectList(context.Context, *GetInspectListRequest) (*GetInspectListResponse, error)
+	mustEmbedUnimplementedQualityInspectServiceServer()
+}
+
+// UnimplementedQualityInspectServiceServer must be embedded to have forward compatible implementations.
+type UnimplementedQualityInspectServiceServer struct {
+}
+
+func (UnimplementedQualityInspectServiceServer) SendPurchaseInspect(context.Context, *SendPurchaseInspectRequest) (*SendPurchaseInspectResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method SendPurchaseInspect not implemented")
+}
+func (UnimplementedQualityInspectServiceServer) GetInspectList(context.Context, *GetInspectListRequest) (*GetInspectListResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetInspectList not implemented")
+}
+func (UnimplementedQualityInspectServiceServer) mustEmbedUnimplementedQualityInspectServiceServer() {}
+
+// UnsafeQualityInspectServiceServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to QualityInspectServiceServer will
+// result in compilation errors.
+type UnsafeQualityInspectServiceServer interface {
+	mustEmbedUnimplementedQualityInspectServiceServer()
+}
+
+func RegisterQualityInspectServiceServer(s grpc.ServiceRegistrar, srv QualityInspectServiceServer) {
+	s.RegisterService(&QualityInspectService_ServiceDesc, srv)
+}
+
+func _QualityInspectService_SendPurchaseInspect_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(SendPurchaseInspectRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(QualityInspectServiceServer).SendPurchaseInspect(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: QualityInspectService_SendPurchaseInspect_FullMethodName,
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(QualityInspectServiceServer).SendPurchaseInspect(ctx, req.(*SendPurchaseInspectRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _QualityInspectService_GetInspectList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GetInspectListRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(QualityInspectServiceServer).GetInspectList(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: QualityInspectService_GetInspectList_FullMethodName,
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(QualityInspectServiceServer).GetInspectList(ctx, req.(*GetInspectListRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+// QualityInspectService_ServiceDesc is the grpc.ServiceDesc for QualityInspectService service.
+// It's only intended for direct use with grpc.RegisterService,
+// and not to be introspected or modified (even as a copy)
+var QualityInspectService_ServiceDesc = grpc.ServiceDesc{
+	ServiceName: "QualityInspectService",
+	HandlerType: (*QualityInspectServiceServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "SendPurchaseInspect",
+			Handler:    _QualityInspectService_SendPurchaseInspect_Handler,
+		},
+		{
+			MethodName: "GetInspectList",
+			Handler:    _QualityInspectService_GetInspectList_Handler,
+		},
+	},
+	Streams:  []grpc.StreamDesc{},
+	Metadata: "quality_inspect.proto",
+}
diff --git a/router/purchase/purchase.go b/router/purchase/purchase.go
index aa59419..a7b3728 100644
--- a/router/purchase/purchase.go
+++ b/router/purchase/purchase.go
@@ -7,13 +7,15 @@
 
 func InitPurchaseRouter(Router *gin.RouterGroup) {
 	purchaseRouter := Router.Group("purchase")
-	purchaseRouterWithoutRecord := Router.Group("purchase")
 	PurchaseApi := purchase.PurchaseApi{}
 	{
-		purchaseRouter.POST("purchase", PurchaseApi.CreatePurchase)                  // 鍒涘缓閲囪喘鍗�
-		purchaseRouter.PUT("purchase", PurchaseApi.UpdatePurchase)                   // 鏇存柊閲囪喘鍗�
-		purchaseRouter.DELETE("purchase/:id", PurchaseApi.DeletePurchase)            // 鍒犻櫎閲囪喘鍗�
-		purchaseRouterWithoutRecord.GET("purchase/:id", PurchaseApi.GetPurchase)     // 鑾峰彇鍗曚竴閲囪喘鍗曚俊鎭�
-		purchaseRouterWithoutRecord.GET("purchaseList", PurchaseApi.GetPurchaseList) // 鑾峰彇閲囪喘鍗曞垪琛�
+		purchaseRouter.POST("purchase", PurchaseApi.CreatePurchase)             // 鍒涘缓閲囪喘鍗�
+		purchaseRouter.PUT("purchase", PurchaseApi.UpdatePurchase)              // 鏇存柊閲囪喘鍗�
+		purchaseRouter.DELETE("purchase/:id", PurchaseApi.DeletePurchase)       // 鍒犻櫎閲囪喘鍗�
+		purchaseRouter.GET("purchase/:id", PurchaseApi.GetPurchase)             // 鑾峰彇鍗曚竴閲囪喘鍗曚俊鎭�
+		purchaseRouter.GET("purchaseList", PurchaseApi.GetPurchaseList)         // 鑾峰彇閲囪喘鍗曞垪琛�
+		purchaseRouter.POST("submit/:id", PurchaseApi.Submit)                   // 鎻愪氦閲囪喘鍗�
+		purchaseRouter.POST("purchaseType", PurchaseApi.SavePurchaseType)       // 淇濆瓨閲囪喘绫诲瀷
+		purchaseRouter.GET("purchaseTypeList", PurchaseApi.GetPurchaseTypeList) // 鏌ヨ閲囪喘绫诲瀷
 	}
 }
diff --git a/service/purchase/purchase.go b/service/purchase/purchase.go
index 6267575..0df0c5c 100644
--- a/service/purchase/purchase.go
+++ b/service/purchase/purchase.go
@@ -1,12 +1,14 @@
 package purchase
 
 import (
+	"context"
 	"github.com/spf13/cast"
 	"gorm.io/gorm"
 	"srm/global"
 	"srm/model/common/request"
 	"srm/model/purchase"
-	purchaserequest "srm/model/purchase/request"
+	"srm/proto/qualityinspect"
+	"srm/service/test"
 )
 
 type PurchaseService struct{}
@@ -20,16 +22,16 @@
 //@param: params *purchaserequest.AddPurchase
 //@return: err error
 
-func (exa *PurchaseService) CreatePurchase(params purchaserequest.AddPurchase) (err error) {
+func (slf *PurchaseService) CreatePurchase(params *purchase.Purchase, productList []*purchase.PurchaseProducts) (err error) {
 	err = global.GVA_DB.Transaction(func(tx *gorm.DB) error {
-		err = global.GVA_DB.Create(&params.Purchase).Error
+		err = tx.Create(&params).Error
 		if err != nil {
 			return err
 		}
-		for _, product := range params.ProductList {
-			product.PurchaseId = cast.ToInt(params.Purchase.ID)
+		for _, product := range productList {
+			product.PurchaseId = cast.ToInt(params.ID)
 		}
-		return global.GVA_DB.Create(params.ProductList).Error
+		return tx.Create(productList).Error
 	})
 
 	return err
@@ -40,13 +42,13 @@
 //@param: id uint
 //@return: err error
 
-func (exa *PurchaseService) DeletePurchase(id uint) (err error) {
+func (slf *PurchaseService) DeletePurchase(id uint) (err error) {
 	err = global.GVA_DB.Transaction(func(tx *gorm.DB) error {
-		err = global.GVA_DB.Where("id = ?", id).Delete(&purchase.Purchase{}).Error
+		err = tx.Where("id = ?", id).Delete(&purchase.Purchase{}).Error
 		if err != nil {
 			return err
 		}
-		return global.GVA_DB.Where("purchase_id = ?", id).Delete(&purchase.PurchaseProducts{}).Error
+		return tx.Where("purchase_id = ?", id).Delete(&purchase.PurchaseProducts{}).Error
 	})
 	return err
 }
@@ -56,21 +58,21 @@
 //@param: params *purchaserequest.AddPurchase
 //@return: err error
 
-func (exa *PurchaseService) UpdatePurchase(params *purchaserequest.AddPurchase) (err error) {
+func (slf *PurchaseService) UpdatePurchase(params *purchase.Purchase, productList []*purchase.PurchaseProducts) (err error) {
 	err = global.GVA_DB.Transaction(func(tx *gorm.DB) error {
-		err = global.GVA_DB.Updates(params.Purchase).Error
+		err = tx.Where("id = ?", params.ID).Updates(params).Error
 		if err != nil {
 			return err
 		}
-		err = global.GVA_DB.Where("purchase_id = ?", params.Purchase.ID).Delete(&purchase.PurchaseProducts{}).Error
+		err = tx.Where("purchase_id = ?", params.ID).Delete(&purchase.PurchaseProducts{}).Error
 		if err != nil {
 			return err
 		}
-		for _, product := range params.ProductList {
+		for _, product := range productList {
 			product.ID = 0
-			product.PurchaseId = cast.ToInt(params.Purchase.ID)
+			product.PurchaseId = cast.ToInt(params.ID)
 		}
-		return global.GVA_DB.Create(params.ProductList).Error
+		return tx.Create(productList).Error
 	})
 	return err
 }
@@ -80,8 +82,8 @@
 //@param: id uint
 //@return: purchase model.Purchase, err error
 
-func (exa *PurchaseService) GetPurchase(id uint) (purchase purchase.Purchase, err error) {
-	err = global.GVA_DB.Where("id = ?", id).First(&purchase).Error
+func (slf *PurchaseService) GetPurchase(id uint) (purchase purchase.Purchase, err error) {
+	err = global.GVA_DB.Where("id = ?", id).Preload("Supplier").First(&purchase).Error
 	return
 }
 
@@ -90,7 +92,7 @@
 //@param: info request.PageInfo
 //@return: list interface{}, total int64, err error
 
-func (exa *PurchaseService) GetPurchaseList(info request.PageInfo) (list interface{}, total int64, err error) {
+func (slf *PurchaseService) GetPurchaseList(info request.PageInfo) (list interface{}, total int64, err error) {
 	limit := info.PageSize
 	offset := info.PageSize * (info.Page - 1)
 	db := global.GVA_DB.Model(&purchase.Purchase{})
@@ -116,7 +118,7 @@
 //@param: purchaseId int
 //@return: list interface{},  err error
 
-func (exa *PurchaseService) GetPurchaseProductList(purchaseId uint) (list []*purchase.PurchaseProducts, err error) {
+func (slf *PurchaseService) GetPurchaseProductList(purchaseId uint) (list []*purchase.PurchaseProducts, err error) {
 	db := global.GVA_DB.Model(&purchase.PurchaseProducts{})
 	list = make([]*purchase.PurchaseProducts, 0)
 	err = db.Where("purchase_id = ?", purchaseId).Find(&list).Error
@@ -128,13 +130,95 @@
 //@param: id uint
 //@return: err error
 
-func (exa *PurchaseService) Submit(id uint) (err error) {
+func (slf *PurchaseService) Submit(id uint) (err error) {
+
+	purchaseData, err := slf.GetPurchase(id)
+	if err != nil {
+		return err
+	}
+	var targetStatus purchase.OrderStatus
+	switch purchaseData.Status {
+	case purchase.OrderStatusConfirmed:
+		targetStatus = purchase.OrderStatusReceived
+	case purchase.OrderStatusReceived:
+		targetStatus = purchase.OrderStatusStored
+	case purchase.OrderStatusStored:
+		targetStatus = purchase.OrderStatusCompleted
+	}
 	err = global.GVA_DB.Transaction(func(tx *gorm.DB) error {
-		err = global.GVA_DB.Where("id = ?", id).Model(&purchase.Purchase{}).Updates(map[string]interface{}{"status": 1}).Error
+		err = tx.Where("id = ?", id).Model(&purchase.Purchase{}).Updates(map[string]interface{}{"status": targetStatus}).Error
 		if err != nil {
 			return err
 		}
-		return global.GVA_DB.Where("purchase_id = ?", id).Delete(&purchase.PurchaseProducts{}).Error
+
+		switch targetStatus {
+		case purchase.OrderStatusReceived:
+			return SendInspect(purchaseData)
+		case purchase.OrderStatusStored:
+		case purchase.OrderStatusCompleted:
+		}
+		return nil
 	})
 	return err
 }
+
+func SendInspect(record purchase.Purchase) error {
+	productList, err := NewPurchaseService().GetPurchaseProductList(record.ID)
+	if err != nil {
+		return err
+	}
+	productIds := make([]uint, 0, len(productList))
+	for _, product := range productList {
+		productIds = append(productIds, uint(product.ProductId))
+	}
+	productService := &test.ProductService{}
+	_, productMap, err := productService.GetProducts(productIds)
+	if err != nil {
+		return err
+	}
+	inspectOrders := make([]*qualityinspect.QualityInspect, 0, len(productList))
+	for _, productItem := range productList {
+		product := productMap[uint(productItem.ProductId)]
+		if product == nil {
+			continue
+		}
+		inspectOrder := &qualityinspect.QualityInspect{
+			InspectType:   qualityinspect.InspectType_InspectTypePurchase,
+			MaterialType:  qualityinspect.MaterialType_MaterialTypeRaw,
+			MaterialName:  product.Name,
+			MaterialId:    product.Number,
+			MaterialTp:    product.ModelNumber,
+			MaterialUnit:  product.Unit,
+			Supplier:      record.Supplier.Name,
+			WarehouseName: "閲囪喘鎬讳粨",
+			ReportAmount:  productItem.Amount.InexactFloat64(),
+			InspectMethod: qualityinspect.InspectMethod_InspectMethodAll,
+			InspectAmount: productItem.Amount.InexactFloat64(),
+		}
+		inspectOrders = append(inspectOrders, inspectOrder)
+	}
+	inspectRequest := qualityinspect.SendPurchaseInspectRequest{List: inspectOrders}
+	_, err = qualityinspect.NewQualityInspectServiceClient(qualityinspect.Conn).SendPurchaseInspect(context.Background(), &inspectRequest)
+	return err
+}
+
+func (slf *PurchaseService) SavePurchaseType(list []*purchase.PurchaseType) (err error) {
+	err = global.GVA_DB.Transaction(func(tx *gorm.DB) error {
+		err = tx.Where("1 = ?", 1).Delete(&purchase.PurchaseType{}).Error
+		if err != nil {
+			return err
+		}
+		for _, item := range list {
+			item.ID = 0
+		}
+		return tx.Create(list).Error
+	})
+	return err
+}
+
+func (slf *PurchaseService) GetPurchaseTypeList() (list []*purchase.PurchaseType, err error) {
+	db := global.GVA_DB.Model(&purchase.PurchaseType{})
+	list = make([]*purchase.PurchaseType, 0)
+	err = db.Order("pin desc, sort desc, id asc").Find(&list).Error
+	return list, err
+}
diff --git a/service/test/product.go b/service/test/product.go
index 9617d8e..d97dd7b 100644
--- a/service/test/product.go
+++ b/service/test/product.go
@@ -79,3 +79,16 @@
 	err = db.Limit(limit).Offset(offset).Preload("Supplier").Find(&ps).Error
 	return ps, total, err
 }
+
+// GetProducts 鏍规嵁ids鑾峰彇Product璁板綍
+func (pService *ProductService) GetProducts(ids []uint) (p []*test.Product, m map[uint]*test.Product, err error) {
+	err = global.GVA_DB.Where("id in ?", ids).Find(&p).Error
+	if err != nil {
+		return
+	}
+	m = make(map[uint]*test.Product, len(p))
+	for _, product := range p {
+		m[product.ID] = product
+	}
+	return
+}

--
Gitblit v1.8.0