From 174932f4f44157958f4112d37cd7df714ebfc223 Mon Sep 17 00:00:00 2001
From: liujiandao <274878379@qq.com>
Date: 星期六, 21 十月 2023 17:47:25 +0800
Subject: [PATCH] 销售机会添加产品选择功能

---
 conf/aps-crm.json           |    4 
 api/v1/saleChance.go        |    1 
 model/saleChanceProduct.go  |  114 ++++++++++++++++++++++
 service/saleChance.go       |   45 ++++++++
 model/request/saleChance.go |    6 +
 model/saleChance.go         |    7 
 docs/swagger.yaml           |   30 +++---
 docs/docs.go                |   43 ++++----
 docs/swagger.json           |   43 ++++----
 9 files changed, 229 insertions(+), 64 deletions(-)

diff --git a/api/v1/saleChance.go b/api/v1/saleChance.go
index 791ce98..445b3c7 100644
--- a/api/v1/saleChance.go
+++ b/api/v1/saleChance.go
@@ -208,6 +208,7 @@
 	sc.Address.CountryId = saleChance.Address.CountryId
 	sc.Address.ProvinceId = saleChance.Address.ProvinceId
 	sc.CodeStandID = saleChance.CodeStandID
+	sc.Products = saleChance.Products
 
 	return ecode.OK, sc
 }
diff --git a/conf/aps-crm.json b/conf/aps-crm.json
index 9774105..eeb4146 100644
--- a/conf/aps-crm.json
+++ b/conf/aps-crm.json
@@ -48,8 +48,8 @@
     "Issuer": "qmPlus"
   },
   "GrpcServiceAddr": {
-    "Aps": "192.168.20.120:9091",
-    "Admin": "192.168.20.120:50051"
+    "Aps": "192.168.20.119:9091",
+    "Admin": "192.168.20.119:50051"
   }
 }
 
diff --git a/docs/docs.go b/docs/docs.go
index ab2884d..e8e2612 100644
--- a/docs/docs.go
+++ b/docs/docs.go
@@ -11850,6 +11850,12 @@
                 "process": {
                     "type": "string"
                 },
+                "products": {
+                    "type": "array",
+                    "items": {
+                        "$ref": "#/definitions/model.Product"
+                    }
+                },
                 "projected_amount": {
                     "type": "number"
                 },
@@ -13282,13 +13288,6 @@
                     "description": "鎵�灞炲叕鍙窱D",
                     "type": "integer"
                 },
-                "codeRule": {
-                    "$ref": "#/definitions/code.CodeStandard"
-                },
-                "codeStandID": {
-                    "description": "缂栫爜id",
-                    "type": "string"
-                },
                 "country_id": {
                     "description": "鍥藉ID",
                     "type": "integer"
@@ -14018,6 +14017,12 @@
                 },
                 "process": {
                     "type": "string"
+                },
+                "products": {
+                    "type": "array",
+                    "items": {
+                        "$ref": "#/definitions/model.Product"
+                    }
                 },
                 "projected_amount": {
                     "type": "number"
@@ -14864,13 +14869,6 @@
                     "description": "鎵�灞炲叕鍙窱D",
                     "type": "integer"
                 },
