package service import ( "context" "database/sql" "fmt" "log" "strings" "time" qu "app.yhyue.com/moapp/jybase/common" "app.yhyue.com/moapp/jybase/date" "bp.jydev.jianyu360.cn/BaseService/userCenter/rpc/pb" cm "bp.jydev.jianyu360.cn/CRM/application/api/common" "bp.jydev.jianyu360.cn/CRM/application/entity" baseC "bp.jydev.jianyu360.cn/CRM/baseCenter/rpc/pb" "github.com/gogf/gf/v2/util/gconv" ) // 客户相关 type CustomService struct { BaseUserId int64 PositionId int64 EntUserId int64 EntId int64 AppId string AccountId int64 EntDeptId int64 CustomType int64 //客户类型 Summary string //概要信息 CustomAllName string //客户全称 CustomAbbreviation string //客户简称 CustomLevel int64 //客户级别 CustomIndustry int64 //客户行业 CustomDetailIndustry int64 //客户细分行业 Province string //省份 City string //城市 District string //地区 Address string //详细地址 CompanyPhone string //公司电话 NextfollowUpTime int64 //下次跟进时间戳 Types int64 //处理方式 1自办;2转办 User []int64 //转办用户 EmployCustomId int64 //客户收录id EmployInfoId int64 //资讯收录id Remarks string //备注 CreateName string //创建人 Source string OwnerId string //潜客收录id(人脉) BusinessId string //商机收录id(人脉) } // Add 创建客户 func (this *CustomService) Add(ctx context.Context) (int64, string) { nowtime := time.Now().Format(date.Date_Full_Layout) nextFollowTime := time.Unix(this.NextfollowUpTime, 0).Format(date.Date_Full_Layout) args := []interface{}{} argsTask := []interface{}{} argsTaskTeam := []interface{}{} //判断处理方式 //转办 baseUserIdArr := []int64{} customId, taskId := int64(-1), int64(-1) groupId := "" if this.Types == 2 { transferArr := []int64{} for _, v := range this.User { i_entuserid := v resp, err := cm.UserCenterRpc.IdentityByEntUserId(ctx, &pb.IdentityReq{ Id: i_entuserid, }) if err != nil { log.Println("获取用户职位id信息出错", i_entuserid, "的信息出错", err) return -1, groupId } else if resp == nil { log.Println("entuser用户", i_entuserid, "没有找到职位信息") return -1, groupId } transferArr = append(transferArr, resp.PositionId) baseUserIdArr = append(baseUserIdArr, resp.UserId) } //客户 args = append(args, this.PositionId, this.EntId, this.EntUserId, this.EmployInfoId, this.EmployCustomId, this.CustomType, this.CustomAllName, this.CustomAbbreviation, this.Summary, qu.If(this.CustomLevel == 0, nil, this.CustomLevel), this.CustomIndustry, this.CustomDetailIndustry, qu.If(this.Province == "", nil, this.Province), qu.If(this.City == "", nil, this.City), qu.If(this.District == "", nil, this.District), qu.If(this.Address == "", nil, this.Address), qu.If(this.CompanyPhone == "", nil, this.CompanyPhone), qu.If(this.Remarks == "", nil, this.Remarks), this.CreateName, nowtime, this.Source, this.OwnerId, this.BusinessId) //任务 argsTask = append(argsTask, this.EntId, this.CustomAllName+"的跟进任务", 3, this.PositionId, 1, nowtime, 1, 0, qu.If(this.NextfollowUpTime == 0, nil, nextFollowTime), nil, nil) customId, taskId = SaveCustom(ctx, args, argsTask, argsTaskTeam, this.EmployInfoId, this.EmployCustomId, this.OwnerId, this.BusinessId, this.PositionId, this.CreateName, transferArr, this.EntId, this.EntUserId, this.EntDeptId) if customId < 0 { return -1, groupId } } else if this.Types == 1 { //客户 args = append(args, this.PositionId, this.EntId, this.EntUserId, this.EmployInfoId, this.EmployCustomId, this.CustomType, this.CustomAllName, this.CustomAbbreviation, this.Summary, qu.If(this.CustomLevel == 0, nil, this.CustomLevel), this.CustomIndustry, this.CustomDetailIndustry, qu.If(this.Province == "", nil, this.Province), qu.If(this.City == "", nil, this.City), qu.If(this.District == "", nil, this.District), qu.If(this.Address == "", nil, this.Address), qu.If(this.CompanyPhone == "", nil, this.CompanyPhone), qu.If(this.Remarks == "", nil, this.Remarks), this.CreateName, nowtime, this.Source, this.OwnerId, this.BusinessId) //任务s argsTask = append(argsTask, this.EntId, this.CustomAllName+"的跟进任务", 3, this.PositionId, 2, nowtime, 1, 0, qu.If(this.NextfollowUpTime == 0, nil, nextFollowTime), nil, nil) //任务团队 argsTaskTeam = append(argsTaskTeam, this.PositionId, this.EntUserId, this.CreateName, 1, nowtime) //存库 customId, taskId = SaveCustom(ctx, args, argsTask, argsTaskTeam, this.EmployInfoId, this.EmployCustomId, this.OwnerId, this.BusinessId, this.PositionId, this.CreateName, []int64{}, this.EntId, this.EntUserId, this.EntDeptId) if customId < 0 { return -1, groupId } baseUserIdArr = append(baseUserIdArr, this.BaseUserId) //自办 创建 群聊 // gp := &Group{ // EntId: this.EntId, // PositionId: this.PositionId, // UserIdArr: []int64{}, // AppId: this.AppId, // EntUserId: this.EntUserId, // AccountId: this.AccountId, // } // groupId = gp.GroupAdd() } else if this.Types == 3 { transferArr := []int64{} transferArr = append(transferArr, this.PositionId) //客户 args = append(args, this.PositionId, this.EntId, this.EntUserId, this.EmployInfoId, this.EmployCustomId, this.CustomType, this.CustomAllName, this.CustomAbbreviation, this.Summary, qu.If(this.CustomLevel == 0, nil, this.CustomLevel), this.CustomIndustry, this.CustomDetailIndustry, qu.If(this.Province == "", nil, this.Province), qu.If(this.City == "", nil, this.City), qu.If(this.District == "", nil, this.District), qu.If(this.Address == "", nil, this.Address), qu.If(this.CompanyPhone == "", nil, this.CompanyPhone), qu.If(this.Remarks == "", nil, this.Remarks), this.CreateName, nowtime, this.Source, this.OwnerId, this.BusinessId) //任务 argsTask = append(argsTask, this.EntId, this.CustomAllName+"的跟进任务", 3, this.PositionId, 1, nowtime, 1, 0, qu.If(this.NextfollowUpTime == 0, nil, nextFollowTime), nil, nil) customId, taskId = SaveCustom(ctx, args, argsTask, argsTaskTeam, this.EmployInfoId, this.EmployCustomId, this.OwnerId, this.BusinessId, this.PositionId, this.CreateName, transferArr, this.EntId, this.EntUserId, this.EntDeptId) if customId < 0 { return -1, groupId } baseUserIdArr = append(baseUserIdArr, this.BaseUserId) } u := &User{BaseUserIds: baseUserIdArr} if this.Types != 3 { var kb strings.Builder var vb strings.Builder for k, v := range u.GetUserId(this.EntId) { kb.WriteString(k + ",") vb.WriteString(gconv.String(v) + ",") userId := strings.TrimRight(kb.String(), ",") positionId := strings.TrimRight(vb.String(), ",") next := strings.Replace(time.Unix(this.NextfollowUpTime, 0).Format(YYYYMMDDHHMM), " ", "%20", -1) pcHref := "" content := "" if this.Types == 1 { pcHref = fmt.Sprintf(cm.Push.Custom.Create.MyselfPcHref, positionId, taskId, customId) content = fmt.Sprintf(cm.Push.Custom.Create.MySelfContent, this.CreateName, strings.Replace(date.NowFormat(YYYYMMDDHHMM), " ", "%20", -1), next) } else if this.Types == 2 { pcHref = fmt.Sprintf(cm.Push.Custom.Create.TransferPcHref, positionId) content = fmt.Sprintf(cm.Push.Custom.Create.TransferContent, this.CreateName, strings.Replace(date.NowFormat(YYYYMMDDHHMM), " ", "%20", -1), next) } StationMailPush(userId, positionId, cm.Push.Custom.Create.Title, content, pcHref, cm.Push.Custom.Create.MobileHref, "11") } } return 1, groupId } func SaleCustomAdd(tx *sql.Tx, args []interface{}) int64 { fields := []string{"position_id", "ent_id", "ent_user_id", "employ_info_id", "employ_custom_id", "type", "full_name", "sort_name", "summary", "level_1", "industry", "subdivision_industry", "province", "city", "county", "address", "phone", "remark", "create_person", "create_time", "source", "connection_owner_id", "connection_business_id"} _, id := cm.CrmMysql.InsertBatchByTx(tx, entity.CUSTOM, fields, args) return id } // EmployUpdate 是否创建线索/机会/客户修改 // return employ_info_id,employ_custom_id func EmployUpdate(tx *sql.Tx, employ_info_id, employ_custom_id, positionId int64, key string, entId, entUserId, entDeptId int64) (int64, int64) { tablename := "" id := int64(0) if employ_custom_id > 0 { tablename = entity.EMPLOY_CUSTOM id = employ_custom_id } else if employ_info_id > 0 { tablename = entity.EMPLOY_INFO id = employ_info_id } fmt.Println(tablename, id) if tablename == "" || id == 0 { return employ_info_id, employ_custom_id } //判断该条信息是不是当前资讯分配员的 d := cm.CrmMysql.SelectBySqlByTx(tx, fmt.Sprintf(`select * from %v where id = ?`, tablename), id) fmt.Println(d) if d != nil && len(*d) > 0 { data := (*d)[0] position_id := gconv.Int64(data["position_id"]) if position_id == positionId { cm.CrmMysql.UpdateByTx(tx, tablename, map[string]interface{}{"id": id, "position_id": positionId}, map[string]interface{}{key: 1, "is_handle": 1}) } else { //判断是否已创建该条,但是是取消收录状态、如果是则改为已收录,不是则创建一条新的 d2 := cm.CrmMysql.SelectBySqlByTx(tx, fmt.Sprintf(`select * from %v where source_id = ? and position_id =?`, tablename), data["source_id"], positionId) if d2 != nil && len(*d2) > 0 { //已创建 qwe := cm.CrmMysql.UpdateByTx(tx, tablename, map[string]interface{}{ "source_id": data["source_id"], "position_id": positionId, }, map[string]interface{}{ key: 1, "status": 1, }) log.Println(qwe, data["source_id"], positionId) } else { data["position_id"] = positionId data["ent_id"] = entId data["ent_dept_id"] = entDeptId data["ent_user_id"] = entUserId //当前咨询不是分配员的 创建该条 if employ_custom_id > 0 { // data["is_handle"] = 1 data["is_ignore"] = 0 data["is_create_custom"] = 1 } else if employ_info_id > 0 { data["is_handle"] = 1 data["is_ignore"] = 0 data["is_dis"] = 0 data[key] = 1 for _, v := range GetOtherKey(key) { data[v] = 0 } } delete(data, "id") newId := cm.CrmMysql.InsertByTx(tx, tablename, data) if tablename == entity.EMPLOY_INFO { employ_info_id = newId } else if tablename == entity.EMPLOY_CUSTOM { employ_custom_id = newId } } } } return employ_info_id, employ_custom_id } func SaveCustom(ctx context.Context, argsCustom, argsTask, argsTaskTeam []interface{}, employ_info_id, employ_custom_id int64, ownerId, connectionBusinessId string, positionId int64, createPerson string, transferArr []int64, entId, entUserId, entDeptId int64) (int64, int64) { customId := int64(-1) taskId := int64(-1) //存库 cm.CrmMysql.ExecTx("创建客户", func(tx *sql.Tx) bool { //修改状态 employ_info_id_new, employ_custom_id_new := EmployUpdate(tx, employ_info_id, employ_custom_id, positionId, "is_create_custom", entId, entUserId, entDeptId) //插入客户 //修改客户id、咨询id argsCustom[3] = employ_info_id_new argsCustom[4] = employ_custom_id_new customId = SaleCustomAdd(tx, argsCustom) //传过来的argTask没有来源id,需要append argsTask = append(argsTask, customId) //任务车存储 taskId = TaskAdd(tx, argsTask, argsTaskTeam, transferArr, positionId) //插入台账 ok2 := SaveLedger(ctx, positionId, customId, taskId, "创建客户", fmt.Sprintf("%s创建了客户", createPerson), createPerson) //人脉信息添加 if ownerId != "" || connectionBusinessId != "" { SaveConnection(tx, positionId, connectionBusinessId, ownerId, entId, entDeptId, entUserId) } if customId > 0 && taskId > 0 && ok2 { return true } log.Println("SaveCustom err:", customId, taskId) return false }) return customId, taskId } // SaveLedger 操作台帐相关 func SaveLedger(ctx context.Context, positionId, businessId, taskId int64, types, content, createPerson string) bool { //操作台账 resp, err := cm.BaseCenterRpc.LedgerAdd(ctx, &baseC.LedgerAddReq{ PositionId: positionId, BusinessId: businessId, //业务id TaskId: taskId, //任务id Types: types, //类型 Content: content, //内容 CreateWay: 1, //创建方式 1:人 2:系统 CreatePerson: createPerson, }) if err != nil { log.Println("save ledger err:", err) return false } if resp == nil { log.Println("save ledger resp is nil") return false } return resp.State } // 消息漏斗保存 func saveSalesFunnel(tx *sql.Tx, args []interface{}, tpl_id int64) int64 { fields := []string{`chance_id`, `task_id`, `chance_name`, `outline`, `next_follow_time`, `expected_transaction_amount`, `business_type`, `ent_id`, `employ_info_id`, `current_generation`, `current_generation_progress`, `generation`} //当前阶段 stageId := int64(0) stageData := cm.CrmMysql.Find(entity.CONFIG_TPL_STAGE, map[string]interface{}{ "tpl_id": tpl_id}, "id, `order`", "", -1, -1) if stageData != nil && len(*stageData) > 0 { var a1 []interface{} for _, m := range *stageData { stageId = gconv.Int64(m["id"]) order := gconv.Int(m["order"]) a1 = append(a1, args...) if order == 1 { a1 = append(a1, stageId) } else { a1 = append(a1, 0) } a1 = append(a1, 0) a1 = append(a1, stageId) //进度查询 /*matterData := cm.CrmMysql.SelectBySql("select COUNT(1) as ratio from config_stage_matter where stage_id=? and is_must == 1", stageId) if matterData != nil && len(*matterData) > 0 { ratio := gconv.Int64((*matterData)[0]["ratio"]) a1 = append(a1, ratio) } else { a1 = append(a1, 0) }*/ } //当前阶段进展 _, id := cm.CrmMysql.InsertBatchByTx(tx, entity.SALES_FUNNEL, fields, a1) return id /**/ } return 0 } func GetOtherKey(key string) []string { parameters := map[string][]string{ "is_create_clue": {"is_create_chance", "is_create_custom"}, "is_create_chance": {"is_create_clue", "is_create_custom"}, "is_create_custom": {"is_create_chance", "is_create_clue"}, } return parameters[key] } func SaveConnection(tx *sql.Tx, positionId int64, businessId, ownerId string, entId, entDeptId, entUserId int64) bool { if businessId != "" || ownerId != "" { table := entity.CONNECTION_STATUS sourceType := 2 if businessId == "" { businessId = ownerId sourceType = 1 } if cm.CrmMysql.Count(table, map[string]interface{}{ "position_id": positionId, "relate_id": businessId, "itype": sourceType, }) > 0 { cm.CrmMysql.UpdateByTx(tx, table, map[string]interface{}{ "position_id": positionId, "relate_id": businessId, "itype": sourceType, }, map[string]interface{}{ "is_handle": 1, "relate_id": businessId, "update_time": time.Now().Format(date.Date_Full_Layout), "is_create": 1, }) return true } else { id := cm.CrmMysql.InsertByTx(tx, table, map[string]interface{}{ "position_id": positionId, "ent_id": entId, "ent_dept_id": entDeptId, "ent_user_id": entUserId, "relate_id": businessId, "is_handle": 1, "is_create": 1, "itype": sourceType, "create_time": time.Now().Format(date.Date_Full_Layout), "update_time": time.Now().Format(date.Date_Full_Layout), }) return id > 0 } } return true }