jobutil.go 65 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855
  1. package main
  2. import (
  3. "app.yhyue.com/moapp/jybase/mail"
  4. "app.yhyue.com/moapp/jybase/redis"
  5. "fmt"
  6. "github.com/tealeg/xlsx"
  7. "log"
  8. "math"
  9. "strings"
  10. "time"
  11. "github.com/gogf/gf/v2/util/gconv"
  12. "app.yhyue.com/moapp/jybase/common"
  13. "app.yhyue.com/moapp/jybase/date"
  14. "app.yhyue.com/moapp/jybase/mongodb"
  15. )
  16. // 电销工单生成
  17. func rderAcceptance() {
  18. sql := fmt.Sprintf(`select * from order_acceptance where is_clue=2 and is_delete=1 order by propose_time `)
  19. //sql := fmt.Sprintf(`select * from order_acceptance where is_clue=2 and is_delete=1 and id = 333 order by propose_time `)
  20. data := WorkOrder.SelectBySql(sql)
  21. if data != nil && len(*data) > 0 {
  22. for _, v := range *data {
  23. acceptance_no := gconv.String(v["acceptance_no"])
  24. childrenArr := WorkOrder.Find("order_acceptance_children", map[string]interface{}{
  25. "acceptance_no": acceptance_no,
  26. }, "", "", -1, -1)
  27. if childrenArr != nil && len(*childrenArr) > 0 {
  28. company := ""
  29. phone := ""
  30. demand := ""
  31. name := ""
  32. product := ""
  33. for _, v1 := range *childrenArr {
  34. if gconv.String(v1["field_name"]) == "公司名称" {
  35. company = gconv.String(v1["field_value"])
  36. }
  37. if gconv.String(v1["field_name"]) == "联系方式num" {
  38. phone = gconv.String(v1["field_value"])
  39. }
  40. if gconv.String(v1["field_name"]) == "客户姓名" {
  41. name = gconv.String(v1["field_value"])
  42. }
  43. if gconv.String(v1["field_name"]) == "客户需求" {
  44. demand = gconv.String(v1["field_value"])
  45. }
  46. if gconv.String(v1["field_name"]) == "咨询产品" {
  47. product = gconv.String(v1["field_value"])
  48. }
  49. }
  50. if !WorkDataHandle(company, phone, demand, name, product, v) {
  51. log.Println("工单创建失败")
  52. }
  53. }
  54. }
  55. }
  56. }
  57. func WorkDataHandle(company, phone, demand, name, product string, acceptanceData map[string]interface{}) bool {
  58. uId := ""
  59. query := map[string]interface{}{}
  60. contactsData := TiDb.SelectBySql("select * from dwd_f_userbase_contacts where phone = ? and is_delete = 1", phone)
  61. if contactsData != nil && len(*contactsData) > 0 {
  62. if common.ObjToString((*contactsData)[0]["baseinfo_id"]) != "" {
  63. uId = common.ObjToString((*contactsData)[0]["baseinfo_id"])
  64. query["uid"] = uId
  65. }
  66. }
  67. if uId == "" {
  68. log.Println("用户信息不存在")
  69. return false
  70. }
  71. cluename := company
  72. if cluename == "" {
  73. cluename = phone //没有线索名,手机号代替
  74. }
  75. ok, data, saleData, isNewScore := false, map[string]interface{}{}, []map[string]interface{}{}, false
  76. isGroup, isCommerce := GetCompanyType(cluename, uId)
  77. uCount, _ := TiDb.FindOne("dwd_f_crm_clue_info", map[string]interface{}{"uid": uId}, "", ""), true //查当前线索是否已存在
  78. if uCount != nil && len(*uCount) > 0 {
  79. isUpdate := gconv.Int64((*uCount)["is_artificially_modified"])
  80. if isUpdate == 1 {
  81. cluename = ""
  82. }
  83. clueId := gconv.Int64((*uCount)["id"])
  84. positionId := gconv.Int64((*uCount)["position_id"])
  85. trailstatus := gconv.String((*uCount)["trailstatus"])
  86. IS_TRANSFER := gconv.Int64((*uCount)["IS_TRANSFER"])
  87. if IS_TRANSFER == 1 {
  88. //客成处理
  89. //客成
  90. //生成客成数据
  91. customerMap := TiDb.FindOne("dwd_f_csm_customer_info", map[string]interface{}{
  92. "clue_id": clueId,
  93. }, "position_id,name", "")
  94. if customerMap != nil && len(*customerMap) > 0 {
  95. //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)
  96. 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)
  97. data = map[string]interface{}{
  98. "type": "kc",
  99. "position_id": (*customerMap)["position_id"],
  100. "name": (*customerMap)["name"],
  101. }
  102. } else {
  103. log.Println("查询不到客成数据", clueId, uId)
  104. return false
  105. }
  106. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  107. "clue_id": clueId,
  108. "position_id": (*customerMap)["position_id"],
  109. "change_type": "加入任务车",
  110. "new_value": "咨询客服转客成",
  111. "createtime": time.Now().Format(date.Date_Full_Layout),
  112. "BCPCID": common.GetRandom(32),
  113. "operator_id": -1,
  114. })
  115. } else {
  116. log.Println("工单分配程序:", positionId)
  117. if positionId == 0 {
  118. //线索变更
  119. isNewScore = true
  120. ok, data, saleData = FindPosition(0, "", gconv.String(acceptanceData["creator_time"]))
  121. if !ok {
  122. log.Println(positionId, "用户查询失败")
  123. return false
  124. }
  125. log.Println("按照比例抽取人数:", gconv.Int64(data["position_id"]), gconv.String(data["name"]))
  126. 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)
  127. } else {
  128. ok, data, saleData = FindPosition(positionId, trailstatus, gconv.String(acceptanceData["creator_time"]))
  129. if !ok {
  130. log.Println(positionId, "用户查询失败")
  131. return false
  132. }
  133. if gconv.Int64(data["position_id"]) == positionId {
  134. 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)
  135. } else {
  136. 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)
  137. }
  138. }
  139. }
  140. } else {
  141. //新增线索
  142. ok, data, _ = FindPosition(0, "", gconv.String(acceptanceData["creator_time"]))
  143. if !ok {
  144. return false
  145. }
  146. isNewScore = true
  147. 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)
  148. }
  149. //工单生成
  150. ok1 := AddOrderWork(acceptanceData, data, product, phone, company, isNewScore)
  151. log.Println("工单创建", ok1, gconv.String(acceptanceData["acceptance_no"]))
  152. return true
  153. }
  154. func AddOrderWork(acceptanceData map[string]interface{}, userData map[string]interface{}, product, phone, company string, isNewScore bool) bool {
  155. time.Sleep(time.Second * 1)
  156. nowTime := time.Now().Format(date.Date_Full_Layout)
  157. work_order_no := fmt.Sprintf("GD%s%s", time.Now().Format(date.Date_yyyyMMdd), FindNumber("gd"))
  158. productArr := []string{}
  159. for _, v := range strings.Split(product, ",") {
  160. switch ProductMap[v] {
  161. case "dk":
  162. continue
  163. default:
  164. productArr = append(productArr, v)
  165. }
  166. }
  167. two_type := "dx"
  168. if gconv.String(userData["type"]) == "kc" {
  169. two_type = "kc"
  170. }
  171. personMap := GetPerson(gconv.String(userData["position_id"]))
  172. if personMap == nil || len(personMap) == 0 {
  173. return false
  174. }
  175. orderWorkMap := map[string]interface{}{
  176. "work_order_no": work_order_no,
  177. "acceptance_no": gconv.String(acceptanceData["acceptance_no"]),
  178. "type": strings.Join(productArr, ","),
  179. "status": common.If(gconv.Int64(userData["orderStatus"]) == 0, 2, 1),
  180. "initiator_name": gconv.String(acceptanceData["creator_name"]),
  181. "initiator_position_id": gconv.String(acceptanceData["initiator_position_id"]),
  182. "current_name": common.If(gconv.Int64(userData["orderStatus"]) == 0, nil, userData["name"]),
  183. "current_position_id": common.If(gconv.Int64(userData["orderStatus"]) == 0, nil, userData["position_id"]),
  184. "history_name": common.If(gconv.Int64(userData["orderStatus"]) == 0, userData["name"], nil),
  185. "history_postion_id": common.If(gconv.Int64(userData["orderStatus"]) == 0, userData["position_id"], nil),
  186. "is_delete": 1,
  187. "creator_name": gconv.String(acceptanceData["creator_name"]),
  188. "creator_position_id": gconv.String(acceptanceData["creator_position_id"]),
  189. "creator_time": nowTime,
  190. "two_type": two_type,
  191. "department_no": gconv.String(personMap["deptId"]),
  192. "department_name": gconv.String(personMap["deptName"]),
  193. "update_time": common.If(gconv.Int64(userData["orderStatus"]) == 0, nowTime, nil),
  194. }
  195. ok3 := WorkOrder.Insert("order_work", orderWorkMap)
  196. if ok3 > 0 {
  197. status := 2
  198. if WorkOrder.Count("order_work", map[string]interface{}{
  199. "status": 1,
  200. "acceptance_no": gconv.String(acceptanceData["acceptance_no"]),
  201. }) > 0 {
  202. status = 1
  203. }
  204. WorkOrder.Update("order_acceptance", map[string]interface{}{
  205. "id": acceptanceData["id"],
  206. }, map[string]interface{}{
  207. "is_clue": 3,
  208. "status": status,
  209. "over_time": common.If(status == 1, nil, nowTime),
  210. })
  211. //日志添加
  212. approvalRecordMap := map[string]interface{}{
  213. "work_order_no": work_order_no,
  214. "status": common.If(gconv.Int64(userData["orderStatus"]) == 0, 3, 1),
  215. "new_status": common.If(gconv.Int64(userData["orderStatus"]) == 0, 2, nil),
  216. "handle_name": userData["name"],
  217. "handle_position_id": userData["position_id"],
  218. "handle_dept_id": gconv.String(personMap["deptId"]),
  219. "handle_dept_name": gconv.String(personMap["deptName"]),
  220. "creator_name": gconv.String(acceptanceData["creator_name"]),
  221. "creator_position_id": gconv.String(acceptanceData["initiator_position_id"]),
  222. "is_delete": 1,
  223. "creator_time": nowTime,
  224. "handle_time": common.If(gconv.Int64(userData["orderStatus"]) == 0, nowTime, nil),
  225. "update_name": common.If(gconv.Int64(userData["orderStatus"]) == 0, userData["name"], nil),
  226. "update_position_id": common.If(gconv.Int64(userData["orderStatus"]) == 0, userData["position_id"], nil),
  227. "update_time": common.If(gconv.Int64(userData["orderStatus"]) == 0, nowTime, nil),
  228. }
  229. WorkOrder.Insert("approval_record", approvalRecordMap)
  230. //工单分配记录添加
  231. if isNewScore {
  232. orderWorkAllocationRecord := map[string]interface{}{
  233. "person_name": userData["name"],
  234. "position_id": userData["position_id"],
  235. "dept_name": personMap["deptName"],
  236. "dept_id": personMap["deptId"],
  237. "work_order_no": work_order_no,
  238. "create_time": nowTime,
  239. "company_dept_numb": common.If(gconv.String(personMap["deptName"]) == "销售三部", 3, 1),
  240. "whee_time": cfg.AllocationTime,
  241. }
  242. WorkOrder.Insert("order_work_allocation_record", orderWorkAllocationRecord)
  243. }
  244. WorkMail(personMap,
  245. strings.Join(productArr, ","),
  246. gconv.Int64(common.If(gconv.Int64(userData["orderStatus"]) == 0, 2, 1)),
  247. gconv.String(personMap["name"]),
  248. gconv.String(acceptanceData["creator_name"]),
  249. nowTime,
  250. work_order_no,
  251. phone,
  252. company)
  253. return true
  254. }
  255. return false
  256. }
  257. // 本级以及上级管理员查询
  258. func GetPerson(positionId string) map[string]interface{} {
  259. person := map[string]interface{}{}
  260. positionArrMap := Base.SelectBySql(fmt.Sprintf(`select a.phone,b.id,b.ent_id from
  261. base_user a
  262. INNER JOIN base_position b
  263. on b.id= %s and b.user_id=a.id and b.type=1`,
  264. positionId))
  265. if positionArrMap == nil || len(*positionArrMap) == 0 {
  266. return map[string]interface{}{}
  267. }
  268. phone := gconv.String((*positionArrMap)[0]["phone"])
  269. entId := gconv.String((*positionArrMap)[0]["ent_id"])
  270. entUserArrMap := Mysql.SelectBySql(fmt.Sprintf(`SELECT
  271. a.name as name,a.mail as mail,b.dept_id as deptId,a.phone ,c.name as deptName
  272. FROM
  273. entniche_user a
  274. INNER JOIN entniche_department_user b ON a.ent_id =%s
  275. AND a.phone IN %s
  276. and a.id=b.user_id
  277. inner join entniche_department c on b.dept_id=c.id
  278. `, entId, fmt.Sprintf("(%s)", phone)))
  279. //商机管理员
  280. if entUserArrMap == nil || len(*entUserArrMap) == 0 {
  281. return map[string]interface{}{}
  282. }
  283. deptId := gconv.Int64((*entUserArrMap)[0]["deptId"])
  284. person = map[string]interface{}{
  285. "name": gconv.String((*entUserArrMap)[0]["name"]),
  286. "mail": gconv.String((*entUserArrMap)[0]["mail"]),
  287. "phone": gconv.String((*entUserArrMap)[0]["phone"]),
  288. "deptId": gconv.String((*entUserArrMap)[0]["deptId"]),
  289. "deptName": gconv.String((*entUserArrMap)[0]["deptName"]),
  290. }
  291. //本部门管理员查询
  292. depthMap := Mysql.SelectBySql(`SELECT
  293. c.name as name,c.mail as mail
  294. FROM
  295. entniche_department_user a
  296. INNER JOIN entniche_user_role b ON a.dept_id = ?
  297. AND a.user_id = b.user_id
  298. AND b.role_id !=""
  299. INNER JOIN entniche_user c ON a.user_id = c.id`, deptId)
  300. if depthMap != nil && len(*depthMap) > 0 {
  301. person["deptPersonName"] = gconv.String((*depthMap)[0]["name"])
  302. person["deptPersonMail"] = gconv.String((*depthMap)[0]["mail"])
  303. }
  304. //商机管理员查询
  305. superiorDepthMap := Mysql.SelectBySql(`SELECT
  306. c.*
  307. FROM
  308. entniche_department d
  309. INNER JOIN entniche_department_user a ON d.id = ?
  310. AND d.pid = a.dept_id
  311. INNER JOIN entniche_user_role b ON a.user_id = b.user_id
  312. AND b.role_id !=""
  313. INNER JOIN entniche_user c ON a.user_id = c.id`, deptId)
  314. if superiorDepthMap != nil && len(*superiorDepthMap) > 0 {
  315. person["superiorDepthPersonName"] = gconv.String((*superiorDepthMap)[0]["name"])
  316. person["superiorDepthPersonMail"] = gconv.String((*superiorDepthMap)[0]["mail"])
  317. }
  318. return person
  319. }
  320. // 编号查询
  321. func FindNumber(moudle string) string {
  322. today := time.Now().Format("2006-01-02")
  323. yesterday := time.Now().AddDate(0, 0, -1).Format("2006-01-02")
  324. key := fmt.Sprintf("%s_%s", today, moudle)
  325. yesterdayKey := fmt.Sprintf("%s_%s", yesterday, moudle)
  326. if ok, _ := redis.Exists("newother", yesterdayKey); ok {
  327. //删除之前数据
  328. redis.Del("newother", yesterdayKey)
  329. }
  330. count := redis.Incr("newother", key)
  331. log.Println("编号获取", moudle, fmt.Sprintf("%04d", count))
  332. return fmt.Sprintf("%04d", count)
  333. }
  334. // 人员查询
  335. func GetAllocation(proportion1, proportion3 float64, deptCount1, deptCount3 int64, administrators1, administrators3 map[string]interface{}) map[string]interface{} {
  336. log.Println("分配比例查询", cfg.AllocationTime, cfg.AllocationRatio, proportion1, proportion3, deptCount1, deptCount3)
  337. if deptCount1 == 0 {
  338. return administrators1
  339. }
  340. if deptCount3 == 0 {
  341. return administrators3
  342. }
  343. nowAllocationRatio := math.Round(gconv.Float64(deptCount1 / deptCount3))
  344. log.Println("分配比例查询", proportion1, proportion3, deptCount1, deptCount3, nowAllocationRatio, cfg.AllocationRatio)
  345. if cfg.AllocationRatio == 0 {
  346. //重新计算
  347. cfg.AllocationRatio = math.Round(proportion1 / proportion3)
  348. cfg.AllocationTime = time.Now().Format(date.Date_Full_Layout)
  349. common.WriteSysConfig(&cfg)
  350. log.Println("新增计算比例", cfg.AllocationRatio)
  351. return administrators1
  352. } else {
  353. if nowAllocationRatio == cfg.AllocationRatio {
  354. //重新计算
  355. cfg.AllocationRatio = math.Round(proportion1 / proportion3)
  356. cfg.AllocationTime = time.Now().Format(date.Date_Full_Layout)
  357. common.WriteSysConfig(&cfg)
  358. return administrators1
  359. }
  360. }
  361. if nowAllocationRatio > cfg.AllocationRatio {
  362. return administrators3
  363. } else {
  364. return administrators1
  365. }
  366. //达到比例也重新计算
  367. }
  368. func FindPosition(positionId int64, trailstatus, creatorTime string) (bool, map[string]interface{}, []map[string]interface{}) {
  369. allData := []map[string]interface{}{}
  370. //查询两个部门高级管理员
  371. //查询两个部门所有人员标识
  372. //电销三部
  373. userData1 := TiDb.SelectBySql(`SELECT
  374. a.position_id,
  375. a.name,
  376. b.seat_number,
  377. b.role_id,
  378. a.bi_pcode,
  379. a.dept_name
  380. FROM
  381. dwd_d_crm_department_level_succbi a
  382. INNER JOIN dwd_f_crm_personnel_management b ON a.resign = 0 and b.resign = 0
  383. AND a.dept_name LIKE "销售一部%"
  384. AND a.position_id = b.position_id`)
  385. userData3 := TiDb.SelectBySql(`SELECT
  386. a.position_id,
  387. a.name,
  388. b.seat_number,
  389. b.role_id,
  390. a.bi_pcode,
  391. a.dept_name
  392. FROM
  393. dwd_d_crm_department_level_succbi a
  394. INNER JOIN dwd_f_crm_personnel_management b ON a.resign = 0 and b.resign = 0
  395. AND a.resign = 0
  396. AND a.dept_name LIKE "%销售三部"
  397. AND a.position_id = b.position_id`)
  398. if userData3 == nil || len(*userData3) == 0 || userData1 == nil || len(*userData1) == 0 {
  399. return false, map[string]interface{}{}, allData
  400. }
  401. //一部管理员信息
  402. administrators1 := map[string]interface{}{}
  403. //三部管理员信息
  404. administrators3 := map[string]interface{}{}
  405. //返回当前人信息
  406. administrators := map[string]interface{}{}
  407. //电销一部
  408. deptNameMap1 := map[string]interface{}{}
  409. deptNameMap3 := map[string]interface{}{}
  410. proportion1 := float64(0)
  411. proportion3 := float64(0)
  412. for _, v := range *userData3 {
  413. v["type"] = 3
  414. id := gconv.Int64(v["position_id"])
  415. roleId := gconv.Int64(v["role_id"])
  416. if id == positionId {
  417. administrators = v
  418. }
  419. if roleId == 8 {
  420. v["orderStatus"] = 2
  421. administrators3 = v
  422. } else if roleId == 3 {
  423. proportion3 += 0.5
  424. } else {
  425. proportion3 += 1
  426. }
  427. deptNameMap3[gconv.String(v["bi_pcode"])] = true
  428. allData = append(allData, v)
  429. }
  430. for _, v := range *userData1 {
  431. v["type"] = 1
  432. id := gconv.Int64(v["position_id"])
  433. roleId := gconv.Int64(v["role_id"])
  434. if id == positionId {
  435. administrators = v
  436. }
  437. if roleId == 8 {
  438. v["orderStatus"] = 2
  439. administrators1 = v
  440. } else if roleId == 3 {
  441. proportion1 += 0.5
  442. } else {
  443. proportion1 += 1
  444. }
  445. deptNameMap1[gconv.String(v["bi_pcode"])] = true
  446. allData = append(allData, v)
  447. }
  448. if positionId != 0 {
  449. if administrators == nil || len(administrators) == 0 {
  450. return false, map[string]interface{}{}, allData
  451. }
  452. positiontype := gconv.Int64(administrators["type"])
  453. if trailstatus == "01" {
  454. switch positiontype {
  455. case 1:
  456. //找他上级
  457. administrators = administrators1
  458. case 3:
  459. //找他上级
  460. administrators = administrators3
  461. }
  462. return true, administrators, allData
  463. } else {
  464. return true, administrators, allData
  465. }
  466. }
  467. //按照比例分配选择一部还是三部
  468. //一部查询
  469. deptCount1 := CalculateProportion(1)
  470. //三部查询
  471. deptCount3 := CalculateProportion(3)
  472. return true, GetAllocation(proportion1, proportion3, deptCount1, deptCount3, administrators1, administrators3), allData
  473. }
  474. func CalculateProportion(deptNumb int64) int64 {
  475. data := WorkOrder.SelectBySql(`SELECT
  476. sum(1) as count
  477. FROM
  478. order_work_allocation_record where create_time >? and company_dept_numb=? `, cfg.AllocationTime, deptNumb)
  479. count := int64(0)
  480. if data != nil && len(*data) > 0 {
  481. count = gconv.Int64((*data)[0]["count"])
  482. }
  483. return count
  484. }
  485. // 未支付订单 30分钟一次
  486. func orders() {
  487. //一个小时未支付进入线索 A
  488. log.Println("未支付订单定时任务开始")
  489. lastOrderId := cfg.LastOrderId
  490. selectTimeStart := time.Unix(time.Now().Unix()-7200, 0).Format(date.Date_Full_Layout)
  491. selectTimeEnd := time.Unix(time.Now().Unix()-3600, 0).Format(date.Date_Full_Layout)
  492. product_type_str1 := `"大会员","VIP订阅","数据流量包","历史数据"`
  493. DataSql := fmt.Sprintf(`select a.*,b.product_type as productType ,b.service_starttime,b.service_endtime,b.filter AS productFilter from dataexport_order a
  494. INNER JOIN jy_order_detail b on a.order_code=b.order_code
  495. and a.create_time<="%s" and a.create_time>="%s" and b.product_type in (%s)
  496. and a.order_status = 0 and a.is_backstage_order = 0 and a.id> %s order by b.id asc`,
  497. selectTimeEnd, selectTimeStart, product_type_str1, gconv.String(lastOrderId))
  498. data, _ := getOrderData(DataSql)
  499. if data != nil && data != nil && len(data) > 0 {
  500. for _, v := range data {
  501. ok1, ok2, _ := FormatData(v, "orders")
  502. if !ok1 {
  503. common.WriteSysConfig(&cfg)
  504. log.Println("线索卡点", "orders", v, selectTimeEnd, selectTimeStart)
  505. } else {
  506. if !ok2 {
  507. log.Println("用户分配已达上限", "orders", v, selectTimeEnd, selectTimeStart)
  508. common.WriteSysConfig(&cfg)
  509. }
  510. }
  511. cfg.LastOrderId = common.IntAll(v["id"])
  512. }
  513. }
  514. common.WriteSysConfig(&cfg)
  515. log.Println("未支付订单定时任务结束")
  516. }
  517. func readClue() {
  518. log.Println("读表进线索定时任务开始")
  519. lastReadClueTime := cfg.LastReadClueTime
  520. sql := fmt.Sprintf(`select * from clue_info where updatetime > "%s" order by updatetime asc`, fmt.Sprint(lastReadClueTime))
  521. data := TiDb.SelectBySql(sql)
  522. if data != nil && *data != nil && len(*data) > 0 {
  523. for _, v := range *data {
  524. ok1, ok2, _ := FormatData(v, "readClue")
  525. if !ok1 {
  526. common.WriteSysConfig(&cfg)
  527. log.Println("线索卡点", "readClue", v, lastReadClueTime)
  528. } else {
  529. if !ok2 {
  530. log.Println("用户分配已达上限", "readClue", v, lastReadClueTime)
  531. common.WriteSysConfig(&cfg)
  532. }
  533. }
  534. cfg.LastReadClueTime = common.ObjToString(v["updatetime"])
  535. }
  536. }
  537. common.WriteSysConfig(&cfg)
  538. log.Println("读表进线索定时任务结束")
  539. }
  540. // 新注册用户 5分钟一次
  541. func users() {
  542. //判断节假日
  543. runOk := getRunOk()
  544. if !runOk {
  545. log.Println("不是工作日,任务暂停")
  546. return
  547. }
  548. //新用户注册后5分钟内进入线索 C
  549. log.Println("新注册用户定时任务开始", cfg.LastUserId)
  550. selectTimeEnd := cfg.LastUserId
  551. sql := fmt.Sprintf(`select * from dwd_f_userbase_baseinfo where createtime > "%s" and (s_platform != 'xcx' or s_sourceid='jyzbw' or s_platform is NULL) and source = "0101" and status != 2 order by createtime asc`, selectTimeEnd)
  552. //sql := fmt.Sprintf(`select * from dwd_f_userbase_baseinfo where id= 12617743`)
  553. data := TiDb.SelectBySql(sql)
  554. if data != nil && *data != nil && len(*data) > 0 {
  555. for k, v := range *data {
  556. //判断用户是否有小程序切使用过剑鱼其他产品
  557. createtime := common.ObjToString(v["createtime"])
  558. changeCode := GetUserChannel(gconv.String(v["userid"]))
  559. if changeCode != "" {
  560. TiDb.Update("dwd_f_userbase_baseinfo", map[string]interface{}{
  561. "userid": gconv.String(v["userid"]),
  562. }, map[string]interface{}{
  563. "belong_to": changeCode,
  564. })
  565. }
  566. ok1, ok2, _ := FormatData(v, "users")
  567. if !ok1 {
  568. log.Println("线索卡点", "users", v, selectTimeEnd)
  569. } else {
  570. if !ok2 {
  571. log.Println("用户分配已达上限", "users", v, selectTimeEnd)
  572. }
  573. }
  574. if k == len(*data)-1 {
  575. cfg.LastUserId = createtime
  576. }
  577. }
  578. }
  579. common.WriteSysConfig(&cfg)
  580. log.Println("新注册用户定时任务结束", cfg.LastUserId)
  581. log.Println("小程序新注册用户定时任务结束", cfg.LastXcxUserId)
  582. selectXcxTimeEnd := cfg.LastXcxUserId
  583. xcxSql := fmt.Sprintf(`SELECT DISTINCT
  584. aa.mgo_id as userId,
  585. cc.code as industry ,
  586. aa.phone,
  587. IF
  588. ( aa.phone_time IS NULL, aa.create_time, aa.phone_time ) as time
  589. FROM
  590. debris_product.miniprogram_user aa
  591. INNER JOIN debris_product.miniprogram bb ON (
  592. aa.phone <> ''
  593. AND
  594. IF
  595. ( aa.phone_time IS NULL, aa.create_time, aa.phone_time ) > '%s'
  596. AND aa.miniprogram_code = bb.CODE
  597. )
  598. INNER JOIN debris_product.industry cc ON ( bb.industry_code = cc.CODE )
  599. WHERE
  600. NOT EXISTS (
  601. SELECT
  602. 1
  603. FROM
  604. debris_product.miniprogram_user a
  605. INNER JOIN debris_product.miniprogram b ON (
  606. aa.unionid = a.unionid
  607. AND aa.miniprogram_code = a.miniprogram_code
  608. AND aa.id != a.id
  609. AND
  610. IF
  611. ( a.phone_time IS NULL, a.create_time, a.phone_time ) <= '%s'
  612. AND a.miniprogram_code = b.CODE
  613. )
  614. INNER JOIN debris_product.miniprogram_user c ON ( a.unionid = c.unionid AND b.CODE = c.miniprogram_code ))
  615. ORDER BY time
  616. `, selectXcxTimeEnd, selectXcxTimeEnd)
  617. xcxData := debrisProductMysql.SelectBySql(xcxSql)
  618. log.Println("11122", selectXcxTimeEnd, xcxData)
  619. if xcxData != nil && *xcxData != nil && len(*xcxData) > 0 {
  620. afList := []map[string]interface{}{}
  621. for k, v := range *xcxData {
  622. //判断用户是否有小程序切使用过剑鱼其他产品
  623. //判断uid
  624. uId := ""
  625. changeCode := GetUserChannel(gconv.String(v["userId"]))
  626. if changeCode != "" {
  627. TiDb.Update("dwd_f_userbase_baseinfo", map[string]interface{}{
  628. "userid": gconv.String(v["userId"]),
  629. }, map[string]interface{}{
  630. "belong_to": changeCode,
  631. })
  632. }
  633. for i := 0; i < 10; i++ {
  634. phone := common.ObjToString(v["phone"])
  635. contactsData := TiDb.SelectBySql("select * from dwd_f_userbase_contacts where phone = ? and is_delete = 1", phone)
  636. if contactsData != nil && len(*contactsData) > 0 {
  637. if common.ObjToString((*contactsData)[0]["baseinfo_id"]) != "" {
  638. uId = common.ObjToString((*contactsData)[0]["baseinfo_id"])
  639. }
  640. }
  641. if uId == "" {
  642. time.Sleep(1 * time.Minute)
  643. } else {
  644. break
  645. }
  646. }
  647. updatetime := common.ObjToString(v["time"])
  648. if uId == "" {
  649. cfg.LastXcxUserId = updatetime
  650. continue
  651. }
  652. ok1, ok2, _ := FormatData(v, "xcxusers")
  653. /*if !ok3 {
  654. //首次使用"安防"小程序新注册用户
  655. afList = append(afList, v)
  656. cfg.LastXcxUserId = updatetime
  657. continue
  658. }*/
  659. if !ok1 {
  660. common.WriteSysConfig(&cfg)
  661. log.Println("小程序用户分配线索卡点", "xcxusers", v, selectXcxTimeEnd)
  662. } else {
  663. if !ok2 {
  664. log.Println("小程序用户分配已达上限", "xcxusers", v, selectXcxTimeEnd)
  665. common.WriteSysConfig(&cfg)
  666. }
  667. }
  668. if k == len(*xcxData)-1 {
  669. cfg.LastXcxUserId = updatetime
  670. }
  671. }
  672. if len(afList) > 0 {
  673. //发邮件给张文福
  674. AFEmail(afList)
  675. }
  676. }
  677. common.WriteSysConfig(&cfg)
  678. log.Println("小程序新注册用户定时任务结束", cfg.LastXcxUserId)
  679. }
  680. // 留资 5分钟一次
  681. func saleLeads() {
  682. //判断节假日
  683. runOk := getRunOk()
  684. if !runOk {
  685. log.Println("不是工作日,任务暂停")
  686. return
  687. }
  688. //留资后5分钟内进入线索
  689. //分为免费留资和付费留资 付费B 免费C
  690. log.Println("用户留资定时任务开始")
  691. session := Mgo.GetMgoConn()
  692. lastId := cfg.LastId
  693. defer func() {
  694. Mgo.DestoryMongoConn(session)
  695. }()
  696. query := map[string]interface{}{}
  697. if lastId != "" {
  698. query["_id"] = map[string]interface{}{"$gt": mongodb.StringTOBsonId(lastId)}
  699. }
  700. log.Println("query :", query)
  701. iter := session.DB(db.Mgo.DbName).C("saleLeads").Find(&query).Sort("_id").Iter()
  702. thisData := map[string]interface{}{}
  703. filterArr := []string{"-pc", "-app", "-wx", "-h5"}
  704. sourceMap := map[string]string{}
  705. saleLeadsConfig := TiDb.Find("saleLeads_config", map[string]interface{}{
  706. "status": 0,
  707. }, "groupName", "", -1, -1)
  708. if saleLeadsConfig == nil || len(*saleLeadsConfig) == 0 {
  709. log.Println("线索卡点", "缺少留资分类名称", "saleLeads", thisData, lastId)
  710. return
  711. }
  712. sourceArr := []string{}
  713. for _, v := range *saleLeadsConfig {
  714. sourceArr = append(sourceArr, fmt.Sprintf(`department LIKE '%%%s%%'`, gconv.String(v["groupName"])))
  715. }
  716. sql := fmt.Sprintf(`SELECT source,name FROM d_saleleads_code WHERE ( %s) AND is_delete = 1`, strings.Join(sourceArr, " or "))
  717. saleSource := TiDb.SelectBySql(sql)
  718. if saleSource != nil && len(*saleSource) > 0 {
  719. for _, v := range *saleSource {
  720. source := common.ObjToString(v["source"])
  721. name := common.ObjToString(v["name"])
  722. for _, s := range filterArr {
  723. name = strings.ReplaceAll(name, s, "")
  724. }
  725. sourceMap[source] = name
  726. }
  727. }
  728. for {
  729. if !iter.Next(&thisData) {
  730. break
  731. }
  732. sourceCode := common.ObjToString(thisData["source"])
  733. if sourceCode == "" {
  734. log.Println("留资没有source", thisData)
  735. continue
  736. }
  737. //
  738. if sourceMap[sourceCode] != "" {
  739. continue
  740. }
  741. ok1, ok2, _ := FormatData(thisData, "saleLeads")
  742. if !ok1 {
  743. log.Println("线索卡点", "saleLeads", thisData, lastId)
  744. } else {
  745. if !ok2 {
  746. log.Println("用户分配已达上限", "saleLeads", thisData, lastId)
  747. }
  748. }
  749. cfg.LastId = mongodb.BsonIdToSId(thisData["_id"])
  750. }
  751. common.WriteSysConfig(&cfg)
  752. log.Println("用户留资定时任务结束")
  753. }
  754. func userbase() {
  755. log.Println("userbase定时任务开始")
  756. timeUnix := time.Now().Unix()
  757. selectTimeStart := cfg.LastUserBindingTime
  758. selectTimeEnd := time.Unix(timeUnix, 0).Format("2006-01-02 15:04:05")
  759. sql := fmt.Sprintf(`SELECT
  760. a.phone,b.uid,a.baseinfo_id,b.l_registedate,a.createtime,b.id,b.userid,b.rsource
  761. FROM
  762. dwd_f_userbase_contacts a
  763. INNER JOIN dwd_f_userbase_baseinfo b ON
  764. b.status= 1
  765. and (b.s_platform != 'xcx' or b.s_sourceid='jyzbw' or b.s_platform is NULL)
  766. AND a.phone = b.phone and a.baseinfo_id= b.uid and b.source ="0101"
  767. and a.phone is not NULL
  768. and a.createtime >"%s"
  769. and a.is_delete=1
  770. ORDER BY a.createtime `, selectTimeStart)
  771. data := TiDb.SelectBySql(sql)
  772. if data != nil && *data != nil && len(*data) > 0 {
  773. for _, v := range *data {
  774. phone := common.ObjToString(v["phone"])
  775. uId := common.ObjToString(v["uid"])
  776. userId := common.ObjToString(v["userid"])
  777. changeCode := GetUserChannel(userId)
  778. if changeCode != "" {
  779. TiDb.Update("", map[string]interface{}{
  780. "userid": userId,
  781. }, map[string]interface{}{
  782. "belong_to": changeCode,
  783. })
  784. }
  785. registedate := common.ObjToString(v["l_registedate"])
  786. name := common.ObjToString(v["name"])
  787. nowTime := time.Now().Format(date.Date_Full_Layout)
  788. layout := "2006-01-02 15:04:05"
  789. createtime := gconv.String(v["createtime"])
  790. cfg.LastUserBindingTime = createtime
  791. createtimeInt64, _ := time.Parse(layout, createtime)
  792. registedateInt64, _ := time.Parse(layout, registedate)
  793. count := TiDb.CountBySql("select count(1) as count from dwd_f_crm_clue_info where uid = ?", uId)
  794. if createtimeInt64.Unix()-registedateInt64.Unix() < int64(db.RegTimes)*86400 {
  795. if count == 0 {
  796. //注册少于7天、走新增
  797. data := TiDb.FindOne("dwd_f_userbase_baseinfo", map[string]interface{}{
  798. "id": gconv.Int64(v["id"]),
  799. }, "", "")
  800. if data != nil && len(*data) > 0 {
  801. ok1, ok2, _ := FormatData(v, "users")
  802. if !ok1 {
  803. log.Println("线索卡点", "userbase uid", v, uId)
  804. } else {
  805. if !ok2 {
  806. log.Println("用户分配已达上限", "userbase uid", v, uId)
  807. }
  808. }
  809. }
  810. }
  811. continue
  812. }
  813. registedates, _ := time.Parse(date.Date_Full_Layout, registedate)
  814. log.Println("userbase uid 线索数量 ", count)
  815. log.Println("userbase uid 注册时间 ", registedates)
  816. if count == 0 {
  817. clueId := int64(0)
  818. sql := fmt.Sprintf(`select * from freeClubSign where mogUserId="%s" and sub_again_date > "%s" `, userId, selectTimeEnd)
  819. data := BiService.SelectBySql(sql)
  820. if len(*data) > 0 && userId != "" {
  821. clueId = TiDb.Insert("dwd_f_crm_clue_info", map[string]interface{}{
  822. "userid": userId,
  823. "uid": uId,
  824. "is_assign": 0,
  825. "comeintime": nowTime,
  826. "createtime": nowTime,
  827. "updatetime": nowTime,
  828. "cluename": phone,
  829. "top_cluetype": "532",
  830. "sub_cluetype": "670",
  831. "trailstatus": "01",
  832. "name": name,
  833. "phone": phone,
  834. "comeintime_open": nowTime,
  835. "comeinsource_open": 1,
  836. "FREEZE_TIME": nowTime,
  837. })
  838. } else {
  839. clueId = TiDb.Insert("dwd_f_crm_clue_info", map[string]interface{}{
  840. "userid": userId,
  841. "uid": uId,
  842. "is_assign": 0,
  843. "comeintime": nowTime,
  844. "createtime": nowTime,
  845. "updatetime": nowTime,
  846. "cluename": phone,
  847. "top_cluetype": "532",
  848. "sub_cluetype": "475",
  849. "trailstatus": "01",
  850. "name": name,
  851. "phone": phone,
  852. "comeintime_open": nowTime,
  853. "comeinsource_open": 1,
  854. "FREEZE_TIME": nowTime,
  855. })
  856. }
  857. if clueId > 0 {
  858. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  859. "clue_id": clueId,
  860. "position_id": -1,
  861. "change_type": "创建线索",
  862. "new_value": "系统自动创建",
  863. "createtime": nowTime,
  864. "BCPCID": common.GetRandom(32),
  865. "operator_id": -1,
  866. })
  867. }
  868. }
  869. }
  870. }
  871. common.WriteSysConfig(&cfg)
  872. log.Println("userbase定时任务结束")
  873. }
  874. func getRunOk() bool {
  875. currentTime, runOk := time.Now(), false
  876. if currentTime.Weekday() == time.Sunday {
  877. isok := false
  878. for k, v := range DateMap {
  879. if currentTime.Format(date.Date_Short_Layout) == k && v == 2 {
  880. isok = true
  881. }
  882. }
  883. if isok {
  884. runOk = true
  885. }
  886. } else {
  887. isok := true
  888. for k, v := range DateMap {
  889. if currentTime.Format(date.Date_Short_Layout) == k && v == 1 {
  890. isok = false
  891. }
  892. }
  893. if isok {
  894. runOk = true
  895. }
  896. }
  897. return runOk
  898. }
  899. func getAreaCode(userId string) (code string) {
  900. followData := Base.Find("follow_project_monitor", map[string]interface{}{"s_userid": userId}, "", "", -1, -1)
  901. sidArr := []string{}
  902. if followData != nil && len(*followData) > 0 {
  903. for _, v := range *followData {
  904. infoId := common.ObjToString(v["s_id"])
  905. sidArr = append(sidArr, infoId)
  906. }
  907. }
  908. if len(sidArr) > 0 {
  909. query := `{"query": {"bool": {"must": [{"terms": {"_id": ["%s"]}}],"must_not": [],"should": []}}}`
  910. query = fmt.Sprintf(query, strings.Join(sidArr, `","`))
  911. biddingData := Es.Get("bidding", "bidding", query)
  912. if biddingData != nil && len(*biddingData) > 0 {
  913. codeMap := map[string]string{}
  914. codeArr := []string{}
  915. for _, v := range *biddingData {
  916. area := common.ObjToString(v["area"])
  917. address := common.ObjToString(v["city"])
  918. if address == "" {
  919. address = area
  920. }
  921. codeMap[address] = AreaCode[address]
  922. }
  923. if len(codeMap) > 0 {
  924. for _, v := range codeMap {
  925. codeArr = append(codeArr, v)
  926. }
  927. }
  928. if len(codeArr) > 0 {
  929. code = strings.Join(codeArr, ",")
  930. }
  931. }
  932. }
  933. log.Println("code ", code)
  934. return
  935. }
  936. func getClueType(item string, data map[string]interface{}, sourceCode string, sourceId int64) (pcode, code, level, topname, subname string) {
  937. if item == "orders" {
  938. productType := common.ObjToString(data["product_type"])
  939. pcode = "1"
  940. level = "A"
  941. topname = "提交订单未支付"
  942. if productType == "VIP订阅" {
  943. code = "6"
  944. subname = "超级订阅"
  945. } else if productType == "大会员" {
  946. code = "7"
  947. subname = "大会员"
  948. } else if productType == "数据流量包" {
  949. code = "8"
  950. subname = "数据流量包"
  951. } else if productType == "历史数据" {
  952. code = "9"
  953. subname = "数据自助导出"
  954. }
  955. } else if item == "users" && sourceCode != "bidCreditReportPreview" && sourceCode != "bidCreditReportFile" {
  956. pcode = "4"
  957. code = "154"
  958. level = "C"
  959. topname = "新增注册"
  960. subname = "新增注册用户"
  961. } else if item == "users" && (sourceCode == "bidCreditReportPreview" || sourceCode == "bidCreditReportFile") {
  962. pcode = "4"
  963. code = "767"
  964. level = "B"
  965. topname = "新增注册"
  966. subname = "信用报告引流用户"
  967. } else if item == "message" {
  968. pcode = "532"
  969. code = "477"
  970. level = "B"
  971. topname = "其他"
  972. subname = "机器人客服主动咨询"
  973. } else if item == "readClue" {
  974. level = "A"
  975. topname = "超级订阅临期用户"
  976. pcode = "614"
  977. if sourceId == 1 {
  978. code = "615"
  979. subname = "60天后到期"
  980. } else if sourceId == 2 {
  981. code = "616"
  982. subname = "45天后到期"
  983. } else if sourceId == 3 {
  984. code = "617"
  985. subname = "15天后到期"
  986. } else {
  987. code = "618"
  988. subname = "7天后到期"
  989. }
  990. } else if item == "allocation" {
  991. pcode = "532"
  992. code = "671"
  993. level = "D"
  994. pcodeData := TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"code": pcode}, "", "")
  995. if pcodeData != nil && len(*pcodeData) > 0 {
  996. topname = common.ObjToString((*pcodeData)["name"])
  997. }
  998. pcodeData = TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"code": code}, "", "")
  999. if pcodeData != nil && len(*pcodeData) > 0 {
  1000. subname = common.ObjToString((*pcodeData)["name"])
  1001. }
  1002. } else if item == "rebind" {
  1003. pcode = "532"
  1004. code = "670"
  1005. level = "D"
  1006. pcodeData := TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"code": pcode}, "", "")
  1007. if pcodeData != nil && len(*pcodeData) > 0 {
  1008. topname = common.ObjToString((*pcodeData)["name"])
  1009. }
  1010. pcodeData = TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"code": code}, "", "")
  1011. if pcodeData != nil && len(*pcodeData) > 0 {
  1012. subname = common.ObjToString((*pcodeData)["name"])
  1013. }
  1014. } else if item == "invite" {
  1015. codeData := TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"code": sourceCode}, "", "")
  1016. if codeData != nil && len(*codeData) > 0 {
  1017. pcode = common.ObjToString((*codeData)["pcode"])
  1018. code = common.ObjToString((*codeData)["code"])
  1019. level = common.ObjToString((*codeData)["clue_level"])
  1020. subname = common.ObjToString((*codeData)["name"])
  1021. pcodeData := TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"code": pcode}, "", "")
  1022. if pcodeData != nil && len(*pcodeData) > 0 {
  1023. topname = common.ObjToString((*pcodeData)["name"])
  1024. }
  1025. }
  1026. } else if item == "tag" {
  1027. pcodeData := TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"name": gconv.String(data["topName"]), "level": 1}, "", "")
  1028. if pcodeData != nil && len(*pcodeData) > 0 {
  1029. pcode = common.ObjToString((*pcodeData)["code"])
  1030. topname = common.ObjToString((*pcodeData)["name"])
  1031. codeData := TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"name": gconv.String(data["subName"]), "level": 2}, "", "")
  1032. if codeData != nil && len(*codeData) > 0 {
  1033. subname = common.ObjToString((*codeData)["name"])
  1034. level = common.ObjToString((*codeData)["clue_level"])
  1035. code = common.ObjToString((*codeData)["code"])
  1036. }
  1037. }
  1038. } else {
  1039. if sourceCode != "" {
  1040. codeData := TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"source": sourceCode}, "", "")
  1041. if codeData != nil && len(*codeData) > 0 {
  1042. pcode = common.ObjToString((*codeData)["pcode"])
  1043. code = common.ObjToString((*codeData)["code"])
  1044. level = common.ObjToString((*codeData)["clue_level"])
  1045. subname = common.ObjToString((*codeData)["name"])
  1046. pcodeData := TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"code": pcode}, "", "")
  1047. if pcodeData != nil && len(*pcodeData) > 0 {
  1048. topname = common.ObjToString((*pcodeData)["name"])
  1049. }
  1050. }
  1051. }
  1052. }
  1053. return
  1054. }
  1055. // 获取自动分配的人
  1056. func autoDraw(mode, cluename, phone string, isGroup, isCommerce int) (positionId int64, seatNumber, saleName string, saleData []map[string]interface{}, isOk, isFreeze bool, noticePositionId int64) {
  1057. isOk = false
  1058. isFreeze = false
  1059. if TiDb.Count("dwd_f_crm_clue_info", map[string]interface{}{"phone": phone, "is_assign": 1}) == 0 { //线索没销售进入,有销售走分配次数最少的逻辑
  1060. if isGroup == 0 && isCommerce == 1 && cluename != "" { //非集团在工商库线索名不为空
  1061. //cdata := TiDb.Find("dwd_f_crm_clue_info", map[string]interface{}{"cluename": cluename, "is_assign": 1}, "", "", -1, -1)
  1062. 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)
  1063. if cdata != nil && len(*cdata) > 0 { //找到了公司有人在跟进
  1064. isOk = true
  1065. pdata := TiDb.SelectBySql(`select * from dwd_f_crm_personnel_management where seat_number is not null and seat_number != ""`)
  1066. if pdata == nil {
  1067. positionId = 0
  1068. seatNumber = ""
  1069. saleName = ""
  1070. return
  1071. }
  1072. saleData = *pdata
  1073. cdataNew := []map[string]interface{}{}
  1074. if len(*cdata) > 1 {
  1075. //可能有多个人跟进
  1076. personMap := map[int64]bool{}
  1077. upperLimitPersonMap := map[int64]bool{}
  1078. upperLimitCdataNew := []map[string]interface{}{}
  1079. upperLimitCount := 0
  1080. isFull := false
  1081. for _, m := range *cdata {
  1082. positionid1 := gconv.Int64(m["position_id"])
  1083. for _, v := range *pdata {
  1084. resign := common.IntAll(v["resign"])
  1085. assign_type := common.IntAll(v["assign_type"])
  1086. role_id := common.IntAll(v["role_id"])
  1087. if positionid1 == common.Int64All(v["position_id"]) {
  1088. if resign == 0 && (assign_type == 1 || role_id == 8) {
  1089. if !FindUpperLimit(gconv.String(positionid1), mode, true) {
  1090. personMap[positionid1] = true
  1091. m["saleName"] = common.ObjToString(v["name"])
  1092. cdataNew = append(cdataNew, m)
  1093. } else {
  1094. upperLimitCount++
  1095. upperLimitPersonMap[positionid1] = true
  1096. m["saleName"] = common.ObjToString(v["name"])
  1097. upperLimitCdataNew = append(upperLimitCdataNew, m)
  1098. }
  1099. }
  1100. }
  1101. }
  1102. }
  1103. if len(cdataNew) == 0 && len(upperLimitCdataNew) > 0 {
  1104. //没有达上限的人数为0 全部都是达上限的
  1105. personMap = upperLimitPersonMap
  1106. cdataNew = upperLimitCdataNew
  1107. isFull = true
  1108. }
  1109. //查询是否都有没有离职
  1110. if len(personMap) != 0 && len(cdataNew) > 0 {
  1111. layout := "2006-01-02 15:04:05"
  1112. //有人没有离职
  1113. data := map[string]interface{}{}
  1114. trailTime := int64(0)
  1115. for _, m := range cdataNew {
  1116. currentTime := int64(0)
  1117. if gconv.String(m["trail_time"]) == "" {
  1118. continue
  1119. }
  1120. t, _ := time.Parse(layout, gconv.String(m["trail_time"]))
  1121. currentTime = t.Unix()
  1122. if currentTime > trailTime {
  1123. trailTime = currentTime
  1124. data = m
  1125. }
  1126. }
  1127. if trailTime == 0 {
  1128. //需要查看通话记录
  1129. lastRingTime := int64(0)
  1130. for _, m := range cdataNew {
  1131. currentTime := int64(0)
  1132. if gconv.String(m["last_ring_time"]) == "" {
  1133. continue
  1134. }
  1135. t, _ := time.Parse(layout, gconv.String(m["last_ring_time"]))
  1136. currentTime = t.Unix()
  1137. if currentTime > lastRingTime {
  1138. lastRingTime = currentTime
  1139. data = m
  1140. }
  1141. }
  1142. if lastRingTime != 0 {
  1143. positionId = common.Int64All(data["position_id"])
  1144. noticePositionId = positionId
  1145. seatNumber = common.ObjToString(data["seatNumber"])
  1146. saleName = common.ObjToString(data["saleName"])
  1147. if isFull {
  1148. isFreeze = true
  1149. noticePositionId = positionId
  1150. positionId = 0
  1151. seatNumber = ""
  1152. saleName = ""
  1153. }
  1154. return
  1155. } else {
  1156. count := 0
  1157. //线索数量判断
  1158. for i, v := range cdataNew {
  1159. if i == 0 {
  1160. count = gconv.Int(v["count"])
  1161. data = v
  1162. } else {
  1163. if count < gconv.Int(v["count"]) {
  1164. count = gconv.Int(v["count"])
  1165. data = v
  1166. }
  1167. }
  1168. }
  1169. positionId = common.Int64All(data["position_id"])
  1170. noticePositionId = positionId
  1171. saleName = common.ObjToString(data["saleName"])
  1172. seatNumber = common.ObjToString(data["seatNumber"])
  1173. if isFull {
  1174. isFreeze = true
  1175. noticePositionId = positionId
  1176. positionId = 0
  1177. seatNumber = ""
  1178. saleName = ""
  1179. }
  1180. return
  1181. }
  1182. } else {
  1183. positionId = common.Int64All(data["position_id"])
  1184. noticePositionId = positionId
  1185. seatNumber = common.ObjToString(data["seatNumber"])
  1186. saleName = common.ObjToString(data["saleName"])
  1187. if isFull {
  1188. isFreeze = true
  1189. noticePositionId = positionId
  1190. positionId = 0
  1191. seatNumber = ""
  1192. saleName = ""
  1193. }
  1194. return
  1195. }
  1196. }
  1197. } else {
  1198. //只有一人跟进
  1199. //(1)该销售人员未离职,则继续分配给该销售人员(保持现状);
  1200. //该销售人员已离职,则随机分配
  1201. positionId = common.Int64All((*cdata)[0]["position_id"])
  1202. noticePositionId = positionId
  1203. seatNumber = common.ObjToString((*cdata)[0]["seatNumber"])
  1204. for _, v := range *pdata {
  1205. resign := common.IntAll(v["resign"])
  1206. assign_type := common.IntAll(v["assign_type"])
  1207. role_id := common.IntAll(v["role_id"])
  1208. if positionId == common.Int64All(v["position_id"]) {
  1209. if resign == 0 && (assign_type == 1 || role_id == 8) {
  1210. if FindUpperLimit(gconv.String(positionId), mode, true) {
  1211. isFreeze = true
  1212. positionId = 0
  1213. seatNumber = ""
  1214. saleName = ""
  1215. break
  1216. } else {
  1217. saleName = common.ObjToString(v["name"])
  1218. return
  1219. }
  1220. }
  1221. }
  1222. }
  1223. }
  1224. }
  1225. }
  1226. }
  1227. positionId = 0
  1228. seatNumber = ""
  1229. saleName = ""
  1230. query := `select * from dwd_f_crm_personnel_management where assign_type = 1 and`
  1231. if mode == "A" {
  1232. query += ` assign_level like "%A%"`
  1233. } else if mode == "B" {
  1234. query += ` assign_level like "%B%"`
  1235. } else if mode == "D" {
  1236. query += ` assign_level like "%D%"`
  1237. } else if mode == "C" {
  1238. query += ` assign_level like "%C%"`
  1239. } else if mode == "S" {
  1240. query += ` assign_level like "%S%"`
  1241. } else if mode == "E" {
  1242. query += ` assign_level like "%E%"`
  1243. }
  1244. data := TiDb.SelectBySql(query)
  1245. if data != nil && len(*data) > 0 {
  1246. saleData = *data
  1247. sql := "select * from dwd_f_crm_clue_autodraw_record where clue_level = ?"
  1248. countData := TiDb.SelectBySql(sql, mode)
  1249. if countData != nil && len(*countData) > 0 {
  1250. for _, v := range *data {
  1251. isOk := false //判断是否有新员工
  1252. for _, vv := range *countData {
  1253. if common.Int64All(v["position_id"]) == common.Int64All(vv["position_id"]) {
  1254. if common.IntAll(v["resign"]) == 0 {
  1255. vv["status"] = 1
  1256. } else {
  1257. vv["status"] = 2
  1258. }
  1259. isOk = true
  1260. }
  1261. }
  1262. if !isOk { //有新员工直接分给新员工
  1263. positionId = common.Int64All(v["position_id"])
  1264. saleName = common.ObjToString(v["name"])
  1265. log.Println("新员工, ", positionId, saleName)
  1266. rData := TiDb.FindOne("dwd_f_crm_clue_autodraw_record", map[string]interface{}{"clue_level": mode}, "", "count desc")
  1267. TiDb.Insert("dwd_f_crm_clue_autodraw_record", map[string]interface{}{
  1268. "position_id": positionId,
  1269. "clue_level": mode,
  1270. "count": common.Int64All((*rData)["count"]),
  1271. })
  1272. break
  1273. }
  1274. }
  1275. if positionId == 0 {
  1276. res := int64(0)
  1277. countres := 0
  1278. for _, v := range *countData {
  1279. if common.IntAll(v["status"]) == 1 {
  1280. if FindUpperLimit(gconv.String(v["position_id"]), mode, false) {
  1281. continue
  1282. }
  1283. if countres == 0 {
  1284. res = common.Int64All(v["count"])
  1285. positionId = common.Int64All(v["position_id"])
  1286. } else {
  1287. if common.Int64All(v["count"]) <= res {
  1288. res = common.Int64All(v["count"])
  1289. positionId = common.Int64All(v["position_id"])
  1290. }
  1291. }
  1292. countres++
  1293. }
  1294. }
  1295. log.Println(444, res)
  1296. }
  1297. } else {
  1298. for _, kv := range *data {
  1299. positionId1 := gconv.String(kv["position_id"])
  1300. if !FindUpperLimit(positionId1, "", false) {
  1301. positionId = common.Int64All(kv["position_id"])
  1302. saleName = common.ObjToString(kv["name"])
  1303. rData := TiDb.FindOne("dwd_f_crm_clue_autodraw_record", map[string]interface{}{"clue_level": mode}, "", "count desc")
  1304. if rData != nil && len(*rData) > 0 {
  1305. TiDb.Insert("dwd_f_crm_clue_autodraw_record", map[string]interface{}{
  1306. "position_id": positionId,
  1307. "clue_level": mode,
  1308. "count": common.Int64All((*rData)["count"]),
  1309. })
  1310. } else {
  1311. TiDb.Insert("dwd_f_crm_clue_autodraw_record", map[string]interface{}{
  1312. "position_id": positionId,
  1313. "clue_level": mode,
  1314. "count": 0,
  1315. })
  1316. }
  1317. break
  1318. }
  1319. }
  1320. }
  1321. for _, v := range *data {
  1322. if positionId == common.Int64All(v["position_id"]) {
  1323. seatNumber = common.ObjToString(v["seat_number"])
  1324. saleName = common.ObjToString(v["name"])
  1325. }
  1326. }
  1327. }
  1328. return
  1329. }
  1330. func getPositionId(phone string) (positionId int64) {
  1331. userData, ok := Mgo.FindOne("user", map[string]interface{}{"s_phone": phone})
  1332. if ok && userData != nil && len(*userData) > 0 {
  1333. userId := common.Int64All((*userData)["base_user_id"])
  1334. positionData := Base.FindOne("base_position", map[string]interface{}{"type": 1, "ent_id": db.EntId, "user_id": userId}, "", "") //TODO ent_id
  1335. if positionData != nil && len(*positionData) > 0 {
  1336. positionId = common.Int64All((*positionData)["id"])
  1337. }
  1338. }
  1339. return
  1340. }
  1341. func GetCompanyType(companyName string, uId string) (int, int) {
  1342. isGroup, isCommerce := 0, 0
  1343. uCount := TiDb.FindOne("dwd_f_crm_clue_info", map[string]interface{}{"uid": uId}, "", "")
  1344. if uCount != nil && len(*uCount) > 0 {
  1345. isUpdate := gconv.Int64((*uCount)["is_artificially_modified"])
  1346. if isUpdate == 1 {
  1347. companyName = gconv.String((*uCount)["cluename"])
  1348. }
  1349. if companyName == "" {
  1350. companyName = gconv.String((*uCount)["cluename"])
  1351. }
  1352. }
  1353. if companyName == "" {
  1354. return isGroup, isCommerce
  1355. }
  1356. //是否是集团
  1357. if c := TiDb.CountBySql(`select count(1) from group_company_name where company_name=?`, companyName); c > 0 {
  1358. isGroup = 1
  1359. }
  1360. //是否在工商库
  1361. if companyName != "" {
  1362. if c := MgoQyxy.Count("qyxy_std", map[string]interface{}{"company_name": companyName, "company_type": map[string]interface{}{"$ne": "个体工商户"}}); c > 0 {
  1363. isCommerce = 1
  1364. }
  1365. }
  1366. return isGroup, isCommerce
  1367. }
  1368. // 查询是否达上限
  1369. func FindUpperLimit(positionId string, level string, isAdd bool) bool {
  1370. if positionId == "" {
  1371. return false
  1372. }
  1373. 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
  1374. if isFull && isAdd && level != "" {
  1375. TiDb.UpdateOrDeleteBySql(`update dwd_f_crm_clue_autodraw_record set count = count + 1 where position_id = ? and clue_level = ?`, positionId, level)
  1376. }
  1377. return isFull
  1378. }
  1379. func getSeatNumberPositionId(seatNumber string) (positionId int64) {
  1380. saleData := TiDb.FindOne("dwd_f_crm_personnel_management", map[string]interface{}{"seat_number": seatNumber}, "", "")
  1381. if saleData != nil && len(*saleData) > 0 {
  1382. positionId = common.Int64All((*saleData)["position_id"])
  1383. }
  1384. return
  1385. }
  1386. // 重新关注用户处理
  1387. func rebind() {
  1388. log.Println("重新关注用户处理开始")
  1389. //判断节假日
  1390. runOk := getRunOk()
  1391. if !runOk {
  1392. log.Println("不是工作日,任务暂停")
  1393. return
  1394. }
  1395. rebindTimeEnd := cfg.RebindTime
  1396. sql := fmt.Sprintf(`select * from freeClubSign where sub_again_date > "%s" order by sub_again_date asc`, rebindTimeEnd)
  1397. data := BiService.SelectBySql(sql)
  1398. if data != nil && *data != nil && len(*data) > 0 {
  1399. for _, v := range *data {
  1400. rebindTimeEnd = common.ObjToString(v["sub_again_date"])
  1401. registedates, _ := time.Parse(date.Date_Full_Layout, gconv.String(v["register_time"]))
  1402. if time.Now().Unix()-registedates.Unix() > int64(db.RegTimes)*86400 {
  1403. ok1, ok2, _ := FormatData(v, "rebind")
  1404. if !ok1 {
  1405. log.Println("线索卡点", "allocation", v, rebindTimeEnd)
  1406. } else {
  1407. if !ok2 {
  1408. log.Println("用户分配已达上限", "allocation", v, rebindTimeEnd)
  1409. }
  1410. }
  1411. }
  1412. }
  1413. cfg.RebindTime = rebindTimeEnd
  1414. common.WriteSysConfig(&cfg)
  1415. }
  1416. log.Println("重新关注用户处理结束")
  1417. }
  1418. // 活跃用户处理
  1419. func activeUsers() {
  1420. log.Println("活跃用户处理开始")
  1421. //判断节假日
  1422. runOk := getRunOk()
  1423. if !runOk {
  1424. log.Println("不是工作日,任务暂停")
  1425. return
  1426. }
  1427. //活跃用户查询
  1428. activeTimeEnd := cfg.ActiveTime
  1429. sql := fmt.Sprintf(`select * from freeClubSign where act_again_date > "%s" order by act_again_date asc`, activeTimeEnd)
  1430. data := BiService.SelectBySql(sql)
  1431. if data != nil && *data != nil && len(*data) > 0 {
  1432. for _, v := range *data {
  1433. activeTimeEnd = common.ObjToString(v["act_again_date"])
  1434. ok1, ok2, _ := FormatData(v, "allocation")
  1435. log.Println(v, "allocation", ok1, ok2)
  1436. if !ok1 {
  1437. log.Println("线索卡点", "allocation", v, activeTimeEnd)
  1438. } else {
  1439. if !ok2 {
  1440. log.Println("用户分配已达上限", "allocation", v, activeTimeEnd)
  1441. }
  1442. }
  1443. }
  1444. cfg.ActiveTime = activeTimeEnd
  1445. common.WriteSysConfig(&cfg)
  1446. }
  1447. log.Println("活跃用户处理结束")
  1448. }
  1449. // 安博会邮件
  1450. /*func ABHEmail(source string, data []map[string]interface{}) {
  1451. fileName, detailName, email, dir := "", "", "", ""
  1452. var err error
  1453. switch source {
  1454. case "user":
  1455. xlsxArr := []string{"姓名", "联系方式", "邮箱", "公司名称", "咨询需求", "销售线索来源", "具体来源", "留资时间"}
  1456. batch := FindBatch("abh")
  1457. fileName, detailName = "安博会用户注册销售线索 "+time.Now().Format(date.Date_Short_Layout)+"-"+batch, ""
  1458. xf := xlsx.NewFile()
  1459. style := xlsx.NewStyle()
  1460. style.Font.Size = 12
  1461. style.Font.Bold = true
  1462. style.Alignment.Vertical = "center"
  1463. style.Alignment.Horizontal = "center"
  1464. detailName = "今日新增安博会销售线索,请查收附件,及时跟进。"
  1465. sh, _ := xf.AddSheet("线索数据")
  1466. row1 := sh.AddRow()
  1467. for _, x := range xlsxArr {
  1468. cell := row1.AddCell()
  1469. cell.SetString(x)
  1470. cell.SetStyle(style)
  1471. }
  1472. for _, v := range data {
  1473. row := sh.AddRow()
  1474. row.AddCell().SetString(common.ObjToString(v["name"]))
  1475. row.AddCell().SetString(common.ObjToString(v["phone"]))
  1476. row.AddCell().SetString(common.ObjToString(v["email"]))
  1477. row.AddCell().SetString(common.ObjToString(v["company_name"]))
  1478. row.AddCell().SetString("")
  1479. row.AddCell().SetString("")
  1480. row.AddCell().SetString("安博会用户注册")
  1481. row.AddCell().SetString(gconv.Time(gconv.Int64(v["createtime"])).Format(date.Date_Full_Layout))
  1482. //增加客户需求
  1483. }
  1484. dir = "./xlsx/abh/" + fileName + ".xlsx"
  1485. err = xf.Save(dir)
  1486. case "saleLeads":
  1487. xlsxArr := []string{"用户昵称", "姓名", "公司名称", "职位", "联系人电话", "购买条数", "用户邮箱", "已支付订单信息", "未支付订单类型", "销售线索来源", "具体来源", "数据需求"}
  1488. batch := FindBatch("abh")
  1489. fileName, detailName = time.Now().Format(date.Date_Short_Layout)+"-"+batch+"安博会电销销售线索", ""
  1490. xf := xlsx.NewFile()
  1491. style := xlsx.NewStyle()
  1492. style.Font.Size = 12
  1493. style.Font.Bold = true
  1494. style.Alignment.Vertical = "center"
  1495. style.Alignment.Horizontal = "center"
  1496. detailName = "今日新增安博会销售线索,请查收附件,及时跟进。"
  1497. sh, _ := xf.AddSheet("线索数据")
  1498. row1 := sh.AddRow()
  1499. for _, x := range xlsxArr {
  1500. cell := row1.AddCell()
  1501. cell.SetString(x)
  1502. cell.SetStyle(style)
  1503. }
  1504. filterArr := []string{"-pc", "-app", "-wx", "-h5"}
  1505. sourceMap := map[string]string{} //根据留资维表:tidb/Jianyu_subjectdb/d_saleleads_code
  1506. saleSource := TiDb.SelectBySql(`SELECT source,name FROM d_saleleads_code WHERE is_delete = 1`)
  1507. if saleSource != nil && len(*saleSource) > 0 {
  1508. for _, v := range *saleSource {
  1509. source := common.ObjToString(v["source"])
  1510. name := common.ObjToString(v["name"])
  1511. for _, s := range filterArr {
  1512. name = strings.ReplaceAll(name, s, "")
  1513. }
  1514. sourceMap[source] = name
  1515. }
  1516. }
  1517. for _, v := range data {
  1518. sources := common.ObjToString(v["source"])
  1519. interest := common.ObjToString(v["interest"])
  1520. row := sh.AddRow()
  1521. row.AddCell().SetString(common.ObjToString(v["usernickname"]))
  1522. row.AddCell().SetString(common.ObjToString(v["name"]))
  1523. row.AddCell().SetString(common.ObjToString(v["company"]))
  1524. row.AddCell().SetString(common.ObjToString(v["position"]))
  1525. row.AddCell().SetString(common.ObjToString(v["phone"]))
  1526. row.AddCell().SetValue(0)
  1527. row.AddCell().SetString(common.ObjToString(v["email"]))
  1528. row.AddCell().SetString("")
  1529. row.AddCell().SetString("")
  1530. row.AddCell().SetString(sourceMap[sources])
  1531. row.AddCell().SetString(interest)
  1532. row.AddCell().SetString(common.ObjToString(v["data_requirement"]))
  1533. //增加客户需求
  1534. }
  1535. dir = "./xlsx/abh/" + fileName + ".xlsx"
  1536. err = xf.Save(dir)
  1537. case "big":
  1538. xlsxArr := []string{"用户昵称", "姓名", "公司名称", "职位", "联系人电话", "购买条数", "用户邮箱", "已支付订单信息", "未支付订单类型", "销售线索来源", "具体来源", "数据需求"}
  1539. batch := FindBatch("abh")
  1540. fileName, detailName = time.Now().Format(date.Date_Short_Layout)+"-"+batch+"安博会大客户销售线索", ""
  1541. xf := xlsx.NewFile()
  1542. style := xlsx.NewStyle()
  1543. style.Font.Size = 12
  1544. style.Font.Bold = true
  1545. style.Alignment.Vertical = "center"
  1546. style.Alignment.Horizontal = "center"
  1547. detailName = "今日新增安博会销售线索,请查收附件,及时跟进。"
  1548. sh, _ := xf.AddSheet("线索数据")
  1549. row1 := sh.AddRow()
  1550. for _, x := range xlsxArr {
  1551. cell := row1.AddCell()
  1552. cell.SetString(x)
  1553. cell.SetStyle(style)
  1554. }
  1555. for _, v := range data {
  1556. row := sh.AddRow()
  1557. row.AddCell().SetString(common.ObjToString(v["usernickname"]))
  1558. row.AddCell().SetString(common.ObjToString(v["username"]))
  1559. row.AddCell().SetString(common.ObjToString(v["company"]))
  1560. row.AddCell().SetString(common.ObjToString(v["job"]))
  1561. row.AddCell().SetString(common.ObjToString(v["phone"]))
  1562. row.AddCell().SetValue(common.IntAll(v["data_count"]))
  1563. row.AddCell().SetString(common.ObjToString(v["email"]))
  1564. row.AddCell().SetString(common.ObjToString(v["payorderinfo"]))
  1565. row.AddCell().SetString(common.ObjToString(v["unpayorderinfo"]))
  1566. row.AddCell().SetString(common.ObjToString(v["source"]))
  1567. row.AddCell().SetString(common.ObjToString(v["interest"]))
  1568. row.AddCell().SetString(common.ObjToString(v["data_requirement"]))
  1569. //增加客户需求
  1570. }
  1571. dir = "./xlsx/abh/" + fileName + ".xlsx"
  1572. err = xf.Save(dir)
  1573. case "advisory":
  1574. xlsxArr := []string{"姓名", "联系方式", "邮箱", "公司名称", "咨询需求", "销售线索来源", "具体来源", "留资时间"}
  1575. //排序:首先按照“联系方式”排序,即同1个用户的留资放在一起,其次按照留资时间正序排序。
  1576. batch := FindBatch("abh")
  1577. fileName, detailName = "安博会咨询服务销售线索 "+time.Now().Format(date.Date_Short_Layout)+"-"+batch, ""
  1578. xf := xlsx.NewFile()
  1579. style := xlsx.NewStyle()
  1580. style.Font.Size = 12
  1581. style.Font.Bold = true
  1582. style.Alignment.Vertical = "center"
  1583. style.Alignment.Horizontal = "center"
  1584. detailName = "今日新增安博会销售线索,请查收附件,及时跟进。"
  1585. sh, _ := xf.AddSheet("线索数据")
  1586. row1 := sh.AddRow()
  1587. for _, x := range xlsxArr {
  1588. cell := row1.AddCell()
  1589. cell.SetString(x)
  1590. cell.SetStyle(style)
  1591. }
  1592. for _, v := range data {
  1593. row := sh.AddRow()
  1594. row.AddCell().SetString(common.ObjToString(v["username"]))
  1595. row.AddCell().SetString(common.ObjToString(v["phone"]))
  1596. row.AddCell().SetString(common.ObjToString(v["email"]))
  1597. row.AddCell().SetString(common.ObjToString(v["company"]))
  1598. row.AddCell().SetString(common.ObjToString(v["data_requirement"]))
  1599. row.AddCell().SetString(common.ObjToString(v["source"]))
  1600. row.AddCell().SetString(common.ObjToString(v["interest"]))
  1601. row.AddCell().SetString(gconv.Time(gconv.Int64(v["createtime"])).Format(date.Date_Full_Layout))
  1602. }
  1603. dir = "./xlsx/abh/" + fileName + ".xlsx"
  1604. err = xf.Save(dir)
  1605. case "market":
  1606. xlsxArr := []string{"姓名", "联系人电话", "公司名称", "职位", "部门", "销售线索来源", "留资时间"}
  1607. batch := FindBatch("abh")
  1608. fileName, detailName = "安博会商务合作销售线索 "+time.Now().Format(date.Date_Short_Layout)+"-"+batch, ""
  1609. xf := xlsx.NewFile()
  1610. style := xlsx.NewStyle()
  1611. style.Font.Size = 12
  1612. style.Font.Bold = true
  1613. style.Alignment.Vertical = "center"
  1614. style.Alignment.Horizontal = "center"
  1615. detailName = "今日新增安博会销售线索,请查收附件,及时跟进。"
  1616. sh, _ := xf.AddSheet("线索数据")
  1617. row1 := sh.AddRow()
  1618. for _, x := range xlsxArr {
  1619. cell := row1.AddCell()
  1620. cell.SetString(x)
  1621. cell.SetStyle(style)
  1622. }
  1623. for _, v := range data {
  1624. row := sh.AddRow()
  1625. row.AddCell().SetString(common.ObjToString(v["username"]))
  1626. row.AddCell().SetString(common.ObjToString(v["phone"]))
  1627. row.AddCell().SetString(common.ObjToString(v["company"]))
  1628. row.AddCell().SetString(common.ObjToString(v["job"]))
  1629. row.AddCell().SetString(common.ObjToString(v["branch"]))
  1630. row.AddCell().SetString(common.ObjToString(v["source"]))
  1631. row.AddCell().SetString(gconv.Time(gconv.Int64(v["createtime"])).Format(date.Date_Full_Layout))
  1632. //增加客户需求
  1633. }
  1634. dir = "./xlsx/abh/" + fileName + ".xlsx"
  1635. err = xf.Save(dir)
  1636. }
  1637. email = db.AbhEmail
  1638. if err != nil {
  1639. log.Println("xls error", err, dir)
  1640. } else {
  1641. gmail := &mail.GmailAuth{
  1642. SmtpHost: "smtp.exmail.qq.com",
  1643. SmtpPort: 465,
  1644. User: "public03@topnet.net.cn",
  1645. Pwd: "ue9Rg9Sf4CVtdm5a",
  1646. }
  1647. status := mail.GSendMail_q("剑鱼标讯", email, "", "", fileName, detailName, dir, fileName+".xlsx", gmail)
  1648. if status {
  1649. log.Println("send mail success", fileName, email)
  1650. }
  1651. }
  1652. }*/
  1653. // 安防邮件
  1654. func AFEmail(data []map[string]interface{}) {
  1655. xlsxArr := []string{"姓名", "联系方式", "邮箱", "公司名称", "咨询需求", "销售线索来源", "具体来源", "留资时间"}
  1656. batch := FindBatch("af")
  1657. fileName, detailName := "安防销售线索 "+time.Now().Format(date.Date_Short_Layout)+"-"+batch, ""
  1658. xf := xlsx.NewFile()
  1659. style := xlsx.NewStyle()
  1660. style.Font.Size = 12
  1661. style.Font.Bold = true
  1662. style.Alignment.Vertical = "center"
  1663. style.Alignment.Horizontal = "center"
  1664. detailName = "今日新增安防销售线索,请查收附件,及时跟进。"
  1665. sh, _ := xf.AddSheet("线索数据")
  1666. row1 := sh.AddRow()
  1667. for _, x := range xlsxArr {
  1668. cell := row1.AddCell()
  1669. cell.SetString(x)
  1670. cell.SetStyle(style)
  1671. }
  1672. for _, v := range data {
  1673. row := sh.AddRow()
  1674. row.AddCell().SetString(common.ObjToString(v["name"]))
  1675. row.AddCell().SetString(common.ObjToString(v["phone"]))
  1676. row.AddCell().SetString(common.ObjToString(v["email"]))
  1677. row.AddCell().SetString(common.ObjToString(v["company_name"]))
  1678. row.AddCell().SetString("")
  1679. row.AddCell().SetString("")
  1680. row.AddCell().SetString("首次使用安防新注册")
  1681. row.AddCell().SetString(gconv.String(v["time"]))
  1682. //增加客户需求
  1683. }
  1684. email := db.AfEmail
  1685. dir := "./xlsx/af/" + fileName + ".xlsx"
  1686. err := xf.Save(dir)
  1687. if err != nil {
  1688. log.Println("xls error", err, dir)
  1689. } else {
  1690. gmail := &mail.GmailAuth{
  1691. SmtpHost: db.Mail.SmtpHost,
  1692. SmtpPort: db.Mail.SmtpPort,
  1693. User: db.Mail.User,
  1694. Pwd: db.Mail.Pwd,
  1695. }
  1696. status := mail.GSendMail_q("剑鱼标讯", email, "", "", fileName, detailName, dir, "", gmail)
  1697. if status {
  1698. log.Println("send mail success", fileName, email)
  1699. }
  1700. }
  1701. }
  1702. func populateAdvisoryData(sh *xlsx.Sheet, data []map[string]interface{}) error {
  1703. for _, v := range data {
  1704. row := sh.AddRow()
  1705. row.AddCell().SetString(common.ObjToString(v["username"]))
  1706. row.AddCell().SetString(common.ObjToString(v["phone"]))
  1707. row.AddCell().SetString(common.ObjToString(v["email"]))
  1708. row.AddCell().SetString(common.ObjToString(v["company"]))
  1709. row.AddCell().SetString(common.ObjToString(v["data_requirement"]))
  1710. row.AddCell().SetString(common.ObjToString(v["source"]))
  1711. row.AddCell().SetString(common.ObjToString(v["interest"]))
  1712. row.AddCell().SetString(gconv.Time(gconv.Int64(v["createtime"])).Format(date.Date_Full_Layout))
  1713. }
  1714. return nil
  1715. }
  1716. // 邀请用户处理
  1717. func inviteUser() {
  1718. log.Println("邀请用户处理开始")
  1719. //判断节假日
  1720. runOk := getRunOk()
  1721. if !runOk {
  1722. log.Println("不是工作日,任务暂停")
  1723. return
  1724. }
  1725. rebindTimeEnd := cfg.InviteTime
  1726. sql := fmt.Sprintf(`select * from user_statistics where createTime > "%s" order by createTime asc`, rebindTimeEnd)
  1727. //sql := fmt.Sprintf(`select * from user_statistics where createTime = "%s" order by createTime asc`, rebindTimeEnd)
  1728. data := BiService.SelectBySql(sql)
  1729. if data != nil && *data != nil && len(*data) > 0 {
  1730. for _, v := range *data {
  1731. rebindTimeEnd = common.ObjToString(v["createTime"])
  1732. event := gconv.Int64(v["event"])
  1733. switch event {
  1734. case 1:
  1735. v["sourceCode"] = "736"
  1736. case 2:
  1737. v["sourceCode"] = "737"
  1738. case 3:
  1739. v["sourceCode"] = "738"
  1740. }
  1741. v["user_id"] = gconv.String(v["userId"])
  1742. ok1, ok2, _ := FormatData(v, "invite")
  1743. if !ok1 {
  1744. log.Println("线索卡点", "invite", v, rebindTimeEnd)
  1745. } else {
  1746. if !ok2 {
  1747. log.Println("用户分配已达上限", "invite", v, rebindTimeEnd)
  1748. }
  1749. }
  1750. }
  1751. cfg.InviteTime = rebindTimeEnd
  1752. common.WriteSysConfig(&cfg)
  1753. }
  1754. log.Println("邀请用户处理结束")
  1755. }
  1756. // 开年活动
  1757. func nextYearActivity() {
  1758. log.Println("开年活动处理开始")
  1759. //判断节假日
  1760. runOk := getRunOk()
  1761. if !runOk {
  1762. log.Println("不是工作日,任务暂停")
  1763. return
  1764. }
  1765. activityTimeEnd := cfg.ActivityTime
  1766. sql := fmt.Sprintf(`SELECT
  1767. a.*
  1768. FROM
  1769. jyactivities.lottery_user_account a
  1770. INNER JOIN jyactivities.lottery_prize_info b on a.create_time > "%s" and a.prize_id=b.id
  1771. INNER JOIN jyactivities.prize_base_info c on c.name like "%s" and b.pb_id=c.id
  1772. ORDER BY
  1773. a.create_time ASC
  1774. `, activityTimeEnd, "%超级订阅%")
  1775. data := Mysql.SelectBySql(sql)
  1776. if data != nil && *data != nil && len(*data) > 0 {
  1777. for _, v := range *data {
  1778. activityTimeEnd = common.ObjToString(v["create_time"])
  1779. v["sourceCode"] = gconv.Int64(v["active_id"])
  1780. v["user_id"] = gconv.String(v["mgo_user_id"])
  1781. ok1, ok2, _ := FormatData(v, "activity")
  1782. if !ok1 {
  1783. log.Println("线索卡点", "activity", v, activityTimeEnd)
  1784. } else {
  1785. if !ok2 {
  1786. log.Println("开年活动分配已达上限", "activity", v, activityTimeEnd)
  1787. }
  1788. }
  1789. }
  1790. cfg.ActivityTime = activityTimeEnd
  1791. common.WriteSysConfig(&cfg)
  1792. }
  1793. log.Println("开年活动处理结束")
  1794. }
  1795. // 获取用户渠道信息
  1796. func GetUserChannel(userId string) string {
  1797. if userId == "" {
  1798. return ""
  1799. }
  1800. codeArr := []string{}
  1801. if len(UserChannel) > 0 {
  1802. for i := range UserChannel {
  1803. codeArr = append(codeArr, fmt.Sprintf(`"%s"`, i))
  1804. }
  1805. }
  1806. //查找注册日志表
  1807. sql := fmt.Sprintf(`select channel_code from user_source where user_id ="%s" and channel_code in (%s) ORDER BY create_time desc limit 1 `, userId, strings.Join(codeArr, ","))
  1808. courceData := ThirdParty.SelectBySql(sql)
  1809. if courceData != nil && len(*courceData) > 0 {
  1810. channelCode := gconv.String((*courceData)[0]["channel_code"])
  1811. data, exit := UserChannel[channelCode]
  1812. if exit {
  1813. return gconv.String(data["clueCode"])
  1814. }
  1815. }
  1816. return ""
  1817. }