From a10d59528a36dc5a1fbe4d9caa6b4abf25ab828c Mon Sep 17 00:00:00 2001
From: zhangqian <zhangqian@123.com>
Date: 星期五, 12 一月 2024 10:49:08 +0800
Subject: [PATCH] Merge branch 'master' of http://192.168.5.5:10010/r/aps/WMS

---
 proto/inventory_order/server.go        |    8 
 controllers/product_controller.go      |  110 ++--
 controllers/operation.go               |  522 ++++++++++----------------
 controllers/report_forms_controller.go |    4 
 models/file_template_attachment.go     |   27 
 models/operation.go                    |   51 +-
 controllers/reorder_rule_controller.go |   15 
 controllers/warehouse.go               |   29 +
 docs/swagger.yaml                      |   86 +++
 request/operation.go                   |   56 +-
 docs/docs.go                           |  109 ++++
 docs/swagger.json                      |  109 ++++
 proto/product_inventory/server.go      |   12 
 router/router.go                       |    1 
 middleware/utils.go                    |    9 
 main.go                                |    1 
 models/operation_details.go            |    5 
 proto/purchase_wms/server.go           |    5 
 controllers/location_product_amount.go |   16 
 19 files changed, 668 insertions(+), 507 deletions(-)

diff --git a/controllers/location_product_amount.go b/controllers/location_product_amount.go
index 36d7c28..195d636 100644
--- a/controllers/location_product_amount.go
+++ b/controllers/location_product_amount.go
@@ -68,7 +68,7 @@
 	}
 	var operation models.Operation
 	for k, v := range records {
-		if res := mysqlx.GetDB().Table("wms_operation").InnerJoins("inner join wms_operation_details on wms_operation_details.operation_id=wms_operation.id").Where("wms_operation.base_operation_type=? and wms_operation.status=? and wms_operation.to_location_id=? and wms_operation_details.product_id=?", constvar.BaseOperationTypeAdjust, constvar.OperationStatus_Ready, v.LocationId, v.ProductId).First(&operation); res.Error != nil {
+		if res := mysqlx.GetDB().Table("wms_operation").InnerJoins("inner join wms_operation_details on wms_operation_details.operation_id=wms_operation.id").Where("wms_operation.base_operation_type=? and wms_operation.status=? and wms_operation_details.to_location_id=? and wms_operation_details.product_id=?", constvar.BaseOperationTypeAdjust, constvar.OperationStatus_Ready, v.LocationId, v.ProductId).First(&operation); res.Error != nil {
 			if errors.Is(res.Error, gorm.ErrRecordNotFound) {
 				records[k].Status = constvar.OperationStatus_Finish
 				records[k].BaseOperationType = constvar.BaseOperationTypeAdjust
@@ -120,7 +120,11 @@
 	}
 
 	var existCount int64
-	if err := models.NewOperationSearch().Orm.Table("wms_operation").InnerJoins("inner join wms_operation_details on wms_operation_details.operation_id=wms_operation.id").Where("wms_operation.from_location_id=? and wms_operation_details.product_id=? and wms_operation.base_operation_type=? and wms_operation.status=?", reqParams.LocationId, reqParams.ProductId, constvar.BaseOperationTypeAdjust, constvar.OperationStatus_Ready).Count(&existCount).Error; err != nil {
+	if err := models.NewOperationSearch().Orm.
+		Table("wms_operation").
+		InnerJoins("inner join wms_operation_details on wms_operation_details.operation_id=wms_operation.id").
+		Where("wms_operation.location_id=? and wms_operation_details.product_id=? and wms_operation.base_operation_type=? and wms_operation.status=?", reqParams.LocationId, reqParams.ProductId, constvar.BaseOperationTypeAdjust, constvar.OperationStatus_Ready).
+		Count(&existCount).Error; err != nil {
 		return err
 	}
 	if existCount > 0 {
@@ -149,8 +153,10 @@
 	}
 
 	detail := &models.OperationDetails{
-		ProductId: reqParams.ProductId,
-		Amount:    reqParams.AdjustAmount,
+		ProductId:      reqParams.ProductId,
+		Amount:         reqParams.AdjustAmount,
+		FromLocationID: location.Id,
+		ToLocationID:   reqParams.LocationId,
 	}
 	operation := models.Operation{
 		Number:            strconv.FormatInt(time.Now().Unix(), 10),
@@ -159,8 +165,6 @@
 		Comment:           "搴撳瓨鐩樼偣",
 		BaseOperationType: constvar.BaseOperationTypeAdjust,
 		Details:           []*models.OperationDetails{detail},
-		FromLocationID:    location.Id,
-		ToLocationID:      reqParams.LocationId,
 	}
 
 	if err := models.WithTransaction(func(tx *gorm.DB) error {
diff --git a/controllers/operation.go b/controllers/operation.go
index 1dda2db..ae51152 100644
--- a/controllers/operation.go
+++ b/controllers/operation.go
@@ -61,6 +61,7 @@
 		util.ResponseFormat(c, code.RequestParamError, err.Error())
 		return
 	}
+
 	if err := slf.FormatLocation(&params); err != nil {
 		util.ResponseFormat(c, code.RequestParamError, err.Error())
 		return
@@ -122,32 +123,41 @@
 		return err
 	}
 	if operationType.BaseOperationType == constvar.BaseOperationTypeIncoming {
-		if location, err := models.NewLocationSearch().SetType(int(constvar.LocationTypeVendor)).First(); err != nil {
+		location, err := models.NewLocationSearch().SetType(int(constvar.LocationTypeVendor)).First()
+		if err != nil {
 			return err
-		} else {
-			params.FromLocationID = location.Id
 		}
-		if params.ToLocationID == 0 {
-			return errors.New("璇烽�夋嫨鐩爣浣嶇疆")
+		for k, v := range params.Details {
+			params.Details[k].FromLocationID = location.Id
+			if v.ToLocationID == 0 {
+				params.Details[k].ToLocationID = params.LocationID
+			}
 		}
+
 	}
 	if operationType.BaseOperationType == constvar.BaseOperationTypeOutgoing {
-		if location, err := models.NewLocationSearch().SetType(int(constvar.LocationTypeCustomer)).First(); err != nil {
+		location, err := models.NewLocationSearch().SetType(int(constvar.LocationTypeCustomer)).First()
+		if err != nil {
 			return err
-		} else {
-			params.ToLocationID = location.Id
 		}
-		if params.FromLocationID == 0 {
-			return errors.New("璇烽�夋嫨婧愪綅缃�")
+		for k, v := range params.Details {
+			params.Details[k].ToLocationID = location.Id
+			if v.FromLocationID == 0 {
+				return errors.New("璇烽�夋嫨鍑哄簱浣嶇疆")
+			}
 		}
+
 	}
 	if operationType.BaseOperationType == constvar.BaseOperationTypeInternal {
-		if params.ToLocationID == 0 {
-			return errors.New("璇烽�夋嫨鐩爣浣嶇疆")
+		for _, v := range params.Details {
+			if v.ToLocationID == 0 {
+				return errors.New("璇烽�夋嫨鐩爣浣嶇疆")
+			}
+			if v.FromLocationID == 0 {
+				return errors.New("璇烽�夋嫨婧愪綅缃�")
+			}
 		}
-		if params.FromLocationID == 0 {
-			return errors.New("璇烽�夋嫨婧愪綅缃�")
-		}
+
 	}
 	return nil
 }
@@ -167,6 +177,10 @@
 
 	if params.OperationDate == "" {
 		return errors.New("璇烽�夋嫨瀹夋帓鏃ユ湡")
+	}
+
+	if params.LocationID == 0 {
+		return errors.New("璇烽�夋嫨婧愪綅缃�")
 	}
 
 	if len(params.Details) <= 0 {
@@ -380,8 +394,27 @@
 		util.ResponseFormat(c, code.RequestError, "璇ュ嚭鍏ュ簱淇℃伅鏃犳硶瀹屾垚")
 		return
 	}
-	err = models.WithTransaction(func(tx *gorm.DB) error {
 
+	listDetails, err := models.NewOperationDetailsSearch().SetOperationId(operation.Id).SetPreload(true).FindAll()
+	if err != nil {
+		util.ResponseFormat(c, code.RequestError, err.Error())
+		return
+	}
+
+	var mapLocAmount map[string]*models.LocationProductAmount
+	locAmountList, err := models.NewLocationProductAmountSearch().Find()
+	if err != nil {
+		util.ResponseFormat(c, code.RequestError, err.Error())
+		return
+	}
+	if len(locAmountList) > 0 {
+		mapLocAmount = make(map[string]*models.LocationProductAmount)
+		for _, v := range locAmountList {
+			mapLocAmount[strconv.Itoa(v.LocationId)+v.ProductId] = v
+		}
+	}
+
+	err = models.WithTransaction(func(tx *gorm.DB) error {
 		if err := models.NewOperationSearch().SetOrm(tx).SetID(id).Update(&models.Operation{Status: constvar.OperationStatus_Finish, AuditDate: time.Now().Format("2006-01-02 15:04:05")}); err != nil {
 			return err
 		}
@@ -389,154 +422,119 @@
 			return err
 		}
 
-		var listProdtId []string
-		var listProdt []*models.Material
-		mapProdt := make(map[string]decimal.Decimal)
-		listDetails, err := models.NewOperationDetailsSearch().SetOperationId(operation.Id).FindAll()
-		if err != nil {
-			return err
-		}
-		for _, v := range listDetails {
-			listProdtId = append(listProdtId, v.ProductId)
-			mapProdt[v.ProductId] = v.Amount
-		}
-
-		if err := models.NewMaterialSearch().Orm.Where("id IN ?", listProdtId).Find(&listProdt).Error; err != nil {
-			return err
-		}
-
 		if operation.BaseOperationType == constvar.BaseOperationTypeIncoming {
-			var operationInputs []*models.Operation
-			for k, v := range listProdt {
-				value, ok := mapProdt[v.ID]
-				if !ok {
-					return errors.New("浜у搧绉嶇被寮傚父")
+			locationRoleList, err := models.NewLocationProductSearch().Find()
+			if err != nil {
+				return errors.New("鑾峰彇涓婃灦瑙勫垯淇℃伅澶辫触")
+			}
+			var mapLocationRoleProduct, mapLocationRoleCategory map[string]*models.LocationProduct
+			if len(locationRoleList) > 0 {
+				mapLocationRoleProduct = make(map[string]*models.LocationProduct)
+				mapLocationRoleCategory = make(map[string]*models.LocationProduct)
+				for _, v := range locationRoleList {
+					if v.RuleType == constvar.RuleType_Product {
+						mapLocationRoleProduct[strconv.Itoa(v.AreaId)+v.ProductId] = v
+					}
+					if v.RuleType == constvar.RuleType_ProductCategory {
+						mapLocationRoleCategory[strconv.Itoa(v.AreaId)+strconv.Itoa(v.ProductCategoryID)] = v
+					}
 				}
+			}
 
-				listProdt[k].Amount = listProdt[k].Amount.Add(value)
-				if err := tx.Save(listProdt[k]).Error; err != nil {
+			var details []*models.OperationDetails
+			for k, v := range listDetails {
+				listDetails[k].Product.Amount = listDetails[k].Product.Amount.Add(v.Amount)
+				if err := tx.Save(&listDetails[k].Product).Error; err != nil {
 					return err
 				}
 
-				locationRule, err := models.NewLocationProductSearch().SetProductId(v.ID).SetAreaId(operation.ToLocationID).First()
-				if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
-					return err
-				}
-
-				if err == nil {
-					operationTransfer := &models.Operation{
-						Number:            operation.Number,
-						SourceNumber:      operation.SourceNumber,
-						OperationTypeId:   0,
-						OperationTypeName: operation.OperationTypeName,
-						Status:            constvar.OperationStatus_Finish,
-						FromLocationID:    locationRule.AreaId,
-						ToLocationID:      locationRule.LocationId,
-						OperationDate:     operation.OperationDate,
-						ContacterID:       operation.ContacterID,
-						ContacterName:     operation.ContacterName,
-						CompanyID:         operation.CompanyID,
-						CompanyName:       operation.CompanyName,
-						Comment:           operation.Comment,
-						BaseOperationType: constvar.BaseOperationTypeInternal,
-						Details: []*models.OperationDetails{
-							{
-								ProductId: v.ID,
-								Amount:    value,
-							},
-						},
+				if roleProduct, ok := mapLocationRoleProduct[strconv.Itoa(operation.LocationID)+v.ProductId]; ok {
+					detail := &models.OperationDetails{
+						ProductId:      v.ProductId,
+						Amount:         v.Amount,
+						FromLocationID: roleProduct.AreaId,
+						ToLocationID:   roleProduct.LocationId,
 					}
-					operationInputs = append(operationInputs, operationTransfer)
+					details = append(details, detail)
 
-					//if err := tx.Create(&operationTransfer).Error; err != nil {
-					//	return err
-					//}
-
-					locAmount, err := models.NewLocationProductAmountSearch().
-						SetProductId(v.ID).
-						SetLocationId(locationRule.LocationId).
-						First()
-					if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
-						return err
-					}
-					locAmount.LocationId = locationRule.LocationId
-					locAmount.ProductId = v.ID
-					locAmount.CreateDate = time.Now().Format("2006-01-02 15:04:05")
-					locAmount.Amount = locAmount.Amount.Add(value)
-					locAmount.ProductCategoryID = v.CategoryId
-					if res := models.NewLocationProductAmountSearch().Orm.Where("id=?", locAmount.ID).Save(locAmount); res.Error != nil {
-						return res.Error
-					}
-				} else {
-					locationRule, err = models.NewLocationProductSearch().SetProductCategoryId(v.CategoryId).SetAreaId(operation.ToLocationID).First()
-					if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
-						return err
-					}
-					if err == nil {
-						operationTransfer := &models.Operation{
-							Number:            operation.Number,
-							SourceNumber:      operation.SourceNumber,
-							OperationTypeId:   0,
-							OperationTypeName: operation.OperationTypeName,
-							Status:            constvar.OperationStatus_Finish,
-							FromLocationID:    locationRule.AreaId,
-							ToLocationID:      locationRule.LocationId,
-							OperationDate:     operation.OperationDate,
-							ContacterID:       operation.ContacterID,
-							ContacterName:     operation.ContacterName,
-							CompanyID:         operation.CompanyID,
-							CompanyName:       operation.CompanyName,
-							Comment:           operation.Comment,
-							BaseOperationType: constvar.BaseOperationTypeInternal,
-							Details: []*models.OperationDetails{
-								{
-									ProductId: v.ID,
-									Amount:    value,
-								},
-							},
-						}
-						operationInputs = append(operationInputs, operationTransfer)
-
-						//if err := tx.Create(&operationTransfer).Error; err != nil {
-						//	return err
-						//}
-
-						locAmount, err := models.NewLocationProductAmountSearch().
-							SetProductId(v.ID).
-							SetLocationId(locationRule.LocationId).
-							First()
-						if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
-							return err
-						}
-						locAmount.LocationId = locationRule.LocationId
-						locAmount.ProductId = v.ID
-						locAmount.CreateDate = time.Now().Format("2006-01-02 15:04:05")
-						locAmount.Amount = locAmount.Amount.Add(value)
-						locAmount.ProductCategoryID = v.CategoryId
+					if locAmount, aok := mapLocAmount[strconv.Itoa(roleProduct.LocationId)+v.ProductId]; aok {
+						locAmount.Amount = locAmount.Amount.Add(v.Amount)
 						if res := models.NewLocationProductAmountSearch().Orm.Where("id=?", locAmount.ID).Save(locAmount); res.Error != nil {
 							return res.Error
 						}
 					} else {
-						locAmount, err := models.NewLocationProductAmountSearch().
-							SetProductId(v.ID).
-							SetLocationId(operation.ToLocationID).
-							First()
-						if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
+						if err := models.NewLocationProductAmountSearch().Create(&models.LocationProductAmount{
+							LocationId:        roleProduct.LocationId,
+							ProductCategoryID: v.Product.CategoryId,
+							ProductId:         v.ProductId,
+							Amount:            v.Amount,
+							CreateDate:        time.Now().Format("2006-01-02 15:04:05"),
+						}); err != nil {
 							return err
 						}
-						locAmount.LocationId = operation.ToLocationID
-						locAmount.ProductId = v.ID
-						locAmount.CreateDate = time.Now().Format("2006-01-02 15:04:05")
-						locAmount.Amount = locAmount.Amount.Add(value)
-						locAmount.ProductCategoryID = v.CategoryId
-						if res := models.NewLocationProductAmountSearch().Orm.Where("id=?", locAmount.ID).Save(locAmount); res.Error != nil {
-							return res.Error
+					}
+				} else {
+					if roleCategory, cok := mapLocationRoleCategory[strconv.Itoa(operation.LocationID)+strconv.Itoa(v.Product.CategoryId)]; cok {
+						detail := &models.OperationDetails{
+							ProductId:      v.ProductId,
+							Amount:         v.Amount,
+							FromLocationID: roleCategory.AreaId,
+							ToLocationID:   roleCategory.LocationId,
+						}
+						details = append(details, detail)
+
+						if locAmount, aok := mapLocAmount[strconv.Itoa(roleCategory.LocationId)+v.ProductId]; aok {
+							locAmount.Amount = locAmount.Amount.Add(v.Amount)
+							if res := models.NewLocationProductAmountSearch().Orm.Where("id=?", locAmount.ID).Save(locAmount); res.Error != nil {
+								return res.Error
+							}
+						} else {
+							if err := models.NewLocationProductAmountSearch().Create(&models.LocationProductAmount{
+								LocationId:        roleCategory.LocationId,
+								ProductCategoryID: v.Product.CategoryId,
+								ProductId:         v.ProductId,
+								Amount:            v.Amount,
+								CreateDate:        time.Now().Format("2006-01-02 15:04:05"),
+							}); err != nil {
+								return err
+							}
+						}
+					} else {
+						if locAmount, aok := mapLocAmount[strconv.Itoa(operation.LocationID)+v.ProductId]; aok {
+							locAmount.Amount = locAmount.Amount.Add(v.Amount)
+							if res := models.NewLocationProductAmountSearch().Orm.Where("id=?", locAmount.ID).Save(locAmount); res.Error != nil {
+								return res.Error
+							}
+						} else {
+							if err := models.NewLocationProductAmountSearch().Create(&models.LocationProductAmount{
+								LocationId:        operation.LocationID,
+								ProductCategoryID: v.Product.CategoryId,
+								ProductId:         v.ProductId,
+								Amount:            v.Amount,
+								CreateDate:        time.Now().Format("2006-01-02 15:04:05"),
+							}); err != nil {
+								return err
+							}
 						}
 					}
 				}
 			}
-			if len(operationInputs) > 0 {
-				if err := tx.Create(&operationInputs).Error; err != nil {
+			if len(details) > 0 {
+				if err := tx.Create(&models.Operation{
+					Number:            operation.Number,
+					SourceNumber:      operation.SourceNumber,
+					OperationTypeId:   0,
+					OperationTypeName: operation.OperationTypeName,
+					Status:            constvar.OperationStatus_Finish,
+					OperationDate:     operation.OperationDate,
+					ContacterID:       operation.ContacterID,
+					ContacterName:     operation.ContacterName,
+					CompanyID:         operation.CompanyID,
+					CompanyName:       operation.CompanyName,
+					Comment:           operation.Comment,
+					BaseOperationType: constvar.BaseOperationTypeInternal,
+					Details:           details,
+				}).Error; err != nil {
 					return err
 				}
 			}
@@ -547,11 +545,7 @@
 		}
 
 		if operation.BaseOperationType == constvar.BaseOperationTypeOutgoing {
-			for k, v := range listProdt {
-				value, ok := mapProdt[v.ID]
-				if !ok {
-					return errors.New("浜у搧绉嶇被寮傚父")
-				}
+			for k, v := range listDetails {
 				//todo 婕旂ず娴嬭瘯鏁版嵁
 				data, err := os.ReadFile("conf/input.json")
 				if err != nil {
@@ -563,30 +557,29 @@
 					return errors.New("鏍煎紡杞崲澶辫触")
 				}
 				if opa.OpaCheck(c, m, "operation") {
-					if v.Amount.LessThan(value) {
-						return errors.New(fmt.Sprintf("浜у搧锛�%v,搴撳瓨锛�%v,鍑哄簱锛�%v,鏁伴噺涓嶅锛屾棤娉曞畬鎴愬嚭搴撴搷浣�", v.Name, v.Amount.String(), value.String()))
+					if v.Product.Amount.LessThan(v.Amount) {
+						return errors.New(fmt.Sprintf("浜у搧锛�%v,搴撳瓨锛�%v,鍑哄簱锛�%v,鏁伴噺涓嶅锛屾棤娉曞畬鎴愬嚭搴撴搷浣�", v.Product.Name, v.Product.Amount.String(), v.Amount.String()))
 					}
 				}
-				listProdt[k].Amount = listProdt[k].Amount.Sub(value)
-				if err := tx.Save(listProdt[k]).Error; err != nil {
+				//todo ================end===============================
+				if v.Product.Amount.LessThan(v.Amount) {
+					return errors.New(fmt.Sprintf("浜у搧锛�%v,搴撳瓨锛�%v,鍑哄簱锛�%v,鏁伴噺涓嶅锛屾棤娉曞畬鎴愬嚭搴撴搷浣�", v.Product.Name, v.Product.Amount.String(), v.Amount.String()))
+				}
+				listDetails[k].Product.Amount = listDetails[k].Product.Amount.Sub(v.Amount)
+				if err := tx.Save(&listDetails[k].Product).Error; err != nil {
 					return err
 				}
-				locAmount, res := models.NewLocationProductAmountSearch().
-					SetProductId(v.ID).
-					SetLocationId(operation.FromLocationID).
-					FirstRes()
-				if res.Error != nil {
-					if res.Error == gorm.ErrRecordNotFound {
-						return errors.New("褰撳墠浠撳簱娌℃湁璇ヤ骇鍝�,璇峰厛鍏ュ簱")
+
+				if locAmount, aok := mapLocAmount[strconv.Itoa(v.FromLocationID)+v.ProductId]; aok {
+					if locAmount.Amount.LessThan(v.Amount) {
+						return errors.New(fmt.Sprintf("浜у搧锛�%v,搴撳瓨锛�%v,鍑哄簱锛�%v,鏁伴噺涓嶅锛屾棤娉曞畬鎴愬嚭搴撴搷浣�", v.Product.Name, locAmount.Amount.String(), v.Amount.String()))
 					}
-					return res.Error
-				}
-				if locAmount.Amount.LessThan(value) {
-					return errors.New(fmt.Sprintf("浜у搧锛�%v,搴撳瓨锛�%v,鍑哄簱锛�%v,鏁伴噺涓嶅锛屾棤娉曞畬鎴愬嚭搴撴搷浣�", v.Name, v.Amount.String(), value.String()))
-				}
-				locAmount.Amount = locAmount.Amount.Sub(value)
-				if err := models.NewLocationProductAmountSearch().SetID(locAmount.Id).Update(locAmount); err != nil {
-					return err
+					locAmount.Amount = locAmount.Amount.Sub(v.Amount)
+					if err := models.NewLocationProductAmountSearch().SetID(locAmount.Id).Update(locAmount); err != nil {
+						return err
+					}
+				} else {
+					return errors.New("褰撳墠浠撳簱娌℃湁璇ヤ骇鍝�,璇峰厛鍏ュ簱")
 				}
 			}
 			if operation.Source != "" {
@@ -595,150 +588,34 @@
 		}
 
 		if operation.BaseOperationType == constvar.BaseOperationTypeInternal {
-			var operationInputs []*models.Operation
-			for _, v := range listProdt {
-				value, ok := mapProdt[v.ID]
-				if !ok {
-					return errors.New("浜у搧绉嶇被寮傚父")
-				}
-				//listProdt[k].Amount = listProdt[k].Amount.Add(value)
-				//if err := tx.Save(listProdt[k]).Error; err != nil {
-				//	return err
-				//}
-				fromLocAmount, res := models.NewLocationProductAmountSearch().
-					SetProductId(v.ID).
-					SetLocationId(operation.FromLocationID).
-					FirstRes()
-				if res.Error != nil {
-					return err
-				}
-				if fromLocAmount.Amount.LessThan(value) {
-					return errors.New(fmt.Sprintf("浜у搧锛�%v,搴撳瓨锛�%v,璋冩嫧锛�%v,鏁伴噺涓嶅锛屾棤娉曞畬鎴愯皟鎷ㄦ搷浣�", v.Name, v.Amount.String(), value.String()))
-				}
-				fromLocAmount.Amount = fromLocAmount.Amount.Sub(value)
-				if err := models.NewLocationProductAmountSearch().SetID(fromLocAmount.Id).Update(fromLocAmount); err != nil {
-					return err
-				}
-
-				locationRule, err := models.NewLocationProductSearch().SetProductId(v.ID).SetAreaId(operation.ToLocationID).First()
-				if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
-					return err
-				}
-
-				if err == nil {
-					operationTransfer := &models.Operation{
-						Number:            operation.Number,
-						SourceNumber:      operation.SourceNumber,
-						OperationTypeId:   0,
-						OperationTypeName: operation.OperationTypeName,
-						Status:            constvar.OperationStatus_Finish,
-						FromLocationID:    locationRule.AreaId,
-						ToLocationID:      locationRule.LocationId,
-						OperationDate:     operation.OperationDate,
-						ContacterID:       operation.ContacterID,
-						ContacterName:     operation.ContacterName,
-						CompanyID:         operation.CompanyID,
-						CompanyName:       operation.CompanyName,
-						Comment:           operation.Comment,
-						BaseOperationType: constvar.BaseOperationTypeInternal,
-						Details: []*models.OperationDetails{
-							{
-								ProductId: v.ID,
-								Amount:    value,
-							},
-						},
+			for _, v := range listDetails {
+				if fromLocAmount, aok := mapLocAmount[strconv.Itoa(v.FromLocationID)+v.ProductId]; aok {
+					if fromLocAmount.Amount.LessThan(v.Amount) {
+						return errors.New(fmt.Sprintf("浜у搧锛�%v,搴撳瓨锛�%v,鍑哄簱锛�%v,鏁伴噺涓嶅锛屾棤娉曞畬鎴愬嚭搴撴搷浣�", v.Product.Name, fromLocAmount.Amount.String(), v.Amount.String()))
 					}
-					operationInputs = append(operationInputs, operationTransfer)
-
-					//if err := tx.Create(&operationTransfer).Error; err != nil {
-					//	return err
-					//}
-
-					locAmount, err := models.NewLocationProductAmountSearch().
-						SetProductId(v.ID).
-						SetLocationId(locationRule.LocationId).
-						First()
-					if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
+					fromLocAmount.Amount = fromLocAmount.Amount.Sub(v.Amount)
+					if err := models.NewLocationProductAmountSearch().SetID(fromLocAmount.Id).Update(fromLocAmount); err != nil {
 						return err
-					}
-					locAmount.LocationId = locationRule.LocationId
-					locAmount.ProductId = v.ID
-					locAmount.CreateDate = time.Now().Format("2006-01-02 15:04:05")
-					locAmount.Amount = locAmount.Amount.Add(value)
-					locAmount.ProductCategoryID = v.CategoryId
-					if res := models.NewLocationProductAmountSearch().Orm.Where("id=?", locAmount.ID).Save(locAmount); res.Error != nil {
-						return res.Error
 					}
 				} else {
-					locationRule, err = models.NewLocationProductSearch().SetProductCategoryId(v.CategoryId).SetAreaId(operation.ToLocationID).First()
-					if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
+					return errors.New("褰撳墠浠撳簱娌℃湁璇ヤ骇鍝�,璇峰厛鍏ュ簱")
+				}
+
+				if toLocAmount, aok := mapLocAmount[strconv.Itoa(v.ToLocationID)+v.ProductId]; aok {
+					toLocAmount.Amount = toLocAmount.Amount.Add(v.Amount)
+					if err := models.NewLocationProductAmountSearch().SetID(toLocAmount.Id).Update(toLocAmount); err != nil {
 						return err
 					}
-					if err == nil {
-						operationTransfer := &models.Operation{
-							Number:            operation.Number,
-							SourceNumber:      operation.SourceNumber,
-							OperationTypeId:   0,
-							OperationTypeName: operation.OperationTypeName,
-							Status:            constvar.OperationStatus_Finish,
-							FromLocationID:    locationRule.AreaId,
-							ToLocationID:      locationRule.LocationId,
-							OperationDate:     operation.OperationDate,
-							ContacterID:       operation.ContacterID,
-							ContacterName:     operation.ContacterName,
-							CompanyID:         operation.CompanyID,
-							CompanyName:       operation.CompanyName,
-							Comment:           operation.Comment,
-							BaseOperationType: constvar.BaseOperationTypeInternal,
-							Details: []*models.OperationDetails{
-								{
-									ProductId: v.ID,
-									Amount:    value,
-								},
-							},
-						}
-						operationInputs = append(operationInputs, operationTransfer)
-
-						//if err := tx.Create(&operationTransfer).Error; err != nil {
-						//	return err
-						//}
-
-						locAmount, err := models.NewLocationProductAmountSearch().
-							SetProductId(v.ID).
-							SetLocationId(locationRule.LocationId).
-							First()
-						if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
-							return err
-						}
-						locAmount.LocationId = locationRule.LocationId
-						locAmount.ProductId = v.ID
-						locAmount.CreateDate = time.Now().Format("2006-01-02 15:04:05")
-						locAmount.Amount = locAmount.Amount.Add(value)
-						locAmount.ProductCategoryID = v.CategoryId
-						if res := models.NewLocationProductAmountSearch().Orm.Where("id=?", locAmount.ID).Save(locAmount); res.Error != nil {
-							return res.Error
-						}
-					} else {
-						locAmount, err := models.NewLocationProductAmountSearch().
-							SetProductId(v.ID).
-							SetLocationId(operation.ToLocationID).
-							First()
-						if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
-							return err
-						}
-						locAmount.LocationId = operation.ToLocationID
-						locAmount.ProductId = v.ID
-						locAmount.CreateDate = time.Now().Format("2006-01-02 15:04:05")
-						locAmount.Amount = locAmount.Amount.Add(value)
-						if res := models.NewLocationProductAmountSearch().Orm.Where("id=?", locAmount.ID).Save(locAmount); res.Error != nil {
-							return res.Error
-						}
+				} else {
+					if err := models.NewLocationProductAmountSearch().Create(&models.LocationProductAmount{
+						LocationId:        v.ToLocationID,
+						ProductCategoryID: v.Product.CategoryId,
+						ProductId:         v.ProductId,
+						Amount:            v.Amount,
+						CreateDate:        time.Now().Format("2006-01-02 15:04:05"),
+					}); err != nil {
+						return err
 					}
-				}
-			}
-			if len(operationInputs) > 0 {
-				if err := tx.Create(&operationInputs).Error; err != nil {
-					return err
 				}
 			}
 		}
@@ -768,10 +645,10 @@
 				Amount:            v.Amount,
 				Unit:              v.Product.Unit,
 				Weight:            operation.Weight,
-				FromLocationId:    operation.FromLocationID,
-				FromLocation:      operation.FromLocation.Name,
-				ToLocationId:      operation.ToLocationID,
-				ToLocation:        operation.ToLocation.Name,
+				FromLocationId:    v.FromLocationID,
+				FromLocation:      v.FromLocation.Name,
+				ToLocationId:      v.ToLocationID,
+				ToLocation:        v.ToLocation.Name,
 			}
 			histories = append(histories, history)
 		}
@@ -983,11 +860,11 @@
 }
 
 func ExportInputSelfmade(category constvar.FileTemplateCategory, operation *models.Operation) (string, error) {
-	template, err := models.NewFileTemplateAttachmentSearch().SetPreload(true).SetCategory(category).First()
+	template, err := models.NewFileTemplateAttachmentSearch().SetCategory(category).First()
 	if err != nil {
 		return "", errors.New("鑾峰彇妯$増璁板綍澶辫触:" + err.Error())
 	}
-	readerCloser, err := http.HttpGetWithReadCloser(template.Attachment.FileUrl)
+	readerCloser, err := http.HttpGetWithReadCloser(template.FileUrl)
 	if err != nil {
 		return "", errors.New("鑾峰彇妯$増澶辫触:" + err.Error())
 	}
@@ -1030,7 +907,7 @@
 		f.SetCellValue("Sheet1", "C"+strconv.Itoa(rowIndex), v.Product.Specs)
 		f.SetCellValue("Sheet1", "D"+strconv.Itoa(rowIndex), v.Product.Unit)
 		f.SetCellValue("Sheet1", "E"+strconv.Itoa(rowIndex), v.Amount.String())
-		f.SetCellValue("Sheet1", "H"+strconv.Itoa(rowIndex), operation.ToLocation.Name)
+		f.SetCellValue("Sheet1", "H"+strconv.Itoa(rowIndex), v.ToLocation.Name)
 		f.SetCellValue("Sheet1", "I"+strconv.Itoa(rowIndex), operation.Comment)
 		rowIndex++
 		totalAmount = totalAmount.Add(v.Amount)
@@ -1063,12 +940,12 @@
 }
 
 func ExportOutputOperation(category constvar.FileTemplateCategory, operation *models.Operation) (string, error) {
-	repositoryLevels := strings.Split(operation.FromLocation.JointName, "/")
-	template, err := models.NewFileTemplateAttachmentSearch().SetPreload(true).SetCategory(category).First()
+	repositoryLevels := strings.Split(operation.Location.JointName, "/")
+	template, err := models.NewFileTemplateAttachmentSearch().SetCategory(category).First()
 	if err != nil {
 		return "", errors.New("鑾峰彇妯$増璁板綍澶辫触:" + err.Error())
 	}
-	readerCloser, err := http.HttpGetWithReadCloser(template.Attachment.FileUrl)
+	readerCloser, err := http.HttpGetWithReadCloser(template.FileUrl)
 	if err != nil {
 		return "", errors.New("鑾峰彇妯$増澶辫触:" + err.Error())
 	}
@@ -1194,9 +1071,14 @@
 		return
 	}
 
-	db := mysqlx.GetDB().Table("wms_operation").Select("wms_operation.id as operation_id,wms_operation.number,wms_operation.base_operation_type,material.id AS product_id,material.`name` AS product_name,wms_operation_details.amount,material.unit,wms_operation.from_location_id,from_location.`name` AS from_location,wms_operation.to_location_id,to_location.`name` AS to_location,wms_operation.operation_date as date,wms_operation.`status`").InnerJoins("inner join wms_operation_details ON wms_operation_details.operation_id = wms_operation.id").InnerJoins("INNER JOIN material ON material.id = wms_operation_details.product_id").InnerJoins("INNER JOIN wms_location AS from_location ON from_location.id = wms_operation.from_location_id").InnerJoins("INNER JOIN wms_location AS to_location ON to_location.id = wms_operation.to_location_id")
+	db := mysqlx.GetDB().Table("wms_operation").
+		Select("wms_operation.id as operation_id,wms_operation.number,wms_operation.base_operation_type,material.id AS product_id,material.`name` AS product_name,wms_operation_details.amount,material.unit,wms_operation_details.from_location_id,from_location.`name` AS from_location,wms_operation_details.to_location_id,to_location.`name` AS to_location,wms_operation.operation_date as date,wms_operation.`status`").
+		InnerJoins("inner join wms_operation_details ON wms_operation_details.operation_id = wms_operation.id").
+		InnerJoins("INNER JOIN material ON material.id = wms_operation_details.product_id").
+		InnerJoins("INNER JOIN wms_location AS from_location ON from_location.id = wms_operation_details.from_location_id").
+		InnerJoins("INNER JOIN wms_location AS to_location ON to_location.id = wms_operation_details.to_location_id")
 	if params.Condition != "" {
-		db = db.Where("wms_operation.number like ? or wms_operation.source_number like ? or from_location.`name` like ? or to_location.`name` like ?", "%"+params.Condition+"%", "%"+params.Condition+"%", "%"+params.Condition+"%", "%"+params.Condition+"%")
+		db = db.Where("wms_operation.number like ? or wms_operation.source_number like ? or from_location.`name` like ? or to_location.`name` like ? or material.`name` like ? ", "%"+params.Condition+"%", "%"+params.Condition+"%", "%"+params.Condition+"%", "%"+params.Condition+"%", "%"+params.Condition+"%")
 	}
 	var (
 		records = make([]*response.InventoryHistory, 0)
@@ -1208,7 +1090,7 @@
 		return
 	}
 
-	if err := db.Offset((params.Page - 1) * params.PageSize).Limit(params.PageSize).Find(&records).Error; err != nil {
+	if err := db.Offset((params.Page - 1) * params.PageSize).Limit(params.PageSize).Order("wms_operation.created_at desc").Find(&records).Error; err != nil {
 		util.ResponseFormat(c, code.RequestError, "鏌ユ壘澶辫触:"+err.Error())
 		return
 	}
diff --git a/controllers/product_controller.go b/controllers/product_controller.go
index 449e97b..84d970e 100644
--- a/controllers/product_controller.go
+++ b/controllers/product_controller.go
@@ -12,6 +12,7 @@
 	"wms/constvar"
 	"wms/extend/code"
 	"wms/extend/util"
+	"wms/middleware"
 	"wms/models"
 	"wms/pkg/logx"
 	"wms/pkg/mysqlx"
@@ -464,8 +465,10 @@
 	}
 
 	detail := &models.OperationDetails{
-		ProductId: params.ProductId,
-		Amount:    params.Amount,
+		ProductId:      params.ProductId,
+		Amount:         params.Amount,
+		FromLocationID: params.FromLocationId,
+		ToLocationID:   params.ToLocationId,
 	}
 	operation := models.Operation{
 		//Number:            strconv.FormatInt(time.Now().Unix(), 10),
@@ -473,8 +476,6 @@
 		SourceNumber:      params.SourceNumber,
 		OperationTypeId:   0,
 		Status:            constvar.OperationStatus_Ready,
-		FromLocationID:    params.FromLocationId,
-		ToLocationID:      params.ToLocationId,
 		OperationDate:     time.Now().Format("2006-01-02 15:04:05"),
 		Details:           []*models.OperationDetails{detail},
 		BaseOperationType: constvar.BaseOperationTypeDisuse,
@@ -505,7 +506,12 @@
 		return
 	}
 
-	db := models.NewOperationSearch().Orm.Table("wms_operation").Select("wms_operation.id,wms_operation.number,wms_operation.source_number,wms_operation.status,wms_operation.from_location_id,wms_operation.to_location_id,wms_operation.operation_date,wms_operation.contacter_id,wms_operation.contacter_name,wms_operation.company_id,wms_operation.company_name,wms_operation.comment,wms_operation_details.product_id,material.name as product_name,material.unit,wms_operation_details.amount,wms_operation.base_operation_type").InnerJoins("inner join wms_operation_details on wms_operation_details.operation_id=wms_operation.id").InnerJoins("inner join material on material.id=wms_operation_details.product_id").Where("wms_operation.base_operation_type=?", constvar.BaseOperationTypeDisuse)
+	db := models.NewOperationSearch().Orm.
+		Table("wms_operation").
+		Select("wms_operation.id,wms_operation.number,wms_operation.source_number,wms_operation.status,wms_operation_details.from_location_id,wms_operation_details.to_location_id,wms_operation.operation_date,wms_operation.contacter_id,wms_operation.contacter_name,wms_operation.company_id,wms_operation.company_name,wms_operation.comment,wms_operation_details.product_id,material.name as product_name,material.unit,wms_operation_details.amount,wms_operation.base_operation_type").
+		InnerJoins("inner join wms_operation_details on wms_operation_details.operation_id=wms_operation.id").
+		InnerJoins("inner join material on material.id=wms_operation_details.product_id").
+		Where("wms_operation.base_operation_type=?", constvar.BaseOperationTypeDisuse)
 
 	if params.Number != "" {
 		db = db.Where("wms_operation.number like ? or wms_operation.source_number like ? or material.name like ?", fmt.Sprintf("%%%v%%", params.Number), fmt.Sprintf("%%%v%%", params.Number), fmt.Sprintf("%%%v%%", params.Number))
@@ -564,62 +570,34 @@
 		if err := models.NewOperationSearch().SetOrm(tx).SetID(id).Update(&models.Operation{Status: constvar.OperationStatus_Finish, AuditDate: time.Now().Format("2006-01-02 15:04:05")}); err != nil {
 			return err
 		}
-		var listProdtId []string
-		var listProdt []*models.Material
-		mapProdt := make(map[string]decimal.Decimal)
-		listDetails, err := models.NewOperationDetailsSearch().SetOperationId(operation.Id).FindAll()
+
+		listDetails, err := models.NewOperationDetailsSearch().SetOperationId(operation.Id).SetPreload(true).FindAll()
 		if err != nil {
 			return err
 		}
-		for _, v := range listDetails {
-			listProdtId = append(listProdtId, v.ProductId)
-			mapProdt[v.ProductId] = v.Amount
-		}
-		if err := models.NewMaterialSearch().Orm.Where("id IN ?", listProdtId).Find(&listProdt).Error; err != nil {
-			return err
-		}
-		for k, v := range listProdt {
-			if value, ok := mapProdt[v.ID]; !ok {
-				return errors.New("浜у搧绉嶇被寮傚父")
-			} else {
-				if v.Amount.LessThan(value) {
-					return errors.New(fmt.Sprintf("浜у搧锛�%v,搴撳瓨锛�%v,鎶ュ簾锛�%v,鏁伴噺涓嶅锛屾棤娉曞畬鎴愭姤搴熸搷浣�", v.Name, v.Amount.String(), value.String()))
-				}
-				listProdt[k].Amount = listProdt[k].Amount.Sub(value)
-				if err := tx.Save(listProdt[k]).Error; err != nil {
-					return err
-				}
 
-				//var locAmount models.LocationProductAmount
-				//if err := models.NewLocationProductAmountSearch().Orm.
-				//	Table("wms_location_product_amount").
-				//	Joins("inner join wms_location_product on wms_location_product.id=wms_location_product_amount.location_product_id").
-				//	Where("wms_location_product.product_id=? and wms_location_product.location_id=?", v.ID, operation.FromLocationID).
-				//	First(&locAmount).Error; err != nil {
-				//	return err
-				//}
-				//if locAmount.Amount.LessThan(value) {
-				//	return errors.New(fmt.Sprintf("浜у搧锛�%v,搴撳瓨锛�%v,鍑哄簱锛�%v,鏁伴噺涓嶅锛屾棤娉曞畬鎴愬嚭搴撴搷浣�", v.Name, v.Amount.String(), value.String()))
-				//}
-				//locAmount.Amount = locAmount.Amount.Sub(value)
-				//if err := models.NewLocationProductAmountSearch().SetID(locAmount.Id).Update(&locAmount); err != nil {
-				//	return err
-				//}
+		for k, v := range listDetails {
+			if v.Product.Amount.LessThan(v.Amount) {
+				return errors.New(fmt.Sprintf("浜у搧锛�%v,搴撳瓨锛�%v,鎶ュ簾锛�%v,鏁伴噺涓嶅锛屾棤娉曞畬鎴愭姤搴熸搷浣�", v.Product.Name, v.Product.Amount.String(), v.Amount.String()))
+			}
+			listDetails[k].Product.Amount = listDetails[k].Product.Amount.Sub(v.Amount)
+			if err := tx.Save(&listDetails[k].Product).Error; err != nil {
+				return err
+			}
 
-				locAmount, res := models.NewLocationProductAmountSearch().
-					SetProductId(v.ID).
-					SetLocationId(operation.FromLocationID).
-					FirstRes()
-				if res.Error != nil {
-					return err
-				}
-				if locAmount.Amount.LessThan(value) {
-					return errors.New(fmt.Sprintf("浜у搧锛�%v,搴撳瓨锛�%v,鎶ュ簾锛�%v,鏁伴噺涓嶅锛屾棤娉曞畬鎴愭姤搴熸搷浣�", v.Name, v.Amount.String(), value.String()))
-				}
-				locAmount.Amount = locAmount.Amount.Sub(value)
-				if err := models.NewLocationProductAmountSearch().SetID(locAmount.Id).Update(locAmount); err != nil {
-					return err
-				}
+			locAmount, res := models.NewLocationProductAmountSearch().
+				SetProductId(v.ProductId).
+				SetLocationId(v.FromLocationID).
+				FirstRes()
+			if res.Error != nil {
+				return err
+			}
+			if locAmount.Amount.LessThan(v.Amount) {
+				return errors.New(fmt.Sprintf("浜у搧锛�%v,搴撳瓨锛�%v,鎶ュ簾锛�%v,鏁伴噺涓嶅锛屾棤娉曞畬鎴愭姤搴熸搷浣�", v.Product.Name, locAmount.Amount.String(), v.Amount.String()))
+			}
+			locAmount.Amount = locAmount.Amount.Sub(v.Amount)
+			if err := models.NewLocationProductAmountSearch().SetID(locAmount.Id).Update(locAmount); err != nil {
+				return err
 			}
 		}
 		return nil
@@ -672,6 +650,8 @@
 		//ProductName: params.ProductName,
 		Amount: params.Amount,
 		//Unit:        params.Unit,
+		FromLocationID: params.FromLocationId,
+		ToLocationID:   params.ToLocationId,
 	}
 	operation := models.Operation{
 		Id:                params.Id,
@@ -679,8 +659,6 @@
 		SourceNumber:      params.SourceNumber,
 		OperationTypeId:   0,
 		Status:            params.Status,
-		FromLocationID:    params.FromLocationId,
-		ToLocationID:      params.ToLocationId,
 		OperationDate:     params.OperationDate,
 		Details:           []*models.OperationDetails{detail},
 		BaseOperationType: params.BaseOperationType,
@@ -723,7 +701,7 @@
 	}
 
 	search := models.NewOperationSearch().SetPage(params.Page, params.PageSize).SetPreload(true).SetOrder("created_at desc")
-	search.SetOrm(search.Orm.InnerJoins("inner join wms_operation_details on wms_operation_details.operation_id=wms_operation.id").Where("wms_operation_details.product_id=? and (wms_operation.from_location_id=? or wms_operation.to_location_id=?)", params.ProductId, params.LocationId, params.LocationId))
+	search.SetOrm(search.Orm.InnerJoins("inner join wms_operation_details on wms_operation_details.operation_id=wms_operation.id").Where("wms_operation_details.product_id=? and (wms_operation_details.from_location_id=? or wms_operation_details.to_location_id=?)", params.ProductId, params.LocationId, params.LocationId))
 
 	list, total, err := search.SetBaseOperationType(constvar.BaseOperationTypeAdjust).Find()
 	if err != nil {
@@ -769,3 +747,17 @@
 	}
 	util.ResponseFormat(c, code.Success, "鎿嶄綔鎴愬姛")
 }
+
+// GetUserInfo
+//
+//	@Tags		浜у搧
+//	@Summary	鑾峰彇鐧诲綍鐢ㄦ埛淇℃伅
+//	@Produce	application/json
+//	@Success	200	{object}	util.ResponseList{data=map[string]interface{}}	"鎴愬姛"
+//	@Router		/api-wms/v1/product/getUserInfo [get]
+func (slf ProductController) GetUserInfo(c *gin.Context) {
+	userInfo := middleware.GetUserInfo(c)
+	m := make(map[string]interface{})
+	m["userName"] = userInfo.Username
+	util.ResponseFormat(c, code.Success, m)
+}
diff --git a/controllers/reorder_rule_controller.go b/controllers/reorder_rule_controller.go
index d1fce38..2a42385 100644
--- a/controllers/reorder_rule_controller.go
+++ b/controllers/reorder_rule_controller.go
@@ -150,17 +150,17 @@
 	var pa []request.ProductAmount
 	search := models.NewOperationDetailsSearch()
 	search.Orm = search.Orm.Model(&models.OperationDetails{}).
-		Select("wms_operation_details.product_id, wms_operation_details.amount, wms_operation.to_location_id as to_location_id, " +
-			"wms_operation.from_location_id as from_location_id, wms_operation.base_operation_type").
+		Select("wms_operation_details.product_id, wms_operation_details.amount, wms_operation_details.to_location_id as to_location_id, " +
+			"wms_operation_details.from_location_id as from_location_id, wms_operation.base_operation_type").
 		Joins("left join wms_operation on wms_operation_details.operation_id = wms_operation.id")
 	if len(productIds) > 0 {
 		search.Orm.Where("wms_operation_details.product_id in (?)", productIds)
 	}
 	if len(toLocationIds) > 0 {
-		search.Orm.Where("wms_operation.to_location_id in (?)", toLocationIds)
+		search.Orm.Where("wms_operation_details.to_location_id in (?)", toLocationIds)
 	}
 	if len(fromLocationIds) > 0 {
-		search.Orm.Where("wms_operation.from_location_id in (?)", fromLocationIds)
+		search.Orm.Where("wms_operation_details.from_location_id in (?)", fromLocationIds)
 	}
 	if len(status) > 0 {
 		search.Orm.Where("wms_operation.status in (?)", status)
@@ -332,16 +332,17 @@
 	var details models.OperationDetails
 	details.ProductId = params.ProductId
 	details.Amount = params.OrderNumber
+	details.FromLocationID = 1
+	details.ToLocationID = params.LocationId
 	operation.Details = append(operation.Details, &details)
 	operation.BaseOperationType = constvar.BaseOperationTypeIncoming
 	operation.Status = constvar.OperationStatus_Ready
 	operation.OperationTypeId = operationType.Id
 	operation.OperationTypeName = operationType.Name
 	operation.OperationDate = timex.TimeToString2(time.Now())
-	//todo 渚涘簲鍟嗕綅缃�
-	operation.FromLocationID = 1
+	operation.LocationID = params.LocationId
 	operation.Number = strconv.FormatInt(time.Now().Unix(), 10)
-	operation.ToLocationID = params.LocationId
+
 	operation.SourceNumber = SourceNumber
 
 	err = models.WithTransaction(func(db *gorm.DB) error {
diff --git a/controllers/report_forms_controller.go b/controllers/report_forms_controller.go
index a495b07..ced1c45 100644
--- a/controllers/report_forms_controller.go
+++ b/controllers/report_forms_controller.go
@@ -97,8 +97,8 @@
 		Where("wms_operation.base_operation_type in (?)", []constvar.BaseOperationType{constvar.BaseOperationTypeOutgoing, constvar.BaseOperationTypeInternal, constvar.BaseOperationTypeDisuse}).
 		Where("wms_operation.status in (?)", []constvar.OperationStatus{constvar.OperationStatus_Ready, constvar.OperationStatus_Finish})
 	if len(locationIds) > 0 {
-		dbIn.Where("wms_operation.to_location_id in (?)", locationIds)
-		dbOut.Where("wms_operation.from_location_id in (?)", locationIds)
+		dbIn.Where("wms_operation_details.to_location_id in (?)", locationIds)
+		dbOut.Where("wms_operation_details.from_location_id in (?)", locationIds)
 	}
 	if len(productIds) > 0 {
 		dbIn.Where("wms_operation_details.product_id in (?)", productIds)
diff --git a/controllers/warehouse.go b/controllers/warehouse.go
index bc2aa7f..f9b54c9 100644
--- a/controllers/warehouse.go
+++ b/controllers/warehouse.go
@@ -122,7 +122,34 @@
 		util.ResponseFormat(c, code.RequestParamError, err.Error())
 		return
 	}
-	err := models.NewWarehouseSearch().SetID(params.Id).Update(&params)
+	warehouse, err := models.NewWarehouseSearch().SetID(params.Id).First()
+	if err != nil {
+		util.ResponseFormat(c, code.RequestParamError, "浠撳簱涓嶅瓨鍦�")
+		return
+	}
+	err = models.WithTransaction(func(db *gorm.DB) error {
+		//鏇存柊浣滀笟绫诲瀷鍚嶇О
+		if params.Name != warehouse.Name {
+			m := make(map[string]interface{})
+			m["name"] = params.Name + "-鍏ュ簱"
+			err := models.NewOperationTypeSearch().SetOrm(db).SetBaseOperationType(constvar.BaseOperationTypeIncoming).SetWarehouseId(params.Id).UpdateByMap(m)
+			if err != nil {
+				return err
+			}
+			m["name"] = params.Name + "-鍑哄簱"
+			err = models.NewOperationTypeSearch().SetOrm(db).SetBaseOperationType(constvar.BaseOperationTypeOutgoing).SetWarehouseId(params.Id).UpdateByMap(m)
+			if err != nil {
+				return err
+			}
+			m["name"] = params.Name + "-鍐呴儴璋冩嫧"
+			err = models.NewOperationTypeSearch().SetOrm(db).SetBaseOperationType(constvar.BaseOperationTypeInternal).SetWarehouseId(params.Id).UpdateByMap(m)
+			if err != nil {
+				return err
+			}
+		}
+		err = models.NewWarehouseSearch().SetID(params.Id).Update(&params)
+		return err
+	})
 
 	if err != nil {
 		util.ResponseFormat(c, code.RequestParamError, "淇敼澶辫触")
diff --git a/docs/docs.go b/docs/docs.go
index 9db38a4..5a2c468 100644
--- a/docs/docs.go
+++ b/docs/docs.go
@@ -1930,6 +1930,38 @@
                 }
             }
         },
+        "/api-wms/v1/product/getUserInfo": {
+            "get": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "浜у搧"
+                ],
+                "summary": "鑾峰彇鐧诲綍鐢ㄦ埛淇℃伅",
+                "responses": {
+                    "200": {
+                        "description": "鎴愬姛",
+                        "schema": {
+                            "allOf": [
+                                {
+                                    "$ref": "#/definitions/util.ResponseList"
+                                },
+                                {
+                                    "type": "object",
+                                    "properties": {
+                                        "data": {
+                                            "type": "object",
+                                            "additionalProperties": true
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                }
+            }
+        },
         "/api-wms/v1/product/listDisuse": {
             "post": {
                 "produces": [
@@ -2748,12 +2780,26 @@
             "enum": [
                 "鍘熸潗鏂�",
                 "鍗婃垚鍝�",
-                "鎴愬搧"
+                "鎴愬搧",
+                "杈呮枡",
+                "鑰楁潗",
+                "鍏朵粬",
+                "铏氭嫙浠�"
             ],
+            "x-enum-comments": {
+                "MaterialModeAuxiliary": "杈呮枡",
+                "MaterialModeConsumables": "鑰楁潗",
+                "MaterialModeOther": "鍏朵粬",
+                "MaterialModeVirtual": "铏氭嫙浠�, 涓嶈兘閿�鍞紝涓嶈兘鍑哄叆搴擄紝涓嶈兘閲囪喘"
+            },
             "x-enum-varnames": [
                 "MaterialModeRaw",
                 "MaterialModeSemi",
-                "MaterialModeFinished"
+                "MaterialModeFinished",
+                "MaterialModeAuxiliary",
+                "MaterialModeConsumables",
+                "MaterialModeOther",
+                "MaterialModeVirtual"
             ]
         },
         "constvar.OperationStatus": {
@@ -3352,7 +3398,10 @@
                         "$ref": "#/definitions/models.OperationDetails"
                     }
                 },
-                "fromLocation": {
+                "id": {
+                    "type": "integer"
+                },
+                "location": {
                     "description": "婧愪綅缃�",
                     "allOf": [
                         {
@@ -3360,11 +3409,8 @@
                         }
                     ]
                 },
-                "fromLocationId": {
+                "locationID": {
                     "description": "婧愪綅缃甶d",
-                    "type": "integer"
-                },
-                "id": {
                     "type": "integer"
                 },
                 "logisticCompany": {
@@ -3382,6 +3428,7 @@
                     "type": "string"
                 },
                 "operationDate": {
+                    "description": "FromLocationID    int                      ` + "`" + `json:\"fromLocationId\"   gorm:\"type:int;not null;comment:婧愪綅缃甶d\"` + "`" + `         //婧愪綅缃甶d\nFromLocation      Location                 ` + "`" + `json:\"fromLocation\"     gorm:\"foreignKey:FromLocationID;references:Id\"` + "`" + ` //婧愪綅缃甛nToLocationID      int                      ` + "`" + `json:\"toLocationId\"    gorm:\"type:int;not null;comment:鐩爣浣嶇疆id\"` + "`" + `         //鐩爣浣嶇疆id\nToLocation        Location                 ` + "`" + `json:\"toLocation\"      gorm:\"foreignKey:ToLocationID;references:Id\"` + "`" + `    //鐩爣浣嶇疆",
                     "type": "string"
                 },
                 "operationTypeId": {
@@ -3451,6 +3498,18 @@
                 "createTime": {
                     "type": "string"
                 },
+                "fromLocation": {
+                    "description": "婧愪綅缃�",
+                    "allOf": [
+                        {
+                            "$ref": "#/definitions/models.Location"
+                        }
+                    ]
+                },
+                "fromLocationId": {
+                    "description": "婧愪綅缃甶d",
+                    "type": "integer"
+                },
                 "id": {
                     "type": "integer"
                 },
@@ -3469,6 +3528,18 @@
                 "productId": {
                     "description": "浜у搧id",
                     "type": "string"
+                },
+                "toLocation": {
+                    "description": "鐩爣浣嶇疆",
+                    "allOf": [
+                        {
+                            "$ref": "#/definitions/models.Location"
+                        }
+                    ]
+                },
+                "toLocationId": {
+                    "description": "鐩爣浣嶇疆id",
+                    "type": "integer"
                 },
                 "updateTime": {
                     "type": "string"
@@ -3781,11 +3852,11 @@
                         "$ref": "#/definitions/request.OperationDetails"
                     }
                 },
-                "fromLocationId": {
-                    "description": "婧愪綅缃甶d",
+                "id": {
                     "type": "integer"
                 },
-                "id": {
+                "locationId": {
+                    "description": "婧愪綅缃甶d",
                     "type": "integer"
                 },
                 "logisticCompanyId": {
@@ -3800,7 +3871,7 @@
                     "type": "string"
                 },
                 "operationDate": {
-                    "description": "瀹夋帓鏃ユ湡",
+                    "description": "FromLocationId    int                      ` + "`" + `json:\"fromLocationId\"   gorm:\"type:int;not null;comment:婧愪綅缃甶d\"` + "`" + `   //婧愪綅缃甶d\nToLocationId      int                      ` + "`" + `json:\"toLocationId\"    gorm:\"type:int;not null;comment:鐩爣浣嶇疆id\"` + "`" + `   //鐩爣浣嶇疆id",
                     "type": "string"
                 },
                 "operationTypeId": {
@@ -4224,9 +4295,17 @@
                     "description": "ProductName string          ` + "`" + `json:\"productName\" gorm:\"type:varchar(255);not null;comment:浜у搧鍚嶇О\"` + "`" + ` //浜у搧鍚嶇О",
                     "type": "number"
                 },
+                "fromLocationId": {
+                    "description": "Unit        string          ` + "`" + `json:\"unit\" gorm:\"type:varchar(31);comment:鍗曚綅\"` + "`" + `                    //鍗曚綅\nProduct models.Material ` + "`" + `json:\"product\" gorm:\"foreignKey:ProductId;references:ID\"` + "`" + `",
+                    "type": "integer"
+                },
                 "productId": {
                     "description": "浜у搧id",
                     "type": "string"
+                },
+                "toLocationId": {
+                    "description": "鐩爣浣嶇疆id",
+                    "type": "integer"
                 }
             }
         },
@@ -4489,11 +4568,11 @@
                         "$ref": "#/definitions/request.OperationDetails"
                     }
                 },
-                "fromLocationId": {
-                    "description": "婧愪綅缃甶d",
+                "id": {
                     "type": "integer"
                 },
-                "id": {
+                "locationId": {
+                    "description": "婧愪綅缃甶d",
                     "type": "integer"
                 },
                 "logisticCompanyId": {
@@ -4508,7 +4587,7 @@
                     "type": "string"
                 },
                 "operationDate": {
-                    "description": "瀹夋帓鏃ユ湡",
+                    "description": "FromLocationId    int                        ` + "`" + `json:\"fromLocationId\"   gorm:\"type:int;not null;comment:婧愪綅缃甶d\"` + "`" + `   //婧愪綅缃甶d\nToLocationId      int                        ` + "`" + `json:\"toLocationId\"    gorm:\"type:int;not null;comment:鐩爣浣嶇疆id\"` + "`" + `   //鐩爣浣嶇疆id",
                     "type": "string"
                 },
                 "operationTypeId": {
diff --git a/docs/swagger.json b/docs/swagger.json
index c1acd3f..fce1458 100644
--- a/docs/swagger.json
+++ b/docs/swagger.json
@@ -1918,6 +1918,38 @@
                 }
             }
         },
+        "/api-wms/v1/product/getUserInfo": {
+            "get": {
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "浜у搧"
+                ],
+                "summary": "鑾峰彇鐧诲綍鐢ㄦ埛淇℃伅",
+                "responses": {
+                    "200": {
+                        "description": "鎴愬姛",
+                        "schema": {
+                            "allOf": [
+                                {
+                                    "$ref": "#/definitions/util.ResponseList"
+                                },
+                                {
+                                    "type": "object",
+                                    "properties": {
+                                        "data": {
+                                            "type": "object",
+                                            "additionalProperties": true
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                }
+            }
+        },
         "/api-wms/v1/product/listDisuse": {
             "post": {
                 "produces": [
@@ -2736,12 +2768,26 @@
             "enum": [
                 "鍘熸潗鏂�",
                 "鍗婃垚鍝�",
-                "鎴愬搧"
+                "鎴愬搧",
+                "杈呮枡",
+                "鑰楁潗",
+                "鍏朵粬",
+                "铏氭嫙浠�"
             ],
+            "x-enum-comments": {
+                "MaterialModeAuxiliary": "杈呮枡",
+                "MaterialModeConsumables": "鑰楁潗",
+                "MaterialModeOther": "鍏朵粬",
+                "MaterialModeVirtual": "铏氭嫙浠�, 涓嶈兘閿�鍞紝涓嶈兘鍑哄叆搴擄紝涓嶈兘閲囪喘"
+            },
             "x-enum-varnames": [
                 "MaterialModeRaw",
                 "MaterialModeSemi",
-                "MaterialModeFinished"
+                "MaterialModeFinished",
+                "MaterialModeAuxiliary",
+                "MaterialModeConsumables",
+                "MaterialModeOther",
+                "MaterialModeVirtual"
             ]
         },
         "constvar.OperationStatus": {
@@ -3340,7 +3386,10 @@
                         "$ref": "#/definitions/models.OperationDetails"
                     }
                 },
-                "fromLocation": {
+                "id": {
+                    "type": "integer"
+                },
+                "location": {
                     "description": "婧愪綅缃�",
                     "allOf": [
                         {
@@ -3348,11 +3397,8 @@
                         }
                     ]
                 },
-                "fromLocationId": {
+                "locationID": {
                     "description": "婧愪綅缃甶d",
-                    "type": "integer"
-                },
-                "id": {
                     "type": "integer"
                 },
                 "logisticCompany": {
@@ -3370,6 +3416,7 @@
                     "type": "string"
                 },
                 "operationDate": {
+                    "description": "FromLocationID    int                      `json:\"fromLocationId\"   gorm:\"type:int;not null;comment:婧愪綅缃甶d\"`         //婧愪綅缃甶d\nFromLocation      Location                 `json:\"fromLocation\"     gorm:\"foreignKey:FromLocationID;references:Id\"` //婧愪綅缃甛nToLocationID      int                      `json:\"toLocationId\"    gorm:\"type:int;not null;comment:鐩爣浣嶇疆id\"`         //鐩爣浣嶇疆id\nToLocation        Location                 `json:\"toLocation\"      gorm:\"foreignKey:ToLocationID;references:Id\"`    //鐩爣浣嶇疆",
                     "type": "string"
                 },
                 "operationTypeId": {
@@ -3439,6 +3486,18 @@
                 "createTime": {
                     "type": "string"
                 },
+                "fromLocation": {
+                    "description": "婧愪綅缃�",
+                    "allOf": [
+                        {
+                            "$ref": "#/definitions/models.Location"
+                        }
+                    ]
+                },
+                "fromLocationId": {
+                    "description": "婧愪綅缃甶d",
+                    "type": "integer"
+                },
                 "id": {
                     "type": "integer"
                 },
@@ -3457,6 +3516,18 @@
                 "productId": {
                     "description": "浜у搧id",
                     "type": "string"
+                },
+                "toLocation": {
+                    "description": "鐩爣浣嶇疆",
+                    "allOf": [
+                        {
+                            "$ref": "#/definitions/models.Location"
+                        }
+                    ]
+                },
+                "toLocationId": {
+                    "description": "鐩爣浣嶇疆id",
+                    "type": "integer"
                 },
                 "updateTime": {
                     "type": "string"
@@ -3769,11 +3840,11 @@
                         "$ref": "#/definitions/request.OperationDetails"
                     }
                 },
-                "fromLocationId": {
-                    "description": "婧愪綅缃甶d",
+                "id": {
                     "type": "integer"
                 },
-                "id": {
+                "locationId": {
+                    "description": "婧愪綅缃甶d",
                     "type": "integer"
                 },
                 "logisticCompanyId": {
@@ -3788,7 +3859,7 @@
                     "type": "string"
                 },
                 "operationDate": {
-                    "description": "瀹夋帓鏃ユ湡",
+                    "description": "FromLocationId    int                      `json:\"fromLocationId\"   gorm:\"type:int;not null;comment:婧愪綅缃甶d\"`   //婧愪綅缃甶d\nToLocationId      int                      `json:\"toLocationId\"    gorm:\"type:int;not null;comment:鐩爣浣嶇疆id\"`   //鐩爣浣嶇疆id",
                     "type": "string"
                 },
                 "operationTypeId": {
@@ -4212,9 +4283,17 @@
                     "description": "ProductName string          `json:\"productName\" gorm:\"type:varchar(255);not null;comment:浜у搧鍚嶇О\"` //浜у搧鍚嶇О",
                     "type": "number"
                 },
+                "fromLocationId": {
+                    "description": "Unit        string          `json:\"unit\" gorm:\"type:varchar(31);comment:鍗曚綅\"`                    //鍗曚綅\nProduct models.Material `json:\"product\" gorm:\"foreignKey:ProductId;references:ID\"`",
+                    "type": "integer"
+                },
                 "productId": {
                     "description": "浜у搧id",
                     "type": "string"
+                },
+                "toLocationId": {
+                    "description": "鐩爣浣嶇疆id",
+                    "type": "integer"
                 }
             }
         },
@@ -4477,11 +4556,11 @@
                         "$ref": "#/definitions/request.OperationDetails"
                     }
                 },
-                "fromLocationId": {
-                    "description": "婧愪綅缃甶d",
+                "id": {
                     "type": "integer"
                 },
-                "id": {
+                "locationId": {
+                    "description": "婧愪綅缃甶d",
                     "type": "integer"
                 },
                 "logisticCompanyId": {
@@ -4496,7 +4575,7 @@
                     "type": "string"
                 },
                 "operationDate": {
-                    "description": "瀹夋帓鏃ユ湡",
+                    "description": "FromLocationId    int                        `json:\"fromLocationId\"   gorm:\"type:int;not null;comment:婧愪綅缃甶d\"`   //婧愪綅缃甶d\nToLocationId      int                        `json:\"toLocationId\"    gorm:\"type:int;not null;comment:鐩爣浣嶇疆id\"`   //鐩爣浣嶇疆id",
                     "type": "string"
                 },
                 "operationTypeId": {
diff --git a/docs/swagger.yaml b/docs/swagger.yaml
index a4cbae1..039abfe 100644
--- a/docs/swagger.yaml
+++ b/docs/swagger.yaml
@@ -166,11 +166,24 @@
     - 鍘熸潗鏂�
     - 鍗婃垚鍝�
     - 鎴愬搧
+    - 杈呮枡
+    - 鑰楁潗
+    - 鍏朵粬
+    - 铏氭嫙浠�
     type: string
+    x-enum-comments:
+      MaterialModeAuxiliary: 杈呮枡
+      MaterialModeConsumables: 鑰楁潗
+      MaterialModeOther: 鍏朵粬
+      MaterialModeVirtual: 铏氭嫙浠�, 涓嶈兘閿�鍞紝涓嶈兘鍑哄叆搴擄紝涓嶈兘閲囪喘
     x-enum-varnames:
     - MaterialModeRaw
     - MaterialModeSemi
     - MaterialModeFinished
+    - MaterialModeAuxiliary
+    - MaterialModeConsumables
+    - MaterialModeOther
+    - MaterialModeVirtual
   constvar.OperationStatus:
     enum:
     - 1
@@ -603,14 +616,14 @@
         items:
           $ref: '#/definitions/models.OperationDetails'
         type: array
-      fromLocation:
+      id:
+        type: integer
+      location:
         allOf:
         - $ref: '#/definitions/models.Location'
         description: 婧愪綅缃�
-      fromLocationId:
+      locationID:
         description: 婧愪綅缃甶d
-        type: integer
-      id:
         type: integer
       logisticCompany:
         $ref: '#/definitions/models.LogisticCompany'
@@ -623,6 +636,11 @@
         description: 鍗曞彿
         type: string
       operationDate:
+        description: |-
+          FromLocationID    int                      `json:"fromLocationId"   gorm:"type:int;not null;comment:婧愪綅缃甶d"`         //婧愪綅缃甶d
+          FromLocation      Location                 `json:"fromLocation"     gorm:"foreignKey:FromLocationID;references:Id"` //婧愪綅缃�
+          ToLocationID      int                      `json:"toLocationId"    gorm:"type:int;not null;comment:鐩爣浣嶇疆id"`         //鐩爣浣嶇疆id
+          ToLocation        Location                 `json:"toLocation"      gorm:"foreignKey:ToLocationID;references:Id"`    //鐩爣浣嶇疆
         type: string
       operationTypeId:
         description: 浣滀笟绫诲瀷id
@@ -669,6 +687,13 @@
         type: number
       createTime:
         type: string
+      fromLocation:
+        allOf:
+        - $ref: '#/definitions/models.Location'
+        description: 婧愪綅缃�
+      fromLocationId:
+        description: 婧愪綅缃甶d
+        type: integer
       id:
         type: integer
       operationId:
@@ -681,6 +706,13 @@
       productId:
         description: 浜у搧id
         type: string
+      toLocation:
+        allOf:
+        - $ref: '#/definitions/models.Location'
+        description: 鐩爣浣嶇疆
+      toLocationId:
+        description: 鐩爣浣嶇疆id
+        type: integer
       updateTime:
         type: string
     type: object
@@ -895,10 +927,10 @@
         items:
           $ref: '#/definitions/request.OperationDetails'
         type: array
-      fromLocationId:
-        description: 婧愪綅缃甶d
-        type: integer
       id:
+        type: integer
+      locationId:
+        description: 婧愪綅缃甶d
         type: integer
       logisticCompanyId:
         type: string
@@ -909,7 +941,9 @@
         description: 鍗曞彿
         type: string
       operationDate:
-        description: 瀹夋帓鏃ユ湡
+        description: |-
+          FromLocationId    int                      `json:"fromLocationId"   gorm:"type:int;not null;comment:婧愪綅缃甶d"`   //婧愪綅缃甶d
+          ToLocationId      int                      `json:"toLocationId"    gorm:"type:int;not null;comment:鐩爣浣嶇疆id"`   //鐩爣浣嶇疆id
         type: string
       operationTypeId:
         description: 浣滀笟绫诲瀷id
@@ -1202,9 +1236,17 @@
         description: ProductName string          `json:"productName" gorm:"type:varchar(255);not
           null;comment:浜у搧鍚嶇О"` //浜у搧鍚嶇О
         type: number
+      fromLocationId:
+        description: |-
+          Unit        string          `json:"unit" gorm:"type:varchar(31);comment:鍗曚綅"`                    //鍗曚綅
+          Product models.Material `json:"product" gorm:"foreignKey:ProductId;references:ID"`
+        type: integer
       productId:
         description: 浜у搧id
         type: string
+      toLocationId:
+        description: 鐩爣浣嶇疆id
+        type: integer
     type: object
   request.OperationList:
     properties:
@@ -1384,10 +1426,10 @@
         items:
           $ref: '#/definitions/request.OperationDetails'
         type: array
-      fromLocationId:
-        description: 婧愪綅缃甶d
-        type: integer
       id:
+        type: integer
+      locationId:
+        description: 婧愪綅缃甶d
         type: integer
       logisticCompanyId:
         type: string
@@ -1398,7 +1440,9 @@
         description: 鍗曞彿
         type: string
       operationDate:
-        description: 瀹夋帓鏃ユ湡
+        description: |-
+          FromLocationId    int                        `json:"fromLocationId"   gorm:"type:int;not null;comment:婧愪綅缃甶d"`   //婧愪綅缃甶d
+          ToLocationId      int                        `json:"toLocationId"    gorm:"type:int;not null;comment:鐩爣浣嶇疆id"`   //鐩爣浣嶇疆id
         type: string
       operationTypeId:
         description: 浣滀笟绫诲瀷id
@@ -2803,6 +2847,24 @@
       summary: 鑾峰彇浜у搧鍒楄〃
       tags:
       - 浜у搧
+  /api-wms/v1/product/getUserInfo:
+    get:
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: 鎴愬姛
+          schema:
+            allOf:
+            - $ref: '#/definitions/util.ResponseList'
+            - properties:
+                data:
+                  additionalProperties: true
+                  type: object
+              type: object
+      summary: 鑾峰彇鐧诲綍鐢ㄦ埛淇℃伅
+      tags:
+      - 浜у搧
   /api-wms/v1/product/listDisuse:
     post:
       parameters:
diff --git a/main.go b/main.go
index 1801bbf..2a44bc8 100644
--- a/main.go
+++ b/main.go
@@ -60,7 +60,6 @@
 			logx.Errorf("grpc server init error: %v", err.Error())
 			panic(fmt.Sprintf("grpc server init error: %v", err.Error()))
 		}
-		fmt.Println("-----------鐩戝惉绔彛: ", conf.WebConf.GrpcPort)
 		s := grpc.NewServer()
 		//todo 娣诲姞鍏蜂綋鏈嶅姟
 		product_inventory.RegisterProductInventoryServiceServer(s, &product_inventory.Server{})
diff --git a/middleware/utils.go b/middleware/utils.go
index 58defa0..cf98138 100644
--- a/middleware/utils.go
+++ b/middleware/utils.go
@@ -2,6 +2,7 @@
 
 import (
 	"errors"
+	"github.com/gin-gonic/gin"
 	"github.com/golang-jwt/jwt/v4"
 	"wms/request"
 )
@@ -58,3 +59,11 @@
 		return nil, TokenInvalid
 	}
 }
+
+func GetUserInfo(c *gin.Context) *request.CustomClaims {
+	if claims, exists := c.Get("claims"); exists {
+		waitUse := claims.(*request.CustomClaims)
+		return waitUse
+	}
+	return nil
+}
diff --git a/models/file_template_attachment.go b/models/file_template_attachment.go
index 575213e..a55c0db 100644
--- a/models/file_template_attachment.go
+++ b/models/file_template_attachment.go
@@ -10,12 +10,13 @@
 type (
 	FileTemplateAttachment struct {
 		WmsModel
-		Id           int                           `json:"id"  gorm:"column:id;primary_key;AUTO_INCREMENT"`
-		Category     constvar.FileTemplateCategory `json:"category" gorm:"type:int(11);comment:妯$増绉嶇被"`
-		Name         string                        `json:"name" gorm:"type:varchar(63);comment:妯$増鍚嶇О"`
-		AttachmentId uint                          `json:"attachmentId" gorm:"comment:闄勪欢琛ㄥ閿�"`
-		Attachment   Attachment                    `json:"attachment" gorm:"foreignKey:AttachmentId;references:Id"`
-		TableInfo    string                        `json:"tableInfo" gorm:"type:varchar(31);comment:琛ㄥ悕"`
+		Id       int                           `json:"id"  gorm:"column:id;primary_key;AUTO_INCREMENT"`
+		Category constvar.FileTemplateCategory `json:"category" gorm:"type:int(11);comment:妯$増绉嶇被"`
+		Name     string                        `json:"name" gorm:"type:varchar(63);comment:妯$増鍚嶇О"`
+		//AttachmentId uint                          `json:"attachmentId" gorm:"comment:闄勪欢琛ㄥ閿�"`
+		//Attachment   Attachment                    `json:"attachment" gorm:"foreignKey:AttachmentId;references:Id"`
+		TableInfo string `json:"tableInfo" gorm:"type:varchar(31);comment:琛ㄥ悕"`
+		FileUrl   string `json:"fileUrl" gorm:"type:varchar(255);comment:鏂囦欢鍦板潃"`
 	}
 	FileTemplateAttachmentSearch struct {
 		FileTemplateAttachment
@@ -61,10 +62,10 @@
 	return slf
 }
 
-func (slf *FileTemplateAttachmentSearch) SetPreload(preload bool) *FileTemplateAttachmentSearch {
-	slf.Preload = preload
-	return slf
-}
+//func (slf *FileTemplateAttachmentSearch) SetPreload(preload bool) *FileTemplateAttachmentSearch {
+//	slf.Preload = preload
+//	return slf
+//}
 
 func (slf *FileTemplateAttachmentSearch) SetCategory(category constvar.FileTemplateCategory) *FileTemplateAttachmentSearch {
 	slf.Category = category
@@ -81,9 +82,9 @@
 		db = db.Order(slf.Order)
 	}
 
-	if slf.Preload {
-		db = db.Model(&FileTemplateAttachment{}).Preload("Attachment")
-	}
+	//if slf.Preload {
+	//	db = db.Model(&FileTemplateAttachment{}).Preload("Attachment")
+	//}
 
 	if int(slf.Category) != 0 {
 		db = db.Where("category=?", slf.Category)
diff --git a/models/operation.go b/models/operation.go
index 2009733..a81b5ae 100644
--- a/models/operation.go
+++ b/models/operation.go
@@ -13,27 +13,27 @@
 	Operation struct {
 		WmsModel
 		Id                int                      `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
-		Number            string                   `json:"number" gorm:"type:varchar(255)"`                                 //鍗曞彿
-		SourceNumber      string                   `json:"sourceNumber" gorm:"type:varchar(255)"`                           //婧愬崟鍙�
-		OperationTypeId   int                      `json:"operationTypeId" gorm:"type:int;not null;comment:浣滀笟绫诲瀷id"`         //浣滀笟绫诲瀷id
-		OperationTypeName string                   `json:"operationTypeName" gorm:"type:varchar(127);comment:浣滀笟绫诲瀷鍚嶇О"`       //浣滀笟绫诲瀷鍚嶇О
-		Status            constvar.OperationStatus `json:"status" gorm:"type:int(11);not null;comment:鐘舵��"`                  //鐘舵��
-		FromLocationID    int                      `json:"fromLocationId"   gorm:"type:int;not null;comment:婧愪綅缃甶d"`         //婧愪綅缃甶d
-		FromLocation      Location                 `json:"fromLocation"     gorm:"foreignKey:FromLocationID;references:Id"` //婧愪綅缃�
-		ToLocationID      int                      `json:"toLocationId"    gorm:"type:int;not null;comment:鐩爣浣嶇疆id"`         //鐩爣浣嶇疆id
-		ToLocation        Location                 `json:"toLocation"      gorm:"foreignKey:ToLocationID;references:Id"`    //鐩爣浣嶇疆
-		OperationDate     string                   `json:"operationDate" gorm:"type:varchar(31);comment:瀹夋帓鏃ユ湡"`
-		ContacterID       int                      `json:"contacterID" gorm:"type:int;comment:鑱旂郴浜篒D"`
-		ContacterName     string                   `json:"contacterName" gorm:"type:varchar(63);comment:鑱旂郴浜哄鍚�"`
-		CompanyID         int                      `json:"companyID" gorm:"type:int;comment:鍏徃ID-瀹㈡埛"`
-		CompanyName       string                   `json:"companyName" gorm:"type:varchar(127);comment:鍏徃鍚嶇О-瀹㈡埛"`
-		Comment           string                   `json:"comment" gorm:"type:text;comment:澶囨敞"`
-		LogisticCompanyId string                   `json:"logisticCompanyId"   gorm:"type:varchar(191);comment:鐗╂祦鍏徃id"`
-		LogisticCompany   LogisticCompany          `json:"logisticCompany"      gorm:"foreignKey:LogisticCompanyId"`
-		WaybillNumber     string                   `json:"waybillNumber" gorm:"type:varchar(255);comment:杩愬崟鍙�"`    //杩愬崟鍙�
-		Weight            decimal.Decimal          `gorm:"type:decimal(20,2);comment:閲嶉噺" json:"weight"`           //閲嶉噺
-		LogisticWeight    decimal.Decimal          `gorm:"type:decimal(20,2);comment:鐗╂祦閲嶉噺" json:"logisticWeight"` //鐗╂祦閲嶉噺
-		Source            string                   `json:"source" gorm:"type:varchar(255);comment:鏉ユ簮绯荤粺,鐢ㄤ簬杩斿洖淇敼鐘舵��"`
+		Number            string                   `json:"number" gorm:"type:varchar(255)"`                           //鍗曞彿
+		SourceNumber      string                   `json:"sourceNumber" gorm:"type:varchar(255)"`                     //婧愬崟鍙�
+		OperationTypeId   int                      `json:"operationTypeId" gorm:"type:int;not null;comment:浣滀笟绫诲瀷id"`   //浣滀笟绫诲瀷id
+		OperationTypeName string                   `json:"operationTypeName" gorm:"type:varchar(127);comment:浣滀笟绫诲瀷鍚嶇О"` //浣滀笟绫诲瀷鍚嶇О
+		Status            constvar.OperationStatus `json:"status" gorm:"type:int(11);not null;comment:鐘舵��"`            //鐘舵��
+		//FromLocationID    int                      `json:"fromLocationId"   gorm:"type:int;not null;comment:婧愪綅缃甶d"`         //婧愪綅缃甶d
+		//FromLocation      Location                 `json:"fromLocation"     gorm:"foreignKey:FromLocationID;references:Id"` //婧愪綅缃�
+		//ToLocationID      int                      `json:"toLocationId"    gorm:"type:int;not null;comment:鐩爣浣嶇疆id"`         //鐩爣浣嶇疆id
+		//ToLocation        Location                 `json:"toLocation"      gorm:"foreignKey:ToLocationID;references:Id"`    //鐩爣浣嶇疆
+		OperationDate     string          `json:"operationDate" gorm:"type:varchar(31);comment:瀹夋帓鏃ユ湡"`
+		ContacterID       int             `json:"contacterID" gorm:"type:int;comment:鑱旂郴浜篒D"`
+		ContacterName     string          `json:"contacterName" gorm:"type:varchar(63);comment:鑱旂郴浜哄鍚�"`
+		CompanyID         int             `json:"companyID" gorm:"type:int;comment:鍏徃ID-瀹㈡埛"`
+		CompanyName       string          `json:"companyName" gorm:"type:varchar(127);comment:鍏徃鍚嶇О-瀹㈡埛"`
+		Comment           string          `json:"comment" gorm:"type:text;comment:澶囨敞"`
+		LogisticCompanyId string          `json:"logisticCompanyId"   gorm:"type:varchar(191);comment:鐗╂祦鍏徃id"`
+		LogisticCompany   LogisticCompany `json:"logisticCompany"      gorm:"foreignKey:LogisticCompanyId"`
+		WaybillNumber     string          `json:"waybillNumber" gorm:"type:varchar(255);comment:杩愬崟鍙�"`    //杩愬崟鍙�
+		Weight            decimal.Decimal `gorm:"type:decimal(20,2);comment:閲嶉噺" json:"weight"`           //閲嶉噺
+		LogisticWeight    decimal.Decimal `gorm:"type:decimal(20,2);comment:鐗╂祦閲嶉噺" json:"logisticWeight"` //鐗╂祦閲嶉噺
+		Source            string          `json:"source" gorm:"type:varchar(255);comment:鏉ユ簮绯荤粺,鐢ㄤ簬杩斿洖淇敼鐘舵��"`
 
 		Details           []*OperationDetails        `json:"details" gorm:"foreignKey:OperationID;references:Id"`
 		BaseOperationType constvar.BaseOperationType `json:"baseOperationType" gorm:"type:tinyint;not null;comment:鍩虹浣滀笟绫诲瀷"` //鍩虹浣滀笟绫诲瀷
@@ -42,6 +42,11 @@
 		ReceiverName  string `json:"receiverName" gorm:"type:varchar(31);comment:鏀惰揣浜哄鍚�"`
 		ReceiverPhone string `json:"receiverPhone" gorm:"type:varchar(31);comment:鑱旂郴鐢佃瘽"`
 		ReceiverAddr  string `json:"receiverAddr" gorm:"type:varchar(255);comment:鏀惰揣鍦板潃"`
+
+		LocationID   int      `json:"locationID"   gorm:"type:int;not null;comment:婧愪綅缃甶d"`          //婧愪綅缃甶d
+		Location     Location `json:"location" gorm:"foreignkey:LocationID;references:Id"`          //婧愪綅缃�
+		ToLocationID int      `json:"toLocationId"    gorm:"type:int;not null;comment:浠撳簱浣嶇疆id"`      //鐩爣浣嶇疆id
+		ToLocation   Location `json:"toLocation"      gorm:"foreignKey:ToLocationID;references:Id"` //鐩爣浣嶇疆
 	}
 
 	OperationSearch struct {
@@ -158,7 +163,7 @@
 	}
 
 	if slf.Preload {
-		db = db.Model(&Operation{}).Preload("Details").Preload("Details.Product").Preload("LogisticCompany").Preload("FromLocation").Preload("ToLocation")
+		db = db.Model(&Operation{}).Preload("Details").Preload("Details.Product").Preload("LogisticCompany").Preload("Location").Preload("ToLocation").Preload("Details.FromLocation").Preload("Details.ToLocation")
 	}
 
 	if slf.Disuse {
@@ -277,7 +282,7 @@
 	if slf.PageNum*slf.PageSize > 0 {
 		db = db.Offset((slf.PageNum - 1) * slf.PageSize).Limit(slf.PageSize)
 	}
-	if err := db.Preload("FromLocation").Preload("ToLocation").Order("created_at desc").Find(&records).Error; err != nil {
+	if err := db.Order("created_at desc").Find(&records).Error; err != nil {
 		return records, total, fmt.Errorf("find records err: %v", err)
 	}
 
diff --git a/models/operation_details.go b/models/operation_details.go
index 067ba63..0434ac9 100644
--- a/models/operation_details.go
+++ b/models/operation_details.go
@@ -18,6 +18,11 @@
 		Amount decimal.Decimal `json:"amount" gorm:"type:decimal(20,2);not null;comment:鏁伴噺"` //鏁伴噺
 		//Unit        string          `json:"unit" gorm:"type:varchar(31);comment:鍗曚綅"`                    //鍗曚綅
 		Product Material `json:"product" gorm:"foreignKey:ProductId;references:ID"`
+
+		FromLocationID int      `json:"fromLocationId"   gorm:"type:int;not null;comment:婧愪綅缃甶d"`         //婧愪綅缃甶d
+		FromLocation   Location `json:"fromLocation"     gorm:"foreignKey:FromLocationID;references:Id"` //婧愪綅缃�
+		ToLocationID   int      `json:"toLocationId"    gorm:"type:int;not null;comment:鐩爣浣嶇疆id"`         //鐩爣浣嶇疆id
+		ToLocation     Location `json:"toLocation"      gorm:"foreignKey:ToLocationID;references:Id"`    //鐩爣浣嶇疆
 	}
 
 	OperationDetailsSearch struct {
diff --git a/proto/inventory_order/server.go b/proto/inventory_order/server.go
index faa9a98..c38a32e 100644
--- a/proto/inventory_order/server.go
+++ b/proto/inventory_order/server.go
@@ -55,10 +55,12 @@
 		operation.Status = constvar.OperationStatus_Ready
 		operation.OperationTypeName = operationType.Name
 		operation.OperationTypeId = operationType.Id
-		operation.FromLocationID = fromLocation.Id
-		operation.ToLocationID = toLocation.Id
 		operation.BaseOperationType = constvar.BaseOperationTypeOutgoing
 		operation.Source = req.Source
+		operation.LocationID = fromLocation.Id
+		if req.OperationType == 1 {
+			operation.LocationID = toLocation.Id
+		}
 		or.WorkOrderId = operation.SourceNumber
 		or.Number = operation.Number
 		operationResp = append(operationResp, &or)
@@ -69,6 +71,8 @@
 			var detail models.OperationDetails
 			detail.ProductId = product.ProductNumber
 			detail.Amount = decimal.NewFromInt(product.Amount)
+			detail.FromLocationID = fromLocation.Id
+			detail.ToLocationID = toLocation.Id
 			details = append(details, &detail)
 		}
 		operation.Details = details
diff --git a/proto/product_inventory/server.go b/proto/product_inventory/server.go
index b564f8d..14bf8cd 100644
--- a/proto/product_inventory/server.go
+++ b/proto/product_inventory/server.go
@@ -34,7 +34,7 @@
 	var productIds []string
 	resp := new(GetInventoryProductInfoResponse)
 	err := models.NewOperationDetailsSearch().Orm.Model(&models.OperationDetails{}).
-		Select("wms_operation_details.product_id,wms_operation_details.amount,wms_operation.from_location_id as location_id,"+
+		Select("wms_operation_details.product_id,wms_operation_details.amount,wms_operation_details.from_location_id as location_id,"+
 			"wms_operation.number,wms_operation.waybill_number, logistic_company.name").
 		Joins("left join wms_operation on wms_operation.id = wms_operation_details.operation_id").
 		Joins("left join logistic_company on logistic_company.id = wms_operation.logistic_company_id").
@@ -92,7 +92,7 @@
 		Select("wms_operation_details.product_id, wms_operation_details.amount").
 		Joins("left join wms_operation on wms_operation_details.operation_id = wms_operation.id").
 		Where("wms_operation_details.product_id in (?)", productIds).
-		Where("wms_operation.from_location_id in (?)", locationIds).Where("wms_operation.status = ?", constvar.OperationStatus_Ready).
+		Where("wms_operation_details.from_location_id in (?)", locationIds).Where("wms_operation.status = ?", constvar.OperationStatus_Ready).
 		Where("wms_operation.base_operation_type in (?)", []constvar.BaseOperationType{constvar.BaseOperationTypeOutgoing, constvar.BaseOperationTypeInternal, constvar.BaseOperationTypeDisuse}).
 		Find(&canUse).Error
 	if err != nil {
@@ -160,12 +160,12 @@
 	if err != nil {
 		return nil, err
 	}
-	operation.FromLocationID = location.Id
+
 	first, err := models.NewLocationSearch().SetType(int(constvar.LocationTypeCustomer)).First()
 	if err != nil {
 		return nil, err
 	}
-	operation.ToLocationID = first.Id
+	operation.LocationID = location.Id
 	operation.BaseOperationType = constvar.BaseOperationTypeOutgoing
 	operation.ReceiverName = req.Addressee
 	operation.ReceiverPhone = req.Phone
@@ -179,6 +179,8 @@
 			detail.ProductId = product.Id
 			amount, _ := decimal.NewFromString(product.Amount)
 			detail.Amount = amount
+			detail.FromLocationID = location.Id
+			detail.ToLocationID = first.Id
 			details = append(details, &detail)
 		}
 		operation.Details = details
@@ -190,6 +192,8 @@
 			detail.ProductId = product.Id
 			amount, _ := decimal.NewFromString(product.Amount)
 			detail.Amount = amount
+			detail.FromLocationID = location.Id
+			detail.ToLocationID = first.Id
 			newOperation.Details = append(newOperation.Details, &detail)
 			operations = append(operations, &newOperation)
 		}
diff --git a/proto/purchase_wms/server.go b/proto/purchase_wms/server.go
index 9cf3096..4416273 100644
--- a/proto/purchase_wms/server.go
+++ b/proto/purchase_wms/server.go
@@ -38,17 +38,18 @@
 	if err != nil {
 		return nil, err
 	}
-	operation.ToLocationID = location.Id
 	first, err := models.NewLocationSearch().SetType(int(constvar.LocationTypeVendor)).First()
 	if err != nil {
 		return nil, err
 	}
-	operation.FromLocationID = first.Id
+	operation.LocationID = location.Id
 	operation.BaseOperationType = constvar.BaseOperationTypeIncoming
 	for _, product := range req.Product {
 		var detail models.OperationDetails
 		detail.ProductId = product.Id
 		detail.Amount = decimal.NewFromInt(product.Amount)
+		detail.FromLocationID = first.Id
+		detail.ToLocationID = location.Id
 		details = append(details, &detail)
 	}
 	err = models.WithTransaction(func(db *gorm.DB) error {
diff --git a/request/operation.go b/request/operation.go
index 138d2d9..dc95942 100644
--- a/request/operation.go
+++ b/request/operation.go
@@ -12,22 +12,24 @@
 	OperationTypeId   int                      `json:"operationTypeId" gorm:"type:int;not null;comment:浣滀笟绫诲瀷id"`   //浣滀笟绫诲瀷id
 	OperationTypeName string                   `json:"operationTypeName" gorm:"type:varchar(127);comment:浣滀笟绫诲瀷鍚嶇О"` //浣滀笟绫诲瀷鍚嶇О
 	Status            constvar.OperationStatus `json:"status" gorm:"type:int(11);not null;comment:鐘舵��"`            //鐘舵��
-	FromLocationId    int                      `json:"fromLocationId"   gorm:"type:int;not null;comment:婧愪綅缃甶d"`   //婧愪綅缃甶d
-	ToLocationId      int                      `json:"toLocationId"    gorm:"type:int;not null;comment:鐩爣浣嶇疆id"`   //鐩爣浣嶇疆id
-	OperationDate     string                   `json:"operationDate" gorm:"type:varchar(31);comment:瀹夋帓鏃ユ湡"`        //瀹夋帓鏃ユ湡
-	Details           []*OperationDetails      `json:"details"`
-	ContacterID       int                      `json:"contacterID" gorm:"type:int;comment:鑱旂郴浜篒D"`           //鑱旂郴浜篒D-闈炲繀濉�
-	ContacterName     string                   `json:"contacterName" gorm:"type:varchar(63);comment:鑱旂郴浜哄鍚�"` //鑱旂郴浜哄鍚�-闈炲繀濉�
-	CompanyID         int                      `json:"companyID" gorm:"type:int;comment:鍏徃ID"`              //鍏徃ID-瀹㈡埛
-	CompanyName       string                   `json:"companyName" gorm:"type:varchar(127);comment:鍏徃鍚嶇О"`   //鍏徃鍚嶇О-瀹㈡埛鍚嶇О
-	Comment           string                   `json:"comment" gorm:"type:text;comment:澶囨敞"`                 //澶囨敞
-	LogisticCompanyId string                   `json:"logisticCompanyId"   gorm:"type:varchar(191);comment:鐗╂祦鍏徃id"`
-	WaybillNumber     string                   `json:"waybillNumber" gorm:"type:varchar(255);comment:杩愬崟鍙�"`    //杩愬崟鍙�
-	Weight            decimal.Decimal          `gorm:"type:decimal(20,2);comment:閲嶉噺" json:"weight"`           //閲嶉噺
-	LogisticWeight    decimal.Decimal          `gorm:"type:decimal(20,2);comment:鐗╂祦閲嶉噺" json:"logisticWeight"` //鐗╂祦閲嶉噺
-	ReceiverName      string                   `json:"receiverName" gorm:"type:varchar(31);comment:鏀惰揣浜哄鍚�"`
-	ReceiverPhone     string                   `json:"receiverPhone" gorm:"type:varchar(31);comment:鑱旂郴鐢佃瘽"`
-	ReceiverAddr      string                   `json:"receiverAddr" gorm:"type:varchar(255);comment:鏀惰揣鍦板潃"`
+	//FromLocationId    int                      `json:"fromLocationId"   gorm:"type:int;not null;comment:婧愪綅缃甶d"`   //婧愪綅缃甶d
+	//ToLocationId      int                      `json:"toLocationId"    gorm:"type:int;not null;comment:鐩爣浣嶇疆id"`   //鐩爣浣嶇疆id
+	OperationDate     string              `json:"operationDate" gorm:"type:varchar(31);comment:瀹夋帓鏃ユ湡"` //瀹夋帓鏃ユ湡
+	Details           []*OperationDetails `json:"details"`
+	ContacterID       int                 `json:"contacterID" gorm:"type:int;comment:鑱旂郴浜篒D"`           //鑱旂郴浜篒D-闈炲繀濉�
+	ContacterName     string              `json:"contacterName" gorm:"type:varchar(63);comment:鑱旂郴浜哄鍚�"` //鑱旂郴浜哄鍚�-闈炲繀濉�
+	CompanyID         int                 `json:"companyID" gorm:"type:int;comment:鍏徃ID"`              //鍏徃ID-瀹㈡埛
+	CompanyName       string              `json:"companyName" gorm:"type:varchar(127);comment:鍏徃鍚嶇О"`   //鍏徃鍚嶇О-瀹㈡埛鍚嶇О
+	Comment           string              `json:"comment" gorm:"type:text;comment:澶囨敞"`                 //澶囨敞
+	LogisticCompanyId string              `json:"logisticCompanyId"   gorm:"type:varchar(191);comment:鐗╂祦鍏徃id"`
+	WaybillNumber     string              `json:"waybillNumber" gorm:"type:varchar(255);comment:杩愬崟鍙�"`    //杩愬崟鍙�
+	Weight            decimal.Decimal     `gorm:"type:decimal(20,2);comment:閲嶉噺" json:"weight"`           //閲嶉噺
+	LogisticWeight    decimal.Decimal     `gorm:"type:decimal(20,2);comment:鐗╂祦閲嶉噺" json:"logisticWeight"` //鐗╂祦閲嶉噺
+	ReceiverName      string              `json:"receiverName" gorm:"type:varchar(31);comment:鏀惰揣浜哄鍚�"`
+	ReceiverPhone     string              `json:"receiverPhone" gorm:"type:varchar(31);comment:鑱旂郴鐢佃瘽"`
+	ReceiverAddr      string              `json:"receiverAddr" gorm:"type:varchar(255);comment:鏀惰揣鍦板潃"`
+	LocationId        int                 `json:"locationId"   gorm:"type:int;not null;comment:婧愪綅缃甶d"`     //婧愪綅缃甶d
+	ToLocationId      int                 `json:"toLocationId"    gorm:"type:int;not null;comment:浠撳簱浣嶇疆id"` //鐩爣浣嶇疆id
 }
 
 type OperationDetails struct {
@@ -37,6 +39,8 @@
 	Amount decimal.Decimal `json:"amount" gorm:"type:decimal(20,2);not null;comment:鏁伴噺"` //鏁伴噺
 	//Unit        string          `json:"unit" gorm:"type:varchar(31);comment:鍗曚綅"`                    //鍗曚綅
 	//Product models.Material `json:"product" gorm:"foreignKey:ProductId;references:ID"`
+	FromLocationId int `json:"fromLocationId"   gorm:"type:int;not null;comment:婧愪綅缃甶d"` //婧愪綅缃甶d
+	ToLocationId   int `json:"toLocationId"    gorm:"type:int;not null;comment:鐩爣浣嶇疆id"` //鐩爣浣嶇疆id
 }
 
 type OperationList struct {
@@ -47,15 +51,15 @@
 }
 
 type UpdateOperation struct {
-	ID                int                        `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
-	Number            string                     `json:"number" gorm:"column:number;type:varchar(255)"`             //鍗曞彿
-	SourceNumber      string                     `json:"sourceNumber" gorm:"type:varchar(255)"`                     //婧愬崟鍙�
-	OperationTypeId   int                        `json:"operationTypeId" gorm:"type:int;not null;comment:浣滀笟绫诲瀷id"`   //浣滀笟绫诲瀷id
-	OperationTypeName string                     `json:"operationTypeName" gorm:"type:varchar(127);comment:浣滀笟绫诲瀷鍚嶇О"` //浣滀笟绫诲瀷鍚嶇О
-	Status            constvar.OperationStatus   `json:"status" gorm:"type:int(11);not null;comment:鐘舵��"`            //鐘舵��
-	FromLocationId    int                        `json:"fromLocationId"   gorm:"type:int;not null;comment:婧愪綅缃甶d"`   //婧愪綅缃甶d
-	ToLocationId      int                        `json:"toLocationId"    gorm:"type:int;not null;comment:鐩爣浣嶇疆id"`   //鐩爣浣嶇疆id
-	OperationDate     string                     `json:"operationDate" gorm:"type:varchar(31);comment:瀹夋帓鏃ユ湡"`        //瀹夋帓鏃ユ湡
+	ID                int                      `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
+	Number            string                   `json:"number" gorm:"column:number;type:varchar(255)"`             //鍗曞彿
+	SourceNumber      string                   `json:"sourceNumber" gorm:"type:varchar(255)"`                     //婧愬崟鍙�
+	OperationTypeId   int                      `json:"operationTypeId" gorm:"type:int;not null;comment:浣滀笟绫诲瀷id"`   //浣滀笟绫诲瀷id
+	OperationTypeName string                   `json:"operationTypeName" gorm:"type:varchar(127);comment:浣滀笟绫诲瀷鍚嶇О"` //浣滀笟绫诲瀷鍚嶇О
+	Status            constvar.OperationStatus `json:"status" gorm:"type:int(11);not null;comment:鐘舵��"`            //鐘舵��
+	//FromLocationId    int                        `json:"fromLocationId"   gorm:"type:int;not null;comment:婧愪綅缃甶d"`   //婧愪綅缃甶d
+	//ToLocationId      int                        `json:"toLocationId"    gorm:"type:int;not null;comment:鐩爣浣嶇疆id"`   //鐩爣浣嶇疆id
+	OperationDate     string                     `json:"operationDate" gorm:"type:varchar(31);comment:瀹夋帓鏃ユ湡"` //瀹夋帓鏃ユ湡
 	Details           []*OperationDetails        `json:"details"`
 	ContacterID       int                        `json:"contacterID" gorm:"type:int;comment:鑱旂郴浜篒D"`           //鑱旂郴浜篒D-闈炲繀濉�
 	ContacterName     string                     `json:"contacterName" gorm:"type:varchar(63);comment:鑱旂郴浜哄鍚�"` //鑱旂郴浜哄鍚�-闈炲繀濉�
@@ -70,6 +74,8 @@
 	ReceiverName      string                     `json:"receiverName" gorm:"type:varchar(31);comment:鏀惰揣浜哄鍚�"`
 	ReceiverPhone     string                     `json:"receiverPhone" gorm:"type:varchar(31);comment:鑱旂郴鐢佃瘽"`
 	ReceiverAddr      string                     `json:"receiverAddr" gorm:"type:varchar(255);comment:鏀惰揣鍦板潃"`
+	LocationId        int                        `json:"locationId"   gorm:"type:int;not null;comment:婧愪綅缃甶d"`     //婧愪綅缃甶d
+	ToLocationId      int                        `json:"toLocationId"    gorm:"type:int;not null;comment:浠撳簱浣嶇疆id"` //鐩爣浣嶇疆id
 }
 
 type OperationAllList struct {
diff --git a/router/router.go b/router/router.go
index e7565eb..3e6ce21 100644
--- a/router/router.go
+++ b/router/router.go
@@ -119,6 +119,7 @@
 		productAPI.POST("updateDisuse", productController.UpdateDisuse)    //淇敼鎶ュ簾淇℃伅
 		productAPI.POST("listHistory", productController.ListHistory)      //浜у搧浣嶇疆鍘嗗彶璁板綍
 		productAPI.PUT("cancelDisuse/:id", productController.CancelDisuse) //鍙栨秷鎶ュ簾
+		productAPI.GET("getUserInfo", productController.GetUserInfo)       //鑾峰彇鐧诲綍鐢ㄦ埛淇℃伅
 
 	}
 

--
Gitblit v1.8.0