Browse Source

Merge remote-tracking branch 'origin/feature/v1.5.8' into feature/v1.5.8

# Conflicts:
#	doFreeClueSign/job/job.go
duxin 1 year ago
parent
commit
35c9e4e7fb
12 changed files with 1582 additions and 147 deletions
  1. 22 8
      clueSync/config.go
  2. 5 2
      clueSync/config.json
  3. 144 0
      clueSync/db.json
  4. 15 2
      clueSync/everything.go
  5. 2 3
      clueSync/go.mod
  6. 1071 7
      clueSync/go.sum
  7. 18 6
      clueSync/job.go
  8. 243 65
      clueSync/jobutil.go
  9. 1 1
      clueSync/kc.go
  10. 52 44
      clueSync/main.go
  11. 7 7
      doFreeClueSign/job/job.go
  12. 2 2
      doFreeClueSign/job/mamager.go

+ 22 - 8
clueSync/config.go

@@ -26,16 +26,20 @@ type (
 		MarketSaleTime     int64   `json:"marketSaleTime"`
 		AllocationTime     string  `json:"allocationTime"`
 		AllocationRatio    float64 `json:"allocationRatio"`
+		ActiveTime         string  `json:"activeTime"`
+		RebindTime         string  `json:"rebindTime"`
 	}
 	DB struct {
-		CornExp1 string `json:"cornexp1"`
-		CornExp2 string `json:"cornexp2"`
-		CornExp3 string `json:"cornexp3"`
-		CornExp4 string `json:"cornexp4"`
-		CornExp5 string `json:"cornexp5"`
-		CornExp6 string `json:"cornexp6"`
-		CornExp7 string `json:"cornexp7"`
-		TiDb     struct {
+		CornExp1      int64  `json:"cornexp1"`
+		CornExp2      int64  `json:"cornexp2"`
+		CornExp2Start string `json:"cornexp2Strat"`
+		CornExp2End   string `json:"cornexp2End"`
+		CornExp3      string `json:"cornexp3"`
+		CornExp4      string `json:"cornexp4"`
+		CornExp5      int64  `json:"cornexp5"`
+		CornExp6      int64  `json:"cornexp6"`
+		CornExp7      string `json:"cornexp7"`
+		TiDb          struct {
 			Host        string `json:"host"`
 			Port        int    `json:"port"`
 			Database    string `json:"database"`
@@ -85,6 +89,16 @@ type (
 			MaxIdle     int    `json:"maxidle"`
 			MaxLeftTime int    `json:"maxleft"`
 		} `json:"baseService"`
+		BiService struct {
+			Host        string `json:"host"`
+			Port        int    `json:"port"`
+			Database    string `json:"database"`
+			User        string `json:"user"`
+			Password    string `json:"password"`
+			PollSize    int    `json:"poolsize"`
+			MaxIdle     int    `json:"maxidle"`
+			MaxLeftTime int    `json:"maxleft"`
+		} `json:"biService"`
 		ThirdParty struct {
 			Host        string `json:"host"`
 			Port        int    `json:"port"`

+ 5 - 2
clueSync/config.json

@@ -16,5 +16,8 @@
   "marketSaleTime": 1708160200,
   "allocationTime": "2024-07-01 14:59:37",
   "allocationRatio": 2,
-  "lastXcxUserId": "2024-07-09 14:59:37"
-}
+  "lastXcxUserId": "2024-07-09 14:59:37",
+  "activeTime": "2024-07-01 14:59:37",
+  "rebindTime": "2024-07-01 14:59:37"
+}
+

+ 144 - 0
clueSync/db.json

@@ -0,0 +1,144 @@
+{
+  "cornexp1": 30,
+  "cornexp2": 1,
+  "cornexp2End": "18:00",
+  "cornexp2Strat": "09:00",
+  "cornexp3": "0 30 8 * * ?",
+  "cornexp4": "0 0 0 */1 * ? ",
+  "cornexp5": 5,
+  "cornexp6": 10,
+  "cornexp7": "0 */10 * * * ?",
+  "redisServer": "bidx=192.168.3.206:1712,newother=192.168.3.149:1712",
+  "tiDb": {
+    "host": "192.168.3.149",
+    "port": 4000,
+    "database": "jianyu_subjectdb_test",
+    "user": "datagroup",
+    "password": "Dgrpdb#2024@36",
+    "poolsize": 20,
+    "maxidle": 40,
+    "maxleft": 40
+  },
+  "tiDbData": {
+    "host": "192.168.3.149",
+    "port": 4000,
+    "database": "Call_Accounting",
+    "user": "datagroup",
+    "password": "Dgrpdb#2024@36",
+    "poolsize": 20,
+    "maxidle": 40,
+    "maxleft": 40
+  },
+  "tiDbPower": {
+    "host": "192.168.3.149",
+    "port": 4000,
+    "database": "jianyu_subjectdb_test",
+    "user": "datagroup",
+    "password": "Dgrpdb#2024@36",
+    "poolsize": 20,
+    "maxidle": 40,
+    "maxleft": 40
+  },
+  "workOrder": {
+    "host": "192.168.3.14",
+    "port": 4000,
+    "database": "work_order",
+    "user": "root",
+    "password": "=PDT49#80Z!RVv52_z",
+    "poolsize": 20,
+    "maxidle": 40,
+    "maxleft": 40
+  },
+  "baseService": {
+    "host": "192.168.3.14",
+    "port": 4000,
+    "database": "base_service",
+    "user": "root",
+    "password": "=PDT49#80Z!RVv52_z",
+    "poolsize": 20,
+    "maxidle": 40,
+    "maxleft": 40
+  },
+  "biService": {
+    "host": "192.168.3.14",
+    "port": 4000,
+    "database": "bi_service",
+    "user": "root",
+    "password": "=PDT49#80Z!RVv52_z",
+    "poolsize": 20,
+    "maxidle": 40,
+    "maxleft": 40
+  },
+  "thirdParty": {
+    "host": "192.168.3.14",
+    "port": 4000,
+    "database": "thirdparty",
+    "user": "root",
+    "password": "=PDT49#80Z!RVv52_z",
+    "poolsize": 20,
+    "maxidle": 40,
+    "maxleft": 40
+  },
+  "mysql": {
+    "host": "192.168.3.14",
+    "port": 4000,
+    "database": "jianyu",
+    "user": "root",
+    "password": "=PDT49#80Z!RVv52_z",
+    "poolsize": 20,
+    "maxidle": 40,
+    "maxleft": 40
+  },
+  "mgo": {
+    "address": "192.168.3.149:27180",
+    "dbName": "qfw",
+    "dbSize": 20
+  },
+  "mgoLog": {
+    "address": "192.168.3.149:27190",
+    "dbName": "qfw",
+    "dbSize": 20,
+    "user": "admin",
+    "password": "123456"
+  },
+  "mgoQyxy": {
+    "address": "192.168.3.149:27102",
+    "dbName": "mixdata",
+    "dbSize": 20,
+    "user": "jyDevGroup",
+    "password": "jy@DevGroup"
+  },
+  "es": {
+    "address": "http://192.168.3.149:9200",
+    "dbSize": 20,
+    "version": "v7",
+    "UserName": "",
+    "password": ""
+  },
+  "productArr": [
+    "数据流量包",
+    "结构化数据",
+    "API接口",
+    "广告服务",
+    "物业专版",
+    "市场分析报告"
+  ],
+  "marketSaleMail": "wanghao@jianyu360.com",
+  "allocationCap": 500,
+  "warningValue": 350,
+  "corn_mail": "",
+  "regTimes": 7,
+  "jyactivities": {
+    "host": "",
+    "port": 0,
+    "database": "",
+    "user": "",
+    "password": "",
+    "poolsize": 0,
+    "maxidle": 0,
+    "maxleft": 0
+  },
+  "nameToMail": null,
+  "thawDay": 3,
+  "loopType": 1
+}

+ 15 - 2
clueSync/everything.go

@@ -394,7 +394,6 @@ func bigCustomer() {
 				email := common.ObjToString(v["mail"])
 				interest := common.ObjToString(v["interest"])
 				data_requirement := common.ObjToString(v["data_requirement"])
-
 				belongTo, usernickname := "大客户", ""
 				userData := TiDb.FindOne("dwd_f_userbase_baseinfo", map[string]interface{}{"uid": uid}, "", "")
 				if userData != nil {
@@ -431,9 +430,23 @@ func bigCustomer() {
 			phone := common.ObjToString(v["user_phone"])
 			order_status := common.IntAll(v["order_status"])
 			product_type := common.ObjToString(v["product_type"])
-			userData := TiDb.FindOne("dwd_f_userbase_baseinfo", map[string]interface{}{"phone": phone}, "", "")
+			orderUserId := gconv.String(v["user_id"])
+			query := map[string]interface{}{}
+			if !mongodb.IsObjectIdHex(orderUserId) {
+				userMapping := TiDb.FindOne("dwd_f_userbase_id_mapping", map[string]interface{}{"position_id": orderUserId}, "", "")
+				if userMapping != nil && len(*userMapping) > 0 {
+					uid := common.ObjToString((*userMapping)["uid"])
+					query["uid"] = uid
+				}
+			} else {
+				query["userid"] = orderUserId
+			}
+			userData := TiDb.FindOne("dwd_f_userbase_baseinfo", query, "", "")
 			username, usernickname, userid, uid, source, payorderinfo, unpayorderinfo := "", "", "", "", "", "", ""
 			if userData != nil {
+				if phone == "" {
+					phone = common.ObjToString((*userData)["phone"])
+				}
 				username = common.ObjToString((*userData)["name"])
 				usernickname = common.ObjToString((*userData)["nickname"])
 				uid = common.ObjToString((*userData)["uid"])

+ 2 - 3
clueSync/go.mod

@@ -3,7 +3,8 @@ module clueSync
 go 1.14
 
 require (
-	app.yhyue.com/moapp/jybase v0.0.0-20240514063605-a33a48d6be14
+	app.yhyue.com/moapp/jybase v0.0.0-20240523083821-42a82b37ae20
+	bp.jydev.jianyu360.cn/BaseService/pushpkg v0.0.0-20240627084125-22b4217112c7
 	github.com/go-xweb/httpsession v0.0.0-20141220075701-356d3b4d38d6 // indirect
 	github.com/go-xweb/log v0.0.0-20140701090824-270d183ad77e // indirect
 	github.com/go-xweb/uuid v0.0.0-20140604020037-d7dce341f851 // indirect
@@ -11,8 +12,6 @@ require (
 	github.com/gogf/gf v1.16.9
 	github.com/gogf/gf/v2 v2.7.0
 	github.com/lunny/csession v0.0.0-20130910075847-fe53c5de3dfd // indirect
-	github.com/mattn/go-runewidth v0.0.13 // indirect
-	github.com/mattn/go-sqlite3 v1.9.0 // indirect
 	github.com/robfig/cron v1.2.0
 	github.com/tealeg/xlsx v1.0.5
 )

File diff suppressed because it is too large
+ 1071 - 7
clueSync/go.sum


+ 18 - 6
clueSync/job.go

@@ -3,6 +3,7 @@ package main
 import (
 	"database/sql"
 	"fmt"
+	"github.com/gogf/gf/v2/util/gconv"
 	"log"
 	"strings"
 	"time"
@@ -89,6 +90,17 @@ func FormatData(data map[string]interface{}, item string) (bool, bool) {
 			}
 
 		}
+	} else if item == "allocation" || item == "rebind" {
+		userId = mongodb.BsonIdToSId(data["mogUserId"])
+		userInfo := TiDb.FindOne("dwd_f_userbase_baseinfo", map[string]interface{}{
+			"userid": userId,
+		}, "", "")
+		if userInfo != nil && len(*userInfo) > 0 {
+			phone = common.ObjToString((*userInfo)["phone"])
+			uId = common.ObjToString((*userInfo)["uid"])
+			source = common.ObjToString((*userInfo)["source"])
+			belong_to = common.ObjToString((*userInfo)["belong_to"])
+		}
 	} else if item == "saleLeads" { //留资
 		userId = common.ObjToString(data["userid"])
 		if !mongodb.IsObjectIdHex(userId) {
@@ -98,7 +110,6 @@ func FormatData(data map[string]interface{}, item string) (bool, bool) {
 				userId = common.ObjToString((*userMapping)["userid"])
 			}
 		}
-
 		cluename = common.ObjToString(data["company"])
 		phone = common.ObjToString(data["phone"])
 		role = common.ObjToString(data["companyType"])
@@ -193,6 +204,7 @@ func FormatData(data map[string]interface{}, item string) (bool, bool) {
 	if cluename == "" && item != "message" && item != "orders" && item != "readClue" {
 		cluename = phone //没有线索名,手机号代替
 	}
+	cluename = strings.ReplaceAll(cluename, " ", "")
 	isGroup, isCommerce := GetCompanyType(cluename)                                                                    //判断是否集团公司、工商库
 	if source == "0104" || strings.HasPrefix(belong_to, "02") || source == "0102" || source == "0103" || phone == "" { //参照用户来源代码表
 		//log.Println("线索分配失败,线索过滤!!", item, source, phone, userId)
@@ -422,6 +434,7 @@ func FormatData(data map[string]interface{}, item string) (bool, bool) {
 }
 
 func SaveClue(item, userId, uId, top_cluetype, sub_cluetype, topname, subname, cluename, name, saleName, phone, position, department, departments, industry, follow_project_area, role, seatNumber string, positionId int64, source, sourceCode, remark string, keyword []string, belong_to string, isGroup, isCommerce int, isFreeze bool, demand string) bool {
+	log.Println("线索修改前", item, userId, uId, top_cluetype, sub_cluetype, topname, subname, cluename, name, saleName, phone, position, department, departments, industry, follow_project_area, role, seatNumber, positionId, source, sourceCode, remark)
 	nowTime := time.Now().Format("2006-01-02 15:04:05")
 	nowTimes := time.Unix(time.Now().Unix()+3600*12, 0).Format("2006-01-02 15:04:05")
 	clueId, uodateId1, uodateId2, uodateId3, uodateId4, uodateId5, uodateId6 := int64(0), int64(0), int64(0), int64(0), int64(0), int64(0), int64(0)
@@ -723,7 +736,7 @@ func WorkUpdateClue(data map[string]interface{}, saleData []map[string]interface
 		"sub_cluetype":         sub_cluetype,
 		"userid":               userId,
 		"comeinsource_private": 2,
-		"tasksource":           "线索来源自动更新" + "-" + topname + "-" + subname,
+		"tasksource":           gconv.String(common.If(gconv.Int64(data["position_id"]) == 0, "线索自动分配", "线索来源自动更新")) + "-" + topname + "-" + subname,
 		"company_nature":       isGroup,
 		"company_verification": isCommerce,
 	}
@@ -792,7 +805,6 @@ func WorkUpdateClue(data map[string]interface{}, saleData []map[string]interface
 			clueUpdateData["comeinsource_open"] = nil
 			clueUpdateData["level_open"] = nil
 			clueUpdateData["clue_level"] = nil
-
 		}
 	} else if is_assign == 1 && positionId != old_position_id {
 		clueUpdateData["seatNumber"] = seatNumber
@@ -873,7 +885,6 @@ func WorkUpdateClue(data map[string]interface{}, saleData []map[string]interface
 		//变更记录
 		if (trailstatus == "00" || old_position_id == 0 || (pIsOk && old_cluename != cluename && cluename != "")) && is_assign == 1 {
 			if trailstatus == "00" && trailstatusTime != "" && time.Now().Unix()-trailstatusTimes.Unix() < 86400 {
-
 			} else if old_position_id == 0 {
 				updateId1 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
 					"clue_id":      clueId,
@@ -1225,7 +1236,8 @@ func WorkUpdateClue(data map[string]interface{}, saleData []map[string]interface
 	}
 }
 func UpdateClue(data map[string]interface{}, saleData []map[string]interface{}, item, userId, uId, top_cluetype, sub_cluetype, topname, subname, cluename, name, saleName, phone, position, department, departments, industry, follow_project_area, role, seatNumber, level string, positionId int64, source, sourceCode, remark string, keyword []string, belong_to string, isGroup, isCommerce int, pIsOk bool) bool {
-	log.Println("线索修改前", data)
+	log.Println("线索修改前", data, item, userId, uId, top_cluetype, sub_cluetype, topname, subname, cluename, name, saleName, phone, position, department, departments, industry, follow_project_area, role, seatNumber, level, positionId, source, sourceCode, remark)
+	name = strings.ReplaceAll(name, " ", "")
 	nowTime := time.Now().Format("2006-01-02 15:04:05")
 	nowTimes := time.Unix(time.Now().Unix()+3600*12, 0).Format("2006-01-02 15:04:05")
 	trailstatus := common.ObjToString(data["trailstatus"]) //data都为原线索数据
@@ -1594,7 +1606,7 @@ func UpdateClue(data map[string]interface{}, saleData []map[string]interface{},
 							"clue_id":     clueId,
 							"position_id": common.If(trailstatus == "00" || is_assign == 0 || is_assign == -1, positionId, common.Int64All(data["position_id"])),
 							"change_type": "加入任务车",
-							"new_value":   "线索来源自动更新" + "-" + topname + "-" + subname,
+							"new_value":   gconv.String(common.If(gconv.Int64(data["position_id"]) == 0, "线索自动分配", "线索来源自动更新")) + "-" + topname + "-" + subname,
 							"createtime":  nowTime,
 							"BCPCID":      common.GetRandom(32),
 							"operator_id": -1,

+ 243 - 65
clueSync/jobutil.go

@@ -573,16 +573,11 @@ func users() {
 				log.Println(v, "用户是否有小程序且未使用过剑鱼其他产品")
 			} else {
 				ok1, ok2 := FormatData(v, "users")
-				//ok1, ok2 := true, true
 				if !ok1 {
-					common.WriteSysConfig(&cfg)
 					log.Println("线索卡点", "users", v, selectTimeEnd)
-					break
 				} else {
 					if !ok2 {
 						log.Println("用户分配已达上限", "users", v, selectTimeEnd)
-						common.WriteSysConfig(&cfg)
-						break
 					}
 				}
 			}
@@ -684,14 +679,10 @@ func saleLeads() {
 		}
 		ok1, ok2 := FormatData(thisData, "saleLeads")
 		if !ok1 {
-			common.WriteSysConfig(&cfg)
 			log.Println("线索卡点", "saleLeads", thisData, lastId)
-			break
 		} else {
 			if !ok2 {
 				log.Println("用户分配已达上限", "saleLeads", thisData, lastId)
-				common.WriteSysConfig(&cfg)
-				break
 			}
 		}
 		cfg.LastId = mongodb.BsonIdToSId(thisData["_id"])
@@ -743,28 +734,46 @@ func userbase() {
 						log.Println("userbase uid 注册时间 ", registedates)
 						if time.Now().Unix()-registedates.Unix() > int64(db.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,
-								})
+								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,
@@ -957,6 +966,32 @@ func getClueType(item string, data map[string]interface{}, sourceCode string, so
 				}
 			}
 		}
+	} else if item == "allocation" {
+		pcode = "532"
+		code = "671"
+		level = "C"
+		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 = "C"
+		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}, "", "")
@@ -981,52 +1016,130 @@ func autoDraw(mode, cluename, phone string, isGroup, isCommerce int) (positionId
 	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}, "", "")
+			//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
-				positionId = common.Int64All((*cdata)["position_id"])
-				noticePositionId = positionId
-				seatNumber = common.ObjToString((*cdata)["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
+				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{}
+					for _, m := range *cdata {
+						positionid := gconv.Int64(m["position_id"])
 						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), mode, true) {
-												positionId = common.Int64All(m["position_id"])
-												noticePositionId = positionId
-												seatNumber = common.ObjToString(m["seat_number"])
-												saleName = common.ObjToString(m["name"])
-												return
-											}
+							if positionid == common.Int64All(v["position_id"]) {
+								if resign == 0 {
+									if !FindUpperLimit(gconv.String(positionId), mode, true) {
+										personMap[positionid] = true
+										m["saleName"] = common.ObjToString(v["name"])
+										cdataNew = append(cdataNew, m)
+									}
+								}
+							}
+						}
+					}
+					//查询是否都有没有离职
+					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"])
+								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
 										}
-										isFreeze = true
-										positionId = 0
-										seatNumber = ""
-										saleName = ""
-										return
 									}
+
+								}
+								//
+								positionId = common.Int64All(data["position_id"])
+								noticePositionId = positionId
+								saleName = common.ObjToString(data["saleName"])
+								seatNumber = common.ObjToString(data["seatNumber"])
+								return
+							}
+						} else {
+							positionId = common.Int64All(data["position_id"])
+							noticePositionId = positionId
+							seatNumber = common.ObjToString(data["seatNumber"])
+							saleName = common.ObjToString(data["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"])
+						if positionId == common.Int64All(v["position_id"]) {
+							if resign == 0 {
+								if FindUpperLimit(gconv.String(positionId), mode, true) {
+									isFreeze = true
+									positionId = 0
+									seatNumber = ""
+									saleName = ""
+									break
 								} else {
-									if FindUpperLimit(gconv.String(positionId), mode, true) {
-										isFreeze = true
-									}
 									saleName = common.ObjToString(v["name"])
+									return
 								}
+
 							}
 						}
 					}
-					if isFreeze {
-						positionId = 0
-						seatNumber = ""
-						saleName = ""
-					}
-					return
 				}
 			}
 		}
