fix
wangpengfei
2023-08-10 f26d6d27c5f756c88a2a44f2cf0125f277ff177e
fix

add multi-criteria query to followRecord
11个文件已修改
1141 ■■■■ 已修改文件
api/v1/followRecord.go 446 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
constvar/const.go 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/docs.go 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/swagger.json 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/swagger.yaml 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
model/contact.go 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
model/followRecord.go 383 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
model/request/contact.go 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
model/request/followRecord.go 72 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/followRecord.go 154 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/salesLeads.go 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/v1/followRecord.go
@@ -1,223 +1,223 @@
package v1
import (
    "aps_crm/model"
    "aps_crm/model/request"
    "aps_crm/model/response"
    "aps_crm/pkg/contextx"
    "aps_crm/pkg/ecode"
    "github.com/gin-gonic/gin"
    "time"
)
type FollowRecordApi struct{}
// Add
//
//    @Tags        FollowRecord
//    @Summary    添加跟进记录
//    @Produce    application/json
//    @Param        object    body        request.AddFollowRecord    true    "查询参数"
//    @Success    200        {object}    contextx.Response{}
//    @Router        /api/followRecord/add [post]
func (fr *FollowRecordApi) Add(c *gin.Context) {
    var params request.AddFollowRecord
    ctx, ok := contextx.NewContext(c, &params)
    if !ok {
        return
    }
    errCode, followRecord := checkFollowRecordParams(params.FollowRecord)
    if errCode != ecode.OK {
        ctx.Fail(errCode)
        return
    }
    errCode = followRecordService.AddFollowRecord(followRecord)
    if errCode != ecode.OK {
        ctx.Fail(errCode)
        return
    }
    ctx.Ok()
}
// Delete
//
//    @Tags        FollowRecord
//    @Summary    删除跟进记录
//    @Produce    application/json
//    @Param        object    body        request.DeleteFollowRecord true    "查询参数"
//    @Success    200    {object}    contextx.Response{}
//    @Router        /api/followRecord/delete [delete]
func (fr *FollowRecordApi) Delete(c *gin.Context) {
    var params request.DeleteFollowRecord
    ctx, ok := contextx.NewContext(c, &params)
    if !ok {
        return
    }
    errCode := followRecordService.DeleteFollowRecord(params.Ids)
    if errCode != ecode.OK {
        ctx.Fail(errCode)
        return
    }
    ctx.Ok()
}
// Update
//
//    @Tags        FollowRecord
//    @Summary    更新跟进记录
//    @Produce    application/json
//    @Param        object    body        request.UpdateFollowRecord    true    "查询参数"
//    @Success    200        {object}    contextx.Response{}
//    @Router        /api/followRecord/update [put]
func (fr *FollowRecordApi) Update(c *gin.Context) {
    var params request.UpdateFollowRecord
    ctx, ok := contextx.NewContext(c, &params)
    if !ok {
        return
    }
    errCode, followRecord := checkFollowRecordParams(params.FollowRecord)
    if errCode != ecode.OK {
        ctx.Fail(errCode)
        return
    }
    followRecord.Id = params.Id
    errCode = followRecordService.UpdateFollowRecord(followRecord)
    if errCode != ecode.OK {
        ctx.Fail(errCode)
        return
    }
    ctx.Ok()
}
// checkFollowRecordParams
// 检查跟进记录参数
func checkFollowRecordParams(followRecord request.FollowRecord) (int, *model.FollowRecord) {
    var followRecordModel model.FollowRecord
    //if followRecord.ClientId != 0 {
    //    // check client exist
    //    if service.CheckClientExist(followRecord.ClientId) != ecode.OK {
    //        return ecode.ClientNotExist, &followRecordModel
    //    }
    //}
    //
    //if followRecord.ContactId != 0 {
    //    // check contact exist
    //    if service.CheckContactExist(followRecord.ContactId) != ecode.OK {
    //        return ecode.ContactNotExist, &followRecordModel
    //    }
    //}
    //
    //if followRecord.SalesLeadsId != 0 {
    //    // check sales leads exist
    //    if service.CheckSalesLeadsExist(followRecord.SalesLeadsId) != ecode.OK {
    //        return ecode.SalesLeadsNotExist, &followRecordModel
    //    }
    //}
    //
    //// check member id
    //if followRecord.MemberId == 0 {
    //    // todo check member exist
    //    return ecode.InvalidParams, &followRecordModel
    //}
    //
    //// check number
    //if followRecord.Number == "" {
    //    return ecode.InvalidParams, &followRecordModel
    //}
    //
    //// check follow content
    //if followRecord.Content == "" {
    //    return ecode.InvalidParams, &followRecordModel
    //}
    // check follow time
    t, err := checkTimeFormat(followRecord.FollowTime)
    if err != nil {
        return ecode.InvalidParams, &followRecordModel
    }
    followRecordModel.FollowTime = t
    t, err = checkTimeFormat(followRecord.NextFollowTime)
    if err != nil {
        return ecode.InvalidParams, &followRecordModel
    }
    followRecordModel.NextFollowTime = t
    followRecordModel.ClientId = followRecord.ClientId
    followRecordModel.Content = followRecord.Content
    followRecordModel.MemberId = followRecord.MemberId
    followRecordModel.Number = followRecord.Number
    followRecordModel.ClientStatusId = followRecord.ClientStatusId
    followRecordModel.ContactId = followRecord.ContactId
    followRecordModel.Topic = followRecord.Topic
    followRecordModel.SalesLeadsId = followRecord.SalesLeadsId
    followRecordModel.SaleChanceId = followRecord.SaleChanceId
    followRecordModel.ContactInformationId = followRecord.ContactInformationId
    followRecordModel.Purpose = followRecord.Purpose
    followRecordModel.Content = followRecord.Content
    followRecordModel.Record = followRecord.Record
    return ecode.OK, &followRecordModel
}
// checkTimeFormat
// 检查时间格式
func checkTimeFormat(t string) (time.Time, error) {
    if t == "" {
        t = "1900-01-01T00:00:00+08:00"
    }
    location, err := time.LoadLocation("Asia/Shanghai")
    if err != nil {
        return time.Time{}, err
    }
    tt, err := time.Parse("2006-01-02T15:04:05.000Z", t)
    if err == nil {
        return tt.In(location), nil
    }
    tt, err = time.Parse("2006-01-02T15:04:05-07:00", t)
    if err == nil {
        return tt.In(location), nil
    }
    return time.Time{}, err
}
// List
//
//    @Tags        FollowRecord
//    @Summary    回访记录列表
//    @Produce    application/json
//    @Param        object    body        request.GetFollowRecordList    true    "参数"
//    @Success    200        {object}    contextx.Response{data=response.FollowRecordResponse}
//    @Router        /api/followRecord/list [post]
func (fr *FollowRecordApi) List(c *gin.Context) {
    var params request.GetFollowRecordList
    ctx, ok := contextx.NewContext(c, &params)
    if !ok {
        return
    }
    followRecords, total, errCode := followRecordService.GetFollowRecordList(params.Page, params.PageSize, params.Keyword)
    if errCode != ecode.OK {
        ctx.Fail(errCode)
        return
    }
    ctx.OkWithDetailed(response.FollowRecordResponse{
        List:  followRecords,
        Count: int(total),
    })
}
package v1
import (
    "aps_crm/model"
    "aps_crm/model/request"
    "aps_crm/model/response"
    "aps_crm/pkg/contextx"
    "aps_crm/pkg/ecode"
    "github.com/gin-gonic/gin"
    "time"
)
type FollowRecordApi struct{}
// Add
//
//    @Tags        FollowRecord
//    @Summary    添加跟进记录
//    @Produce    application/json
//    @Param        object    body        request.AddFollowRecord    true    "查询参数"
//    @Success    200        {object}    contextx.Response{}
//    @Router        /api/followRecord/add [post]
func (fr *FollowRecordApi) Add(c *gin.Context) {
    var params request.AddFollowRecord
    ctx, ok := contextx.NewContext(c, &params)
    if !ok {
        return
    }
    errCode, followRecord := checkFollowRecordParams(params.FollowRecord)
    if errCode != ecode.OK {
        ctx.Fail(errCode)
        return
    }
    errCode = followRecordService.AddFollowRecord(followRecord)
    if errCode != ecode.OK {
        ctx.Fail(errCode)
        return
    }
    ctx.Ok()
}
// Delete
//
//    @Tags        FollowRecord
//    @Summary    删除跟进记录
//    @Produce    application/json
//    @Param        object    body        request.DeleteFollowRecord true    "查询参数"
//    @Success    200    {object}    contextx.Response{}
//    @Router        /api/followRecord/delete [delete]
func (fr *FollowRecordApi) Delete(c *gin.Context) {
    var params request.DeleteFollowRecord
    ctx, ok := contextx.NewContext(c, &params)
    if !ok {
        return
    }
    errCode := followRecordService.DeleteFollowRecord(params.Ids)
    if errCode != ecode.OK {
        ctx.Fail(errCode)
        return
    }
    ctx.Ok()
}
// Update
//
//    @Tags        FollowRecord
//    @Summary    更新跟进记录
//    @Produce    application/json
//    @Param        object    body        request.UpdateFollowRecord    true    "查询参数"
//    @Success    200        {object}    contextx.Response{}
//    @Router        /api/followRecord/update [put]
func (fr *FollowRecordApi) Update(c *gin.Context) {
    var params request.UpdateFollowRecord
    ctx, ok := contextx.NewContext(c, &params)
    if !ok {
        return
    }
    errCode, followRecord := checkFollowRecordParams(params.FollowRecord)
    if errCode != ecode.OK {
        ctx.Fail(errCode)
        return
    }
    followRecord.Id = params.Id
    errCode = followRecordService.UpdateFollowRecord(followRecord)
    if errCode != ecode.OK {
        ctx.Fail(errCode)
        return
    }
    ctx.Ok()
}
// checkFollowRecordParams
// 检查跟进记录参数
func checkFollowRecordParams(followRecord request.FollowRecord) (int, *model.FollowRecord) {
    var followRecordModel model.FollowRecord
    //if followRecord.ClientId != 0 {
    //    // check client exist
    //    if service.CheckClientExist(followRecord.ClientId) != ecode.OK {
    //        return ecode.ClientNotExist, &followRecordModel
    //    }
    //}
    //
    //if followRecord.ContactId != 0 {
    //    // check contact exist
    //    if service.CheckContactExist(followRecord.ContactId) != ecode.OK {
    //        return ecode.ContactNotExist, &followRecordModel
    //    }
    //}
    //
    //if followRecord.SalesLeadsId != 0 {
    //    // check sales leads exist
    //    if service.CheckSalesLeadsExist(followRecord.SalesLeadsId) != ecode.OK {
    //        return ecode.SalesLeadsNotExist, &followRecordModel
    //    }
    //}
    //
    //// check member id
    //if followRecord.MemberId == 0 {
    //    // todo check member exist
    //    return ecode.InvalidParams, &followRecordModel
    //}
    //
    //// check number
    //if followRecord.Number == "" {
    //    return ecode.InvalidParams, &followRecordModel
    //}
    //
    //// check follow content
    //if followRecord.Content == "" {
    //    return ecode.InvalidParams, &followRecordModel
    //}
    // check follow time
    t, err := checkTimeFormat(followRecord.FollowTime)
    if err != nil {
        return ecode.InvalidParams, &followRecordModel
    }
    followRecordModel.FollowTime = t
    t, err = checkTimeFormat(followRecord.NextFollowTime)
    if err != nil {
        return ecode.InvalidParams, &followRecordModel
    }
    followRecordModel.NextFollowTime = t
    followRecordModel.ClientId = followRecord.ClientId
    followRecordModel.Content = followRecord.Content
    followRecordModel.MemberId = followRecord.MemberId
    followRecordModel.Number = followRecord.Number
    followRecordModel.ClientStatusId = followRecord.ClientStatusId
    followRecordModel.ContactId = followRecord.ContactId
    followRecordModel.Topic = followRecord.Topic
    followRecordModel.SalesLeadsId = followRecord.SalesLeadsId
    followRecordModel.SaleChanceId = followRecord.SaleChanceId
    followRecordModel.ContactInformationId = followRecord.ContactInformationId
    followRecordModel.Purpose = followRecord.Purpose
    followRecordModel.Content = followRecord.Content
    followRecordModel.Record = followRecord.Record
    return ecode.OK, &followRecordModel
}
// checkTimeFormat
// 检查时间格式
func checkTimeFormat(t string) (time.Time, error) {
    if t == "" {
        t = "1900-01-01T00:00:00+08:00"
    }
    location, err := time.LoadLocation("Asia/Shanghai")
    if err != nil {
        return time.Time{}, err
    }
    tt, err := time.Parse("2006-01-02T15:04:05.000Z", t)
    if err == nil {
        return tt.In(location), nil
    }
    tt, err = time.Parse("2006-01-02T15:04:05-07:00", t)
    if err == nil {
        return tt.In(location), nil
    }
    return time.Time{}, err
}
// List
//
//    @Tags        FollowRecord
//    @Summary    回访记录列表
//    @Produce    application/json
//    @Param        object    body        request.GetFollowRecordList    true    "参数"
//    @Success    200        {object}    contextx.Response{data=response.FollowRecordResponse}
//    @Router        /api/followRecord/list [post]
func (fr *FollowRecordApi) List(c *gin.Context) {
    var params request.GetFollowRecordList
    ctx, ok := contextx.NewContext(c, &params)
    if !ok {
        return
    }
    followRecords, total, errCode := followRecordService.GetFollowRecordList(params.Page, params.PageSize, params.SearchMap)
    if errCode != ecode.OK {
        ctx.Fail(errCode)
        return
    }
    ctx.OkWithDetailed(response.FollowRecordResponse{
        List:  followRecords,
        Count: int(total),
    })
}
constvar/const.go
@@ -37,7 +37,6 @@
const (
    SalesStatusNew                           SalesStatus = iota // 新建
    SalesStatusIng                                              // 进行中
    SalesStatusSuccess                                          // 成功
    SalesStatusLevelUptoClient                                  // 升级为客户
    SalesStatusLevelUptoClientAndSalesChance                    // 升级为客户并且有销售机会
    SalesStatusFail                          SalesStatus = -1   // 失败
docs/docs.go
@@ -9663,7 +9663,6 @@
                1,
                2,
                3,
                4,
                -1
            ],
            "x-enum-comments": {
@@ -9671,13 +9670,11 @@
                "SalesStatusIng": "进行中",
                "SalesStatusLevelUptoClient": "升级为客户",
                "SalesStatusLevelUptoClientAndSalesChance": "升级为客户并且有销售机会",
                "SalesStatusNew": "新建",
                "SalesStatusSuccess": "成功"
                "SalesStatusNew": "新建"
            },
            "x-enum-varnames": [
                "SalesStatusNew",
                "SalesStatusIng",
                "SalesStatusSuccess",
                "SalesStatusLevelUptoClient",
                "SalesStatusLevelUptoClientAndSalesChance",
                "SalesStatusFail"
@@ -10369,6 +10366,9 @@
                },
                "id": {
                    "type": "integer"
                },
                "member": {
                    "$ref": "#/definitions/model.User"
                },
                "member_id": {
                    "type": "integer"
@@ -13682,7 +13682,7 @@
                    "type": "integer"
                },
                "search_map": {
                    "description": "搜索条件: map[string]interface{}{\"name\": \"xxx\"}; {\"name\": \"客户名称\", \"phone\": \"手机号码\", \"detail_address\":\"详细地址\", \"next_visit_time\":\"下回回访日期\", \"member_name\": \"销售负责人\", \"client_status\": \"客户状态\", \"client_level\": \"重要级别\"}",
                    "description": "搜索条件: map[string]interface{}{\"name\": \"xxx\"}; {\"name\": \"客户名称\", \"phone\": \"手机号码\", \"detail_address\":\"详细地址\", \"next_visit_time\":\"下回回访日期\", \"member_name\": \"销售负责人\", \"client_status\": \"客户状态\", \"client_level\": \"重要级别\", \"is_first\": \"是否是首要联系人\"}",
                    "type": "object",
                    "additionalProperties": true
                }
