jobutil.go 63 KB

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