clue.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  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. }
  84. ok := JyBiTidb.Update("dwd_f_crm_clue_info", map[string]interface{}{"id": v}, updateClue)
  85. // ok := JyBiTidb.Update("dwd_f_crm_private_sea", map[string]interface{}{"clue_id": v}, map[string]interface{}{
  86. // "position_id": positionId,
  87. // "seatNumber": seatNumber,
  88. // "comeinsource": 4,
  89. // "comeintime": nowTime,
  90. // })
  91. if ok {
  92. JyBiTidb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  93. "clue_id": v,
  94. "position_id": positionId,
  95. "change_field": "position_id",
  96. "change_type": "所属人变更",
  97. "old_value": oldName,
  98. "new_value": name,
  99. "createtime": nowTime,
  100. "BCPCID": common.GetRandom(32),
  101. "operator_id": thispositionId,
  102. })
  103. JyBiTidb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  104. "clue_id": v,
  105. "position_id": oldpositionId,
  106. "change_field": "trailstatus",
  107. "change_type": "基本信息变更",
  108. "old_value": CodeTrail[trailstatus],
  109. "new_value": "流失",
  110. "createtime": nowTime,
  111. "BCPCID": common.GetRandom(32),
  112. "operator_id": thispositionId,
  113. })
  114. JyBiTidb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  115. "clue_id": v,
  116. "position_id": positionId,
  117. "change_field": "trailstatus",
  118. "change_type": "基本信息变更",
  119. "old_value": CodeTrail[trailstatus],
  120. "new_value": "新增",
  121. "createtime": nowTime,
  122. "BCPCID": common.GetRandom(32),
  123. "operator_id": thispositionId,
  124. })
  125. } else {
  126. log.Println("私海修改失败 ", v, positionId, seatNumber)
  127. }
  128. } else {
  129. updateClue := map[string]interface{}{
  130. "position_id": positionId,
  131. "seatNumber": seatNumber,
  132. "is_assign": 1,
  133. "updatetime": nowTime,
  134. "comeintime": nowTime,
  135. "comeinsource_private": 4,
  136. "is_task": 0,
  137. "taskstatus": 0,
  138. }
  139. if trailstatus != "08" {
  140. updateClue["trailstatus"] = "01"
  141. }
  142. ok := JyBiTidb.Update("dwd_f_crm_clue_info", map[string]interface{}{"id": v}, updateClue)
  143. // seaId := JyBiTidb.Insert("dwd_f_crm_private_sea", map[string]interface{}{
  144. // "clue_id": v,
  145. // "position_id": positionId,
  146. // "seatNumber": seatNumber,
  147. // "comeinsource": 4,
  148. // "comeintime": nowTime,
  149. // "is_task": 0,
  150. // // "task_time": nowTime,
  151. // // "tasktime": nowTime,
  152. // "taskstatus": 0,
  153. // // "tasksource": "线索批量分配",
  154. // })
  155. if ok {
  156. // JyBiTidb.Delete("dwd_f_crm_open_sea", map[string]interface{}{"clue_id": v})
  157. JyBiTidb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  158. "clue_id": v,
  159. "position_id": positionId,
  160. "change_field": "position_id",
  161. "change_type": "所属人变更",
  162. "old_value": "/",
  163. "new_value": name,
  164. "createtime": nowTime,
  165. "BCPCID": common.GetRandom(32),
  166. "operator_id": thispositionId,
  167. })
  168. if trailstatus != "08" {
  169. JyBiTidb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  170. "clue_id": v,
  171. "position_id": positionId,
  172. "change_field": "trailstatus",
  173. "change_type": "基本信息变更",
  174. "old_value": "商机线索",
  175. "new_value": "新增",
  176. "createtime": nowTime,
  177. "BCPCID": common.GetRandom(32),
  178. "operator_id": thispositionId,
  179. })
  180. }
  181. } else {
  182. log.Println("私海插入失败 ", v, positionId, seatNumber)
  183. }
  184. }
  185. }
  186. }(v)
  187. }
  188. wg.Wait()
  189. }
  190. func DrawClue(this *biservice.DrawClueReq) *biservice.AddProjectResp {
  191. count, status := DrawClueSync(this)
  192. log.Println("领取数量 ", count)
  193. return &biservice.AddProjectResp{
  194. ErrorCode: 0,
  195. Data: &biservice.AddProject{
  196. Status: int64(status),
  197. Count: int64(count),
  198. },
  199. }
  200. }
  201. func DrawClueSync(this *biservice.DrawClueReq) (int, int) {
  202. if DataLock.TryLock() {
  203. defer DataLock.Unlock()
  204. count1 := JyBiTidb.Count("dwd_f_crm_clue_info", map[string]interface{}{"level": 1, "is_assign": 0})
  205. count2 := JyBiTidb.Count("dwd_f_crm_clue_info", map[string]interface{}{"level": 2, "is_assign": 0})
  206. counts1, counts2, counts3 := int64(0), int64(0), int64(0)
  207. counts1 = int64(math.Ceil(float64(this.Count) / float64(10) * 5))
  208. if this.Count-counts1 == 0 {
  209. counts2 = 0
  210. counts3 = 0
  211. } else {
  212. counts2 = int64(math.Ceil(float64(this.Count) / float64(10) * 4))
  213. if this.Count-counts1-counts2 == 0 {
  214. counts3 = 0
  215. } else {
  216. counts3 = this.Count - counts1 - counts2
  217. }
  218. }
  219. if counts1 > count1 {
  220. counts2 += counts1 - count1
  221. counts1 = count1
  222. }
  223. if counts2 > count2 {
  224. counts3 += counts2 - count2
  225. counts2 = count2
  226. }
  227. log.Println(count1, count2)
  228. log.Println(counts1, counts2, counts3)
  229. return DrawClues(this.PositionId, counts1, counts2, counts3), 1
  230. } else {
  231. return 0, 2
  232. }
  233. }
  234. func DrawClues(positionId, count1, count2, count3 int64) int {
  235. data1, data2, data3, drawCount := &[]map[string]interface{}{}, &[]map[string]interface{}{}, &[]map[string]interface{}{}, 0
  236. if count1 > 0 {
  237. data1 = JyBiTidb.Find("dwd_f_crm_clue_info", map[string]interface{}{"level": 1, "is_assign": 0}, "", "", 0, int(count1))
  238. }
  239. if count2 > 0 {
  240. data2 = JyBiTidb.Find("dwd_f_crm_clue_info", map[string]interface{}{"level": 2, "is_assign": 0}, "", "", 0, int(count2))
  241. }
  242. if count3 > 0 {
  243. data3 = JyBiTidb.Find("dwd_f_crm_clue_info", map[string]interface{}{"level": 3, "is_assign": 0}, "", "", 0, int(count3))
  244. }
  245. nowTime := time.Now().Format("2006-01-02 15:04:05")
  246. seatNumber, name := getSeatNumber(positionId)
  247. if data1 != nil && len(*data1) > 0 {
  248. batchDraw(*data1, nowTime, seatNumber, name, positionId)
  249. drawCount += len(*data1)
  250. }
  251. if data2 != nil && len(*data2) > 0 {
  252. batchDraw(*data2, nowTime, seatNumber, name, positionId)
  253. drawCount += len(*data2)
  254. }
  255. if data3 != nil && len(*data3) > 0 {
  256. batchDraw(*data3, nowTime, seatNumber, name, positionId)
  257. drawCount += len(*data3)
  258. }
  259. return drawCount
  260. }
  261. func batchDraw(data []map[string]interface{}, nowTime, seatNumber, name string, positionId int64) {
  262. wg := new(sync.WaitGroup)
  263. ch := make(chan bool, 20)
  264. for _, v := range data {
  265. wg.Add(1)
  266. ch <- true
  267. go func(v map[string]interface{}) {
  268. defer func() {
  269. wg.Done()
  270. <-ch
  271. }()
  272. clueId := common.Int64All(v["id"])
  273. trailstatus := common.ObjToString(v["trailstatus"])
  274. if JyBiMysql.ExecTx("领取线索等", func(tx *sql.Tx) bool {
  275. updateClue := map[string]interface{}{
  276. "position_id": positionId,
  277. "seatNumber": seatNumber,
  278. "is_assign": 1,
  279. "updatetime": nowTime,
  280. "comeintime": nowTime,
  281. "comeinsource_private": 3,
  282. "is_task": 1,
  283. "task_time": nowTime,
  284. "tasktime": nowTime,
  285. "taskstatus": 0,
  286. "tasksource": "领取公海线索",
  287. }
  288. if trailstatus != "08" {
  289. updateClue["trailstatus"] = "01"
  290. }
  291. ok1 := JyBiTidb.UpdateByTx(tx, "dwd_f_crm_clue_info", map[string]interface{}{"id": clueId}, updateClue)
  292. // ok2 := JyBiTidb.DeleteByTx(tx, "dwd_f_crm_open_sea", map[string]interface{}{"clue_id": clueId})
  293. // seaId := JyBiTidb.InsertByTx(tx, "dwd_f_crm_private_sea", map[string]interface{}{
  294. // "clue_id": clueId,
  295. // "seatNumber": seatNumber,
  296. // "position_id": positionId,
  297. // "comeintime": nowTime,
  298. // "comeinsource": 3,
  299. // "is_task": 1,
  300. // "task_time": nowTime,
  301. // "tasktime": nowTime,
  302. // "taskstatus": 0,
  303. // "tasksource": "领取公海线索",
  304. // })
  305. recordId := JyBiTidb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  306. "clue_id": clueId,
  307. "position_id": positionId,
  308. "change_field": "position_id",
  309. "change_type": "所属人变更",
  310. "old_value": "/",
  311. "new_value": name,
  312. "createtime": nowTime,
  313. "BCPCID": common.GetRandom(32),
  314. "operator_id": positionId,
  315. })
  316. recordId1 := JyBiTidb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  317. "clue_id": clueId,
  318. "position_id": positionId,
  319. "change_type": "领取公海线索",
  320. "createtime": nowTime,
  321. "BCPCID": common.GetRandom(32),
  322. "operator_id": positionId,
  323. })
  324. recordId2 := JyBiTidb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  325. "clue_id": clueId,
  326. "position_id": positionId,
  327. "change_type": "加入任务车",
  328. "new_value": "领取公海线索",
  329. "createtime": nowTime,
  330. "BCPCID": common.GetRandom(32),
  331. "operator_id": positionId,
  332. })
  333. recordId3, recordId4 := int64(0), int64(0)
  334. if trailstatus != "08" {
  335. recordId3 = JyBiTidb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  336. "clue_id": clueId,
  337. "position_id": positionId,
  338. "change_field": "trailstatus",
  339. "change_type": "基本信息变更",
  340. "old_value": "商机线索",
  341. "new_value": "新增",
  342. "createtime": nowTime,
  343. "BCPCID": common.GetRandom(32),
  344. "operator_id": positionId,
  345. })
  346. recordId4 = JyBiTidb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  347. "clue_id": clueId,
  348. "position_id": positionId,
  349. "change_field": "trailstatus",
  350. "change_type": "基本信息变更",
  351. "old_value": CodeTrail[trailstatus],
  352. "new_value": "商机线索",
  353. "createtime": nowTime,
  354. "BCPCID": common.GetRandom(32),
  355. "operator_id": positionId,
  356. })
  357. }
  358. return ok1 && recordId > 0 && recordId1 > 0 && recordId2 > 0 && recordId3 > -1 && recordId4 > -1
  359. }) {
  360. log.Println("领取线索成功")
  361. } else {
  362. log.Println("领取线索失败")
  363. }
  364. }(v)
  365. }
  366. wg.Wait()
  367. }
  368. func getSeatNumber(positionId int64) (seatNumber, name string) {
  369. positionData := JyTidb.FindOne("base_position", map[string]interface{}{"id": positionId}, "", "")
  370. if positionData != nil && len(*positionData) > 0 {
  371. userId := common.Int64All((*positionData)["user_id"])
  372. if userId > 0 {
  373. userData, ok := Mgo.FindOne("user", map[string]interface{}{"base_user_id": userId})
  374. if ok && userData != nil && len(*userData) > 0 {
  375. s_phone := common.ObjToString((*userData)["s_phone"])
  376. if s_phone == "" {
  377. s_phone = common.ObjToString((*userData)["s_m_phone"])
  378. }
  379. saleData := JyBiTidb.FindOne("jy_salesperson_info", map[string]interface{}{"phone": s_phone}, "", "")
  380. if saleData != nil && len(*saleData) > 0 {
  381. seatNumber = common.ObjToString((*saleData)["seatNumber"])
  382. name = common.ObjToString((*saleData)["name"])
  383. }
  384. }
  385. }
  386. }
  387. return
  388. }