kc.go 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290
  1. package main
  2. import (
  3. "app.yhyue.com/moapp/jybase/mail"
  4. "database/sql"
  5. "encoding/json"
  6. "fmt"
  7. "log"
  8. "strings"
  9. "time"
  10. "github.com/gogf/gf/v2/util/gconv"
  11. "app.yhyue.com/moapp/jybase/common"
  12. "app.yhyue.com/moapp/jybase/date"
  13. "app.yhyue.com/moapp/jybase/mongodb"
  14. )
  15. func kcSync() {
  16. log.Println("客户成功系统移交定时任务开始")
  17. sql := `select * from dwd_f_userbase_order_info where (payable_money > 0 or (payable_money=0 and ( filter like "%分期付款补充权益%" or filter like "%原订单不支持开通多项权益%" or filter like "%权益码兑换%")))
  18. and data_spec!="dhy4" and order_status=1 and (refund_status!=1 or refund_status is null ) and vip_starttime<"2099-01-01"
  19. and vip_endtime > "` + time.Now().Format(date.Date_Full_Layout) + `" and autoUpdate > "` + cfg.LastkcTime + `" order by autoUpdate asc`
  20. //sql := `select * from dwd_f_userbase_order_info where order_code="152504013602" `
  21. data := TiDb.SelectBySql(sql)
  22. if data != nil && *data != nil && len(*data) > 0 {
  23. arr := []string{}
  24. for _, v := range *data {
  25. product_type := common.ObjToString(v["product_type"])
  26. vip_starttime := common.ObjToString(v["vip_starttime"])
  27. vip_endtime := common.ObjToString(v["vip_endtime"])
  28. order_change := gconv.Int64(v["order_change"])
  29. if (product_type == "大会员" || product_type == "企业商机管理") && ((order_change != 0) || (order_change == 0 && TimeStrcount(vip_starttime, vip_endtime) > 95)) {
  30. orderCode := gconv.String(v["order_code"])
  31. arr = append(arr, orderCode)
  32. status := kcJob(v)
  33. if status == 0 {
  34. break
  35. }
  36. }
  37. cfg.LastkcTime = common.ObjToString(v["autoUpdate"])
  38. }
  39. log.Println(strings.Join(arr, "`,`"))
  40. }
  41. common.WriteSysConfig(&cfg)
  42. log.Println("客户成功系统移交定时任务结束")
  43. }
  44. func kcJob(data map[string]interface{}) int {
  45. nowTime := time.Now().Format(date.Date_Full_Layout)
  46. uId, entId, clueId, saveMap, status := common.ObjToString(data["uid"]), fmt.Sprint(data["ent_id"]), int64(0), map[string]interface{}{}, 1
  47. clueData := TiDb.FindOne("dwd_f_crm_clue_info", map[string]interface{}{"uid": uId}, "", "")
  48. orderCode := gconv.String(data["order_code"])
  49. saleDep, orderPositionId, salesperson := FindSaleRecord(orderCode)
  50. log.Println(data["order_code"], saleDep, orderPositionId, salesperson)
  51. if clueData == nil || len(*clueData) == 0 {
  52. if saleDep == "销售部" || saleDep == "市场部" {
  53. return 1
  54. }
  55. //创建线索
  56. //原始订单获取
  57. position_id := int64(0)
  58. orderData := Mysql.FindOne("dataexport_order", map[string]interface{}{
  59. "order_code": orderCode,
  60. }, "", "")
  61. if orderData == nil {
  62. log.Println("原始订单查询不到:", orderCode)
  63. }
  64. userId, cluename, phone := common.ObjToString((*orderData)["user_id"]), "", ""
  65. seatNumber := ""
  66. if saleDep == "客户成功组" {
  67. //新增线索
  68. position_id = 0
  69. } else if saleDep == "销售部" {
  70. log.Println("该订单数据销售部业绩,不会创建线索")
  71. return 0
  72. } else {
  73. position_id = orderPositionId
  74. //其他信息
  75. seatNumber = "0000"
  76. }
  77. cluename = common.ObjToString(data["company_name"])
  78. phone = common.ObjToString(data["user_phone"])
  79. if cluename == "" {
  80. cluename = phone
  81. }
  82. trailstatus := "08"
  83. isGroup, isCommerce := GetCompanyType(cluename, uId) //判断是否集团公司、工商库
  84. clueId = TiDb.Insert("dwd_f_crm_clue_info", map[string]interface{}{
  85. "userid": userId,
  86. "uid": uId,
  87. "is_assign": common.If(position_id > 0, 1, 0),
  88. "createtime": nowTime,
  89. "updatetime": nowTime,
  90. "cluename": cluename,
  91. "seatNumber": seatNumber,
  92. "position_id": position_id,
  93. "top_cluetype": "4",
  94. "sub_cluetype": "154",
  95. "trailstatus": trailstatus,
  96. "name": phone,
  97. "phone": phone,
  98. "is_task": 0,
  99. "taskstatus": 0,
  100. "company_nature": isGroup,
  101. "company_verification": isCommerce,
  102. "FREEZE_TIME": nowTime,
  103. "label": common.If(position_id > 0, 1, nil),
  104. })
  105. if clueId > 0 {
  106. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  107. "clue_id": clueId,
  108. "position_id": common.If(position_id > 0, position_id, -1),
  109. "change_type": "创建线索",
  110. "new_value": "系统自动创建",
  111. "createtime": nowTime,
  112. "BCPCID": common.GetRandom(32),
  113. "operator_id": -1,
  114. })
  115. clueData = TiDb.FindOne("dwd_f_crm_clue_info", map[string]interface{}{"uid": uId}, "", "")
  116. if clueData == nil || len(*clueData) == 0 {
  117. return 0
  118. }
  119. } else {
  120. return 1
  121. }
  122. }
  123. clueId = common.Int64All((*clueData)["id"])
  124. starttime := common.ObjToString(data["vip_starttime"])
  125. endtime := common.ObjToString(data["vip_endtime"])
  126. buy_subject := common.IntAll(data["buy_subject"])
  127. product_type := common.ObjToString(data["product_type"])
  128. data_spec := common.ObjToString(data["data_spec"])
  129. userName := common.ObjToString((*clueData)["name"])
  130. product, company_name := 0, common.ObjToString(data["company_name"])
  131. productMap := map[string]int{
  132. "dhy6": 1,
  133. "dhy7": 2,
  134. "dhy3": 4,
  135. "dhy1": 5,
  136. "dhy2": 6,
  137. "dhy5": 7,
  138. "企业商机管理": 8,
  139. }
  140. if buy_subject == 1 || buy_subject == 0 {
  141. entId = common.ObjToString(data["userid"])
  142. }
  143. if product_type == "企业商机管理" {
  144. product = productMap[product_type]
  145. powerData := TiDb.FindOne("dwd_f_data_equity_info", map[string]interface{}{"uid": uId, "product_type": "商机管理"}, "", "comeintime desc")
  146. if powerData != nil {
  147. starttime = common.ObjToString((*powerData)["starttime"])
  148. endtime = common.ObjToString((*powerData)["endtime"])
  149. } else {
  150. log.Println("客成移交权限未查到--", uId)
  151. return 0
  152. }
  153. } else {
  154. if data_spec == "dhy6" {
  155. product = 1
  156. filter := common.ObjToString(data["filter"])
  157. filterMap := map[string]interface{}{}
  158. json.Unmarshal([]byte(filter), &filterMap)
  159. if len(filterMap) > 0 {
  160. areaCount := common.IntAll(filterMap["areaCount"])
  161. if areaCount == 1 {
  162. product = 3
  163. }
  164. }
  165. } else {
  166. product = productMap[data_spec]
  167. }
  168. }
  169. //同一公司名称(以客户详情-组织机构-公司名称)下的线索需分配给同1人
  170. saveMap = map[string]interface{}{
  171. "clue_id": clueId,
  172. "transfertime": nowTime,
  173. "service_starttime": starttime,
  174. "service_endtime": endtime,
  175. "ent_id": entId,
  176. "is_task": 1,
  177. "tasktime": nowTime,
  178. "taskstatus": 0,
  179. "tasksource": "1",
  180. "is_admin": 1,
  181. "product_access": product,
  182. "buy_subject": buy_subject,
  183. "relationship_building_way": 1,
  184. "inventory_way": 1,
  185. "training_way": 1,
  186. "is_pre_sales_training": 0,
  187. "service_stage": 1,
  188. "company_name": company_name,
  189. }
  190. if TiDb.Count("dwd_f_csm_customer_info", map[string]interface{}{"clue_id": clueId}) > 0 {
  191. csmdata := TiDb.FindOne("dwd_f_csm_customer_info", map[string]interface{}{"clue_id": clueId}, "", "")
  192. if csmdata != nil && len(*csmdata) > 0 {
  193. id := gconv.Int64((*csmdata)["id"])
  194. log.Println(1111111, id, orderCode)
  195. //'已移交销售,0移交客成 1移交销售',
  196. is_transfer := gconv.Int64((*csmdata)["is_transfer"])
  197. customerPositionId, customerName := cAutoDraw(0, orderPositionId, salesperson, saleDep, true, csmdata)
  198. log.Println("移交客成positionId", customerPositionId, customerName, saleDep, orderPositionId, salesperson, true)
  199. oldName := gconv.String((*csmdata)["name"])
  200. updateMap := map[string]interface{}{
  201. "is_transfer": 0,
  202. "is_renewal_protection": 0,
  203. "product_access": product,
  204. "buy_subject": buy_subject,
  205. "transfertime": nowTime,
  206. "service_starttime": starttime,
  207. "service_endtime": endtime,
  208. "ent_id": entId,
  209. "company_name": company_name,
  210. "name": customerName,
  211. "position_id": customerPositionId,
  212. }
  213. if is_transfer == 1 {
  214. //重新进去
  215. updateMap["relationship_building_way"] = 1
  216. updateMap["tasksource"] = "1"
  217. updateMap["inventory_way"] = 1
  218. updateMap["training_way"] = 1
  219. updateMap["is_pre_sales_training"] = 0
  220. updateMap["service_stage"] = 1
  221. updateMap["is_task"] = 1
  222. }
  223. TiDb.Update("dwd_f_csm_customer_info", map[string]interface{}{"clue_id": clueId}, updateMap)
  224. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  225. "clue_id": clueId,
  226. "position_id": customerPositionId,
  227. "change_type": "成交客户移交",
  228. "new_value": "移交至客户成功组",
  229. "createtime": nowTime,
  230. "BCPCID": common.GetRandom(32),
  231. "operator_id": -1,
  232. })
  233. if customerPositionId > 0 && is_transfer == 1 {
  234. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  235. "clue_id": clueId,
  236. "position_id": customerPositionId,
  237. "change_field": "position_id",
  238. "change_type": "客户成功经理",
  239. "old_value": common.If(oldName != customerName, customerName, common.If(oldName == "", "/", oldName)),
  240. "new_value": customerName,
  241. "createtime": nowTime,
  242. "BCPCID": common.GetRandom(32),
  243. "operator_id": -1,
  244. })
  245. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  246. "clue_id": clueId,
  247. "position_id": customerPositionId,
  248. "change_type": "加入任务车",
  249. "new_value": "未建联",
  250. "createtime": nowTime,
  251. "BCPCID": common.GetRandom(32),
  252. "operator_id": -1,
  253. })
  254. }
  255. KcSend(orderCode, customerName)
  256. TiDb.Update("dwd_f_crm_clue_info", map[string]interface{}{"id": clueId}, map[string]interface{}{"is_transfer": 1, "updatetime": nowTime, "name": userName})
  257. }
  258. } else {
  259. entIds := common.IntAll(data["ent_id"])
  260. customerPositionId, customerName := cAutoDraw(entIds, orderPositionId, salesperson, saleDep, false, nil)
  261. log.Println("移交客成positionId", customerPositionId, customerName, saleDep, orderPositionId, salesperson, false)
  262. cId, ok, updateId1, updateId2, updateId3 := int64(0), false, int64(0), int64(0), int64(0)
  263. if TiDb.ExecTx("保存客户", func(tx *sql.Tx) bool {
  264. saveMap["position_id"] = customerPositionId
  265. saveMap["name"] = customerName
  266. cId = TiDb.InsertByTx(tx, "dwd_f_csm_customer_info", saveMap)
  267. ok = TiDb.UpdateByTx(tx, "dwd_f_crm_clue_info", map[string]interface{}{"id": clueId}, map[string]interface{}{"is_transfer": 1, "updatetime": nowTime, "name": userName})
  268. if customerPositionId > 0 {
  269. updateId1 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  270. "clue_id": clueId,
  271. "position_id": customerPositionId,
  272. "change_type": "加入任务车",
  273. "new_value": "未建联",
  274. "createtime": nowTime,
  275. "BCPCID": common.GetRandom(32),
  276. "operator_id": -1,
  277. })
  278. updateId3 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  279. "clue_id": clueId,
  280. "position_id": customerPositionId,
  281. "change_field": "position_id",
  282. "change_type": "客户成功经理",
  283. "old_value": "/",
  284. "new_value": customerName,
  285. "createtime": nowTime,
  286. "BCPCID": common.GetRandom(32),
  287. "operator_id": -1,
  288. })
  289. }
  290. KcSend(orderCode, customerName)
  291. updateId2 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  292. "clue_id": clueId,
  293. "position_id": customerPositionId,
  294. "change_type": "成交客户移交",
  295. "new_value": "移交至客户成功组",
  296. "createtime": nowTime,
  297. "BCPCID": common.GetRandom(32),
  298. "operator_id": -1,
  299. })
  300. return cId > -1 && ok && updateId1 > -1 && updateId2 > -1 && updateId3 > -1
  301. }) {
  302. //TiDb.UpdateOrDeleteBySql(`update dwd_f_csm_customer_autodraw_record set count = count + 1 where name = ?`, name)
  303. log.Println("保存客户成功")
  304. } else {
  305. log.Println("保存客户失败!!!", clueId, cId, ok, updateId1, updateId2, updateId3, " 用户信息 ", customerName, customerPositionId, uId)
  306. }
  307. }
  308. return status
  309. }
  310. func cAutoDraw(entId int, orderPositionId int64, salesperson, saleDep string, isExist bool, csmdata *map[string]interface{}) (positionId int64, name string) {
  311. query := `SELECT name,position_id FROM dwd_d_crm_department_level_succbi WHERE bi_pcode = (SELECT bi_code FROM dwd_d_crm_department_level_succbi WHERE name = "客户成功部" and resign=0) and resign = 0 `
  312. data := TiDb.SelectBySql(query)
  313. if data == nil || len(*data) == 0 {
  314. return
  315. }
  316. //判断是否需要新增客成数据
  317. if isExist {
  318. //用户存在客成数据
  319. positionid := common.Int64All((*csmdata)["position_id"])
  320. if positionid != 0 {
  321. //以前没有,需要找一个新的
  322. for _, v := range *data {
  323. deptPositionId := gconv.Int64(v["position_id"])
  324. if deptPositionId == positionid {
  325. positionId = positionid
  326. name = common.ObjToString((*csmdata)["name"])
  327. return
  328. }
  329. }
  330. }
  331. //原始用户已离职 查看订单是否有合适的订单
  332. if saleDep == "客户成功组" {
  333. positionId = orderPositionId
  334. name = salesperson
  335. return
  336. }
  337. }
  338. //客成数据不存在的时候
  339. //查找企业有没有其他信息
  340. if entId > 0 {
  341. entdata := TiDb.Find("dwd_f_csm_customer_info", map[string]interface{}{"ent_id": entId}, "", "", -1, -1)
  342. if entdata != nil && len(*entdata) > 0 {
  343. for _, v := range *entdata {
  344. positionid := common.Int64All(v["position_id"])
  345. name = common.ObjToString(v["name"])
  346. for _, v := range *data {
  347. deptPositionId := gconv.Int64(v["position_id"])
  348. if deptPositionId == positionId {
  349. positionId = positionid
  350. name = common.ObjToString((*csmdata)["name"])
  351. return
  352. }
  353. }
  354. }
  355. }
  356. //原始用户已离职 或者没有查找相关企业客成信息 以订单信息为主
  357. if saleDep == "客户成功组" {
  358. positionId = orderPositionId
  359. name = salesperson
  360. }
  361. return
  362. //没有相同企业的客成信息
  363. } else {
  364. //没有人 分配给自己
  365. if saleDep == "客户成功组" {
  366. positionId = orderPositionId
  367. name = salesperson
  368. return
  369. }
  370. return
  371. }
  372. }
  373. func kcAuto() {
  374. log.Println("客户成功系统自动进入任务车定时任务开始")
  375. nowTime := time.Now().Format(date.Date_Full_Layout)
  376. sql := `select * from dwd_f_csm_customer_info where ((relationship_building_way != 1 and inventory_way = 1) or (inventory_way != 1 and training_way = 1)) and is_task = 0`
  377. data := TiDb.SelectBySql(sql)
  378. if data != nil && *data != nil && len(*data) > 0 {
  379. for _, v := range *data {
  380. relationship_building_way := common.IntAll(v["relationship_building_way"])
  381. inventory_way := common.IntAll(v["inventory_way"])
  382. training_way := common.IntAll(v["training_way"])
  383. positionId := common.Int64All(v["position_id"])
  384. clueId := common.Int64All(v["clue_id"])
  385. tasksource, tasksources := common.ObjToString(v["tasksource"]), ""
  386. taskstatus := common.IntAll(v["taskstatus"])
  387. if relationship_building_way != 1 && inventory_way == 1 {
  388. tasksources = "2"
  389. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  390. "clue_id": clueId,
  391. "position_id": positionId,
  392. "change_type": "加入任务车",
  393. "new_value": "未盘点",
  394. "createtime": nowTime,
  395. "BCPCID": common.GetRandom(32),
  396. "operator_id": -1,
  397. })
  398. } else if inventory_way != 1 && training_way == 1 {
  399. tasksources = "3"
  400. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  401. "clue_id": clueId,
  402. "position_id": positionId,
  403. "change_type": "加入任务车",
  404. "new_value": "未培训",
  405. "createtime": nowTime,
  406. "BCPCID": common.GetRandom(32),
  407. "operator_id": -1,
  408. })
  409. }
  410. if taskstatus == 1 {
  411. tasksource = tasksources
  412. } else {
  413. if tasksource != "" {
  414. if !strings.Contains(tasksource, tasksources) {
  415. tasksource += "," + tasksources
  416. }
  417. } else {
  418. tasksource = tasksources
  419. }
  420. }
  421. TiDb.Update("dwd_f_csm_customer_info", map[string]interface{}{"clue_id": clueId}, map[string]interface{}{
  422. "tasksource": tasksource,
  423. "tasktime": nowTime,
  424. "is_task": 1,
  425. "taskstatus": 0,
  426. })
  427. }
  428. }
  429. log.Println("客户成功系统进入任务车定时任务结束")
  430. }
  431. func ordersClue() {
  432. log.Println("后台订单线索定时任务开始")
  433. lastOrderClueId := cfg.LastOrderClueId
  434. nowTime := time.Now().Format(date.Date_Full_Layout)
  435. sql := fmt.Sprintf(`select order_code,order_status,is_backstage_order,pay_money,saleDep,salesperson,user_phone,create_person,saleMoney,user_id,product_type,company_name,autoUpdate from dataexport_order where autoUpdate >= "%s" order by autoUpdate asc`, lastOrderClueId)
  436. data := Mysql.SelectBySql(sql)
  437. if data != nil && *data != nil && len(*data) > 0 {
  438. for _, v := range *data {
  439. order_status := common.IntAll(v["order_status"])
  440. is_backstage_order := common.IntAll(v["is_backstage_order"])
  441. pay_money := common.IntAll(v["pay_money"])
  442. orderCode := gconv.String(v["order_code"])
  443. saleDep, _, salesperson := FindSaleRecord(orderCode)
  444. user_phone := common.ObjToString(v["user_phone"])
  445. createperson := common.ObjToString(v["create_person"])
  446. userId, uId, cluename, seatNumber, positionId, trailstatus, clueId := common.ObjToString(v["user_id"]), "", "", "", int64(0), "", int64(0)
  447. product_type_str2 := `"大会员","企业商机管理","VIP订阅"`
  448. product_type := common.ObjToString(v["product_type"])
  449. if order_status == 1 && is_backstage_order == 1 && saleDep != "" && !strings.HasPrefix(user_phone, "9") && strings.Contains(product_type_str2, product_type) {
  450. //销售部
  451. query := map[string]interface{}{}
  452. source := ""
  453. if product_type == "企业商机管理" {
  454. query["phone"] = user_phone
  455. userInfo := TiDb.FindOne("dwd_f_userbase_baseinfo", query, "", "")
  456. if userInfo != nil && len(*userInfo) > 0 {
  457. uId = common.ObjToString((*userInfo)["uid"])
  458. userId = common.ObjToString((*userInfo)["userid"])
  459. source = common.ObjToString((*userInfo)["source"])
  460. } else {
  461. log.Println("后台订单--未查询到 ", user_phone)
  462. break
  463. }
  464. } else {
  465. if !mongodb.IsObjectIdHex(userId) {
  466. userMapping := TiDb.FindOne("dwd_f_userbase_id_mapping", map[string]interface{}{"position_id": userId}, "", "")
  467. if userMapping != nil && len(*userMapping) > 0 {
  468. userId = common.ObjToString((*userMapping)["userid"])
  469. } else {
  470. log.Println("后台订单--未查询到 ", user_phone)
  471. break
  472. }
  473. }
  474. query["userid"] = userId
  475. userInfo := TiDb.FindOne("dwd_f_userbase_baseinfo", query, "", "")
  476. if userInfo != nil && len(*userInfo) > 0 {
  477. uId = common.ObjToString((*userInfo)["uid"])
  478. source = common.ObjToString((*userInfo)["source"])
  479. } else {
  480. log.Println("后台订单--未查询到 ", query, user_phone)
  481. break
  482. }
  483. }
  484. is_assign := 1
  485. mailContent := ""
  486. cluename = common.ObjToString(v["company_name"])
  487. mailContent = fmt.Sprintf("%s(%s)", cluename, user_phone)
  488. if cluename == "" {
  489. cluename = user_phone
  490. mailContent = user_phone
  491. }
  492. if pay_money > 0 {
  493. trailstatus = "08"
  494. } else {
  495. trailstatus = "01"
  496. }
  497. isGroup, isCommerce := GetCompanyType(cluename, uId) //判断是否集团公司、工商库
  498. clueData := TiDb.FindOne("dwd_f_crm_clue_info", map[string]interface{}{"uid": uId}, "", "")
  499. if clueData == nil || len(*clueData) == 0 {
  500. log.Println("saleDep", saleDep)
  501. if saleDep == "销售部" {
  502. //撞单
  503. log.Println("销售部订单", saleDep)
  504. if strings.Contains(salesperson, ",") {
  505. log.Println("销售部撞单 ", salesperson)
  506. if salesperson == "" {
  507. salesperson = createperson
  508. }
  509. }
  510. log.Println("销售部订单salesperson", salesperson)
  511. saleData := TiDb.FindOne("dwd_f_crm_personnel_management", map[string]interface{}{"name": salesperson}, "", "")
  512. if saleData != nil {
  513. seatNumber = common.ObjToString((*saleData)["seat_number"])
  514. positionId = common.Int64All((*saleData)["position_id"])
  515. }
  516. if IsFreeze(source, pay_money, gconv.String(positionId), trailstatus) {
  517. //线索需要冻结
  518. is_assign = -3
  519. }
  520. clueId = TiDb.Insert("dwd_f_crm_clue_info", map[string]interface{}{
  521. "userid": userId,
  522. "uid": uId,
  523. "seatNumber": seatNumber,
  524. "position_id": positionId,
  525. "is_assign": is_assign,
  526. "comeintime": nowTime,
  527. "createtime": nowTime,
  528. "updatetime": nowTime,
  529. "cluename": cluename,
  530. "top_cluetype": "4",
  531. "sub_cluetype": "154",
  532. "trailstatus": trailstatus,
  533. "name": user_phone,
  534. "phone": user_phone,
  535. "comeinsource_private": 2,
  536. "is_task": 0,
  537. "taskstatus": 0,
  538. "company_nature": isGroup,
  539. "company_verification": isCommerce,
  540. "FREEZE_TIME": nowTime,
  541. })
  542. } else if saleDep == "市场部" {
  543. log.Println("市场部订单", saleDep)
  544. clueId = TiDb.Insert("dwd_f_crm_clue_info", map[string]interface{}{
  545. "userid": userId,
  546. "uid": uId,
  547. "is_assign": -2,
  548. "createtime": nowTime,
  549. "updatetime": nowTime,
  550. "cluename": cluename,
  551. "top_cluetype": "4",
  552. "sub_cluetype": "154",
  553. "trailstatus": trailstatus,
  554. "name": user_phone,
  555. "phone": user_phone,
  556. "is_task": 0,
  557. "taskstatus": 0,
  558. "company_nature": isGroup,
  559. "company_verification": isCommerce,
  560. "FREEZE_TIME": nowTime,
  561. })
  562. }
  563. if clueId > 0 {
  564. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  565. "clue_id": clueId,
  566. "position_id": common.If(positionId > 0, positionId, -1),
  567. "change_type": "创建线索",
  568. "new_value": "系统自动创建",
  569. "createtime": nowTime,
  570. "BCPCID": common.GetRandom(32),
  571. "operator_id": -1,
  572. })
  573. if is_assign == -3 {
  574. //新增冻结记录
  575. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  576. "clue_id": clueId,
  577. "position_id": positionId,
  578. "change_type": "线索冻结",
  579. "new_value": "销售人员私海已达上限",
  580. "createtime": nowTime,
  581. "BCPCID": common.GetRandom(32),
  582. "operator_id": -1,
  583. })
  584. //移交失败发送消息
  585. if IsFreeze(source, pay_money, gconv.String(positionId), trailstatus) {
  586. //发送邮件信息
  587. OrderCreateFail(positionId, mailContent)
  588. }
  589. }
  590. }
  591. }
  592. }
  593. cfg.LastOrderClueId = common.ObjToString(v["autoUpdate"])
  594. }
  595. }
  596. common.WriteSysConfig(&cfg)
  597. log.Println("后台订单线索定时任务结束")
  598. }
  599. func refundAuto() {
  600. log.Println("自动移交销售定时任务开始")
  601. findNowTime := time.Now().AddDate(0, 0, -db.ExpirationPeriod).Format(date.Date_Full_Layout)
  602. nowTime := time.Now().Format(date.Date_Full_Layout)
  603. mailData := map[string][]map[string]interface{}{}
  604. TiDb.SelectByBath(100, func(l *[]map[string]interface{}) bool {
  605. for _, v := range *l {
  606. saleId, cluename, company_nature, company_verification, uid, phone, userName := int64(0), "", 0, 0, "", "", ""
  607. clueId := common.Int64All(v["clue_id"])
  608. company_name := gconv.String(v["company_name"])
  609. name := common.ObjToString(v["name"])
  610. kcposition_id := common.Int64All(v["position_id"])
  611. isRenewalProtection := common.IntAll(v["is_renewal_protection"])
  612. clueData := TiDb.FindOne("dwd_f_crm_clue_info", map[string]interface{}{"id": clueId}, "name,phone,company_nature,company_verification,cluename,userid,position_id,uid", "")
  613. if clueData != nil && len(*clueData) > 0 {
  614. saleId = common.Int64All((*clueData)["position_id"])
  615. cluename = common.ObjToString((*clueData)["cluename"])
  616. userName = gconv.String((*clueData)["name"])
  617. company_nature = common.IntAll((*clueData)["company_nature"])
  618. company_verification = common.IntAll((*clueData)["company_verification"])
  619. uid = common.ObjToString((*clueData)["uid"])
  620. phone = common.ObjToString((*clueData)["phone"])
  621. }
  622. //查询即将到期数据
  623. if isRenewalProtection == 0 {
  624. orderData := TiDb.SelectBySql(`select * from dwd_f_userbase_order_info where uid=? and (product_type = "企业商机管理" or product_type = "大会员") and order_status = 1 and refund_status!=1 `, uid)
  625. if orderData != nil && len(*orderData) > 0 {
  626. endDate := time.Now().AddDate(0, 0, -db.ExpirationPeriod+1).Unix()
  627. startDate := time.Now().AddDate(0, 0, -db.ExpirationPeriod).Unix()
  628. vipEndDate, _ := time.Parse(time.DateTime, gconv.String((*orderData)[0]["vip_endtime"]))
  629. if vipEndDate.Unix() > startDate && vipEndDate.Unix() < endDate {
  630. //即将到期
  631. mailData[name] = append(mailData[name], map[string]interface{}{
  632. "company_name": company_name,
  633. "phone": phone,
  634. "userName": userName,
  635. "remrk": "1天后即将移交",
  636. "reason": "成交客户续费失败",
  637. })
  638. continue
  639. }
  640. }
  641. }
  642. isFull := FindUpperLimit(gconv.String(saleId), "", false)
  643. isAllRefund := false
  644. myOrders := TiDb.SelectBySql(`select refund_status from dwd_f_userbase_order_info where uid=? and (product_type = "企业商机管理" or product_type = "大会员") and order_status = 1 `, uid)
  645. if myOrders != nil {
  646. refundCount := 0
  647. for _, v := range *myOrders {
  648. if common.IntAll(v["refund_status"]) == 1 {
  649. refundCount++
  650. }
  651. }
  652. if len(*myOrders) > 0 && len(*myOrders) == refundCount {
  653. isAllRefund = true
  654. }
  655. }
  656. if isAllRefund {
  657. //全退款了
  658. TiDb.UpdateOrDeleteBySql(`UPDATE dwd_f_crm_clue_info SET is_unfollow=0,is_assign=0,trailstatus="01",position_id=null,seatNumber=null,updatetime=?,comeintime_open=?,comeinsource_open=1,level_open=3,next_trail_time=null,is_task=null,tasktime=null,taskstatus=null,comeinsource_private=null,tasksource=null,is_transfer=0 WHERE id = ?`, nowTime, nowTime, clueId)
  659. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  660. "clue_id": clueId,
  661. "position_id": common.If(kcposition_id > 0, kcposition_id, -1),
  662. "change_type": "退回公海",
  663. "new_value": "成交客户申请退款",
  664. "createtime": nowTime,
  665. "BCPCID": common.GetRandom(32),
  666. "operator_id": -1,
  667. })
  668. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  669. "clue_id": clueId,
  670. "position_id": common.If(kcposition_id > 0, kcposition_id, -1),
  671. "change_field": "trailstatus",
  672. "change_type": "基本信息变更",
  673. "old_value": "成交客户",
  674. "new_value": "商机线索",
  675. "createtime": nowTime,
  676. "BCPCID": common.GetRandom(32),
  677. "operator_id": -1,
  678. })
  679. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  680. "clue_id": clueId,
  681. "position_id": common.If(kcposition_id > 0, kcposition_id, -1),
  682. "change_type": "客户成功经理",
  683. "change_field": "position_id",
  684. "old_value": name,
  685. "new_value": "/",
  686. "createtime": nowTime,
  687. "BCPCID": common.GetRandom(32),
  688. "operator_id": -1,
  689. })
  690. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  691. "clue_id": clueId,
  692. "position_id": common.If(kcposition_id > 0, kcposition_id, -1),
  693. "change_type": "移交销售",
  694. "new_value": "成交客户申请退款",
  695. "createtime": nowTime,
  696. "BCPCID": common.GetRandom(32),
  697. "operator_id": -1,
  698. })
  699. mailData[name] = append(mailData[name], map[string]interface{}{
  700. "company_name": company_name,
  701. "phone": phone,
  702. "userName": userName,
  703. "remrk": "已移交",
  704. "reason": "成交客户申请退款",
  705. })
  706. TiDb.UpdateOrDeleteBySql(`UPDATE dwd_f_csm_customer_info SET is_transfer=1 WHERE clue_id = ?`, clueId)
  707. } else {
  708. order1 := TiDb.SelectBySql(`select id from dwd_f_userbase_order_info where uid=? and (product_type = "企业商机管理" or product_type = "大会员") and vip_endtime > ? and order_status = 1 `, uid, findNowTime)
  709. if order1 == nil || len(*order1) == 0 {
  710. isOk := false
  711. order3 := TiDb.SelectBySql(`select vip_endtime from dwd_f_userbase_order_info where uid=? and (product_type = "企业商机管理" or product_type = "大会员") and vip_endtime < ? and order_status = 1 `, uid, findNowTime)
  712. if order3 != nil && len(*order3) > 0 {
  713. for _, vv := range *order3 {
  714. if isRenewalProtection == 1 {
  715. vip_endtime := common.ObjToString(vv["vip_endtime"])
  716. vip_endtimes, _ := time.ParseInLocation(date.Date_Full_Layout, vip_endtime, time.Local)
  717. //查询申请保护时间
  718. renewalTime := time.Now()
  719. timeData := TiDb.SelectBySql(`select max(createtime) as createtime from dwd_f_crm_clue_change_record where clue_id = ? and change_type="申请续费保护"`, clueId)
  720. if timeData != nil && len(*timeData) > 0 {
  721. if gconv.String(gconv.String((*timeData)[0]["createtime"])) != "" {
  722. renewalTime, _ = time.ParseInLocation(date.Date_Short_Layout, gconv.String((*timeData)[0]["createtime"]), time.Local)
  723. }
  724. }
  725. renewalInt := renewalTime.Unix()
  726. log.Println("申请保护期时间", clueId, renewalInt)
  727. log.Println("申请保护期时间222", time.Now().Unix()-vip_endtimes.Unix(), (db.HandoverCycle-1)*86400, (db.HandoverCycle)*86400)
  728. log.Println("申请保护期时间333", (db.HandoverCycle-1)*86400 < time.Now().Unix()-vip_endtimes.Unix(), time.Now().Unix()-vip_endtimes.Unix() < (db.HandoverCycle)*86400)
  729. //查看服务到期时间
  730. if renewalInt != 0 && renewalInt < db.CustomerTime {
  731. //三个月
  732. if time.Now().Unix()-vip_endtimes.Unix() < 3*30*86400 {
  733. isOk = true
  734. }
  735. } else if (db.HandoverCycle-2)*86400 < time.Now().Unix()-vip_endtimes.Unix() && time.Now().Unix()-vip_endtimes.Unix() < (db.HandoverCycle-1)*86400 {
  736. //提前一天提示
  737. mailData[name] = append(mailData[name], map[string]interface{}{
  738. "company_name": company_name,
  739. "phone": phone,
  740. "userName": userName,
  741. "remrk": "1天后即将移交",
  742. "reason": "成交客户续费失败",
  743. })
  744. } else if time.Now().Unix()-vip_endtimes.Unix() < db.HandoverCycle*86400 {
  745. isOk = true
  746. }
  747. }
  748. }
  749. }
  750. if !isOk {
  751. //全到期了
  752. if saleId > 0 {
  753. saleData := TiDb.FindOne("dwd_f_crm_personnel_management", map[string]interface{}{"position_id": saleId, "resign": 0}, "", "")
  754. if saleData != nil && len(*saleData) > 0 {
  755. if FindUpperLimit(gconv.String(saleId), "", false) {
  756. TiDb.UpdateOrDeleteBySql(`UPDATE dwd_f_crm_clue_info SET is_unfollow=0,updatetime=?,trailstatus="01",is_task=1,tasktime=?,top_cluetype="532",sub_cluetype="537",taskstatus=0,tasksource="其他-成交客户续约失败",is_transfer=0,is_assign=-3,FREEZE_TIME=? WHERE id = ?`, nowTime, nowTime, nowTime, clueId)
  757. } else {
  758. TiDb.UpdateOrDeleteBySql(`UPDATE dwd_f_crm_clue_info SET is_unfollow=0,updatetime=?,trailstatus="01",is_task=1,tasktime=?,top_cluetype="532",sub_cluetype="537",taskstatus=0,tasksource="其他-成交客户续约失败",is_transfer=0 WHERE id = ?`, nowTime, nowTime, clueId)
  759. }
  760. } else {
  761. if company_nature == 0 && company_verification == 1 && cluename != "" {
  762. adata := TiDb.Find("dwd_f_crm_clue_info", map[string]interface{}{"cluename": cluename, "is_assign": 1}, "seatNumber,position_id", "", -1, -1)
  763. if adata != nil && len(*adata) > 0 {
  764. isOks := false
  765. for _, vv := range *adata {
  766. position_ids := common.Int64All(vv["position_id"])
  767. seatNumber := common.ObjToString(vv["seatNumber"])
  768. saleDatas := TiDb.FindOne("dwd_f_crm_personnel_management", map[string]interface{}{"position_id": position_ids, "resign": 0}, "", "")
  769. if saleDatas != nil && len(*saleDatas) > 0 {
  770. saleId = position_ids
  771. if isFull {
  772. TiDb.UpdateOrDeleteBySql(`UPDATE dwd_f_crm_clue_info SET is_unfollow=0,updatetime=?,trailstatus="01",position_id=?,seatNumber=?,is_task=1,tasktime=?,top_cluetype="532",sub_cluetype="537",taskstatus=0,tasksource="其他-成交客户续约失败",is_transfer=0,is_assign=-3,FREEZE_TIME=? WHERE id = ?`, nowTime, saleId, seatNumber, nowTime, nowTime, clueId)
  773. } else {
  774. TiDb.UpdateOrDeleteBySql(`UPDATE dwd_f_crm_clue_info SET is_unfollow=0,updatetime=?,trailstatus="01",position_id=?,seatNumber=?,is_task=1,tasktime=?,top_cluetype="532",sub_cluetype="537",taskstatus=0,tasksource="其他-成交客户续约失败",is_transfer=0 WHERE id = ?`, nowTime, saleId, seatNumber, nowTime, clueId)
  775. }
  776. isOks = true
  777. break
  778. }
  779. }
  780. if !isOks {
  781. sdata := TiDb.SelectBySql(`SELECT b.name,b.position_id,b.seat_number from dwd_d_crm_department_level_succbi a INNER JOIN dwd_f_crm_personnel_management b on a.position_id = b.position_id where a.bi_pcode = (SELECT bi_pcode from dwd_d_crm_department_level_succbi where position_id = ?) and b.role_id = 3`, saleId)
  782. if sdata != nil && len(*sdata) > 0 {
  783. saleId = common.Int64All((*sdata)[0]["position_id"])
  784. seatNumber := common.ObjToString((*sdata)[0]["seat_number"])
  785. if isFull {
  786. TiDb.UpdateOrDeleteBySql(`UPDATE dwd_f_crm_clue_info SET is_unfollow=0,updatetime=?,trailstatus="01",position_id=?,seatNumber=?,is_task=1,tasktime=?,top_cluetype="532",sub_cluetype="537",taskstatus=0,tasksource="其他-成交客户续约失败",is_transfer=0,is_assign=-3,FREEZE_TIME=? WHERE id = ?`, nowTime, saleId, seatNumber, nowTime, nowTime, clueId)
  787. } else {
  788. TiDb.UpdateOrDeleteBySql(`UPDATE dwd_f_crm_clue_info SET is_unfollow=0,updatetime=?,trailstatus="01",position_id=?,seatNumber=?,is_task=1,tasktime=?,top_cluetype="532",sub_cluetype="537",taskstatus=0,tasksource="其他-成交客户续约失败",is_transfer=0 WHERE id = ?`, nowTime, saleId, seatNumber, nowTime, clueId)
  789. }
  790. }
  791. }
  792. }
  793. } else {
  794. sdata := TiDb.SelectBySql(`SELECT b.name,b.position_id,b.seat_number from dwd_d_crm_department_level_succbi a INNER JOIN dwd_f_crm_personnel_management b on a.position_id = b.position_id where a.bi_pcode = (SELECT bi_pcode from dwd_d_crm_department_level_succbi where position_id = ?) and b.role_id = 3`, saleId)
  795. if sdata != nil && len(*sdata) > 0 {
  796. saleId = common.Int64All((*sdata)[0]["position_id"])
  797. seatNumber := common.ObjToString((*sdata)[0]["seat_number"])
  798. if isFull {
  799. TiDb.UpdateOrDeleteBySql(`UPDATE dwd_f_crm_clue_info SET is_unfollow=0,updatetime=?,trailstatus="01",position_id=?,seatNumber=?,is_task=1,tasktime=?,top_cluetype="532",sub_cluetype="537",taskstatus=0,tasksource="其他-成交客户续约失败",is_transfer=0,is_assign=-3,FREEZE_TIME=? WHERE id = ?`, nowTime, saleId, seatNumber, nowTime, nowTime, clueId)
  800. } else {
  801. TiDb.UpdateOrDeleteBySql(`UPDATE dwd_f_crm_clue_info SET is_unfollow=0,updatetime=?,trailstatus="01",position_id=?,seatNumber=?,is_task=1,tasktime=?,top_cluetype="532",sub_cluetype="537",taskstatus=0,tasksource="其他-成交客户续约失败",is_transfer=0 WHERE id = ?`, nowTime, saleId, seatNumber, nowTime, clueId)
  802. }
  803. }
  804. }
  805. }
  806. } else {
  807. if isFull {
  808. TiDb.UpdateOrDeleteBySql(`UPDATE dwd_f_crm_clue_info SET is_unfollow=0,updatetime=?,trailstatus="01",top_cluetype="532",sub_cluetype="537",is_transfer=0,is_assign=-3,FREEZE_TIME=? WHERE id = ?`, nowTime, nowTime, clueId)
  809. } else {
  810. TiDb.UpdateOrDeleteBySql(`UPDATE dwd_f_crm_clue_info SET is_unfollow=0,updatetime=?,trailstatus="01",top_cluetype="532",sub_cluetype="537",is_transfer=0 WHERE id = ?`, nowTime, clueId)
  811. }
  812. }
  813. if kcposition_id > 0 {
  814. mailData[name] = append(mailData[name], map[string]interface{}{
  815. "company_name": company_name,
  816. "phone": phone,
  817. "userName": userName,
  818. "remrk": "已移交",
  819. "reason": "成交客户续费失败",
  820. })
  821. }
  822. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  823. "clue_id": clueId,
  824. "position_id": common.If(kcposition_id > 0, kcposition_id, -1),
  825. "change_type": "基本信息变更",
  826. "old_value": "成交客户",
  827. "change_field": "trailstatus",
  828. "new_value": "商机线索",
  829. "createtime": nowTime,
  830. "BCPCID": common.GetRandom(32),
  831. "operator_id": -1,
  832. })
  833. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  834. "clue_id": clueId,
  835. "position_id": saleId,
  836. "change_type": "加入任务车",
  837. "new_value": "线索自动分配-其他-成交客户续约失败",
  838. "createtime": nowTime,
  839. "BCPCID": common.GetRandom(32),
  840. "operator_id": -1,
  841. })
  842. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  843. "clue_id": clueId,
  844. "position_id": common.If(kcposition_id > 0, kcposition_id, -1),
  845. "change_type": "客户成功经理",
  846. "change_field": "position_id",
  847. "old_value": name,
  848. "new_value": "/",
  849. "createtime": nowTime,
  850. "BCPCID": common.GetRandom(32),
  851. "operator_id": -1,
  852. })
  853. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  854. "clue_id": clueId,
  855. "position_id": saleId,
  856. "change_type": "移交销售",
  857. "new_value": "成交客户续费失败,到期自动移交",
  858. "createtime": nowTime,
  859. "BCPCID": common.GetRandom(32),
  860. "operator_id": -1,
  861. })
  862. TiDb.UpdateOrDeleteBySql(`UPDATE dwd_f_csm_customer_info SET is_transfer=1 WHERE clue_id = ?`, clueId)
  863. if isFull {
  864. //新增冻结记录
  865. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  866. "clue_id": clueId,
  867. "position_id": saleId,
  868. "change_type": "线索冻结",
  869. "new_value": "销售人员私海已达上限",
  870. "createtime": nowTime,
  871. "BCPCID": common.GetRandom(32),
  872. "operator_id": -1,
  873. })
  874. //发送邮件
  875. mailContent := ""
  876. if cluename != "" {
  877. if phone != "" {
  878. if cluename == phone {
  879. mailContent = phone
  880. } else {
  881. mailContent = fmt.Sprintf("%s(%s)", cluename, phone)
  882. }
  883. } else {
  884. mailContent = cluename
  885. }
  886. } else {
  887. mailContent = phone
  888. }
  889. HandOverFail(saleId, mailContent)
  890. }
  891. }
  892. }
  893. }
  894. }
  895. return true
  896. }, `select ent_id,clue_id,position_id,name,is_renewal_protection,company_name from dwd_f_csm_customer_info where is_transfer = 0`)
  897. //}, `select ent_id,clue_id,position_id,name,is_renewal_protection,company_name from dwd_f_csm_customer_info where clue_id =1471384`)
  898. //移交电销提醒
  899. for i, v := range mailData {
  900. ExitKcSend(i, v)
  901. }
  902. log.Println("自动移交销售定时任务结束")
  903. }
  904. func refundAutoHistory() {
  905. data := TiDb.Find("dwd_f_crm_clue_autodraw_record", nil, "", "", -1, -1)
  906. if data != nil {
  907. for _, v := range *data {
  908. seatNumber := common.ObjToString(v["seatNumber"])
  909. adata := TiDb.Find("dwd_f_crm_personnel_management", map[string]interface{}{"seat_number": seatNumber}, "", "", -1, -1)
  910. if adata != nil {
  911. for _, vv := range *adata {
  912. if common.IntAll(vv["resign"]) == 0 {
  913. position_id := common.Int64All(vv["position_id"])
  914. TiDb.Update("dwd_f_crm_clue_autodraw_record", map[string]interface{}{"seatNumber": seatNumber}, map[string]interface{}{"position_id": position_id})
  915. break
  916. }
  917. }
  918. }
  919. }
  920. }
  921. }
  922. func IsFreeze(source string, pay_money int, positionId, trailstatus string) bool {
  923. log.Println(source, pay_money == 0, FindUpperLimit(gconv.String(
  924. positionId), "", false), trailstatus)
  925. if source == "0104" && pay_money == 0 && FindUpperLimit(gconv.String(
  926. positionId), "", false) {
  927. return true
  928. } else if source == "0104" && pay_money > 0 && trailstatus == "08" && FindUpperLimit(gconv.String(
  929. positionId), "", false) {
  930. return true
  931. }
  932. return false
  933. }
  934. func FindSaleRecord(orderCode string) (dept string, positionId int64, position string) {
  935. recordList := Mysql.SelectBySql("select * from order_sale_record where ordercode=? ORDER BY state ,money ", orderCode)
  936. if recordList != nil && len(*recordList) > 0 {
  937. saler_dept := gconv.String((*recordList)[0]["saler_dept"])
  938. if strings.Contains(saler_dept, "销售") {
  939. saler_dept = "销售部"
  940. } else if strings.Contains(saler_dept, "市场") {
  941. saler_dept = "市场部"
  942. } else if strings.Contains(saler_dept, "客户成功") {
  943. saler_dept = "客户成功组"
  944. } else {
  945. saler_dept = ""
  946. }
  947. return saler_dept, gconv.Int64((*recordList)[0]["saler_Id"]), gconv.String((*recordList)[0]["saler_name"])
  948. }
  949. return "", int64(0), ""
  950. }
  951. func kcClue(userId, uId, seatNumber, cluename, top_cluetype, sub_cluetype,
  952. name, phone, position, sourceCode, industry, follow_project_area,
  953. role, item, subname, topname, remark, demand, department, departments, saleName, source string,
  954. positionId int64, isGroup, isCommerce int,
  955. keywords []string) bool {
  956. clueId, uodateId1, uodateId2, uodateId3, uodateId4, uodateId5 := int64(0), int64(0), int64(0), int64(0), int64(0), int64(0)
  957. nowTime := time.Now().Format("2006-01-02 15:04:05")
  958. nowTimes := time.Unix(time.Now().Unix()+3600*12, 0).Format("2006-01-02 15:04:05")
  959. if TiDb.ExecTx("保存线索", func(tx *sql.Tx) bool {
  960. clueId = TiDb.InsertByTx(tx, "dwd_f_crm_clue_info", map[string]interface{}{
  961. "userid": userId,
  962. "uid": uId,
  963. "seatNumber": seatNumber,
  964. "position_id": positionId,
  965. "is_assign": common.If(positionId > 0, 1, 0),
  966. "comeintime": nowTime,
  967. "createtime": nowTime,
  968. "updatetime": nowTime,
  969. "cluename": cluename,
  970. "top_cluetype": top_cluetype,
  971. "sub_cluetype": sub_cluetype,
  972. "trailstatus": "01",
  973. "name": name,
  974. "phone": phone,
  975. "position": position,
  976. "department": common.If(sourceCode == "app_xzcyh", departments, department),
  977. "industry": industry,
  978. "follow_project_area": follow_project_area,
  979. "role": role,
  980. "comeinsource_private": 2,
  981. "is_task": 1,
  982. "task_time": nowTime,
  983. "tasktime": common.If(item == "users", nowTimes, nowTime),
  984. "taskstatus": 0,
  985. "tasksource": "线索自动分配" + "-" + topname + "-" + subname,
  986. "business_scope": common.If(sourceCode == "app_xzcyh", keywords, nil),
  987. "company_nature": isGroup,
  988. "company_verification": isCommerce,
  989. "remark": remark,
  990. "customer_demand": demand,
  991. "FREEZE_TIME": nowTime,
  992. "label": 1,
  993. "labelChangeTime": time.Now().Format("2006-01-02"),
  994. })
  995. uodateId1 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  996. "clue_id": clueId,
  997. "position_id": positionId,
  998. "change_type": "创建线索",
  999. "new_value": "系统自动创建",
  1000. "createtime": nowTime,
  1001. "BCPCID": common.GetRandom(32),
  1002. "operator_id": -1,
  1003. })
  1004. uodateId2 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  1005. "clue_id": clueId,
  1006. "position_id": positionId,
  1007. "change_field": "position_id",
  1008. "change_type": "所属人变更",
  1009. "old_value": "/",
  1010. "new_value": saleName,
  1011. "createtime": nowTime,
  1012. "BCPCID": common.GetRandom(32),
  1013. "operator_id": -1,
  1014. })
  1015. uodateId3 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  1016. "clue_id": clueId,
  1017. "position_id": positionId,
  1018. "change_field": "trailstatus",
  1019. "change_type": "基本信息变更",
  1020. "old_value": "商机线索",
  1021. "new_value": "新增",
  1022. "createtime": nowTime,
  1023. "BCPCID": common.GetRandom(32),
  1024. "operator_id": -1,
  1025. })
  1026. uodateId5 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  1027. "clue_id": clueId,
  1028. "position_id": positionId,
  1029. "change_field": "top_cluetype",
  1030. "change_type": "基本信息变更",
  1031. "old_value": "/",
  1032. "new_value": topname,
  1033. "createtime": nowTime,
  1034. "BCPCID": common.GetRandom(32),
  1035. "operator_id": -1,
  1036. })
  1037. uodateId5 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  1038. "clue_id": clueId,
  1039. "position_id": positionId,
  1040. "change_field": "sub_cluetype", //222
  1041. "change_type": "基本信息变更",
  1042. "old_value": "/",
  1043. "new_value": subname,
  1044. "createtime": nowTime,
  1045. "BCPCID": common.GetRandom(32),
  1046. "operator_id": -1,
  1047. })
  1048. return clueId > -1 && uodateId1 > -1 && uodateId2 > -1 && uodateId3 > -1 && uodateId4 > -1 && uodateId5 > -1
  1049. }) {
  1050. log.Println("线索分配成功")
  1051. if TiDb.Count("dwd_f_userbase_contacts", map[string]interface{}{"phone": phone}) == 0 {
  1052. TiDb.Insert("dwd_f_userbase_contacts", map[string]interface{}{
  1053. "status": 1,
  1054. "is_delete": 1,
  1055. "createtime": nowTime,
  1056. "updatetime": nowTime,
  1057. "phone": phone,
  1058. "baseinfo_id": uId,
  1059. "SOURCE": source,
  1060. })
  1061. }
  1062. return true
  1063. }
  1064. return false
  1065. }
  1066. type OrderInfo struct {
  1067. Id int64
  1068. UserId string
  1069. CompanyName string
  1070. ProductType string
  1071. OrderCode string
  1072. PayMoney float64
  1073. ReturnMoney float64
  1074. UserPhone string
  1075. StartEnd string
  1076. DisKcName string
  1077. UserName string
  1078. SeriveList []string
  1079. SaleName string
  1080. }
  1081. // 客成发送邮箱
  1082. func KcSend(orderCode, personName string) {
  1083. log.Println("客成发邮件", orderCode)
  1084. bigmemberService := map[int64]string{}
  1085. combo := map[int64]string{}
  1086. Mysql.SelectByBath(1, func(l *[]map[string]interface{}) bool {
  1087. bigmemberService[common.Int64All((*l)[0]["id"])] = common.ObjToString((*l)[0]["s_name"])
  1088. return true
  1089. }, `select id,s_name from jianyu.bigmember_service`)
  1090. Mysql.SelectByBath(1, func(l *[]map[string]interface{}) bool {
  1091. combo[common.Int64All((*l)[0]["id"])] = common.ObjToString((*l)[0]["s_name"])
  1092. return true
  1093. }, `select id,s_name from jianyu.bigmember_combo`)
  1094. orderInfo := KcOrderFormat(orderCode, bigmemberService, combo)
  1095. if orderInfo != nil {
  1096. tableAppend := ""
  1097. if len(orderInfo.SeriveList) > 0 {
  1098. tableAppend = fmt.Sprintf(db.KeCheng.Mail.ServiceList, strings.Join(orderInfo.SeriveList, ","))
  1099. }
  1100. if orderInfo.ReturnMoney > 0 {
  1101. tableAppend += fmt.Sprintf(db.KeCheng.Mail.ReturnMoney, orderInfo.ReturnMoney)
  1102. }
  1103. table := ""
  1104. orderInfo.DisKcName = personName
  1105. deptData := Mysql.SelectBySql("select b.mail from jianyu.entniche_department_user a inner join jianyu.entniche_user b on a.dept_id=? and a.user_id=b.id and b.name=? ", db.KeCheng.DeptId, personName)
  1106. adminData := Mysql.SelectBySql(` select c.mail from entniche_department_user a INNER JOIN entniche_user_role b on a.dept_id=59005 and a.user_id = b.user_id and b.role_id=2 INNER JOIN entniche_user c on a.user_id=c.id`)
  1107. table += fmt.Sprintf(db.KeCheng.Mail.Table, orderInfo.ProductType, orderInfo.CompanyName, orderInfo.UserPhone, orderInfo.UserName, orderInfo.OrderCode, orderInfo.PayMoney, orderInfo.StartEnd, orderInfo.DisKcName, orderInfo.SaleName, tableAppend)
  1108. adminMailStr := ""
  1109. if adminData != nil && len(*adminData) > 0 {
  1110. adminMailStr = gconv.String((*adminData)[0]["mail"])
  1111. }
  1112. //发送邮件
  1113. if personName == "" {
  1114. if adminData != nil && len(*adminData) > 0 {
  1115. //发送给管理员
  1116. if adminMailStr != "" {
  1117. gmail := &mail.GmailAuth{
  1118. SmtpHost: db.Mail.SmtpHost,
  1119. SmtpPort: db.Mail.SmtpPort,
  1120. User: db.Mail.User,
  1121. Pwd: db.Mail.Pwd,
  1122. }
  1123. status := mail.GSendMail_q("剑鱼标讯", adminMailStr, "", "", db.KeCheng.Title, fmt.Sprintf(db.KeCheng.Mail.Content, table), "", "", gmail)
  1124. if status {
  1125. log.Println("客成发邮件 send mail success", table, adminMailStr)
  1126. }
  1127. }
  1128. }
  1129. return
  1130. }
  1131. //当事人 管理员发送
  1132. if deptData != nil && len(*deptData) > 0 {
  1133. mailStr := gconv.String((*deptData)[0]["mail"])
  1134. if mailStr != "" || adminMailStr != "" {
  1135. gmail := &mail.GmailAuth{
  1136. SmtpHost: db.Mail.SmtpHost,
  1137. SmtpPort: db.Mail.SmtpPort,
  1138. User: db.Mail.User,
  1139. Pwd: db.Mail.Pwd,
  1140. }
  1141. status := true
  1142. if mailStr == "" {
  1143. status = mail.GSendMail_q("剑鱼标讯", adminMailStr, "", "", db.KeCheng.Title, fmt.Sprintf(db.KeCheng.Mail.Content, table), "", "", gmail)
  1144. } else {
  1145. status = mail.GSendMail_q("剑鱼标讯", mailStr, adminMailStr, "", db.KeCheng.Title, fmt.Sprintf(db.KeCheng.Mail.Content, table), "", "", gmail)
  1146. }
  1147. if status {
  1148. log.Println("客成发邮件 send mail success", table, mailStr, adminMailStr)
  1149. }
  1150. }
  1151. }
  1152. }
  1153. }
  1154. func ExitKcSend(personName string, infoList []map[string]interface{}) {
  1155. //退出客成 即将退出客成信息
  1156. deptData := Mysql.SelectBySql("select b.mail from jianyu.entniche_department_user a inner join jianyu.entniche_user b on a.dept_id=? and a.user_id=b.id and b.name=? ", db.KeCheng.DeptId, personName)
  1157. adminData := Mysql.SelectBySql(` select c.mail from entniche_department_user a INNER JOIN entniche_user_role b on a.dept_id=59005 and a.user_id = b.user_id and b.role_id=2 INNER JOIN entniche_user c on a.user_id=c.id`)
  1158. if personName == "" {
  1159. //没有客成人员
  1160. adminMailStr := ""
  1161. if adminData != nil && len(*adminData) > 0 {
  1162. adminMailStr = gconv.String((*adminData)[0]["mail"])
  1163. }
  1164. if adminMailStr != "" {
  1165. gmail := &mail.GmailAuth{
  1166. SmtpHost: db.Mail.SmtpHost,
  1167. SmtpPort: db.Mail.SmtpPort,
  1168. User: db.Mail.User,
  1169. Pwd: db.Mail.Pwd,
  1170. }
  1171. //正文拼接
  1172. startStr := `<html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, initial-scale=1.0"><style>table{width:100%;border-collapse:collapse}th,td{border:1px solid#000;padding:8px;text-align:left}th{background-color:#f2f2f2}</style></head><body><p>以下客户已从或即将从客成系统退出,并移交销售跟进,请收悉,客户明细如下:</p><table><thead><tr><th>序号</th><th>公司名称</th><th>联系人</th><th>姓名</th><th>移交状态</th><th>移交销售原因</th></tr></thead><tbody>`
  1173. for i, v := range infoList {
  1174. startStr += fmt.Sprintf(`<tr><td>%d</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>`, i+1, gconv.String(v["company_name"]), gconv.String(v["phone"]), gconv.String(v["userName"]), gconv.String(v["remrk"]), gconv.String(v["reason"]))
  1175. }
  1176. endStr := `</tbody></table><p></body></html>`
  1177. startStr += endStr
  1178. status := mail.GSendMail_q("剑鱼标讯", adminMailStr, "", "", "客户退出客成系统通知", startStr, "", "", gmail)
  1179. if status {
  1180. log.Println("客成发邮件 send mail success", startStr, adminMailStr)
  1181. }
  1182. }
  1183. return
  1184. }
  1185. if deptData != nil && len(*deptData) > 0 {
  1186. mailStr := gconv.String((*deptData)[0]["mail"])
  1187. adminMailStr := ""
  1188. if adminData != nil && len(*adminData) > 0 {
  1189. adminMailStr = gconv.String((*adminData)[0]["mail"])
  1190. }
  1191. if mailStr != "" || adminMailStr != "" {
  1192. gmail := &mail.GmailAuth{
  1193. SmtpHost: db.Mail.SmtpHost,
  1194. SmtpPort: db.Mail.SmtpPort,
  1195. User: db.Mail.User,
  1196. Pwd: db.Mail.Pwd,
  1197. }
  1198. //正文拼接
  1199. startStr := `<html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, initial-scale=1.0"><style>table{width:100%;border-collapse:collapse}th,td{border:1px solid#000;padding:8px;text-align:left}th{background-color:#f2f2f2}</style></head><body><p>以下客户已从或即将从客成系统退出,并移交销售跟进,请收悉,客户明细如下:</p><table><thead><tr><th>序号</th><th>公司名称</th><th>联系人</th><th>姓名</th><th>移交状态</th><th>移交销售原因</th></tr></thead><tbody>`
  1200. for i, v := range infoList {
  1201. startStr += fmt.Sprintf(`<tr><td>%d</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>`, i+1, gconv.String(v["company_name"]), gconv.String(v["phone"]), gconv.String(v["userName"]), gconv.String(v["remrk"]), gconv.String(v["reason"]))
  1202. }
  1203. endStr := `</tbody></table><p></body></html>`
  1204. startStr += endStr
  1205. status := true
  1206. if mailStr == "" {
  1207. status = mail.GSendMail_q("剑鱼标讯", adminMailStr, "", "", "客户退出客成系统通知", startStr, "", "", gmail)
  1208. } else {
  1209. status = mail.GSendMail_q("剑鱼标讯", mailStr, adminMailStr, "", "客户退出客成系统通知", startStr, "", "", gmail)
  1210. }
  1211. if status {
  1212. log.Println("客成发邮件 send mail success", startStr, mailStr)
  1213. }
  1214. }
  1215. }
  1216. }
  1217. func KcOrderFormat(orderCode string, bigmemberService, combo map[int64]string) *OrderInfo {
  1218. orderData := Mysql.SelectBySql(`SELECT a.id,a.order_code,a.pay_money,a.user_phone,a.vip_starttime,a.vip_endtime,a.product_type,a.filter,a.user_id,a.ent_id,a.company_name,a.create_person,SUM(b.return_money) AS return_money
  1219. FROM jianyu.dataexport_order a
  1220. LEFT JOIN return_money_record b ON (a.order_code=b.order_code)
  1221. WHERE a.order_code=? AND a.order_status=1 AND (a.product_type='大会员' OR a.product_type='大会员-子账号')
  1222. GROUP BY a.id ORDER BY a.autoUpdate`, orderCode)
  1223. data := &OrderInfo{}
  1224. if orderData != nil && len(*orderData) > 0 {
  1225. id := common.Int64All((*orderData)[0]["id"])
  1226. user_phone := common.ObjToString((*orderData)[0]["user_phone"])
  1227. user_id := common.ObjToString((*orderData)[0]["user_id"])
  1228. product_type := common.ObjToString((*orderData)[0]["product_type"])
  1229. serviceList := []string{}
  1230. if filter := common.ObjToString((*orderData)[0]["filter"]); filter != "" {
  1231. filterMap := map[string]interface{}{}
  1232. json.Unmarshal([]byte(filter), &filterMap)
  1233. if level := common.Int64All(filterMap["level"]); level == 5 {
  1234. product_type += "自定义版"
  1235. for _, serversId := range strings.Split(common.ObjToString(filterMap["serversId"]), ",") {
  1236. if serviceName := bigmemberService[common.Int64All(serversId)]; serviceName != "" {
  1237. serviceList = append(serviceList, serviceName)
  1238. }
  1239. }
  1240. } else {
  1241. product_type += combo[common.Int64All(filterMap["comboId"])]
  1242. }
  1243. }
  1244. //联系人姓名
  1245. sqlStr := `SELECT
  1246. a.phone,
  1247. b.NAME AS bname
  1248. FROM
  1249. dwd_f_userbase_contacts a
  1250. INNER JOIN dwd_f_crm_clue_info b ON ( a.phone = ? AND a.baseinfo_id = b.uid )
  1251. LEFT JOIN dwd_f_csm_customer_info c ON ( b.id = c.clue_id)`
  1252. userName := ""
  1253. if user_phone != "" {
  1254. userData := TiDb.SelectBySql(sqlStr, user_phone)
  1255. if userData != nil && len(*userData) > 0 {
  1256. userName = gconv.String((*userData)[0]["bname"])
  1257. }
  1258. }
  1259. data = &OrderInfo{
  1260. Id: id,
  1261. CompanyName: common.ObjToString((*orderData)[0]["company_name"]),
  1262. UserId: user_id,
  1263. ProductType: product_type,
  1264. OrderCode: orderCode,
  1265. PayMoney: common.Float64All((*orderData)[0]["pay_money"]) / 100,
  1266. ReturnMoney: common.Float64All((*orderData)[0]["return_money"]) / 100,
  1267. UserPhone: user_phone,
  1268. StartEnd: fmt.Sprintf("%s--%s", strings.Split(common.ObjToString((*orderData)[0]["vip_starttime"]), " ")[0], strings.Split(common.ObjToString((*orderData)[0]["vip_endtime"]), " ")[0]),
  1269. SeriveList: serviceList,
  1270. SaleName: common.ObjToString((*orderData)[0]["create_person"]),
  1271. UserName: userName,
  1272. }
  1273. }
  1274. return data
  1275. }