@@ -13729,9 +13729,6 @@
        "request.GetFollowRecordList": {
            "type": "object",
            "properties": {
                "keyword": {
                    "type": "string"
                },
                "page": {
                    "description": "页码",
                    "type": "integer"
@@ -13739,6 +13736,11 @@
                "pageSize": {
                    "description": "每页大小",
                    "type": "integer"
                },
                "search_map": {
                    "description": "搜索条件: map[string]interface{}{\"name\": \"xxx\"}; {\"topic\": \"跟进主题\", \"member_name\": \"跟进人\", \"client_name\": \"客户名称\", \"client_status\": \"客户状态\", \"follow_time\": \"跟进时间\", \"next_follow_time\": \"下次跟进时间\", \"record\": \"跟进记录\", \"phone\": \"联系人电话\", \"contact_name\": \"联系人姓名\"}",
                    "type": "object",
                    "additionalProperties": true
                }
            }
        },
docs/swagger.json
@@ -9651,7 +9651,6 @@
                1,
                2,
                3,
                4,
                -1
            ],
            "x-enum-comments": {
@@ -9659,13 +9658,11 @@
                "SalesStatusIng": "进行中",
                "SalesStatusLevelUptoClient": "升级为客户",
                "SalesStatusLevelUptoClientAndSalesChance": "升级为客户并且有销售机会",
                "SalesStatusNew": "新建",
                "SalesStatusSuccess": "成功"
                "SalesStatusNew": "新建"
            },
            "x-enum-varnames": [
                "SalesStatusNew",
                "SalesStatusIng",
                "SalesStatusSuccess",
                "SalesStatusLevelUptoClient",
                "SalesStatusLevelUptoClientAndSalesChance",
                "SalesStatusFail"
@@ -10357,6 +10354,9 @@
                },
                "id": {
                    "type": "integer"
                },
                "member": {
                    "$ref": "#/definitions/model.User"
                },
                "member_id": {
                    "type": "integer"
@@ -13670,7 +13670,7 @@
                    "type": "integer"
                },
                "search_map": {
                    "description": "搜索条件: map[string]interface{}{\"name\": \"xxx\"}; {\"name\": \"客户名称\", \"phone\": \"手机号码\", \"detail_address\":\"详细地址\", \"next_visit_time\":\"下回回访日期\", \"member_name\": \"销售负责人\", \"client_status\": \"客户状态\", \"client_level\": \"重要级别\"}",
                    "description": "搜索条件: map[string]interface{}{\"name\": \"xxx\"}; {\"name\": \"客户名称\", \"phone\": \"手机号码\", \"detail_address\":\"详细地址\", \"next_visit_time\":\"下回回访日期\", \"member_name\": \"销售负责人\", \"client_status\": \"客户状态\", \"client_level\": \"重要级别\", \"is_first\": \"是否是首要联系人\"}",
                    "type": "object",
                    "additionalProperties": true
                }
