jobutil.go 65 KB

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