Przeglądaj źródła

Merge remote-tracking branch 'origin/feature/v1.5.24' into dev_v1.5.26_wh

# Conflicts:
#	clueSync/main.go
WH01243 6 miesięcy temu
rodzic
commit
17fe6dee3c

+ 3 - 0
clueSync/autoTask.go

@@ -622,6 +622,9 @@ func ClueToDxTask() {
 			}
 		} else { //企业大会员
 			//根据企业id查询企业下的员工
+			if gconv.Int(val["ent_id"]) == 0 {
+				continue
+			}
 			data := TiDb.Query("SELECT userid,uid FROM dwd_f_userbase_id_mapping WHERE ent_id = ?", gconv.Int(val["ent_id"]))
 			if data != nil && len(*data) > 0 {
 				log.Println("企业下员工数:", gconv.Int(val["ent_id"]), len(*data))

+ 25 - 2
clueSync/config.go

@@ -1,9 +1,9 @@
 package main
 
 import (
-	"log"
-
 	"app.yhyue.com/moapp/jybase/common"
+	"gopkg.in/gomail.v2"
+	"log"
 )
 
 type (
@@ -194,8 +194,31 @@ type (
 		ExpirationPeriod int               `json:"expirationPeriod"` //客成到期周期
 		HandoverCycle    int64             `json:"handoverCycle"`    //移交周期
 		CustomerTime     int64             `json:"customerTime"`     //客成时间
+		KeCheng          struct {
+			DeptId int64  `json:"deptId"`
+			Title  string `json:"title"`
+			Mail   struct {
+				Table       string `json:"table"`
+				Content     string `json:"content"`
+				ServiceList string `json:"serviceList"`
+				ReturnMoney string `json:"returnMoney"`
+			} `json:"mail"`
+			Message            string `json:"message"`
+			MessageServiceList string `json:"messageServiceList"`
+			MessageReturnMoney string `json:"messageReturnMoney"`
+		} `json:"keCheng"`
+		Mail GmailAuth `json:"mail"` //邮箱配置
 	}
 )
+type GmailAuth struct {
+	SmtpHost string //邮箱服务器
+	SmtpPort int    //邮箱端口
+	User     string //用户
+	Pwd      string //密码
+	PoolChan chan *gomail.Dialer
+	PoolSize int
+	ReTry    int
+}
 
 var AreaCode = map[string]string{}
 var CodeArea = map[string]string{}

+ 20 - 1
clueSync/db.json

@@ -164,5 +164,24 @@
   "newRegistration": 1,
   "expirationPeriod": 30,
   "handoverCycle": 60,
-  "customerTime": 1733846400
+  "customerTime": 1603846400,
+  "mail": {
+    "smtpHost": "smtp.exmail.qq.com",
+    "smtpPort": 465,
+    "user": "public03@topnet.net.cn",
+    "pwd": "ue9Rg9Sf4CVtdm5a"
+  },
+  "kecheng":{
+    "deptId":59005,
+    "title":"客户移交客户成功组",
+    "mail":{
+      "content":"<style> *,body,html{margin:10px;font-family:tahoma,arial,'Hiragino Sans GB','Microsoft YaHei',宋体,ans-serif;font-size:16px;}p{margin:15px;font-size:18px;}table{background-color: rgb(244, 244, 249);padding:5px 15px;border:solid 1px #ddd;margin: 20px 0px 20px 50px;vertical-align:top;display:inline-block;}.tit{width:120px;}td{padding: 5px;}.clear{clear: both;}</style><p>各位好,以下订单用户已经完成支付,烦请对接后续售后服务事项,谢谢!</p>%s<div class='clear'></div>",
+      "table":"<table><tr><td class='tit'>产品名称:</td><td>%s</td></tr><tr><td class='tit'>公司名称:</td><td>%s</td></tr><tr><td class='tit'>联系方式:</td><td>%s</td></tr><tr><td class='tit'>联系人姓名:</td><td>%s</td></tr><tr><td class='tit'>订单编号:</td><td>%s</td></tr><tr><td class='tit'>合同金额:</td><td>%.2f</td></tr><tr><td class='tit'>使用起止时间:</td><td>%s</td></tr><tr><td class='tit'>分配客成:</td><td>%s</td></tr><tr><td class='tit'>签署销售:</td><td>%s</td></tr>%s</table>",
+      "serviceList":"<tr><td class='tit'>服务列表:</td><td>%s</td></tr>",
+      "returnMoney":"<tr><td class='tit'>回款金额:</td><td>%.2f</td></tr>"
+    },
+    "message":"该订单用户已经完成支付,烦请对接后续售后服务事项,谢谢!\n产品名称:%s 公司名称:%s 联系方式:%s 联系人姓名:%s 订单编号:%s 合同金额:%.2f 使用起止时间:%s 分配客成:%s 签署销售:%s%s",
+    "messageServiceList":" 服务列表:%s",
+    "messageReturnMoney":" 回款金额:%.2f"
+  }
 }

+ 8 - 8
clueSync/everything.go

@@ -614,10 +614,10 @@ func bigCustomer() {
 				log.Println("xls error", err, dir)
 			} else {
 				gmail := &mail.GmailAuth{
-					SmtpHost: "smtp.exmail.qq.com",
-					SmtpPort: 465,
-					User:     "public03@topnet.net.cn",
-					Pwd:      "ue9Rg9Sf4CVtdm5a",
+					SmtpHost: db.Mail.SmtpHost,
+					SmtpPort: db.Mail.SmtpPort,
+					User:     db.Mail.User,
+					Pwd:      db.Mail.Pwd,
 				}
 				status := mail.GSendMail_q("剑鱼标讯", email, "", "", fileName, detailName, dir, fileName+".xlsx", gmail)
 				if status {
@@ -974,10 +974,10 @@ func exportToExcel(dataArr []map[string]interface{}, title, batch string) {
 // 发送邮件
 func sendEmail(fileName, detailName, dir, email string) {
 	gmail := &mail.GmailAuth{
-		SmtpHost: "smtp.exmail.qq.com",
-		SmtpPort: 465,
-		User:     "public03@topnet.net.cn",
-		Pwd:      "ue9Rg9Sf4CVtdm5a",
+		SmtpHost: db.Mail.SmtpHost,
+		SmtpPort: db.Mail.SmtpPort,
+		User:     db.Mail.User,
+		Pwd:      db.Mail.Pwd,
 	}
 	if status := mail.GSendMail_q("剑鱼标讯", email, "", "", fileName, detailName, dir, fileName+".xlsx", gmail); status {
 		log.Println("send mail success", fileName, email)

+ 1 - 0
clueSync/go.mod

@@ -14,4 +14,5 @@ require (
 	github.com/lunny/csession v0.0.0-20130910075847-fe53c5de3dfd // indirect
 	github.com/robfig/cron v1.2.0
 	github.com/tealeg/xlsx v1.0.5
+	gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect
 )

+ 9 - 9
clueSync/jobutil.go

@@ -1684,12 +1684,12 @@ func AFEmail(data []map[string]interface{}) {
 		log.Println("xls error", err, dir)
 	} else {
 		gmail := &mail.GmailAuth{
-			SmtpHost: "smtp.exmail.qq.com",
-			SmtpPort: 465,
-			User:     "public03@topnet.net.cn",
-			Pwd:      "ue9Rg9Sf4CVtdm5a",
+			SmtpHost: db.Mail.SmtpHost,
+			SmtpPort: db.Mail.SmtpPort,
+			User:     db.Mail.User,
+			Pwd:      db.Mail.Pwd,
 		}
-		status := mail.GSendMail_q("剑鱼标讯", email, "", "", fileName, detailName, dir, fileName+".xlsx", gmail)
+		status := mail.GSendMail_q("剑鱼标讯", email, "", "", fileName, detailName, dir, "", gmail)
 		if status {
 			log.Println("send mail success", fileName, email)
 		}
@@ -1853,10 +1853,10 @@ func sendEmailIfSuccessful(err error, fileName, detailName, dir string) {
 	}
 	email := db.AbhEmail
 	gmail := &mail.GmailAuth{
-		SmtpHost: "smtp.exmail.qq.com",
-		SmtpPort: 465,
-		User:     "public03@topnet.net.cn",
-		Pwd:      "ue9Rg9Sf4CVtdm5a",
+		SmtpHost: db.Mail.SmtpHost,
+		SmtpPort: db.Mail.SmtpPort,
+		User:     db.Mail.User,
+		Pwd:      db.Mail.Pwd,
 	}
 	status := mail.GSendMail_q("剑鱼标讯", email, "", "", fileName, detailName, dir, fileName+".xlsx", gmail)
 	if status {

+ 679 - 265
clueSync/kc.go

@@ -1,6 +1,7 @@
 package main
 
 import (
+	"app.yhyue.com/moapp/jybase/mail"
 	"database/sql"
 	"encoding/json"
 	"fmt"
@@ -13,21 +14,25 @@ import (
 	"app.yhyue.com/moapp/jybase/common"
 	"app.yhyue.com/moapp/jybase/date"
 	"app.yhyue.com/moapp/jybase/mongodb"
-	"app.yhyue.com/moapp/jybase/redis"
 )
 
 func kcSync() {
 	log.Println("客户成功系统移交定时任务开始")
-	sql := `select * from dwd_f_userbase_order_info where payable_money > 0 and vip_endtime > "` + time.Now().Format(date.Date_Full_Layout) + `" and autoUpdate > "` + cfg.LastkcTime + `" order by autoUpdate asc`
+	sql := `select * from dwd_f_userbase_order_info where (payable_money > 0 or  (payable_money=0 and  ( filter  like "%分期付款补充权益%"  or   filter  like "%原订单不支持开通多项权益%"  or    filter  like "%权益码兑换%")))
+	  and  data_spec!="dhy4" and  order_status=1  and (refund_status!=1  or  refund_status is null  ) and  vip_starttime<"2099-01-01"
+	  and vip_endtime > "` + time.Now().Format(date.Date_Full_Layout) + `" and autoUpdate > "` + cfg.LastkcTime + `" order by autoUpdate asc`
+	//sql := `select * from dwd_f_userbase_order_info where order_code="152504013602"  `
 	data := TiDb.SelectBySql(sql)
 	if data != nil && *data != nil && len(*data) > 0 {
+		arr := []string{}
 		for _, v := range *data {
 			product_type := common.ObjToString(v["product_type"])
-			data_spec := common.ObjToString(v["data_spec"])
-			starttime := common.ObjToString(v["vip_starttime"])
-			order_status := common.IntAll(v["order_status"])
-			refund_status := common.IntAll(v["refund_status"])
-			if (product_type == "大会员" || product_type == "企业商机管理") && order_status == 1 && data_spec != "dhy4" && !strings.HasPrefix(starttime, "2099") && refund_status != 1 {
+			vip_starttime := common.ObjToString(v["vip_starttime"])
+			vip_endtime := common.ObjToString(v["vip_endtime"])
+			order_change := gconv.Int64(v["order_change"])
+			if (product_type == "大会员" || product_type == "企业商机管理") && ((order_change != 0) || (order_change == 0 && TimeStrcount(vip_starttime, vip_endtime) > 95)) {
+				orderCode := gconv.String(v["order_code"])
+				arr = append(arr, orderCode)
 				status := kcJob(v)
 				if status == 0 {
 					break
@@ -35,314 +40,343 @@ func kcSync() {
 			}
 			cfg.LastkcTime = common.ObjToString(v["autoUpdate"])
 		}
+		log.Println(strings.Join(arr, "`,`"))
 	}
+
 	common.WriteSysConfig(&cfg)
 	log.Println("客户成功系统移交定时任务结束")
 }
 
 func kcJob(data map[string]interface{}) int {
 	nowTime := time.Now().Format(date.Date_Full_Layout)
-	uId, entId, clueId, saveMap, name, positionId, status := common.ObjToString(data["uid"]), fmt.Sprint(data["ent_id"]), int64(0), map[string]interface{}{}, "", int64(0), 1
+	uId, entId, clueId, saveMap, status := common.ObjToString(data["uid"]), fmt.Sprint(data["ent_id"]), int64(0), map[string]interface{}{}, 1
 	clueData := TiDb.FindOne("dwd_f_crm_clue_info", map[string]interface{}{"uid": uId}, "", "")
-	if clueData != nil && len(*clueData) > 0 {
-		clueId = common.Int64All((*clueData)["id"])
-		starttime := common.ObjToString(data["vip_starttime"])
-		endtime := common.ObjToString(data["vip_endtime"])
-		// user_role := common.IntAll(data["user_role"])
-		buy_subject := common.IntAll(data["buy_subject"])
-		product_type := common.ObjToString(data["product_type"])
-		data_spec := common.ObjToString(data["data_spec"])
-		userName := common.ObjToString((*clueData)["name"])
-		//phone := common.ObjToString((*clueData)["phone"])
-		product, company_name := 0, common.ObjToString(data["company_name"])
-		productMap := map[string]int{
-			"dhy6":   1,
-			"dhy7":   2,
-			"dhy3":   4,
-			"dhy1":   5,
-			"dhy2":   6,
-			"dhy5":   7,
-			"企业商机管理": 8,
-		}
-		if buy_subject == 1 || buy_subject == 0 {
-			entId = common.ObjToString(data["userid"])
-		}
-		if product_type == "企业商机管理" {
-			product = productMap[product_type]
-			powerData := TiDb.FindOne("dwd_f_data_equity_info", map[string]interface{}{"uid": uId, "product_type": "商机管理"}, "", "comeintime desc")
-			if powerData != nil {
-				starttime = common.ObjToString((*powerData)["starttime"])
-				endtime = common.ObjToString((*powerData)["endtime"])
-			} else {
-				log.Println("客成移交权限未查到--", uId)
+	orderCode := gconv.String(data["order_code"])
+	saleDep, orderPositionId, salesperson := FindSaleRecord(orderCode)
+	log.Println(data["order_code"], saleDep, orderPositionId, salesperson)
+	if clueData == nil || len(*clueData) == 0 {
+		if saleDep == "销售部" || saleDep == "市场部" {
+			return 1
+		}
+		//创建线索
+		//原始订单获取
+		position_id := int64(0)
+		orderData := Mysql.FindOne("dataexport_order", map[string]interface{}{
+			"order_code": orderCode,
+		}, "", "")
+		if orderData == nil {
+			log.Println("原始订单查询不到:", orderCode)
+		}
+		userId, cluename, phone := common.ObjToString((*orderData)["user_id"]), "", ""
+		seatNumber := ""
+		if saleDep == "客户成功组" {
+			//新增线索
+			position_id = 0
+		} else if saleDep == "销售部" {
+			log.Println("该订单数据销售部业绩,不会创建线索")
+			return 0
+		} else {
+			position_id = orderPositionId
+			//其他信息
+			seatNumber = "0000"
+		}
+		cluename = common.ObjToString(data["company_name"])
+		phone = common.ObjToString(data["user_phone"])
+		if cluename == "" {
+			cluename = phone
+		}
+		trailstatus := "08"
+		isGroup, isCommerce := GetCompanyType(cluename, uId) //判断是否集团公司、工商库
+		clueId = TiDb.Insert("dwd_f_crm_clue_info", map[string]interface{}{
+			"userid":               userId,
+			"uid":                  uId,
+			"is_assign":            common.If(position_id > 0, 1, 0),
+			"createtime":           nowTime,
+			"updatetime":           nowTime,
+			"cluename":             cluename,
+			"seatNumber":           seatNumber,
+			"position_id":          position_id,
+			"top_cluetype":         "4",
+			"sub_cluetype":         "154",
+			"trailstatus":          trailstatus,
+			"name":                 phone,
+			"phone":                phone,
+			"is_task":              0,
+			"taskstatus":           0,
+			"company_nature":       isGroup,
+			"company_verification": isCommerce,
+			"FREEZE_TIME":          nowTime,
+			"label":                common.If(position_id > 0, 1, nil),
+		})
+		if clueId > 0 {
+			TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
+				"clue_id":     clueId,
+				"position_id": common.If(position_id > 0, position_id, -1),
+				"change_type": "创建线索",
+				"new_value":   "系统自动创建",
+				"createtime":  nowTime,
+				"BCPCID":      common.GetRandom(32),
+				"operator_id": -1,
+			})
+			clueData = TiDb.FindOne("dwd_f_crm_clue_info", map[string]interface{}{"uid": uId}, "", "")
+			if clueData == nil || len(*clueData) == 0 {
 				return 0
 			}
 		} else {
-			if data_spec == "dhy6" {
-				product = 1
-				filter := common.ObjToString(data["filter"])
-				filterMap := map[string]interface{}{}
-				json.Unmarshal([]byte(filter), &filterMap)
-				if len(filterMap) > 0 {
-					areaCount := common.IntAll(filterMap["areaCount"])
-					if areaCount == 1 {
-						product = 3
-					}
+			return 1
+		}
+	}
+	clueId = common.Int64All((*clueData)["id"])
+	starttime := common.ObjToString(data["vip_starttime"])
+	endtime := common.ObjToString(data["vip_endtime"])
+	buy_subject := common.IntAll(data["buy_subject"])
+	product_type := common.ObjToString(data["product_type"])
+	data_spec := common.ObjToString(data["data_spec"])
+	userName := common.ObjToString((*clueData)["name"])
+	product, company_name := 0, common.ObjToString(data["company_name"])
+	productMap := map[string]int{
+		"dhy6":   1,
+		"dhy7":   2,
+		"dhy3":   4,
+		"dhy1":   5,
+		"dhy2":   6,
+		"dhy5":   7,
+		"企业商机管理": 8,
+	}
+	if buy_subject == 1 || buy_subject == 0 {
+		entId = common.ObjToString(data["userid"])
+	}
+	if product_type == "企业商机管理" {
+		product = productMap[product_type]
+		powerData := TiDb.FindOne("dwd_f_data_equity_info", map[string]interface{}{"uid": uId, "product_type": "商机管理"}, "", "comeintime desc")
+		if powerData != nil {
+			starttime = common.ObjToString((*powerData)["starttime"])
+			endtime = common.ObjToString((*powerData)["endtime"])
+		} else {
+			log.Println("客成移交权限未查到--", uId)
+			return 0
+		}
+	} else {
+		if data_spec == "dhy6" {
+			product = 1
+			filter := common.ObjToString(data["filter"])
+			filterMap := map[string]interface{}{}
+			json.Unmarshal([]byte(filter), &filterMap)
+			if len(filterMap) > 0 {
+				areaCount := common.IntAll(filterMap["areaCount"])
+				if areaCount == 1 {
+					product = 3
 				}
-			} else {
-				product = productMap[data_spec]
 			}
+		} else {
+			product = productMap[data_spec]
 		}
-		//同一公司名称(以客户详情-组织机构-公司名称)下的线索需分配给同1人
-		//合力亿捷线索同步
-		/*customerData := TiDbData.FindOne("customer", map[string]interface{}{"phone": phone}, "", "")
-		if customerData != nil {
-			log.Println("移交客成查询到合力亿捷")
-			status999 := common.ObjToString((*customerData)["status999"])               //线索状态
-			source := common.ObjToString((*customerData)["source"])                     //销售来源
-			customerNeeds := common.ObjToString((*customerData)["customerNeeds"])       //客户需求
-			wantGoods := common.ObjToString((*customerData)["wantGoods"])               //意向产品
-			job := common.ObjToString((*customerData)["job"])                           //职位
-			createTime := common.ObjToString((*customerData)["createTime"])             //创建时间
-			lastUpdateTime := common.ObjToString((*customerData)["lastUpdateTime"])     //更新时间
-			area := common.ObjToString((*customerData)["area"])                         //关注区域
-			customerBudget := common.ObjToString((*customerData)["customerBudget"])     //客户预算
-			isPolicymaker := common.ObjToString((*customerData)["customerBudget"])      //是否为决策人
-			belongToIndustry := common.ObjToString((*customerData)["belongToIndustry"]) //所属行业
-			seatNumber := common.ObjToString((*customerData)["empNo"])                  //坐席号
-			statusMap := map[string]string{
-				"status0":     "08",
-				"status1":     "07",
-				"status2":     "06",
-				"status3":     "05",
-				"status4":     "04",
-				"status6":     "00",
-				"status5":     "01",
-				"spaceNumber": "02",
-				"phoneDown":   "02",
-			}
-			if status999 != "" {
-				status999 = statusMap[status999]
-			} else {
-				status999 = "01"
-			}
-			top_cluetype := "172"
-			sub_cluetype := ""
-			cluetypeData := TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"name": "其他-" + source}, "", "")
-			if cluetypeData != nil {
-				sub_cluetype = common.ObjToString((*cluetypeData)["code"])
-			}
-			wantGoods = strings.ReplaceAll(wantGoods, "剑鱼大会员", "大会员")
-			wantGoods = strings.ReplaceAll(wantGoods, "数据导出", "数据流量包")
-			if isPolicymaker == "是" {
-				isPolicymaker = "决策人"
-			} else {
-				isPolicymaker = "使用人"
-			}
-			areaCodeArr := []string{}
-			areaCode := ""
-			for _, v := range strings.Split(area, ",") {
-				areaCodeArr = append(areaCodeArr, AreaCode[v])
+	}
+	//同一公司名称(以客户详情-组织机构-公司名称)下的线索需分配给同1人
+
+	saveMap = map[string]interface{}{
+		"clue_id":                   clueId,
+		"transfertime":              nowTime,
+		"service_starttime":         starttime,
+		"service_endtime":           endtime,
+		"ent_id":                    entId,
+		"is_task":                   1,
+		"tasktime":                  nowTime,
+		"taskstatus":                0,
+		"tasksource":                "1",
+		"is_admin":                  1,
+		"product_access":            product,
+		"buy_subject":               buy_subject,
+		"relationship_building_way": 1,
+		"inventory_way":             1,
+		"training_way":              1,
+		"is_pre_sales_training":     0,
+		"service_stage":             1,
+		"company_name":              company_name,
+	}
+	if TiDb.Count("dwd_f_csm_customer_info", map[string]interface{}{"clue_id": clueId}) > 0 {
+		csmdata := TiDb.FindOne("dwd_f_csm_customer_info", map[string]interface{}{"clue_id": clueId}, "", "")
+		if csmdata != nil && len(*csmdata) > 0 {
+			id := gconv.Int64((*csmdata)["id"])
+			log.Println(1111111, id, orderCode)
+			//'已移交销售,0移交客成 1移交销售',
+			is_transfer := gconv.Int64((*csmdata)["is_transfer"])
+			customerPositionId, customerName := cAutoDraw(0, orderPositionId, salesperson, saleDep, true, csmdata)
+			log.Println("移交客成positionId", customerPositionId, customerName, saleDep, orderPositionId, salesperson, true)
+			oldName := gconv.String((*csmdata)["name"])
+			updateMap := map[string]interface{}{
+				"is_transfer":           0,
+				"is_renewal_protection": 0,
+				"product_access":        product,
+				"buy_subject":           buy_subject,
+				"transfertime":          nowTime,
+				"service_starttime":     starttime,
+				"service_endtime":       endtime,
+				"ent_id":                entId,
+				"company_name":          company_name,
+				"name":                  customerName,
+				"position_id":           customerPositionId,
 			}
-			if len(areaCodeArr) > 0 {
-				areaCode = strings.Join(areaCodeArr, ",")
+			if is_transfer == 1 {
+				//重新进去
+				updateMap["relationship_building_way"] = 1
+				updateMap["tasksource"] = "1"
+				updateMap["inventory_way"] = 1
+				updateMap["training_way"] = 1
+				updateMap["is_pre_sales_training"] = 0
+				updateMap["service_stage"] = 1
+				updateMap["is_task"] = 1
 			}
-			SalePositionId := getSeatNumberPositionId(seatNumber)
-			TiDb.Update("dwd_f_crm_clue_info", map[string]interface{}{"uid": uId}, map[string]interface{}{
-				"position_id":         SalePositionId,
-				"seatNumber":          seatNumber,
-				"is_assign":           -2,
-				"createtime":          createTime,
-				"updatetime":          lastUpdateTime,
-				"top_cluetype":        top_cluetype,
-				"sub_cluetype":        sub_cluetype,
-				"customer_demand":     customerNeeds,
-				"intended_products":   wantGoods,
-				"customer_budget":     customerBudget,
-				"contact_type":        isPolicymaker,
-				"position":            job,
-				"industry":            belongToIndustry,
-				"follow_project_area": areaCode,
+			TiDb.Update("dwd_f_csm_customer_info", map[string]interface{}{"clue_id": clueId}, updateMap)
+			TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
+				"clue_id":     clueId,
+				"position_id": customerPositionId,
+				"change_type": "成交客户移交",
+				"new_value":   "移交至客户成功组",
+				"createtime":  nowTime,
+				"BCPCID":      common.GetRandom(32),
+				"operator_id": -1,
 			})
-		}*/
-		//
-		entIds := common.IntAll(data["ent_id"])
-		positionId, name = cAutoDraw(entIds)
-		log.Println("移交客成positionId", positionId, name)
-		saveMap = map[string]interface{}{
-			"clue_id":                   clueId,
-			"transfertime":              nowTime,
-			"position_id":               positionId,
-			"name":                      name,
-			"service_starttime":         starttime,
-			"service_endtime":           endtime,
-			"ent_id":                    entId,
-			"is_task":                   1,
-			"tasktime":                  nowTime,
-			"taskstatus":                0,
-			"tasksource":                "1",
-			"is_admin":                  1,
-			"product_access":            product,
-			"buy_subject":               buy_subject,
-			"relationship_building_way": 1,
-			"inventory_way":             1,
-			"training_way":              1,
-			"is_pre_sales_training":     0,
-			"service_stage":             1,
-			"company_name":              company_name,
-		}
-		if TiDb.Count("dwd_f_csm_customer_info", map[string]interface{}{"clue_id": clueId}) > 0 {
-			csmdata := TiDb.FindOne("dwd_f_csm_customer_info", map[string]interface{}{"clue_id": clueId}, "", "")
-			if csmdata != nil && len(*csmdata) > 0 {
-				TiDb.Update("dwd_f_csm_customer_info", map[string]interface{}{"clue_id": clueId}, map[string]interface{}{
-					"is_transfer":           0,
-					"is_renewal_protection": 0,
-					"product_access":        product,
-					"buy_subject":           buy_subject,
-					"transfertime":          nowTime,
-					"service_starttime":     starttime,
-					"service_endtime":       endtime,
-					"ent_id":                entId,
-					"company_name":          company_name,
-				})
-				TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
-					"clue_id":     clueId,
-					"position_id": (*csmdata)["position_id"],
-					"change_type": "成交客户移交",
-					"new_value":   "移交至客户成功组",
-					"createtime":  nowTime,
-					"BCPCID":      common.GetRandom(32),
-					"operator_id": -1,
-				})
+			if customerPositionId > 0 && is_transfer == 1 {
 				TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
 					"clue_id":      clueId,
-					"position_id":  (*csmdata)["position_id"],
+					"position_id":  customerPositionId,
 					"change_field": "position_id",
 					"change_type":  "客户成功经理",
-					"old_value":    "/",
-					"new_value":    (*csmdata)["name"],
+					"old_value":    common.If(oldName != customerName, customerName, common.If(oldName == "", "/", oldName)),
+					"new_value":    customerName,
 					"createtime":   nowTime,
 					"BCPCID":       common.GetRandom(32),
 					"operator_id":  -1,
 				})
-				TiDb.Update("dwd_f_crm_clue_info", map[string]interface{}{"id": clueId}, map[string]interface{}{"is_transfer": 1, "updatetime": nowTime, "name": userName})
-			}
-		} else {
-			cId, ok, updateId1, updateId2, updateId3 := int64(-1), false, int64(-1), int64(-1), int64(-1)
-			if TiDb.ExecTx("保存客户", func(tx *sql.Tx) bool {
-				cId = TiDb.InsertByTx(tx, "dwd_f_csm_customer_info", saveMap)
-				ok = TiDb.UpdateByTx(tx, "dwd_f_crm_clue_info", map[string]interface{}{"id": clueId}, map[string]interface{}{"is_transfer": 1, "updatetime": nowTime, "name": userName})
-				updateId1 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
+				TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
 					"clue_id":     clueId,
-					"position_id": positionId,
+					"position_id": customerPositionId,
 					"change_type": "加入任务车",
 					"new_value":   "未建联",
 					"createtime":  nowTime,
 					"BCPCID":      common.GetRandom(32),
 					"operator_id": -1,
 				})
-				updateId2 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
+			}
+			KcSend(orderCode, customerName)
+			TiDb.Update("dwd_f_crm_clue_info", map[string]interface{}{"id": clueId}, map[string]interface{}{"is_transfer": 1, "updatetime": nowTime, "name": userName})
+		}
+	} else {
+		entIds := common.IntAll(data["ent_id"])
+		customerPositionId, customerName := cAutoDraw(entIds, orderPositionId, salesperson, saleDep, false, nil)
+		log.Println("移交客成positionId", customerPositionId, customerName, saleDep, orderPositionId, salesperson, false)
+		cId, ok, updateId1, updateId2, updateId3 := int64(0), false, int64(0), int64(0), int64(0)
+		if TiDb.ExecTx("保存客户", func(tx *sql.Tx) bool {
+			saveMap["position_id"] = customerPositionId
+			saveMap["name"] = customerName
+			cId = TiDb.InsertByTx(tx, "dwd_f_csm_customer_info", saveMap)
+			ok = TiDb.UpdateByTx(tx, "dwd_f_crm_clue_info", map[string]interface{}{"id": clueId}, map[string]interface{}{"is_transfer": 1, "updatetime": nowTime, "name": userName})
+			if customerPositionId > 0 {
+				updateId1 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
 					"clue_id":     clueId,
-					"position_id": positionId,
-					"change_type": "成交客户移交",
-					"new_value":   "移交至客户成功组",
+					"position_id": customerPositionId,
+					"change_type": "加入任务车",
+					"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,
+					"position_id":  customerPositionId,
 					"change_field": "position_id",
 					"change_type":  "客户成功经理",
 					"old_value":    "/",
-					"new_value":    name,
+					"new_value":    customerName,
 					"createtime":   nowTime,
 					"BCPCID":       common.GetRandom(32),
 					"operator_id":  -1,
 				})
-				return cId > -1 && ok && updateId1 > -1 && updateId2 > -1 && updateId3 > -1
-			}) {
-				TiDb.UpdateOrDeleteBySql(`update dwd_f_csm_customer_autodraw_record set count = count + 1 where name = ?`, name)
-				log.Println("保存客户成功")
-			} else {
-				log.Println("保存客户失败!!!", clueId, cId, ok, updateId1, updateId2, updateId3, " 用户信息 ", name, positionId, uId)
-			}
-		}
-		return status
-	} else {
-		log.Println("客户未查到线索!!!", uId)
-		if isExists, _ := redis.Exists("bidx", "bidx_uId_"+uId); isExists {
-			redisInt := redis.GetInt("bidx", "bidx_uId_"+uId)
-			if redisInt > 2 {
-				return 1
-			} else {
-				redis.Incr("bidx", "bidx_uId_"+uId)
-				return 0
 			}
+			KcSend(orderCode, customerName)
+			updateId2 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
+				"clue_id":     clueId,
+				"position_id": customerPositionId,
+				"change_type": "成交客户移交",
+				"new_value":   "移交至客户成功组",
+				"createtime":  nowTime,
+				"BCPCID":      common.GetRandom(32),
+				"operator_id": -1,
+			})
+			return cId > -1 && ok && updateId1 > -1 && updateId2 > -1 && updateId3 > -1
+		}) {
+			//TiDb.UpdateOrDeleteBySql(`update dwd_f_csm_customer_autodraw_record set count = count + 1 where name = ?`, name)
+			log.Println("保存客户成功")
 		} else {
-			redis.Put("bidx", "bidx_uId_"+uId, 1, 3600)
-			return 0
+			log.Println("保存客户失败!!!", clueId, cId, ok, updateId1, updateId2, updateId3, " 用户信息 ", customerName, customerPositionId, uId)
 		}
 	}
+	return status
 }
 
-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) and resign = 0`
+func cAutoDraw(entId int, orderPositionId int64, salesperson, saleDep string, isExist bool, csmdata *map[string]interface{}) (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) and resign = 0 `
 	data := TiDb.SelectBySql(query)
-	if data != nil && len(*data) > 0 {
-		if entId > 0 {
-			entdata := TiDb.FindOne("dwd_f_csm_customer_info", map[string]interface{}{"ent_id": entId}, "", "")
-			if entdata != nil && len(*entdata) > 0 {
-				positionId = common.Int64All((*entdata)["position_id"])
-				name = common.ObjToString((*entdata)["name"])
-				return
-			}
-		}
-		sql := `select a.name,a.count from dwd_f_csm_customer_autodraw_record a INNER JOIN dwd_d_crm_department_level_succbi b on (a.name = b.name) where b.resign = 0`
-		countData := TiDb.SelectBySql(sql)
-		if countData != nil && len(*countData) > 0 {
+	if data == nil || len(*data) == 0 {
+		return
+	}
+	//判断是否需要新增客成数据
+	if isExist {
+		//用户存在客成数据
+		positionid := common.Int64All((*csmdata)["position_id"])
+		if positionid != 0 {
+			//以前没有,需要找一个新的
 			for _, v := range *data {
-				//判断是否有新员工
-				isOk := false
-				for _, vv := range *countData {
-					if common.ObjToString(v["name"]) == common.ObjToString(vv["name"]) {
-						isOk = true
-					}
-				}
-				//有新员工直接分给新员工
-				if !isOk {
-					name = common.ObjToString(v["name"])
-					rData := TiDb.FindOne("dwd_f_csm_customer_autodraw_record", map[string]interface{}{}, "", "count desc")
-					TiDb.Insert("dwd_f_csm_customer_autodraw_record", map[string]interface{}{
-						"name":  name,
-						"count": common.Int64All((*rData)["count"]),
-					})
-					break
+				deptPositionId := gconv.Int64(v["position_id"])
+				if deptPositionId == positionid {
+					positionId = positionid
+					name = common.ObjToString((*csmdata)["name"])
+					return
 				}
 			}
-			res := int64(0)
-			countres := 0
-			for _, v := range *countData {
-				if countres == 0 {
-					res = common.Int64All(v["count"])
-					name = common.ObjToString(v["name"])
-				} else {
-					if common.Int64All(v["count"]) <= res {
-						res = common.Int64All(v["count"])
-						name = common.ObjToString(v["name"])
+		}
+		//原始用户已离职 查看订单是否有合适的订单
+		if saleDep == "客户成功组" {
+			positionId = orderPositionId
+			name = salesperson
+			return
+		}
+	}
+	//客成数据不存在的时候
+	//查找企业有没有其他信息
+	if entId > 0 {
+		entdata := TiDb.Find("dwd_f_csm_customer_info", map[string]interface{}{"ent_id": entId}, "", "", -1, -1)
+		if entdata != nil && len(*entdata) > 0 {
+			for _, v := range *entdata {
+				positionid := common.Int64All(v["position_id"])
+				name = common.ObjToString(v["name"])
+				for _, v := range *data {
+					deptPositionId := gconv.Int64(v["position_id"])
+					if deptPositionId == positionId {
+						positionId = positionid
+						name = common.ObjToString((*csmdata)["name"])
+						return
 					}
 				}
-				countres++
 			}
 		}
-		for _, v := range *data {
-			if name == common.ObjToString(v["name"]) {
-				positionId = common.Int64All(v["position_id"])
-			}
+		//原始用户已离职 或者没有查找相关企业客成信息    以订单信息为主
+		if saleDep == "客户成功组" {
+			positionId = orderPositionId
+			name = salesperson
 		}
+		return
+		//没有相同企业的客成信息
+	} else {
+		//没有人  分配给自己
+		if saleDep == "客户成功组" {
+			positionId = orderPositionId
+			name = salesperson
+			return
+		}
+		return
 	}
-	return
 }
 
 func kcAuto() {
@@ -577,25 +611,45 @@ func refundAuto() {
 	log.Println("自动移交销售定时任务开始")
 	findNowTime := time.Now().AddDate(0, 0, -db.ExpirationPeriod).Format(date.Date_Full_Layout)
 	nowTime := time.Now().Format(date.Date_Full_Layout)
+	mailData := map[string][]map[string]interface{}{}
 	TiDb.SelectByBath(100, func(l *[]map[string]interface{}) bool {
 		for _, v := range *l {
-			saleId, cluename, company_nature, company_verification, uid, phone := int64(0), "", 0, 0, "", ""
+			saleId, cluename, company_nature, company_verification, uid, phone, userName := int64(0), "", 0, 0, "", "", ""
 			clueId := common.Int64All(v["clue_id"])
+			company_name := gconv.String(v["company_name"])
 			name := common.ObjToString(v["name"])
 			kcposition_id := common.Int64All(v["position_id"])
 			isRenewalProtection := common.IntAll(v["is_renewal_protection"])
-			clueData := TiDb.FindOne("dwd_f_crm_clue_info", map[string]interface{}{"id": clueId}, "phone,company_nature,company_verification,cluename,userid,position_id,uid", "")
+			clueData := TiDb.FindOne("dwd_f_crm_clue_info", map[string]interface{}{"id": clueId}, "name,phone,company_nature,company_verification,cluename,userid,position_id,uid", "")
 			if clueData != nil && len(*clueData) > 0 {
 				saleId = common.Int64All((*clueData)["position_id"])
 				cluename = common.ObjToString((*clueData)["cluename"])
+				userName = gconv.String((*clueData)["name"])
 				company_nature = common.IntAll((*clueData)["company_nature"])
 				company_verification = common.IntAll((*clueData)["company_verification"])
 				uid = common.ObjToString((*clueData)["uid"])
 				phone = common.ObjToString((*clueData)["phone"])
 			}
+			//查询即将到期数据
+			if isRenewalProtection == 0 {
+				aaa := TiDb.CountBySql(`select count(1) from dwd_f_userbase_order_info where uid=?   and (product_type = "企业商机管理" or product_type = "大会员") and order_status = 1  and  refund_status!=1 and vip_endtime < ? and  vip_endtime > ? `, uid, time.Now().AddDate(0, 0, -db.ExpirationPeriod+1).Format(date.Date_Short_Layout), time.Now().AddDate(0, 0, -db.ExpirationPeriod).Format(date.Date_Short_Layout))
+				log.Println(aaa)
+				if aaa > 0 {
+					//即将到期
+					mailData[name] = append(mailData[name], map[string]interface{}{
+						"company_name": company_name,
+						"phone":        phone,
+						"userName":     userName,
+						"remrk":        "1天后即将移交",
+						"reason":       "成交客户续费失败",
+					})
+					continue
+				}
+
+			}
 			isFull := FindUpperLimit(gconv.String(saleId), "", false)
 			isAllRefund := false
-			myOrders := TiDb.SelectBySql(`select refund_status from dwd_f_userbase_order_info where uid=? and (product_type = "企业商机管理" or product_type = "大会员") and order_status = 1  and vip_endtime < ?`, uid, findNowTime)
+			myOrders := TiDb.SelectBySql(`select refund_status from dwd_f_userbase_order_info where uid=? and (product_type = "企业商机管理" or product_type = "大会员") and order_status = 1 `, uid)
 			if myOrders != nil {
 				refundCount := 0
 				for _, v := range *myOrders {
@@ -650,6 +704,13 @@ func refundAuto() {
 					"BCPCID":      common.GetRandom(32),
 					"operator_id": -1,
 				})
+				mailData[name] = append(mailData[name], map[string]interface{}{
+					"company_name": company_name,
+					"phone":        phone,
+					"userName":     userName,
+					"remrk":        "已移交",
+					"reason":       "成交客户申请退款",
+				})
 				TiDb.UpdateOrDeleteBySql(`UPDATE dwd_f_csm_customer_info SET is_transfer=1 WHERE clue_id = ?`, clueId)
 			} else {
 				order1 := TiDb.SelectBySql(`select id from dwd_f_userbase_order_info where uid=? and (product_type = "企业商机管理" or product_type = "大会员") and vip_endtime > ? and order_status = 1 `, uid, findNowTime)
@@ -662,24 +723,34 @@ func refundAuto() {
 								vip_endtime := common.ObjToString(vv["vip_endtime"])
 								vip_endtimes, _ := time.ParseInLocation(date.Date_Full_Layout, vip_endtime, time.Local)
 								//查询申请保护时间
-								renewalTime := time.Time{}
+								renewalTime := time.Now()
 								timeData := TiDb.SelectBySql(`select  max(createtime) as createtime from   dwd_f_crm_clue_change_record   where   clue_id =  ?  and  change_type="申请续费保护"`, clueId)
 								if timeData != nil && len(*timeData) > 0 {
-									renewalTime, _ = time.ParseInLocation(date.Date_Full_Layout, gconv.String((*timeData)[0]["createtime"]), time.Local)
+									if gconv.String(gconv.String((*timeData)[0]["createtime"])) != "" {
+										renewalTime, _ = time.ParseInLocation(date.Date_Short_Layout, gconv.String((*timeData)[0]["createtime"]), time.Local)
+									}
 								}
 								renewalInt := renewalTime.Unix()
 								log.Println("申请保护期时间", clueId, renewalInt)
+								log.Println("申请保护期时间222", time.Now().Unix()-vip_endtimes.Unix(), (db.HandoverCycle-1)*86400, (db.HandoverCycle)*86400)
+								log.Println("申请保护期时间333", (db.HandoverCycle-1)*86400 < time.Now().Unix()-vip_endtimes.Unix(), time.Now().Unix()-vip_endtimes.Unix() < (db.HandoverCycle)*86400)
 								//查看服务到期时间
 								if renewalInt != 0 && renewalInt < db.CustomerTime {
 									//三个月
 									if time.Now().Unix()-vip_endtimes.Unix() < 3*30*86400 {
 										isOk = true
 									}
-								} else {
-									//一个月
-									if time.Now().Unix()-vip_endtimes.Unix() < db.HandoverCycle*86400 {
-										isOk = true
-									}
+								} else if (db.HandoverCycle-2)*86400 < time.Now().Unix()-vip_endtimes.Unix() && time.Now().Unix()-vip_endtimes.Unix() < (db.HandoverCycle-1)*86400 {
+									//提前一天提示
+									mailData[name] = append(mailData[name], map[string]interface{}{
+										"company_name": company_name,
+										"phone":        phone,
+										"userName":     userName,
+										"remrk":        "1天后即将移交",
+										"reason":       "成交客户续费失败",
+									})
+								} else if time.Now().Unix()-vip_endtimes.Unix() < db.HandoverCycle*86400 {
+									isOk = true
 								}
 							}
 						}
@@ -747,7 +818,15 @@ func refundAuto() {
 								TiDb.UpdateOrDeleteBySql(`UPDATE dwd_f_crm_clue_info SET is_unfollow=0,updatetime=?,trailstatus="01",top_cluetype="532",sub_cluetype="537",is_transfer=0 WHERE id = ?`, nowTime, clueId)
 							}
 						}
-
+						if kcposition_id > 0 {
+							mailData[name] = append(mailData[name], map[string]interface{}{
+								"company_name": company_name,
+								"phone":        phone,
+								"userName":     userName,
+								"remrk":        "已移交",
+								"reason":       "成交客户续费失败",
+							})
+						}
 						TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
 							"clue_id":      clueId,
 							"position_id":  common.If(kcposition_id > 0, kcposition_id, -1),
@@ -822,7 +901,13 @@ func refundAuto() {
 			}
 		}
 		return true
-	}, `select ent_id,clue_id,position_id,name,is_renewal_protection from dwd_f_csm_customer_info where is_transfer = 0`)
+	}, `select ent_id,clue_id,position_id,name,is_renewal_protection,company_name from dwd_f_csm_customer_info where is_transfer = 0`)
+	//}, `select ent_id,clue_id,position_id,name,is_renewal_protection,company_name from dwd_f_csm_customer_info where clue_id =1471384`)
+
+	//移交电销提醒
+	for i, v := range mailData {
+		ExitKcSend(i, v)
+	}
 	log.Println("自动移交销售定时任务结束")
 }
 
@@ -864,6 +949,8 @@ func FindSaleRecord(orderCode string) (dept string, positionId int64, position s
 			saler_dept = "销售部"
 		} else if strings.Contains(saler_dept, "市场") {
 			saler_dept = "市场部"
+		} else if strings.Contains(saler_dept, "客户成功") {
+			saler_dept = "客户成功组"
 		} else {
 			saler_dept = ""
 		}
@@ -871,3 +958,330 @@ func FindSaleRecord(orderCode string) (dept string, positionId int64, position s
 	}
 	return "", int64(0), ""
 }
+func kcClue(userId, uId, seatNumber, cluename, top_cluetype, sub_cluetype,
+	name, phone, position, sourceCode, industry, follow_project_area,
+	role, item, subname, topname, remark, demand, department, departments, saleName, source string,
+	positionId int64, isGroup, isCommerce int,
+	keywords []string) bool {
+	clueId, uodateId1, uodateId2, uodateId3, uodateId4, uodateId5 := int64(0), int64(0), int64(0), int64(0), int64(0), int64(0)
+	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")
+	if TiDb.ExecTx("保存线索", func(tx *sql.Tx) bool {
+		clueId = TiDb.InsertByTx(tx, "dwd_f_crm_clue_info", map[string]interface{}{
+			"userid":               userId,
+			"uid":                  uId,
+			"seatNumber":           seatNumber,
+			"position_id":          positionId,
+			"is_assign":            common.If(positionId > 0, 1, 0),
+			"comeintime":           nowTime,
+			"createtime":           nowTime,
+			"updatetime":           nowTime,
+			"cluename":             cluename,
+			"top_cluetype":         top_cluetype,
+			"sub_cluetype":         sub_cluetype,
+			"trailstatus":          "01",
+			"name":                 name,
+			"phone":                phone,
+			"position":             position,
+			"department":           common.If(sourceCode == "app_xzcyh", departments, department),
+			"industry":             industry,
+			"follow_project_area":  follow_project_area,
+			"role":                 role,
+			"comeinsource_private": 2,
+			"is_task":              1,
+			"task_time":            nowTime,
+			"tasktime":             common.If(item == "users", nowTimes, nowTime),
+			"taskstatus":           0,
+			"tasksource":           "线索自动分配" + "-" + topname + "-" + subname,
+			"business_scope":       common.If(sourceCode == "app_xzcyh", keywords, nil),
+			"company_nature":       isGroup,
+			"company_verification": isCommerce,
+			"remark":               remark,
+			"customer_demand":      demand,
+			"FREEZE_TIME":          nowTime,
+			"label":                1,
+			"labelChangeTime":      time.Now().Format("2006-01-02"),
+		})
+		uodateId1 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
+			"clue_id":     clueId,
+			"position_id": positionId,
+			"change_type": "创建线索",
+			"new_value":   "系统自动创建",
+			"createtime":  nowTime,
+			"BCPCID":      common.GetRandom(32),
+			"operator_id": -1,
+		})
+		uodateId2 = 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":    "/",
+			"new_value":    saleName,
+			"createtime":   nowTime,
+			"BCPCID":       common.GetRandom(32),
+			"operator_id":  -1,
+		})
+		uodateId3 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
+			"clue_id":      clueId,
+			"position_id":  positionId,
+			"change_field": "trailstatus",
+			"change_type":  "基本信息变更",
+			"old_value":    "商机线索",
+			"new_value":    "新增",
+			"createtime":   nowTime,
+			"BCPCID":       common.GetRandom(32),
+			"operator_id":  -1,
+		})
+		uodateId5 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
+			"clue_id":      clueId,
+			"position_id":  positionId,
+			"change_field": "top_cluetype",
+			"change_type":  "基本信息变更",
+			"old_value":    "/",
+			"new_value":    topname,
+			"createtime":   nowTime,
+			"BCPCID":       common.GetRandom(32),
+			"operator_id":  -1,
+		})
+		uodateId5 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
+			"clue_id":      clueId,
+			"position_id":  positionId,
+			"change_field": "sub_cluetype", //222
+			"change_type":  "基本信息变更",
+			"old_value":    "/",
+			"new_value":    subname,
+			"createtime":   nowTime,
+			"BCPCID":       common.GetRandom(32),
+			"operator_id":  -1,
+		})
+		return clueId > -1 && uodateId1 > -1 && uodateId2 > -1 && uodateId3 > -1 && uodateId4 > -1 && uodateId5 > -1
+	}) {
+		log.Println("线索分配成功")
+		if TiDb.Count("dwd_f_userbase_contacts", map[string]interface{}{"phone": phone}) == 0 {
+			TiDb.Insert("dwd_f_userbase_contacts", map[string]interface{}{
+				"status":      1,
+				"is_delete":   1,
+				"createtime":  nowTime,
+				"updatetime":  nowTime,
+				"phone":       phone,
+				"baseinfo_id": uId,
+				"SOURCE":      source,
+			})
+		}
+		return true
+	}
+	return false
+}
+
+type OrderInfo struct {
+	Id          int64
+	UserId      string
+	CompanyName string
+	ProductType string
+	OrderCode   string
+	PayMoney    float64
+	ReturnMoney float64
+	UserPhone   string
+	StartEnd    string
+	DisKcName   string
+	UserName    string
+	SeriveList  []string
+	SaleName    string
+}
+
+// 客成发送邮箱
+func KcSend(orderCode, personName string) {
+	log.Println("客成发邮件", orderCode)
+	bigmemberService := map[int64]string{}
+	combo := map[int64]string{}
+	Mysql.SelectByBath(1, func(l *[]map[string]interface{}) bool {
+		bigmemberService[common.Int64All((*l)[0]["id"])] = common.ObjToString((*l)[0]["s_name"])
+		return true
+	}, `select id,s_name from jianyu.bigmember_service`)
+	Mysql.SelectByBath(1, func(l *[]map[string]interface{}) bool {
+		combo[common.Int64All((*l)[0]["id"])] = common.ObjToString((*l)[0]["s_name"])
+		return true
+	}, `select id,s_name from jianyu.bigmember_combo`)
+	orderInfo := KcOrderFormat(orderCode, bigmemberService, combo)
+	if orderInfo != nil {
+		tableAppend := ""
+		if len(orderInfo.SeriveList) > 0 {
+			tableAppend = fmt.Sprintf(db.KeCheng.Mail.ServiceList, strings.Join(orderInfo.SeriveList, ","))
+		}
+		if orderInfo.ReturnMoney > 0 {
+			tableAppend += fmt.Sprintf(db.KeCheng.Mail.ReturnMoney, orderInfo.ReturnMoney)
+		}
+		table := ""
+		orderInfo.DisKcName = personName
+		deptData := Mysql.SelectBySql("select b.mail from jianyu.entniche_department_user a inner join jianyu.entniche_user b on a.dept_id=? and a.user_id=b.id and b.name=? ", db.KeCheng.DeptId, personName)
+		adminData := Mysql.SelectBySql(`	select c.mail   from entniche_department_user  a   INNER JOIN     entniche_user_role b  on  a.dept_id=59005 and  a.user_id = b.user_id and  b.role_id=2  INNER JOIN   entniche_user c  on a.user_id=c.id`)
+		table += fmt.Sprintf(db.KeCheng.Mail.Table, orderInfo.ProductType, orderInfo.CompanyName, orderInfo.UserPhone, orderInfo.UserName, orderInfo.OrderCode, orderInfo.PayMoney, orderInfo.StartEnd, orderInfo.DisKcName, orderInfo.SaleName, tableAppend)
+		adminMailStr := ""
+		if adminData != nil && len(*adminData) > 0 {
+			adminMailStr = gconv.String((*adminData)[0]["mail"])
+		}
+		//发送邮件
+		if personName == "" {
+			if adminData != nil && len(*adminData) > 0 {
+				//发送给管理员
+				if adminMailStr != "" {
+					gmail := &mail.GmailAuth{
+						SmtpHost: db.Mail.SmtpHost,
+						SmtpPort: db.Mail.SmtpPort,
+						User:     db.Mail.User,
+						Pwd:      db.Mail.Pwd,
+					}
+					status := mail.GSendMail_q("剑鱼标讯", adminMailStr, "", "", db.KeCheng.Title, fmt.Sprintf(db.KeCheng.Mail.Content, table), "", "", gmail)
+					if status {
+						log.Println("客成发邮件 send mail success", table, adminMailStr)
+					}
+				}
+			}
+			return
+		}
+		//当事人  管理员发送
+		if deptData != nil && len(*deptData) > 0 {
+			mailStr := gconv.String((*deptData)[0]["mail"])
+			if mailStr != "" || adminMailStr != "" {
+				gmail := &mail.GmailAuth{
+					SmtpHost: db.Mail.SmtpHost,
+					SmtpPort: db.Mail.SmtpPort,
+					User:     db.Mail.User,
+					Pwd:      db.Mail.Pwd,
+				}
+				status := true
+				if mailStr == "" {
+					status = mail.GSendMail_q("剑鱼标讯", adminMailStr, "", "", db.KeCheng.Title, fmt.Sprintf(db.KeCheng.Mail.Content, table), "", "", gmail)
+				} else {
+					status = mail.GSendMail_q("剑鱼标讯", mailStr, adminMailStr, "", db.KeCheng.Title, fmt.Sprintf(db.KeCheng.Mail.Content, table), "", "", gmail)
+				}
+				if status {
+					log.Println("客成发邮件 send mail success", table, mailStr, adminMailStr)
+				}
+			}
+		}
+	}
+}
+func ExitKcSend(personName string, infoList []map[string]interface{}) {
+	//退出客成 即将退出客成信息
+	deptData := Mysql.SelectBySql("select b.mail from jianyu.entniche_department_user a inner join jianyu.entniche_user b on a.dept_id=? and a.user_id=b.id and b.name=? ", db.KeCheng.DeptId, personName)
+	adminData := Mysql.SelectBySql(`	select c.mail   from entniche_department_user  a   INNER JOIN     entniche_user_role b  on  a.dept_id=59005 and  a.user_id = b.user_id and  b.role_id=2  INNER JOIN   entniche_user c  on a.user_id=c.id`)
+	if personName == "" {
+		//没有客成人员
+		adminMailStr := ""
+		if adminData != nil && len(*adminData) > 0 {
+			adminMailStr = gconv.String((*adminData)[0]["mail"])
+		}
+		if adminMailStr != "" {
+			gmail := &mail.GmailAuth{
+				SmtpHost: db.Mail.SmtpHost,
+				SmtpPort: db.Mail.SmtpPort,
+				User:     db.Mail.User,
+				Pwd:      db.Mail.Pwd,
+			}
+			//正文拼接
+			startStr := `<html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, initial-scale=1.0"><style>table{width:100%;border-collapse:collapse}th,td{border:1px solid#000;padding:8px;text-align:left}th{background-color:#f2f2f2}</style></head><body><p>以下客户已从或即将从客成系统退出,并移交销售跟进,请收悉,客户明细如下:</p><table><thead><tr><th>序号</th><th>公司名称</th><th>联系人</th><th>姓名</th><th>移交状态</th><th>移交销售原因</th></tr></thead><tbody>`
+			for i, v := range infoList {
+				startStr += fmt.Sprintf(`<tr><td>%d</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>`, i+1, gconv.String(v["company_name"]), gconv.String(v["phone"]), gconv.String(v["userName"]), gconv.String(v["remrk"]), gconv.String(v["reason"]))
+			}
+			endStr := `</tbody></table><p></body></html>`
+			startStr += endStr
+			status := mail.GSendMail_q("剑鱼标讯", adminMailStr, "", "", "客户退出客成系统通知", startStr, "", "", gmail)
+			if status {
+				log.Println("客成发邮件 send mail success", startStr, adminMailStr)
+			}
+		}
+		return
+	}
+	if deptData != nil && len(*deptData) > 0 {
+		mailStr := gconv.String((*deptData)[0]["mail"])
+		adminMailStr := ""
+		if adminData != nil && len(*adminData) > 0 {
+			adminMailStr = gconv.String((*adminData)[0]["mail"])
+		}
+		if mailStr != "" || adminMailStr != "" {
+			gmail := &mail.GmailAuth{
+				SmtpHost: db.Mail.SmtpHost,
+				SmtpPort: db.Mail.SmtpPort,
+				User:     db.Mail.User,
+				Pwd:      db.Mail.Pwd,
+			}
+			//正文拼接
+			startStr := `<html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, initial-scale=1.0"><style>table{width:100%;border-collapse:collapse}th,td{border:1px solid#000;padding:8px;text-align:left}th{background-color:#f2f2f2}</style></head><body><p>以下客户已从或即将从客成系统退出,并移交销售跟进,请收悉,客户明细如下:</p><table><thead><tr><th>序号</th><th>公司名称</th><th>联系人</th><th>姓名</th><th>移交状态</th><th>移交销售原因</th></tr></thead><tbody>`
+			for i, v := range infoList {
+				startStr += fmt.Sprintf(`<tr><td>%d</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>`, i+1, gconv.String(v["company_name"]), gconv.String(v["phone"]), gconv.String(v["userName"]), gconv.String(v["remrk"]), gconv.String(v["reason"]))
+			}
+			endStr := `</tbody></table><p></body></html>`
+			startStr += endStr
+			status := true
+			if mailStr == "" {
+				status = mail.GSendMail_q("剑鱼标讯", adminMailStr, "", "", "客户退出客成系统通知", startStr, "", "", gmail)
+			} else {
+				status = mail.GSendMail_q("剑鱼标讯", mailStr, adminMailStr, "", "客户退出客成系统通知", startStr, "", "", gmail)
+			}
+			if status {
+				log.Println("客成发邮件 send mail success", startStr, mailStr)
+			}
+		}
+	}
+}
+func KcOrderFormat(orderCode string, bigmemberService, combo map[int64]string) *OrderInfo {
+	orderData := Mysql.SelectBySql(`SELECT a.id,a.order_code,a.pay_money,a.user_phone,a.vip_starttime,a.vip_endtime,a.product_type,a.filter,a.user_id,a.ent_id,a.company_name,a.create_person,SUM(b.return_money) AS return_money 
+		FROM jianyu.dataexport_order a
+	LEFT JOIN return_money_record b ON (a.order_code=b.order_code)
+	WHERE a.order_code=? AND a.order_status=1 AND (a.product_type='大会员' OR a.product_type='大会员-子账号')
+	GROUP BY a.id ORDER BY a.autoUpdate`, orderCode)
+	data := &OrderInfo{}
+	if orderData != nil && len(*orderData) > 0 {
+		id := common.Int64All((*orderData)[0]["id"])
+		user_phone := common.ObjToString((*orderData)[0]["user_phone"])
+		user_id := common.ObjToString((*orderData)[0]["user_id"])
+		product_type := common.ObjToString((*orderData)[0]["product_type"])
+		serviceList := []string{}
+		if filter := common.ObjToString((*orderData)[0]["filter"]); filter != "" {
+			filterMap := map[string]interface{}{}
+			json.Unmarshal([]byte(filter), &filterMap)
+			if level := common.Int64All(filterMap["level"]); level == 5 {
+				product_type += "自定义版"
+				for _, serversId := range strings.Split(common.ObjToString(filterMap["serversId"]), ",") {
+					if serviceName := bigmemberService[common.Int64All(serversId)]; serviceName != "" {
+						serviceList = append(serviceList, serviceName)
+					}
+				}
+			} else {
+				product_type += combo[common.Int64All(filterMap["comboId"])]
+			}
+		}
+		//联系人姓名
+		sqlStr := `SELECT
+					a.phone,
+					b.NAME AS bname
+				FROM
+					dwd_f_userbase_contacts a
+					INNER JOIN dwd_f_crm_clue_info b ON (  a.phone =  ? AND a.baseinfo_id = b.uid )
+					LEFT JOIN dwd_f_csm_customer_info c ON ( b.id = c.clue_id)`
+		userName := ""
+		if user_phone != "" {
+			userData := TiDb.SelectBySql(sqlStr, user_phone)
+			if userData != nil && len(*userData) > 0 {
+				userName = gconv.String((*userData)[0]["bname"])
+			}
+		}
+		data = &OrderInfo{
+			Id:          id,
+			CompanyName: common.ObjToString((*orderData)[0]["company_name"]),
+			UserId:      user_id,
+			ProductType: product_type,
+			OrderCode:   orderCode,
+			PayMoney:    common.Float64All((*orderData)[0]["pay_money"]) / 100,
+			ReturnMoney: common.Float64All((*orderData)[0]["return_money"]) / 100,
+			UserPhone:   user_phone,
+			StartEnd:    fmt.Sprintf("%s--%s", strings.Split(common.ObjToString((*orderData)[0]["vip_starttime"]), " ")[0], strings.Split(common.ObjToString((*orderData)[0]["vip_endtime"]), " ")[0]),
+			SeriveList:  serviceList,
+			SaleName:    common.ObjToString((*orderData)[0]["create_person"]),
+			UserName:    userName,
+		}
+	}
+	return data
+}