@@ -13717,9 +13717,6 @@
        "request.GetFollowRecordList": {
            "type": "object",
            "properties": {
                "keyword": {
                    "type": "string"
                },
                "page": {
                    "description": "页码",
                    "type": "integer"
@@ -13727,6 +13724,11 @@
                "pageSize": {
                    "description": "每页大小",
                    "type": "integer"
                },
                "search_map": {
                    "description": "搜索条件: map[string]interface{}{\"name\": \"xxx\"}; {\"topic\": \"跟进主题\", \"member_name\": \"跟进人\", \"client_name\": \"客户名称\", \"client_status\": \"客户状态\", \"follow_time\": \"跟进时间\", \"next_follow_time\": \"下次跟进时间\", \"record\": \"跟进记录\", \"phone\": \"联系人电话\", \"contact_name\": \"联系人姓名\"}",
                    "type": "object",
                    "additionalProperties": true
                }
            }
        },
docs/swagger.yaml
@@ -120,7 +120,6 @@
    - 1
    - 2
    - 3
    - 4
    - -1
    type: integer
    x-enum-comments:
@@ -129,11 +128,9 @@
      SalesStatusLevelUptoClient: 升级为客户
      SalesStatusLevelUptoClientAndSalesChance: 升级为客户并且有销售机会
      SalesStatusNew: 新建
      SalesStatusSuccess: 成功
    x-enum-varnames:
    - SalesStatusNew
    - SalesStatusIng
    - SalesStatusSuccess
    - SalesStatusLevelUptoClient
    - SalesStatusLevelUptoClientAndSalesChance
    - SalesStatusFail
@@ -611,6 +608,8 @@
        type: string
      id:
        type: integer
      member:
        $ref: '#/definitions/model.User'
      member_id:
        type: integer
      next_follow_time:
@@ -2852,7 +2851,7 @@
        additionalProperties: true
        description: '搜索条件: map[string]interface{}{"name": "xxx"}; {"name": "客户名称",
          "phone": "手机号码", "detail_address":"详细地址", "next_visit_time":"下回回访日期", "member_name":
          "销售负责人", "client_status": "客户状态", "client_level": "重要级别"}'
          "销售负责人", "client_status": "客户状态", "client_level": "重要级别", "is_first": "是否是首要联系人"}'
        type: object
    type: object
  request.GetContractList:
