jobutil.go 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384
  1. package main
  2. import (
  3. "app.yhyue.com/moapp/jybase/redis"
  4. "fmt"
  5. "log"
  6. "math"
  7. "strings"
  8. "time"
  9. "github.com/gogf/gf/v2/util/gconv"
  10. "app.yhyue.com/moapp/jybase/common"
  11. "app.yhyue.com/moapp/jybase/date"
  12. "app.yhyue.com/moapp/jybase/mongodb"
  13. )
  14. // 电销工单生成
  15. func rderAcceptance() {
  16. sql := fmt.Sprintf(`select * from order_acceptance where is_clue=2 and is_delete=1 order by propose_time `)
  17. //sql := fmt.Sprintf(`select * from order_acceptance where is_clue=2 and is_delete=1 and id = 333 order by propose_time `)
  18. data := WorkOrder.SelectBySql(sql)
  19. if data != nil && len(*data) > 0 {
  20. for _, v := range *data {
  21. acceptance_no := gconv.String(v["acceptance_no"])
  22. childrenArr := WorkOrder.Find("order_acceptance_children", map[string]interface{}{
  23. "acceptance_no": acceptance_no,
  24. }, "", "", -1, -1)
  25. if childrenArr != nil && len(*childrenArr) > 0 {
  26. company := ""
  27. phone := ""
  28. demand := ""
  29. name := ""
  30. product := ""
  31. for _, v1 := range *childrenArr {
  32. if gconv.String(v1["field_name"]) == "公司名称" {
  33. company = gconv.String(v1["field_value"])
  34. }
  35. if gconv.String(v1["field_name"]) == "联系方式num" {
  36. phone = gconv.String(v1["field_value"])
  37. }
  38. if gconv.String(v1["field_name"]) == "客户姓名" {
  39. name = gconv.String(v1["field_value"])
  40. }
  41. if gconv.String(v1["field_name"]) == "客户需求" {
  42. demand = gconv.String(v1["field_value"])
  43. }
  44. if gconv.String(v1["field_name"]) == "咨询产品" {
  45. product = gconv.String(v1["field_value"])
  46. }
  47. }
  48. if !WorkDataHandle(company, phone, demand, name, product, v) {
  49. log.Println("工单创建失败")
  50. }
  51. }
  52. }
  53. }
  54. }
  55. func WorkDataHandle(company, phone, demand, name, product string, acceptanceData map[string]interface{}) bool {
  56. uId := ""
  57. query := map[string]interface{}{}
  58. contactsData := TiDb.SelectBySql("select * from dwd_f_userbase_contacts where phone = ? and is_delete = 1", phone)
  59. if contactsData != nil && len(*contactsData) > 0 {
  60. if common.ObjToString((*contactsData)[0]["baseinfo_id"]) != "" {
  61. uId = common.ObjToString((*contactsData)[0]["baseinfo_id"])
  62. query["uid"] = uId
  63. }
  64. }
  65. if uId == "" {
  66. log.Println("用户信息不存在")
  67. return false
  68. }
  69. cluename := company
  70. if cluename == "" {
  71. cluename = phone //没有线索名,手机号代替
  72. }
  73. ok, data, saleData := false, map[string]interface{}{}, []map[string]interface{}{}
  74. isGroup, isCommerce := GetCompanyType(cluename)
  75. uCount, _ := TiDb.FindOne("dwd_f_crm_clue_info", map[string]interface{}{"uid": uId}, "", ""), true //查当前线索是否已存在
  76. if uCount != nil && len(*uCount) > 0 {
  77. clueId := gconv.Int64((*uCount)["id"])
  78. positionId := gconv.Int64((*uCount)["position_id"])
  79. trailstatus := gconv.String((*uCount)["trailstatus"])
  80. IS_TRANSFER := gconv.Int64((*uCount)["IS_TRANSFER"])
  81. if IS_TRANSFER == 1 {
  82. //客成处理
  83. //客成
  84. //生成客成数据
  85. customerMap := TiDb.FindOne("dwd_f_csm_customer_info", map[string]interface{}{
  86. "clue_id": clueId,
  87. }, "position_id,name", "")
  88. if customerMap != nil && len(*customerMap) > 0 {
  89. //UpdateClue(*uCount, saleData, "", "", uId, "5", "169", "新增线索", "主动咨询客服留资客户", company, name, gconv.String((*uCount)["name"]), phone, "", "", "", "", "", "", gconv.String((*uCount)["seat_number"]), "", gconv.Int64((*uCount)["position_id"]), "", "", "", []string{}, "", isGroup, isCommerce, false, demand)
  90. WorkUpdateClue(*uCount, saleData, "", "", uId, "5", "169", "新增线索", "主动咨询客服留资客户", cluename, name, gconv.String((*uCount)["name"]), phone, "", "", "", "", "", "", gconv.String((*uCount)["seat_number"]), "", gconv.Int64((*uCount)["position_id"]), "", "", "", []string{}, "", isGroup, isCommerce, false, demand)
  91. data = map[string]interface{}{
  92. "type": "kc",
  93. "position_id": (*customerMap)["position_id"],
  94. "name": (*customerMap)["name"],
  95. }
  96. } else {
  97. log.Println("查询不到客成数据", clueId, uId)
  98. return false
  99. }
  100. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  101. "clue_id": clueId,
  102. "position_id": (*customerMap)["position_id"],
  103. "change_type": "加入任务车",
  104. "new_value": "咨询客服转客成",
  105. "createtime": time.Now().Format(date.Date_Full_Layout),
  106. "BCPCID": common.GetRandom(32),
  107. "operator_id": -1,
  108. })
  109. } else {
  110. if positionId == 0 {
  111. //线索变更
  112. ok, data, saleData = FindPosition(0, "", gconv.String(acceptanceData["creator_time"]))
  113. if !ok {
  114. log.Println(positionId, "用户查询失败")
  115. return false
  116. }
  117. WorkUpdateClue(*uCount, saleData, "", "", uId, "5", "169", "新增线索", "主动咨询客服留资客户", cluename, name, gconv.String(data["name"]), phone, "", "", "", "", "", "", gconv.String(data["seat_number"]), "", gconv.Int64(data["position_id"]), "", "", "", []string{}, "", isGroup, isCommerce, true, demand)
  118. } else {
  119. ok, data, saleData = FindPosition(positionId, trailstatus, gconv.String(acceptanceData["creator_time"]))
  120. if !ok {
  121. log.Println(positionId, "用户查询失败")
  122. return false
  123. }
  124. if gconv.Int64(data["position_id"]) == positionId {
  125. WorkUpdateClue(*uCount, saleData, "", "", uId, "5", "169", "新增线索", "主动咨询客服留资客户", cluename, name, gconv.String(data["name"]), phone, "", "", "", "", "", "", gconv.String(data["seat_number"]), "", gconv.Int64(data["position_id"]), "", "", "", []string{}, "", isGroup, isCommerce, false, demand)
  126. } else {
  127. WorkUpdateClue(*uCount, saleData, "", "", uId, "5", "169", "新增线索", "主动咨询客服留资客户", cluename, name, gconv.String(data["name"]), phone, "", "", "", "", "", "", gconv.String(data["seat_number"]), "", gconv.Int64(data["position_id"]), "", "", "", []string{}, "", isGroup, isCommerce, true, demand)
  128. }
  129. }
  130. }
  131. } else {
  132. //新增线索
  133. ok, data, _ = FindPosition(0, "", gconv.String(acceptanceData["creator_time"]))
  134. if !ok {
  135. return false
  136. }
  137. SaveClue("", "", uId, "5", "169", "新增线索", "主动咨询客服留资客户", cluename, name, gconv.String(data["name"]), phone, "", "", "", "", "", "", gconv.String(data["seat_number"]), gconv.Int64(data["position_id"]), "", "", "", []string{}, "", isGroup, isCommerce, false, demand)
  138. }
  139. //工单生成
  140. ok1 := AddOrderWork(acceptanceData, data, product, phone, company)
  141. log.Println("工单创建", ok1, gconv.String(acceptanceData["acceptance_no"]))
  142. return true
  143. }
  144. func AddOrderWork(acceptanceData map[string]interface{}, userData map[string]interface{}, product, phone, company string) bool {
  145. nowTime := time.Now().Format(date.Date_Full_Layout)
  146. work_order_no := fmt.Sprintf("GD%s%s", time.Now().Format(date.Date_yyyyMMdd), FindNumber("gd"))
  147. productArr := []string{}
  148. for _, v := range strings.Split(product, ",") {
  149. switch ProductMap[v] {
  150. case "dk":
  151. continue
  152. default:
  153. productArr = append(productArr, v)
  154. }
  155. }
  156. two_type := "dx"
  157. if gconv.String(userData["type"]) == "kc" {
  158. two_type = "kc"
  159. }
  160. personMap := GetPerson(gconv.String(userData["position_id"]))
  161. if personMap == nil || len(personMap) == 0 {
  162. return false
  163. }
  164. orderWorkMap := map[string]interface{}{
  165. "work_order_no": work_order_no,
  166. "acceptance_no": gconv.String(acceptanceData["acceptance_no"]),
  167. "type": strings.Join(productArr, ","),
  168. "status": common.If(gconv.Int64(userData["orderStatus"]) == 0, 2, 1),
  169. "initiator_name": gconv.String(acceptanceData["creator_name"]),
  170. "initiator_position_id": gconv.String(acceptanceData["initiator_position_id"]),
  171. "current_name": common.If(gconv.Int64(userData["orderStatus"]) == 0, nil, userData["name"]),
  172. "current_position_id": common.If(gconv.Int64(userData["orderStatus"]) == 0, nil, userData["position_id"]),
  173. "history_name": common.If(gconv.Int64(userData["orderStatus"]) == 0, userData["name"], nil),
  174. "history_postion_id": common.If(gconv.Int64(userData["orderStatus"]) == 0, userData["position_id"], nil),
  175. "is_delete": 1,
  176. "creator_name": gconv.String(acceptanceData["creator_name"]),
  177. "creator_position_id": gconv.String(acceptanceData["creator_position_id"]),
  178. "creator_time": nowTime,
  179. "two_type": two_type,
  180. "department_no": gconv.String(personMap["deptId"]),
  181. "department_name": gconv.String(personMap["deptName"]),
  182. "update_time": common.If(gconv.Int64(userData["orderStatus"]) == 0, nowTime, nil),
  183. }
  184. ok3 := WorkOrder.Insert("order_work", orderWorkMap)
  185. if ok3 > 0 {
  186. status := 2
  187. if WorkOrder.Count("order_work", map[string]interface{}{
  188. "status": 1,
  189. "acceptance_no": gconv.String(acceptanceData["acceptance_no"]),
  190. }) > 0 {
  191. status = 1
  192. }
  193. WorkOrder.Update("order_acceptance", map[string]interface{}{
  194. "id": acceptanceData["id"],
  195. }, map[string]interface{}{
  196. "is_clue": 3,
  197. "status": status,
  198. "over_time": common.If(status == 1, nil, nowTime),
  199. })
  200. //日志添加
  201. approvalRecordMap := map[string]interface{}{
  202. "work_order_no": work_order_no,
  203. "status": common.If(gconv.Int64(userData["orderStatus"]) == 0, 3, 1),
  204. "new_status": common.If(gconv.Int64(userData["orderStatus"]) == 0, 2, nil),
  205. "handle_name": userData["name"],
  206. "handle_position_id": userData["position_id"],
  207. "handle_dept_id": gconv.String(personMap["deptId"]),
  208. "handle_dept_name": gconv.String(personMap["deptName"]),
  209. "creator_name": gconv.String(acceptanceData["creator_name"]),
  210. "creator_position_id": gconv.String(acceptanceData["initiator_position_id"]),
  211. "is_delete": 1,
  212. "creator_time": nowTime,
  213. "handle_time": common.If(gconv.Int64(userData["orderStatus"]) == 0, nowTime, nil),
  214. "update_name": common.If(gconv.Int64(userData["orderStatus"]) == 0, userData["name"], nil),
  215. "update_position_id": common.If(gconv.Int64(userData["orderStatus"]) == 0, userData["position_id"], nil),
  216. "update_time": common.If(gconv.Int64(userData["orderStatus"]) == 0, nowTime, nil),
  217. }
  218. WorkOrder.Insert("approval_record", approvalRecordMap)
  219. WorkMail(personMap,
  220. strings.Join(productArr, ","),
  221. gconv.Int64(common.If(gconv.Int64(userData["orderStatus"]) == 0, 2, 1)),
  222. gconv.String(personMap["name"]),
  223. gconv.String(acceptanceData["creator_name"]),
  224. nowTime,
  225. work_order_no,
  226. phone,
  227. company)
  228. return true
  229. }
  230. return false
  231. }
  232. // 本级以及上级管理员查询
  233. func GetPerson(positionId string) map[string]interface{} {
  234. person := map[string]interface{}{}
  235. positionArrMap := Base.SelectBySql(fmt.Sprintf(`select a.phone,b.id,b.ent_id from
  236. base_user a
  237. INNER JOIN base_position b
  238. on b.id=%s and b.user_id=a.id and b.type=1`,
  239. positionId))
  240. if positionArrMap == nil || len(*positionArrMap) == 0 {
  241. return map[string]interface{}{}
  242. }
  243. phone := gconv.String((*positionArrMap)[0]["phone"])
  244. entId := gconv.String((*positionArrMap)[0]["ent_id"])
  245. entUserArrMap := Mysql.SelectBySql(fmt.Sprintf(`SELECT
  246. a.name as name,a.mail as mail,b.dept_id as deptId,a.phone ,c.name as deptName
  247. FROM
  248. entniche_user a
  249. INNER JOIN entniche_department_user b ON a.ent_id =%s
  250. AND a.phone IN %s
  251. and a.id=b.user_id
  252. inner join entniche_department c on b.dept_id=c.id
  253. `, entId, fmt.Sprintf("(%s)", phone)))
  254. //商机管理员
  255. if entUserArrMap == nil || len(*entUserArrMap) == 0 {
  256. return map[string]interface{}{}
  257. }
  258. deptId := gconv.Int64((*entUserArrMap)[0]["deptId"])
  259. person = map[string]interface{}{
  260. "name": gconv.String((*entUserArrMap)[0]["name"]),
  261. "mail": gconv.String((*entUserArrMap)[0]["mail"]),
  262. "phone": gconv.String((*entUserArrMap)[0]["phone"]),
  263. "deptId": gconv.String((*entUserArrMap)[0]["deptId"]),
  264. "deptName": gconv.String((*entUserArrMap)[0]["deptName"]),
  265. }
  266. //本部门管理员查询
  267. depthMap := Mysql.SelectBySql(`SELECT
  268. c.name as name,c.mail as mail
  269. FROM
  270. entniche_department_user a
  271. INNER JOIN entniche_user_role b ON a.dept_id = ?
  272. AND a.user_id = b.user_id
  273. AND b.role_id !=""
  274. INNER JOIN entniche_user c ON a.user_id = c.id`, deptId)
  275. if depthMap != nil && len(*depthMap) > 0 {
  276. person["deptPersonName"] = gconv.String((*depthMap)[0]["name"])
  277. person["deptPersonMail"] = gconv.String((*depthMap)[0]["mail"])
  278. }
  279. //商机管理员查询
  280. superiorDepthMap := Mysql.SelectBySql(`SELECT
  281. c.*
  282. FROM
  283. entniche_department d
  284. INNER JOIN entniche_department_user a ON d.id = ?
  285. AND d.pid = a.dept_id
  286. INNER JOIN entniche_user_role b ON a.user_id = b.user_id
  287. AND b.role_id !=""
  288. INNER JOIN entniche_user c ON a.user_id = c.id`, deptId)
  289. if superiorDepthMap != nil && len(*superiorDepthMap) > 0 {
  290. person["superiorDepthPersonName"] = gconv.String((*superiorDepthMap)[0]["name"])
  291. person["superiorDepthPersonMail"] = gconv.String((*superiorDepthMap)[0]["mail"])
  292. }
  293. return person
  294. }
  295. // 编号查询
  296. func FindNumber(moudle string) string {
  297. today := time.Now().Format("2006-01-02")
  298. yesterday := time.Now().AddDate(0, 0, -1).Format("2006-01-02")
  299. key := fmt.Sprintf("%s_%s", today, moudle)
  300. yesterdayKey := fmt.Sprintf("%s_%s", yesterday, moudle)
  301. if ok, _ := redis.Exists("newother", yesterdayKey); ok {
  302. //删除之前数据
  303. redis.Del("newother", yesterdayKey)
  304. }
  305. count := redis.Incr("newother", key)
  306. log.Println("编号获取", moudle, fmt.Sprintf("%04d", count))
  307. return fmt.Sprintf("%04d", count)
  308. }
  309. // 人员查询
  310. func GetAllocation(proportion1, proportion3 float64, deptCount1, deptCount3 int64, administrators1, administrators3 map[string]interface{}, creatorTime string) map[string]interface{} {
  311. log.Println("分配比例查询", proportion1, proportion3, deptCount1, deptCount3)
  312. if deptCount1 == 0 {
  313. return administrators1
  314. }
  315. if deptCount3 == 0 {
  316. return administrators3
  317. }
  318. nowAllocationRatio := math.Round(gconv.Float64(deptCount1 / deptCount3))
  319. if cfg.AllocationRatio == 0 {
  320. //重新计算
  321. cfg.AllocationRatio = math.Round(proportion1 / proportion3)
  322. cfg.AllocationTime = creatorTime
  323. common.WriteSysConfig(&cfg)
  324. log.Println("新增计算比例", cfg.AllocationRatio)
  325. return administrators1
  326. } else {
  327. if nowAllocationRatio == cfg.AllocationRatio {
  328. //重新计算
  329. cfg.AllocationRatio = math.Round(proportion1 / proportion3)
  330. cfg.AllocationTime = creatorTime
  331. common.WriteSysConfig(&cfg)
  332. return administrators1
  333. }
  334. }
  335. if nowAllocationRatio > cfg.AllocationRatio {
  336. return administrators3
  337. } else {
  338. return administrators1
  339. }
  340. //达到比例也重新计算
  341. }
  342. func FindPosition(positionId int64, trailstatus, creatorTime string) (bool, map[string]interface{}, []map[string]interface{}) {
  343. allData := []map[string]interface{}{}
  344. //查询两个部门高级管理员
  345. //查询两个部门所有人员标识
  346. //电销三部
  347. userData1 := TiDb.SelectBySql(`SELECT
  348. a.position_id,
  349. a.name,
  350. b.seat_number,
  351. b.role_id,
  352. a.bi_pcode,
  353. a.dept_name
  354. FROM
  355. dwd_d_crm_department_level_succbi a
  356. INNER JOIN dwd_f_crm_personnel_management b ON a.resign = 0 and b.resign = 0
  357. AND a.dept_name LIKE "%电销部%"
  358. AND a.position_id = b.position_id`)
  359. userData3 := TiDb.SelectBySql(`SELECT
  360. a.position_id,
  361. a.name,
  362. b.seat_number,
  363. b.role_id,
  364. a.bi_pcode,
  365. a.dept_name
  366. FROM
  367. dwd_d_crm_department_level_succbi a
  368. INNER JOIN dwd_f_crm_personnel_management b ON a.resign = 0 and b.resign = 0
  369. AND a.resign = 0
  370. AND a.dept_name LIKE "%销售三部"
  371. AND a.position_id = b.position_id`)
  372. if userData3 == nil || len(*userData3) == 0 || userData1 == nil || len(*userData1) == 0 {
  373. return false, map[string]interface{}{}, allData
  374. }
  375. //一部管理员信息
  376. administrators1 := map[string]interface{}{}
  377. //三部管理员信息
  378. administrators3 := map[string]interface{}{}
  379. //返回当前人信息
  380. administrators := map[string]interface{}{}
  381. //电销一部
  382. deptNameMap1 := map[string]interface{}{}
  383. deptNameMap3 := map[string]interface{}{}
  384. proportion1 := float64(0)
  385. proportion3 := float64(0)
  386. for _, v := range *userData3 {
  387. v["type"] = 3
  388. id := gconv.Int64(v["position_id"])
  389. roleId := gconv.Int64(v["role_id"])
  390. if id == positionId {
  391. administrators = v
  392. }
  393. if roleId == 8 {
  394. v["orderStatus"] = 2
  395. administrators3 = v
  396. } else if roleId == 3 {
  397. proportion3 += 0.5
  398. } else {
  399. proportion3 += 1
  400. }
  401. deptNameMap3[gconv.String(v["bi_pcode"])] = true
  402. allData = append(allData, v)
  403. }
  404. for _, v := range *userData1 {
  405. v["type"] = 1
  406. id := gconv.Int64(v["position_id"])
  407. roleId := gconv.Int64(v["role_id"])
  408. if id == positionId {
  409. administrators = v
  410. }
  411. if roleId == 8 {
  412. v["orderStatus"] = 2
  413. administrators1 = v
  414. } else if roleId == 3 {
  415. proportion1 += 0.5
  416. } else {
  417. proportion1 += 1
  418. }
  419. deptNameMap1[gconv.String(v["bi_pcode"])] = true
  420. allData = append(allData, v)
  421. }
  422. if positionId != 0 {
  423. if administrators == nil || len(administrators) == 0 {
  424. return false, map[string]interface{}{}, allData
  425. }
  426. positiontype := gconv.Int64(administrators["type"])
  427. if trailstatus == "01" || trailstatus == "03" || trailstatus == "04" {
  428. switch positiontype {
  429. case 1:
  430. //找他上级
  431. administrators = administrators1
  432. case 3:
  433. //找他上级
  434. administrators = administrators3
  435. }
  436. return true, administrators, allData
  437. } else {
  438. return true, administrators, allData
  439. }
  440. }
  441. //按照比例分配选择一部还是三部
  442. //一部查询
  443. deptCount1 := CalculateProportion(deptNameMap1)
  444. //三部查询
  445. deptCount3 := CalculateProportion(deptNameMap3)
  446. return true, GetAllocation(proportion1, proportion3, deptCount1, deptCount3, administrators1, administrators3, creatorTime), allData
  447. log.Println("电销信息获取失败", positionId)
  448. return false, map[string]interface{}{}, allData
  449. }
  450. func CalculateProportion(deptNameMap map[string]interface{}) int64 {
  451. deptNameStr := ""
  452. for k := range deptNameMap {
  453. if deptNameStr == "" {
  454. deptNameStr = k
  455. } else {
  456. deptNameStr = fmt.Sprintf("%s,%s", deptNameStr, k)
  457. }
  458. }
  459. if deptNameStr == "" {
  460. return int64(0)
  461. }
  462. count := int64(0)
  463. sql := fmt.Sprintf(`SELECT
  464. sum(1) as count
  465. FROM
  466. order_work a
  467. INNER JOIN approval_record b ON a.creator_time >= "%s"
  468. AND FIND_IN_SET( a.department_no , "%s")
  469. AND a.work_order_no = b.work_order_no
  470. and (b.new_status!= 1 or b.new_status is null )
  471. `, cfg.AllocationTime, deptNameStr)
  472. data := WorkOrder.SelectBySql(sql)
  473. if data != nil && len(*data) > 0 {
  474. count = gconv.Int64((*data)[0]["count"])
  475. }
  476. return count
  477. }
  478. // 未支付订单 30分钟一次
  479. func orders() {
  480. //一个小时未支付进入线索 A
  481. log.Println("未支付订单定时任务开始")
  482. lastOrderId := cfg.LastOrderId
  483. selectTimeStart := time.Unix(time.Now().Unix()-7200, 0).Format(date.Date_Full_Layout)
  484. selectTimeEnd := time.Unix(time.Now().Unix()-3600, 0).Format(date.Date_Full_Layout)
  485. sql := fmt.Sprintf(`select * from dataexport_order where create_time <= "%s" and create_time >= "%s" and id > %s`, selectTimeEnd, selectTimeStart, fmt.Sprint(lastOrderId))
  486. data := Mysql.SelectBySql(sql)
  487. if data != nil && *data != nil && len(*data) > 0 {
  488. for _, v := range *data {
  489. order_status := common.IntAll(v["order_status"])
  490. is_backstage_order := common.IntAll(v["is_backstage_order"])
  491. product_type_str1 := `"大会员","VIP订阅","数据流量包","历史数据"`
  492. product_type := common.ObjToString(v["product_type"])
  493. if order_status == 0 && is_backstage_order == 0 && strings.Contains(product_type_str1, product_type) {
  494. ok1, ok2 := FormatData(v, "orders")
  495. if !ok1 {
  496. common.WriteSysConfig(&cfg)
  497. log.Println("线索卡点", "orders", v, selectTimeEnd, selectTimeStart)
  498. break
  499. } else {
  500. if !ok2 {
  501. log.Println("用户分配已达上限", "orders", v, selectTimeEnd, selectTimeStart)
  502. common.WriteSysConfig(&cfg)
  503. break
  504. }
  505. }
  506. }
  507. cfg.LastOrderId = common.IntAll(v["id"])
  508. }
  509. }
  510. common.WriteSysConfig(&cfg)
  511. log.Println("未支付订单定时任务结束")
  512. }
  513. func readClue() {
  514. log.Println("读表进线索定时任务开始")
  515. lastReadClueTime := cfg.LastReadClueTime
  516. sql := fmt.Sprintf(`select * from clue_info where updatetime > "%s" order by updatetime asc`, fmt.Sprint(lastReadClueTime))
  517. data := TiDb.SelectBySql(sql)
  518. if data != nil && *data != nil && len(*data) > 0 {
  519. for _, v := range *data {
  520. ok1, ok2 := FormatData(v, "readClue")
  521. if !ok1 {
  522. common.WriteSysConfig(&cfg)
  523. log.Println("线索卡点", "readClue", v, lastReadClueTime)
  524. break
  525. } else {
  526. if !ok2 {
  527. log.Println("用户分配已达上限", "readClue", v, lastReadClueTime)
  528. common.WriteSysConfig(&cfg)
  529. break
  530. }
  531. }
  532. cfg.LastReadClueTime = common.ObjToString(v["updatetime"])
  533. }
  534. }
  535. common.WriteSysConfig(&cfg)
  536. log.Println("读表进线索定时任务结束")
  537. }
  538. // 新注册用户 5分钟一次
  539. func users() {
  540. //判断节假日
  541. runOk := getRunOk()
  542. if !runOk {
  543. log.Println("不是工作日,任务暂停")
  544. return
  545. }
  546. //新用户注册后5分钟内进入线索 C
  547. log.Println("新注册用户定时任务开始")
  548. selectTimeEnd := cfg.LastUserId
  549. sql := fmt.Sprintf(`select * from dwd_f_userbase_baseinfo where createtime > "%s" and source = "0101" and status != 2 order by createtime asc`, selectTimeEnd)
  550. data := TiDb.SelectBySql(sql)
  551. if data != nil && *data != nil && len(*data) > 0 {
  552. for k, v := range *data {
  553. //判断用户是否有小程序切使用过剑鱼其他产品
  554. s_platform := gconv.String(v["s_platform"])
  555. login_positionid := gconv.Int64(v["login_positionid"])
  556. createtime := common.ObjToString(v["createtime"])
  557. if s_platform == "xcx" && login_positionid == 0 {
  558. log.Println(v, "用户是否有小程序且未使用过剑鱼其他产品")
  559. } else {
  560. ok1, ok2 := FormatData(v, "users")
  561. if !ok1 {
  562. log.Println("线索卡点", "users", v, selectTimeEnd)
  563. } else {
  564. if !ok2 {
  565. log.Println("用户分配已达上限", "users", v, selectTimeEnd)
  566. }
  567. }
  568. }
  569. if k == len(*data)-1 {
  570. cfg.LastUserId = createtime
  571. }
  572. }
  573. }
  574. common.WriteSysConfig(&cfg)
  575. selectXcxTimeEnd := cfg.LastXcxUserId
  576. xcxSql := fmt.Sprintf(`select * from dwd_f_userbase_baseinfo where s_platform ="xcx" and updatetime> "%s" and source = "0101" and status != 2 and clue_operate_status!=1 order by createtime asc`, selectXcxTimeEnd)
  577. xcxData := TiDb.SelectBySql(xcxSql)
  578. if xcxData != nil && *xcxData != nil && len(*xcxData) > 0 {
  579. for k, v := range *xcxData {
  580. //判断用户是否有小程序切使用过剑鱼其他产品
  581. s_platform := gconv.String(v["s_platform"])
  582. login_positionid := gconv.Int64(v["login_positionid"])
  583. updatetime := common.ObjToString(v["updatetime"])
  584. if s_platform == "xcx" && login_positionid == 0 {
  585. log.Println(gconv.String(v["id"]), "用户是否有小程序且未使用过剑鱼其他产品")
  586. } else {
  587. ok1, ok2 := FormatData(v, "xcxusers")
  588. if !ok1 {
  589. common.WriteSysConfig(&cfg)
  590. log.Println("小程序用户分配线索卡点", "xcxusers", v, selectXcxTimeEnd)
  591. break
  592. } else {
  593. if !ok2 {
  594. log.Println("小程序用户分配已达上限", "xcxusers", v, selectXcxTimeEnd)
  595. common.WriteSysConfig(&cfg)
  596. break
  597. }
  598. }
  599. TiDb.Update("dwd_f_userbase_baseinfo", map[string]interface{}{
  600. "id": gconv.Int64(v["id"]),
  601. }, map[string]interface{}{
  602. "clue_operate_status": 1,
  603. })
  604. }
  605. if k == len(*xcxData)-1 {
  606. cfg.LastXcxUserId = updatetime
  607. }
  608. }
  609. }
  610. common.WriteSysConfig(&cfg)
  611. log.Println("新注册用户定时任务结束")
  612. }
  613. // 留资 5分钟一次
  614. func saleLeads() {
  615. //判断节假日
  616. runOk := getRunOk()
  617. if !runOk {
  618. log.Println("不是工作日,任务暂停")
  619. return
  620. }
  621. //留资后5分钟内进入线索
  622. //分为免费留资和付费留资 付费B 免费C
  623. log.Println("用户留资定时任务开始")
  624. session := Mgo.GetMgoConn()
  625. lastId := cfg.LastId
  626. defer func() {
  627. Mgo.DestoryMongoConn(session)
  628. }()
  629. query := map[string]interface{}{}
  630. if lastId != "" {
  631. query["_id"] = map[string]interface{}{"$gt": mongodb.StringTOBsonId(lastId)}
  632. }
  633. log.Println("query :", query)
  634. iter := session.DB(db.Mgo.DbName).C("saleLeads").Find(&query).Sort("_id").Iter()
  635. thisData := map[string]interface{}{}
  636. for {
  637. if !iter.Next(&thisData) {
  638. break
  639. }
  640. sourceCode := common.ObjToString(thisData["source"])
  641. if sourceCode == "" {
  642. log.Println("留资没有source", thisData)
  643. continue
  644. }
  645. //
  646. filterArr := []string{"-pc", "-app", "-wx", "-h5"}
  647. sourceMap := map[string]string{}
  648. saleSource := TiDb.SelectBySql(`SELECT source,name FROM d_saleleads_code WHERE (department LIKE '%大客户%' or department LIKE '%市场组%' or department LIKE '%咨询组%') AND is_delete = 1`)
  649. if saleSource != nil && len(*saleSource) > 0 {
  650. for _, v := range *saleSource {
  651. source := common.ObjToString(v["source"])
  652. name := common.ObjToString(v["name"])
  653. for _, s := range filterArr {
  654. name = strings.ReplaceAll(name, s, "")
  655. }
  656. sourceMap[source] = name
  657. }
  658. }
  659. if sourceMap[sourceCode] != "" {
  660. continue
  661. }
  662. ok1, ok2 := FormatData(thisData, "saleLeads")
  663. if !ok1 {
  664. log.Println("线索卡点", "saleLeads", thisData, lastId)
  665. } else {
  666. if !ok2 {
  667. log.Println("用户分配已达上限", "saleLeads", thisData, lastId)
  668. }
  669. }
  670. cfg.LastId = mongodb.BsonIdToSId(thisData["_id"])
  671. }
  672. common.WriteSysConfig(&cfg)
  673. log.Println("用户留资定时任务结束")
  674. }
  675. func userbase() {
  676. log.Println("userbase定时任务开始")
  677. selectTimeEnd := time.Unix(time.Now().Unix()-1800, 0).Format("2006-01-02 15:04:05")
  678. sql := fmt.Sprintf(`select * from dwd_f_userbase_baseinfo where updatetime > "%s" and source != "0105" and source != "0104" and source != "0103" and source != "0102"`, selectTimeEnd)
  679. data := TiDb.SelectBySql(sql)
  680. if data != nil && *data != nil && len(*data) > 0 {
  681. for _, v := range *data {
  682. phone := common.ObjToString(v["phone"])
  683. uId := common.ObjToString(v["uid"])
  684. userId := common.ObjToString(v["userid"])
  685. //判断用户是否有小程序切使用过剑鱼其他产品
  686. s_platform := gconv.String(v["s_platform"])
  687. login_positionid := gconv.Int64(v["login_positionid"])
  688. if s_platform == "xcx" && login_positionid == 0 {
  689. log.Println(phone, uId, userId, "用户是否有小程序且未使用过剑鱼其他产品")
  690. continue
  691. }
  692. registedate := common.ObjToString(v["l_registedate"])
  693. name := common.ObjToString(v["name"])
  694. nowTime := time.Now().Format(date.Date_Full_Layout)
  695. source := common.ObjToString(v["source"])
  696. if phone != "" {
  697. contactsData := TiDb.SelectBySql("select * from dwd_f_userbase_contacts where phone = ? and is_delete = 1", phone)
  698. if contactsData == nil || len(*contactsData) == 0 {
  699. contactsData2 := TiDb.SelectBySql("select * from dwd_f_userbase_contacts where baseinfo_id = ? and is_delete = 1", uId)
  700. if contactsData2 != nil && len(*contactsData2) > 0 {
  701. log.Println("userbase uid不为空 新增通讯录", uId)
  702. TiDb.Insert("dwd_f_userbase_contacts", map[string]interface{}{
  703. "status": 1,
  704. "is_delete": 1,
  705. "createtime": nowTime,
  706. "updatetime": nowTime,
  707. "phone": phone,
  708. "baseinfo_id": uId,
  709. "SOURCE": source,
  710. })
  711. } else {
  712. registedates, _ := time.Parse(date.Date_Full_Layout, registedate)
  713. count := TiDb.CountBySql("select count(1) as count from dwd_f_crm_clue_info where uid = ?", uId)
  714. log.Println("userbase uid 线索数量 ", count)
  715. log.Println("userbase uid 注册时间 ", registedates)
  716. if time.Now().Unix()-registedates.Unix() > int64(db.RegTimes)*86400 {
  717. if count == 0 {
  718. clueId := int64(0)
  719. sql := fmt.Sprintf(`select * from freeClubSign where mogUserId="%s" and sub_again_date > "%s" `, userId, selectTimeEnd)
  720. data := BiService.SelectBySql(sql)
  721. if len(*data) > 0 && userId != "" {
  722. clueId = TiDb.Insert("dwd_f_crm_clue_info", map[string]interface{}{
  723. "userid": userId,
  724. "uid": uId,
  725. "is_assign": 0,
  726. "comeintime": nowTime,
  727. "createtime": nowTime,
  728. "updatetime": nowTime,
  729. "cluename": phone,
  730. "top_cluetype": "532",
  731. "sub_cluetype": "670",
  732. "trailstatus": "01",
  733. "name": name,
  734. "phone": phone,
  735. "comeintime_open": nowTime,
  736. "comeinsource_open": 1,
  737. "FREEZE_TIME": nowTime,
  738. })
  739. } else {
  740. clueId = TiDb.Insert("dwd_f_crm_clue_info", map[string]interface{}{
  741. "userid": userId,
  742. "uid": uId,
  743. "is_assign": 0,
  744. "comeintime": nowTime,
  745. "createtime": nowTime,
  746. "updatetime": nowTime,
  747. "cluename": phone,
  748. "top_cluetype": "532",
  749. "sub_cluetype": "475",
  750. "trailstatus": "01",
  751. "name": name,
  752. "phone": phone,
  753. "comeintime_open": nowTime,
  754. "comeinsource_open": 1,
  755. "FREEZE_TIME": nowTime,
  756. })
  757. }
  758. if clueId > 0 {
  759. TiDb.Insert("dwd_f_userbase_contacts", map[string]interface{}{
  760. "status": 1,
  761. "is_delete": 1,
  762. "createtime": nowTime,
  763. "updatetime": nowTime,
  764. "phone": phone,
  765. "baseinfo_id": uId,
  766. "SOURCE": source,
  767. })
  768. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  769. "clue_id": clueId,
  770. "position_id": -1,
  771. "change_type": "创建线索",
  772. "new_value": "系统自动创建",
  773. "createtime": nowTime,
  774. "BCPCID": common.GetRandom(32),
  775. "operator_id": -1,
  776. })
  777. }
  778. } else {
  779. TiDb.Insert("dwd_f_userbase_contacts", map[string]interface{}{
  780. "status": 1,
  781. "is_delete": 1,
  782. "createtime": nowTime,
  783. "updatetime": nowTime,
  784. "phone": phone,
  785. "baseinfo_id": uId,
  786. "SOURCE": source,
  787. })
  788. }
  789. } else {
  790. if count == 0 {
  791. ok1, ok2 := FormatData(v, "users")
  792. if !ok1 {
  793. common.WriteSysConfig(&cfg)
  794. log.Println("线索卡点", "userbase uid", v, uId)
  795. break
  796. } else {
  797. if !ok2 {
  798. log.Println("用户分配已达上限", "userbase uid", v, uId)
  799. common.WriteSysConfig(&cfg)
  800. break
  801. }
  802. }
  803. } else {
  804. TiDb.Insert("dwd_f_userbase_contacts", map[string]interface{}{
  805. "status": 1,
  806. "is_delete": 1,
  807. "createtime": nowTime,
  808. "updatetime": nowTime,
  809. "phone": phone,
  810. "baseinfo_id": uId,
  811. "SOURCE": source,
  812. })
  813. }
  814. }
  815. }
  816. }
  817. }
  818. }
  819. }
  820. log.Println("userbase定时任务结束")
  821. }
  822. func getRunOk() bool {
  823. currentTime, runOk := time.Now(), false
  824. if currentTime.Weekday() == time.Sunday {
  825. isok := false
  826. for k, v := range DateMap {
  827. if currentTime.Format(date.Date_Short_Layout) == k && v == 2 {
  828. isok = true
  829. }
  830. }
  831. if isok {
  832. runOk = true
  833. }
  834. } else {
  835. isok := true
  836. for k, v := range DateMap {
  837. if currentTime.Format(date.Date_Short_Layout) == k && v == 1 {
  838. isok = false
  839. }
  840. }
  841. if isok {
  842. runOk = true
  843. }
  844. }
  845. return runOk
  846. }
  847. func getAreaCode(userId string) (code string) {
  848. followData := Base.Find("follow_project_monitor", map[string]interface{}{"s_userid": userId}, "", "", -1, -1)
  849. sidArr := []string{}
  850. if followData != nil && len(*followData) > 0 {
  851. for _, v := range *followData {
  852. infoId := common.ObjToString(v["s_id"])
  853. sidArr = append(sidArr, infoId)
  854. }
  855. }
  856. if len(sidArr) > 0 {
  857. query := `{"query": {"bool": {"must": [{"terms": {"_id": ["%s"]}}],"must_not": [],"should": []}}}`
  858. query = fmt.Sprintf(query, strings.Join(sidArr, `","`))
  859. biddingData := Es.Get("bidding", "bidding", query)
  860. if biddingData != nil && len(*biddingData) > 0 {
  861. codeMap := map[string]string{}
  862. codeArr := []string{}
  863. for _, v := range *biddingData {
  864. area := common.ObjToString(v["area"])
  865. address := common.ObjToString(v["city"])
  866. if address == "" {
  867. address = area
  868. }
  869. codeMap[address] = AreaCode[address]
  870. }
  871. if len(codeMap) > 0 {
  872. for _, v := range codeMap {
  873. codeArr = append(codeArr, v)
  874. }
  875. }
  876. if len(codeArr) > 0 {
  877. code = strings.Join(codeArr, ",")
  878. }
  879. }
  880. }
  881. log.Println("code ", code)
  882. return
  883. }
  884. func getClueType(item string, data map[string]interface{}, sourceCode string, sourceId int64) (pcode, code, level, topname, subname string) {
  885. if item == "orders" {
  886. productType := common.ObjToString(data["product_type"])
  887. pcode = "1"
  888. level = "A"
  889. topname = "提交订单未支付"
  890. if productType == "VIP订阅" {
  891. code = "6"
  892. subname = "超级订阅"
  893. } else if productType == "大会员" {
  894. code = "7"
  895. subname = "大会员"
  896. } else if productType == "数据流量包" {
  897. code = "8"
  898. subname = "数据流量包"
  899. } else if productType == "历史数据" {
  900. code = "9"
  901. subname = "数据自助导出"
  902. }
  903. } else if item == "users" {
  904. pcode = "4"
  905. code = "154"
  906. level = "C"
  907. topname = "新增注册"
  908. subname = "新增注册用户"
  909. } else if item == "message" {
  910. pcode = "532"
  911. code = "477"
  912. level = "B"
  913. topname = "其他"
  914. subname = "机器人客服主动咨询"
  915. } else if item == "readClue" {
  916. level = "A"
  917. topname = "超级订阅临期用户"
  918. pcode = "614"
  919. if sourceId == 1 {
  920. code = "615"
  921. subname = "60天后到期"
  922. } else if sourceId == 2 {
  923. code = "616"
  924. subname = "45天后到期"
  925. } else if sourceId == 3 {
  926. code = "617"
  927. subname = "15天后到期"
  928. } else {
  929. code = "618"
  930. subname = "7天后到期"
  931. }
  932. } else if item == "xcxusers" {
  933. level = "C"
  934. if sourceCode != "" {
  935. codeData := TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"source": sourceCode}, "", "")
  936. if codeData != nil && len(*codeData) > 0 {
  937. pcode = common.ObjToString((*codeData)["pcode"])
  938. code = common.ObjToString((*codeData)["code"])
  939. level = common.ObjToString((*codeData)["clue_level"])
  940. subname = common.ObjToString((*codeData)["name"])
  941. pcodeData := TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"code": pcode}, "", "")
  942. if pcodeData != nil && len(*pcodeData) > 0 {
  943. topname = common.ObjToString((*pcodeData)["name"])
  944. }
  945. }
  946. }
  947. } else if item == "allocation" {
  948. pcode = "532"
  949. code = "671"
  950. level = "C"
  951. pcodeData := TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"code": pcode}, "", "")
  952. if pcodeData != nil && len(*pcodeData) > 0 {
  953. topname = common.ObjToString((*pcodeData)["name"])
  954. }
  955. pcodeData = TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"code": code}, "", "")
  956. if pcodeData != nil && len(*pcodeData) > 0 {
  957. subname = common.ObjToString((*pcodeData)["name"])
  958. }
  959. } else if item == "rebind" {
  960. pcode = "532"
  961. code = "670"
  962. level = "C"
  963. pcodeData := TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"code": pcode}, "", "")
  964. if pcodeData != nil && len(*pcodeData) > 0 {
  965. topname = common.ObjToString((*pcodeData)["name"])
  966. }
  967. pcodeData = TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"code": code}, "", "")
  968. if pcodeData != nil && len(*pcodeData) > 0 {
  969. subname = common.ObjToString((*pcodeData)["name"])
  970. }
  971. } else {
  972. if sourceCode != "" {
  973. codeData := TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"source": sourceCode}, "", "")
  974. if codeData != nil && len(*codeData) > 0 {
  975. pcode = common.ObjToString((*codeData)["pcode"])
  976. code = common.ObjToString((*codeData)["code"])
  977. level = common.ObjToString((*codeData)["clue_level"])
  978. subname = common.ObjToString((*codeData)["name"])
  979. pcodeData := TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"code": pcode}, "", "")
  980. if pcodeData != nil && len(*pcodeData) > 0 {
  981. topname = common.ObjToString((*pcodeData)["name"])
  982. }
  983. }
  984. }
  985. }
  986. return
  987. }
  988. // 获取自动分配的人
  989. func autoDraw(mode, cluename, phone string, isGroup, isCommerce int) (positionId int64, seatNumber, saleName string, saleData []map[string]interface{}, isOk, isFreeze bool, noticePositionId int64) {
  990. isOk = false
  991. isFreeze = false
  992. if TiDb.Count("dwd_f_crm_clue_info", map[string]interface{}{"phone": phone, "is_assign": 1}) == 0 { //线索没销售进入,有销售走分配次数最少的逻辑
  993. if isGroup == 0 && isCommerce == 1 && cluename != "" { //非集团在工商库线索名不为空
  994. //cdata := TiDb.Find("dwd_f_crm_clue_info", map[string]interface{}{"cluename": cluename, "is_assign": 1}, "", "", -1, -1)
  995. cdata := TiDb.SelectBySql(`select position_id,MAX(trail_time) as trail_time,max(last_ring_time) as last_ring_time,seatNumber,count(id) as count from dwd_f_crm_clue_info where cluename=? and is_assign =1 GROUP BY position_id `, cluename)
  996. if cdata != nil && len(*cdata) > 0 { //找到了公司有人在跟进
  997. isOk = true
  998. pdata := TiDb.SelectBySql(`select * from dwd_f_crm_personnel_management where seat_number is not null and seat_number != ""`)
  999. if pdata == nil {
  1000. positionId = 0
  1001. seatNumber = ""
  1002. saleName = ""
  1003. return
  1004. }
  1005. saleData = *pdata
  1006. cdataNew := []map[string]interface{}{}
  1007. if len(*cdata) > 1 {
  1008. //可能有多个人跟进
  1009. personMap := map[int64]bool{}
  1010. upperLimitPersonMap := map[int64]bool{}
  1011. upperLimitCdataNew := []map[string]interface{}{}
  1012. upperLimitCount := 0
  1013. isFull := false
  1014. for _, m := range *cdata {
  1015. positionid := gconv.Int64(m["position_id"])
  1016. for _, v := range *pdata {
  1017. resign := common.IntAll(v["resign"])
  1018. if positionid == common.Int64All(v["position_id"]) {
  1019. if resign == 0 {
  1020. if !FindUpperLimit(gconv.String(positionid), mode, true) {
  1021. personMap[positionid] = true
  1022. m["saleName"] = common.ObjToString(v["name"])
  1023. cdataNew = append(cdataNew, m)
  1024. } else {
  1025. upperLimitCount++
  1026. upperLimitPersonMap[positionid] = true
  1027. m["saleName"] = common.ObjToString(v["name"])
  1028. upperLimitCdataNew = append(upperLimitCdataNew, m)
  1029. }
  1030. }
  1031. }
  1032. }
  1033. if len(cdataNew) == 0 && len(upperLimitCdataNew) > 0 {
  1034. //没有达上限的人数为0 全部都是达上限的
  1035. personMap = upperLimitPersonMap
  1036. cdataNew = upperLimitCdataNew
  1037. isFull = true
  1038. }
  1039. }
  1040. //查询是否都有没有离职
  1041. if len(personMap) != 0 && len(cdataNew) > 0 {
  1042. layout := "2006-01-02 15:04:05"
  1043. //有人没有离职
  1044. data := map[string]interface{}{}
  1045. trailTime := int64(0)
  1046. for _, m := range cdataNew {
  1047. currentTime := int64(0)
  1048. if gconv.String(m["trail_time"]) == "" {
  1049. continue
  1050. }
  1051. t, _ := time.Parse(layout, gconv.String(m["trail_time"]))
  1052. currentTime = t.Unix()
  1053. if currentTime > trailTime {
  1054. trailTime = currentTime
  1055. data = m
  1056. }
  1057. }
  1058. if trailTime == 0 {
  1059. //需要查看通话记录
  1060. lastRingTime := int64(0)
  1061. for _, m := range cdataNew {
  1062. currentTime := int64(0)
  1063. if gconv.String(m["last_ring_time"]) == "" {
  1064. continue
  1065. }
  1066. t, _ := time.Parse(layout, gconv.String(m["last_ring_time"]))
  1067. currentTime = t.Unix()
  1068. if currentTime > lastRingTime {
  1069. lastRingTime = currentTime
  1070. data = m
  1071. }
  1072. }
  1073. if lastRingTime != 0 {
  1074. positionId = common.Int64All(data["position_id"])
  1075. noticePositionId = positionId
  1076. seatNumber = common.ObjToString(data["seatNumber"])
  1077. saleName = common.ObjToString(data["saleName"])
  1078. if isFull {
  1079. isFreeze = true
  1080. noticePositionId = positionId
  1081. positionId = 0
  1082. seatNumber = ""
  1083. saleName = ""
  1084. }
  1085. return
  1086. } else {
  1087. count := 0
  1088. //线索数量判断
  1089. for i, v := range cdataNew {
  1090. if i == 0 {
  1091. count = gconv.Int(v["count"])
  1092. data = v
  1093. } else {
  1094. if count < gconv.Int(v["count"]) {
  1095. count = gconv.Int(v["count"])
  1096. data = v
  1097. }
  1098. }
  1099. }
  1100. positionId = common.Int64All(data["position_id"])
  1101. noticePositionId = positionId
  1102. saleName = common.ObjToString(data["saleName"])
  1103. seatNumber = common.ObjToString(data["seatNumber"])
  1104. if isFull {
  1105. isFreeze = true
  1106. noticePositionId = positionId
  1107. positionId = 0
  1108. seatNumber = ""
  1109. saleName = ""
  1110. }
  1111. return
  1112. }
  1113. } else {
  1114. positionId = common.Int64All(data["position_id"])
  1115. noticePositionId = positionId
  1116. seatNumber = common.ObjToString(data["seatNumber"])
  1117. saleName = common.ObjToString(data["saleName"])
  1118. if isFull {
  1119. isFreeze = true
  1120. noticePositionId = positionId
  1121. positionId = 0
  1122. seatNumber = ""
  1123. saleName = ""
  1124. }
  1125. return
  1126. }
  1127. }
  1128. } else {
  1129. //只有一人跟进
  1130. //(1)该销售人员未离职,则继续分配给该销售人员(保持现状);
  1131. //该销售人员已离职,则随机分配
  1132. positionId = common.Int64All((*cdata)[0]["position_id"])
  1133. noticePositionId = positionId
  1134. seatNumber = common.ObjToString((*cdata)[0]["seatNumber"])
  1135. for _, v := range *pdata {
  1136. resign := common.IntAll(v["resign"])
  1137. if positionId == common.Int64All(v["position_id"]) {
  1138. if resign == 0 {
  1139. if FindUpperLimit(gconv.String(positionId), mode, true) {
  1140. isFreeze = true
  1141. positionId = 0
  1142. seatNumber = ""
  1143. saleName = ""
  1144. break
  1145. } else {
  1146. saleName = common.ObjToString(v["name"])
  1147. return
  1148. }
  1149. }
  1150. }
  1151. }
  1152. }
  1153. }
  1154. }
  1155. }
  1156. query := `select * from dwd_f_crm_personnel_management where assign_type = 1 and`
  1157. if mode == "A" {
  1158. query += ` assign_level like "%A%"`
  1159. } else if mode == "B" {
  1160. query += ` assign_level like "%B%"`
  1161. } else {
  1162. query += ` assign_level like "%C%"`
  1163. }
  1164. data := TiDb.SelectBySql(query)
  1165. if data != nil && len(*data) > 0 {
  1166. saleData = *data
  1167. sql := "select * from dwd_f_crm_clue_autodraw_record where clue_level = ?"
  1168. countData := TiDb.SelectBySql(sql, mode)
  1169. if countData != nil && len(*countData) > 0 {
  1170. for _, v := range *data {
  1171. isOk := false //判断是否有新员工
  1172. for _, vv := range *countData {
  1173. if common.Int64All(v["position_id"]) == common.Int64All(vv["position_id"]) {
  1174. if common.IntAll(v["resign"]) == 0 {
  1175. vv["status"] = 1
  1176. } else {
  1177. vv["status"] = 2
  1178. }
  1179. isOk = true
  1180. }
  1181. }
  1182. if !isOk { //有新员工直接分给新员工
  1183. positionId = common.Int64All(v["position_id"])
  1184. saleName = common.ObjToString(v["name"])
  1185. log.Println("新员工, ", positionId, saleName)
  1186. rData := TiDb.FindOne("dwd_f_crm_clue_autodraw_record", map[string]interface{}{"clue_level": mode}, "", "count desc")
  1187. TiDb.Insert("dwd_f_crm_clue_autodraw_record", map[string]interface{}{
  1188. "position_id": positionId,
  1189. "clue_level": mode,
  1190. "count": common.Int64All((*rData)["count"]),
  1191. })
  1192. break
  1193. }
  1194. }
  1195. if positionId == 0 {
  1196. res := int64(0)
  1197. countres := 0
  1198. for _, v := range *countData {
  1199. if common.IntAll(v["status"]) == 1 {
  1200. if FindUpperLimit(gconv.String(v["position_id"]), mode, false) {
  1201. continue
  1202. }
  1203. if countres == 0 {
  1204. res = common.Int64All(v["count"])
  1205. positionId = common.Int64All(v["position_id"])
  1206. } else {
  1207. if common.Int64All(v["count"]) <= res {
  1208. res = common.Int64All(v["count"])
  1209. positionId = common.Int64All(v["position_id"])
  1210. }
  1211. }
  1212. countres++
  1213. }
  1214. }
  1215. log.Println(444, res)
  1216. }
  1217. } else {
  1218. for _, kv := range *data {
  1219. positionId1 := gconv.String(kv["position_id"])
  1220. if !FindUpperLimit(positionId1, "", false) {
  1221. positionId = common.Int64All(kv["position_id"])
  1222. saleName = common.ObjToString(kv["name"])
  1223. rData := TiDb.FindOne("dwd_f_crm_clue_autodraw_record", map[string]interface{}{"clue_level": mode}, "", "count desc")
  1224. if rData != nil && len(*rData) > 0 {
  1225. TiDb.Insert("dwd_f_crm_clue_autodraw_record", map[string]interface{}{
  1226. "position_id": positionId,
  1227. "clue_level": mode,
  1228. "count": common.Int64All((*rData)["count"]),
  1229. })
  1230. } else {
  1231. TiDb.Insert("dwd_f_crm_clue_autodraw_record", map[string]interface{}{
  1232. "position_id": positionId,
  1233. "clue_level": mode,
  1234. "count": 0,
  1235. })
  1236. }
  1237. break
  1238. }
  1239. }
  1240. }
  1241. for _, v := range *data {
  1242. if positionId == common.Int64All(v["position_id"]) {
  1243. seatNumber = common.ObjToString(v["seat_number"])
  1244. saleName = common.ObjToString(v["name"])
  1245. }
  1246. }
  1247. }
  1248. return
  1249. }
  1250. func getPositionId(phone string) (positionId int64) {
  1251. userData, ok := Mgo.FindOne("user", map[string]interface{}{"s_phone": phone})
  1252. if ok && userData != nil && len(*userData) > 0 {
  1253. userId := common.Int64All((*userData)["base_user_id"])
  1254. positionData := Base.FindOne("base_position", map[string]interface{}{"type": 1, "ent_id": 25917, "user_id": userId}, "", "") //TODO ent_id
  1255. if positionData != nil && len(*positionData) > 0 {
  1256. positionId = common.Int64All((*positionData)["id"])
  1257. }
  1258. }
  1259. return
  1260. }
  1261. func GetCompanyType(companyName string) (int, int) {
  1262. //是否是集团
  1263. isGroup, isCommerce := 0, 0
  1264. if c := TiDb.CountBySql(`select count(1) from group_company_name where company_name=?`, companyName); c > 0 {
  1265. isGroup = 1
  1266. }
  1267. //是否在工商库
  1268. if c := MgoQyxy.Count("qyxy_std", map[string]interface{}{"company_name": companyName, "company_type": map[string]interface{}{"$ne": "个体工商户"}}); c > 0 {
  1269. isCommerce = 1
  1270. }
  1271. return isGroup, isCommerce
  1272. }
  1273. // 查询是否达上限
  1274. func FindUpperLimit(positionId string, level string, isAdd bool) bool {
  1275. if positionId == "" {
  1276. return false
  1277. }
  1278. isFull := TiDb.CountBySql(`select count(1) from dwd_f_crm_clue_info where position_id=? and is_assign=1 and is_transfer != 1 `, positionId) >= db.AllocationCap
  1279. if isFull && isAdd && level != "" {
  1280. TiDb.UpdateOrDeleteBySql(`update dwd_f_crm_clue_autodraw_record set count = count + 1 where position_id = ? and clue_level = ?`, positionId, level)
  1281. }
  1282. return isFull
  1283. }
  1284. func getSeatNumberPositionId(seatNumber string) (positionId int64) {
  1285. saleData := TiDb.FindOne("dwd_f_crm_personnel_management", map[string]interface{}{"seat_number": seatNumber}, "", "")
  1286. if saleData != nil && len(*saleData) > 0 {
  1287. positionId = common.Int64All((*saleData)["position_id"])
  1288. }
  1289. return
  1290. }
  1291. // 重新关注用户处理
  1292. func rebind() {
  1293. log.Println("重新关注用户处理开始")
  1294. //判断节假日
  1295. runOk := getRunOk()
  1296. if !runOk {
  1297. log.Println("不是工作日,任务暂停")
  1298. return
  1299. }
  1300. rebindTimeEnd := cfg.RebindTime
  1301. sql := fmt.Sprintf(`select * from freeClubSign where sub_again_date > "%s" order by sub_again_date asc`, rebindTimeEnd)
  1302. data := BiService.SelectBySql(sql)
  1303. if data != nil && *data != nil && len(*data) > 0 {
  1304. for _, v := range *data {
  1305. rebindTimeEnd = common.ObjToString(v["sub_again_date"])
  1306. registedates, _ := time.Parse(date.Date_Full_Layout, gconv.String(v["register_time"]))
  1307. if time.Now().Unix()-registedates.Unix() > int64(db.RegTimes)*86400 {
  1308. ok1, ok2 := FormatData(v, "rebind")
  1309. if !ok1 {
  1310. log.Println("线索卡点", "allocation", v, rebindTimeEnd)
  1311. } else {
  1312. if !ok2 {
  1313. log.Println("用户分配已达上限", "allocation", v, rebindTimeEnd)
  1314. }
  1315. }
  1316. }
  1317. }
  1318. cfg.RebindTime = rebindTimeEnd
  1319. common.WriteSysConfig(&cfg)
  1320. }
  1321. log.Println("重新关注用户处理结束")
  1322. }
  1323. // 活跃用户处理
  1324. func activeUsers() {
  1325. log.Println("活跃用户处理开始")
  1326. //判断节假日
  1327. runOk := getRunOk()
  1328. if !runOk {
  1329. log.Println("不是工作日,任务暂停")
  1330. return
  1331. }
  1332. //活跃用户查询
  1333. activeTimeEnd := cfg.ActiveTime
  1334. sql := fmt.Sprintf(`select * from freeClubSign where act_again_date > "%s" order by act_again_date asc`, activeTimeEnd)
  1335. data := BiService.SelectBySql(sql)
  1336. if data != nil && *data != nil && len(*data) > 0 {
  1337. for _, v := range *data {
  1338. activeTimeEnd = common.ObjToString(v["act_again_date"])
  1339. ok1, ok2 := FormatData(v, "allocation")
  1340. log.Println(v, "allocation", ok1, ok2)
  1341. if !ok1 {
  1342. log.Println("线索卡点", "allocation", v, activeTimeEnd)
  1343. } else {
  1344. if !ok2 {
  1345. log.Println("用户分配已达上限", "allocation", v, activeTimeEnd)
  1346. }
  1347. }
  1348. }
  1349. cfg.ActiveTime = activeTimeEnd
  1350. common.WriteSysConfig(&cfg)
  1351. }
  1352. log.Println("活跃用户处理结束")
  1353. }