-                "codeRule": {
-                    "$ref": "#/definitions/code.CodeStandard"
-                },
-                "codeStandID": {
-                    "description": "缂栫爜id",
-                    "type": "string"
-                },
                 "country_id": {
                     "description": "鍥藉ID",
                     "type": "integer"
@@ -15362,6 +15360,10 @@
                 },
                 "keywordType": {
                     "$ref": "#/definitions/constvar.SalesDetailsKeywordType"
+                },
+                "number": {
+                    "description": "閿�鍞瓙鍗曞彿",
+                    "type": "string"
                 },
                 "page": {
                     "description": "椤电爜",
@@ -16228,13 +16230,6 @@
                 "client_id": {
                     "description": "鎵�灞炲叕鍙窱D",
                     "type": "integer"
-                },
-                "codeRule": {
-                    "$ref": "#/definitions/code.CodeStandard"
-                },
-                "codeStandID": {
-                    "description": "缂栫爜id",
-                    "type": "string"
                 },
                 "country_id": {
                     "description": "鍥藉ID",
@@ -17295,6 +17290,12 @@
                 "process": {
                     "type": "string"
                 },
+                "products": {
+                    "type": "array",
+                    "items": {
+                        "$ref": "#/definitions/model.Product"
+                    }
+                },
                 "projected_amount": {
                     "type": "number"
                 },
diff --git a/docs/swagger.json b/docs/swagger.json
index 8016219..b6ef544 100644
--- a/docs/swagger.json
+++ b/docs/swagger.json
@@ -11838,6 +11838,12 @@
                 "process": {
                     "type": "string"
                 },
+                "products": {
+                    "type": "array",
+                    "items": {
+                        "$ref": "#/definitions/model.Product"
+                    }
+                },
                 "projected_amount": {
                     "type": "number"
                 },
@@ -13270,13 +13276,6 @@
                     "description": "鎵�灞炲叕鍙窱D",
                     "type": "integer"
                 },
-                "codeRule": {
-                    "$ref": "#/definitions/code.CodeStandard"
-                },
-                "codeStandID": {
-                    "description": "缂栫爜id",
-                    "type": "string"
-                },
                 "country_id": {
                     "description": "鍥藉ID",
                     "type": "integer"
@@ -14006,6 +14005,12 @@
                 },
                 "process": {
                     "type": "string"
+                },
+                "products": {
+                    "type": "array",
+                    "items": {
+                        "$ref": "#/definitions/model.Product"
+                    }
                 },
                 "projected_amount": {
                     "type": "number"
@@ -14852,13 +14857,6 @@
                     "description": "鎵�灞炲叕鍙窱D",
                     "type": "integer"
                 },
-                "codeRule": {
-                    "$ref": "#/definitions/code.CodeStandard"
-                },
-                "codeStandID": {
-                    "description": "缂栫爜id",
-                    "type": "string"
-                },
                 "country_id": {
                     "description": "鍥藉ID",
                     "type": "integer"
@@ -15350,6 +15348,10 @@
                 },
                 "keywordType": {
                     "$ref": "#/definitions/constvar.SalesDetailsKeywordType"
+                },
+                "number": {
+                    "description": "閿�鍞瓙鍗曞彿",
+                    "type": "string"
                 },
                 "page": {
                     "description": "椤电爜",
@@ -16216,13 +16218,6 @@
                 "client_id": {
                     "description": "鎵�灞炲叕鍙窱D",
                     "type": "integer"
-                },
-                "codeRule": {
-                    "$ref": "#/definitions/code.CodeStandard"
-                },
-                "codeStandID": {
-                    "description": "缂栫爜id",
-                    "type": "string"
                 },
                 "country_id": {
                     "description": "鍥藉ID",
@@ -17283,6 +17278,12 @@
                 "process": {
                     "type": "string"
                 },
+                "products": {
+                    "type": "array",
+                    "items": {
+                        "$ref": "#/definitions/model.Product"
+                    }
+                },
                 "projected_amount": {
                     "type": "number"
                 },
diff --git a/docs/swagger.yaml b/docs/swagger.yaml
index 6b262fd..da4a29b 100644
--- a/docs/swagger.yaml
+++ b/docs/swagger.yaml
@@ -1332,6 +1332,10 @@
         $ref: '#/definitions/model.Possibility'
       process:
         type: string
+      products:
+        items:
+          $ref: '#/definitions/model.Product'
+        type: array
       projected_amount:
         type: number
       province:
@@ -2301,11 +2305,6 @@
       client_id:
         description: 鎵�灞炲叕鍙窱D
         type: integer
-      codeRule:
-        $ref: '#/definitions/code.CodeStandard'
-      codeStandID:
-        description: 缂栫爜id
-        type: string
       country_id:
         description: 鍥藉ID
         type: integer
@@ -2790,6 +2789,10 @@
         type: integer
       process:
         type: string
+      products:
+        items:
+          $ref: '#/definitions/model.Product'
+        type: array
       projected_amount:
         type: number
       province_id:
@@ -3369,11 +3372,6 @@
       client_id:
         description: 鎵�灞炲叕鍙窱D
         type: integer
-      codeRule:
-        $ref: '#/definitions/code.CodeStandard'
-      codeStandID:
-        description: 缂栫爜id
-        type: string
       country_id:
         description: 鍥藉ID
         type: integer
@@ -3729,6 +3727,9 @@
         type: string
       keywordType:
         $ref: '#/definitions/constvar.SalesDetailsKeywordType'
+      number:
+        description: 閿�鍞瓙鍗曞彿
+        type: string
       page:
         description: 椤电爜
         type: integer
@@ -4322,11 +4323,6 @@
       client_id:
         description: 鎵�灞炲叕鍙窱D
         type: integer
-      codeRule:
-        $ref: '#/definitions/code.CodeStandard'
-      codeStandID:
-        description: 缂栫爜id
-        type: string
       country_id:
         description: 鍥藉ID
         type: integer
@@ -5031,6 +5027,10 @@
         type: integer
       process:
         type: string
+      products:
+        items:
+          $ref: '#/definitions/model.Product'
+        type: array
       projected_amount:
         type: number
       province_id:
diff --git a/model/request/saleChance.go b/model/request/saleChance.go
index 20d4619..34085de 100644
--- a/model/request/saleChance.go
+++ b/model/request/saleChance.go
@@ -1,6 +1,9 @@
 package request
 
-import "aps_crm/proto/code"
+import (
+	"aps_crm/model"
+	"aps_crm/proto/code"
+)
 
 type AddSaleChance struct {
 	SaleChance
@@ -38,6 +41,7 @@
 	DetailAddress      string            `json:"detail_address"`
 	CodeStandID        string            `json:"codeStandID"` //缂栫爜id
 	CodeRule           code.CodeStandard `json:"codeRule"`
+	Products           []*model.Product  `json:"products" gorm:"many2many:SaleChance_Product;"`
 	Address
 }
 
diff --git a/model/saleChance.go b/model/saleChance.go
index 86fcb5f..751863b 100644
--- a/model/saleChance.go
+++ b/model/saleChance.go
@@ -47,6 +47,7 @@
 		CollectionProjections []CollectionProjection `json:"collection_projections" gorm:"foreignKey:SaleChanceId"`
 		SalesSources          SalesSources           `json:"sales_sources"`
 		CodeStandID           string                 `json:"codeStandID" gorm:"column:code_stand_id;type:varchar(255);comment:缂栫爜id"`
+		Products              []*Product             `json:"products" gorm:"many2many:SaleChanceProduct;"`
 		Address
 		gorm.Model `json:"-"`
 	}
@@ -133,7 +134,7 @@
 
 func (slf *SaleChanceSearch) Update(record *SaleChance) (err error) {
 	var db = slf.build()
-	err = db.Updates(record).Error
+	err = db.Preload("Products").Updates(record).Error
 	return
 }
 
@@ -145,7 +146,7 @@
 
 func (slf *SaleChanceSearch) Find() (record SaleChance, err error) {
 	var db = slf.build()
-	err = db.First(&record).Error
+	err = db.Preload("Products").First(&record).Error
 	return
 }
 
@@ -160,7 +161,7 @@
 		db = db.Limit(slf.PageSize).Offset((slf.PageNum - 1) * slf.PageSize)
 	}
 
-	err := db.Preload("SaleType").Preload("RegularCustomers").Preload("SalesSources").
+	err := db.Preload("SaleType").Preload("RegularCustomers").Preload("SalesSources").Preload("Products").
 		Preload("Member").Preload("SaleStage").Preload("Possibility").
 		Preload("CollectionProjections").Preload("Client").
 		Preload("Province").Preload("City").Preload("Contact").Order("id desc").Find(&records).Error
diff --git a/model/saleChanceProduct.go b/model/saleChanceProduct.go
new file mode 100644
index 0000000..0236b44
--- /dev/null
+++ b/model/saleChanceProduct.go
@@ -0,0 +1,114 @@
+package model
+
+import (
+	"aps_crm/pkg/mysqlx"
+	"fmt"
+	"gorm.io/gorm"
+)
+
+type (
+	// SaleChanceProduct 閿�鍞満浼氬拰浜у搧鍏宠仈
+	SaleChanceProduct struct {
+		SaleChanceId int  `json:"saleChanceId" gorm:"column:sale_chance_id;type:int;primary_key;not null;default:0"`
+		ProductId    uint `json:"productId" gorm:"primary_key;column:product_id;type:int;not null;default:0;comment:浜у搧id"`
+	}
+
+	// SaleChanceProductSearch 閿�鍞満浼氬拰浜у搧鍏宠仈鎼滅储鏉′欢
+	SaleChanceProductSearch struct {
+		SaleChanceProduct
+		Orm      *gorm.DB
+		Keyword  string
+		PageNum  int
+		PageSize int
+	}
+)
+
+func (SaleChanceProduct) TableName() string {
+	return "sale_chance_product"
+}
+
+func NewSaleChanceProductSearch() *SaleChanceProductSearch {
+	return &SaleChanceProductSearch{
+		Orm: mysqlx.GetDB(),
+	}
+}
+
+func (slf *SaleChanceProductSearch) build() *gorm.DB {
+	var db = slf.Orm.Model(&SaleChanceProduct{})
+
+	return db
+}
+
+func (slf *SaleChanceProductSearch) Create(record *SaleChanceProduct) error {
+	var db = slf.build()
+	return db.Create(record).Error
+}
+
+func (slf *SaleChanceProductSearch) CreateBatch(records []*SaleChanceProduct) error {
+	var db = slf.build()
+	return db.Create(records).Error
+}
+
+func (slf *SaleChanceProductSearch) Delete() error {
+	var db = slf.build()
+	return db.Delete(&SaleChanceProduct{}).Error
+}
+
+func (slf *SaleChanceProductSearch) Update(record *SaleChanceProduct) error {
+	var db = slf.build()
+	return db.Updates(record).Error
+}
+
+func (slf *SaleChanceProductSearch) FindAll() ([]*SaleChanceProduct, error) {
+	var db = slf.build()
+	var record = make([]*SaleChanceProduct, 0)
+	err := db.Find(&record).Error
+	return record, err
+}
+
+func (slf *SaleChanceProductSearch) SetPage(page, size int) *SaleChanceProductSearch {
+	slf.PageNum, slf.PageSize = page, size
+	return slf
+}
+
+func (slf *SaleChanceProductSearch) SetOrm(tx *gorm.DB) *SaleChanceProductSearch {
+	slf.Orm = tx
+	return slf
+}
+
+func (slf *SaleChanceProductSearch) First() (*SaleChanceProduct, error) {
+	var db = slf.build()
+	var record = new(SaleChanceProduct)
+	err := db.First(record).Error
+	return record, err
+}
+
+func (slf *SaleChanceProductSearch) Updates(values interface{}) error {
+	var db = slf.build()
+	return db.Updates(values).Error
+}
+
+func (slf *SaleChanceProductSearch) Save(record *SaleChanceProduct) error {
+	var db = slf.build()
+
+	if err := db.Save(record).Error; err != nil {
+		return fmt.Errorf("save err: %v, record: %+v", err, record)
+	}
+
+	return nil
+}
+
+func (slf *SaleChanceProductSearch) Find() ([]*SaleChanceProduct, int64, error) {
+	var db = slf.build()
+	var records = make([]*SaleChanceProduct, 0)
+	var total int64
+	if err := db.Count(&total).Error; err != nil {
+		return records, total, err
+	}
+	if slf.PageNum > 0 && slf.PageSize > 0 {
+		db = db.Limit(slf.PageSize).Offset((slf.PageNum - 1) * slf.PageSize)
+	}
+
+	err := db.Find(&records).Error
+	return records, total, err
+}
diff --git a/service/saleChance.go b/service/saleChance.go
index 1610c07..a8f419b 100644
--- a/service/saleChance.go
+++ b/service/saleChance.go
@@ -3,6 +3,7 @@
 import (
 	"aps_crm/model"
 	"aps_crm/pkg/ecode"
+	"gorm.io/gorm"
 )
 
 type SaleChanceService struct{}
@@ -17,7 +18,49 @@
 
 func (SaleChanceService) UpdateSaleChance(saleChange *model.SaleChance) int {
 	// update saleChange
-	err := model.NewSaleChanceSearch().SetId(saleChange.Id).Update(saleChange)
+	old, err := model.NewSaleChanceSearch().SetId(saleChange.Id).Find()
+	if err != nil {
+		return ecode.SaleChanceNotExist
+	}
+	newProducts, removedProducts := NewProductsService().PickDiffProducts(saleChange.Products, old.Products)
+	err = model.WithTransaction(func(db *gorm.DB) error {
+		err = model.NewSaleChanceSearch().SetId(saleChange.Id).Update(saleChange)
+		if err != nil {
+			return err
+		}
+		if len(removedProducts) > 0 {
+			removedProductIds := make([]uint, 0, len(removedProducts))
+			for _, product := range removedProducts {
+				removedProductIds = append(removedProductIds, product.Id)
+			}
+			err = model.NewProductSearch(db).SetIds(removedProductIds).Delete()
+			if err != nil {
+				return err
+			}
+		}
+		if len(newProducts) > 0 {
+			for _, p := range newProducts {
+				p.Id = 0
+			}
+			err = model.NewProductSearch(db).CreateBatch(newProducts)
+			if err != nil {
+				return err
+			}
+			var rel []*model.SaleChanceProduct
+			for _, p := range newProducts {
+				rel = append(rel, &model.SaleChanceProduct{
+					SaleChanceId: saleChange.Id,
+					ProductId:    p.Id,
+				})
+			}
+			err = model.NewSaleChanceProductSearch().CreateBatch(rel)
+			if err != nil {
+				return err
+			}
+		}
+		return nil
+	})
+
 	if err != nil {
 		return ecode.SaleChanceUpdateErr
 	}

--
Gitblit v1.8.0