clue.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. package service
  2. import (
  3. "database/sql"
  4. "log"
  5. "math"
  6. "sync"
  7. "time"
  8. "app.yhyue.com/moapp/jybase/date"
  9. common "app.yhyue.com/moapp/jybase/common"
  10. . "bp.jydev.jianyu360.cn/BaseService/biService/entity"
  11. "bp.jydev.jianyu360.cn/BaseService/biService/rpc/biservice"
  12. )
  13. func DistributeClue(this *biservice.DistributeClueReq) *biservice.AddProjectResp {
  14. count, status := DistributeClueSync(this)
  15. log.Println("分配数量 ", count)
  16. return &biservice.AddProjectResp{
  17. ErrorCode: 0,
  18. Data: &biservice.AddProject{
  19. Status: int64(status),
  20. Count: int64(count),
  21. },
  22. }
  23. }
  24. func DistributeClueSync(this *biservice.DistributeClueReq) (int, int) {
  25. if DistributeLock.TryLock() {
  26. defer DistributeLock.Unlock()
  27. saleMap, count := map[string]map[string]interface{}{}, 0
  28. saleData := JyBiTidb.SelectBySql("select * from jy_salesperson_info where is_complete = 1 or is_complete = 0")
  29. if saleData != nil && len(*saleData) > 0 {
  30. for _, v := range *saleData {
  31. name := common.ObjToString(v["name"])
  32. saleMap[name] = v
  33. }
  34. }
  35. for _, data := range this.Datas {
  36. seatNumber := common.ObjToString(saleMap[data.Name]["seatNumber"])
  37. distributedCount := int(data.DistributedCount)
  38. if distributedCount > 0 {
  39. distributedArr := this.ClueIdList[count : count+distributedCount]
  40. count += distributedCount
  41. DistributeClueMore(saleMap, distributedArr, seatNumber, data.Name, data.PositionId, this.PositionId)
  42. }
  43. }
  44. return count, 1
  45. } else {
  46. return 0, 2
  47. }
  48. }
  49. func DistributeClueMore(saleMap map[string]map[string]interface{}, distributedArr []int64, seatNumber, name string, positionId, thispositionId int64) {
  50. wg := new(sync.WaitGroup)
  51. ch := make(chan bool, 20)
  52. for _, v := range distributedArr {
  53. wg.Add(1)
  54. ch <- true
  55. go func(v int64) {
  56. defer func() {
  57. wg.Done()
  58. <-ch
  59. }()
  60. clueData := JyBiTidb.FindOne("dwd_f_crm_clue_info", map[string]interface{}{"id": v}, "", "")
  61. nowTime := time.Now().Format(date.Date_Full_Layout)
  62. if clueData != nil && len(*clueData) > 0 {
  63. isAssign := common.IntAll((*clueData)["is_assign"])
  64. clueSeatNumber := common.ObjToString((*clueData)["seatNumber"])
  65. oldName := ""
  66. trailstatus := common.ObjToString((*clueData)["trailstatus"])
  67. if clueSeatNumber != "" {
  68. for _, s := range saleMap {
  69. if common.ObjToString(s["seatNumber"]) == clueSeatNumber {
  70. oldName = common.ObjToString(s["name"])
  71. }
  72. }
  73. }
  74. if isAssign == 1 {
  75. oldpositionId := common.Int64All((*clueData)["position_id"])
  76. updateClue := map[string]interface{}{
  77. "position_id": positionId,
  78. "seatNumber": seatNumber,
  79. "is_assign": 1,
  80. "updatetime": nowTime,
  81. "comeintime": nowTime,
  82. "comeinsource_private": 4,
  83. "comeinsource_open": nil,
  84. "level_open": nil,
  85. "clue_level": nil,
  86. "out_task_time": nil,
  87. "out_task_status": nil,
  88. "trail_time": nil,
  89. }
  90. ok := JyBiTidb.Update("dwd_f_crm_clue_info", map[string]interface{}{"id": v}, updateClue)
  91. // ok := JyBiTidb.Update("dwd_f_crm_private_sea", map[string]interface{}{"clue_id": v}, map[string]interface{}{
  92. // "position_id": positionId,
  93. // "seatNumber": seatNumber,
  94. // "comeinsource": 4,
  95. // "comeintime": nowTime,
  96. // })
  97. if ok {
  98. JyBiTidb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  99. "clue_id": v,
  100. "position_id": positionId,
  101. "change_field": "position_id",
  102. "change_type": "所属人变更",
  103. "old_value": oldName,
  104. "new_value": name,
  105. "createtime": nowTime,
  106. "BCPCID": common.GetRandom(32),
  107. "operator_id": thispositionId,
  108. })
  109. JyBiTidb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  110. "clue_id": v,
  111. "position_id": oldpositionId,
  112. "change_field": "trailstatus",
  113. "change_type": "基本信息变更",
  114. "old_value": CodeTrail[trailstatus],
  115. "new_value": "流失",
  116. "createtime": nowTime,
  117. "BCPCID": common.GetRandom(32),
  118. "operator_id": thispositionId,
  119. })
  120. JyBiTidb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  121. "clue_id": v,
  122. "position_id": positionId,
  123. "change_field": "trailstatus",
  124. "change_type": "基本信息变更",
  125. "old_value": CodeTrail[trailstatus],
  126. "new_value": "新增",
  127. "createtime": nowTime,
  128. "BCPCID": common.GetRandom(32),
  129. "operator_id": thispositionId,
  130. })
  131. } else {
  132. log.Println("私海修改失败 ", v, positionId, seatNumber)
  133. }
  134. } else {
  135. updateClue := map[string]interface{}{
  136. "position_id": positionId,
  137. "seatNumber": seatNumber,
  138. "is_assign": 1,
  139. "updatetime": nowTime,
  140. "comeintime": nowTime,
  141. "comeinsource_private": 4,
  142. "is_task": 0,
  143. "taskstatus": 0,
  144. "comeinsource_open": nil,
  145. "level_open": nil,
  146. "clue_level": nil,
  147. "out_task_time": nil,
  148. "out_task_status": nil,
  149. "trail_time": nil,
  150. "next_trail_time": nil,
  151. }
  152. if trailstatus != "08" {
  153. updateClue["trailstatus"] = "01"
  154. }
  155. ok := JyBiTidb.Update("dwd_f_crm_clue_info", map[string]interface{}{"id": v}, updateClue)
  156. // seaId := JyBiTidb.Insert("dwd_f_crm_private_sea", map[string]interface{}{
  157. // "clue_id": v,
  158. // "position_id": positionId,
  159. // "seatNumber": seatNumber,
  160. // "comeinsource": 4,
  161. // "comeintime": nowTime,
  162. // "is_task": 0,
  163. // // "task_time": nowTime,
  164. // // "tasktime": nowTime,
  165. // "taskstatus": 0,
  166. // // "tasksource": "线索批量分配",
  167. // })
  168. if ok {
  169. // JyBiTidb.Delete("dwd_f_crm_open_sea", map[string]interface{}{"clue_id": v})
  170. JyBiTidb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  171. "clue_id": v,
  172. "position_id": positionId,
  173. "change_field": "position_id",
  174. "change_type": "所属人变更",
  175. "old_value": "/",
  176. "new_value": name,
  177. "createtime": nowTime,
  178. "BCPCID": common.GetRandom(32),
  179. "operator_id": thispositionId,
  180. })
  181. if trailstatus != "08" {
  182. JyBiTidb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  183. "clue_id": v,
  184. "position_id": positionId,
  185. "change_field": "trailstatus",
  186. "change_type": "基本信息变更",
  187. "old_value": "商机线索",
  188. "new_value": "新增",
  189. "createtime": nowTime,
  190. "BCPCID": common.GetRandom(32),
  191. "operator_id": thispositionId,
  192. })
  193. }
  194. } else {
  195. log.Println("私海插入失败 ", v, positionId, seatNumber)
  196. }
  197. }
  198. }
  199. }(v)
  200. }
  201. wg.Wait()
  202. }
  203. func DrawClue(this *biservice.DrawClueReq) *biservice.AddProjectResp {
  204. count, status := DrawClueSync(this)
  205. log.Println("领取数量 ", count)
  206. return &biservice.AddProjectResp{
  207. ErrorCode: 0,
  208. Data: &biservice.AddProject{
  209. Status: int64(status),
  210. Count: int64(count),
  211. },
  212. }
  213. }
  214. func DrawClueSync(this *biservice.DrawClueReq) (int, int) {
  215. if DataLock.TryLock() {
  216. defer DataLock.Unlock()
  217. count1 := JyBiTidb.Count("dwd_f_crm_clue_info", map[string]interface{}{"level_open": 1, "is_assign": 0})
  218. count2 := JyBiTidb.Count("dwd_f_crm_clue_info", map[string]interface{}{"level_open": 2, "is_assign": 0})
  219. counts1, counts2, counts3 := int64(0), int64(0), int64(0)
  220. counts1 = int64(math.Ceil(float64(this.Count) / float64(10) * 5))
  221. if this.Count-counts1 == 0 {
  222. counts2 = 0
  223. counts3 = 0
  224. } else {
  225. counts2 = int64(math.Ceil(float64(this.Count) / float64(10) * 4))
  226. if this.Count-counts1-counts2 == 0 {
  227. counts3 = 0
  228. } else {
  229. counts3 = this.Count - counts1 - counts2
  230. }
  231. }
  232. if counts1 > count1 {
  233. counts2 += counts1 - count1
  234. counts1 = count1
  235. }
  236. if counts2 > count2 {
  237. counts3 += counts2 - count2
  238. counts2 = count2
  239. }
  240. log.Println(count1, count2)
  241. log.Println(counts1, counts2, counts3)
  242. return DrawClues(this.PositionId, counts1, counts2, counts3), 1
  243. } else {
  244. return 0, 2
  245. }
  246. }
  247. func DrawClues(positionId, count1, count2, count3 int64) int {
  248. data1, data2, data3, drawCount := &[]map[string]interface{}{}, &[]map[string]interface{}{}, &[]map[string]interface{}{}, 0
  249. if count1 > 0 {
  250. // data1 = JyBiTidb.Find("dwd_f_crm_clue_info", map[string]interface{}{"level_open": 1, "is_assign": 0}, "", "", 0, int(count1))
  251. data1 = JyBiTidb.SelectBySql(`SELECT a.* FROM dwd_f_crm_clue_info a
  252. LEFT JOIN dwd_f_userbase_contacts b ON b.baseinfo_id=a.uid
  253. LEFT JOIN Call_Accounting.voice_record c ON c.CalledNo = b.phone
  254. WHERE a.level_open = ? AND a.is_assign = 0 AND a.uid !="" ORDER BY c.createTime asc limit ?`, 1, count1)
  255. }
  256. if count2 > 0 {
  257. // data2 = JyBiTidb.Find("dwd_f_crm_clue_info", map[string]interface{}{"level_open": 2, "is_assign": 0}, "", "", 0, int(count2))
  258. data2 = JyBiTidb.SelectBySql(`SELECT a.* FROM dwd_f_crm_clue_info a
  259. LEFT JOIN dwd_f_userbase_contacts b ON b.baseinfo_id=a.uid
  260. LEFT JOIN Call_Accounting.voice_record c ON c.CalledNo = b.phone
  261. WHERE a.level_open = ? AND a.is_assign = 0 AND a.uid !="" ORDER BY c.createTime asc limit ?`, 2, count2)
  262. }
  263. if count3 > 0 {
  264. // data3 = JyBiTidb.Find("dwd_f_crm_clue_info", map[string]interface{}{"level_open": 3, "is_assign": 0}, "", "", 0, int(count3))
  265. data3 = JyBiTidb.SelectBySql(`SELECT a.* FROM dwd_f_crm_clue_info a
  266. LEFT JOIN dwd_f_userbase_contacts b ON b.baseinfo_id=a.uid
  267. LEFT JOIN Call_Accounting.voice_record c ON c.CalledNo = b.phone
  268. WHERE a.level_open = ? AND a.is_assign = 0 AND a.uid !="" ORDER BY c.createTime asc limit ?`, 3, count3)
  269. }
  270. nowTime := time.Now().Format("2006-01-02 15:04:05")
  271. seatNumber, name := getSeatNumber(positionId)
  272. if data1 != nil && len(*data1) > 0 {
  273. batchDraw(*data1, nowTime, seatNumber, name, positionId)
  274. drawCount += len(*data1)
  275. }
  276. if data2 != nil && len(*data2) > 0 {
  277. batchDraw(*data2, nowTime, seatNumber, name, positionId)
  278. drawCount += len(*data2)
  279. }
  280. if data3 != nil && len(*data3) > 0 {
  281. batchDraw(*data3, nowTime, seatNumber, name, positionId)
  282. drawCount += len(*data3)
  283. }
  284. return drawCount
  285. }
  286. func batchDraw(data []map[string]interface{}, nowTime, seatNumber, name string, positionId int64) {
  287. wg := new(sync.WaitGroup)
  288. ch := make(chan bool, 20)
  289. for _, v := range data {
  290. wg.Add(1)
  291. ch <- true
  292. go func(v map[string]interface{}) {
  293. defer func() {
  294. wg.Done()
  295. <-ch
  296. }()
  297. clueId := common.Int64All(v["id"])
  298. trailstatus := common.ObjToString(v["trailstatus"])
  299. if JyBiMysql.ExecTx("领取线索等", func(tx *sql.Tx) bool {
  300. updateClue := map[string]interface{}{
  301. "position_id": positionId,
  302. "seatNumber": seatNumber,
  303. "is_assign": 1,
  304. "updatetime": nowTime,
  305. "comeintime": nowTime,
  306. "comeinsource_private": 3,
  307. "is_task": 1,
  308. "task_time": nowTime,
  309. "tasktime": nowTime,
  310. "taskstatus": 0,
  311. "tasksource": "领取公海线索",
  312. "comeinsource_open": nil,
  313. "level_open": nil,
  314. "clue_level": nil,
  315. }
  316. if trailstatus != "08" {
  317. updateClue["trailstatus"] = "01"
  318. }
  319. ok1 := JyBiTidb.UpdateByTx(tx, "dwd_f_crm_clue_info", map[string]interface{}{"id": clueId}, updateClue)
  320. // ok2 := JyBiTidb.DeleteByTx(tx, "dwd_f_crm_open_sea", map[string]interface{}{"clue_id": clueId})
  321. // seaId := JyBiTidb.InsertByTx(tx, "dwd_f_crm_private_sea", map[string]interface{}{
  322. // "clue_id": clueId,
  323. // "seatNumber": seatNumber,
  324. // "position_id": positionId,
  325. // "comeintime": nowTime,
  326. // "comeinsource": 3,
  327. // "is_task": 1,
  328. // "task_time": nowTime,
  329. // "tasktime": nowTime,
  330. // "taskstatus": 0,
  331. // "tasksource": "领取公海线索",
  332. // })
  333. recordId := JyBiTidb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  334. "clue_id": clueId,
  335. "position_id": positionId,
  336. "change_field": "position_id",
  337. "change_type": "所属人变更",
  338. "old_value": "/",
  339. "new_value": name,
  340. "createtime": nowTime,
  341. "BCPCID": common.GetRandom(32),
  342. "operator_id": positionId,
  343. })
  344. recordId1 := JyBiTidb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  345. "clue_id": clueId,
  346. "position_id": positionId,
  347. "change_type": "领取公海线索",
  348. "createtime": nowTime,
  349. "BCPCID": common.GetRandom(32),
  350. "operator_id": positionId,
  351. })
  352. recordId2 := JyBiTidb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  353. "clue_id": clueId,
  354. "position_id": positionId,
  355. "change_type": "加入任务车",
  356. "new_value": "领取公海线索",
  357. "createtime": nowTime,
  358. "BCPCID": common.GetRandom(32),
  359. "operator_id": positionId,
  360. })
  361. recordId3, recordId4 := int64(0), int64(0)
  362. if trailstatus != "08" {
  363. recordId3 = JyBiTidb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  364. "clue_id": clueId,
  365. "position_id": positionId,
  366. "change_field": "trailstatus",
  367. "change_type": "基本信息变更",
  368. "old_value": "商机线索",
  369. "new_value": "新增",
  370. "createtime": nowTime,
  371. "BCPCID": common.GetRandom(32),
  372. "operator_id": positionId,
  373. })
  374. recordId4 = JyBiTidb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  375. "clue_id": clueId,
  376. "position_id": positionId,
  377. "change_field": "trailstatus",
  378. "change_type": "基本信息变更",
  379. "old_value": CodeTrail[trailstatus],
  380. "new_value": "商机线索",
  381. "createtime": nowTime,
  382. "BCPCID": common.GetRandom(32),
  383. "operator_id": positionId,
  384. })
  385. }
  386. return ok1 && recordId > 0 && recordId1 > 0 && recordId2 > 0 && recordId3 > -1 && recordId4 > -1
  387. }) {
  388. log.Println("领取线索成功")
  389. } else {
  390. log.Println("领取线索失败")
  391. }
  392. }(v)
  393. }
  394. wg.Wait()
  395. }
  396. func getSeatNumber(positionId int64) (seatNumber, name string) {
  397. positionData := JyTidb.FindOne("base_position", map[string]interface{}{"id": positionId}, "", "")
  398. if positionData != nil && len(*positionData) > 0 {
  399. userId := common.Int64All((*positionData)["user_id"])
  400. if userId > 0 {
  401. userData, ok := Mgo.FindOne("user", map[string]interface{}{"base_user_id": userId})
  402. if ok && userData != nil && len(*userData) > 0 {
  403. s_phone := common.ObjToString((*userData)["s_phone"])
  404. if s_phone == "" {
  405. s_phone = common.ObjToString((*userData)["s_m_phone"])
  406. }
  407. saleData := JyBiTidb.FindOne("jy_salesperson_info", map[string]interface{}{"phone": s_phone}, "", "")
  408. if saleData != nil && len(*saleData) > 0 {
  409. seatNumber = common.ObjToString((*saleData)["seatNumber"])
  410. name = common.ObjToString((*saleData)["name"])
  411. }
  412. }
  413. }
  414. }
  415. return
  416. }