package main import ( "app.yhyue.com/moapp/jybase/mail" "app.yhyue.com/moapp/jybase/redis" "fmt" "github.com/tealeg/xlsx" "log" "math" "strings" "time" "github.com/gogf/gf/v2/util/gconv" "app.yhyue.com/moapp/jybase/common" "app.yhyue.com/moapp/jybase/date" "app.yhyue.com/moapp/jybase/mongodb" ) // 电销工单生成 func rderAcceptance() { sql := fmt.Sprintf(`select * from order_acceptance where is_clue=2 and is_delete=1 order by propose_time `) //sql := fmt.Sprintf(`select * from order_acceptance where is_clue=2 and is_delete=1 and id = 333 order by propose_time `) data := WorkOrder.SelectBySql(sql) if data != nil && len(*data) > 0 { for _, v := range *data { acceptance_no := gconv.String(v["acceptance_no"]) childrenArr := WorkOrder.Find("order_acceptance_children", map[string]interface{}{ "acceptance_no": acceptance_no, }, "", "", -1, -1) if childrenArr != nil && len(*childrenArr) > 0 { company := "" phone := "" demand := "" name := "" product := "" for _, v1 := range *childrenArr { if gconv.String(v1["field_name"]) == "公司名称" { company = gconv.String(v1["field_value"]) } if gconv.String(v1["field_name"]) == "联系方式num" { phone = gconv.String(v1["field_value"]) } if gconv.String(v1["field_name"]) == "客户姓名" { name = gconv.String(v1["field_value"]) } if gconv.String(v1["field_name"]) == "客户需求" { demand = gconv.String(v1["field_value"]) } if gconv.String(v1["field_name"]) == "咨询产品" { product = gconv.String(v1["field_value"]) } } if !WorkDataHandle(company, phone, demand, name, product, v) { log.Println("工单创建失败") } } } } } func WorkDataHandle(company, phone, demand, name, product string, acceptanceData map[string]interface{}) bool { uId := "" query := map[string]interface{}{} contactsData := TiDb.SelectBySql("select * from dwd_f_userbase_contacts where phone = ? and is_delete = 1", phone) if contactsData != nil && len(*contactsData) > 0 { if common.ObjToString((*contactsData)[0]["baseinfo_id"]) != "" { uId = common.ObjToString((*contactsData)[0]["baseinfo_id"]) query["uid"] = uId } } if uId == "" { log.Println("用户信息不存在") return false } cluename := company if cluename == "" { cluename = phone //没有线索名,手机号代替 } ok, data, saleData := false, map[string]interface{}{}, []map[string]interface{}{} isGroup, isCommerce := GetCompanyType(cluename) uCount, _ := TiDb.FindOne("dwd_f_crm_clue_info", map[string]interface{}{"uid": uId}, "", ""), true //查当前线索是否已存在 if uCount != nil && len(*uCount) > 0 { isUpdate := gconv.Int64((*uCount)["is_artificially_modified"]) if isUpdate == 1 { cluename = "" } clueId := gconv.Int64((*uCount)["id"]) positionId := gconv.Int64((*uCount)["position_id"]) trailstatus := gconv.String((*uCount)["trailstatus"]) IS_TRANSFER := gconv.Int64((*uCount)["IS_TRANSFER"]) if IS_TRANSFER == 1 { //客成处理 //客成 //生成客成数据 customerMap := TiDb.FindOne("dwd_f_csm_customer_info", map[string]interface{}{ "clue_id": clueId, }, "position_id,name", "") if customerMap != nil && len(*customerMap) > 0 { //UpdateClue(*uCount, saleData, "", "", uId, "5", "169", "新增线索", "主动咨询客服留资客户", company, name, gconv.String((*uCount)["name"]), phone, "", "", "", "", "", "", gconv.String((*uCount)["seat_number"]), "", gconv.Int64((*uCount)["position_id"]), "", "", "", []string{}, "", isGroup, isCommerce, false, demand) WorkUpdateClue(*uCount, saleData, "", "", uId, "5", "169", "新增线索", "主动咨询客服留资客户", cluename, name, gconv.String((*uCount)["name"]), phone, "", "", "", "", "", "", gconv.String((*uCount)["seat_number"]), "", gconv.Int64((*uCount)["position_id"]), "", "", "", []string{}, "", isGroup, isCommerce, false, demand) data = map[string]interface{}{ "type": "kc", "position_id": (*customerMap)["position_id"], "name": (*customerMap)["name"], } } else { log.Println("查询不到客成数据", clueId, uId) return false } TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{ "clue_id": clueId, "position_id": (*customerMap)["position_id"], "change_type": "加入任务车", "new_value": "咨询客服转客成", "createtime": time.Now().Format(date.Date_Full_Layout), "BCPCID": common.GetRandom(32), "operator_id": -1, }) } else { if positionId == 0 { //线索变更 ok, data, saleData = FindPosition(0, "", gconv.String(acceptanceData["creator_time"])) if !ok { log.Println(positionId, "用户查询失败") return false } WorkUpdateClue(*uCount, saleData, "", "", uId, "5", "169", "新增线索", "主动咨询客服留资客户", cluename, name, gconv.String(data["name"]), phone, "", "", "", "", "", "", gconv.String(data["seat_number"]), "", gconv.Int64(data["position_id"]), "", "", "", []string{}, "", isGroup, isCommerce, true, demand) } else { ok, data, saleData = FindPosition(positionId, trailstatus, gconv.String(acceptanceData["creator_time"])) if !ok { log.Println(positionId, "用户查询失败") return false } if gconv.Int64(data["position_id"]) == positionId { WorkUpdateClue(*uCount, saleData, "", "", uId, "5", "169", "新增线索", "主动咨询客服留资客户", cluename, name, gconv.String(data["name"]), phone, "", "", "", "", "", "", gconv.String(data["seat_number"]), "", gconv.Int64(data["position_id"]), "", "", "", []string{}, "", isGroup, isCommerce, false, demand) } else { WorkUpdateClue(*uCount, saleData, "", "", uId, "5", "169", "新增线索", "主动咨询客服留资客户", cluename, name, gconv.String(data["name"]), phone, "", "", "", "", "", "", gconv.String(data["seat_number"]), "", gconv.Int64(data["position_id"]), "", "", "", []string{}, "", isGroup, isCommerce, true, demand) } } } } else { //新增线索 ok, data, _ = FindPosition(0, "", gconv.String(acceptanceData["creator_time"])) if !ok { return false } SaveClue("", "", uId, "5", "169", "新增线索", "主动咨询客服留资客户", cluename, name, gconv.String(data["name"]), phone, "", "", "", "", "", "", gconv.String(data["seat_number"]), gconv.Int64(data["position_id"]), "", "", "", []string{}, "", isGroup, isCommerce, false, demand) } //工单生成 ok1 := AddOrderWork(acceptanceData, data, product, phone, company) log.Println("工单创建", ok1, gconv.String(acceptanceData["acceptance_no"])) return true } func AddOrderWork(acceptanceData map[string]interface{}, userData map[string]interface{}, product, phone, company string) bool { nowTime := time.Now().Format(date.Date_Full_Layout) work_order_no := fmt.Sprintf("GD%s%s", time.Now().Format(date.Date_yyyyMMdd), FindNumber("gd")) productArr := []string{} for _, v := range strings.Split(product, ",") { switch ProductMap[v] { case "dk": continue default: productArr = append(productArr, v) } } two_type := "dx" if gconv.String(userData["type"]) == "kc" { two_type = "kc" } personMap := GetPerson(gconv.String(userData["position_id"])) if personMap == nil || len(personMap) == 0 { return false } orderWorkMap := map[string]interface{}{ "work_order_no": work_order_no, "acceptance_no": gconv.String(acceptanceData["acceptance_no"]), "type": strings.Join(productArr, ","), "status": common.If(gconv.Int64(userData["orderStatus"]) == 0, 2, 1), "initiator_name": gconv.String(acceptanceData["creator_name"]), "initiator_position_id": gconv.String(acceptanceData["initiator_position_id"]), "current_name": common.If(gconv.Int64(userData["orderStatus"]) == 0, nil, userData["name"]), "current_position_id": common.If(gconv.Int64(userData["orderStatus"]) == 0, nil, userData["position_id"]), "history_name": common.If(gconv.Int64(userData["orderStatus"]) == 0, userData["name"], nil), "history_postion_id": common.If(gconv.Int64(userData["orderStatus"]) == 0, userData["position_id"], nil), "is_delete": 1, "creator_name": gconv.String(acceptanceData["creator_name"]), "creator_position_id": gconv.String(acceptanceData["creator_position_id"]), "creator_time": nowTime, "two_type": two_type, "department_no": gconv.String(personMap["deptId"]), "department_name": gconv.String(personMap["deptName"]), "update_time": common.If(gconv.Int64(userData["orderStatus"]) == 0, nowTime, nil), } ok3 := WorkOrder.Insert("order_work", orderWorkMap) if ok3 > 0 { status := 2 if WorkOrder.Count("order_work", map[string]interface{}{ "status": 1, "acceptance_no": gconv.String(acceptanceData["acceptance_no"]), }) > 0 { status = 1 } WorkOrder.Update("order_acceptance", map[string]interface{}{ "id": acceptanceData["id"], }, map[string]interface{}{ "is_clue": 3, "status": status, "over_time": common.If(status == 1, nil, nowTime), }) //日志添加 approvalRecordMap := map[string]interface{}{ "work_order_no": work_order_no, "status": common.If(gconv.Int64(userData["orderStatus"]) == 0, 3, 1), "new_status": common.If(gconv.Int64(userData["orderStatus"]) == 0, 2, nil), "handle_name": userData["name"], "handle_position_id": userData["position_id"], "handle_dept_id": gconv.String(personMap["deptId"]), "handle_dept_name": gconv.String(personMap["deptName"]), "creator_name": gconv.String(acceptanceData["creator_name"]), "creator_position_id": gconv.String(acceptanceData["initiator_position_id"]), "is_delete": 1, "creator_time": nowTime, "handle_time": common.If(gconv.Int64(userData["orderStatus"]) == 0, nowTime, nil), "update_name": common.If(gconv.Int64(userData["orderStatus"]) == 0, userData["name"], nil), "update_position_id": common.If(gconv.Int64(userData["orderStatus"]) == 0, userData["position_id"], nil), "update_time": common.If(gconv.Int64(userData["orderStatus"]) == 0, nowTime, nil), } WorkOrder.Insert("approval_record", approvalRecordMap) WorkMail(personMap, strings.Join(productArr, ","), gconv.Int64(common.If(gconv.Int64(userData["orderStatus"]) == 0, 2, 1)), gconv.String(personMap["name"]), gconv.String(acceptanceData["creator_name"]), nowTime, work_order_no, phone, company) return true } return false } // 本级以及上级管理员查询 func GetPerson(positionId string) map[string]interface{} { person := map[string]interface{}{} positionArrMap := Base.SelectBySql(fmt.Sprintf(`select a.phone,b.id,b.ent_id from base_user a INNER JOIN base_position b on b.id=%s and b.user_id=a.id and b.type=1`, positionId)) if positionArrMap == nil || len(*positionArrMap) == 0 { return map[string]interface{}{} } phone := gconv.String((*positionArrMap)[0]["phone"]) entId := gconv.String((*positionArrMap)[0]["ent_id"]) entUserArrMap := Mysql.SelectBySql(fmt.Sprintf(`SELECT a.name as name,a.mail as mail,b.dept_id as deptId,a.phone ,c.name as deptName FROM entniche_user a INNER JOIN entniche_department_user b ON a.ent_id =%s AND a.phone IN %s and a.id=b.user_id inner join entniche_department c on b.dept_id=c.id `, entId, fmt.Sprintf("(%s)", phone))) //商机管理员 if entUserArrMap == nil || len(*entUserArrMap) == 0 { return map[string]interface{}{} } deptId := gconv.Int64((*entUserArrMap)[0]["deptId"]) person = map[string]interface{}{ "name": gconv.String((*entUserArrMap)[0]["name"]), "mail": gconv.String((*entUserArrMap)[0]["mail"]), "phone": gconv.String((*entUserArrMap)[0]["phone"]), "deptId": gconv.String((*entUserArrMap)[0]["deptId"]), "deptName": gconv.String((*entUserArrMap)[0]["deptName"]), } //本部门管理员查询 depthMap := Mysql.SelectBySql(`SELECT c.name as name,c.mail as mail FROM entniche_department_user a INNER JOIN entniche_user_role b ON a.dept_id = ? AND a.user_id = b.user_id AND b.role_id !="" INNER JOIN entniche_user c ON a.user_id = c.id`, deptId) if depthMap != nil && len(*depthMap) > 0 { person["deptPersonName"] = gconv.String((*depthMap)[0]["name"]) person["deptPersonMail"] = gconv.String((*depthMap)[0]["mail"]) } //商机管理员查询 superiorDepthMap := Mysql.SelectBySql(`SELECT c.* FROM entniche_department d INNER JOIN entniche_department_user a ON d.id = ? AND d.pid = a.dept_id INNER JOIN entniche_user_role b ON a.user_id = b.user_id AND b.role_id !="" INNER JOIN entniche_user c ON a.user_id = c.id`, deptId) if superiorDepthMap != nil && len(*superiorDepthMap) > 0 { person["superiorDepthPersonName"] = gconv.String((*superiorDepthMap)[0]["name"]) person["superiorDepthPersonMail"] = gconv.String((*superiorDepthMap)[0]["mail"]) } return person } // 编号查询 func FindNumber(moudle string) string { today := time.Now().Format("2006-01-02") yesterday := time.Now().AddDate(0, 0, -1).Format("2006-01-02") key := fmt.Sprintf("%s_%s", today, moudle) yesterdayKey := fmt.Sprintf("%s_%s", yesterday, moudle) if ok, _ := redis.Exists("newother", yesterdayKey); ok { //删除之前数据 redis.Del("newother", yesterdayKey) } count := redis.Incr("newother", key) log.Println("编号获取", moudle, fmt.Sprintf("%04d", count)) return fmt.Sprintf("%04d", count) } // 人员查询 func GetAllocation(proportion1, proportion3 float64, deptCount1, deptCount3 int64, administrators1, administrators3 map[string]interface{}, creatorTime string) map[string]interface{} { log.Println("分配比例查询", proportion1, proportion3, deptCount1, deptCount3) if deptCount1 == 0 { return administrators1 } if deptCount3 == 0 { return administrators3 } nowAllocationRatio := math.Round(gconv.Float64(deptCount1 / deptCount3)) if cfg.AllocationRatio == 0 { //重新计算 cfg.AllocationRatio = math.Round(proportion1 / proportion3) cfg.AllocationTime = creatorTime common.WriteSysConfig(&cfg) log.Println("新增计算比例", cfg.AllocationRatio) return administrators1 } else { if nowAllocationRatio == cfg.AllocationRatio { //重新计算 cfg.AllocationRatio = math.Round(proportion1 / proportion3) cfg.AllocationTime = creatorTime common.WriteSysConfig(&cfg) return administrators1 } } if nowAllocationRatio > cfg.AllocationRatio { return administrators3 } else { return administrators1 } //达到比例也重新计算 } func FindPosition(positionId int64, trailstatus, creatorTime string) (bool, map[string]interface{}, []map[string]interface{}) { allData := []map[string]interface{}{} //查询两个部门高级管理员 //查询两个部门所有人员标识 //电销三部 userData1 := TiDb.SelectBySql(`SELECT a.position_id, a.name, b.seat_number, b.role_id, a.bi_pcode, a.dept_name FROM dwd_d_crm_department_level_succbi a INNER JOIN dwd_f_crm_personnel_management b ON a.resign = 0 and b.resign = 0 AND a.dept_name LIKE "%电销部%" AND a.position_id = b.position_id`) userData3 := TiDb.SelectBySql(`SELECT a.position_id, a.name, b.seat_number, b.role_id, a.bi_pcode, a.dept_name FROM dwd_d_crm_department_level_succbi a INNER JOIN dwd_f_crm_personnel_management b ON a.resign = 0 and b.resign = 0 AND a.resign = 0 AND a.dept_name LIKE "%销售三部" AND a.position_id = b.position_id`) if userData3 == nil || len(*userData3) == 0 || userData1 == nil || len(*userData1) == 0 { return false, map[string]interface{}{}, allData } //一部管理员信息 administrators1 := map[string]interface{}{} //三部管理员信息 administrators3 := map[string]interface{}{} //返回当前人信息 administrators := map[string]interface{}{} //电销一部 deptNameMap1 := map[string]interface{}{} deptNameMap3 := map[string]interface{}{} proportion1 := float64(0) proportion3 := float64(0) for _, v := range *userData3 { v["type"] = 3 id := gconv.Int64(v["position_id"]) roleId := gconv.Int64(v["role_id"]) if id == positionId { administrators = v } if roleId == 8 { v["orderStatus"] = 2 administrators3 = v } else if roleId == 3 { proportion3 += 0.5 } else { proportion3 += 1 } deptNameMap3[gconv.String(v["bi_pcode"])] = true allData = append(allData, v) } for _, v := range *userData1 { v["type"] = 1 id := gconv.Int64(v["position_id"]) roleId := gconv.Int64(v["role_id"]) if id == positionId { administrators = v } if roleId == 8 { v["orderStatus"] = 2 administrators1 = v } else if roleId == 3 { proportion1 += 0.5 } else { proportion1 += 1 } deptNameMap1[gconv.String(v["bi_pcode"])] = true allData = append(allData, v) } if positionId != 0 { if administrators == nil || len(administrators) == 0 { return false, map[string]interface{}{}, allData } positiontype := gconv.Int64(administrators["type"]) if trailstatus == "01" { switch positiontype { case 1: //找他上级 administrators = administrators1 case 3: //找他上级 administrators = administrators3 } return true, administrators, allData } else { return true, administrators, allData } } //按照比例分配选择一部还是三部 //一部查询 deptCount1 := CalculateProportion(deptNameMap1) //三部查询 deptCount3 := CalculateProportion(deptNameMap3) return true, GetAllocation(proportion1, proportion3, deptCount1, deptCount3, administrators1, administrators3, creatorTime), allData log.Println("电销信息获取失败", positionId) return false, map[string]interface{}{}, allData } func CalculateProportion(deptNameMap map[string]interface{}) int64 { deptNameStr := "" for k := range deptNameMap { if deptNameStr == "" { deptNameStr = k } else { deptNameStr = fmt.Sprintf("%s,%s", deptNameStr, k) } } if deptNameStr == "" { return int64(0) } count := int64(0) sql := fmt.Sprintf(`SELECT sum(1) as count FROM order_work a INNER JOIN approval_record b ON a.creator_time >= "%s" AND FIND_IN_SET( a.department_no , "%s") AND a.work_order_no = b.work_order_no and (b.new_status!= 1 or b.new_status is null ) `, cfg.AllocationTime, deptNameStr) data := WorkOrder.SelectBySql(sql) if data != nil && len(*data) > 0 { count = gconv.Int64((*data)[0]["count"]) } return count } // 未支付订单 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) log.Println("线索卡点", "orders", v, selectTimeEnd, selectTimeStart) } else { if !ok2 { log.Println("用户分配已达上限", "orders", v, selectTimeEnd, selectTimeStart) common.WriteSysConfig(&cfg) } } } 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) log.Println("线索卡点", "readClue", v, lastReadClueTime) } else { if !ok2 { log.Println("用户分配已达上限", "readClue", v, lastReadClueTime) common.WriteSysConfig(&cfg) } } 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 (s_platform != 'xcx' or s_platform is NULL) and source = "0101" and status != 2 order by createtime asc`, selectTimeEnd) data := TiDb.SelectBySql(sql) abhList := []map[string]interface{}{} if data != nil && *data != nil && len(*data) > 0 { for k, v := range *data { //判断用户是否有小程序切使用过剑鱼其他产品 createtime := common.ObjToString(v["createtime"]) ok1, ok2, ok3 := FormatData(v, "users") if !ok3 { cfg.LastUserId = createtime //安博会数据 abhList = append(abhList, v) continue } if !ok1 { log.Println("线索卡点", "users", v, selectTimeEnd) } else { if !ok2 { log.Println("用户分配已达上限", "users", v, selectTimeEnd) } } if k == len(*data)-1 { cfg.LastUserId = createtime } } if len(abhList) > 0 { //安博会发邮件高翔 ABHEmail("user", abhList) } } common.WriteSysConfig(&cfg) selectXcxTimeEnd := cfg.LastXcxUserId xcxSql := fmt.Sprintf(`SELECT DISTINCT aa.mgo_id as userId, cc.NAME as industry , aa.phone, IF ( aa.phone_time IS NULL, aa.create_time, aa.phone_time ) as time FROM debris_product.miniprogram_user aa INNER JOIN debris_product.miniprogram bb ON ( aa.phone <> '' AND IF ( aa.phone_time IS NULL, aa.create_time, aa.phone_time ) > '%s' AND aa.miniprogram_code = bb.CODE ) INNER JOIN debris_product.industry cc ON ( bb.industry_code = cc.CODE ) WHERE NOT EXISTS ( SELECT 1 FROM debris_product.miniprogram_user a INNER JOIN debris_product.miniprogram b ON ( aa.unionid = a.unionid AND aa.miniprogram_code = a.miniprogram_code AND aa.id != a.id AND IF ( a.phone_time IS NULL, a.create_time, a.phone_time ) <= '%s' AND a.miniprogram_code = b.CODE ) INNER JOIN debris_product.miniprogram_user c ON ( a.unionid = c.unionid AND b.CODE = c.miniprogram_code )) ORDER BY time `, selectXcxTimeEnd, selectXcxTimeEnd) xcxData := debrisProductMysql.SelectBySql(xcxSql) log.Println("11122", selectXcxTimeEnd, xcxData) if xcxData != nil && *xcxData != nil && len(*xcxData) > 0 { afList := []map[string]interface{}{} for k, v := range *xcxData { //判断用户是否有小程序切使用过剑鱼其他产品 //判断uid uId := "" for i := 0; i < 10; i++ { phone := common.ObjToString(v["phone"]) contactsData := TiDb.SelectBySql("select * from dwd_f_userbase_contacts where phone = ? and is_delete = 1", phone) if contactsData != nil && len(*contactsData) > 0 { if common.ObjToString((*contactsData)[0]["baseinfo_id"]) != "" { uId = common.ObjToString((*contactsData)[0]["baseinfo_id"]) } } if uId == "" { time.Sleep(1 * time.Minute) } else { break } } updatetime := common.ObjToString(v["time"]) if uId == "" { cfg.LastXcxUserId = updatetime continue } ok1, ok2, _ := FormatData(v, "xcxusers") /*if !ok3 { //首次使用"安防"小程序新注册用户 afList = append(afList, v) cfg.LastXcxUserId = updatetime continue }*/ if !ok1 { common.WriteSysConfig(&cfg) log.Println("小程序用户分配线索卡点", "xcxusers", v, selectXcxTimeEnd) } else { if !ok2 { log.Println("小程序用户分配已达上限", "xcxusers", v, selectXcxTimeEnd) common.WriteSysConfig(&cfg) } } if k == len(*xcxData)-1 { cfg.LastXcxUserId = updatetime } } if len(afList) > 0 { //发邮件给张文福 AFEmail(afList) } } 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 abhList := []map[string]interface{}{} 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(db.Mgo.DbName).C("saleLeads").Find(&query).Sort("_id").Iter() thisData := map[string]interface{}{} for { if !iter.Next(&thisData) { break } sourceCode := common.ObjToString(thisData["source"]) if sourceCode == "" { log.Println("留资没有source", thisData) continue } // filterArr := []string{"-pc", "-app", "-wx", "-h5"} sourceMap := map[string]string{} saleSource := TiDb.SelectBySql(`SELECT source,name FROM d_saleleads_code WHERE (department LIKE '%大客户%' or department LIKE '%市场组%' or department LIKE '%咨询组%') AND is_delete = 1`) if saleSource != nil && len(*saleSource) > 0 { for _, v := range *saleSource { source := common.ObjToString(v["source"]) name := common.ObjToString(v["name"]) for _, s := range filterArr { name = strings.ReplaceAll(name, s, "") } sourceMap[source] = name } } if sourceMap[sourceCode] != "" { continue } ok1, ok2, ok3 := FormatData(thisData, "saleLeads") if !ok3 { cfg.LastId = mongodb.BsonIdToSId(thisData["_id"]) //安博会数据 abhList = append(abhList, thisData) continue } if !ok1 { log.Println("线索卡点", "saleLeads", thisData, lastId) } else { if !ok2 { log.Println("用户分配已达上限", "saleLeads", thisData, lastId) } } cfg.LastId = mongodb.BsonIdToSId(thisData["_id"]) } if len(abhList) > 0 { //安博会发邮件高翔 ABHEmail("saleLeads", abhList) } 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) data := TiDb.SelectBySql(sql) if data != nil && *data != nil && len(*data) > 0 { abhList := []map[string]interface{}{} for _, v := range *data { phone := common.ObjToString(v["phone"]) uId := common.ObjToString(v["uid"]) userId := common.ObjToString(v["userid"]) //判断用户是否有小程序切使用过剑鱼其他产品 s_platform := gconv.String(v["s_platform"]) login_positionid := gconv.Int64(v["login_positionid"]) if s_platform == "xcx" && login_positionid == 0 { log.Println(phone, uId, userId, "用户是否有小程序且未使用过剑鱼其他产品") continue } 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 phone = ? 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(db.RegTimes)*86400 { if count == 0 { clueId := int64(0) sql := fmt.Sprintf(`select * from freeClubSign where mogUserId="%s" and sub_again_date > "%s" `, userId, selectTimeEnd) data := BiService.SelectBySql(sql) if len(*data) > 0 && userId != "" { 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": "670", "trailstatus": "01", "name": name, "phone": phone, "comeintime_open": nowTime, "comeinsource_open": 1, "FREEZE_TIME": nowTime, }) } else { 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 { ok1, ok2, ok3 := FormatData(v, "users") if !ok3 { //安博会数据 abhList = append(abhList, v) continue } if !ok1 { log.Println("线索卡点", "userbase uid", v, uId) } else { if !ok2 { log.Println("用户分配已达上限", "userbase uid", v, uId) } } } 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, }) } } } } } } if len(abhList) > 0 { //安博会发邮件高翔 ABHEmail("user", abhList) } } 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 item == "xcxusers" { level = "S" pcode = "532" code = "477" topname = "其他" switch sourceCode { case "环境采购": pcode = "532" code = "696" subname = `首次使用“环境”小程序` case "物业": pcode = "532" code = "693" subname = `首次使用“物业”小程序` case "印务商机": pcode = "532" code = "697" subname = `首次使用“印务”小程序` case "家具": pcode = "532" code = "695" subname = `首次使用“家具”小程序` case "车辆租赁": pcode = "532" code = "694" subname = `首次使用“车辆”小程序` case "安防": pcode = "532" code = "701" subname = `首次使用“安防”小程序` } } else if item == "allocation" { pcode = "532" code = "671" level = "D" pcodeData := TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"code": pcode}, "", "") if pcodeData != nil && len(*pcodeData) > 0 { topname = common.ObjToString((*pcodeData)["name"]) } pcodeData = TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"code": code}, "", "") if pcodeData != nil && len(*pcodeData) > 0 { subname = common.ObjToString((*pcodeData)["name"]) } } else if item == "rebind" { pcode = "532" code = "670" level = "D" pcodeData := TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"code": pcode}, "", "") if pcodeData != nil && len(*pcodeData) > 0 { topname = common.ObjToString((*pcodeData)["name"]) } pcodeData = TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"code": code}, "", "") if pcodeData != nil && len(*pcodeData) > 0 { subname = common.ObjToString((*pcodeData)["name"]) } } 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 bool, noticePositionId int64) { 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.Find("dwd_f_crm_clue_info", map[string]interface{}{"cluename": cluename, "is_assign": 1}, "", "", -1, -1) cdata := TiDb.SelectBySql(`select position_id,MAX(trail_time) as trail_time,max(last_ring_time) as last_ring_time,seatNumber,count(id) as count from dwd_f_crm_clue_info where cluename=? and is_assign =1 GROUP BY position_id `, cluename) if cdata != nil && len(*cdata) > 0 { //找到了公司有人在跟进 isOk = true pdata := TiDb.SelectBySql(`select * from dwd_f_crm_personnel_management where seat_number is not null and seat_number != ""`) if pdata == nil { positionId = 0 seatNumber = "" saleName = "" return } saleData = *pdata cdataNew := []map[string]interface{}{} if len(*cdata) > 1 { //可能有多个人跟进 personMap := map[int64]bool{} upperLimitPersonMap := map[int64]bool{} upperLimitCdataNew := []map[string]interface{}{} upperLimitCount := 0 isFull := false for _, m := range *cdata { positionid1 := gconv.Int64(m["position_id"]) for _, v := range *pdata { resign := common.IntAll(v["resign"]) assign_type := common.IntAll(v["assign_type"]) role_id := common.IntAll(v["role_id"]) if positionid1 == common.Int64All(v["position_id"]) { if resign == 0 && (assign_type == 1 || role_id == 8) { if !FindUpperLimit(gconv.String(positionid1), mode, true) { personMap[positionid1] = true m["saleName"] = common.ObjToString(v["name"]) cdataNew = append(cdataNew, m) } else { upperLimitCount++ upperLimitPersonMap[positionid1] = true m["saleName"] = common.ObjToString(v["name"]) upperLimitCdataNew = append(upperLimitCdataNew, m) } } } } } if len(cdataNew) == 0 && len(upperLimitCdataNew) > 0 { //没有达上限的人数为0 全部都是达上限的 personMap = upperLimitPersonMap cdataNew = upperLimitCdataNew isFull = true } //查询是否都有没有离职 if len(personMap) != 0 && len(cdataNew) > 0 { layout := "2006-01-02 15:04:05" //有人没有离职 data := map[string]interface{}{} trailTime := int64(0) for _, m := range cdataNew { currentTime := int64(0) if gconv.String(m["trail_time"]) == "" { continue } t, _ := time.Parse(layout, gconv.String(m["trail_time"])) currentTime = t.Unix() if currentTime > trailTime { trailTime = currentTime data = m } } if trailTime == 0 { //需要查看通话记录 lastRingTime := int64(0) for _, m := range cdataNew { currentTime := int64(0) if gconv.String(m["last_ring_time"]) == "" { continue } t, _ := time.Parse(layout, gconv.String(m["last_ring_time"])) currentTime = t.Unix() if currentTime > lastRingTime { lastRingTime = currentTime data = m } } if lastRingTime != 0 { positionId = common.Int64All(data["position_id"]) noticePositionId = positionId seatNumber = common.ObjToString(data["seatNumber"]) saleName = common.ObjToString(data["saleName"]) if isFull { isFreeze = true noticePositionId = positionId positionId = 0 seatNumber = "" saleName = "" } return } else { count := 0 //线索数量判断 for i, v := range cdataNew { if i == 0 { count = gconv.Int(v["count"]) data = v } else { if count < gconv.Int(v["count"]) { count = gconv.Int(v["count"]) data = v } } } positionId = common.Int64All(data["position_id"]) noticePositionId = positionId saleName = common.ObjToString(data["saleName"]) seatNumber = common.ObjToString(data["seatNumber"]) if isFull { isFreeze = true noticePositionId = positionId positionId = 0 seatNumber = "" saleName = "" } return } } else { positionId = common.Int64All(data["position_id"]) noticePositionId = positionId seatNumber = common.ObjToString(data["seatNumber"]) saleName = common.ObjToString(data["saleName"]) if isFull { isFreeze = true noticePositionId = positionId positionId = 0 seatNumber = "" saleName = "" } return } } } else { //只有一人跟进 //(1)该销售人员未离职,则继续分配给该销售人员(保持现状); //该销售人员已离职,则随机分配 positionId = common.Int64All((*cdata)[0]["position_id"]) noticePositionId = positionId seatNumber = common.ObjToString((*cdata)[0]["seatNumber"]) for _, v := range *pdata { resign := common.IntAll(v["resign"]) assign_type := common.IntAll(v["assign_type"]) role_id := common.IntAll(v["role_id"]) if positionId == common.Int64All(v["position_id"]) { if resign == 0 && (assign_type == 1 || role_id == 8) { if FindUpperLimit(gconv.String(positionId), mode, true) { isFreeze = true positionId = 0 seatNumber = "" saleName = "" break } else { saleName = common.ObjToString(v["name"]) return } } } } } } } } positionId = 0 seatNumber = "" saleName = "" 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 if mode == "D" { query += ` assign_level like "%D%"` } else if mode == "C" { query += ` assign_level like "%C%"` } else if mode == "S" { query += ` assign_level like "%S%"` } 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(v["position_id"]), mode, false) { 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"]) positionId = common.Int64All(v["position_id"]) } } countres++ } } log.Println(444, res) } } else { for _, kv := range *data { positionId1 := gconv.String(kv["position_id"]) if !FindUpperLimit(positionId1, "", false) { positionId = common.Int64All(kv["position_id"]) saleName = common.ObjToString(kv["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, level string, isAdd bool) bool { if positionId == "" { return false } isFull := TiDb.CountBySql(`select count(1) from dwd_f_crm_clue_info where position_id=? and is_assign=1 and is_transfer != 1 `, positionId) >= db.AllocationCap if isFull && isAdd && level != "" { TiDb.UpdateOrDeleteBySql(`update dwd_f_crm_clue_autodraw_record set count = count + 1 where position_id = ? and clue_level = ?`, positionId, level) } return isFull } 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 } // 重新关注用户处理 func rebind() { log.Println("重新关注用户处理开始") //判断节假日 runOk := getRunOk() if !runOk { log.Println("不是工作日,任务暂停") return } rebindTimeEnd := cfg.RebindTime sql := fmt.Sprintf(`select * from freeClubSign where sub_again_date > "%s" order by sub_again_date asc`, rebindTimeEnd) data := BiService.SelectBySql(sql) if data != nil && *data != nil && len(*data) > 0 { for _, v := range *data { rebindTimeEnd = common.ObjToString(v["sub_again_date"]) registedates, _ := time.Parse(date.Date_Full_Layout, gconv.String(v["register_time"])) if time.Now().Unix()-registedates.Unix() > int64(db.RegTimes)*86400 { ok1, ok2, _ := FormatData(v, "rebind") if !ok1 { log.Println("线索卡点", "allocation", v, rebindTimeEnd) } else { if !ok2 { log.Println("用户分配已达上限", "allocation", v, rebindTimeEnd) } } } } cfg.RebindTime = rebindTimeEnd common.WriteSysConfig(&cfg) } log.Println("重新关注用户处理结束") } // 活跃用户处理 func activeUsers() { log.Println("活跃用户处理开始") //判断节假日 runOk := getRunOk() if !runOk { log.Println("不是工作日,任务暂停") return } //活跃用户查询 activeTimeEnd := cfg.ActiveTime sql := fmt.Sprintf(`select * from freeClubSign where act_again_date > "%s" order by act_again_date asc`, activeTimeEnd) data := BiService.SelectBySql(sql) if data != nil && *data != nil && len(*data) > 0 { for _, v := range *data { activeTimeEnd = common.ObjToString(v["act_again_date"]) ok1, ok2, _ := FormatData(v, "allocation") log.Println(v, "allocation", ok1, ok2) if !ok1 { log.Println("线索卡点", "allocation", v, activeTimeEnd) } else { if !ok2 { log.Println("用户分配已达上限", "allocation", v, activeTimeEnd) } } } cfg.ActiveTime = activeTimeEnd common.WriteSysConfig(&cfg) } log.Println("活跃用户处理结束") } // 安博会邮件 func ABHEmail(source string, data []map[string]interface{}) { fileName, detailName, email, dir := "", "", "", "" var err error switch source { case "user": xlsxArr := []string{"姓名", "联系方式", "邮箱", "公司名称", "咨询需求", "销售线索来源", "具体来源", "留资时间"} batch := FindBatch("abh") fileName, detailName = "安博会用户注册销售线索 "+time.Now().Format(date.Date_Short_Layout)+"-"+batch, "" xf := xlsx.NewFile() style := xlsx.NewStyle() style.Font.Size = 12 style.Font.Bold = true style.Alignment.Vertical = "center" style.Alignment.Horizontal = "center" detailName = "今日新增安博会销售线索,请查收附件,及时跟进。" sh, _ := xf.AddSheet("线索数据") row1 := sh.AddRow() for _, x := range xlsxArr { cell := row1.AddCell() cell.SetString(x) cell.SetStyle(style) } for _, v := range data { row := sh.AddRow() row.AddCell().SetString(common.ObjToString(v["name"])) row.AddCell().SetString(common.ObjToString(v["phone"])) row.AddCell().SetString(common.ObjToString(v["email"])) row.AddCell().SetString(common.ObjToString(v["company_name"])) row.AddCell().SetString("") row.AddCell().SetString("") row.AddCell().SetString("安博会用户注册") row.AddCell().SetString(gconv.Time(gconv.Int64(v["createtime"])).Format(date.Date_Full_Layout)) //增加客户需求 } dir = "./xlsx/abh/" + fileName + ".xlsx" err = xf.Save(dir) case "saleLeads": xlsxArr := []string{"用户昵称", "姓名", "公司名称", "职位", "联系人电话", "购买条数", "用户邮箱", "已支付订单信息", "未支付订单类型", "销售线索来源", "具体来源", "数据需求"} batch := FindBatch("abh") fileName, detailName = time.Now().Format(date.Date_Short_Layout)+"-"+batch+"安博会电销销售线索", "" xf := xlsx.NewFile() style := xlsx.NewStyle() style.Font.Size = 12 style.Font.Bold = true style.Alignment.Vertical = "center" style.Alignment.Horizontal = "center" detailName = "今日新增安博会销售线索,请查收附件,及时跟进。" sh, _ := xf.AddSheet("线索数据") row1 := sh.AddRow() for _, x := range xlsxArr { cell := row1.AddCell() cell.SetString(x) cell.SetStyle(style) } filterArr := []string{"-pc", "-app", "-wx", "-h5"} sourceMap := map[string]string{} //根据留资维表:tidb/Jianyu_subjectdb/d_saleleads_code saleSource := TiDb.SelectBySql(`SELECT source,name FROM d_saleleads_code WHERE is_delete = 1`) if saleSource != nil && len(*saleSource) > 0 { for _, v := range *saleSource { source := common.ObjToString(v["source"]) name := common.ObjToString(v["name"]) for _, s := range filterArr { name = strings.ReplaceAll(name, s, "") } sourceMap[source] = name } } for _, v := range data { sources := common.ObjToString(v["source"]) interest := common.ObjToString(v["interest"]) row := sh.AddRow() row.AddCell().SetString(common.ObjToString(v["usernickname"])) row.AddCell().SetString(common.ObjToString(v["name"])) row.AddCell().SetString(common.ObjToString(v["company"])) row.AddCell().SetString(common.ObjToString(v["position"])) row.AddCell().SetString(common.ObjToString(v["phone"])) row.AddCell().SetValue(0) row.AddCell().SetString(common.ObjToString(v["email"])) row.AddCell().SetString("") row.AddCell().SetString("") row.AddCell().SetString(sourceMap[sources]) row.AddCell().SetString(interest) row.AddCell().SetString(common.ObjToString(v["data_requirement"])) //增加客户需求 } dir = "./xlsx/abh/" + fileName + ".xlsx" err = xf.Save(dir) case "big": xlsxArr := []string{"用户昵称", "姓名", "公司名称", "职位", "联系人电话", "购买条数", "用户邮箱", "已支付订单信息", "未支付订单类型", "销售线索来源", "具体来源", "数据需求"} batch := FindBatch("abh") fileName, detailName = time.Now().Format(date.Date_Short_Layout)+"-"+batch+"安博会大客户销售线索", "" xf := xlsx.NewFile() style := xlsx.NewStyle() style.Font.Size = 12 style.Font.Bold = true style.Alignment.Vertical = "center" style.Alignment.Horizontal = "center" detailName = "今日新增安博会销售线索,请查收附件,及时跟进。" sh, _ := xf.AddSheet("线索数据") row1 := sh.AddRow() for _, x := range xlsxArr { cell := row1.AddCell() cell.SetString(x) cell.SetStyle(style) } for _, v := range data { row := sh.AddRow() row.AddCell().SetString(common.ObjToString(v["usernickname"])) row.AddCell().SetString(common.ObjToString(v["username"])) row.AddCell().SetString(common.ObjToString(v["company"])) row.AddCell().SetString(common.ObjToString(v["job"])) row.AddCell().SetString(common.ObjToString(v["phone"])) row.AddCell().SetValue(common.IntAll(v["data_count"])) row.AddCell().SetString(common.ObjToString(v["email"])) row.AddCell().SetString(common.ObjToString(v["payorderinfo"])) row.AddCell().SetString(common.ObjToString(v["unpayorderinfo"])) row.AddCell().SetString(common.ObjToString(v["source"])) row.AddCell().SetString(common.ObjToString(v["interest"])) row.AddCell().SetString(common.ObjToString(v["data_requirement"])) //增加客户需求 } dir = "./xlsx/abh/" + fileName + ".xlsx" err = xf.Save(dir) case "advisory": xlsxArr := []string{"姓名", "联系方式", "邮箱", "公司名称", "咨询需求", "销售线索来源", "具体来源", "留资时间"} //排序:首先按照“联系方式”排序,即同1个用户的留资放在一起,其次按照留资时间正序排序。 batch := FindBatch("abh") fileName, detailName = "安博会咨询服务销售线索 "+time.Now().Format(date.Date_Short_Layout)+"-"+batch, "" xf := xlsx.NewFile() style := xlsx.NewStyle() style.Font.Size = 12 style.Font.Bold = true style.Alignment.Vertical = "center" style.Alignment.Horizontal = "center" detailName = "今日新增安博会销售线索,请查收附件,及时跟进。" sh, _ := xf.AddSheet("线索数据") row1 := sh.AddRow() for _, x := range xlsxArr { cell := row1.AddCell() cell.SetString(x) cell.SetStyle(style) } for _, v := range data { row := sh.AddRow() row.AddCell().SetString(common.ObjToString(v["username"])) row.AddCell().SetString(common.ObjToString(v["phone"])) row.AddCell().SetString(common.ObjToString(v["email"])) row.AddCell().SetString(common.ObjToString(v["company"])) row.AddCell().SetString(common.ObjToString(v["data_requirement"])) row.AddCell().SetString(common.ObjToString(v["source"])) row.AddCell().SetString(common.ObjToString(v["interest"])) row.AddCell().SetString(gconv.Time(gconv.Int64(v["createtime"])).Format(date.Date_Full_Layout)) } dir = "./xlsx/abh/" + fileName + ".xlsx" err = xf.Save(dir) case "market": xlsxArr := []string{"姓名", "联系人电话", "公司名称", "职位", "部门", "销售线索来源", "留资时间"} batch := FindBatch("abh") fileName, detailName = "安博会商务合作销售线索 "+time.Now().Format(date.Date_Short_Layout)+"-"+batch, "" xf := xlsx.NewFile() style := xlsx.NewStyle() style.Font.Size = 12 style.Font.Bold = true style.Alignment.Vertical = "center" style.Alignment.Horizontal = "center" detailName = "今日新增安博会销售线索,请查收附件,及时跟进。" sh, _ := xf.AddSheet("线索数据") row1 := sh.AddRow() for _, x := range xlsxArr { cell := row1.AddCell() cell.SetString(x) cell.SetStyle(style) } for _, v := range data { row := sh.AddRow() row.AddCell().SetString(common.ObjToString(v["username"])) row.AddCell().SetString(common.ObjToString(v["phone"])) row.AddCell().SetString(common.ObjToString(v["company"])) row.AddCell().SetString(common.ObjToString(v["job"])) row.AddCell().SetString(common.ObjToString(v["branch"])) row.AddCell().SetString(common.ObjToString(v["source"])) row.AddCell().SetString(gconv.Time(gconv.Int64(v["createtime"])).Format(date.Date_Full_Layout)) //增加客户需求 } dir = "./xlsx/abh/" + fileName + ".xlsx" err = xf.Save(dir) } email = db.AbhEmail if err != nil { log.Println("xls error", err, dir) } else { gmail := &mail.GmailAuth{ SmtpHost: "smtp.exmail.qq.com", SmtpPort: 465, User: "public03@topnet.net.cn", Pwd: "ue9Rg9Sf4CVtdm5a", } status := mail.GSendMail_q("剑鱼标讯", email, "", "", fileName, detailName, dir, fileName+".xlsx", gmail) if status { log.Println("send mail success", fileName, email) } } } // 安防邮件 func AFEmail(data []map[string]interface{}) { xlsxArr := []string{"姓名", "联系方式", "邮箱", "公司名称", "咨询需求", "销售线索来源", "具体来源", "留资时间"} batch := FindBatch("af") fileName, detailName := "安防销售线索 "+time.Now().Format(date.Date_Short_Layout)+"-"+batch, "" xf := xlsx.NewFile() style := xlsx.NewStyle() style.Font.Size = 12 style.Font.Bold = true style.Alignment.Vertical = "center" style.Alignment.Horizontal = "center" detailName = "今日新增安防销售线索,请查收附件,及时跟进。" sh, _ := xf.AddSheet("线索数据") row1 := sh.AddRow() for _, x := range xlsxArr { cell := row1.AddCell() cell.SetString(x) cell.SetStyle(style) } for _, v := range data { row := sh.AddRow() row.AddCell().SetString(common.ObjToString(v["name"])) row.AddCell().SetString(common.ObjToString(v["phone"])) row.AddCell().SetString(common.ObjToString(v["email"])) row.AddCell().SetString(common.ObjToString(v["company_name"])) row.AddCell().SetString("") row.AddCell().SetString("") row.AddCell().SetString("首次使用安防新注册") row.AddCell().SetString(gconv.String(v["time"])) //增加客户需求 } email := db.AfEmail dir := "./xlsx/af/" + fileName + ".xlsx" err := xf.Save(dir) if err != nil { log.Println("xls error", err, dir) } else { gmail := &mail.GmailAuth{ SmtpHost: "smtp.exmail.qq.com", SmtpPort: 465, User: "public03@topnet.net.cn", Pwd: "ue9Rg9Sf4CVtdm5a", } status := mail.GSendMail_q("剑鱼标讯", email, "", "", fileName, detailName, dir, fileName+".xlsx", gmail) if status { log.Println("send mail success", fileName, email) } } }