package main import ( "fmt" "github.com/gogf/gf/v2/util/gconv" "log" "strings" "time" "app.yhyue.com/moapp/jybase/common" "app.yhyue.com/moapp/jybase/date" "app.yhyue.com/moapp/jybase/mongodb" ) // 未支付订单 30分钟一次 func orders() { //一个小时未支付进入线索 A log.Println("未支付订单定时任务开始") lastOrderId := cfg.LastOrderId selectTimeStart := time.Unix(time.Now().Unix()-7200, 0).Format(date.Date_Full_Layout) selectTimeEnd := time.Unix(time.Now().Unix()-3600, 0).Format(date.Date_Full_Layout) sql := fmt.Sprintf(`select * from dataexport_order where create_time <= "%s" and create_time >= "%s" and id > %s`, selectTimeEnd, selectTimeStart, fmt.Sprint(lastOrderId)) data := Mysql.SelectBySql(sql) if data != nil && *data != nil && len(*data) > 0 { for _, v := range *data { order_status := common.IntAll(v["order_status"]) is_backstage_order := common.IntAll(v["is_backstage_order"]) product_type_str1 := `"大会员","VIP订阅","数据流量包","历史数据"` product_type := common.ObjToString(v["product_type"]) if order_status == 0 && is_backstage_order == 0 && strings.Contains(product_type_str1, product_type) { ok1, ok2 := FormatData(v, "orders") if !ok1 { common.WriteSysConfig(&cfg) break } else { if !ok2 { log.Println("用户分配已达上限") common.WriteSysConfig(&cfg) break } } } cfg.LastOrderId = common.IntAll(v["id"]) } } common.WriteSysConfig(&cfg) log.Println("未支付订单定时任务结束") } func readClue() { log.Println("读表进线索定时任务开始") lastReadClueTime := cfg.LastReadClueTime sql := fmt.Sprintf(`select * from clue_info where updatetime > "%s" order by updatetime asc`, fmt.Sprint(lastReadClueTime)) data := TiDb.SelectBySql(sql) if data != nil && *data != nil && len(*data) > 0 { for _, v := range *data { ok1, ok2 := FormatData(v, "readClue") if !ok1 { common.WriteSysConfig(&cfg) break } else { if !ok2 { log.Println("用户分配已达上限") common.WriteSysConfig(&cfg) break } } cfg.LastReadClueTime = common.ObjToString(v["updatetime"]) } } common.WriteSysConfig(&cfg) log.Println("读表进线索定时任务结束") } // 新注册用户 5分钟一次 func users() { //判断节假日 runOk := getRunOk() if !runOk { log.Println("不是工作日,任务暂停") return } //新用户注册后5分钟内进入线索 C log.Println("新注册用户定时任务开始") selectTimeEnd := cfg.LastUserId sql := fmt.Sprintf(`select * from dwd_f_userbase_baseinfo where createtime > "%s" and source = "0101" and status != 2`, selectTimeEnd) data := TiDb.SelectBySql(sql) if data != nil && *data != nil && len(*data) > 0 { for k, v := range *data { createtime := common.ObjToString(v["createtime"]) FormatData(v, "users") if k == len(*data)-1 { cfg.LastUserId = createtime } } } common.WriteSysConfig(&cfg) log.Println("新注册用户定时任务结束") } // 留资 5分钟一次 func saleLeads() { //判断节假日 runOk := getRunOk() if !runOk { log.Println("不是工作日,任务暂停") return } //留资后5分钟内进入线索 //分为免费留资和付费留资 付费B 免费C log.Println("用户留资定时任务开始") session := Mgo.GetMgoConn() lastId := cfg.LastId defer func() { Mgo.DestoryMongoConn(session) }() query := map[string]interface{}{} if lastId != "" { query["_id"] = map[string]interface{}{"$gt": mongodb.StringTOBsonId(lastId)} } log.Println("query :", query) iter := session.DB(cfg.Mgo.DbName).C("saleLeads").Find(&query).Sort("_id").Iter() thisData := map[string]interface{}{} for { if !iter.Next(&thisData) { break } ok1, ok2 := FormatData(thisData, "saleLeads") if !ok1 { common.WriteSysConfig(&cfg) break } else { if !ok2 { log.Println("用户分配已达上限") common.WriteSysConfig(&cfg) break } } cfg.LastId = mongodb.BsonIdToSId(thisData["_id"]) } common.WriteSysConfig(&cfg) log.Println("用户留资定时任务结束") } func userbase() { log.Println("userbase定时任务开始") selectTimeEnd := time.Unix(time.Now().Unix()-1800, 0).Format("2006-01-02 15:04:05") sql := fmt.Sprintf(`select * from dwd_f_userbase_baseinfo where updatetime > "%s" and source != "0105" and source != "0104" and source != "0103" and source != "0102"`, selectTimeEnd) //sql := fmt.Sprintf(`select * from dwd_f_userbase_baseinfo where id='11927183'`) data := TiDb.SelectBySql(sql) if data != nil && *data != nil && len(*data) > 0 { for _, v := range *data { phone := common.ObjToString(v["phone"]) uId := common.ObjToString(v["uid"]) userId := common.ObjToString(v["userid"]) registedate := common.ObjToString(v["l_registedate"]) name := common.ObjToString(v["name"]) nowTime := time.Now().Format(date.Date_Full_Layout) source := common.ObjToString(v["source"]) if phone != "" { contactsData := TiDb.SelectBySql("select * from dwd_f_userbase_contacts where D = ? and is_delete = 1", phone) if contactsData == nil || len(*contactsData) == 0 { contactsData2 := TiDb.SelectBySql("select * from dwd_f_userbase_contacts where baseinfo_id = ? and is_delete = 1", uId) if contactsData2 != nil && len(*contactsData2) > 0 { log.Println("userbase uid不为空 新增通讯录", uId) TiDb.Insert("dwd_f_userbase_contacts", map[string]interface{}{ "status": 1, "is_delete": 1, "createtime": nowTime, "updatetime": nowTime, "phone": phone, "baseinfo_id": uId, "SOURCE": source, }) } else { registedates, _ := time.Parse(date.Date_Full_Layout, registedate) count := TiDb.CountBySql("select count(1) as count from dwd_f_crm_clue_info where uid = ?", uId) log.Println("userbase uid 线索数量 ", count) log.Println("userbase uid 注册时间 ", registedates) if time.Now().Unix()-registedates.Unix() > int64(cfg.RegTimes)*86400 { if count == 0 { // TiDb.Insert("dwd_f_crm_open_sea", map[string]interface{}{ // "clue_id": clueId, // "comeintime": nowTime, // "comeinsource": 2, // }) clueId := TiDb.Insert("dwd_f_crm_clue_info", map[string]interface{}{ "userid": userId, "uid": uId, "is_assign": 0, "comeintime": nowTime, "createtime": nowTime, "updatetime": nowTime, "cluename": phone, "top_cluetype": "532", "sub_cluetype": "475", "trailstatus": "01", "name": name, "phone": phone, "comeintime_open": nowTime, "comeinsource_open": 1, "FREEZE_TIME": nowTime, }) if clueId > 0 { TiDb.Insert("dwd_f_userbase_contacts", map[string]interface{}{ "status": 1, "is_delete": 1, "createtime": nowTime, "updatetime": nowTime, "phone": phone, "baseinfo_id": uId, "SOURCE": source, }) TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{ "clue_id": clueId, "position_id": -1, "change_type": "创建线索", "new_value": "系统自动创建", "createtime": nowTime, "BCPCID": common.GetRandom(32), "operator_id": -1, }) } } else { TiDb.Insert("dwd_f_userbase_contacts", map[string]interface{}{ "status": 1, "is_delete": 1, "createtime": nowTime, "updatetime": nowTime, "phone": phone, "baseinfo_id": uId, "SOURCE": source, }) } } else { if count == 0 { FormatData(v, "users") } else { TiDb.Insert("dwd_f_userbase_contacts", map[string]interface{}{ "status": 1, "is_delete": 1, "createtime": nowTime, "updatetime": nowTime, "phone": phone, "baseinfo_id": uId, "SOURCE": source, }) } } } } } } } log.Println("userbase定时任务结束") } func getRunOk() bool { currentTime, runOk := time.Now(), false if currentTime.Weekday() == time.Sunday { isok := false for k, v := range DateMap { if currentTime.Format(date.Date_Short_Layout) == k && v == 2 { isok = true } } if isok { runOk = true } } else { isok := true for k, v := range DateMap { if currentTime.Format(date.Date_Short_Layout) == k && v == 1 { isok = false } } if isok { runOk = true } } return runOk } func getAreaCode(userId string) (code string) { followData := Base.Find("follow_project_monitor", map[string]interface{}{"s_userid": userId}, "", "", -1, -1) sidArr := []string{} if followData != nil && len(*followData) > 0 { for _, v := range *followData { infoId := common.ObjToString(v["s_id"]) sidArr = append(sidArr, infoId) } } if len(sidArr) > 0 { query := `{"query": {"bool": {"must": [{"terms": {"_id": ["%s"]}}],"must_not": [],"should": []}}}` query = fmt.Sprintf(query, strings.Join(sidArr, `","`)) biddingData := Es.Get("bidding", "bidding", query) if biddingData != nil && len(*biddingData) > 0 { codeMap := map[string]string{} codeArr := []string{} for _, v := range *biddingData { area := common.ObjToString(v["area"]) address := common.ObjToString(v["city"]) if address == "" { address = area } codeMap[address] = AreaCode[address] } if len(codeMap) > 0 { for _, v := range codeMap { codeArr = append(codeArr, v) } } if len(codeArr) > 0 { code = strings.Join(codeArr, ",") } } } log.Println("code ", code) return } func getClueType(item string, data map[string]interface{}, sourceCode string, sourceId int64) (pcode, code, level, topname, subname string) { if item == "orders" { productType := common.ObjToString(data["product_type"]) pcode = "1" level = "A" topname = "提交订单未支付" if productType == "VIP订阅" { code = "6" subname = "超级订阅" } else if productType == "大会员" { code = "7" subname = "大会员" } else if productType == "数据流量包" { code = "8" subname = "数据流量包" } else if productType == "历史数据" { code = "9" subname = "数据自助导出" } } else if item == "users" { pcode = "4" code = "154" level = "C" topname = "新增注册" subname = "新增注册用户" } else if item == "message" { pcode = "532" code = "477" level = "B" topname = "其他" subname = "机器人客服主动咨询" } else if item == "readClue" { level = "A" topname = "超级订阅临期用户" pcode = "614" if sourceId == 1 { code = "615" subname = "60天后到期" } else if sourceId == 2 { code = "616" subname = "45天后到期" } else if sourceId == 3 { code = "617" subname = "15天后到期" } else { code = "618" subname = "7天后到期" } } else { if sourceCode != "" { codeData := TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"source": sourceCode}, "", "") if codeData != nil && len(*codeData) > 0 { pcode = common.ObjToString((*codeData)["pcode"]) code = common.ObjToString((*codeData)["code"]) level = common.ObjToString((*codeData)["clue_level"]) subname = common.ObjToString((*codeData)["name"]) pcodeData := TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"code": pcode}, "", "") if pcodeData != nil && len(*pcodeData) > 0 { topname = common.ObjToString((*pcodeData)["name"]) } } } } return } // 获取自动分配的人 func autoDraw(mode, cluename, phone string, isGroup, isCommerce int) (positionId int64, seatNumber, saleName string, saleData []map[string]interface{}, isOk, isFreeze, isWait bool) { isOk = false isFreeze = false if TiDb.Count("dwd_f_crm_clue_info", map[string]interface{}{"phone": phone, "is_assign": 1}) == 0 { //线索没销售进入,有销售走分配次数最少的逻辑 if isGroup == 0 && isCommerce == 1 && cluename != "" { //非集团在工商库线索名不为空 cdata := TiDb.FindOne("dwd_f_crm_clue_info", map[string]interface{}{"cluename": cluename, "is_assign": 1}, "", "") if cdata != nil && len(*cdata) > 0 { //找到了公司有人在跟进 isOk = true positionId = common.Int64All((*cdata)["position_id"]) seatNumber = common.ObjToString((*cdata)["seatNumber"]) log.Println("positionId seatNumber ", positionId, seatNumber) if positionId > 0 { pdata := TiDb.SelectBySql(`select * from dwd_f_crm_personnel_management where seat_number is not null and seat_number != ""`) if pdata != nil { saleData = *pdata for _, v := range *pdata { resign := common.IntAll(v["resign"]) if positionId == common.Int64All(v["position_id"]) { if resign == 1 { //离职分配,找到的销售离职了,分给组员,没离职就给他 sdata := TiDb.SelectBySql(`SELECT b.name,b.position_id,b.seat_number from dwd_d_crm_department_level_succbi a INNER JOIN dwd_f_crm_personnel_management b on a.position_id = b.position_id where a.bi_pcode = (SELECT bi_pcode from dwd_d_crm_department_level_succbi where position_id = ?) and b.role_id = 3`, positionId) if sdata != nil && len(*sdata) > 0 { for _, m := range *sdata { if !FindUpperLimit(gconv.String(positionId), "positionId") { positionId = common.Int64All(m["position_id"]) seatNumber = common.ObjToString(m["seat_number"]) saleName = common.ObjToString(m["name"]) return } } isWait = true return } } else { saleName = common.ObjToString(v["name"]) if FindUpperLimit(gconv.String(positionId), "positionId") { isFreeze = true } } } } } return } } } } query := `select * from dwd_f_crm_personnel_management where assign_type = 1 and` if mode == "A" { query += ` assign_level like "%A%"` } else if mode == "B" { query += ` assign_level like "%B%"` } else { query += ` assign_level like "%C%"` } data := TiDb.SelectBySql(query) if data != nil && len(*data) > 0 { saleData = *data sql := "select * from dwd_f_crm_clue_autodraw_record where clue_level = ?" countData := TiDb.SelectBySql(sql, mode) if countData != nil && len(*countData) > 0 { for _, v := range *data { isOk := false //判断是否有新员工 for _, vv := range *countData { if common.Int64All(v["position_id"]) == common.Int64All(vv["position_id"]) { if common.IntAll(v["resign"]) == 0 { vv["status"] = 1 } else { vv["status"] = 2 } isOk = true } } if !isOk { //有新员工直接分给新员工 positionId = common.Int64All(v["position_id"]) saleName = common.ObjToString(v["name"]) log.Println("新员工, ", positionId, saleName) rData := TiDb.FindOne("dwd_f_crm_clue_autodraw_record", map[string]interface{}{"clue_level": mode}, "", "count desc") TiDb.Insert("dwd_f_crm_clue_autodraw_record", map[string]interface{}{ "position_id": positionId, "clue_level": mode, "count": common.Int64All((*rData)["count"]), }) break } } if positionId == 0 { res := int64(0) countres := 0 for _, v := range *countData { if common.IntAll(v["status"]) == 1 { if FindUpperLimit(gconv.String(common.Int64All(v["position_id"])), "positionId") { continue } if countres == 0 { res = common.Int64All(v["count"]) positionId = common.Int64All(v["position_id"]) } else { if common.Int64All(v["count"]) <= res { res = common.Int64All(v["count"]) seatNumber = common.ObjToString(v["seatNumber"]) } } countres++ } } } } else { for _, kv := range *data { positionId1 := gconv.String(kv["position_id"]) if !FindUpperLimit(positionId1, "positionId") { saleName = common.ObjToString(kv["name"]) positionId = common.Int64All((*data)[0]["position_id"]) saleName = common.ObjToString((*data)[0]["name"]) rData := TiDb.FindOne("dwd_f_crm_clue_autodraw_record", map[string]interface{}{"clue_level": mode}, "", "count desc") if rData != nil && len(*rData) > 0 { TiDb.Insert("dwd_f_crm_clue_autodraw_record", map[string]interface{}{ "position_id": positionId, "clue_level": mode, "count": common.Int64All((*rData)["count"]), }) } else { TiDb.Insert("dwd_f_crm_clue_autodraw_record", map[string]interface{}{ "position_id": positionId, "clue_level": mode, "count": 0, }) } break } } } for _, v := range *data { if positionId == common.Int64All(v["position_id"]) { seatNumber = common.ObjToString(v["seat_number"]) saleName = common.ObjToString(v["name"]) } } } return } func getPositionId(phone string) (positionId int64) { userData, ok := Mgo.FindOne("user", map[string]interface{}{"s_phone": phone}) if ok && userData != nil && len(*userData) > 0 { userId := common.Int64All((*userData)["base_user_id"]) positionData := Base.FindOne("base_position", map[string]interface{}{"type": 1, "ent_id": 25917, "user_id": userId}, "", "") //TODO ent_id if positionData != nil && len(*positionData) > 0 { positionId = common.Int64All((*positionData)["id"]) } } return } func GetCompanyType(companyName string) (int, int) { //是否是集团 isGroup, isCommerce := 0, 0 if c := TiDb.CountBySql(`select count(1) from group_company_name where company_name=?`, companyName); c > 0 { isGroup = 1 } //是否在工商库 if c := MgoQyxy.Count("qyxy_std", map[string]interface{}{"company_name": companyName, "company_type": map[string]interface{}{"$ne": "个体工商户"}}); c > 0 { isCommerce = 1 } return isGroup, isCommerce } // 查询是否达上限 func FindUpperLimit(positionId string, dataType string) bool { if positionId == "" { return false } if dataType == "positionId" { fmt.Println("111", positionId, TiDb.CountBySql(`select count(1) from dwd_f_crm_clue_info where position_id=? and is_assign=1 `, positionId)) return TiDb.CountBySql(`select count(1) from dwd_f_crm_clue_info where position_id=? and is_assign=1 and trailstatus != '08' `, positionId) >= cfg.AllocationCap //return TiDb.CountBySql(`select count(1) from dwd_f_crm_clue_info where position_id=? and is_assign=1 `, positionId) >= cfg.AllocationCap } else { fmt.Println("222", positionId, TiDb.CountBySql(`select count(1) from dwd_f_crm_clue_info where seatNumber=? and is_assign `, positionId)) return TiDb.CountBySql(`select count(1) from dwd_f_crm_clue_info where seatNumber=? and is_assign and trailstatus != '08' `, positionId) >= cfg.AllocationCap //return TiDb.CountBySql(`select count(1) from dwd_f_crm_clue_info where seatNumber=? and is_assign `, positionId) >= cfg.AllocationCap } } func getSeatNumberPositionId(seatNumber string) (positionId int64) { saleData := TiDb.FindOne("dwd_f_crm_personnel_management", map[string]interface{}{"seat_number": seatNumber}, "", "") if saleData != nil && len(*saleData) > 0 { positionId = common.Int64All((*saleData)["position_id"]) } return }