@@ -2883,14 +2882,19 @@
    type: object
  request.GetFollowRecordList:
    properties:
      keyword:
        type: string
      page:
        description: 页码
        type: integer
      pageSize:
        description: 每页大小
        type: integer
      search_map:
        additionalProperties: true
        description: '搜索条件: map[string]interface{}{"name": "xxx"}; {"topic": "跟进主题",
          "member_name": "跟进人", "client_name": "客户名称", "client_status": "客户状态", "follow_time":
          "跟进时间", "next_follow_time": "下次跟进时间", "record": "跟进记录", "phone": "联系人电话",
          "contact_name": "联系人姓名"}'
        type: object
    type: object
  request.GetMasterOrderList:
    properties:
model/contact.go
@@ -12,6 +12,7 @@
        Name     string    `json:"name" gorm:"column:name;type:varchar(255);comment:联系人姓名"`
        Number   string    `json:"number" gorm:"column:number;type:varchar(255);comment:联系人编号"`
        ClientId int       `json:"client_id" gorm:"column:client_id;type:int(11);comment:客户ID"`
        Client   Client    `json:"-" gorm:"foreignKey:ClientId"`
        Position string    `json:"position" gorm:"column:position;type:varchar(255);comment:职位"`
        Phone    string    `json:"phone" gorm:"column:phone;type:varchar(255);comment:电话"`
        MemberId int       `json:"member_id" gorm:"column:member_id;type:int(11);comment:负责人ID"`
@@ -80,7 +81,16 @@
                }
                if key == "client_name" {
                    db = db.Joins("inner join clients on clients.id = contacts.client_id").Where("clients.name LIKE ?", "%"+v+"%")
                    //db = db.Joins("inner join clients on clients.id = contacts.client_id").Where("clients.name LIKE ?", "%"+v+"%")
                    db = db.Joins("Client").Where("Client.name LIKE ?", "%"+v+"%")
                }
                if key == "is_first" {
                    if v == "是" {
                        db = db.Where("is_first = ?", true)
                    } else if v == "否" {
                        db = db.Where("is_first = ?", false)
                    }
                }
            case int:
            }