@@ -1170,3 +1283,68 @@ func getSeatNumberPositionId(seatNumber string) (positionId int64) {
 	}
 	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("活跃用户处理结束")
+}

+ 1 - 1
clueSync/kc.go

@@ -289,7 +289,7 @@ func kcJob(data map[string]interface{}) int {
 }
 
 func cAutoDraw(entId int) (positionId int64, name string) {
-	query := `SELECT name,position_id FROM dwd_d_crm_department_level_succbi WHERE bi_pcode = (SELECT bi_code FROM dwd_d_crm_department_level_succbi WHERE name = "客户成功组") and resign = 0`
+	query := `SELECT name,position_id FROM dwd_d_crm_department_level_succbi WHERE bi_pcode = (SELECT bi_code FROM dwd_d_crm_department_level_succbi WHERE name = "客户成功组" and resign=0) and resign = 0`
 	data := TiDb.SelectBySql(query)
 	if data != nil && len(*data) > 0 {
 		if entId > 0 {

+ 52 - 44
clueSync/main.go

@@ -1,35 +1,36 @@
 package main
 
 import (
-	"flag"
-	"fmt"
-	"github.com/robfig/cron"
-	"log"
-
 	"app.yhyue.com/moapp/jybase/common"
 	elastic "app.yhyue.com/moapp/jybase/es"
 	"app.yhyue.com/moapp/jybase/mongodb"
 	"app.yhyue.com/moapp/jybase/mysql"
-
 	"app.yhyue.com/moapp/jybase/redis"
+	"bp.jydev.jianyu360.cn/BaseService/pushpkg/p"
+	"flag"
+	"fmt"
+	"github.com/robfig/cron"
+	"log"
 )
 
 var (
-	cfg          = new(Config)
-	db           = new(DB)
-	Mysql        *mysql.Mysql
-	TiDb         *mysql.Mysql
-	TiDbData     *mysql.Mysql
-	TiDbPower    *mysql.Mysql
-	WorkOrder    *mysql.Mysql
-	ThirdParty   *mysql.Mysql
-	Jyactivities *mysql.Mysql
-	Base         *mysql.Mysql
-	Es           elastic.Es
-	Mgo          *mongodb.MongodbSim
-	MgoLog       *mongodb.MongodbSim
-	MgoQyxy      *mongodb.MongodbSim
-	mode         = flag.Int("m", 1, "")
+	cfg                = new(Config)
+	db                 = new(DB)
+	Mysql              *mysql.Mysql
+	TiDb               *mysql.Mysql
+	TiDbData           *mysql.Mysql
+	TiDbPower          *mysql.Mysql
+	WorkOrder          *mysql.Mysql
+	ThirdParty         *mysql.Mysql
+	Jyactivities       *mysql.Mysql
+	Base               *mysql.Mysql
+	BiService          *mysql.Mysql
+	Es                 elastic.Es
+	Mgo                *mongodb.MongodbSim
+	MgoLog             *mongodb.MongodbSim
+	MgoQyxy            *mongodb.MongodbSim
+	mode               = flag.Int("m", 1, "")
+	startTime, endTime = "00:00", "23:59"
 )
 
 func main() {
@@ -110,6 +111,15 @@ func main() {
 		MaxIdleConns: db.BaseService.MaxIdle,
 	}
 	Base.Init()
+	BiService = &mysql.Mysql{
+		Address:      db.BiService.Host + ":" + fmt.Sprint(db.BiService.Port),
+		UserName:     db.BiService.User,
+		PassWord:     db.BiService.Password,
+		DBName:       db.BiService.Database,
+		MaxOpenConns: db.BiService.PollSize,
+		MaxIdleConns: db.BiService.MaxIdle,
+	}
+	BiService.Init()
 	Es = elastic.NewEs(db.Es.Version, db.Es.Address, db.Es.DbSize, db.Es.UserName, db.Es.Password)
 	redis.InitRedis(db.RedisServer)
 	Mgo = mongodb.NewMgo(db.Mgo.Address, db.Mgo.DbName, db.Mgo.DbSize)
@@ -117,30 +127,30 @@ func main() {
 	MgoQyxy = mongodb.NewMgoWithUser(db.MgoQyxy.Address, db.MgoQyxy.DbName, db.MgoQyxy.User, db.MgoQyxy.Password, db.MgoQyxy.DbSize)
 	InitArea()
 	InitProduct(db.ProductArr)
+	//activeUsers() //取关重新关注处理
 	if *mode == 1 {
 		//30分钟一次
-		a := cron.New()
-		a.AddFunc(db.CornExp1, func() {
+		go p.VarTimeTask.RunInTimeLoop("30分钟定时任务", "", "", db.CornExp1, true, true, nil, func() {
 			orders()      //未支付订单
 			messageSync() //聊天记录进线索
 			userbase()    //新绑定手机号进线索
 		})
-		a.Start()
 		//5分钟一次
-		b := cron.New()
-		b.AddFunc(db.CornExp2, func() {
+
+		go p.VarTimeTask.RunInTimeSection("5分钟定时任务1", db.CornExp2Start, db.CornExp2End, db.CornExp2, func(dayFirst bool) {
 			users()          //新注册用户进线索
 			saleLeads()      //留资进线索
 			eventReg()       //渠道
 			bigCustomer()    //大客户线索
 			marketCustomer() //市场部线索
+			rebind()         //取关重新关注处理
 		})
-		b.Start()
 		//每天8点30
 		c := cron.New()
 		c.AddFunc(db.CornExp3, func() {
-			users()     //新注册用户进线索
-			saleLeads() //留资进线索
+			users()       //新注册用户进线索
+			saleLeads()   //留资进线索
+			activeUsers() //活跃用户处理
 		})
 		c.Start()
 		// 一天一次
@@ -152,24 +162,24 @@ func main() {
 		d.Start()
 		// 5分钟一次
 		go ordersClue() //后台订单进线索
-		e := cron.New()
-		e.AddFunc(db.CornExp5, func() {
-			go everythingSync() //渠道
-			go ordersClue()     //后台订单进线索
-			go kcSync()         //移交客成
-			go kcAuto()         //客成自动加入任务车
-			go tagAddSync()     //用户标签增量
-			go autoExitSea()    //自动退海
-			go Thaw()           //自动解冻处理
+		go p.VarTimeTask.RunInTimeLoop("5分钟定时任务2", "", "", db.CornExp5, true, true, nil, func() {
+			//go p.VarTimeTask.RunInTimeSection("5分钟定时任务2", startTime, endTime, db.CornExp5, func(dayFirst bool) {
+			everythingSync()   //渠道
+			ordersClue()       //后台订单进线索
+			kcSync()           //移交客成
+			kcAuto()           //客成自动加入任务车
+			tagAddSync()       //用户标签增量
+			autoExitSea()      //自动退海
+			Thaw()             //自动解冻处理
+			subscribeAddSync() //订阅增量
+			rderAcceptance()   //工单生成
 		})
-		e.Start()
 		//5分钟一次
-		f := cron.New()
-		f.AddFunc(db.CornExp6, func() {
+		go p.VarTimeTask.RunInTimeLoop("5分钟定时任务3", "", "", db.CornExp6, true, true, nil, func() {
+			//go p.VarTimeTask.RunInTimeSection("5分钟定时任务3", startTime, endTime, db.CornExp6, func(dayFirst bool) {
 			subscribeAddSync() //订阅增量
 			rderAcceptance()   //工单生成
 		})
-		f.Start()
 		//自动进入任务车 1天一次
 		g := cron.New()
 		g.AddFunc(db.CornExp7, func() {
@@ -177,10 +187,8 @@ func main() {
 			refundAuto() //客成移交销售
 			autoTask()   //超时未跟进加入任务车
 			autoTasks()  //按照下次跟进时间提前一天加入任务车
-
 		})
 		g.Start()
-
 		log.Println("个人邮件告警查询开始")
 		WarningPerl() // 个人
 		log.Println("部门邮件告警查询开始")

+ 7 - 7
doFreeClueSign/job/job.go

@@ -11,11 +11,11 @@ import (
 // LoadActivityUser 加载新活跃用户
 func (jm *JobManager) LoadActivityUser() {
 	var (
-		//runNow = time.Now()
-		ctx = context.TODO()
+		runNow = time.Now()
+		ctx    = context.TODO()
 	)
-	start, _ := time.Parse(time.DateTime, jm.lastRun.NewActivity)
-	val, end := public.GetNewActiveUser(start)
+	start, _ := time.ParseInLocation(time.DateTime, jm.lastRun.NewActivity, time.Local)
+	val := public.GetNewActiveUser(start, runNow)
 	if len(val) > 0 {
 		for i, msg := range val {
 			if i%10 == 0 {
@@ -27,7 +27,7 @@ func (jm *JobManager) LoadActivityUser() {
 		}
 	}
 	//更新
-	jm.lastRun.NewActivity = end.Format(time.DateTime)
+	jm.lastRun.NewActivity = runNow.Format(time.DateTime)
 	if err := jm.SaveLastRun(); err != nil {
 		g.Log().Errorf(ctx, "LoadActivityUser error %v", err)
 	}
@@ -39,7 +39,7 @@ func (jm *JobManager) LoadBindPhoneUser() {
 		runNow = time.Now()
 		ctx    = context.TODO()
 	)
-	start, _ := time.Parse(time.DateTime, jm.lastRun.BindPhone)
+	start, _ := time.ParseInLocation(time.DateTime, jm.lastRun.BindPhone, time.Local)
 	val := public.GetBidPhoneUser(start, runNow)
 	if len(val) > 0 {
 		for i, msg := range val {
@@ -64,7 +64,7 @@ func (jm *JobManager) LoadAgainSubUser() {
 		runNow = time.Now()
 		ctx    = context.TODO()
 	)
-	start, _ := time.Parse(time.DateTime, jm.lastRun.AgainSub)
+	start, _ := time.ParseInLocation(time.DateTime, jm.lastRun.AgainSub, time.Local)
 	val := public.GetAgainSubUser(start, runNow)
 	if len(val) > 0 {
 		for i, msg := range val {

+ 2 - 2
doFreeClueSign/job/mamager.go

@@ -56,7 +56,7 @@ func InitJobManager() *JobManager {
 
 			job.LoadPayUser()
 			job.LoadAgainSubUser()
-			job.LoadBindPhoneUser()
+			//job.LoadBindPhoneUser()
 		}, "bindPhoneAndSubAgain")
 		if err != nil {
 			panic(err)
@@ -138,7 +138,7 @@ func (jm *JobManager) FilterPayUserAndSaveDb(ctx context.Context, value interfac
 			return nil
 		}
 		operationTime = time.Unix(msg.TimeStamp, 0).Format(time.DateTime)
-		sql += `(mogUserId,register_time,phone,bind_phone_date,create_time)VALUES (?,?,?,?,?)ON DUPLICATE KEY UPDATE phone=?, bind_phone_date=?`
+		sql += `(mogUserId,register_time,bind_phone_date,create_time)VALUES (?,?,?,?,?)ON DUPLICATE KEY UPDATE bind_phone_date=?`
 		val = append(val, msg.MgoUserID, jm.GetAndCacheRegisterDate(msg.MgoUserID), msg.Phone, operationTime, now, msg.Phone, operationTime)
 	} else if msg, ok := value.(*public.NewActiveMsg); ok {
 		if jm.payUser.Contains(msg.MgoUserID) {

Some files were not shown because too many files changed in this diff