everything.go 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123
  1. package main
  2. import (
  3. "app.yhyue.com/moapp/jybase/redis"
  4. "database/sql"
  5. "encoding/json"
  6. "fmt"
  7. "github.com/gogf/gf/util/gconv"
  8. "log"
  9. "net/url"
  10. "os"
  11. "path/filepath"
  12. "strings"
  13. "time"
  14. "app.yhyue.com/moapp/jybase/mail"
  15. "github.com/tealeg/xlsx"
  16. "app.yhyue.com/moapp/jybase/date"
  17. dates "app.yhyue.com/moapp/jybase/date"
  18. "app.yhyue.com/moapp/jybase/mongodb"
  19. "app.yhyue.com/moapp/jybase/common"
  20. )
  21. // 渠道定时任务
  22. func everythingSync() {
  23. lastEverythingTime := cfg.LastEverythingTime
  24. codeArr := []string{}
  25. if len(UserChannel) > 0 {
  26. for i := range UserChannel {
  27. codeArr = append(codeArr, fmt.Sprintf(`"%s"`, i))
  28. }
  29. }
  30. sql := fmt.Sprintf(`select * from user_source where channel_code in (%s) and create_time > "%s" order by create_time asc`, strings.Join(codeArr, ","), lastEverythingTime)
  31. //sql := fmt.Sprintf(`select * from user_source where id =662847`)
  32. log.Println("三方渠道数据定时任务开始", sql)
  33. data := ThirdParty.SelectBySql(sql)
  34. if data != nil && *data != nil && len(*data) > 0 {
  35. everythingSyncHandle(data, true)
  36. }
  37. sql = fmt.Sprintf(`select * from user_source where channel_code in (%s) and ishandle=1 order by create_time asc`, strings.Join(codeArr, ","))
  38. log.Println("三方渠道数据定时任务开始1", sql)
  39. data = ThirdParty.SelectBySql(sql)
  40. if data != nil && *data != nil && len(*data) > 0 {
  41. everythingSyncHandle(data, false)
  42. }
  43. log.Println("三方渠道数据定时任务结束")
  44. }
  45. func everythingSyncHandle(data *[]map[string]interface{}, isUpdate bool) {
  46. nowTime := time.Now().Format(dates.Date_Full_Layout)
  47. for _, v := range *data {
  48. id := gconv.Int64(v["id"])
  49. channel_code := gconv.String(v["channel_code"])
  50. changeMap := UserChannel[channel_code]
  51. channeName := changeMap["name"]
  52. channelCode := changeMap["clueCode"]
  53. user_id := common.ObjToString(v["user_id"])
  54. position_id := common.Int64All(v["position_id"])
  55. phone := common.ObjToString(v["phone"])
  56. state := common.IntAll(v["state"])
  57. user_mold, is_assign, is_transfer, last_login_time, registe_time, mailbox, source, clueId, order_type := 4, 0, 0, "", "", "", "", int64(0), ""
  58. owner, sales_lead_phone, sales_ent_name, sales_position, sales_dep, data_request, sales_leads_source := "", "", "", "", "", "", ""
  59. cData := TiDb.FindOne("dwd_f_crm_clue_info", map[string]interface{}{"phone": phone}, "", "")
  60. if cData != nil {
  61. is_assign = common.IntAll((*cData)["is_assign"])
  62. is_transfer = common.IntAll((*cData)["is_transfer"])
  63. clueId = common.Int64All((*cData)["id"])
  64. }
  65. udata := TiDb.FindOne("dwd_f_userbase_baseinfo", map[string]interface{}{"userid": user_id}, "", "")
  66. if udata != nil {
  67. userSource := common.ObjToString((*udata)["source"])
  68. if userSource == "0102" {
  69. continue
  70. }
  71. }
  72. //
  73. /*cuData := TiDbData.FindOne("customer", map[string]interface{}{"phone": phone}, "", "")
  74. if cuData != nil {
  75. owner = common.ObjToString((*cuData)["owner"])
  76. unique_id = common.ObjToString((*cuData)["unique_id"])
  77. belongTo = common.ObjToString((*cuData)["belongTo"])
  78. }*/
  79. vData := TiDb.FindOne("dwd_f_userbase_visit_info", map[string]interface{}{"userid": user_id}, "", "")
  80. if vData != nil {
  81. last_login_time = common.ObjToString((*vData)["date"])
  82. }
  83. dData := Mysql.Find("dataexport_order", map[string]interface{}{"user_id": user_id}, "", "", -1, -1)
  84. if dData != nil && len(*dData) > 0 {
  85. pMap := map[string]string{}
  86. pArr := []string{}
  87. for _, v := range *dData {
  88. product_type := common.ObjToString(v["product_type"])
  89. pMap[product_type] = "1"
  90. }
  91. for k := range pMap {
  92. pArr = append(pArr, k)
  93. }
  94. if len(pArr) > 0 {
  95. order_type = strings.Join(pArr, ",")
  96. }
  97. }
  98. uData, ok := Mgo.FindOne("user", map[string]interface{}{"_id": mongodb.StringTOBsonId(user_id)})
  99. if ok && uData != nil {
  100. l_registedate := common.Int64All((*uData)["l_registedate"])
  101. registe_time = time.Unix(l_registedate, 0).Format(dates.Date_Full_Layout)
  102. }
  103. if TiDb.Count("dwd_f_userbase_baseinfo", map[string]interface{}{
  104. "userid": user_id,
  105. }) <= 0 {
  106. ThirdParty.Update("user_source", map[string]interface{}{
  107. "id": id,
  108. }, map[string]interface{}{
  109. "ishandle": 1,
  110. })
  111. continue
  112. }
  113. sData, oks := Mgo.Find("saleLeads", map[string]interface{}{"userid": user_id}, `{"_id":-1}`, nil, false, 0, 1)
  114. if oks && sData != nil {
  115. if len(*sData) > 0 {
  116. sDatas := (*sData)[0]
  117. sales_lead_phone = common.ObjToString(sDatas["phone"])
  118. sales_position = common.ObjToString(sDatas["position"])
  119. sales_ent_name = common.ObjToString(sDatas["company"])
  120. sales_dep = common.ObjToString(sDatas["branch"])
  121. if sales_dep == "" {
  122. sales_dep = common.ObjToString(sDatas["department"])
  123. }
  124. data_request = common.ObjToString(sDatas["data_requirement"])
  125. mailbox = common.ObjToString(sDatas["mail"])
  126. source = common.ObjToString(sDatas["interest"])
  127. }
  128. }
  129. if state == 1 {
  130. sales_leads_source = fmt.Sprintf("%s登录", channeName)
  131. if is_assign == 1 || is_transfer == 1 || owner != "" {
  132. user_mold = 1
  133. } else {
  134. user_mold = 2
  135. }
  136. } else if state == 2 {
  137. sales_leads_source = fmt.Sprintf("%s注册", channeName)
  138. if is_assign == 1 || is_transfer == 1 || owner != "" {
  139. user_mold = 3
  140. } else {
  141. user_mold = 4
  142. }
  143. }
  144. if ThirdParty.Count("user_channel_info", map[string]interface{}{"user_id": user_id}) > 0 {
  145. ThirdParty.Update("user_channel_info", map[string]interface{}{"user_id": user_id}, map[string]interface{}{
  146. "user_mold": user_mold,
  147. "last_login_time": common.If(last_login_time != "", last_login_time, nil),
  148. "sales_lead_phone": sales_lead_phone,
  149. "sales_ent_name": sales_ent_name,
  150. "sales_position": sales_position,
  151. "sales_dep": sales_dep,
  152. "sales_leads_source": sales_leads_source,
  153. "mailbox": mailbox,
  154. "order_type": order_type,
  155. "data_request": data_request,
  156. "source": source,
  157. "update_time": nowTime,
  158. })
  159. } else {
  160. ThirdParty.Insert("user_channel_info", map[string]interface{}{
  161. "user_id": user_id,
  162. "registe_time": registe_time,
  163. "phone": phone,
  164. "user_mold": user_mold,
  165. "last_login_time": common.If(last_login_time != "", last_login_time, nil),
  166. "sales_lead_phone": sales_lead_phone,
  167. "sales_ent_name": sales_ent_name,
  168. "sales_position": sales_position,
  169. "sales_dep": sales_dep,
  170. "sales_leads_source": sales_leads_source,
  171. "order_type": order_type,
  172. "mailbox": mailbox,
  173. "data_request": data_request,
  174. "source": source,
  175. "update_time": nowTime,
  176. })
  177. }
  178. if clueId > 0 && is_assign != 1 && is_transfer != 1 {
  179. TiDb.Update("dwd_f_userbase_baseinfo", map[string]interface{}{"userid": user_id}, map[string]interface{}{"belong_to": channelCode})
  180. TiDb.Update("dwd_f_crm_clue_info", map[string]interface{}{"phone": phone}, map[string]interface{}{"is_assign": -1})
  181. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  182. "clue_id": clueId,
  183. "position_id": common.If(position_id > 0, position_id, -1),
  184. "change_type": "退出公海",
  185. "new_value": fmt.Sprintf("通过合作渠道%s", channeName) + fmt.Sprint(common.If(user_mold == 1 || user_mold == 2, "登录", "注册")),
  186. "createtime": nowTime,
  187. "BCPCID": common.GetRandom(32),
  188. "operator_id": -1,
  189. })
  190. }
  191. ThirdParty.Update("user_source", map[string]interface{}{
  192. "id": id,
  193. }, map[string]interface{}{
  194. "ishandle": 0,
  195. })
  196. }
  197. if isUpdate {
  198. cfg.LastEverythingTime = common.ObjToString((*data)[len(*data)-1]["create_time"])
  199. common.WriteSysConfig(&cfg)
  200. }
  201. }
  202. func saveEverything(user_id, phone, item, sourceName, sourceCode, belongTo string) bool {
  203. changeMap := UserChannel[belongTo]
  204. changeName := gconv.String(changeMap["name"])
  205. nowTime, isOk := time.Now().Format(dates.Date_Full_Layout), false
  206. user_mold, is_assign, is_transfer, last_login_time, registe_time, mailbox, source, order_type, sales_leads_source := 4, 0, 0, "", "", "", "", "", ""
  207. owner, sales_lead_phone, sales_ent_name, sales_position, sales_dep, data_request, clueId, position_id := "", "", "", "", "", "", int64(0), int64(0)
  208. cData := TiDb.FindOne("dwd_f_crm_clue_info", map[string]interface{}{"phone": phone}, "", "")
  209. if cData != nil {
  210. is_assign = common.IntAll((*cData)["is_assign"])
  211. is_transfer = common.IntAll((*cData)["is_transfer"])
  212. clueId = common.Int64All((*cData)["is_transfer"])
  213. position_id = common.Int64All((*cData)["position_id"])
  214. }
  215. cuData := TiDbData.FindOne("customer", map[string]interface{}{"phone": phone}, "", "")
  216. if cuData != nil {
  217. owner = common.ObjToString((*cuData)["owner"])
  218. }
  219. dData := Mysql.Find("dataexport_order", map[string]interface{}{"user_id": user_id}, "", "", -1, -1)
  220. if dData != nil && len(*dData) > 0 {
  221. pMap := map[string]string{}
  222. pArr := []string{}
  223. for _, v := range *dData {
  224. product_type := common.ObjToString(v["product_type"])
  225. pMap[product_type] = "1"
  226. }
  227. for k := range pMap {
  228. pArr = append(pArr, k)
  229. }
  230. if len(pArr) > 0 {
  231. order_type = strings.Join(pArr, ",")
  232. }
  233. }
  234. vData := TiDb.FindOne("dwd_f_userbase_visit_info", map[string]interface{}{"userid": user_id}, "", "")
  235. if vData != nil {
  236. last_login_time = common.ObjToString((*vData)["date"])
  237. }
  238. uData, ok := Mgo.FindOne("user", map[string]interface{}{"_id": mongodb.StringTOBsonId(user_id)})
  239. if ok && uData != nil {
  240. l_registedate := common.Int64All((*uData)["l_registedate"])
  241. registe_time = time.Unix(l_registedate, 0).Format(dates.Date_Full_Layout)
  242. }
  243. if item == "orders" {
  244. sales_leads_source = "订单未支付"
  245. } else if item == "users" || item == "xcxusers" {
  246. return false
  247. } else if item == "saleLeads" {
  248. sales_leads_source = sourceName
  249. } else {
  250. sales_leads_source = "用户留资"
  251. }
  252. query := map[string]interface{}{"userid": user_id}
  253. if sourceCode != "" {
  254. query["source"] = sourceCode
  255. }
  256. sData, oks := Mgo.Find("saleLeads", query, `{"_id":-1}`, nil, false, 0, 1)
  257. if oks && sData != nil {
  258. if len(*sData) > 0 {
  259. sDatas := (*sData)[0]
  260. sales_lead_phone = common.ObjToString(sDatas["phone"])
  261. sales_position = common.ObjToString(sDatas["position"])
  262. sales_ent_name = common.ObjToString(sDatas["company"])
  263. sales_dep = common.ObjToString(sDatas["branch"])
  264. if sales_dep == "" {
  265. sales_dep = common.ObjToString(sDatas["department"])
  266. }
  267. data_request = common.ObjToString(sDatas["data_requirement"])
  268. mailbox = common.ObjToString(sDatas["mail"])
  269. source = common.ObjToString(sDatas["interest"])
  270. }
  271. }
  272. if is_assign == 1 || is_transfer == 1 || owner != "" {
  273. user_mold = 1
  274. } else {
  275. user_mold = 2
  276. }
  277. /*if owner == "" && unique_id != "" && belongTo == "市场部" {
  278. token := getToken()
  279. if token != "" {
  280. sss := url.QueryEscape("合作渠道一切都好")
  281. urls := `https://a1.7x24cc.com/commonInte?flag=1008&account=N000000029739&accessToken=` + token + `&cusObj={"unique_id":"` + unique_id + `","empNo":"8049","owner":"8049","source":"` + sss + `"}&dbType=0001`
  282. bs, err := doGet(urls)
  283. if err != nil {
  284. log.Println("调用接口失败", unique_id, err)
  285. }
  286. resMap := common.StringToMap(string(bs))
  287. if resMap["success"] != nil && resMap["success"].(bool) {
  288. ok := TiDbData.Update("customer", map[string]interface{}{"unique_id": unique_id}, map[string]interface{}{"empNo": "8049", "owner": "8049", "source": "合作渠道一切都好"})
  289. if ok {
  290. log.Println("更新成功", unique_id)
  291. } else {
  292. log.Println("更新失败", unique_id)
  293. }
  294. } else {
  295. log.Println("调用接口失败!!", unique_id)
  296. }
  297. }
  298. }*/
  299. if ThirdParty.Count("user_channel_info", map[string]interface{}{"user_id": user_id}) > 0 {
  300. ThirdParty.Update("user_channel_info", map[string]interface{}{"user_id": user_id}, map[string]interface{}{
  301. "user_mold": user_mold,
  302. "last_login_time": common.If(last_login_time != "", last_login_time, nil),
  303. "sales_lead_phone": sales_lead_phone,
  304. "sales_ent_name": sales_ent_name,
  305. "sales_position": sales_position,
  306. "sales_dep": sales_dep,
  307. "sales_leads_source": sales_leads_source,
  308. "mailbox": mailbox,
  309. "data_request": data_request,
  310. "source": source,
  311. "order_type": order_type,
  312. "update_time": nowTime,
  313. })
  314. } else {
  315. ThirdParty.Insert("user_channel_info", map[string]interface{}{
  316. "user_id": user_id,
  317. "registe_time": registe_time,
  318. "phone": phone,
  319. "user_mold": user_mold,
  320. "last_login_time": common.If(last_login_time != "", last_login_time, nil),
  321. "sales_lead_phone": sales_lead_phone,
  322. "sales_ent_name": sales_ent_name,
  323. "sales_position": sales_position,
  324. "sales_dep": sales_dep,
  325. "sales_leads_source": sales_leads_source,
  326. "mailbox": mailbox,
  327. "data_request": data_request,
  328. "order_type": order_type,
  329. "source": source,
  330. "update_time": nowTime,
  331. })
  332. }
  333. if clueId > 0 && is_assign != 1 && is_transfer != 1 {
  334. TiDb.Update("dwd_f_crm_clue_info", map[string]interface{}{"phone": phone}, map[string]interface{}{"is_assign": -1})
  335. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  336. "clue_id": clueId,
  337. "position_id": common.If(position_id > 0, position_id, -1),
  338. "change_type": "退出公海",
  339. "new_value": fmt.Sprintf("通过合作渠道%s登录", changeName),
  340. "createtime": nowTime,
  341. "BCPCID": common.GetRandom(32),
  342. "operator_id": -1,
  343. })
  344. } else if is_assign == 1 || is_transfer == 1 {
  345. isOk = true
  346. }
  347. return isOk
  348. }
  349. // 大客户线索-发邮件
  350. func bigCustomer() {
  351. runOk := getRunOk()
  352. if !runOk {
  353. log.Println("不是工作日,任务暂停")
  354. return
  355. }
  356. log.Println("大客户线索定时任务开始")
  357. dataArr := []map[string]interface{}{}
  358. filterArr := []string{"-pc", "-app", "-wx", "-h5"}
  359. sourceMap := map[string]map[string]interface{}{} //根据留资维表:tidb/Jianyu_subjectdb/d_saleleads_code
  360. saleSource := TiDb.SelectBySql(`SELECT source,name,appoint_email FROM d_saleleads_code WHERE department LIKE '%大客户%' AND is_delete = 1`)
  361. if saleSource != nil && len(*saleSource) > 0 {
  362. for _, v := range *saleSource {
  363. saleSourceMap := v
  364. source := common.ObjToString(v["source"])
  365. name := common.ObjToString(v["name"])
  366. for _, s := range filterArr {
  367. name = strings.ReplaceAll(name, s, "")
  368. }
  369. saleSourceMap["name"] = name
  370. sourceMap[source] = saleSourceMap
  371. }
  372. }
  373. nowTime := time.Now().Format(date.Date_Full_Layout)
  374. bigSaleTime := cfg.BigSaleTime
  375. bigOrderTime := cfg.BigOrderTime
  376. if bigSaleTime == 0 {
  377. bigSaleTime = time.Now().Unix()
  378. }
  379. if bigOrderTime == "" {
  380. bigOrderTime = nowTime
  381. }
  382. data := FindBatchData("dk")
  383. saleleadsData, ok := Mgo.Find("saleLeads", map[string]interface{}{"createtime": map[string]interface{}{"$gt": bigSaleTime}}, `{"phone":1,"createtime":1}`, nil, false, -1, -1)
  384. if ok && saleleadsData != nil && len(*saleleadsData) > 0 {
  385. for _, v := range *saleleadsData {
  386. sources := common.ObjToString(v["source"])
  387. userid := common.ObjToString(v["userid"])
  388. uid := ""
  389. if !mongodb.IsObjectIdHex(userid) {
  390. userMapping := TiDb.FindOne("data_service.user_system", map[string]interface{}{"position_id": userid}, "", "")
  391. if userMapping != nil && len(*userMapping) > 0 {
  392. userid = common.ObjToString((*userMapping)["userid"])
  393. uid = common.ObjToString((*userMapping)["uid"])
  394. }
  395. } else {
  396. userMapping := TiDb.FindOne("data_service.user_system", map[string]interface{}{"userid": userid}, "", "")
  397. if userMapping != nil && len(*userMapping) > 0 {
  398. userid = common.ObjToString((*userMapping)["userid"])
  399. uid = common.ObjToString((*userMapping)["uid"])
  400. }
  401. }
  402. if sourceMap[sources] != nil {
  403. sourceData := sourceMap[sources]
  404. source := sourceData["name"]
  405. phone := common.ObjToString(v["phone"])
  406. if IsInternal(phone) {
  407. continue
  408. }
  409. key := fmt.Sprintf("%s_%s", source, phone)
  410. if _, ok := data[key]; ok {
  411. continue
  412. }
  413. data[key] = true
  414. company := common.ObjToString(v["company"])
  415. job := common.ObjToString(v["position"])
  416. username := common.ObjToString(v["name"])
  417. email := common.ObjToString(v["mail"])
  418. interest := common.ObjToString(v["interest"])
  419. data_requirement := common.ObjToString(v["data_requirement"])
  420. belongTo, usernickname := "大客户", ""
  421. userData := TiDb.FindOne("dwd_f_userbase_baseinfo", map[string]interface{}{"uid": uid}, "", "")
  422. if userData != nil {
  423. usernickname = common.ObjToString((*userData)["nickname"])
  424. bt := common.ObjToString((*userData)["belong_to"])
  425. if strings.HasPrefix(bt, "03") || bt == "0102" {
  426. continue
  427. }
  428. }
  429. dataArr = append(dataArr, map[string]interface{}{
  430. "createTime": nowTime,
  431. "lastUpdateTime": nowTime,
  432. "uid": uid,
  433. "userid": userid,
  434. "username": username,
  435. "usernickname": usernickname,
  436. "company": company,
  437. "job": job,
  438. "phone": phone,
  439. "email": email,
  440. "source": source,
  441. "belongTo": belongTo,
  442. "interest": interest,
  443. "data_requirement": data_requirement,
  444. "appoint_email": sourceData["appoint_email"],
  445. "companyType": gconv.String(v["companyType"]),
  446. "industry": gconv.String(v["industry"]),
  447. })
  448. }
  449. if gconv.Int64(v["createtime"]) > bigSaleTime {
  450. bigSaleTime = gconv.Int64(v["createtime"])
  451. }
  452. }
  453. }
  454. cfg.BigSaleTime = bigSaleTime
  455. orderDataSql := `select a.*,b.product_type as productType,b.filter as productFilter,b.final_price from dataexport_order a INNER JOIN
  456. jy_order_detail b on a.order_code=b.order_code
  457. and a.create_time>? and b.product_type in ("数据流量包","历史数据") and a.order_status IN (0,1) AND a.salesperson IS NULL AND a.is_backstage_order = 0 `
  458. orderData := Mysql.SelectBySql(orderDataSql, bigOrderTime)
  459. if orderData != nil && len(*orderData) > 0 {
  460. for _, v := range *orderData {
  461. bigOrderTime = gconv.Time(gconv.String(v["create_time"])).Format(date.Date_Full_Layout)
  462. phone := common.ObjToString(v["user_phone"])
  463. order_status := common.IntAll(v["order_status"])
  464. product_type := common.ObjToString(v["productType"])
  465. orderUserId := gconv.String(v["user_id"])
  466. query := map[string]interface{}{}
  467. if !mongodb.IsObjectIdHex(orderUserId) {
  468. userMapping := TiDb.FindOne("data_service.user_system", map[string]interface{}{"position_id": orderUserId}, "", "")
  469. if userMapping != nil && len(*userMapping) > 0 {
  470. uid := common.ObjToString((*userMapping)["uid"])
  471. query["uid"] = uid
  472. }
  473. } else {
  474. query["userid"] = orderUserId
  475. }
  476. userData := TiDb.FindOne("dwd_f_userbase_baseinfo", query, "", "")
  477. username, usernickname, userid, uid, source, payorderinfo, unpayorderinfo := "", "", "", "", "", "", ""
  478. if userData != nil {
  479. if phone == "" {
  480. phone = common.ObjToString((*userData)["phone"])
  481. }
  482. if IsInternal(phone) {
  483. continue
  484. }
  485. username = common.ObjToString((*userData)["name"])
  486. usernickname = common.ObjToString((*userData)["nickname"])
  487. uid = common.ObjToString((*userData)["uid"])
  488. userid = common.ObjToString((*userData)["userid"])
  489. bt := common.ObjToString((*userData)["belong_to"])
  490. if strings.HasPrefix(bt, "03") || bt == "0102" {
  491. continue
  492. }
  493. }
  494. if product_type == "历史数据" {
  495. if order_status == 0 {
  496. source = "线上历史数据导出未支付订单"
  497. unpayorderinfo = "历史数据"
  498. } else {
  499. source = "线上历史数据导出已支付订单"
  500. payorderinfo = "历史数据" + fmt.Sprint(common.IntAll(v["final_price"])/100)
  501. }
  502. } else {
  503. if order_status == 0 {
  504. source = "线上数据流量包未支付订单"
  505. unpayorderinfo = "数据流量包"
  506. } else {
  507. source = "线上数据流量包已支付订单"
  508. payorderinfo = "数据流量包" + fmt.Sprint(common.IntAll(v["final_price"])/100)
  509. }
  510. }
  511. key := fmt.Sprintf("%s_%s", source, phone)
  512. if _, ok := data[key]; ok {
  513. continue
  514. }
  515. data[key] = true
  516. productFilterMap := gconv.Map(v["productFilter"])
  517. data_count := productFilterMap["pNum"]
  518. dataArr = append(dataArr, map[string]interface{}{
  519. "createTime": nowTime,
  520. "lastUpdateTime": nowTime,
  521. "phone": phone,
  522. "username": username,
  523. "usernickname": usernickname,
  524. "uid": uid,
  525. "userid": userid,
  526. "company": v["company_name"],
  527. "email": v["user_mail"],
  528. "belongTo": "大客户",
  529. "source": source,
  530. "data_count": data_count,
  531. "unpayorderinfo": unpayorderinfo,
  532. "payorderinfo": payorderinfo, //增加客户需求
  533. "appoint_email": "",
  534. })
  535. }
  536. cfg.BigOrderTime = bigOrderTime
  537. }
  538. saveDataToRedis(data, "dk")
  539. xlsxArr := []string{"用户昵称", "姓名", "公司名称", "职位", "联系人电话", "购买条数", "用户邮箱", "已支付订单信息", "未支付订单类型", "销售线索来源", "具体来源", "数据需求"}
  540. if len(dataArr) > 0 {
  541. bigArr := map[string][]map[string]interface{}{}
  542. for _, v := range dataArr {
  543. minemail := ""
  544. if gconv.String(v["appoint_email"]) == "" {
  545. minemail, _ = EmailSelect("dk", "")
  546. } else {
  547. minemail = gconv.String(v["appoint_email"])
  548. }
  549. bigArr[minemail] = append(bigArr[minemail], v)
  550. }
  551. for k, vb := range bigArr {
  552. batch := FindBatch("dk")
  553. fileName, detailName := time.Now().Format(date.Date_Short_Layout)+"-"+batch+"大客户销售线索", ""
  554. xf := xlsx.NewFile()
  555. style := xlsx.NewStyle()
  556. style.Font.Size = 12
  557. style.Font.Bold = true
  558. style.Alignment.Vertical = "center"
  559. style.Alignment.Horizontal = "center"
  560. detailName = time.Now().Format(date.Date_Short_Layout) + "数据详情请查看附件"
  561. sh, _ := xf.AddSheet("线索数据")
  562. row1 := sh.AddRow()
  563. for _, x := range xlsxArr {
  564. cell := row1.AddCell()
  565. cell.SetString(x)
  566. cell.SetStyle(style)
  567. }
  568. for _, v := range vb {
  569. row := sh.AddRow()
  570. row.AddCell().SetString(gconv.String(v["usernickname"]))
  571. row.AddCell().SetString(gconv.String(v["username"]))
  572. row.AddCell().SetString(gconv.String(v["company"]))
  573. row.AddCell().SetString(gconv.String(v["job"]))
  574. row.AddCell().SetString(gconv.String(v["phone"]))
  575. row.AddCell().SetValue(gconv.Int64(v["data_count"]))
  576. row.AddCell().SetString(gconv.String(v["email"]))
  577. row.AddCell().SetString(gconv.String(v["payorderinfo"]))
  578. row.AddCell().SetString(gconv.String(v["unpayorderinfo"]))
  579. row.AddCell().SetString(gconv.String(v["source"]))
  580. row.AddCell().SetString(gconv.String(v["interest"]))
  581. row.AddCell().SetString(gconv.String(v["data_requirement"]))
  582. //增加客户需求
  583. }
  584. email := k
  585. //email = "wanghao@jianyu360.com"
  586. dir := "./xlsx/dk/" + fileName + ".xlsx"
  587. err := xf.Save(dir)
  588. if err != nil {
  589. log.Println("xls error", err, dir)
  590. } else {
  591. status := mail.GSendMail_q("剑鱼标讯", email, "", "", fileName, detailName, dir, fileName+".xlsx", &Gmail)
  592. //往营销里边插入数据
  593. go MarketingSave(vb, email)
  594. if status {
  595. log.Println("send mail success", fileName, email)
  596. }
  597. }
  598. }
  599. }
  600. common.WriteSysConfig(&cfg)
  601. log.Println("大客户线索定时任务结束")
  602. }
  603. func IsInternal(phone string) bool {
  604. if DataAnalysisService.Count("dwd_f_userbase_insider", map[string]interface{}{
  605. "mobile": phone,
  606. }) > 0 {
  607. return true
  608. }
  609. return false
  610. }
  611. func eventReg() {
  612. lastEventRegTime := cfg.LastEventRegTime
  613. sql := fmt.Sprintf(`select * from exhibition_sign_up where is_del = 0 and update_time > "%s" order by update_time asc`, lastEventRegTime)
  614. log.Println("活动报名表定时任务开始", sql)
  615. data := Jyactivities.SelectBySql(sql)
  616. if data != nil && *data != nil && len(*data) > 0 {
  617. for _, v := range *data {
  618. ok1, ok2, _ := FormatData(v, "eventReg")
  619. if !ok1 {
  620. common.WriteSysConfig(&cfg)
  621. log.Println("线索卡点", "eventReg", v, lastEventRegTime)
  622. } else {
  623. if !ok2 {
  624. log.Println("用户分配已达上限", "eventReg", v, lastEventRegTime)
  625. common.WriteSysConfig(&cfg)
  626. }
  627. }
  628. cfg.LastEventRegTime = gconv.String(v["update_time"])
  629. }
  630. }
  631. common.WriteSysConfig(&cfg)
  632. log.Println("活动报名表定时任务结束")
  633. }
  634. func saveHlyj(belong_to, item, phone, name, sourceName, cluename, position, nowTime string, isGroup, isCommerce int) {
  635. if strings.HasPrefix(belong_to, "02") && item == "eventReg" {
  636. saveMap := map[string]interface{}{
  637. "unique_id": phone,
  638. "phone": phone,
  639. "username": name,
  640. "source": sourceName,
  641. "status999": "status5",
  642. "company": cluename,
  643. "job": position,
  644. "belongTo": "市场部",
  645. "createTime": nowTime,
  646. "lastUpdateTime": nowTime,
  647. }
  648. token := getToken()
  649. updateData := map[string]interface{}{
  650. "dbType": "0001",
  651. "customerList": []map[string]interface{}{saveMap},
  652. }
  653. dataByte, _ := json.Marshal(&updateData)
  654. url := `https://a1.7x24cc.com/commonInte?flag=1007&account=N000000029739&accessToken=` + token + `&json=` + url.QueryEscape(string(dataByte))
  655. bs, err := doGet(url)
  656. if err != nil {
  657. log.Println("调用接口失败")
  658. } else {
  659. resMap := common.StringToMap(string(bs))
  660. if resMap["success"] != nil && resMap["success"].(bool) {
  661. saveMap["company_nature"] = isGroup
  662. saveMap["company_verification"] = isCommerce
  663. TiDbData.Insert("customer", saveMap)
  664. } else {
  665. log.Println("新增线索失败")
  666. }
  667. }
  668. }
  669. }
  670. func FindBatch(moudle string) string {
  671. now := time.Now().Format("2006-01-02")
  672. key := fmt.Sprintf("batch_%s_%s", now, moudle)
  673. yesterday := time.Now().AddDate(0, 0, -1).Format("2006-01-02")
  674. yesterdayKey := fmt.Sprintf("batch_%s_%s", yesterday, moudle)
  675. if ok, _ := redis.Exists("newother", yesterdayKey); ok {
  676. //删除之前数据
  677. redis.Del("newother", yesterdayKey)
  678. }
  679. batch := redis.Incr("newother", key)
  680. return fmt.Sprintf("%04d", batch)
  681. }
  682. func FindBatchData(moudle string) map[string]interface{} {
  683. now := time.Now().Format("2006-01-02")
  684. //数据提取
  685. keyContent := fmt.Sprintf("data_%s_%s", now, moudle)
  686. data := redis.Get("newother", keyContent)
  687. if data == nil {
  688. return make(map[string]interface{})
  689. } else {
  690. return gconv.Map(data)
  691. }
  692. }
  693. // 特殊留资
  694. func SpecialSaleLeads() {
  695. /*if !isRunning() {
  696. log.Println("不是工作日,任务暂停")
  697. return
  698. }*/
  699. saleLeadsConfig := TiDb.Find("saleLeads_config", map[string]interface{}{
  700. "status": 0,
  701. }, "", "", -1, -1)
  702. log.Println("特殊留资线索定时任务开始")
  703. for _, v := range *saleLeadsConfig {
  704. log.Println(fmt.Sprintf("%s留资线索定时任务开始", gconv.String(v["groupName"])), gconv.String(v["lastTime"]))
  705. //留来源获取
  706. sourceMap := buildSourceMap(gconv.String(v["groupName"]))
  707. if len(sourceMap) == 0 {
  708. log.Println(fmt.Sprintf("%s留资线索定时任务结束", gconv.String(v["groupName"])))
  709. continue
  710. }
  711. dataArr, endtime := processLeads(v, sourceMap)
  712. //最后一次数据修改
  713. TiDb.Update("saleLeads_config", map[string]interface{}{
  714. "id": gconv.Int64(v["id"]),
  715. }, map[string]interface{}{
  716. "lastTime": endtime,
  717. })
  718. exportToExcel(dataArr, gconv.String(v["title"]), gconv.String(v["groupCode"]), gconv.String(v["mail"]))
  719. log.Println(fmt.Sprintf("%s留资线索定时任务结束", gconv.String(v["groupName"])))
  720. }
  721. log.Println("特殊留资线索定时任务结束")
  722. }
  723. // 判断是否在工作日
  724. func isRunning() bool {
  725. return getRunOk()
  726. }
  727. // 从数据库构建来源映射
  728. func buildSourceMap(department string) map[string]map[string]interface{} {
  729. sourceMap := map[string]map[string]interface{}{}
  730. saleSource := TiDb.SelectBySql(fmt.Sprintf(`SELECT source,name,appoint_email FROM d_saleleads_code WHERE department LIKE '%%%s%%' AND is_delete = 1`, department))
  731. if saleSource != nil {
  732. for _, v := range *saleSource {
  733. source := gconv.String(v["source"])
  734. name := gconv.String(v["name"])
  735. name = filterSourceName(name)
  736. appointEmail := gconv.String(v["appoint_email"])
  737. sourceMap[source] = map[string]interface{}{
  738. "name": name,
  739. "appointEmail": appointEmail,
  740. }
  741. }
  742. }
  743. return sourceMap
  744. }
  745. // 过滤来源名称
  746. func filterSourceName(name string) string {
  747. filterArr := []string{"-pc", "-app", "-wx", "-h5"}
  748. for _, s := range filterArr {
  749. name = strings.ReplaceAll(name, s, "")
  750. }
  751. return name
  752. }
  753. // 获取最后一条数据时间
  754. func getCommitteeTime(cfgTime int64) int64 {
  755. if cfgTime == 0 {
  756. return time.Now().Unix()
  757. }
  758. return cfgTime
  759. }
  760. // 处理留资信息
  761. func processLeads(saleLeadsMap map[string]interface{}, sourceMap map[string]map[string]interface{}) ([]map[string]interface{}, int64) {
  762. batch := gconv.String(saleLeadsMap["groupCode"])
  763. lastTime := gconv.Int64(saleLeadsMap["lastTime"])
  764. dataArr := []map[string]interface{}{}
  765. endtime := lastTime
  766. saleleadsData, ok := Mgo.Find("saleLeads", map[string]interface{}{"createtime": map[string]interface{}{"$gt": lastTime}}, `{"phone":1,"createtime":1}`, nil, false, -1, -1)
  767. if ok && saleleadsData != nil {
  768. data := FindBatchData(batch)
  769. for _, v := range *saleleadsData {
  770. lead := map[string]interface{}{}
  771. lead, endtime = processLead(v, sourceMap, lastTime, data)
  772. if lead != nil {
  773. dataArr = append(dataArr, lead)
  774. }
  775. }
  776. saveDataToRedis(data, batch)
  777. }
  778. return dataArr, endtime
  779. }
  780. // 处理单个线索
  781. func processLead(v map[string]interface{}, sourceMap map[string]map[string]interface{}, lastTime int64, data map[string]interface{}) (map[string]interface{}, int64) {
  782. sources := gconv.String(v["source"])
  783. nowTime := time.Now().Format(date.Date_Full_Layout)
  784. // 更新最后会时间
  785. if gconv.Int64(v["createtime"]) > lastTime {
  786. lastTime = gconv.Int64(v["createtime"])
  787. }
  788. sourceData, exist := sourceMap[sources]
  789. if !exist {
  790. return nil, lastTime
  791. }
  792. phone := gconv.String(v["phone"])
  793. if IsInternal(phone) {
  794. return nil, lastTime
  795. }
  796. // 获取用户信息
  797. if getUserData(v) {
  798. return nil, lastTime
  799. }
  800. key := fmt.Sprintf("%s_%s_%s", sources, phone, common.ObjToString(v["interest"]))
  801. if _, exists := data[key]; exists {
  802. return nil, lastTime
  803. }
  804. data[key] = true
  805. return map[string]interface{}{
  806. "createTime": nowTime,
  807. "createtime": v["createtime"],
  808. "username": gconv.String(v["name"]),
  809. "company": gconv.String(v["company"]),
  810. "phone": phone,
  811. "source": gconv.String(sourceData["name"]),
  812. "belongTo": "咨询组/市场组", // 根据需要修改
  813. "interest": gconv.String(v["interest"]),
  814. "data_requirement": gconv.String(v["data_requirement"]),
  815. "branch": v["branch"],
  816. "job": v["position"],
  817. "email": gconv.String(v["mail"]),
  818. "appointEmail": gconv.String(sourceData["appointEmail"]),
  819. }, lastTime
  820. }
  821. // 获取用户数据
  822. func getUserData(v map[string]interface{}) bool {
  823. userid := gconv.String(v["userid"])
  824. userMapping := &map[string]interface{}{}
  825. if !mongodb.IsObjectIdHex(userid) {
  826. userMapping = TiDb.FindOne("data_service.user_system", map[string]interface{}{"position_id": userid}, "", "")
  827. } else {
  828. userMapping = TiDb.FindOne("data_service.user_system", map[string]interface{}{"userid": userid}, "", "")
  829. }
  830. if userMapping == nil || len(*userMapping) == 0 {
  831. return false
  832. }
  833. uid := gconv.String((*userMapping)["uid"])
  834. userData := TiDb.FindOne("dwd_f_userbase_baseinfo", map[string]interface{}{"uid": uid}, "", "")
  835. if userData != nil {
  836. bt := common.ObjToString((*userData)["belong_to"])
  837. if strings.HasPrefix(bt, "03") || bt == "0102" {
  838. return true
  839. }
  840. }
  841. return false
  842. }
  843. // 判断用户是否在黑名单
  844. func isUserInBlackList(userData map[string]interface{}) bool {
  845. bt := gconv.String(userData["belong_to"])
  846. return strings.HasPrefix(bt, "03") || bt == "0102"
  847. }
  848. // 判断是否是安博会线索
  849. func isABHLead(lead map[string]interface{}) bool {
  850. s_sourceid := gconv.String(lead["s_sourceid"])
  851. return s_sourceid == db.Sourceid
  852. }
  853. // 导出到 Excel
  854. func exportToExcel(dataArr []map[string]interface{}, title, batch, mails string) {
  855. if len(dataArr) == 0 {
  856. return
  857. }
  858. bigArr := map[string][]map[string]interface{}{}
  859. for _, v := range dataArr {
  860. appointEmail := gconv.String(v["appointEmail"])
  861. if appointEmail == "" {
  862. appointEmail, _ = EmailSelect(batch, mails)
  863. }
  864. bigArr[appointEmail] = append(bigArr[appointEmail], v)
  865. }
  866. for email, arr := range bigArr {
  867. data := FindBatch(batch)
  868. xlsxArr := []string{"姓名", "联系方式", "职位", "部门", "邮箱", "公司名称", "咨询需求", "销售线索来源", "具体来源", "留资时间"}
  869. fileName, detailName := fmt.Sprintf("%s %s-%s", title, time.Now().Format(date.Date_Short_Layout), data), "今日新增销售线索,请查收附件,及时跟进。"
  870. xf := xlsx.NewFile()
  871. style := xlsx.NewStyle()
  872. style.Font.Size = 12
  873. style.Font.Bold = true
  874. style.Alignment.Vertical = "center"
  875. style.Alignment.Horizontal = "center"
  876. sh, _ := xf.AddSheet("线索数据")
  877. row1 := sh.AddRow()
  878. for _, x := range xlsxArr {
  879. cell := row1.AddCell()
  880. cell.SetString(x)
  881. cell.SetStyle(style)
  882. }
  883. for _, v := range arr {
  884. row := sh.AddRow()
  885. row.AddCell().SetString(gconv.String(v["username"]))
  886. row.AddCell().SetString(gconv.String(v["phone"]))
  887. row.AddCell().SetString(gconv.String(v["job"]))
  888. row.AddCell().SetString(gconv.String(v["branch"]))
  889. row.AddCell().SetString(gconv.String(v["email"]))
  890. row.AddCell().SetString(gconv.String(v["company"]))
  891. row.AddCell().SetString(gconv.String(v["data_requirement"]))
  892. row.AddCell().SetString(gconv.String(v["source"]))
  893. row.AddCell().SetString(gconv.String(v["interest"]))
  894. row.AddCell().SetString(gconv.Time(gconv.Int64(v["createtime"])).Format(date.Date_Full_Layout))
  895. }
  896. dir := fmt.Sprintf("./xlsx/%s/%s.xlsx", batch, fileName)
  897. // 确保目录存在(自动创建)
  898. dirPath := filepath.Dir(dir) // 提取目录部分(如 "./xlsx/batch")
  899. if err := os.MkdirAll(dirPath, 0755); err != nil {
  900. log.Println("创建目录失败:", err)
  901. return
  902. }
  903. if err := xf.Save(dir); err != nil {
  904. log.Println("xls error", err, dir)
  905. return
  906. }
  907. sendEmail(fileName, detailName, dir, email)
  908. }
  909. }
  910. // 发送邮件
  911. func sendEmail(fileName, detailName, dir, email string) {
  912. gmail := &mail.GmailAuth{
  913. SmtpHost: db.Mail.SmtpHost,
  914. SmtpPort: db.Mail.SmtpPort,
  915. User: db.Mail.User,
  916. Pwd: db.Mail.Pwd,
  917. }
  918. if status := mail.GSendMail_q("剑鱼标讯", email, "", "", fileName, detailName, dir, fileName+".xlsx", gmail); status {
  919. log.Println("send mail success", fileName, email)
  920. }
  921. }
  922. // 保存数据到 Redis
  923. func saveDataToRedis(data map[string]interface{}, batch string) {
  924. keyContent := fmt.Sprintf("data_%s_%s", time.Now().Format("2006-01-02"), batch)
  925. redis.Put("newother", keyContent, data, 86400)
  926. }
  927. // 邮箱选择处理
  928. func EmailSelect(batch, mailStr string) (string, string) {
  929. name := ""
  930. minemail := ""
  931. bigData := TiDb.SelectBySql("select * from dwd_f_crm_clue_big_autodraw_record where type =? ", batch)
  932. if bigData != nil && len(*bigData) > 0 {
  933. //查看有没有新增人员 人名-邮箱,邮箱|人名-邮箱,
  934. mailMap := map[string]string{}
  935. if mailStr != "" {
  936. for _, s := range strings.Split(mailStr, "|") {
  937. if len(strings.Split(s, "-")) > 1 {
  938. arr := strings.Split(s, "-")
  939. personName := arr[0]
  940. mailMap[personName] = arr[1]
  941. }
  942. }
  943. for personName, mail := range mailMap {
  944. isOk := false
  945. for _, m := range *bigData {
  946. tablePersonName := gconv.String(m["name"])
  947. if tablePersonName == personName {
  948. isOk = true
  949. }
  950. }
  951. if !isOk {
  952. rData := TiDb.FindOne("dwd_f_crm_clue_big_autodraw_record", map[string]interface{}{
  953. "type": batch,
  954. }, "", "count desc")
  955. //这是一个新人
  956. TiDb.Insert("dwd_f_crm_clue_big_autodraw_record", map[string]interface{}{
  957. "name": personName,
  958. "count": common.Int64All((*rData)["count"]),
  959. "email": mail,
  960. "type": batch,
  961. })
  962. return minemail, name
  963. }
  964. }
  965. }
  966. mincount := common.IntAll((*bigData)[0]["count"])
  967. for _, vv := range *bigData {
  968. vcount := common.IntAll(vv["count"])
  969. vemail := gconv.String(vv["email"])
  970. vName := gconv.String(vv["name"])
  971. if vcount <= mincount {
  972. mincount = vcount
  973. minemail = vemail
  974. name = vName
  975. }
  976. }
  977. } else {
  978. for k, s := range strings.Split(mailStr, "|") {
  979. if len(strings.Split(s, "-")) > 1 {
  980. arr := strings.Split(s, "-")
  981. if k == 0 {
  982. minemail, name = arr[1], arr[0]
  983. }
  984. personName := arr[0]
  985. TiDb.Insert("dwd_f_crm_clue_big_autodraw_record", map[string]interface{}{
  986. "name": personName,
  987. "count": 0,
  988. "email": arr[1],
  989. "type": batch,
  990. })
  991. }
  992. }
  993. }
  994. TiDb.UpdateOrDeleteBySql(`update dwd_f_crm_clue_big_autodraw_record set count = count + 1 where name = ? and type=?`, name, batch)
  995. return minemail, name
  996. }
  997. // 进入营销处理
  998. func MarketingSave(data []map[string]interface{}, email string) {
  999. personData := TiDb.FindOne("dwd_f_crm_clue_big_autodraw_record", map[string]interface{}{
  1000. "type": "dk",
  1001. "email": email,
  1002. }, "", "")
  1003. if personData == nil || len(*personData) == 0 {
  1004. log.Println("大客用户获取失败")
  1005. return
  1006. }
  1007. positionId := gconv.Int64((*personData)["position_id"])
  1008. name := gconv.String((*personData)["name"])
  1009. userMapping := TiDb.FindOne("data_service.user_system", map[string]interface{}{"position_id": positionId, "status": 1}, "", "")
  1010. if userMapping == nil || len(*userMapping) == 0 {
  1011. log.Println("大客用户信息获取失败")
  1012. return
  1013. }
  1014. entId := gconv.Int64((*userMapping)["ent_id"])
  1015. entUserId := gconv.Int64((*userMapping)["ent_user_id"])
  1016. CrmService.ExecTx("", func(tx *sql.Tx) bool {
  1017. for _, v := range data {
  1018. remarkFields := []string{
  1019. fmt.Sprintf("%s :%s", "提交时间", gconv.String(v["createTime"])),
  1020. fmt.Sprintf("%s :%s", "销售线索来源", gconv.String(v["source"])),
  1021. fmt.Sprintf("%s :%s", "具体来源", gconv.String(v["interest"])),
  1022. fmt.Sprintf("%s :%s", "姓名", common.If(gconv.String(v["username"]) == "", gconv.String(v["phone"]), gconv.String(v["username"]))),
  1023. fmt.Sprintf("%s :%s", "手机号", gconv.String(v["phone"])),
  1024. fmt.Sprintf("%s :%s", "公司名称", gconv.String(v["company"])),
  1025. fmt.Sprintf("%s :%s", "数据需求", gconv.String(v["data_requirement"])),
  1026. fmt.Sprintf("%s :%s", "邮箱", gconv.String(v["email"])),
  1027. fmt.Sprintf("%s :%s", "公司类型", gconv.String(v["companyType"])),
  1028. fmt.Sprintf("%s :%s", "职位", gconv.String(v["job"])),
  1029. fmt.Sprintf("%s :%s", "行业", gconv.String(v["industry"])),
  1030. }
  1031. filterStr := strings.Join(remarkFields, "\n")
  1032. //线索保存
  1033. clueId := CrmService.InsertByTx(tx, "sale_clue", map[string]interface{}{
  1034. "position_id": positionId,
  1035. "ent_id": entId,
  1036. "ent_user_id": entUserId,
  1037. "employ_info_id": 0,
  1038. "name": common.If(gconv.String(v["company"]) == "", gconv.String(v["phone"]), gconv.String(v["company"])),
  1039. "source_BAK": "",
  1040. "summary": common.If(gconv.String(v["company"]) == "", gconv.String(v["phone"]), gconv.String(v["company"])),
  1041. "is_close": 0,
  1042. "close_reason_classify": nil,
  1043. "close_reason_desc": nil,
  1044. "create_person": name,
  1045. "create_time": time.Now().Format(date.Date_Full_Layout),
  1046. "channel": "剑鱼平台提交兴趣点",
  1047. "source": gconv.String(v["source"]),
  1048. })
  1049. //任务保存
  1050. taskId := CrmService.InsertByTx(tx, "task", map[string]interface{}{
  1051. "ent_id": entId,
  1052. "name": common.If(gconv.String(v["username"]) == "", gconv.String(v["phone"]), gconv.String(v["username"])),
  1053. "source": 1,
  1054. "source_id": clueId,
  1055. "create_way": 2,
  1056. "status": 2,
  1057. "create_time": time.Now().Format(date.Date_Full_Layout),
  1058. "join_task_vehicle": 0,
  1059. "remark": filterStr,
  1060. })
  1061. if taskId <= 0 {
  1062. return false
  1063. }
  1064. //任务划转处理
  1065. CrmService.InsertByTx(tx, "task_transfer", map[string]interface{}{
  1066. "task_id": taskId,
  1067. "transfer_id": positionId,
  1068. "responsible_id": positionId,
  1069. "is_transfer": 0,
  1070. "create_time": time.Now().Format(date.Date_Full_Layout),
  1071. })
  1072. //任务团队
  1073. CrmService.InsertByTx(tx, "task_team", map[string]interface{}{
  1074. "task_id": taskId,
  1075. "position_id": positionId,
  1076. "ent_user_id": entUserId,
  1077. "name": name,
  1078. "role": 1,
  1079. "create_time": time.Now().Format(date.Date_Full_Layout),
  1080. })
  1081. }
  1082. return true
  1083. })
  1084. return
  1085. }