model/followRecord.go
@@ -1,194 +1,189 @@
package model
import (
    "aps_crm/pkg/mysqlx"
    "gorm.io/gorm"
    "time"
)
type (
    FollowRecord struct {
        Id                   int       `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
        ClientId             int       `json:"client_id" gorm:"column:client_id;type:int(11);comment:客户id"`
        ClientStatusId       int       `json:"client_status_id" gorm:"column:client_status_id;type:int(11);comment:客户状态id"`
        MemberId             int       `json:"member_id" gorm:"column:member_id;type:int(11);comment:跟进人id"`
        Number               string    `json:"number" gorm:"column:number;type:varchar(255);comment:跟进编号"`
        ContactId            int       `json:"contact_id" gorm:"column:contact_id;type:int(11);comment:联系人id"`
        Topic                string    `json:"topic" gorm:"column:topic;type:varchar(255);comment:跟进主题"`
        Record               string    `json:"record" gorm:"column:record;type:MEDIUMTEXT;comment:跟进记录"`
        SaleChanceId         int       `json:"sale_chance_id" gorm:"column:sale_chance_id;type:int(11);comment:销售机会id"`
        SalesLeadsId         int       `json:"sales_leads_id" gorm:"column:sales_leads_id;type:int(11);comment:销售线索id"`
        ContactInformationId int       `json:"contact_information_id" gorm:"column:contact_information_id;type:int(11);comment:联系方式id"`
        FollowTime           time.Time `json:"follow_time" gorm:"column:follow_time;type:datetime;comment:跟进时间"`
        NextFollowTime       time.Time `json:"next_follow_time" gorm:"column:next_follow_time;type:datetime;comment:下次跟进时间"`
        Purpose              string    `json:"purpose" gorm:"column:purpose;type:varchar(255);comment:跟进目的"`
        Content              string    `json:"content" gorm:"column:content;type:MEDIUMTEXT;comment:跟进内容"`
        Client               Client    `json:"client" gorm:"foreignKey:ClientId"`
        Contact              Contact   `json:"contact" gorm:"foreignKey:ContactId"`
        gorm.Model           `json:"-"`
    }
    FollowRecordSearch struct {
        FollowRecord
        Orm      *gorm.DB
        Keyword  string
        OrderBy  string
        PageNum  int
        PageSize int
    }
)
func (FollowRecord) TableName() string {
    return "follow_records"
}
func NewFollowRecordSearch() *FollowRecordSearch {
    return &FollowRecordSearch{
        Orm: mysqlx.GetDB(),
    }
}
func (slf *FollowRecordSearch) build() *gorm.DB {
    var db = slf.Orm.Model(&FollowRecord{})
    if slf.Keyword != "" {
        db = db.Where("name LIKE ?", "%"+slf.Keyword+"%")
    }
    if slf.Keyword != "" {
        db = db.Where("topic LIKE ?", "%"+slf.Keyword+"%")
    }
    if slf.Id != 0 {
        db = db.Where("id = ?", slf.Id)
    }
    if slf.ClientId != 0 {
        db = db.Where("client_id = ?", slf.ClientId)
    }
    if slf.ClientStatusId != 0 {
        db = db.Where("client_status_id = ?", slf.ClientStatusId)
    }
    if slf.MemberId != 0 {
        db = db.Where("member_id = ?", slf.MemberId)
    }
    if slf.Number != "" {
        db = db.Where("number = ?", slf.Number)
    }
    if slf.ContactId != 0 {
        db = db.Where("contact_id = ?", slf.ContactId)
    }
    if slf.Topic != "" {
        db = db.Where("topic = ?", slf.Topic)
    }
    if slf.Record != "" {
        db = db.Where("record = ?", slf.Record)
    }
    if slf.SaleChanceId != 0 {
        db = db.Where("sale_chance_id = ?", slf.SaleChanceId)
    }
    if slf.SalesLeadsId != 0 {
        db = db.Where("sales_leads_id = ?", slf.SalesLeadsId)
    }
    if slf.ContactInformationId != 0 {
        db = db.Where("contact_information_id = ?", slf.ContactInformationId)
    }
    if !slf.FollowTime.IsZero() {
        db = db.Where("follow_time = ?", slf.FollowTime)
    }
    if !slf.NextFollowTime.IsZero() {
        db = db.Where("next_follow_time = ?", slf.NextFollowTime)
    }
    if slf.Purpose != "" {
        db = db.Where("purpose = ?", slf.Purpose)
    }
    if slf.Content != "" {
        db = db.Where("content = ?", slf.Content)
    }
    return db
}
func (slf *FollowRecordSearch) First() (*FollowRecord, error) {
    var record = new(FollowRecord)
    err := slf.build().First(record).Error
    return record, err
}
func (slf *FollowRecordSearch) FindAll() ([]*FollowRecord, int64, error) {
    var db = slf.build()
    var records = make([]*FollowRecord, 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.Preload("Client").Preload("Contact").Find(&records).Error
    return records, total, err
}
func (slf *FollowRecordSearch) Count() (int64, error) {
    var count int64
    err := slf.build().Count(&count).Error
    return count, err
}
func (slf *FollowRecordSearch) Page(page, pageSize int) ([]*FollowRecord, int64, error) {
    var records = make([]*FollowRecord, 0)
    var count int64
    err := slf.build().Count(&count).Error
    if err != nil {
        return records, count, err
    }
    err = slf.build().Offset((page - 1) * pageSize).Limit(pageSize).Find(&records).Error
    return records, count, err
}
func (slf *FollowRecordSearch) Create(record *FollowRecord) error {
    var db = slf.build()
    return db.Create(record).Error
}
func (slf *FollowRecordSearch) Update(record *FollowRecord) error {
    var db = slf.build()
    return db.Updates(record).Error
}
func (slf *FollowRecordSearch) Delete() error {
    var db = slf.build()
    return db.Delete(&slf.FollowRecord).Error
}
func (slf *FollowRecordSearch) SetId(id int) *FollowRecordSearch {
    slf.Id = id
    return slf
}
func (slf *FollowRecordSearch) SetClientId(clientId int) *FollowRecordSearch {
    slf.ClientId = clientId
    return slf
}
func (slf *FollowRecordSearch) SetKeyword(keyword string) *FollowRecordSearch {
    slf.Keyword = keyword
    return slf
}
func (slf *FollowRecordSearch) SetPage(page, size int) *FollowRecordSearch {
    slf.PageNum, slf.PageSize = page, size
    return slf
}
func (slf *FollowRecordSearch) SetOrder(order string) *FollowRecordSearch {
    slf.OrderBy = order
    return slf
}
func (slf *FollowRecordSearch) SetIds(ids []int) *FollowRecordSearch {
    slf.Orm = slf.Orm.Where("id in (?)", ids)
    return slf
}
func (slf *FollowRecordSearch) UpdateMap(data map[string]interface{}) error {
    var db = slf.build()
    return db.Updates(data).Error
}
package model
import (
    "aps_crm/pkg/mysqlx"
    "gorm.io/gorm"
    "time"
)
type (
    FollowRecord struct {
        Id                   int       `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
        ClientId             int       `json:"client_id" gorm:"column:client_id;type:int(11);comment:客户id"`
        ClientStatusId       int       `json:"client_status_id" gorm:"column:client_status_id;type:int(11);comment:客户状态id"`
        MemberId             int       `json:"member_id" gorm:"column:member_id;type:int(11);comment:跟进人id"`
        Member               User      `json:"member" gorm:"foreignKey:MemberId"`
        Number               string    `json:"number" gorm:"column:number;type:varchar(255);comment:跟进编号"`
        ContactId            int       `json:"contact_id" gorm:"column:contact_id;type:int(11);comment:联系人id"`
        Topic                string    `json:"topic" gorm:"column:topic;type:varchar(255);comment:跟进主题"`
        Record               string    `json:"record" gorm:"column:record;type:MEDIUMTEXT;comment:跟进记录"`
        SaleChanceId         int       `json:"sale_chance_id" gorm:"column:sale_chance_id;type:int(11);comment:销售机会id"`
        SalesLeadsId         int       `json:"sales_leads_id" gorm:"column:sales_leads_id;type:int(11);comment:销售线索id"`
        ContactInformationId int       `json:"contact_information_id" gorm:"column:contact_information_id;type:int(11);comment:联系方式id"`
        FollowTime           time.Time `json:"follow_time" gorm:"column:follow_time;type:datetime;comment:跟进时间"`
        NextFollowTime       time.Time `json:"next_follow_time" gorm:"column:next_follow_time;type:datetime;comment:下次跟进时间"`
        Purpose              string    `json:"purpose" gorm:"column:purpose;type:varchar(255);comment:跟进目的"`
        Content              string    `json:"content" gorm:"column:content;type:MEDIUMTEXT;comment:跟进内容"`
        Client               Client    `json:"client" gorm:"foreignKey:ClientId"`
        Contact              Contact   `json:"contact" gorm:"foreignKey:ContactId"`
        gorm.Model           `json:"-"`
    }
    FollowRecordSearch struct {
        FollowRecord
        Orm       *gorm.DB
        SearchMap map[string]interface{}
        OrderBy   string
        PageNum   int
        PageSize  int
    }
)
func (FollowRecord) TableName() string {
    return "follow_records"
}
func NewFollowRecordSearch() *FollowRecordSearch {
    return &FollowRecordSearch{
        Orm: mysqlx.GetDB(),
    }
}
func (slf *FollowRecordSearch) build() *gorm.DB {
    var db = slf.Orm.Model(&FollowRecord{})
    if slf.Id != 0 {
        db = db.Where("id = ?", slf.Id)
    }
    if slf.ClientId != 0 {
        db = db.Where("client_id = ?", slf.ClientId)
    }
    if len(slf.SearchMap) > 0 {
        for key, value := range slf.SearchMap {
            switch v := value.(type) {
            case string:
                if key == "topic" || key == "record" {
                    db = db.Where(key+" LIKE ?", "%"+v+"%")
                }
                if key == "client_name" {
                    db = db.Joins("Client").Where("Client.name LIKE ?", "%"+v+"%")
                }
                if key == "contact_name" {
                    db = db.Joins("Contact").Where("Contact.name LIKE ?", "%"+v+"%")
                }
                if key == "member_name" {
                    db = db.Joins("Member").Where("Member.username LIKE ?", "%"+v+"%")
                }
                if key == "phone" {
                    db = db.Joins("Contact").Where("Contacts.phone LIKE ?", "%"+v+"%")
                }
                if key == "follow_time" {
                    db = db.Where("follow_time = ?", v)
                }
                if key == "next_follow_time" {
                    db = db.Where("next_follow_time = ?", v)
                }
                if key == "client_status" {
                    db = db.Joins("Client").Joins("Client.ClientStatus").Where("Client__ClientStatus.name LIKE ?", "%"+v+"%")
                }
            }
        }
    }
    return db
}
func (slf *FollowRecordSearch) First() (*FollowRecord, error) {
    var record = new(FollowRecord)
    err := slf.build().First(record).Error
    return record, err
}
func (slf *FollowRecordSearch) FindAll() ([]*FollowRecord, int64, error) {
    var db = slf.build()
    var records = make([]*FollowRecord, 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.Preload("Client").Preload("Contact").Find(&records).Error
    return records, total, err
}
func (slf *FollowRecordSearch) Count() (int64, error) {
    var count int64
    err := slf.build().Count(&count).Error
    return count, err
}
func (slf *FollowRecordSearch) Page(page, pageSize int) ([]*FollowRecord, int64, error) {
    var records = make([]*FollowRecord, 0)
    var count int64
    err := slf.build().Count(&count).Error
    if err != nil {
        return records, count, err
    }
    err = slf.build().Offset((page - 1) * pageSize).Limit(pageSize).Find(&records).Error
    return records, count, err
}
func (slf *FollowRecordSearch) Create(record *FollowRecord) error {
    var db = slf.build()
    return db.Create(record).Error
}
func (slf *FollowRecordSearch) Update(record *FollowRecord) error {
    var db = slf.build()
    return db.Updates(record).Error
}
func (slf *FollowRecordSearch) Delete() error {
    var db = slf.build()
    return db.Delete(&slf.FollowRecord).Error
}
func (slf *FollowRecordSearch) SetId(id int) *FollowRecordSearch {
    slf.Id = id
    return slf
}
func (slf *FollowRecordSearch) SetClientId(clientId int) *FollowRecordSearch {
    slf.ClientId = clientId
    return slf
}
func (slf *FollowRecordSearch) SetPage(page, size int) *FollowRecordSearch {
    slf.PageNum, slf.PageSize = page, size
    return slf
}
func (slf *FollowRecordSearch) SetOrder(order string) *FollowRecordSearch {
    slf.OrderBy = order
    return slf
}
func (slf *FollowRecordSearch) SetIds(ids []int) *FollowRecordSearch {
    slf.Orm = slf.Orm.Where("id in (?)", ids)
    return slf
}
func (slf *FollowRecordSearch) UpdateMap(data map[string]interface{}) error {
    var db = slf.build()
    return db.Updates(data).Error
}
func (slf *FollowRecordSearch) SetSearchMap(data map[string]interface{}) *FollowRecordSearch {
    slf.SearchMap = data
    return slf
}
model/request/contact.go
@@ -29,7 +29,7 @@
type GetContactList struct {
    PageInfo
    SearchMap map[string]interface{} `json:"search_map"` // 搜索条件: map[string]interface{}{"name": "xxx"}; {"name": "客户名称", "phone": "手机号码", "detail_address":"详细地址", "next_visit_time":"下回回访日期", "member_name": "销售负责人", "client_status": "客户状态", "client_level": "重要级别"}
    SearchMap map[string]interface{} `json:"search_map"` // 搜索条件: map[string]interface{}{"name": "xxx"}; {"name": "客户名称", "phone": "手机号码", "detail_address":"详细地址", "next_visit_time":"下回回访日期", "member_name": "销售负责人", "client_status": "客户状态", "client_level": "重要级别", "is_first": "是否是首要联系人"}
}
type DeleteContact struct {
model/request/followRecord.go
@@ -1,36 +1,36 @@
package request
type AddFollowRecord struct {
    FollowRecord FollowRecord `json:"follow_record" binding:"required"`
}
type FollowRecord struct {
    ClientId             int    `json:"client_id" gorm:"column:client_id;type:int(11);comment:客户id"`
    ClientStatusId       int    `json:"client_status_id" gorm:"column:client_status_id;type:int(11);comment:客户状态id"`
    MemberId             int    `json:"member_id" gorm:"column:member_id;type:int(11);comment:跟进人id"`
    Number               string `json:"number" gorm:"column:number;type:varchar(255);comment:跟进编号"`
    ContactId            int    `json:"contact_id" gorm:"column:contact_id;type:int(11);comment:联系人id"`
    Topic                string `json:"topic" gorm:"column:topic;type:varchar(255);comment:跟进主题"`
    Record               string `json:"record" gorm:"column:record;type:MEDIUMTEXT;comment:跟进记录"`
    SaleChanceId         int    `json:"sale_chance_id" gorm:"column:sale_chance_id;type:int(11);comment:销售机会id"`
    SalesLeadsId         int    `json:"sales_leads_id" gorm:"column:sales_leads_id;type:int(11);comment:销售线索id"`
    ContactInformationId int    `json:"contact_information_id" gorm:"column:contact_information_id;type:int(11);comment:联系方式id"`
    FollowTime           string `json:"follow_time" gorm:"column:follow_time;type:datetime;comment:跟进时间"`
    NextFollowTime       string `json:"next_follow_time" gorm:"column:next_follow_time;type:datetime;comment:下次跟进时间"`
    Purpose              string `json:"purpose" gorm:"column:purpose;type:varchar(255);comment:跟进目的"`
    Content              string `json:"content" gorm:"column:content;type:varchar(255);comment:跟进内容"`
}
type UpdateFollowRecord struct {
    Id           int          `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
    FollowRecord FollowRecord `json:"follow_record" binding:"required"`
}
type GetFollowRecordList struct {
    PageInfo
    Keyword string `json:"keyword"`
}
type DeleteFollowRecord struct {
    Ids []int `json:"ids"`
}
package request
type AddFollowRecord struct {
    FollowRecord FollowRecord `json:"follow_record" binding:"required"`
}
type FollowRecord struct {
    ClientId             int    `json:"client_id" gorm:"column:client_id;type:int(11);comment:客户id"`
    ClientStatusId       int    `json:"client_status_id" gorm:"column:client_status_id;type:int(11);comment:客户状态id"`
    MemberId             int    `json:"member_id" gorm:"column:member_id;type:int(11);comment:跟进人id"`
    Number               string `json:"number" gorm:"column:number;type:varchar(255);comment:跟进编号"`
    ContactId            int    `json:"contact_id" gorm:"column:contact_id;type:int(11);comment:联系人id"`
    Topic                string `json:"topic" gorm:"column:topic;type:varchar(255);comment:跟进主题"`
    Record               string `json:"record" gorm:"column:record;type:MEDIUMTEXT;comment:跟进记录"`
    SaleChanceId         int    `json:"sale_chance_id" gorm:"column:sale_chance_id;type:int(11);comment:销售机会id"`
    SalesLeadsId         int    `json:"sales_leads_id" gorm:"column:sales_leads_id;type:int(11);comment:销售线索id"`
    ContactInformationId int    `json:"contact_information_id" gorm:"column:contact_information_id;type:int(11);comment:联系方式id"`
    FollowTime           string `json:"follow_time" gorm:"column:follow_time;type:datetime;comment:跟进时间"`
    NextFollowTime       string `json:"next_follow_time" gorm:"column:next_follow_time;type:datetime;comment:下次跟进时间"`
    Purpose              string `json:"purpose" gorm:"column:purpose;type:varchar(255);comment:跟进目的"`
    Content              string `json:"content" gorm:"column:content;type:varchar(255);comment:跟进内容"`
}
type UpdateFollowRecord struct {
    Id           int          `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
    FollowRecord FollowRecord `json:"follow_record" binding:"required"`
}
type GetFollowRecordList struct {
    PageInfo
    SearchMap map[string]interface{} `json:"search_map"` // 搜索条件: map[string]interface{}{"name": "xxx"}; {"topic": "跟进主题", "member_name": "跟进人", "client_name": "客户名称", "client_status": "客户状态", "follow_time": "跟进时间", "next_follow_time": "下次跟进时间", "record": "跟进记录", "phone": "联系人电话", "contact_name": "联系人姓名"}
}
type DeleteFollowRecord struct {
    Ids []int `json:"ids"`
}
service/followRecord.go
@@ -1,77 +1,77 @@
package service
import (
    "aps_crm/model"
    "aps_crm/pkg/ecode"
)
type FollowRecordService struct{}
func (FollowRecordService) AddFollowRecord(followRecord *model.FollowRecord) int {
    err := model.NewFollowRecordSearch().Create(followRecord)
    if err != nil {
        return ecode.FollowRecordExist
    }
    return ecode.OK
}
// check followRecord exist
func checkFollowRecordExist(id int) int {
    _, err := model.NewFollowRecordSearch().SetId(id).First()
    if err != nil {
        return ecode.FollowRecordNotExist
    }
    return ecode.OK
}
func (FollowRecordService) UpdateFollowRecord(followRecord *model.FollowRecord) int {
    // check followRecord exist
    errCode := checkFollowRecordExist(followRecord.Id)
    if errCode != ecode.OK {
        return errCode
    }
    // update followRecord
    err := model.NewFollowRecordSearch().SetId(followRecord.Id).Update(followRecord)
    if err != nil {
        return ecode.FollowRecordUpdateErr
    }
    return ecode.OK
}
func (FollowRecordService) GetFollowRecordList(page, pageSize int, keyword string) ([]*model.FollowRecord, int64, int) {
    // get contact list
    contacts, total, err := model.NewFollowRecordSearch().SetKeyword(keyword).SetPage(page, pageSize).FindAll()
    if err != nil {
        return nil, 0, ecode.FollowRecordListErr
    }
    return contacts, total, ecode.OK
}
func (FollowRecordService) DeleteFollowRecord(ids []int) int {
    // delete client
    err := model.NewFollowRecordSearch().SetIds(ids).Delete()
    if err != nil {
        return ecode.FollowRecordDeleteErr
    }
    return ecode.OK
}
func (FollowRecordService) Assign(ids []int, memberId int) int {
    // check followRecord exist
    //errCode := checkFollowRecordExist(id)
    //if errCode != ecode.OK {
    //    return errCode
    //}
    // assign followRecord
    err := model.NewFollowRecordSearch().SetIds(ids).UpdateMap(map[string]interface{}{
        "member_id": memberId,
    })
    if err != nil {
        return ecode.FollowRecordAssignErr
    }
    return ecode.OK
}
package service
import (
    "aps_crm/model"
    "aps_crm/pkg/ecode"
)
type FollowRecordService struct{}
func (FollowRecordService) AddFollowRecord(followRecord *model.FollowRecord) int {
    err := model.NewFollowRecordSearch().Create(followRecord)
    if err != nil {
        return ecode.FollowRecordExist
    }
    return ecode.OK
}
// check followRecord exist
func checkFollowRecordExist(id int) int {
    _, err := model.NewFollowRecordSearch().SetId(id).First()
    if err != nil {
        return ecode.FollowRecordNotExist
    }
    return ecode.OK
}
func (FollowRecordService) UpdateFollowRecord(followRecord *model.FollowRecord) int {
    // check followRecord exist
    errCode := checkFollowRecordExist(followRecord.Id)
    if errCode != ecode.OK {
        return errCode
    }
    // update followRecord
    err := model.NewFollowRecordSearch().SetId(followRecord.Id).Update(followRecord)
    if err != nil {
        return ecode.FollowRecordUpdateErr
    }
    return ecode.OK
}
func (FollowRecordService) GetFollowRecordList(page, pageSize int, data map[string]interface{}) ([]*model.FollowRecord, int64, int) {
    // get contact list
    contacts, total, err := model.NewFollowRecordSearch().SetPage(page, pageSize).SetSearchMap(data).FindAll()
    if err != nil {
        return nil, 0, ecode.FollowRecordListErr
    }
    return contacts, total, ecode.OK
}
func (FollowRecordService) DeleteFollowRecord(ids []int) int {
    // delete client
    err := model.NewFollowRecordSearch().SetIds(ids).Delete()
    if err != nil {
        return ecode.FollowRecordDeleteErr
    }
    return ecode.OK
}
func (FollowRecordService) Assign(ids []int, memberId int) int {
    // check followRecord exist
    //errCode := checkFollowRecordExist(id)
    //if errCode != ecode.OK {
    //    return errCode
    //}
    // assign followRecord
    err := model.NewFollowRecordSearch().SetIds(ids).UpdateMap(map[string]interface{}{
        "member_id": memberId,
    })
    if err != nil {
        return ecode.FollowRecordAssignErr
    }
    return ecode.OK
}
service/salesLeads.go
@@ -27,17 +27,17 @@
}
// CheckSalesLeadsExist check salesLeads exist
func CheckSalesLeadsExist(id int) int {
    tmp, err := model.NewSalesLeadsSearch(nil).SetId(id).Find()
func CheckSalesLeadsExist(id int) (int, *model.SalesLeads) {
    tmp, err := model.NewSalesLeadsSearch(nil).SetId(id).First()
    if err != nil {
        return ecode.SalesLeadsNotExist
        return ecode.SalesLeadsNotExist, nil
    }
    if len(tmp) == 0 {
        return ecode.SalesLeadsNotExist
    if tmp.Id == 0 {
        return ecode.SalesLeadsNotExist, nil
    }
    return ecode.OK
    return ecode.OK, &tmp
}
func (SalesLeadsService) GetSalesLeadsList(page, pageSize int, data map[string]interface{}) ([]*model.SalesLeads, int64, int) {
@@ -78,11 +78,16 @@
func (SalesLeadsService) PushSalesLeads(id int, step constvar.SalesStatus, txt string) int {
    // check salesLeads exist
    errCode := CheckSalesLeadsExist(id)
    errCode, tmp := CheckSalesLeadsExist(id)
    if errCode != ecode.OK {
        return errCode
    }
    // check step
    if tmp.SalesStatus > step && step != constvar.SalesStatusFail {
        return ecode.SalesLeadsStatusErr
    }
    switch step {
    case constvar.SalesStatusFail:
        err := model.NewSalesLeadsSearch(nil).SetId(id).UpdateMap(map[string]interface{}{