yuelujie 1 月之前
父節點
當前提交
2e3a33c084
共有 5 個文件被更改,包括 191 次插入95 次删除
  1. 1 0
      clueSync/config.go
  2. 29 1
      clueSync/config.json
  3. 121 66
      clueSync/everything.go
  4. 31 17
      clueSync/jobutil.go
  5. 9 11
      clueSync/main.go

+ 1 - 0
clueSync/config.go

@@ -39,6 +39,7 @@ type (
 		InviteTime              string  `json:"inviteTime"`
 		ActivityTime            string  `json:"activityTime"`
 		LastKcChangeTime        string  `json:"lastKcChangeTime"`
+		LastUserBindingTime     string  `json:"lastUserBindingTime"`
 	}
 	DB struct {
 		CornExp1      int64  `json:"cornexp1"`

+ 29 - 1
clueSync/config.json

@@ -1 +1,29 @@
-{"lastOrderId":263043,"lastOrderClueId":"2025-05-16 10:05:24","lastUserId":"2025-04-15 15:20:01","lastXcxUserId":"2025-04-17 15:03:03","lastId":"67f8808952d21982ca5970cb","lastOrderTime":"2025-04-21 10:41:30","lastUserTime":"2025-04-21 13:30:02","lastSubscribeId":"67fcb9c1cdf0004e40e69cba","lastMessageTime":"2025-04-02 10:21:06","lastMessageButtonTime":"2025-05-28 16:59:23","lastkcTime":"2025-05-17 15:18:00","lastEverythingTime":"2024-11-20 13:40:21","lastEventRegTime":"2024-11-20 13:40:21","lastReadClueTime":"2025-03-25 14:43:42","bigSaleTime":1747293636,"bigOrderTime":"2025-04-29 15:18:31","marketSaleTime":1745218148,"advisoryCommitteeTime":1745216244,"selectionDepartmentTime":1745216244,"allocationTime":"2024-11-20 13:40:21","allocationRatio":2,"activeTime":"2025-04-14 22:00:00","rebindTime":"2025-04-09 11:11:56","inviteTime":"2025-04-21 00:00:00","activityTime":"2025-04-03 16:59:23","lastKcChangeTime":"2025-04-14 15:00:27.000"}
+{
+  "lastOrderId": 263906,
+  "lastOrderClueId": "2025-06-13 17:47:39",
+  "lastUserId": "2025-06-19 09:35:02",
+  "lastXcxUserId": "2025-06-18 16:31:01",
+  "lastId": "684cef938a04a21118691ba3",
+  "lastOrderTime": "2025-04-21 10:41:30",
+  "lastUserTime": "2025-04-21 13:30:02",
+  "lastSubscribeId": "67fcb9c1cdf0004e40e69cba",
+  "lastMessageTime": "2025-05-29 11:16:13",
+  "lastMessageButtonTime": "2025-05-28 16:59:23",
+  "lastkcTime": "2025-06-07 11:39:31",
+  "lastEverythingTime": "2025-06-19 15:13:26",
+  "lastEventRegTime": "2024-11-20 13:40:21",
+  "lastReadClueTime": "2025-03-25 14:43:42",
+  "bigSaleTime": 1747293636,
+  "bigOrderTime": "2025-04-29 15:18:31",
+  "marketSaleTime": 1745218148,
+  "advisoryCommitteeTime": 1745216244,
+  "selectionDepartmentTime": 1745216244,
+  "allocationTime": "2024-11-20 13:40:21",
+  "allocationRatio": 2,
+  "activeTime": "2025-04-14 22:00:00",
+  "rebindTime": "2025-04-09 11:11:56",
+  "inviteTime": "2025-04-21 00:00:00",
+  "activityTime": "2025-04-03 16:59:23",
+  "lastKcChangeTime": "2025-04-14 15:00:27.000",
+  "lastUserBindingTime": "2025-04-21 00:00:00"
+}

+ 121 - 66
clueSync/everything.go

@@ -7,6 +7,8 @@ import (
 	"github.com/gogf/gf/util/gconv"
 	"log"
 	"net/url"
+	"os"
+	"path/filepath"
 	"strings"
 	"time"
 
@@ -28,7 +30,7 @@ func everythingSync() {
 
 	codeArr := []string{}
 	if len(UserChannel) > 0 {
-		for i, _ := range UserChannel {
+		for i := range UserChannel {
 			codeArr = append(codeArr, fmt.Sprintf(`"%s"`, i))
 		}
 	}
@@ -549,7 +551,7 @@ func bigCustomer() {
 		for _, v := range dataArr {
 			minemail := ""
 			if gconv.String(v["appoint_email"]) == "" {
-				minemail, _ = EmailSelect("dk")
+				minemail, _ = EmailSelect("dk", "")
 			} else {
 				minemail = gconv.String(v["appoint_email"])
 			}
@@ -702,59 +704,35 @@ func FindBatchData(moudle string) map[string]interface{} {
 
 }
 
-// 咨询组线索
-func AdvisoryCommittee() {
-	if !isRunning() {
-		log.Println("不是工作日,任务暂停")
-		return
-	}
-	log.Println("咨询部线索定时任务开始")
-
-	sourceMap := buildSourceMap("咨询组")
-	nowTime := time.Now().Format(date.Date_Full_Layout)
-	startTime := getCommitteeTime(cfg.AdvisoryCommitteeTime)
-	dataArr, endtime := processLeads("zx", startTime, sourceMap, nowTime)
-
-	cfg.AdvisoryCommitteeTime = endtime
-	exportToExcel(dataArr, "咨询服务销售线索", "zx")
-	log.Println("咨询部线索定时任务结束")
-	common.WriteSysConfig(&cfg)
-}
-
-// 运营部线索
-func SelectionDepartment() {
-	if !isRunning() {
-		log.Println("不是工作日,任务暂停")
-		return
-	}
-	log.Println("运营部线索定时任务开始")
-
-	sourceMap := buildSourceMap("运营部")
-	nowTime := time.Now().Format(date.Date_Full_Layout)
-	startTime := getCommitteeTime(cfg.SelectionDepartmentTime)
-	dataArr, endtime := processLeads("yy", startTime, sourceMap, nowTime)
-	cfg.SelectionDepartmentTime = endtime
-	exportToExcel(dataArr, "运营部销售线索", "yy")
-	log.Println("运营部线索定时任务结束")
-	common.WriteSysConfig(&cfg)
-}
-
-// 市场部线索
-func MarketCustomer() {
-	if !isRunning() {
+// 特殊留资
+func SpecialSaleLeads() {
+	/*if !isRunning() {
 		log.Println("不是工作日,任务暂停")
 		return
+	}*/
+	saleLeadsConfig := TiDb.Find("saleLeads_config", map[string]interface{}{
+		"status": 0,
+	}, "", "", -1, -1)
+	log.Println("特殊留资线索定时任务开始")
+	for _, v := range *saleLeadsConfig {
+		log.Println(fmt.Sprintf("%s留资线索定时任务开始", gconv.String(v["groupName"])), gconv.String(v["lastTime"]))
+		//留来源获取
+		sourceMap := buildSourceMap(gconv.String(v["groupName"]))
+		if len(sourceMap) == 0 {
+			log.Println(fmt.Sprintf("%s留资线索定时任务结束", gconv.String(v["groupName"])))
+			continue
+		}
+		dataArr, endtime := processLeads(v, sourceMap)
+		//最后一次数据修改
+		TiDb.Update("saleLeads_config", map[string]interface{}{
+			"id": gconv.Int64(v["id"]),
+		}, map[string]interface{}{
+			"lastTime": endtime,
+		})
+		exportToExcel(dataArr, gconv.String(v["title"]), gconv.String(v["groupCode"]), gconv.String(v["mail"]))
+		log.Println(fmt.Sprintf("%s留资线索定时任务结束", gconv.String(v["groupName"])))
 	}
-	log.Println("市场部线索定时任务开始")
-
-	sourceMap := buildSourceMap("市场组")
-	nowTime := time.Now().Format(date.Date_Full_Layout)
-	startTime := getCommitteeTime(cfg.MarketSaleTime)
-	dataArr, endtime := processLeads("sc", startTime, sourceMap, nowTime)
-	cfg.MarketSaleTime = endtime
-	exportToExcel(dataArr, "商务合作销售线索", "sc")
-	common.WriteSysConfig(&cfg)
-	log.Println("市场部线索定时任务结束")
+	log.Println("特殊留资线索定时任务结束")
 }
 
 // 判断是否在工作日
@@ -798,17 +776,18 @@ func getCommitteeTime(cfgTime int64) int64 {
 	return cfgTime
 }
 
-// 处理线索
-func processLeads(batch string, committeeTime int64, sourceMap map[string]map[string]interface{}, nowTime string) ([]map[string]interface{}, int64) {
+// 处理留资信息
+func processLeads(saleLeadsMap map[string]interface{}, sourceMap map[string]map[string]interface{}) ([]map[string]interface{}, int64) {
+	batch := gconv.String(saleLeadsMap["groupCode"])
+	lastTime := gconv.Int64(saleLeadsMap["lastTime"])
 	dataArr := []map[string]interface{}{}
-	endtime := int64(0)
-	saleleadsData, ok := Mgo.Find("saleLeads", map[string]interface{}{"createtime": map[string]interface{}{"$gt": committeeTime}}, `{"phone":1,"createtime":1}`, nil, false, -1, -1)
-	//saleleadsData, ok := Mgo.Find("saleLeads", map[string]interface{}{"createtime": committeeTime}, `{"phone":1,"createtime":1}`, nil, false, -1, -1)
+	endtime := lastTime
+	saleleadsData, ok := Mgo.Find("saleLeads", map[string]interface{}{"createtime": map[string]interface{}{"$gt": lastTime}}, `{"phone":1,"createtime":1}`, nil, false, -1, -1)
 	if ok && saleleadsData != nil {
 		data := FindBatchData(batch)
 		for _, v := range *saleleadsData {
 			lead := map[string]interface{}{}
-			lead, endtime = processLead(v, sourceMap, nowTime, committeeTime, data)
+			lead, endtime = processLead(v, sourceMap, lastTime, data)
 			if lead != nil {
 				dataArr = append(dataArr, lead)
 			}
@@ -819,29 +798,43 @@ func processLeads(batch string, committeeTime int64, sourceMap map[string]map[st
 	return dataArr, endtime
 }
 
+<<<<<<< HEAD
 // 处理单个线索
 func processLead(v map[string]interface{}, sourceMap map[string]map[string]interface{}, nowTime string, committeeTime int64, data map[string]interface{}) (map[string]interface{}, int64) {
 	sources := gconv.String(v["source"])
 	// 更新委员会时间
 	if gconv.Int64(v["createtime"]) > committeeTime {
 		committeeTime = gconv.Int64(v["createtime"])
+=======
+// 处理单个留资信息
+func processLead(v map[string]interface{}, sourceMap map[string]map[string]interface{}, lastTime int64, data map[string]interface{}) (map[string]interface{}, int64) {
+	nowTime := time.Now().Format(date.Date_Full_Layout)
+	sources := common.ObjToString(v["source"])
+	// 更新最后会时间
+	if gconv.Int64(v["createtime"]) > lastTime {
+		lastTime = gconv.Int64(v["createtime"])
+>>>>>>> master
 	}
 	sourceData, exist := sourceMap[sources]
 	if !exist {
-		return nil, committeeTime
+		return nil, lastTime
 	}
 	phone := gconv.String(v["phone"])
 	if IsInternal(phone) {
-		return nil, committeeTime
+		return nil, lastTime
 	}
 	// 获取用户信息
 	userData := getUserData(v)
 	if userData == nil || isUserInBlackList(userData) {
-		return nil, committeeTime
+		return nil, lastTime
 	}
+<<<<<<< HEAD
 	key := fmt.Sprintf("%s_%s_%s", sourceMap[sources], phone, gconv.String(v["interest"]))
+=======
+	key := fmt.Sprintf("%s_%s_%s", sources, phone, common.ObjToString(v["interest"]))
+>>>>>>> master
 	if _, exists := data[key]; exists {
-		return nil, committeeTime
+		return nil, lastTime
 	}
 	data[key] = true
 
@@ -852,14 +845,19 @@ func processLead(v map[string]interface{}, sourceMap map[string]map[string]inter
 		"company":          gconv.String(v["company"]),
 		"phone":            phone,
 		"source":           gconv.String(sourceData["name"]),
+<<<<<<< HEAD
 		"belongTo":         "咨询组/市场组", // 根据需要修改
 		"interest":         gconv.String(v["interest"]),
 		"data_requirement": gconv.String(v["data_requirement"]),
+=======
+		"interest":         common.ObjToString(v["interest"]),
+		"data_requirement": common.ObjToString(v["data_requirement"]),
+>>>>>>> master
 		"branch":           v["branch"],
 		"job":              v["position"],
 		"email":            gconv.String(v["mail"]),
 		"appointEmail":     gconv.String(sourceData["appointEmail"]),
-	}, committeeTime
+	}, lastTime
 }
 
 // 获取用户数据
@@ -891,7 +889,7 @@ func isABHLead(lead map[string]interface{}) bool {
 }
 
 // 导出到 Excel
-func exportToExcel(dataArr []map[string]interface{}, title, batch string) {
+func exportToExcel(dataArr []map[string]interface{}, title, batch, mails string) {
 	if len(dataArr) == 0 {
 		return
 	}
@@ -899,7 +897,7 @@ func exportToExcel(dataArr []map[string]interface{}, title, batch string) {
 	for _, v := range dataArr {
 		appointEmail := gconv.String(v["appointEmail"])
 		if appointEmail == "" {
-			appointEmail, _ = EmailSelect(batch)
+			appointEmail, _ = EmailSelect(batch, mails)
 		}
 		bigArr[appointEmail] = append(bigArr[appointEmail], v)
 	}
@@ -935,6 +933,12 @@ func exportToExcel(dataArr []map[string]interface{}, title, batch string) {
 			row.AddCell().SetString(gconv.Time(gconv.Int64(v["createtime"])).Format(date.Date_Full_Layout))
 		}
 		dir := fmt.Sprintf("./xlsx/%s/%s.xlsx", batch, fileName)
+		// 确保目录存在(自动创建)
+		dirPath := filepath.Dir(dir) // 提取目录部分(如 "./xlsx/batch")
+		if err := os.MkdirAll(dirPath, 0755); err != nil {
+			log.Println("创建目录失败:", err)
+			return
+		}
 		if err := xf.Save(dir); err != nil {
 			log.Println("xls error", err, dir)
 			return
@@ -963,11 +967,45 @@ func saveDataToRedis(data map[string]interface{}, batch string) {
 }
 
 // 邮箱选择处理
-func EmailSelect(batch string) (string, string) {
+func EmailSelect(batch, mailStr string) (string, string) {
 	name := ""
 	minemail := ""
 	bigData := TiDb.SelectBySql("select * from dwd_f_crm_clue_big_autodraw_record where   type =?  ", batch)
 	if bigData != nil && len(*bigData) > 0 {
+		//查看有没有新增人员 人名-邮箱,邮箱|人名-邮箱,
+		mailMap := map[string]string{}
+		if mailStr != "" {
+			for _, s := range strings.Split(mailStr, "|") {
+				if len(strings.Split(s, "-")) > 1 {
+					arr := strings.Split(s, "-")
+					personName := arr[0]
+					mailMap[personName] = arr[1]
+				}
+			}
+			for personName, mail := range mailMap {
+				isOk := false
+				for _, m := range *bigData {
+					tablePersonName := gconv.String(m["name"])
+					if tablePersonName == personName {
+						isOk = true
+					}
+				}
+				if !isOk {
+					rData := TiDb.FindOne("dwd_f_crm_clue_big_autodraw_record", map[string]interface{}{
+						"type": batch,
+					}, "", "count desc")
+					//这是一个新人
+					TiDb.Insert("dwd_f_crm_clue_big_autodraw_record", map[string]interface{}{
+						"name":  personName,
+						"count": common.Int64All((*rData)["count"]),
+						"email": mail,
+						"type":  batch,
+					})
+					return minemail, name
+				}
+
+			}
+		}
 		mincount := common.IntAll((*bigData)[0]["count"])
 		for _, vv := range *bigData {
 			vcount := common.IntAll(vv["count"])
@@ -979,6 +1017,23 @@ func EmailSelect(batch string) (string, string) {
 				name = vName
 			}
 		}
+	} else {
+		for k, s := range strings.Split(mailStr, "|") {
+			if len(strings.Split(s, "-")) > 1 {
+				arr := strings.Split(s, "-")
+				if k == 0 {
+					minemail, name = arr[1], arr[0]
+				}
+				personName := arr[0]
+				TiDb.Insert("dwd_f_crm_clue_big_autodraw_record", map[string]interface{}{
+					"name":  personName,
+					"count": 0,
+					"email": arr[1],
+					"type":  batch,
+				})
+			}
+		}
+
 	}
 	TiDb.UpdateOrDeleteBySql(`update dwd_f_crm_clue_big_autodraw_record set count = count + 1 where name = ? and   type=?`, name, batch)
 	return minemail, name

+ 31 - 17
clueSync/jobutil.go

@@ -717,6 +717,31 @@ func saleLeads() {
 	log.Println("query :", query)
 	iter := session.DB(db.Mgo.DbName).C("saleLeads").Find(&query).Sort("_id").Iter()
 	thisData := map[string]interface{}{}
+	filterArr := []string{"-pc", "-app", "-wx", "-h5"}
+	sourceMap := map[string]string{}
+	saleLeadsConfig := TiDb.Find("saleLeads_config", map[string]interface{}{
+		"status": 0,
+	}, "groupName", "", -1, -1)
+	if saleLeadsConfig == nil || len(*saleLeadsConfig) == 0 {
+		log.Println("线索卡点", "缺少留资分类名称", "saleLeads", thisData, lastId)
+		return
+	}
+	sourceArr := []string{}
+	for _, v := range *saleLeadsConfig {
+		sourceArr = append(sourceArr, fmt.Sprintf(`department   LIKE '%%%s%%'`, gconv.String(v["groupName"])))
+	}
+	sql := fmt.Sprintf(`SELECT source,name FROM d_saleleads_code WHERE ( %s) AND is_delete = 1`, strings.Join(sourceArr, " or   "))
+	saleSource := TiDb.SelectBySql(sql)
+	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 {
 		if !iter.Next(&thisData) {
 			break
@@ -727,19 +752,6 @@ func saleLeads() {
 			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 '%咨询组%' 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
 		}
@@ -759,7 +771,7 @@ func saleLeads() {
 func userbase() {
 	log.Println("userbase定时任务开始")
 	timeUnix := time.Now().Unix()
-	selectTimeStart := time.Unix(timeUnix-1800, 0).Format("2006-01-02 15:04:05")
+	selectTimeStart := cfg.LastUserBindingTime
 	selectTimeEnd := time.Unix(timeUnix, 0).Format("2006-01-02 15:04:05")
 	sql := fmt.Sprintf(`SELECT
 		a.phone,b.uid,a.baseinfo_id,b.l_registedate,a.createtime,b.id,b.userid,b.rsource
@@ -770,10 +782,9 @@ func userbase() {
 	    and  (b.s_platform != 'xcx' or  b.s_sourceid='jyzbw' or  b.s_platform is  NULL)
 		AND a.phone = b.phone and a.baseinfo_id= b.uid and     b.source  ="0101"
   		and  a.phone  is  not   NULL  
-		and   a.createtime   >="%s"
-		and   a.createtime   <"%s"
+		and   a.createtime   >"%s"
 		and  a.is_delete=1  
-		ORDER BY    a.createtime `, selectTimeStart, selectTimeEnd)
+		ORDER BY    a.createtime `, selectTimeStart)
 	data := TiDb.SelectBySql(sql)
 	if data != nil && *data != nil && len(*data) > 0 {
 		for _, v := range *data {
@@ -789,10 +800,12 @@ func userbase() {
 				})
 			}
 			registedate := common.ObjToString(v["l_registedate"])
+
 			name := common.ObjToString(v["name"])
 			nowTime := time.Now().Format(date.Date_Full_Layout)
 			layout := "2006-01-02 15:04:05"
 			createtime := gconv.String(v["createtime"])
+			cfg.LastUserBindingTime = createtime
 			createtimeInt64, _ := time.Parse(layout, createtime)
 			registedateInt64, _ := time.Parse(layout, registedate)
 			count := TiDb.CountBySql("select count(1) as count from dwd_f_crm_clue_info where uid = ?", uId)
@@ -873,6 +886,7 @@ func userbase() {
 			}
 		}
 	}
+	common.WriteSysConfig(&cfg)
 	log.Println("userbase定时任务结束")
 }
 

+ 9 - 11
clueSync/main.go

@@ -177,17 +177,15 @@ func main() {
 		//5分钟一次
 		go p.VarTimeTask.RunInTimeSection("5分钟定时任务1", db.CornExp2Start, db.CornExp2End, db.CornExp2, func(dayFirst bool) {
 			InitUserChannel()
-			users()               //新注册用户进线索
-			saleLeads()           //留资进线索
-			eventReg()            //渠道
-			bigCustomer()         //大客户线索
-			MarketCustomer()      //市场部线索
-			AdvisoryCommittee()   //咨询组线索
-			SelectionDepartment() //运营部线索
-			rebind()              //取关重新关注处理
-			activeUsers()         //活跃用户处理
-			inviteUser()          //邀请用户
-			nextYearActivity()    //开年活动
+			users()       //新注册用户进线索
+			saleLeads()   //留资进线索
+			eventReg()    //渠道
+			bigCustomer() //大客户线索
+			SpecialSaleLeads()
+			rebind()           //取关重新关注处理
+			activeUsers()      //活跃用户处理
+			inviteUser()       //邀请用户
+			nextYearActivity() //开年活动
 		})
 		//每天8点30
 		c := cron.New()