package service import ( "database/sql" "log" "math" "sync" "time" "app.yhyue.com/moapp/jybase/date" common "app.yhyue.com/moapp/jybase/common" . "bp.jydev.jianyu360.cn/BaseService/biService/entity" "bp.jydev.jianyu360.cn/BaseService/biService/rpc/biservice" ) func DistributeClue(this *biservice.DistributeClueReq) *biservice.AddProjectResp { count, status := DistributeClueSync(this) log.Println("分配数量 ", count) return &biservice.AddProjectResp{ ErrorCode: 0, Data: &biservice.AddProject{ Status: int64(status), Count: int64(count), }, } } func DistributeClueSync(this *biservice.DistributeClueReq) (int, int) { if DistributeLock.TryLock() { defer DistributeLock.Unlock() saleMap, count := map[string]map[string]interface{}{}, 0 saleData := JyBiTidb.SelectBySql("select * from jy_salesperson_info where is_complete = 1 or is_complete = 0") if saleData != nil && len(*saleData) > 0 { for _, v := range *saleData { name := common.ObjToString(v["name"]) saleMap[name] = v } } for _, data := range this.Datas { seatNumber := common.ObjToString(saleMap[data.Name]["seatNumber"]) distributedCount := int(data.DistributedCount) if distributedCount > 0 { distributedArr := this.ClueIdList[count : count+distributedCount] count += distributedCount DistributeClueMore(saleMap, distributedArr, seatNumber, data.Name, data.PositionId, this.PositionId) } } return count, 1 } else { return 0, 2 } } func DistributeClueMore(saleMap map[string]map[string]interface{}, distributedArr []int64, seatNumber, name string, positionId, thispositionId int64) { wg := new(sync.WaitGroup) ch := make(chan bool, 20) for _, v := range distributedArr { wg.Add(1) ch <- true go func(v int64) { defer func() { wg.Done() <-ch }() clueData := JyBiTidb.FindOne("dwd_f_crm_clue_info", map[string]interface{}{"id": v}, "", "") nowTime := time.Now().Format(date.Date_Full_Layout) if clueData != nil && len(*clueData) > 0 { isAssign := common.IntAll((*clueData)["is_assign"]) clueSeatNumber := common.ObjToString((*clueData)["seatNumber"]) oldName := "" trailstatus := common.ObjToString((*clueData)["trailstatus"]) if clueSeatNumber != "" { for _, s := range saleMap { if common.ObjToString(s["seatNumber"]) == clueSeatNumber { oldName = common.ObjToString(s["name"]) } } } if isAssign == 1 { oldpositionId := common.Int64All((*clueData)["position_id"]) updateClue := map[string]interface{}{ "position_id": positionId, "seatNumber": seatNumber, "is_assign": 1, "updatetime": nowTime, "comeintime": nowTime, "comeinsource_private": 4, "level_open": nil, "clue_level": nil, "out_task_time": nil, "out_task_status": nil, "trail_time": nil, // "comeinsource_open": nil, } ok := JyBiTidb.Update("dwd_f_crm_clue_info", map[string]interface{}{"id": v}, updateClue) // ok := JyBiTidb.Update("dwd_f_crm_private_sea", map[string]interface{}{"clue_id": v}, map[string]interface{}{ // "position_id": positionId, // "seatNumber": seatNumber, // "comeinsource": 4, // "comeintime": nowTime, // }) if ok { JyBiTidb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{ "clue_id": v, "position_id": positionId, "change_field": "position_id", "change_type": "所属人变更", "old_value": oldName, "new_value": name, "createtime": nowTime, "BCPCID": common.GetRandom(32), "operator_id": thispositionId, }) JyBiTidb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{ "clue_id": v, "position_id": oldpositionId, "change_field": "trailstatus", "change_type": "基本信息变更", "old_value": CodeTrail[trailstatus], "new_value": "流失", "createtime": nowTime, "BCPCID": common.GetRandom(32), "operator_id": thispositionId, }) JyBiTidb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{ "clue_id": v, "position_id": positionId, "change_field": "trailstatus", "change_type": "基本信息变更", "old_value": CodeTrail[trailstatus], "new_value": "新增", "createtime": nowTime, "BCPCID": common.GetRandom(32), "operator_id": thispositionId, }) } else { log.Println("私海修改失败 ", v, positionId, seatNumber) } } else { updateClue := map[string]interface{}{ "position_id": positionId, "seatNumber": seatNumber, "is_assign": 1, "updatetime": nowTime, "comeintime": nowTime, "comeinsource_private": 4, "is_task": 0, "taskstatus": 0, "level_open": nil, "clue_level": nil, "out_task_time": nil, "out_task_status": nil, "trail_time": nil, "next_trail_time": nil, // "comeinsource_open": nil, } if trailstatus != "08" { updateClue["trailstatus"] = "01" } ok := JyBiTidb.Update("dwd_f_crm_clue_info", map[string]interface{}{"id": v}, updateClue) // seaId := JyBiTidb.Insert("dwd_f_crm_private_sea", map[string]interface{}{ // "clue_id": v, // "position_id": positionId, // "seatNumber": seatNumber, // "comeinsource": 4, // "comeintime": nowTime, // "is_task": 0, // // "task_time": nowTime, // // "tasktime": nowTime, // "taskstatus": 0, // // "tasksource": "线索批量分配", // }) if ok { // JyBiTidb.Delete("dwd_f_crm_open_sea", map[string]interface{}{"clue_id": v}) JyBiTidb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{ "clue_id": v, "position_id": positionId, "change_field": "position_id", "change_type": "所属人变更", "old_value": "/", "new_value": name, "createtime": nowTime, "BCPCID": common.GetRandom(32), "operator_id": thispositionId, }) if trailstatus != "08" { JyBiTidb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{ "clue_id": v, "position_id": positionId, "change_field": "trailstatus", "change_type": "基本信息变更", "old_value": "商机线索", "new_value": "新增", "createtime": nowTime, "BCPCID": common.GetRandom(32), "operator_id": thispositionId, }) JyBiTidb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{ "clue_id": v, "position_id": positionId, "change_field": "trailstatus", "change_type": "基本信息变更", "old_value": CodeTrail[trailstatus], "new_value": "商机线索", "createtime": nowTime, "BCPCID": common.GetRandom(32), "operator_id": thispositionId, }) } } else { log.Println("私海插入失败 ", v, positionId, seatNumber) } } } }(v) } wg.Wait() } func DrawClue(this *biservice.DrawClueReq) *biservice.AddProjectResp { count, status := DrawClueSync(this) log.Println("领取数量 ", count) return &biservice.AddProjectResp{ ErrorCode: 0, Data: &biservice.AddProject{ Status: int64(status), Count: int64(count), }, } } func DrawClueSync(this *biservice.DrawClueReq) (int, int) { if DataLock.TryLock() { defer DataLock.Unlock() count1 := JyBiTidb.Count("dwd_f_crm_clue_info", map[string]interface{}{"level_open": 1, "is_assign": 0}) count2 := JyBiTidb.Count("dwd_f_crm_clue_info", map[string]interface{}{"level_open": 2, "is_assign": 0}) counts1, counts2, counts3 := int64(0), int64(0), int64(0) counts1 = int64(math.Ceil(float64(this.Count) / float64(10) * 5)) if this.Count-counts1 == 0 { counts2 = 0 counts3 = 0 } else { counts2 = int64(math.Ceil(float64(this.Count) / float64(10) * 4)) if this.Count-counts1-counts2 == 0 { counts3 = 0 } else { counts3 = this.Count - counts1 - counts2 } } if counts1 > count1 { counts2 += counts1 - count1 counts1 = count1 } if counts2 > count2 { counts3 += counts2 - count2 counts2 = count2 } log.Println(count1, count2) log.Println(counts1, counts2, counts3) return DrawClues(this.PositionId, counts1, counts2, counts3), 1 } else { return 0, 2 } } func DrawClues(positionId, count1, count2, count3 int64) int { data1, data2, data3, drawCount := &[]map[string]interface{}{}, &[]map[string]interface{}{}, &[]map[string]interface{}{}, 0 if count1 > 0 { // data1 = JyBiTidb.Find("dwd_f_crm_clue_info", map[string]interface{}{"level_open": 1, "is_assign": 0}, "", "", 0, int(count1)) data1 = JyBiTidb.SelectBySql(`SELECT max(c.createTime) as ctime,a.id,a.trailstatus FROM dwd_f_crm_clue_info a LEFT JOIN Call_Accounting.voice_record c ON c.CalledNo = a.phone WHERE a.level_open = ? AND a.is_assign = 0 AND a.uid !="" GROUP BY a.id ORDER BY ctime asc limit ?`, 1, count1) } if count2 > 0 { // data2 = JyBiTidb.Find("dwd_f_crm_clue_info", map[string]interface{}{"level_open": 2, "is_assign": 0}, "", "", 0, int(count2)) data2 = JyBiTidb.SelectBySql(`SELECT max(c.createTime) as ctime,a.id,a.trailstatus FROM dwd_f_crm_clue_info a LEFT JOIN Call_Accounting.voice_record c ON c.CalledNo = a.phone WHERE a.level_open = ? AND a.is_assign = 0 AND a.uid !="" GROUP BY a.id ORDER BY ctime asc limit ?`, 2, count2) } if count3 > 0 { // data3 = JyBiTidb.Find("dwd_f_crm_clue_info", map[string]interface{}{"level_open": 3, "is_assign": 0}, "", "", 0, int(count3)) data3 = JyBiTidb.SelectBySql(`SELECT max(c.createTime) as ctime,a.id,a.trailstatus FROM dwd_f_crm_clue_info a LEFT JOIN Call_Accounting.voice_record c ON c.CalledNo = a.phone WHERE a.level_open = ? AND a.is_assign = 0 AND a.uid !="" GROUP BY a.id ORDER BY ctime asc limit ?`, 3, count3) } nowTime := time.Now().Format("2006-01-02 15:04:05") seatNumber, name := getSeatNumber(positionId) if data1 != nil && len(*data1) > 0 { batchDraw(*data1, nowTime, seatNumber, name, positionId) drawCount += len(*data1) } if data2 != nil && len(*data2) > 0 { batchDraw(*data2, nowTime, seatNumber, name, positionId) drawCount += len(*data2) } if data3 != nil && len(*data3) > 0 { batchDraw(*data3, nowTime, seatNumber, name, positionId) drawCount += len(*data3) } return drawCount } func batchDraw(data []map[string]interface{}, nowTime, seatNumber, name string, positionId int64) { wg := new(sync.WaitGroup) ch := make(chan bool, 20) for _, v := range data { wg.Add(1) ch <- true go func(v map[string]interface{}) { defer func() { wg.Done() <-ch }() clueId := common.Int64All(v["id"]) trailstatus := common.ObjToString(v["trailstatus"]) if JyBiMysql.ExecTx("领取线索等", func(tx *sql.Tx) bool { updateClue := map[string]interface{}{ "position_id": positionId, "seatNumber": seatNumber, "is_assign": 1, "updatetime": nowTime, "comeintime": nowTime, "comeinsource_private": 3, "is_task": 1, "task_time": nowTime, "tasktime": nowTime, "taskstatus": 0, "tasksource": "领取公海线索", "level_open": nil, "clue_level": nil, // "comeinsource_open": nil, } if trailstatus != "08" { updateClue["trailstatus"] = "01" } ok1 := JyBiTidb.UpdateByTx(tx, "dwd_f_crm_clue_info", map[string]interface{}{"id": clueId}, updateClue) // ok2 := JyBiTidb.DeleteByTx(tx, "dwd_f_crm_open_sea", map[string]interface{}{"clue_id": clueId}) // seaId := JyBiTidb.InsertByTx(tx, "dwd_f_crm_private_sea", map[string]interface{}{ // "clue_id": clueId, // "seatNumber": seatNumber, // "position_id": positionId, // "comeintime": nowTime, // "comeinsource": 3, // "is_task": 1, // "task_time": nowTime, // "tasktime": nowTime, // "taskstatus": 0, // "tasksource": "领取公海线索", // }) recordId := JyBiTidb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{ "clue_id": clueId, "position_id": positionId, "change_field": "position_id", "change_type": "所属人变更", "old_value": "/", "new_value": name, "createtime": nowTime, "BCPCID": common.GetRandom(32), "operator_id": positionId, }) recordId1 := JyBiTidb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{ "clue_id": clueId, "position_id": positionId, "change_type": "领取公海线索", "createtime": nowTime, "BCPCID": common.GetRandom(32), "operator_id": positionId, }) recordId2 := JyBiTidb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{ "clue_id": clueId, "position_id": positionId, "change_type": "加入任务车", "new_value": "领取公海线索", "createtime": nowTime, "BCPCID": common.GetRandom(32), "operator_id": positionId, }) recordId3, recordId4 := int64(0), int64(0) if trailstatus != "08" { recordId3 = JyBiTidb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{ "clue_id": clueId, "position_id": positionId, "change_field": "trailstatus", "change_type": "基本信息变更", "old_value": "商机线索", "new_value": "新增", "createtime": nowTime, "BCPCID": common.GetRandom(32), "operator_id": positionId, }) recordId4 = JyBiTidb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{ "clue_id": clueId, "position_id": positionId, "change_field": "trailstatus", "change_type": "基本信息变更", "old_value": CodeTrail[trailstatus], "new_value": "商机线索", "createtime": nowTime, "BCPCID": common.GetRandom(32), "operator_id": positionId, }) } return ok1 && recordId > 0 && recordId1 > 0 && recordId2 > 0 && recordId3 > -1 && recordId4 > -1 }) { log.Println("领取线索成功") } else { log.Println("领取线索失败") } }(v) } wg.Wait() } func getSeatNumber(positionId int64) (seatNumber, name string) { positionData := JyTidb.FindOne("base_position", map[string]interface{}{"id": positionId}, "", "") if positionData != nil && len(*positionData) > 0 { userId := common.Int64All((*positionData)["user_id"]) if userId > 0 { userData, ok := Mgo.FindOne("user", map[string]interface{}{"base_user_id": userId}) if ok && userData != nil && len(*userData) > 0 { s_phone := common.ObjToString((*userData)["s_phone"]) if s_phone == "" { s_phone = common.ObjToString((*userData)["s_m_phone"]) } saleData := JyBiTidb.FindOne("jy_salesperson_info", map[string]interface{}{"phone": s_phone}, "", "") if saleData != nil && len(*saleData) > 0 { seatNumber = common.ObjToString((*saleData)["seatNumber"]) name = common.ObjToString((*saleData)["name"]) } } } } return }