+ 1 - 3
clueSync/main.go

@@ -145,9 +145,6 @@ func main() {
 	MgoQyxy = mongodb.NewMgoWithUser(db.MgoQyxy.Address, db.MgoQyxy.DbName, db.MgoQyxy.User, db.MgoQyxy.Password, db.MgoQyxy.DbSize)
 	InitArea()
 	InitProduct(db.ProductArr)
-	//nextYearActivity()
-	//kcSync()
-	//refundAuto() //客成移交销售
 	if *mode == 1 {
 		go ordersClue() //后台订单进线索
 		//一秒钟一次
@@ -162,6 +159,7 @@ func main() {
 		})
 		//5分钟一次
 		go p.VarTimeTask.RunInTimeSection("5分钟定时任务1", db.CornExp2Start, db.CornExp2End, db.CornExp2, func(dayFirst bool) {
+
 			users()               //新注册用户进线索
 			saleLeads()           //留资进线索
 			eventReg()            //渠道

+ 4 - 4
clueSync/sendMail.go

@@ -394,10 +394,10 @@ func sendInfo(to, cs, title, content string) {
 	log.Println("发送人:", to)
 	log.Println("抄送:", cs)
 	gmail := &mail.GmailAuth{
-		SmtpHost: "smtp.exmail.qq.com",
-		SmtpPort: 465,
-		User:     "public03@topnet.net.cn",
-		Pwd:      "ue9Rg9Sf4CVtdm5a",
+		SmtpHost: db.Mail.SmtpHost,
+		SmtpPort: db.Mail.SmtpPort,
+		User:     db.Mail.User,
+		Pwd:      db.Mail.Pwd,
 	}
 	status := mail.GSendMail_dx("剑鱼标讯", to, cs, "", title, content, "", "", gmail)
 	if status {

+ 28 - 0
clueSync/util.go

@@ -0,0 +1,28 @@
+package main
+
+import (
+	"fmt"
+	"time"
+)
+
+func TimeStrcount(start, end string) int64 {
+	timeFormat := "2006-01-02 15:04:05" // 定义时间格式
+	// 两个时间字符串
+	// 解析时间字符串为 Time 对象
+	startTime, err := time.Parse(timeFormat, start)
+	if err != nil {
+		fmt.Println("Error parsing start time:", err)
+		return 0
+	}
+	endTime, err := time.Parse(timeFormat, end)
+	if err != nil {
+		fmt.Println("Error parsing end time:", err)
+		return 0
+	}
+	// 计算时间差
+	diff := endTime.Sub(startTime)
+	// 获取相差的天数
+	days := int64(diff.Hours() / 24)
+	fmt.Printf("相差的天数: %d 天\n", days)
+	return days
+}