liujiandao
2023-10-21 174932f4f44157958f4112d37cd7df714ebfc223
销售机会添加产品选择功能
1个文件已添加
8个文件已修改
293 ■■■■ 已修改文件
api/v1/saleChance.go 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
conf/aps-crm.json 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/docs.go 43 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/swagger.json 43 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/swagger.yaml 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
model/request/saleChance.go 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
model/saleChance.go 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
model/saleChanceProduct.go 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/saleChance.go 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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
}
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"
  }
}
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": "所属公司ID",
                    "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": "所属公司ID",
                    "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": "所属公司ID",
                    "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"
                },
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": "所属公司ID",
                    "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": "所属公司ID",
                    "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": "所属公司ID",
                    "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"
                },
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: 所属公司ID
        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: 所属公司ID
        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: 所属公司ID
        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:
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
}
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
model/saleChanceProduct.go
New file
@@ -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
}
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
    }