autoTask.go 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662
  1. package main
  2. import (
  3. "app.yhyue.com/moapp/jybase/mongodb"
  4. "database/sql"
  5. "fmt"
  6. "github.com/gogf/gf/v2/util/gconv"
  7. "log"
  8. "time"
  9. "app.yhyue.com/moapp/jybase/common"
  10. "app.yhyue.com/moapp/jybase/date"
  11. )
  12. func autoTask() {
  13. log.Println("超时未跟进定时任务开始")
  14. t := time.Now()
  15. nowTime := time.Now().Format(date.Date_Full_Layout)
  16. statusMap := map[string]int{
  17. "07": 2, //待签署客户
  18. "06": 2, //高意向客户
  19. "05": 3, //意向客户
  20. "04": 7, //潜在客户
  21. }
  22. //判断节假日
  23. for status, statusInt := range statusMap {
  24. count, counts := 0, 0
  25. for {
  26. count++
  27. currentTime := t.AddDate(0, 0, -count)
  28. if currentTime.Weekday() == time.Sunday || currentTime.Weekday() == time.Saturday {
  29. isok := false
  30. for k, v := range DateMap {
  31. if currentTime.Format(date.Date_Short_Layout) == k && v == 2 {
  32. isok = true
  33. }
  34. }
  35. if isok {
  36. counts++
  37. }
  38. } else {
  39. isok := true
  40. for k, v := range DateMap {
  41. if currentTime.Format(date.Date_Short_Layout) == k && v == 1 {
  42. isok = false
  43. }
  44. }
  45. if isok {
  46. counts++
  47. }
  48. }
  49. if counts >= statusInt {
  50. break
  51. }
  52. }
  53. statusMap[status] = count
  54. }
  55. log.Println(statusMap)
  56. for trailstatus := range map[string]string{
  57. "07": "", //待签署客户
  58. "06": "", //高意向客户
  59. "05": "", //意向客户
  60. "04": "", //潜在客户
  61. } {
  62. sql := `SELECT id,position_id,seatNumber,out_task_status FROM dwd_f_crm_clue_info
  63. WHERE trailstatus = ?`
  64. argsSelect := []interface{}{trailstatus}
  65. intime := ""
  66. sql += " AND comeintime <?"
  67. // nt := nexttime.(time.Time)
  68. nt := t.AddDate(0, 0, -statusMap[trailstatus])
  69. intime = nt.Format(date.Date_Full_Layout)
  70. argsSelect = append(argsSelect, intime)
  71. //
  72. TiDb.SelectByBath(100, func(l *[]map[string]interface{}) bool {
  73. for _, v := range *l {
  74. clueId := common.Int64All(v["id"])
  75. position_id := common.Int64All(v["position_id"])
  76. out_task_status := common.IntAll(v["out_task_status"])
  77. args2 := []interface{}{clueId}
  78. //获取跟进内容
  79. // sql1 := `select COUNT(1) FROM dwd_f_crm_trail_content WHERE clue_id =?;`
  80. sql2 := `SELECT COUNT(1) FROM dwd_f_crm_trail_content WHERE clue_id = ? and position_id = ?`
  81. if intime != "" {
  82. sql2 += ` and createtime > ?`
  83. args2 = append(args2, position_id)
  84. args2 = append(args2, intime)
  85. }
  86. //保留未跟进线索
  87. // if c1, c2 := TiDb.CountBySql(sql1, clueId), TiDb.CountBySql(sql2, args2...); (c1 != 0 && c2 > 0) || out_task_status == 1 {
  88. // log.Println("不满足线索过滤", clueId)
  89. // continue
  90. // }
  91. log.Println("intime ", clueId, intime, sql2)
  92. if c2 := TiDb.CountBySql(sql2, args2...); c2 > 0 || out_task_status == 1 {
  93. log.Println("不满足线索过滤", clueId)
  94. continue
  95. }
  96. if TiDb.Update("dwd_f_crm_clue_info", map[string]interface{}{"id": clueId}, map[string]interface{}{
  97. "is_task": 1,
  98. "task_time": nowTime,
  99. "tasktime": time.Now().Format(date.Date_Short_Layout) + " 10:00:00",
  100. "taskstatus": 0,
  101. "tasksource": "超时未跟进自动加车",
  102. }) {
  103. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  104. "clue_id": clueId,
  105. "position_id": position_id,
  106. "change_type": "加入任务车",
  107. "new_value": "超时未跟进自动加车",
  108. "createtime": nowTime,
  109. "BCPCID": common.GetRandom(32),
  110. "operator_id": -1,
  111. })
  112. }
  113. }
  114. return true
  115. }, sql, argsSelect...)
  116. }
  117. log.Println("超时未跟进定时任务结束")
  118. }
  119. func autoTasks() {
  120. log.Println("按照跟进时间提前一天进入任务车定时任务开始")
  121. nowTime2 := time.Now().Format(date.Date_Full_Layout)
  122. nextTime := time.Now().AddDate(0, 0, 1).Format(date.Date_Full_Layout)
  123. TiDb.SelectByBath(100, func(l *[]map[string]interface{}) bool {
  124. for _, v := range *l {
  125. clueId := common.Int64All(v["id"])
  126. position_id := common.Int64All(v["position_id"])
  127. out_task_status := common.IntAll(v["out_task_status"])
  128. if position_id > 0 {
  129. if out_task_status != 1 && position_id > 0 {
  130. if TiDb.Update("dwd_f_crm_clue_info", map[string]interface{}{"id": clueId}, map[string]interface{}{
  131. "is_task": 1,
  132. "task_time": nowTime2,
  133. "tasktime": nowTime2,
  134. "taskstatus": 0,
  135. "tasksource": "即将到达下次跟进时间",
  136. }) {
  137. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  138. "clue_id": clueId,
  139. "position_id": position_id,
  140. "change_type": "加入任务车",
  141. "new_value": "即将到达下次跟进时间",
  142. "createtime": nowTime2,
  143. "BCPCID": common.GetRandom(32),
  144. "operator_id": -1,
  145. })
  146. }
  147. }
  148. }
  149. }
  150. return true
  151. }, `SELECT a.id,a.position_id,a.seatNumber,a.out_task_status FROM dwd_f_crm_clue_info a
  152. LEFT JOIN dwd_f_crm_trail_content c ON c.clue_id=a.id
  153. WHERE c.next_time >= "`+nowTime2+`" and c.next_time <= "`+nextTime+`"`)
  154. log.Println("按照跟进时间提前一天进入任务车定时任务结束")
  155. }
  156. // 所有人达上限退公海处理
  157. func UpperLimitAutoExitSea(upperLimit int64) {
  158. countData := TiDb.SelectBySql(`SELECT
  159. COUNT(b.ID) AS count ,a.position_id
  160. FROM
  161. dwd_f_crm_clue_info b
  162. right JOIN
  163. ( select position_id from dwd_f_crm_personnel_management where assign_type = 1
  164. AND resign = 0 ) a on a.position_id=b.position_id and b.is_transfer != 1
  165. GROUP BY
  166. a.position_id HAVING count<?`, upperLimit)
  167. if countData == nil || len(*countData) > 0 {
  168. return
  169. }
  170. log.Println("所有人达上限退公海处理任务开始")
  171. data := TiDb.SelectBySql(`select * from dwd_f_crm_clue_info where (trailstatus = "04" or trailstatus = "03" or trailstatus = "01" ) and (is_assign = 1)`)
  172. if data != nil && len(*data) > 0 {
  173. fool := false
  174. for _, v := range *data {
  175. trailstatus := gconv.String(v["trailstatus"])
  176. //坐席信息查询
  177. clueId := common.Int64All(v["id"])
  178. createtime := gconv.String(v["comeintime"])
  179. positionId := common.Int64All(v["position_id"])
  180. seatNumber := common.ObjToString(v["seatNumber"])
  181. if trailstatus == "01" {
  182. //该线索最近一次分配给该电销人员后存在通话记录
  183. uid := gconv.String(v["uid"])
  184. if createtime == "" {
  185. continue
  186. }
  187. if !PhoneState(uid, seatNumber, createtime) {
  188. continue
  189. }
  190. }
  191. //退私海处理
  192. nowTime := time.Now().Format(date.Date_Full_Layout)
  193. positionMap := map[int64]interface{}{}
  194. if TiDb.ExecTx("退出线索", func(tx *sql.Tx) bool {
  195. positionMap[positionId] = true
  196. recordId := TiDb.UpdateOrDeleteBySqlByTx(tx, `UPDATE dwd_f_crm_clue_info SET is_assign=0,position_id=null,seatNumber=null,updatetime = ?,comeinsource_open=null,level_open=null,next_trail_time=null,is_task=null,tasktime=null,taskstatus=null,comeinsource_private=null,tasksource=null WHERE id = ?`, nowTime, clueId) //,start_trail_time=null,content=null
  197. recordId2 := TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  198. "clue_id": clueId,
  199. "position_id": positionId,
  200. "change_type": "退回公海",
  201. "new_value": "所有人员私海已达上限",
  202. "createtime": nowTime,
  203. "BCPCID": common.GetRandom(32),
  204. "operator_id": -1,
  205. })
  206. recordId1 := TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  207. "clue_id": clueId,
  208. "position_id": positionId,
  209. "change_field": "position_id",
  210. "change_type": "所属人变更",
  211. "old_value": GetPositionName(seatNumber),
  212. "new_value": "/",
  213. "createtime": nowTime,
  214. "BCPCID": common.GetRandom(32),
  215. "operator_id": -1,
  216. })
  217. return recordId > -1 && recordId1 > -1 && recordId2 > -1
  218. }) {
  219. //发送消息,找wjh
  220. fool = true
  221. log.Println("达上限自动退出线索成功")
  222. } else {
  223. log.Println("达上限自动退出线索失败")
  224. }
  225. }
  226. //释放邮件
  227. //发送信息
  228. if fool {
  229. AutoReleaseNots()
  230. } else {
  231. CantBeAssignedNots()
  232. }
  233. }
  234. }
  235. func autoExitSea() {
  236. log.Println("自动退海任务开始")
  237. data := TiDb.SelectBySql(`select * from dwd_f_crm_clue_info where trailstatus = "02" and (is_assign = 1 or is_assign = 0)`)
  238. if data != nil && len(*data) > 0 {
  239. for _, v := range *data {
  240. clueId := common.Int64All(v["id"])
  241. positionId := common.Int64All(v["position_id"])
  242. seatNumber := common.ObjToString(v["seatNumber"])
  243. nowTime := time.Now().Format(date.Date_Full_Layout)
  244. // is_assign := common.IntAll(v["is_assign"])
  245. if TiDb.ExecTx("退出线索", func(tx *sql.Tx) bool {
  246. recordId := TiDb.UpdateOrDeleteBySqlByTx(tx, `UPDATE dwd_f_crm_clue_info SET is_assign=-1,position_id=null,seatNumber=null,updatetime = ?,comeinsource_open=null,level_open=null,next_trail_time=null,is_task=null,tasktime=null,taskstatus=null,comeinsource_private=null,tasksource=null WHERE id = ?`, nowTime, clueId) //,start_trail_time=null,content=null
  247. // ok1 := true
  248. // if is_assign == 1 {
  249. // ok1 = TiDb.DeleteByTx(tx, "dwd_f_crm_private_sea", map[string]interface{}{"clue_id": clueId})
  250. // } else if is_assign == 0 {
  251. // ok1 = TiDb.DeleteByTx(tx, "dwd_f_crm_open_sea", map[string]interface{}{"clue_id": clueId})
  252. // }
  253. recordId1 := TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  254. "clue_id": clueId,
  255. "position_id": positionId,
  256. "change_field": "position_id",
  257. "change_type": "所属人变更",
  258. "old_value": GetPositionName(seatNumber),
  259. "new_value": "/",
  260. "createtime": nowTime,
  261. "BCPCID": common.GetRandom(32),
  262. "operator_id": -1,
  263. })
  264. recordId2 := TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  265. "clue_id": clueId,
  266. "position_id": positionId,
  267. "change_field": "trailstatus",
  268. "change_type": "基本信息变更",
  269. "old_value": "空号停机",
  270. "new_value": "流失",
  271. "createtime": nowTime,
  272. "BCPCID": common.GetRandom(32),
  273. "operator_id": -1,
  274. })
  275. recordId3 := TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  276. "clue_id": clueId,
  277. "position_id": positionId,
  278. "change_type": "退出任务车",
  279. "new_value": "空号停机自动从线索池删除",
  280. "createtime": nowTime,
  281. "BCPCID": common.GetRandom(32),
  282. "operator_id": -1,
  283. })
  284. recordId4 := TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  285. "clue_id": clueId,
  286. "position_id": positionId,
  287. "change_type": "退出公海",
  288. "new_value": "空号停机自动从线索池删除",
  289. "createtime": nowTime,
  290. "BCPCID": common.GetRandom(32),
  291. "operator_id": -1,
  292. })
  293. return recordId > -1 && recordId1 > -1 && recordId2 > -1 && recordId3 > -1 && recordId4 > -1
  294. }) {
  295. log.Println("自动退出线索成功")
  296. } else {
  297. log.Println("自动退出线索失败")
  298. }
  299. }
  300. }
  301. datas := TiDb.SelectBySql("select * from dwd_f_crm_clue_info where (trailstatus='09' or trailstatus='00') and is_assign=1")
  302. if datas != nil && len(*datas) > 0 {
  303. for _, v := range *datas {
  304. trailstatus := gconv.String(v["trailstatus"])
  305. clueId := common.Int64All(v["id"])
  306. positionId := common.Int64All(v["position_id"])
  307. seatNumber := common.ObjToString(v["seatNumber"])
  308. nowTime := time.Now().Format(date.Date_Full_Layout)
  309. // is_assign := common.IntAll(v["is_assign"])
  310. if TiDb.ExecTx("自动退海", func(tx *sql.Tx) bool {
  311. recordId := TiDb.UpdateOrDeleteBySqlByTx(tx, `UPDATE dwd_f_crm_clue_info SET is_assign=0,position_id=null,seatNumber=null,updatetime = ?,comeintime_open = ?,comeinsource_open=?,level_open=4,next_trail_time=null,is_task=null,tasktime=null,taskstatus=null,comeinsource_private=null,tasksource=null WHERE id = ?`, nowTime, nowTime, common.If(trailstatus == "00", 8, 11), clueId) //,content=null,start_trail_time=null
  312. recordId1 := TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  313. "clue_id": clueId,
  314. "position_id": positionId,
  315. "change_field": "position_id",
  316. "change_type": "所属人变更",
  317. "old_value": GetPositionName(seatNumber),
  318. "new_value": "/",
  319. "createtime": nowTime,
  320. "BCPCID": common.GetRandom(32),
  321. "operator_id": -1,
  322. })
  323. recordId2 := TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  324. "clue_id": clueId,
  325. "position_id": positionId,
  326. "change_field": "trailstatus",
  327. "change_type": "基本信息变更",
  328. "old_value": common.If(trailstatus == "00", "无意向客户", "拒绝客户"),
  329. "new_value": "流失",
  330. "createtime": nowTime,
  331. "BCPCID": common.GetRandom(32),
  332. "operator_id": -1,
  333. })
  334. recordId3 := TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  335. "clue_id": clueId,
  336. "position_id": positionId,
  337. "change_type": "退出任务车",
  338. "new_value": common.If(trailstatus == "00", "无意向客户自动退回公海", "拒绝客户自动退回公海"),
  339. "createtime": nowTime,
  340. "BCPCID": common.GetRandom(32),
  341. "operator_id": -1,
  342. })
  343. recordId4 := TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  344. "clue_id": clueId,
  345. "position_id": positionId,
  346. "change_type": "退回公海",
  347. "new_value": common.If(trailstatus == "00", "无意向客户自动退回公海", "拒绝客户自动退回公海"),
  348. "createtime": nowTime,
  349. "BCPCID": common.GetRandom(32),
  350. "operator_id": -1,
  351. })
  352. return recordId > -1 && recordId1 > -1 && recordId2 > -1 && recordId3 > -1 && recordId4 > -1
  353. }) {
  354. log.Println("自动退出私海成功")
  355. } else {
  356. log.Println("自动退出私海失败")
  357. }
  358. }
  359. }
  360. log.Println("自动退海任务结束")
  361. }
  362. func GetPositionName(seatNumber string) string {
  363. data := TiDb.SelectBySql(`select name from dwd_f_crm_personnel_management where resign = 0 and seat_number = ? limit 1`, seatNumber)
  364. if data != nil && len(*data) > 0 {
  365. return common.ObjToString((*data)[0]["name"])
  366. }
  367. return ""
  368. }
  369. func Thaw() {
  370. //3个工作日查询
  371. k := db.ThawDay
  372. nowTime := time.Now()
  373. for {
  374. if k == 0 {
  375. break
  376. }
  377. nowTime = nowTime.AddDate(0, 0, -1)
  378. if !IsBreak(nowTime) {
  379. continue
  380. }
  381. k--
  382. }
  383. nameMap := map[int64]string{}
  384. nameList := TiDb.SelectBySql("select name,position_id from dwd_f_crm_personnel_management")
  385. if nameList != nil && len(*nameList) > 0 {
  386. for _, v := range *nameList {
  387. nameMap[gconv.Int64(v["position_id"])] = gconv.String(v["name"])
  388. }
  389. }
  390. //查询
  391. layout := "2006-01-02 15:04:05"
  392. //三天以后退公海处理
  393. TiDb.SelectByBath(100, func(l *[]map[string]interface{}) bool {
  394. for _, v := range *l {
  395. clueId := gconv.Int64(v["id"])
  396. positionId := gconv.Int64(v["position_id"])
  397. freezeInt64 := int64(0)
  398. freezeStr := gconv.String(v["FREEZE_TIME"])
  399. if freezeStr != "" {
  400. t, _ := time.ParseInLocation(layout, freezeStr, time.Local)
  401. freezeInt64 = t.Unix()
  402. }
  403. if freezeInt64 < nowTime.Unix() {
  404. //超三天处理
  405. //分配状态改改
  406. if TiDb.Update("dwd_f_crm_clue_info", map[string]interface{}{"id": clueId}, map[string]interface{}{
  407. "is_assign": 0,
  408. "position_id": 0,
  409. "seatNumber": nil,
  410. }) {
  411. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  412. "clue_id": clueId,
  413. "position_id": 0,
  414. "change_field": "position_id",
  415. "change_type": "所属人变更",
  416. "old_value": nameMap[positionId],
  417. "new_value": "/",
  418. "createtime": time.Now().Format(date.Date_Full_Layout),
  419. "BCPCID": common.GetRandom(32),
  420. "operator_id": -1,
  421. })
  422. }
  423. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  424. "clue_id": clueId,
  425. "position_id": 0,
  426. "change_field": "position_id",
  427. "change_type": "线索解冻",
  428. "new_value": "自动退回公海",
  429. "createtime": time.Now().Format(date.Date_Full_Layout),
  430. "BCPCID": common.GetRandom(32),
  431. "operator_id": -1,
  432. })
  433. } else {
  434. if !FindUpperLimit(gconv.String(positionId), "", false) {
  435. if TiDb.Update("dwd_f_crm_clue_info", map[string]interface{}{"id": clueId}, map[string]interface{}{
  436. "is_assign": 1,
  437. }) {
  438. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  439. "clue_id": clueId,
  440. "position_id": positionId,
  441. "change_field": "position_id",
  442. "change_type": "所属人变更",
  443. "old_value": "/",
  444. "new_value": nameMap[positionId],
  445. "createtime": time.Now().Format(date.Date_Full_Layout),
  446. "BCPCID": common.GetRandom(32),
  447. "operator_id": -1,
  448. })
  449. }
  450. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  451. "clue_id": clueId,
  452. "position_id": positionId,
  453. "change_field": "position_id",
  454. "change_type": "线索解冻",
  455. "new_value": "销售人员私海线索已释放",
  456. "createtime": time.Now().Format(date.Date_Full_Layout),
  457. "BCPCID": common.GetRandom(32),
  458. "operator_id": -1,
  459. })
  460. }
  461. }
  462. }
  463. return true
  464. }, `select id,position_id,FREEZE_TIME from dwd_f_crm_clue_info where is_assign = -3 `)
  465. }
  466. func IsBreak(currentTime time.Time) bool {
  467. if currentTime.Weekday() == time.Sunday {
  468. isok := false
  469. for k, v := range DateMap {
  470. if currentTime.Format(date.Date_Short_Layout) == k && v == 2 {
  471. isok = true
  472. }
  473. }
  474. return isok
  475. } else {
  476. isok := true
  477. for k, v := range DateMap {
  478. if currentTime.Format(date.Date_Short_Layout) == k && v == 1 {
  479. isok = false
  480. }
  481. }
  482. return isok
  483. }
  484. }
  485. func PhoneState(uid, seatNumber, createtime string) bool {
  486. phoneData := TiDb.SelectBySql("select DISTINCT phone from dwd_f_userbase_contacts where baseinfo_id= ?", uid)
  487. if phoneData == nil || len(*phoneData) == 0 {
  488. //数据不对跳过去
  489. return false
  490. }
  491. for _, v1 := range *phoneData {
  492. phone := gconv.String(v1["phone"])
  493. callData := TiDb.SelectBySql("select DISTINCT Exten from Call_Accounting.voice_record where CalledNo=? and createtime>=? ORDER BY createTime", phone, createtime)
  494. if callData == nil || len(*callData) == 0 {
  495. //手机号没有通话记录
  496. continue
  497. }
  498. for _, v2 := range *callData {
  499. exten := gconv.String(v2["Exten"])
  500. if seatNumber == exten {
  501. return true
  502. }
  503. }
  504. }
  505. return false
  506. }
  507. func LockHandle() {
  508. time.Now()
  509. log.Println("线索锁定定时任务开始")
  510. timeData := -1 * (db.CornExp8 + 5)
  511. timeDate := time.Now().Add(time.Duration(timeData) * time.Second)
  512. timeStr := timeDate.Format("2006-01-02 15:04:05")
  513. a := 1
  514. fool := false
  515. page := 1
  516. pageSize := 1000
  517. for !fool {
  518. sqlStr := fmt.Sprintf(`select id,cluename,position_id,updatetime,company_nature,company_verification,lock_status from dwd_f_crm_clue_info where updatetime>="%s" order by updatetime limit %d OFFSET %d`, timeStr, pageSize, (page-1)*pageSize)
  519. data := TiDb.SelectBySql(sqlStr)
  520. if len(*data) == 0 {
  521. fool = true
  522. break
  523. }
  524. for _, v := range *data {
  525. log.Println(a, gconv.String(v["updatetime"]))
  526. a++
  527. clue_id := gconv.Int64(v["id"])
  528. cluename := gconv.String(v["cluename"])
  529. position_id := gconv.String(v["position_id"])
  530. company_nature := gconv.Int64(v["company_nature"])
  531. company_verification := gconv.Int64(v["company_verification"])
  532. lock_status := gconv.Int64(v["lock_status"])
  533. //非集团在工商需要查询其他数据是否分配的有人
  534. if company_nature == 0 && company_verification == 1 {
  535. status4Data := TiDb.SelectBySql(fmt.Sprintf(`select GROUP_CONCAT(DISTINCT position_id) as position_id from dwd_f_crm_clue_info where cluename="%s" and position_id>0 `, cluename))
  536. if len(*status4Data) > 0 || status4Data != nil {
  537. position_id = gconv.String((*status4Data)[0]["position_id"])
  538. }
  539. }
  540. if company_nature == 1 && lock_status != 3 {
  541. //无需锁定处理
  542. if lock_status != 3 {
  543. go UpdateData(3, map[string]interface{}{
  544. "id": clue_id,
  545. }, 3, "")
  546. }
  547. } else if company_nature == 0 && company_verification == 1 {
  548. //已锁定处理
  549. if position_id != "" {
  550. go UpdateData(1, map[string]interface{}{
  551. "cluename": cluename,
  552. "company_verification": 1,
  553. "company_nature": 0,
  554. }, 1, position_id)
  555. } else {
  556. go UpdateData(2, map[string]interface{}{
  557. "cluename": cluename,
  558. "company_verification": 1,
  559. "company_nature": 0,
  560. }, 2, "")
  561. }
  562. } else {
  563. //未锁定处理
  564. if lock_status != 2 {
  565. go UpdateData(2, map[string]interface{}{
  566. "id": clue_id,
  567. }, 2, "")
  568. }
  569. }
  570. }
  571. page++
  572. }
  573. log.Println("线索锁定定时任务结束")
  574. }
  575. func UpdateData(lockStatus int64, query map[string]interface{}, status int, positionId string) {
  576. TiDb.Update("dwd_f_crm_clue_info", query, map[string]interface{}{
  577. "lock_status": lockStatus,
  578. "lock_position_id": positionId,
  579. })
  580. }
  581. // 大会员子账号不作为电销线索
  582. func ClueToDxTask() {
  583. //把所-5有的用户刷至公海
  584. ok := TiDb.Update("dwd_f_crm_clue_info", map[string]interface{}{"is_assign": -5}, map[string]interface{}{"is_assign": 0, "seatNumber": nil, "position_id": 0})
  585. if !ok {
  586. log.Println("更新dwd_f_crm_clue_info处理子账号出错")
  587. return
  588. }
  589. //查询在客成的用户
  590. res := TiDb.Query("SELECT clue_id,ent_id FROM `dwd_f_csm_customer_info` WHERE is_transfer = 0")
  591. if res == nil || len(*res) <= 0 {
  592. log.Println("查dwd_f_csm_customer_info 客成用户异常")
  593. return
  594. }
  595. log.Println("客成用户量:", len(*res))
  596. for _, val := range *res {
  597. //log.Println("ent_id", val["ent_id"])
  598. clue_id := gconv.Int(val["clue_id"])
  599. childIds := []string{}
  600. if gconv.String(val["ent_id"]) == "" || gconv.String(val["ent_id"]) == "0" {
  601. continue
  602. }
  603. if mongodb.IsObjectIdHex(gconv.String(val["ent_id"])) { //mongodb 个人身份大会员
  604. //查询个人大会员下的子账号
  605. query := map[string]interface{}{"s_member_mainid": gconv.String(val["ent_id"])}
  606. childAccount, _ := Mgo.Find("user", query, "", `"_id":1`, false, -1, -1)
  607. if childAccount != nil && len(*childAccount) > 0 {
  608. log.Println("个人大会员子账号数量:", gconv.String(val["ent_id"]), len(*childAccount))
  609. for _, v := range *childAccount {
  610. childIds = append(childIds, mongodb.BsonIdToSId(v["_id"]))
  611. }
  612. }
  613. } else { //企业大会员
  614. //根据企业id查询企业下的员工
  615. if gconv.Int(val["ent_id"]) == 0 {
  616. continue
  617. }
  618. data := TiDb.Query("SELECT userid,uid FROM dwd_f_userbase_id_mapping WHERE ent_id = ?", gconv.Int(val["ent_id"]))
  619. if data != nil && len(*data) > 0 {
  620. log.Println("企业下员工数:", gconv.Int(val["ent_id"]), len(*data))
  621. for _, vv := range *data {
  622. //判断员工是否有大会员权益
  623. count := TiDb.CountBySql("SELECT COUNT(1) FROM dwd_f_data_equity_info WHERE (product_type = '大会员' or product_type='商机管理') AND equity_status = 1 AND user_type = 2 AND user_role = 1 AND uid = ?", gconv.String(vv["uid"]))
  624. log.Println("用户是否有权益", gconv.String(vv["uid"]), count)
  625. if count > 0 {
  626. childIds = append(childIds, gconv.String(vv["userid"]))
  627. }
  628. }
  629. }
  630. }
  631. //更新线索信息
  632. if len(childIds) > 0 {
  633. ids := ""
  634. for k, vv := range childIds {
  635. if k == 0 {
  636. ids += fmt.Sprintf("'%s'", vv)
  637. } else {
  638. ids += fmt.Sprintf(",'%s'", vv)
  639. }
  640. }
  641. //log.Println("线索ids:", ids)
  642. sql := fmt.Sprintf("UPDATE dwd_f_crm_clue_info SET is_assign = -5 WHERE id != %d and userid IN (%s)", clue_id, ids)
  643. log.Println("sql:", sql)
  644. up := TiDb.UpdateOrDeleteBySql(sql)
  645. if up < 0 {
  646. log.Println("更新线索为-5出错", childIds)
  647. return
  648. }
  649. }
  650. }
  651. log.Println("定时任务完成")
  652. }