소스 검색

Merge branch 'dev1.1' of http://192.168.3.207:8080/dataservice/datatools into dev1.1

zhangxinlei1996 2 년 전
부모
커밋
260cacc2a8
11개의 변경된 파일534개의 추가작업 그리고 73개의 파일을 삭제
  1. 52 8
      clueSync/autoTask.go
  2. 16 0
      clueSync/config.go
  3. 64 1
      clueSync/config.json
  4. 5 0
      clueSync/go.mod
  5. 13 0
      clueSync/go.sum
  6. 153 50
      clueSync/job.go
  7. 73 0
      clueSync/log.go
  8. 6 2
      clueSync/main.go
  9. 88 0
      clueSync/trailContent.go
  10. 8 0
      telemarketingEtl/config/config.go
  11. 56 12
      telemarketingEtl/entity/dwd_f_crm_open_sea.go

+ 52 - 8
clueSync/autoTask.go

@@ -12,11 +12,51 @@ func autoTask() {
 	log.Println("超时未跟进定时任务开始")
 	t := time.Now()
 	nowTime := time.Now().Format(date.Date_Full_Layout)
-	for trailstatus, nexttime := range map[string]interface{}{
-		"07": t.AddDate(0, 0, -5), //待签署客户
-		"06": t.AddDate(0, 0, -3), //高意向客户
-		"05": t.AddDate(0, 0, -5), //意向客户
-		"04": t.AddDate(0, 0, -7), //潜在客户
+	statusMap := map[string]int{
+		"07": 5, //待签署客户
+		"06": 3, //高意向客户
+		"05": 5, //意向客户
+		"04": 7, //潜在客户
+	}
+	//判断节假日
+	for status, statusInt := range statusMap {
+		count, counts := 0, 0
+		for {
+			count++
+			currentTime := t.AddDate(0, 0, -count)
+			currentTime.Format(date.Date_Short_Layout)
+			if currentTime.Weekday() == time.Sunday || 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 {
+					counts++
+				}
+			} else {
+				isok := true
+				for k, v := range DateMap {
+					if currentTime.Format(date.Date_Short_Layout) == k && v == 1 {
+						isok = false
+					}
+				}
+				if isok {
+					counts++
+				}
+			}
+			if counts >= statusInt {
+				break
+			}
+		}
+		statusMap[status] = counts
+	}
+	for trailstatus, _ := range map[string]string{
+		"07": "", //待签署客户
+		"06": "", //高意向客户
+		"05": "", //意向客户
+		"04": "", //潜在客户
 	} {
 		sql := `SELECT a.clue_id,a.position_id,a.seatNumber,a.out_task_status FROM dwd_f_crm_private_sea a 
 				LEFT JOIN dwd_f_crm_clue_info b ON a.clue_id=b.id 
@@ -24,7 +64,7 @@ func autoTask() {
 		argsSelect := []interface{}{trailstatus}
 		intime := ""
 		sql += " AND a.comeintime <?"
-		nt, _ := nexttime.(time.Time)
+		nt := t.AddDate(0, 0, -statusMap[trailstatus])
 		intime = nt.Format(date.Date_Short_Layout) + " 00:00:00"
 		argsSelect = append(argsSelect, intime)
 		log.Println(sql)
@@ -37,14 +77,18 @@ func autoTask() {
 				out_task_status := common.IntAll(v["out_task_status"])
 				args2 := []interface{}{clueId}
 				//获取跟进内容
-				sql1 := `select COUNT(1) FROM dwd_f_crm_trail_content WHERE clue_id =?;`
+				// sql1 := `select COUNT(1) FROM dwd_f_crm_trail_content WHERE clue_id =?;`
 				sql2 := `SELECT COUNT(1) FROM dwd_f_crm_trail_content WHERE clue_id =? `
 				if intime != "" {
 					sql2 += ` and createtime > ?`
 					args2 = append(args2, intime)
 				}
 				//保留未跟进线索
-				if c1, c2 := TiDb.CountBySql(sql1, clueId), TiDb.CountBySql(sql2, args2...); (c1 != 0 && c2 > 0) || out_task_status == 1 {
+				// if c1, c2 := TiDb.CountBySql(sql1, clueId), TiDb.CountBySql(sql2, args2...); (c1 != 0 && c2 > 0) || out_task_status == 1 {
+				// 	log.Println("不满足线索过滤", clueId)
+				// 	continue
+				// }
+				if c2 := TiDb.CountBySql(sql2, args2...); c2 > 0 || out_task_status == 1 {
 					log.Println("不满足线索过滤", clueId)
 					continue
 				}

+ 16 - 0
clueSync/config.go

@@ -21,7 +21,9 @@ type (
 		LastOrderTime   string `json:"lastOrderTime"`
 		LastUserTime    string `json:"lastUserTime"`
 		LastSubscribeId string `json:"lastSubscribeId"`
+		XlsxNum         string `json:"xlsxNum"`
 		CountLimit      int64  `json:"countLimit"`
+		RedisServer     string `json:"redisServer"`
 		TiDb            struct {
 			Host        string `json:"host"`
 			Port        int    `json:"port"`
@@ -73,6 +75,8 @@ type (
 
 var AreaCode = map[string]string{}
 var CodeArea = map[string]string{}
+var CodeTrail = map[string]string{}
+var DateMap = map[string]int{}
 
 func InitArea() {
 	info := TiDb.Find("d_area_code", nil, "", "", -1, -1)
@@ -84,4 +88,16 @@ func InitArea() {
 	}
 	log.Println("AreaCodeLen ", len(AreaCode))
 	log.Println("CodeAreaLen ", len(CodeArea))
+	trailData := TiDb.Find("dwd_d_crm_trailstatus_code", nil, "", "", -1, -1)
+	if trailData != nil && len(*trailData) > 0 {
+		for _, m := range *trailData {
+			CodeTrail[common.ObjToString(m["code"])] = common.ObjToString(m["name"])
+		}
+	}
+	holidayRecords := TiDb.Find("holiday_records", nil, "", "", -1, -1)
+	if holidayRecords != nil && len(*holidayRecords) > 0 {
+		for _, m := range *holidayRecords {
+			DateMap[common.ObjToString(m["date"])] = common.IntAll(m["change"])
+		}
+	}
 }

+ 64 - 1
clueSync/config.json

@@ -1 +1,64 @@
-{"cornexp1":"0 */30 * * * ?","cornexp2":"0 */10 * * * ?","cornexp3":"0 */5 * * * ?","cornexp4":"0 0 0 */1 * ? ","cornexp5":"0 */5 * * * ?","cornexp6":"0 */10 * * * ?","cornexp7":"","lastOrderId":172508,"lastUserId":"644101e58b6d74a60a09aec7","lastId":"6440faf7bd4ea1862af84c56","lastOrderTime":"2023-04-25 00:00:00","lastUserTime":"2023-04-25 00:00:00","lastSubscribeId":"64473e36c572141d78ec7a03","countLimit":1000,"tiDb":{"host":"192.168.3.149","port":4000,"database":"jianyu_subjectdb_test","user":"root","password":"Tibi#20211222","poolsize":20,"maxidle":40,"maxleft":40},"baseService":{"host":"192.168.3.217","port":4000,"database":"base_service","user":"root","password":"=PDT49#80Z!RVv52_z","poolsize":20,"maxidle":40,"maxleft":40},"mysql":{"host":"192.168.3.149","port":3306,"database":"jianyu","user":"root","password":"Topnet123","poolsize":20,"maxidle":40,"maxleft":40},"mgo":{"address":"192.168.3.206:27080","dbName":"qfw","dbSize":20},"mgoLog":{"address":"192.168.3.206:27090","dbName":"qfw","dbSize":20,"user":"admin","password":"123456"},"es":{"address":"http://192.168.3.206:9800","dbSize":20}}
+{
+	"cornexp1": "0 */30 * * * ?",
+	"cornexp2": "0 */10 * * * ?",
+	"cornexp3": "0 */5 * * * ?",
+	"cornexp4": "0 0 0 */1 * ? ",
+	"cornexp5": "0 */5 * * * ?",
+	"cornexp6": "0 */10 * * * ?",
+	"cornexp7": "0 */10 * * * ?",
+	"lastOrderId": 172508,
+	"lastUserId": "644101e58b6d74a60a09aec7",
+	"lastId": "6440faf7bd4ea1862af84c56",
+	"lastOrderTime": "2023-04-25 00:00:00",
+	"lastUserTime": "2023-04-25 00:00:00",
+	"lastSubscribeId": "64473e36c572141d78ec7a03",
+	"countLimit": 1000,
+	"xlsxNum": "1",
+	"redisServer":"192.168.3.206:1712",
+	"tiDb": {
+		"host": "192.168.3.217",
+		"port": 4000,
+		"database": "jianyu_subjectdb_test",
+		"user": "root",
+		"password": "=PDT49#80Z!RVv52_z",
+		"poolsize": 20,
+		"maxidle": 40,
+		"maxleft": 40
+	},
+	"baseService": {
+		"host": "192.168.3.217",
+		"port": 4000,
+		"database": "base_service",
+		"user": "root",
+		"password": "=PDT49#80Z!RVv52_z",
+		"poolsize": 20,
+		"maxidle": 40,
+		"maxleft": 40
+	},
+	"mysql": {
+		"host": "192.168.3.149",
+		"port": 3306,
+		"database": "jianyu",
+		"user": "root",
+		"password": "Topnet123",
+		"poolsize": 20,
+		"maxidle": 40,
+		"maxleft": 40
+	},
+	"mgo": {
+		"address": "192.168.3.206:27080",
+		"dbName": "qfw",
+		"dbSize": 20
+	},
+	"mgoLog": {
+		"address": "192.168.3.206:27090",
+		"dbName": "qfw",
+		"dbSize": 20,
+		"user": "admin",
+		"password": "123456"
+	},
+	"es": {
+		"address": "http://192.168.3.206:9800",
+		"dbSize": 20
+	}
+}

+ 5 - 0
clueSync/go.mod

@@ -5,6 +5,11 @@ go 1.14
 require (
 	app.yhyue.com/moapp/jybase v0.0.0-20230405040249-a36a23595798
 	app.yhyue.com/zhp/util v0.0.0-20211207072713-d9f1393203de
+	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
+	github.com/go-xweb/xweb v0.2.1
 	github.com/nsqio/go-nsq v1.1.0
 	github.com/robfig/cron v1.2.0
+	github.com/tealeg/xlsx v1.0.5
 )

+ 13 - 0
clueSync/go.sum

@@ -121,6 +121,7 @@ github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHqu
 github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
+github.com/garyburd/redigo v1.6.2 h1:yE/pwKCrbLpLpQICzYTeZ7JsTA/C53wFTJHaEtRqniM=
 github.com/garyburd/redigo v1.6.2/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
 github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
 github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
@@ -152,6 +153,14 @@ github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LB
 github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
+github.com/go-xweb/httpsession v0.0.0-20141220075701-356d3b4d38d6 h1:DUiWdm3rS8cC96Y0XeVkDeizzEK6X+qiNgXytLVtbkM=
+github.com/go-xweb/httpsession v0.0.0-20141220075701-356d3b4d38d6/go.mod h1:lwPk13GS+i/NK4FkMm68IcJrAwiu+HtjYa1Y4kW59aY=
+github.com/go-xweb/log v0.0.0-20140701090824-270d183ad77e h1:xmffs7hgrWpAOcquZrdlWpAEaAdlI9myaYcUUmhIP7k=
+github.com/go-xweb/log v0.0.0-20140701090824-270d183ad77e/go.mod h1:ASmYUSBf32lWkkNVX/pnOU4MLuUQpFH4qYHvWHt/l0w=
+github.com/go-xweb/uuid v0.0.0-20140604020037-d7dce341f851 h1:D46USD6oGNWzoJ/h5CWaFq3ELLoLoJzllJ03Xh78VYg=
+github.com/go-xweb/uuid v0.0.0-20140604020037-d7dce341f851/go.mod h1:OmDEC58ZYO1Esk+Uy32SB6LWof9lyROl7q76dBFOCWw=
+github.com/go-xweb/xweb v0.2.1 h1:u5t/ttuSfxiIMDTXj/Pouw9C2ASNABWT16JWHyrtdvY=
+github.com/go-xweb/xweb v0.2.1/go.mod h1:vPjYJgfidYAgBKIwiAyKFC1hfczlqsw9rRT8LtwrGew=
 github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
 github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
 github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
@@ -189,6 +198,7 @@ github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
 github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
 github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/gomodule/redigo v1.8.9 h1:Sl3u+2BI/kk+VEatbj0scLdrFhjPmbxOc1myhDP41ws=
 github.com/gomodule/redigo v1.8.9/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE=
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@@ -240,6 +250,7 @@ github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplb
 github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/howeyc/fsnotify v0.9.0 h1:0gtV5JmOKH4A8SsFxG2BczSeXWWPvcMT0euZt5gDAxY=
 github.com/howeyc/fsnotify v0.9.0/go.mod h1:41HzSPxBGeFRQKEEwgh49TRw/nKBsYZ2cF1OzPjSJsA=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
@@ -404,6 +415,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
 github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
 github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
 github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/tealeg/xlsx v1.0.5 h1:+f8oFmvY8Gw1iUXzPk+kz+4GpbDZPK1FhPiQRd+ypgE=
+github.com/tealeg/xlsx v1.0.5/go.mod h1:btRS8dz54TDnvKNosuAqxrM1QgN1udgk9O34bDCnORM=
 github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
 github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
 github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=

+ 153 - 50
clueSync/job.go

@@ -7,6 +7,8 @@ import (
 	"strings"
 	"time"
 
+	"app.yhyue.com/moapp/jybase/redis"
+
 	"app.yhyue.com/moapp/jybase/common"
 	"app.yhyue.com/moapp/jybase/mongodb"
 )
@@ -21,14 +23,19 @@ func orders() {
 	sql := fmt.Sprintf(`select * from dataexport_order where order_status = 0 and product_type in ("大会员","VIP订阅","数据流量包","历史数据") and 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 k, v := range *data {
-			FormatData(v, "orders")
-			if k == len(*data)-1 {
-				lastOrderId = common.IntAll(v["id"])
+		for _, v := range *data {
+			// FormatData(v, "orders")
+			// if k == len(*data)-1 {
+			// 	lastOrderId = common.IntAll(v["id"])
+			// }
+			ok1, _ := FormatData(v, "orders")
+			if !ok1 {
+				common.WriteSysConfig(&cfg)
+				break
 			}
+			cfg.LastOrderId = common.IntAll(v["id"])
 		}
 	}
-	cfg.LastOrderId = lastOrderId
 	common.WriteSysConfig(&cfg)
 	log.Println("未支付订单定时任务结束")
 }
@@ -90,8 +97,13 @@ func saleLeads() {
 		if !iter.Next(&thisData) {
 			break
 		}
+		ok1, _ := FormatData(thisData, "saleLeads")
+		if !ok1 {
+			common.WriteSysConfig(&cfg)
+			break
+		}
 		cfg.LastId = mongodb.BsonIdToSId(thisData["_id"])
-		FormatData(thisData, "saleLeads")
+		// FormatData(thisData, "saleLeads")
 	}
 	common.WriteSysConfig(&cfg)
 	log.Println("用户留资定时任务结束")
@@ -162,9 +174,22 @@ func FormatData(data map[string]interface{}, item string) (bool, bool) {
 	}
 	//域外用户和内部用户和没有手机号,不存线索
 	if source == 5 || source == 6 || phone == "" {
+		log.Println("线索分配失败,线索过滤!!", item, source, phone, userId)
 		return true, false
 	}
 	if uId == "" {
+		if isExists, _ := redis.Exists("bidx", "bidx_userId_"+userId); isExists {
+			redisInt := redis.GetInt("bidx", "bidx_userId_"+userId)
+			if redisInt > 2 {
+				log.Println("线索分配失败,线索缺少信息,任务已执行超过3次", item, userId, phone)
+				return true, true
+			} else {
+				redis.Incr("bidx", "bidx_userId_"+userId)
+			}
+		} else {
+			redis.Put("bidx", "bidx_userId_"+userId, 1, 3600)
+		}
+		log.Println("线索分配失败,线索缺少信息", item, phone, userId)
 		return false, false
 	}
 	//不是留资的要查一遍留资
@@ -189,31 +214,44 @@ func FormatData(data map[string]interface{}, item string) (bool, bool) {
 	//follow_project_area --> follow_project_monitor
 	follow_project_area = getAreaCode(userId)
 	//seatNumber position_id
-	//自动分配规则暂不确定
 	log.Println("data +++", top_cluetype, sub_cluetype, level, follow_project_area)
+	if top_cluetype == "" || sub_cluetype == "" || level == "" {
+		log.Println("线索分配失败,线索过滤top_cluetype!!", item, uId, phone, userId)
+		return true, true
+	}
 	position_id, seatNumber, saleName, saleData := autoDraw(level)
 	log.Println("data -------", position_id, seatNumber, saleName)
 	if position_id > 0 && seatNumber != "" {
 		if TiDb.Count("dwd_f_crm_private_sea", map[string]interface{}{"position_id": position_id}) >= cfg.CountLimit {
-			return true, false
+			log.Println("线索分配失败,私海线索数据超过限制", item, position_id, seatNumber, uId, userId, phone)
+			TiDb.UpdateOrDeleteBySql(`update dwd_f_crm_clue_autodraw_record set count = count + 1 where seatNumber = ? and clue_level = ?`, seatNumber, level)
+			return false, false
+			// position_id, seatNumber, saleName, saleData = autoDraw(level)
 		}
-		uCount := TiDb.FindOne("dwd_f_crm_clue_info", map[string]interface{}{"uid": uId}, "", "")
+		uCount, oks := TiDb.FindOne("dwd_f_crm_clue_info", map[string]interface{}{"uid": uId}, "", ""), true
 		if uCount != nil && len(*uCount) > 0 {
-			UpdateClue(*uCount, saleData, item, userId, uId, top_cluetype, sub_cluetype, topname, subname, cluename, name, saleName, phone, position, department, industry, follow_project_area, role, seatNumber, position_id)
+			oks = UpdateClue(*uCount, saleData, item, userId, uId, top_cluetype, sub_cluetype, topname, subname, cluename, name, saleName, phone, position, department, industry, follow_project_area, role, seatNumber, position_id)
+		} else {
+			oks = SaveClue(item, userId, uId, top_cluetype, sub_cluetype, topname, subname, cluename, name, saleName, phone, position, department, industry, follow_project_area, role, seatNumber, position_id)
+		}
+		if oks {
+			TiDb.UpdateOrDeleteBySql(`update dwd_f_crm_clue_autodraw_record set count = count + 1 where seatNumber = ? and clue_level = ?`, seatNumber, level)
 		} else {
-			SaveClue(item, userId, uId, top_cluetype, sub_cluetype, topname, subname, cluename, name, saleName, phone, position, department, industry, follow_project_area, role, seatNumber, position_id)
+			log.Println("线索分配失败!!", item, position_id, seatNumber, uId, userId, phone)
+			return false, false
 		}
 	}
 	return true, true
 }
 
-func SaveClue(item, userId, uId, top_cluetype, sub_cluetype, topname, subname, cluename, name, saleName, phone, position, department, industry, follow_project_area, role, seatNumber string, positionId int64) {
+func SaveClue(item, userId, uId, top_cluetype, sub_cluetype, topname, subname, cluename, name, saleName, phone, position, department, industry, follow_project_area, role, seatNumber string, positionId int64) bool {
 	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, seaId, uodateId1, uodateId2, uodateId3, uodateId4 := int64(0), int64(0), int64(0), int64(0), int64(0), int64(0)
 	// BCPCID := common.GetRandom(32)
-	TiDb.ExecTx("保存线索", func(tx *sql.Tx) bool {
+	if TiDb.ExecTx("保存线索", func(tx *sql.Tx) bool {
 		//线索
-		clueId := TiDb.InsertByTx(tx, "dwd_f_crm_clue_info", map[string]interface{}{
+		clueId = TiDb.InsertByTx(tx, "dwd_f_crm_clue_info", map[string]interface{}{
 			"userid":              userId,
 			"uid":                 uId,
 			"seatNumber":          seatNumber,
@@ -235,7 +273,7 @@ func SaveClue(item, userId, uId, top_cluetype, sub_cluetype, topname, subname, c
 			"role":                role,
 		})
 		//私海 --> 任务车
-		seaId := TiDb.InsertByTx(tx, "dwd_f_crm_private_sea", map[string]interface{}{
+		seaId = TiDb.InsertByTx(tx, "dwd_f_crm_private_sea", map[string]interface{}{
 			"clue_id":      clueId,
 			"seatNumber":   seatNumber,
 			"position_id":  positionId,
@@ -248,7 +286,7 @@ func SaveClue(item, userId, uId, top_cluetype, sub_cluetype, topname, subname, c
 			"tasksource":   "线索自动分配" + "-" + topname + "-" + subname,
 		})
 		//变更记录
-		uodateId1 := TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
+		uodateId1 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
 			"clue_id":     clueId,
 			"position_id": positionId,
 			"change_type": "创建线索",
@@ -257,7 +295,7 @@ func SaveClue(item, userId, uId, top_cluetype, sub_cluetype, topname, subname, c
 			"BCPCID":      common.GetRandom(32),
 			"operator_id": -1,
 		})
-		uodateId2 := TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
+		uodateId2 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
 			"clue_id":      clueId,
 			"position_id":  positionId,
 			"change_field": "position_id",
@@ -268,7 +306,7 @@ func SaveClue(item, userId, uId, top_cluetype, sub_cluetype, topname, subname, c
 			"BCPCID":       common.GetRandom(32),
 			"operator_id":  -1,
 		})
-		uodateId3 := TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
+		uodateId3 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
 			"clue_id":      clueId,
 			"position_id":  positionId,
 			"change_field": "trailstatus",
@@ -279,7 +317,7 @@ func SaveClue(item, userId, uId, top_cluetype, sub_cluetype, topname, subname, c
 			"BCPCID":       common.GetRandom(32),
 			"operator_id":  -1,
 		})
-		uodateId4 := TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
+		uodateId4 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
 			"clue_id":     clueId,
 			"position_id": positionId,
 			"change_type": "加入任务车",
@@ -288,11 +326,17 @@ func SaveClue(item, userId, uId, top_cluetype, sub_cluetype, topname, subname, c
 			"BCPCID":      common.GetRandom(32),
 			"operator_id": -1,
 		})
-		return clueId > 0 && seaId > 0 && uodateId1 > 0 && uodateId2 > 0 && uodateId3 > 0 && uodateId4 > 0
-	})
+		return clueId > -1 && seaId > -1 && uodateId1 > -1 && uodateId2 > -1 && uodateId3 > -1 && uodateId4 > -1
+	}) {
+		log.Println("线索分配成功")
+		return true
+	} else {
+		log.Println("线索分配失败!!!", clueId, seaId, uodateId1, uodateId2, uodateId3, uodateId4, " 用户信息 ", item, position, seatNumber, uId, userId, phone)
+		return false
+	}
 }
 
-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, industry, follow_project_area, role, seatNumber string, positionId int64) {
+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, industry, follow_project_area, role, seatNumber string, positionId int64) bool {
 	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 = 无意向 为变更线索状态
@@ -301,6 +345,7 @@ func UpdateClue(data map[string]interface{}, saleData []map[string]interface{},
 	clueId := common.Int64All(data["id"])
 	is_assign := common.IntAll(data["is_assign"])
 	oldsaleName, oldTaskTime, taskTime, is_task, taskstatus := "", "", "", 0, 0
+	old_position_id, old_seatNumber, old_trailstatus := common.Int64All(data["position_id"]), common.ObjToString(data["seatNumber"]), common.ObjToString(data["trailstatus"])
 	//已在任务车的判断任务时间
 	privateData := TiDb.FindOne("dwd_f_crm_private_sea", map[string]interface{}{"clue_id": clueId}, "", "")
 	if privateData != nil && len(*privateData) > 0 {
@@ -357,10 +402,12 @@ func UpdateClue(data map[string]interface{}, saleData []map[string]interface{},
 		clueUpdateData["role"] = role
 		clueUpdateData["cluename"] = cluename
 	}
-	if trailstatus == "00" || trailstatus == "01" {
+	if trailstatus == "00" || trailstatus == "01" || old_position_id == 0 {
 		clueUpdateData["seatNumber"] = seatNumber
 		clueUpdateData["position_id"] = positionId
-		clueUpdateData["trailstatus"] = "01"
+		if trailstatus == "00" || trailstatus == "01" {
+			clueUpdateData["trailstatus"] = "01"
+		}
 		seaUpdateData["seatNumber"] = seatNumber
 		seaUpdateData["position_id"] = positionId
 		insertSeaData["seatNumber"] = seatNumber
@@ -371,30 +418,31 @@ func UpdateClue(data map[string]interface{}, saleData []map[string]interface{},
 			}
 		}
 	} else {
-		insertSeaData["seatNumber"] = common.ObjToString(data["seatNumber"])
-		insertSeaData["position_id"] = common.Int64All(data["position_id"])
+		insertSeaData["seatNumber"] = old_seatNumber
+		insertSeaData["position_id"] = old_position_id
 	}
+	ok, ok1, ok2, seaId := true, true, true, int64(0)
+	updateId1, updateId2, updateId3, updateId4, updateId5 := int64(0), int64(0), int64(0), int64(0), int64(0)
+	updateId6, updateId7, updateId8, updateId9, updateId10 := int64(0), int64(0), int64(0), int64(0), int64(0)
+	updateId11, updateId12, updateId13 := int64(0), int64(0), int64(0)
 	if TiDb.ExecTx("更新线索", func(tx *sql.Tx) bool {
 		//线索
-		ok := TiDb.UpdateByTx(tx, "dwd_f_crm_clue_info", map[string]interface{}{"uid": uId}, clueUpdateData)
-		ok1, seaId := false, int64(0)
+		ok = TiDb.UpdateByTx(tx, "dwd_f_crm_clue_info", map[string]interface{}{"uid": uId}, clueUpdateData)
 		if is_assign == 1 {
 			ok1 = TiDb.UpdateByTx(tx, "dwd_f_crm_private_sea", map[string]interface{}{"clue_id": clueId}, seaUpdateData)
 		} else {
+			ok2 = TiDb.Delete("dwd_f_crm_open_sea", map[string]interface{}{"clue_id": clueId})
 			seaId = TiDb.InsertByTx(tx, "dwd_f_crm_private_sea", insertSeaData)
 		}
-		updateId1, updateId2, updateId3, updateId4, updateId5 := int64(0), int64(0), int64(0), int64(0), int64(0)
-		updateId6, updateId7, updateId8, updateId9, updateId10 := int64(0), int64(0), int64(0), int64(0), int64(0)
-		updateId11, updateId12, updateId13 := int64(0), int64(0), int64(0)
 		//变更记录
-		if trailstatus == "00" || trailstatus == "01" {
+		if trailstatus == "00" || trailstatus == "01" || old_position_id == 0 {
 			updateId1 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
 				"clue_id":      clueId,
 				"position_id":  positionId,
 				"change_field": "position_id",
 				"change_type":  "所属人变更",
-				"old_value":    oldsaleName,
-				"new_value":    saleName,
+				"old_value":    common.If(oldsaleName != "", oldsaleName, "/"),
+				"new_value":    common.If(saleName != "", saleName, "/"),
 				"createtime":   nowTime,
 				"BCPCID":       common.GetRandom(32),
 				"operator_id":  -1,
@@ -433,18 +481,32 @@ func UpdateClue(data map[string]interface{}, saleData []map[string]interface{},
 					"BCPCID":       common.GetRandom(32),
 					"operator_id":  -1,
 				})
-			} else {
-				updateId2 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
+			} else if old_position_id == 0 {
+				updateId3 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
 					"clue_id":      clueId,
-					"position_id":  common.Int64All(data["position_id"]),
+					"position_id":  positionId,
 					"change_field": "trailstatus",
 					"change_type":  "基本信息变更",
-					"old_value":    "商机线索",
-					"new_value":    "流失",
+					"old_value":    CodeTrail[old_trailstatus],
+					"new_value":    "新增",
 					"createtime":   nowTime,
 					"BCPCID":       common.GetRandom(32),
 					"operator_id":  -1,
 				})
+			} else {
+				if common.Int64All(data["position_id"]) > 0 {
+					updateId2 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
+						"clue_id":      clueId,
+						"position_id":  common.Int64All(data["position_id"]),
+						"change_field": "trailstatus",
+						"change_type":  "基本信息变更",
+						"old_value":    "商机线索",
+						"new_value":    "流失",
+						"createtime":   nowTime,
+						"BCPCID":       common.GetRandom(32),
+						"operator_id":  -1,
+					})
+				}
 				updateId3 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
 					"clue_id":      clueId,
 					"position_id":  positionId,
@@ -618,6 +680,10 @@ func UpdateClue(data map[string]interface{}, saleData []map[string]interface{},
 				"baseinfo_id": uId,
 			})
 		}
+		return true
+	} else {
+		log.Println("线索更新失败!!!", ok, ok1, ok2, seaId, updateId1, updateId2, updateId3, updateId4, updateId5, updateId6, updateId7, updateId8, updateId9, updateId10, updateId11, updateId12, updateId13, " 用户信息 ", item, position, seatNumber, uId, userId, phone)
+		return false
 	}
 }
 
@@ -705,9 +771,11 @@ func getClueType(item string, data map[string]interface{}) (pcode, code, level,
 
 // 获取自动分配的人
 func autoDraw(mode string) (positionId int64, seatNumber, saleName string, saleData []map[string]interface{}) {
-	query := `select * from jy_salesperson_info where status = 0 and position != 0`
+	query := `select * from jy_salesperson_info where`
 	if mode == "A" || mode == "B" {
-		query += ` and is_complete = 1`
+		query += ` is_complete = 1`
+	} else {
+		query += ` is_complete = 1 or is_complete = 0`
 	}
 	data := TiDb.SelectBySql(query)
 	if data != nil && len(*data) > 0 {
@@ -720,6 +788,11 @@ func autoDraw(mode string) (positionId int64, seatNumber, saleName string, saleD
 				isOk := false
 				for _, vv := range *countData {
 					if common.ObjToString(v["seatNumber"]) == common.ObjToString(vv["seatNumber"]) {
+						if common.IntAll(v["status"]) == 0 {
+							vv["status"] = 1
+						} else {
+							vv["status"] = 2
+						}
 						isOk = true
 					}
 				}
@@ -738,18 +811,48 @@ func autoDraw(mode string) (positionId int64, seatNumber, saleName string, saleD
 			}
 			if seatNumber == "" {
 				res := int64(0)
-				for k, v := range *countData {
-					if k == 0 {
-						res = common.Int64All(v["count"])
-						seatNumber = common.ObjToString(v["seatNumber"])
-					} else {
-						if common.Int64All(v["count"]) <= res {
+				countres := 0
+				for _, v := range *countData {
+					if common.IntAll(v["status"]) == 1 {
+						if countres == 0 {
 							res = common.Int64All(v["count"])
 							seatNumber = common.ObjToString(v["seatNumber"])
+						} else {
+							if common.Int64All(v["count"]) <= res {
+								res = common.Int64All(v["count"])
+								seatNumber = common.ObjToString(v["seatNumber"])
+							}
 						}
+						countres++
 					}
+					// if k == 0 {
+					// 	res = common.Int64All(v["count"])
+					// 	seatNumber = common.ObjToString(v["seatNumber"])
+					// } else {
+					// 	if common.Int64All(v["count"]) <= res {
+					// 		res = common.Int64All(v["count"])
+					// 		seatNumber = common.ObjToString(v["seatNumber"])
+					// 	}
+					// }
 				}
 			}
+		} else {
+			seatNumber = common.ObjToString((*data)[0]["seatNumber"])
+			saleName = common.ObjToString((*data)[0]["name"])
+			rData := TiDb.FindOne("dwd_f_crm_clue_autodraw_record", map[string]interface{}{"clue_level": mode}, "", "count asc")
+			if rData != nil && len(*rData) > 0 {
+				TiDb.Insert("dwd_f_crm_clue_autodraw_record", map[string]interface{}{
+					"seatNumber": seatNumber,
+					"clue_level": mode,
+					"count":      common.Int64All((*rData)["count"]),
+				})
+			} else {
+				TiDb.Insert("dwd_f_crm_clue_autodraw_record", map[string]interface{}{
+					"seatNumber": seatNumber,
+					"clue_level": mode,
+					"count":      0,
+				})
+			}
 		}
 		for _, v := range *data {
 			if seatNumber == common.ObjToString(v["seatNumber"]) {
@@ -757,9 +860,9 @@ func autoDraw(mode string) (positionId int64, seatNumber, saleName string, saleD
 				saleName = common.ObjToString(v["name"])
 			}
 		}
-		if positionId > 0 {
-			TiDb.UpdateOrDeleteBySql(`update dwd_f_crm_clue_autodraw_record set count = count + 1 where seatNumber = ? and clue_level = ?`, seatNumber, mode)
-		}
+		// if positionId > 0 {
+		// 	TiDb.UpdateOrDeleteBySql(`update dwd_f_crm_clue_autodraw_record set count = count + 1 where seatNumber = ? and clue_level = ?`, seatNumber, mode)
+		// }
 	}
 	return
 }

+ 73 - 0
clueSync/log.go

@@ -0,0 +1,73 @@
+package main
+
+/**
+日志文件自动切换,默认保留15天内日志
+**/
+
+import (
+	"log"
+	"os"
+	"path/filepath"
+	"regexp"
+	"time"
+
+	"github.com/go-xweb/xweb"
+	"github.com/robfig/cron"
+)
+
+// 日志格式
+var fileReg = regexp.MustCompile("^(\\d{4}_[0-9_]{14})\\.log$")
+
+// 当前日志文件句柄
+var LogFile *os.File
+
+// 时间格式
+var FMT = "2006_01_02_15_04_05"
+
+// 日志目录
+var LogPath = "./jylog"
+
+func init() {
+	os.Mkdir(LogPath, os.ModePerm)
+	//默认保留15天内的日志,-1为永久保留
+	initLog(15)
+}
+
+func initLog(saveDay int) {
+	go logfile()
+	task := cron.New()
+	task.Start()
+	task.AddFunc("0 0 0 * * ?", func() {
+		go logfile()
+		time.Sleep(50 * time.Second)
+		if saveDay > 0 {
+			filepath.Walk(LogPath, func(path string, info os.FileInfo, err error) error {
+				str := fileReg.FindStringSubmatch(info.Name())
+				if len(str) == 2 {
+					t, er := time.ParseInLocation(FMT, str[1], time.Local)
+					if er == nil {
+						if (time.Now().Unix()-t.Unix())/86400 > int64(saveDay) {
+							log.Println("delete log file:", path, os.Remove(path))
+						}
+					}
+				}
+				return nil
+			})
+		}
+	})
+}
+
+// 创建并切换输出文件
+func logfile() {
+	now := time.Now().Format(FMT)
+	file, _ := os.Create(LogPath + "/" + now + ".log")
+	log.SetOutput(file)
+	xweb.RootApp().Logger.SetOutput(file)
+	go func(file *os.File) {
+		time.Sleep(5 * time.Second)
+		if LogFile != nil {
+			LogFile.Close()
+		}
+		LogFile = file
+	}(file)
+}

+ 6 - 2
clueSync/main.go

@@ -9,6 +9,7 @@ import (
 	elastic "app.yhyue.com/moapp/jybase/esv1"
 	"app.yhyue.com/moapp/jybase/mongodb"
 	"app.yhyue.com/moapp/jybase/mysql"
+	"app.yhyue.com/moapp/jybase/redis"
 	"github.com/robfig/cron"
 )
 
@@ -61,6 +62,7 @@ func main() {
 		I_size:  cfg.Es.DbSize,
 	}
 	Es.InitElasticSize()
+	redis.InitRedis(cfg.RedisServer)
 	Mgo = mongodb.NewMgo(cfg.Mgo.Address, cfg.Mgo.DbName, cfg.Mgo.DbSize)
 	MgoLog = mongodb.NewMgoWithUser(cfg.MgoLog.Address, cfg.MgoLog.DbName, cfg.MgoLog.User, cfg.MgoLog.Password, cfg.MgoLog.DbSize)
 	InitArea()
@@ -108,8 +110,8 @@ func main() {
 		})
 		f.Start()
 		//自动进入任务车 1天一次
-		autoTask()
-		autoTasks()
+		// autoTask()
+		// autoTasks()
 		g := cron.New()
 		g.AddFunc(cfg.CornExp7, func() {
 			autoTask()
@@ -148,5 +150,7 @@ func main() {
 		autoTask()
 	} else if *mode == 10 {
 		getAreaCode("6447753fb4f3c077da9d5336")
+	} else if *mode == 11 {
+		trail()
 	}
 }

+ 88 - 0
clueSync/trailContent.go

@@ -0,0 +1,88 @@
+package main
+
+import (
+	"log"
+	"regexp"
+
+	"strings"
+
+	"app.yhyue.com/moapp/jybase/common"
+	"github.com/tealeg/xlsx"
+)
+
+func trail() {
+	log.Println("合力亿捷跟进历史任务开始")
+	nameReg := regexp.MustCompile("【.*?】")
+	filePath := "./xlsx/跟进历史" + cfg.XlsxNum + ".xlsx"
+	log.Println("文件名 ", filePath)
+	xlFile, _ := xlsx.OpenFile(filePath)
+	//获取行数
+	length := len(xlFile.Sheets[0].Rows)
+	log.Println("获取行数 ", length)
+	//遍历sheet
+	for _, sheet := range xlFile.Sheets {
+		//遍历每一行
+		for rowIndex, row := range sheet.Rows {
+			//跳过第一行表头信息
+			if rowIndex == 0 {
+				continue
+			}
+			createtime := row.Cells[0].Value
+			name := row.Cells[1].Value
+			nexttype := row.Cells[2].Value
+			content := row.Cells[3].Value
+			phone := row.Cells[6].Value
+			positionId, clueId := getSale(name, phone)
+			log.Println("positionId,clueId ", positionId, clueId)
+			if clueId > 0 {
+				if nexttype == "无类型" {
+					TiDb.Insert("dwd_f_crm_trail_content", map[string]interface{}{
+						"clue_id":     clueId,
+						"position_id": positionId,
+						"createtime":  createtime,
+						"content":     content,
+						"operator_id": positionId,
+					})
+				} else {
+					old_value := strings.ReplaceAll(strings.ReplaceAll(nameReg.FindAllString(content, -1)[0], "【", ""), "】", "")
+					new_value := strings.ReplaceAll(strings.ReplaceAll(nameReg.FindAllString(content, -1)[1], "【", ""), "】", "")
+					TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
+						"clue_id":      clueId,
+						"position_id":  positionId,
+						"createtime":   createtime,
+						"change_field": common.If(nexttype == "所属人变更", "position_id", "trailstatus"),
+						"change_type":  common.If(nexttype == "所属人变更", nexttype, "基本信息变更"),
+						"old_value":    common.If(old_value == "销售线索", "商机线索", old_value),
+						"new_value":    common.If(new_value == "销售线索", "商机线索", new_value),
+						"operator_id":  positionId,
+					})
+				}
+			}
+		}
+	}
+}
+
+func getSale(name, phone string) (positionId, clueId int64) {
+	saleData := TiDb.FindOne("jy_salesperson_info", map[string]interface{}{"name": name, "status": 0}, "", "")
+	if saleData != nil && len(*saleData) > 0 {
+		salePhone := common.ObjToString((*saleData)["phone"])
+		userInfo := TiDb.FindOne("dwd_f_userbase_baseinfo", map[string]interface{}{"phone": salePhone}, "", "")
+		if userInfo != nil && len(*userInfo) > 0 {
+			base_user_id := common.Int64All((*userInfo)["base_user_id"])
+			positionData := Base.FindOne("base_position", map[string]interface{}{"type": 1, "user_id": base_user_id, "ent_id": 25917}, "", "")
+			if positionData != nil && len(*positionData) > 0 {
+				positionId = common.Int64All((*positionData)["id"])
+			}
+		}
+	} else {
+		positionId = -1
+	}
+	if positionId == 0 {
+		positionId = -1
+	}
+	clueInfo := TiDb.FindOne("dwd_f_crm_clue_info", map[string]interface{}{"phone": phone}, "", "")
+	if clueInfo != nil && len(*clueInfo) > 0 {
+		clueId = common.Int64All((*clueInfo)["id"])
+	}
+	return
+}

+ 8 - 0
telemarketingEtl/config/config.go

@@ -3,6 +3,7 @@ package config
 import (
 	"log"
 
+	"app.yhyue.com/moapp/jybase/common"
 	mg "app.yhyue.com/moapp/jybase/mongodb"
 	"app.yhyue.com/moapp/jybase/mysql"
 	"github.com/gogf/gf/v2/frame/g"
@@ -17,6 +18,7 @@ var (
 	MgoLog          mg.MongodbSim
 	MgoBid          mg.MongodbSim
 	MgoEnt          mg.MongodbSim
+	DateMap         = map[string]int{}
 )
 
 func init() {
@@ -93,4 +95,10 @@ func init() {
 		}
 		MgoBid.InitPool()
 	}
+	holidayRecords := JianyuSubjectdb.Find("holiday_records", nil, "", "", -1, -1)
+	if holidayRecords != nil && len(*holidayRecords) > 0 {
+		for _, m := range *holidayRecords {
+			DateMap[common.ObjToString(m["date"])] = common.IntAll(m["change"])
+		}
+	}
 }

+ 56 - 12
telemarketingEtl/entity/dwd_f_crm_open_sea.go

@@ -482,14 +482,57 @@ func ReturnOpenSea() {
 
 	now := time.Now().Format(date.Date_Full_Layout)
 
+	//判断节假日
+	statusMap := map[string]int{
+		"06": highIntentionCustomer,
+		"05": intentionCustomer,
+		"04": latentCustomer,
+		"03": sleepCustomer,
+		"01": businessLeads,
+	}
+	for status, statusInt := range statusMap {
+		count, counts := 0, 0
+		for {
+			count++
+			currentTime := t.AddDate(0, 0, -count)
+			currentTime.Format(date.Date_Short_Layout)
+			if currentTime.Weekday() == time.Sunday || currentTime.Weekday() == time.Sunday {
+				isok := false
+				for k, v := range config.DateMap {
+					if currentTime.Format(date.Date_Short_Layout) == k && v == 2 {
+						isok = true
+					}
+				}
+				if isok {
+					counts++
+				}
+			} else {
+				isok := true
+				for k, v := range config.DateMap {
+					if currentTime.Format(date.Date_Short_Layout) == k && v == 1 {
+						isok = false
+					}
+				}
+				if isok {
+					counts++
+				}
+			}
+			if counts >= statusInt {
+				break
+			}
+		}
+		statusMap[status] = counts
+	}
+	//
+
 	//2.“高意向客户”超过30天未更新跟进记录自动退回公海;
-	for trailstatus, nexttime := range map[string]interface{}{
-		"06": t.AddDate(0, 0, -highIntentionCustomer),
-		"05": t.AddDate(0, 0, -intentionCustomer),
-		"04": t.AddDate(0, 0, -latentCustomer),
-		"03": t.AddDate(0, 0, -sleepCustomer),
-		"01": t.AddDate(0, 0, -businessLeads),
-		"00": t,
+	for trailstatus, _ := range map[string]string{
+		"06": "",
+		"05": "",
+		"04": "",
+		"03": "",
+		"01": "",
+		"00": "",
 	} {
 		sql := `SELECT a.clue_id,a.position_id,a.seatNumber FROM dwd_f_crm_private_sea a 
 				LEFT JOIN dwd_f_crm_clue_info b ON a.clue_id=b.id 
@@ -499,7 +542,8 @@ func ReturnOpenSea() {
 		intime := ""
 		if trailstatus != "00" {
 			sql += " AND a.comeintime <?"
-			nt, _ := nexttime.(time.Time)
+			nt := t.AddDate(0, 0, -statusMap[trailstatus])
+			// nt, _ := nexttime.(time.Time)
 			intime = nt.Format(date.Date_Full_Layout)
 			argsSelect = append(argsSelect, intime)
 		}
@@ -594,7 +638,7 @@ func ReturnOpenSea() {
 	log.Println("return sea end")
 }
 
-//2私海手动退回 3私海高意向客户自动退回 4私海意向客户退回 5私海潜在客户退回 6私海沉睡客户退回 7私海商机线索退回 8私海无意向客户退回
+// 2私海手动退回 3私海高意向客户自动退回 4私海意向客户退回 5私海潜在客户退回 6私海沉睡客户退回 7私海商机线索退回 8私海无意向客户退回
 func GetComeSource() map[string]int {
 	return map[string]int{
 		"06": 3,
@@ -640,9 +684,9 @@ func GetPositionName(seatNumber string) string {
 	return ""
 }
 
-//(4)回收站:
-//A.5个自然日内被销售人员手动退回公海的客户;
-//B.3个自然日内有过“已接听”的通话记录且仍处于“商机线索”状态下的客户。
+// (4)回收站:
+// A.5个自然日内被销售人员手动退回公海的客户;
+// B.3个自然日内有过“已接听”的通话记录且仍处于“商机线索”状态下的客户。
 func Recycle() {
 	log.Println("回收站开始")
 	ctx := gctx.New()