kc.go 81 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080
  1. package main
  2. import (
  3. "app.yhyue.com/moapp/jybase/mail"
  4. "app.yhyue.com/moapp/jybase/redis"
  5. "database/sql"
  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. //商品查询
  18. productArr, _ := KcProduct()
  19. if len(productArr) == 0 {
  20. log.Println("查询不到进客成商品类型")
  21. return
  22. }
  23. sql := `SELECT
  24. a.*,b.product_type,b.service_starttime,b.service_endtime,b.service_type,b.filter as productFilter,TIMESTAMPDIFF(DAY, b.service_starttime, b.service_endtime) as difference,b.update_time
  25. FROM
  26. dataexport_order a
  27. INNER JOIN jy_order_detail b ON a.order_code = b.order_code
  28. and b.product_type in (%s)
  29. AND (
  30. a.pay_money > 0
  31. OR (
  32. a.pay_money = 0
  33. AND ( a.zero_type = "分期付款权益补充" OR a.zero_type = "原订单不支持开通多项权益" OR a.zero_type = "权益码兑换" )))
  34. AND a.user_phone NOT LIKE "%s"
  35. and a.user_id !=""
  36. AND a.order_status = 1
  37. AND ( a.refund_status != 1 OR a.refund_status IS NULL )
  38. AND b.service_starttime < "2099-01-01" AND b.service_endtime > now()
  39. AND b.update_time > "%s"
  40. ORDER BY
  41. b.update_time asc ,
  42. a.order_code ASC,
  43. difference desc ,
  44. b.final_price DESC `
  45. sql = fmt.Sprintf(sql, strings.Join(productArr, ","), "9%", cfg.LastkcTime)
  46. //sql = fmt.Sprintf(sql, strings.Join(productArr, ","), "9%", "2025-01-02", "103557341197")
  47. data := Mysql.SelectBySql(sql)
  48. fmt.Println("客成查询到的数量:", len(*data))
  49. customList := gconv.Strings(redis.Get("newother", "customList"))
  50. if data != nil && *data != nil && len(*data) > 0 {
  51. orderMap := map[string]map[string]interface{}{}
  52. for _, v := range *data {
  53. orderCode := gconv.String(v["order_code"])
  54. productType := gconv.String(v["product_type"])
  55. vipStarttime := gconv.String(v["service_starttime"])
  56. vipEndtime := gconv.String(v["service_endtime"])
  57. service_type := gconv.Int64(v["service_type"])
  58. difference := gconv.Int(v["difference"])
  59. if (service_type != 4) || (service_type == 4 && difference > 95) {
  60. isExit := false
  61. for _, v := range customList {
  62. if v == orderCode {
  63. isExit = true
  64. continue
  65. }
  66. }
  67. if isExit {
  68. continue
  69. }
  70. //判断一下服务周期
  71. _, productInt64, _ := GetOrderProduct(productType, gconv.String(v["productFilter"]))
  72. if productInt64 == 0 {
  73. continue
  74. }
  75. if _, exists := orderMap[orderCode]; exists {
  76. //判断服务周期
  77. data := orderMap[orderCode]
  78. //商品类型获取
  79. oldDifference := gconv.Int(data["difference"])
  80. if oldDifference < difference {
  81. //需要更换
  82. v["difference"] = difference
  83. v["product"] = productInt64
  84. v["service_endtime"] = vipEndtime
  85. v["service_starttime"] = vipStarttime
  86. orderMap[orderCode] = v
  87. }
  88. } else {
  89. v["difference"] = difference
  90. v["product"] = productInt64
  91. orderMap[orderCode] = v
  92. }
  93. }
  94. }
  95. for _, v := range *data {
  96. orderCode := gconv.String(v["order_code"])
  97. if _, exists := orderMap[orderCode]; exists {
  98. status := kcJob(orderMap[orderCode])
  99. log.Println("订单进客成打印", orderCode, status)
  100. if status == 0 {
  101. break
  102. }
  103. cfg.LastkcTime = gconv.String(v["update_time"])
  104. customList = append(customList, orderCode)
  105. delete(orderMap, orderCode)
  106. }
  107. }
  108. }
  109. redis.Put("newother", "customList", customList, 0)
  110. common.WriteSysConfig(&cfg)
  111. log.Println("客户成功系统移交定时任务结束")
  112. }
  113. func kcJob(data map[string]interface{}) int {
  114. nowTime := time.Now().Format(date.Date_Full_Layout)
  115. uId, entId, clueId, saveMap, status := "", gconv.String(data["ent_id"]), int64(0), map[string]interface{}{}, 1
  116. userId, cluename, phone := "", "", ""
  117. phone = gconv.String(data["user_phone"])
  118. uId, userId = GetUidToUserId(gconv.String(data["user_id"]), "")
  119. log.Println("用户信息获取", data["user_id"], uId, userId)
  120. if uId == "" {
  121. log.Println("移交客成缺少基本信息,缺少用户信息", uId)
  122. return 0
  123. }
  124. buy_subject := common.IntAll(data["buy_subject"])
  125. if buy_subject == 1 || buy_subject == 0 {
  126. entId = gconv.String(data["user_id"])
  127. }
  128. clueData := TiDb.FindOne("dwd_f_crm_clue_info", map[string]interface{}{"uid": uId}, "", "")
  129. orderCode := gconv.String(data["order_code"])
  130. saleDep, orderPositionId, salesperson := FindSaleRecord(orderCode)
  131. log.Println(data["order_code"], saleDep, orderPositionId, salesperson)
  132. if clueData == nil || len(*clueData) == 0 {
  133. if saleDep == "销售部" || saleDep == "市场部" {
  134. log.Println("移交客成缺少基本信息", uId)
  135. return 0
  136. }
  137. //原始订单获取
  138. position_id := int64(0)
  139. seatNumber := ""
  140. if saleDep == "客户成功部" {
  141. //新增线索
  142. position_id = 0
  143. } else {
  144. position_id = orderPositionId
  145. //其他信息
  146. seatNumber = "0000"
  147. }
  148. cluename = gconv.String(data["company_name"])
  149. if cluename == "" {
  150. cluename = phone
  151. }
  152. trailstatus := "08"
  153. isGroup, isCommerce := GetCompanyType(cluename, uId) //判断是否集团公司、工商库
  154. clueId = TiDb.Insert("dwd_f_crm_clue_info", map[string]interface{}{
  155. "userid": userId,
  156. "uid": uId,
  157. "is_assign": common.If(position_id > 0, 1, 0),
  158. "createtime": nowTime,
  159. "updatetime": nowTime,
  160. "cluename": cluename,
  161. "seatNumber": seatNumber,
  162. "position_id": position_id,
  163. "top_cluetype": "4",
  164. "sub_cluetype": "154",
  165. "trailstatus": trailstatus,
  166. "name": phone,
  167. "phone": phone,
  168. "is_task": 0,
  169. "taskstatus": 0,
  170. "company_nature": isGroup,
  171. "company_verification": isCommerce,
  172. "FREEZE_TIME": nowTime,
  173. "label": common.If(position_id > 0, 1, nil),
  174. })
  175. if clueId > 0 {
  176. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  177. "clue_id": clueId,
  178. "position_id": common.If(position_id > 0, position_id, -1),
  179. "change_type": "创建线索",
  180. "new_value": "系统自动创建",
  181. "createtime": nowTime,
  182. "BCPCID": common.GetRandom(32),
  183. "operator_id": -1,
  184. })
  185. clueData = TiDb.FindOne("dwd_f_crm_clue_info", map[string]interface{}{"uid": uId}, "", "")
  186. if clueData == nil || len(*clueData) == 0 {
  187. return 0
  188. }
  189. } else {
  190. return 0
  191. }
  192. }
  193. clueId = common.Int64All((*clueData)["id"])
  194. starttime := gconv.String(data["service_starttime"])
  195. endtime := gconv.String(data["service_endtime"])
  196. //product_type := gconv.String(data["product_type"])
  197. userName := gconv.String((*clueData)["name"])
  198. product, company_name := gconv.String(data["product"]), gconv.String(data["company_name"])
  199. //同一公司名称(以客户详情-组织机构-公司名称)下的线索需分配给同1人
  200. saveMap = map[string]interface{}{
  201. "clue_id": clueId,
  202. "transfertime": nowTime,
  203. "service_starttime": starttime,
  204. "service_endtime": endtime,
  205. "ent_id": entId,
  206. "is_task": 1,
  207. "tasktime": nowTime,
  208. "taskstatus": 0,
  209. "tasksource": "1",
  210. "is_admin": 1,
  211. "product_access": product,
  212. "buy_subject": buy_subject,
  213. "relationship_building_way": 1,
  214. "inventory_way": 1,
  215. "training_way": 1,
  216. "is_pre_sales_training": 0,
  217. "service_stage": 1,
  218. "company_name": company_name,
  219. }
  220. if TiDb.Count("dwd_f_csm_customer_info", map[string]interface{}{"clue_id": clueId}) > 0 {
  221. csmdata := TiDb.FindOne("dwd_f_csm_customer_info", map[string]interface{}{"clue_id": clueId}, "", "")
  222. if csmdata != nil && len(*csmdata) > 0 {
  223. id := gconv.Int64((*csmdata)["id"])
  224. log.Println(1111111, id, orderCode)
  225. //'已移交销售,0移交客成 1移交销售',
  226. is_transfer := gconv.Int64((*csmdata)["is_transfer"])
  227. customerPositionId, customerName := cAutoDraw(0, orderPositionId, salesperson, saleDep, true, csmdata)
  228. log.Println("移交客成positionId", customerPositionId, customerName, saleDep, orderPositionId, salesperson, true)
  229. oldName := gconv.String((*csmdata)["name"])
  230. updateMap := map[string]interface{}{
  231. "is_transfer": 0,
  232. "is_renewal_protection": 0,
  233. "product_access": product,
  234. "buy_subject": buy_subject,
  235. "transfertime": nowTime,
  236. "service_starttime": starttime,
  237. "service_endtime": endtime,
  238. "ent_id": entId,
  239. "company_name": company_name,
  240. "name": customerName,
  241. "position_id": customerPositionId,
  242. }
  243. if is_transfer == 1 || customerPositionId != gconv.Int64((*csmdata)["position_id"]) {
  244. //重新进去
  245. updateMap["relationship_building_way"] = 1
  246. updateMap["tasksource"] = "1"
  247. updateMap["inventory_way"] = 1
  248. updateMap["training_way"] = 1
  249. updateMap["is_pre_sales_training"] = 0
  250. updateMap["service_stage"] = 1
  251. updateMap["is_task"] = 1
  252. }
  253. TiDb.Update("dwd_f_csm_customer_info", map[string]interface{}{"clue_id": clueId}, updateMap)
  254. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  255. "clue_id": clueId,
  256. "position_id": customerPositionId,
  257. "change_type": "成交客户移交",
  258. "new_value": "移交至客户成功组",
  259. "createtime": nowTime,
  260. "BCPCID": common.GetRandom(32),
  261. "operator_id": -1,
  262. })
  263. if customerPositionId > 0 && (is_transfer == 1 || customerPositionId != gconv.Int64((*csmdata)["position_id"])) {
  264. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  265. "clue_id": clueId,
  266. "position_id": customerPositionId,
  267. "change_field": "position_id",
  268. "change_type": "客户成功经理",
  269. "old_value": common.If(oldName != customerName, oldName, common.If(oldName == "", "/", oldName)),
  270. "new_value": customerName,
  271. "createtime": nowTime,
  272. "BCPCID": common.GetRandom(32),
  273. "operator_id": -1,
  274. })
  275. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  276. "clue_id": clueId,
  277. "position_id": customerPositionId,
  278. "change_type": "加入任务车",
  279. "new_value": "未建联",
  280. "createtime": nowTime,
  281. "BCPCID": common.GetRandom(32),
  282. "operator_id": -1,
  283. })
  284. }
  285. if is_transfer == 1 || customerPositionId != gconv.Int64((*csmdata)["position_id"]) {
  286. if customerName == db.KeCheng.Admin {
  287. TiDb.UpdateOrDeleteBySql(`update dwd_f_csm_customer_autodraw_record set count = count + 2 where name = ?`, customerName)
  288. } else {
  289. TiDb.UpdateOrDeleteBySql(`update dwd_f_csm_customer_autodraw_record set count = count + 1 where name = ?`, customerName)
  290. }
  291. }
  292. KcSend(orderCode, customerName)
  293. TiDb.Update("dwd_f_crm_clue_info", map[string]interface{}{"id": clueId}, map[string]interface{}{"is_transfer": 1, "updatetime": nowTime, "name": userName})
  294. }
  295. } else {
  296. customerPositionId, customerName := cAutoDraw(gconv.Int(entId), orderPositionId, salesperson, saleDep, false, nil)
  297. log.Println("移交客成positionId", customerPositionId, customerName, saleDep, orderPositionId, salesperson, false)
  298. cId, ok, updateId1, updateId2, updateId3 := int64(0), false, int64(0), int64(0), int64(0)
  299. if TiDb.ExecTx("保存客户", func(tx *sql.Tx) bool {
  300. saveMap["position_id"] = customerPositionId
  301. saveMap["name"] = customerName
  302. cId = TiDb.InsertByTx(tx, "dwd_f_csm_customer_info", saveMap)
  303. ok = TiDb.UpdateByTx(tx, "dwd_f_crm_clue_info", map[string]interface{}{"id": clueId}, map[string]interface{}{"is_transfer": 1, "updatetime": nowTime, "name": userName})
  304. if customerPositionId > 0 {
  305. updateId1 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  306. "clue_id": clueId,
  307. "position_id": customerPositionId,
  308. "change_type": "加入任务车",
  309. "new_value": "未建联",
  310. "createtime": nowTime,
  311. "BCPCID": common.GetRandom(32),
  312. "operator_id": -1,
  313. })
  314. updateId3 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  315. "clue_id": clueId,
  316. "position_id": customerPositionId,
  317. "change_field": "position_id",
  318. "change_type": "客户成功经理",
  319. "old_value": "/",
  320. "new_value": customerName,
  321. "createtime": nowTime,
  322. "BCPCID": common.GetRandom(32),
  323. "operator_id": -1,
  324. })
  325. }
  326. KcSend(orderCode, customerName)
  327. updateId2 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  328. "clue_id": clueId,
  329. "position_id": customerPositionId,
  330. "change_type": "成交客户移交",
  331. "new_value": "移交至客户成功组",
  332. "createtime": nowTime,
  333. "BCPCID": common.GetRandom(32),
  334. "operator_id": -1,
  335. })
  336. return cId > -1 && ok && updateId1 > -1 && updateId2 > -1 && updateId3 > -1
  337. }) {
  338. if customerName == db.KeCheng.Admin {
  339. TiDb.UpdateOrDeleteBySql(`update dwd_f_csm_customer_autodraw_record set count = count + 2 where name = ?`, customerName)
  340. } else {
  341. TiDb.UpdateOrDeleteBySql(`update dwd_f_csm_customer_autodraw_record set count = count + 1 where name = ?`, customerName)
  342. }
  343. log.Println("保存客户成功")
  344. } else {
  345. log.Println("保存客户失败!!!", clueId, cId, ok, updateId1, updateId2, updateId3, " 用户信息 ", customerName, customerPositionId, uId)
  346. }
  347. }
  348. return status
  349. }
  350. func cAutoDraw(entId int, orderPositionId int64, salesperson, saleDep string, isExist bool, csmdata *map[string]interface{}) (positionId int64, name string) {
  351. 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 ent_id=?) and resign = 0 and position_id is not null `
  352. data := TiDb.SelectBySql(query, db.EntId)
  353. if data == nil || len(*data) == 0 {
  354. return
  355. }
  356. positionId, name = findKcOldPerson(entId, orderPositionId, salesperson, saleDep, isExist, csmdata, data)
  357. if positionId == 0 {
  358. positionId, name = findKcNewPerson(entId, data)
  359. }
  360. return
  361. }
  362. func findKcOldPerson(entId int, orderPositionId int64, salesperson, saleDep string, isExist bool, csmdata *map[string]interface{}, data *[]map[string]interface{}) (positionId int64, name string) {
  363. //判断是否需要新增客成数据
  364. if isExist {
  365. //用户存在客成数据
  366. positionid := common.Int64All((*csmdata)["position_id"])
  367. if positionid != 0 {
  368. //以前没有,需要找一个新的
  369. for _, v := range *data {
  370. deptPositionId := gconv.Int64(v["position_id"])
  371. if deptPositionId == positionid {
  372. positionId = positionid
  373. name = gconv.String((*csmdata)["name"])
  374. return
  375. }
  376. }
  377. }
  378. //原始用户已离职 查看订单是否有合适的订单
  379. if saleDep == "客户成功部" {
  380. positionId = orderPositionId
  381. name = salesperson
  382. return
  383. }
  384. }
  385. //客成数据不存在的时候
  386. //查找企业有没有其他信息
  387. if entId > 0 {
  388. entdata := TiDb.Find("dwd_f_csm_customer_info", map[string]interface{}{"ent_id": entId}, "", "", -1, -1)
  389. if entdata != nil && len(*entdata) > 0 {
  390. for _, v := range *entdata {
  391. positionid := common.Int64All(v["position_id"])
  392. name = gconv.String(v["name"])
  393. for _, v := range *data {
  394. deptPositionId := gconv.Int64(v["position_id"])
  395. if deptPositionId == positionId {
  396. positionId = positionid
  397. name = gconv.String((*csmdata)["name"])
  398. return
  399. }
  400. }
  401. }
  402. }
  403. //原始用户已离职 或者没有查找相关企业客成信息 以订单信息为主
  404. if saleDep == "客户成功部" {
  405. positionId = orderPositionId
  406. name = salesperson
  407. }
  408. return
  409. //没有相同企业的客成信息
  410. } else {
  411. //没有人 分配给自己
  412. if saleDep == "客户成功部" {
  413. positionId = orderPositionId
  414. name = salesperson
  415. return
  416. }
  417. return
  418. }
  419. }
  420. func findKcNewPerson(entId int, data *[]map[string]interface{}) (positionId int64, name string) {
  421. if entId > 0 {
  422. entdata := TiDb.FindOne("dwd_f_csm_customer_info", map[string]interface{}{"ent_id": entId}, "", "")
  423. if entdata != nil && len(*entdata) > 0 {
  424. positionId = common.Int64All((*entdata)["position_id"])
  425. name = gconv.String((*entdata)["name"])
  426. return
  427. }
  428. }
  429. sql := `select a.name,a.count from dwd_f_csm_customer_autodraw_record a INNER JOIN dwd_d_crm_department_level_succbi b on b.ent_id=? and (a.name = b.name) and b.resign = 0`
  430. countData := TiDb.SelectBySql(sql, db.EntId)
  431. if countData != nil && len(*countData) > 0 {
  432. for _, v := range *data {
  433. //判断是否有新员工
  434. isOk := false
  435. for _, vv := range *countData {
  436. if gconv.String(v["name"]) == gconv.String(vv["name"]) {
  437. isOk = true
  438. }
  439. }
  440. //有新员工直接分给新员工
  441. if !isOk {
  442. name = gconv.String(v["name"])
  443. rData := TiDb.FindOne("dwd_f_csm_customer_autodraw_record", map[string]interface{}{}, "", "count desc")
  444. TiDb.Insert("dwd_f_csm_customer_autodraw_record", map[string]interface{}{
  445. "name": name,
  446. "count": common.Int64All((*rData)["count"]),
  447. })
  448. break
  449. }
  450. }
  451. res := int64(0)
  452. countres := 0
  453. for _, v := range *countData {
  454. if countres == 0 {
  455. res = common.Int64All(v["count"])
  456. name = gconv.String(v["name"])
  457. } else {
  458. if common.Int64All(v["count"]) <= res {
  459. res = common.Int64All(v["count"])
  460. name = gconv.String(v["name"])
  461. }
  462. }
  463. countres++
  464. }
  465. }
  466. for _, v := range *data {
  467. if name == gconv.String(v["name"]) {
  468. positionId = common.Int64All(v["position_id"])
  469. }
  470. }
  471. return
  472. }
  473. func kcAuto() {
  474. log.Println("客户成功系统自动进入任务车定时任务开始")
  475. nowTime := time.Now().Format(date.Date_Full_Layout)
  476. 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`
  477. data := TiDb.SelectBySql(sql)
  478. if data != nil && *data != nil && len(*data) > 0 {
  479. for _, v := range *data {
  480. relationship_building_way := common.IntAll(v["relationship_building_way"])
  481. inventory_way := common.IntAll(v["inventory_way"])
  482. training_way := common.IntAll(v["training_way"])
  483. positionId := common.Int64All(v["position_id"])
  484. clueId := common.Int64All(v["clue_id"])
  485. tasksource, tasksources := gconv.String(v["tasksource"]), ""
  486. taskstatus := common.IntAll(v["taskstatus"])
  487. if relationship_building_way != 1 && inventory_way == 1 {
  488. tasksources = "2"
  489. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  490. "clue_id": clueId,
  491. "position_id": positionId,
  492. "change_type": "加入任务车",
  493. "new_value": "未盘点",
  494. "createtime": nowTime,
  495. "BCPCID": common.GetRandom(32),
  496. "operator_id": -1,
  497. })
  498. } else if inventory_way != 1 && training_way == 1 {
  499. tasksources = "3"
  500. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  501. "clue_id": clueId,
  502. "position_id": positionId,
  503. "change_type": "加入任务车",
  504. "new_value": "未培训",
  505. "createtime": nowTime,
  506. "BCPCID": common.GetRandom(32),
  507. "operator_id": -1,
  508. })
  509. }
  510. if taskstatus == 1 {
  511. tasksource = tasksources
  512. } else {
  513. if tasksource != "" {
  514. if !strings.Contains(tasksource, tasksources) {
  515. tasksource += "," + tasksources
  516. }
  517. } else {
  518. tasksource = tasksources
  519. }
  520. }
  521. TiDb.Update("dwd_f_csm_customer_info", map[string]interface{}{"clue_id": clueId}, map[string]interface{}{
  522. "tasksource": tasksource,
  523. "tasktime": nowTime,
  524. "is_task": 1,
  525. "taskstatus": 0,
  526. })
  527. }
  528. }
  529. log.Println("客户成功系统进入任务车定时任务结束")
  530. }
  531. func ordersClue() {
  532. log.Println("后台订单线索定时任务开始")
  533. lastOrderClueId := cfg.LastOrderClueId
  534. nowTime := time.Now().Format(date.Date_Full_Layout)
  535. product_type_str2 := `"大会员","企业商机管理","VIP订阅"`
  536. sql := fmt.Sprintf(`select a.*,b.product_type as productType ,b.service_starttime,b.service_endtime,b.filter AS productFilter,b.update_time from dataexport_order a
  537. INNER JOIN jy_order_detail b on a.order_code=b.order_code
  538. and b.update_time>="%s" AND a.user_phone NOT LIKE "%s" and a.user_id !=""
  539. and b.product_type in (%s) and a.order_status = 1 and a.is_backstage_order = 1 order by b.update_time asc`, lastOrderClueId, "9%", product_type_str2)
  540. log.Println("后台订单线索定时任务", sql)
  541. data := Mysql.SelectBySql(sql)
  542. log.Println("后台订单线索定时任务", len(*data))
  543. if data != nil && *data != nil && len(*data) > 0 {
  544. for _, v := range *data {
  545. payMoney := common.IntAll(v["pay_money"])
  546. orderCode := gconv.String(v["order_code"])
  547. saleDep, _, salesperson := FindSaleRecord(orderCode)
  548. userPhone := gconv.String(v["user_phone"])
  549. createperson := gconv.String(v["create_person"])
  550. userId, uId, cluename, seatNumber, positionId, trailstatus, clueId := gconv.String(v["user_id"]), "", "", "", int64(0), "", int64(0)
  551. if saleDep != "" {
  552. //销售部
  553. query := map[string]interface{}{}
  554. source := ""
  555. if !mongodb.IsObjectIdHex(userId) {
  556. userMapping := TiDb.FindOne("data_service.user_system", map[string]interface{}{"position_id": userId}, "", "")
  557. if userMapping != nil && len(*userMapping) > 0 {
  558. userId = gconv.String((*userMapping)["userid"])
  559. } else {
  560. log.Println("后台订单--未查询到 ", userPhone)
  561. break
  562. }
  563. }
  564. query["userid"] = userId
  565. userInfo := TiDb.FindOne("dwd_f_userbase_baseinfo", query, "", "")
  566. if userInfo != nil && len(*userInfo) > 0 {
  567. uId = gconv.String((*userInfo)["uid"])
  568. source = gconv.String((*userInfo)["source"])
  569. } else {
  570. log.Println("后台订单--未查询到 ", query, userPhone)
  571. break
  572. }
  573. is_assign := 1
  574. mailContent := ""
  575. cluename = gconv.String(v["company_name"])
  576. mailContent = fmt.Sprintf("%s(%s)", cluename, userPhone)
  577. if cluename == "" {
  578. cluename = userPhone
  579. mailContent = userPhone
  580. }
  581. if payMoney > 0 {
  582. trailstatus = "08"
  583. } else {
  584. trailstatus = "01"
  585. }
  586. isGroup, isCommerce := GetCompanyType(cluename, uId) //判断是否集团公司、工商库
  587. clueData := TiDb.FindOne("dwd_f_crm_clue_info", map[string]interface{}{"uid": uId}, "", "")
  588. if clueData == nil || len(*clueData) == 0 {
  589. log.Println("saleDep", saleDep)
  590. if saleDep == "销售部" {
  591. //撞单
  592. log.Println("销售部订单", saleDep)
  593. if strings.Contains(salesperson, ",") {
  594. log.Println("销售部撞单 ", salesperson)
  595. if salesperson == "" {
  596. salesperson = createperson
  597. }
  598. }
  599. log.Println("销售部订单salesperson", salesperson)
  600. saleData := TiDb.FindOne("dwd_f_crm_personnel_management", map[string]interface{}{"name": salesperson}, "", "")
  601. if saleData != nil {
  602. seatNumber = gconv.String((*saleData)["seat_number"])
  603. positionId = common.Int64All((*saleData)["position_id"])
  604. }
  605. if IsFreeze(source, payMoney, gconv.String(positionId), trailstatus) {
  606. //线索需要冻结
  607. is_assign = -3
  608. }
  609. clueId = TiDb.Insert("dwd_f_crm_clue_info", map[string]interface{}{
  610. "userid": userId,
  611. "uid": uId,
  612. "seatNumber": seatNumber,
  613. "position_id": positionId,
  614. "is_assign": is_assign,
  615. "comeintime": nowTime,
  616. "createtime": nowTime,
  617. "updatetime": nowTime,
  618. "cluename": cluename,
  619. "top_cluetype": "4",
  620. "sub_cluetype": "154",
  621. "trailstatus": trailstatus,
  622. "name": userPhone,
  623. "phone": userPhone,
  624. "comeinsource_private": 2,
  625. "is_task": 0,
  626. "taskstatus": 0,
  627. "company_nature": isGroup,
  628. "company_verification": isCommerce,
  629. "FREEZE_TIME": nowTime,
  630. })
  631. } else if saleDep == "市场部" {
  632. log.Println("市场部订单", saleDep)
  633. clueId = TiDb.Insert("dwd_f_crm_clue_info", map[string]interface{}{
  634. "userid": userId,
  635. "uid": uId,
  636. "is_assign": -2,
  637. "createtime": nowTime,
  638. "updatetime": nowTime,
  639. "cluename": cluename,
  640. "top_cluetype": "4",
  641. "sub_cluetype": "154",
  642. "trailstatus": trailstatus,
  643. "name": userPhone,
  644. "phone": userPhone,
  645. "is_task": 0,
  646. "taskstatus": 0,
  647. "company_nature": isGroup,
  648. "company_verification": isCommerce,
  649. "FREEZE_TIME": nowTime,
  650. })
  651. }
  652. if clueId > 0 {
  653. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  654. "clue_id": clueId,
  655. "position_id": common.If(positionId > 0, positionId, -1),
  656. "change_type": "创建线索",
  657. "new_value": "系统自动创建",
  658. "createtime": nowTime,
  659. "BCPCID": common.GetRandom(32),
  660. "operator_id": -1,
  661. })
  662. if is_assign == -3 {
  663. //新增冻结记录
  664. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  665. "clue_id": clueId,
  666. "position_id": positionId,
  667. "change_type": "线索冻结",
  668. "new_value": "销售人员私海已达上限",
  669. "createtime": nowTime,
  670. "BCPCID": common.GetRandom(32),
  671. "operator_id": -1,
  672. })
  673. //移交失败发送消息
  674. if IsFreeze(source, payMoney, gconv.String(positionId), trailstatus) {
  675. //发送邮件信息
  676. OrderCreateFail(positionId, mailContent)
  677. }
  678. }
  679. }
  680. }
  681. }
  682. cfg.LastOrderClueId = gconv.String(v["update_time"])
  683. }
  684. }
  685. common.WriteSysConfig(&cfg)
  686. log.Println("后台订单线索定时任务结束")
  687. }
  688. func refundAuto() {
  689. log.Println("自动移交销售定时任务开始")
  690. findNowTime := time.Now().AddDate(0, 0, -db.ExpirationPeriod).Format(date.Date_Full_Layout)
  691. nowTime := time.Now().Format(date.Date_Full_Layout)
  692. mailData := map[string][]map[string]interface{}{}
  693. salesEmailData := map[int64][]map[string]interface{}{}
  694. TiDb.SelectByBath(100, func(l *[]map[string]interface{}) bool {
  695. for _, v := range *l {
  696. cluename, company_nature, company_verification, uid, phone, userName, oldSaleId, oldsaleName := "", 0, 0, "", "", "", int64(0), ""
  697. saleId, newSeatNumber, newPerson := int64(0), "", ""
  698. clueId := common.Int64All(v["clue_id"])
  699. company_name := gconv.String(v["company_name"])
  700. name := gconv.String(v["name"])
  701. kcposition_id := common.Int64All(v["position_id"])
  702. isRenewalProtection := common.IntAll(v["is_renewal_protection"])
  703. clueData := TiDb.FindOne("dwd_f_crm_clue_info", map[string]interface{}{"id": clueId}, "name,phone,company_nature,company_verification,cluename,userid,position_id,uid", "")
  704. if clueData != nil && len(*clueData) > 0 {
  705. uid = gconv.String((*clueData)["uid"])
  706. saleId, newPerson, newSeatNumber = FindPositionIdClueId(uid)
  707. oldSaleId = common.Int64All((*clueData)["position_id"])
  708. oldPersonData := FindPersonOne(oldSaleId)
  709. if oldSaleId != 0 {
  710. oldsaleName = gconv.String(oldPersonData["name"])
  711. }
  712. cluename = gconv.String((*clueData)["cluename"])
  713. userName = gconv.String((*clueData)["name"])
  714. company_nature = common.IntAll((*clueData)["company_nature"])
  715. company_verification = common.IntAll((*clueData)["company_verification"])
  716. phone = gconv.String((*clueData)["phone"])
  717. }
  718. personArr := getUserIdToUid(uid)
  719. productArr, _ := KcProduct()
  720. if len(productArr) == 0 || len(personArr) == 0 {
  721. log.Println("查询不到进客成商品类型或查询不到用户信息")
  722. continue
  723. }
  724. //查询即将到期数据
  725. if isRenewalProtection == 0 {
  726. sqlStr := fmt.Sprintf(`select a.*,b.product_type as productType,b.service_starttime,b.service_endtime,b.filter AS productFilter from dataexport_order a INNER JOIN jy_order_detail b on a.order_code=b.order_code and a.user_id in (%s) and b.product_type in (%s) ORDER BY b.service_endtime desc `, strings.Join(personArr, ","), strings.Join(productArr, ","))
  727. _, vipEndDateStr := getOrderData(sqlStr)
  728. if vipEndDateStr != "" {
  729. endDate := time.Now().AddDate(0, 0, -db.ExpirationPeriod+3).Unix()
  730. startDate := time.Now().AddDate(0, 0, -db.ExpirationPeriod+2).Unix()
  731. vipEndDate, _ := time.ParseInLocation(time.DateTime, vipEndDateStr, time.Local)
  732. log.Println(vipEndDate.Unix() > startDate, vipEndDate.Unix() < endDate)
  733. log.Println(vipEndDate.Unix(), startDate, endDate)
  734. if vipEndDate.Unix() > startDate && vipEndDate.Unix() < endDate {
  735. //即将到期
  736. mailData[name] = append(mailData[name], map[string]interface{}{
  737. "company_name": company_name,
  738. "phone": phone,
  739. "userName": userName,
  740. "remrk": "3天后即将移交",
  741. "reason": "成交客户续费失败",
  742. })
  743. continue
  744. }
  745. }
  746. }
  747. isFull := false
  748. isAllRefund := false
  749. orderSql := fmt.Sprintf(` select a.*,b.product_type as productType,b.service_starttime,b.service_endtime,b.filter AS productFilter from dataexport_order a INNER JOIN jy_order_detail b on a.order_code=b.order_code and a.user_id in (%s) and b.product_type in (%s) and order_status = 1 ORDER BY b.service_endtime desc `, strings.Join(personArr, ","), strings.Join(productArr, ","))
  750. myOrders, _ := getOrderData(orderSql)
  751. if myOrders != nil || len(myOrders) > 0 {
  752. refundCount := 0
  753. for _, v := range myOrders {
  754. if common.IntAll(v["refund_status"]) == 1 {
  755. refundCount++
  756. }
  757. }
  758. if len(myOrders) > 0 && len(myOrders) == refundCount {
  759. isAllRefund = true
  760. }
  761. }
  762. if isAllRefund {
  763. //全退款了
  764. 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)
  765. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  766. "clue_id": clueId,
  767. "position_id": common.If(kcposition_id > 0, kcposition_id, -1),
  768. "change_type": "退回公海",
  769. "new_value": "成交客户申请退款",
  770. "createtime": nowTime,
  771. "BCPCID": common.GetRandom(32),
  772. "operator_id": -1,
  773. })
  774. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  775. "clue_id": clueId,
  776. "position_id": common.If(kcposition_id > 0, kcposition_id, -1),
  777. "change_field": "trailstatus",
  778. "change_type": "基本信息变更",
  779. "old_value": "成交客户",
  780. "new_value": "商机线索",
  781. "createtime": nowTime,
  782. "BCPCID": common.GetRandom(32),
  783. "operator_id": -1,
  784. })
  785. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  786. "clue_id": clueId,
  787. "position_id": common.If(kcposition_id > 0, kcposition_id, -1),
  788. "change_type": "客户成功经理",
  789. "change_field": "position_id",
  790. "old_value": name,
  791. "new_value": "/",
  792. "createtime": nowTime,
  793. "BCPCID": common.GetRandom(32),
  794. "operator_id": -1,
  795. })
  796. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  797. "clue_id": clueId,
  798. "position_id": common.If(kcposition_id > 0, kcposition_id, -1),
  799. "change_type": "移交销售",
  800. "new_value": "成交客户申请退款",
  801. "createtime": nowTime,
  802. "BCPCID": common.GetRandom(32),
  803. "operator_id": -1,
  804. })
  805. mailData[name] = append(mailData[name], map[string]interface{}{
  806. "company_name": company_name,
  807. "phone": phone,
  808. "userName": userName,
  809. "remrk": "已移交",
  810. "reason": "成交客户申请退款",
  811. })
  812. TiDb.UpdateOrDeleteBySql(`UPDATE dwd_f_csm_customer_info SET is_transfer=1 WHERE clue_id = ?`, clueId)
  813. } else {
  814. log.Println("客成到期处理")
  815. order1Sql := fmt.Sprintf(`select a.id from dataexport_order a INNER JOIN jy_order_detail b on a.order_code=b.order_code and a.user_id in (%s) and b.product_type in (%s) and order_status = 1 and b.service_endtime>"%s" ORDER BY b.service_endtime desc `, strings.Join(personArr, ","), strings.Join(productArr, ","), findNowTime)
  816. log.Println("有效订单查询", order1Sql)
  817. order1 := Mysql.SelectBySql(order1Sql)
  818. if order1 == nil || len(*order1) == 0 {
  819. isOk := false
  820. order3Sql := fmt.Sprintf(`select a.* , b.product_type AS productType,b.service_starttime,b.service_endtime ,b.filter AS productFilter
  821. from dataexport_order a INNER JOIN jy_order_detail b
  822. on a.order_code=b.order_code and a.user_id in (%s) and b.product_type in (%s)
  823. and order_status = 1 and b.service_endtime<"%s" ORDER BY b.service_endtime desc `,
  824. strings.Join(personArr, ","), strings.Join(productArr, ","), findNowTime)
  825. log.Println("有效订单查询1", order3Sql)
  826. _, vip_endtime := getOrderData(order3Sql)
  827. if vip_endtime != "" {
  828. //获取最后一个订单信息
  829. if isRenewalProtection == 1 {
  830. vip_endtimes, _ := time.ParseInLocation(date.Date_Full_Layout, vip_endtime, time.Local)
  831. //查询申请保护时间
  832. renewalTime := time.Now()
  833. timeData := TiDb.SelectBySql(`select max(createtime) as createtime from dwd_f_crm_clue_change_record where clue_id = ? and change_type="申请续费保护"`, clueId)
  834. if timeData != nil && len(*timeData) > 0 {
  835. if gconv.String(gconv.String((*timeData)[0]["createtime"])) != "" {
  836. renewalTime, _ = time.ParseInLocation(date.Date_Full_Layout, gconv.String((*timeData)[0]["createtime"]), time.Local)
  837. }
  838. }
  839. renewalInt := renewalTime.Unix()
  840. log.Println("申请保护期时间", clueId, renewalInt)
  841. log.Println("申请保护期时间222", time.Now().Unix()-vip_endtimes.Unix(), (db.HandoverCycle-1)*86400, (db.HandoverCycle)*86400)
  842. //查看服务到期时间
  843. if renewalInt != 0 && renewalInt < db.CustomerTime {
  844. //三个月
  845. if time.Now().Unix()-vip_endtimes.Unix() < 3*30*86400 {
  846. isOk = true
  847. }
  848. } else if (db.HandoverCycle-5)*86400 < time.Now().Unix()-vip_endtimes.Unix() && time.Now().Unix()-vip_endtimes.Unix() < (db.HandoverCycle-4)*86400 {
  849. //提前一天提示
  850. mailData[name] = append(mailData[name], map[string]interface{}{
  851. "company_name": company_name,
  852. "phone": phone,
  853. "userName": userName,
  854. "remrk": "3天后即将移交",
  855. "reason": "成交客户续费失败",
  856. })
  857. isOk = true
  858. } else if time.Now().Unix()-vip_endtimes.Unix() < db.HandoverCycle*86400 {
  859. isOk = true
  860. }
  861. }
  862. }
  863. if !isOk {
  864. //全到期了
  865. if saleId > 0 {
  866. saleData := TiDb.FindOne("dwd_f_crm_personnel_management", map[string]interface{}{"position_id": saleId, "resign": 0}, "", "")
  867. if saleData != nil && len(*saleData) > 0 {
  868. //该销售人没有变更
  869. } else {
  870. if company_nature == 0 && company_verification == 1 && cluename != "" {
  871. adata := TiDb.Find("dwd_f_crm_clue_info", map[string]interface{}{"cluename": cluename, "is_assign": 1}, "seatNumber,position_id", "", -1, -1)
  872. if adata != nil && len(*adata) > 0 {
  873. isOks := false
  874. for _, vv := range *adata {
  875. position_ids := common.Int64All(vv["position_id"])
  876. newSeatNumber = gconv.String(vv["seatNumber"])
  877. saleDatas := TiDb.FindOne("dwd_f_crm_personnel_management", map[string]interface{}{"position_id": position_ids, "resign": 0}, "", "")
  878. if saleDatas != nil && len(*saleDatas) > 0 {
  879. saleId = position_ids
  880. newPerson = gconv.String((*saleDatas)["name"])
  881. isOks = true
  882. break
  883. }
  884. }
  885. if !isOks {
  886. 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)
  887. if len(*sdata) == 0 {
  888. 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 = 8`, saleId)
  889. }
  890. if sdata != nil && len(*sdata) > 0 {
  891. saleId = common.Int64All((*sdata)[0]["position_id"])
  892. newSeatNumber = gconv.String((*sdata)[0]["seat_number"])
  893. newPerson = gconv.String((*sdata)[0]["name"])
  894. }
  895. }
  896. }
  897. } else {
  898. sdata := &[]map[string]interface{}{}
  899. //查看当前是否属于一部三部
  900. userData := FindPersonOne(saleId)
  901. if userData != nil {
  902. deptName := gconv.String(userData["dept_name"])
  903. if strings.Contains(deptName, "一部") {
  904. 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)
  905. if len(*sdata) == 0 {
  906. 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 = 8`, saleId)
  907. }
  908. } else if strings.Contains(deptName, "三部") {
  909. 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 = 8`, saleId)
  910. }
  911. }
  912. if sdata != nil && len(*sdata) > 0 {
  913. saleId = common.Int64All((*sdata)[0]["position_id"])
  914. newSeatNumber = gconv.String((*sdata)[0]["seat_number"])
  915. newPerson = gconv.String((*sdata)[0]["name"])
  916. }
  917. }
  918. }
  919. }
  920. if kcposition_id > 0 {
  921. mailData[name] = append(mailData[name], map[string]interface{}{
  922. "company_name": company_name,
  923. "phone": phone,
  924. "userName": userName,
  925. "remrk": "已移交",
  926. "reason": "成交客户续费失败",
  927. })
  928. }
  929. isFull = FindUpperLimit(gconv.String(saleId), "", false)
  930. if saleId > 0 {
  931. salesEmailData[saleId] = append(salesEmailData[saleId], map[string]interface{}{
  932. "company_name": company_name,
  933. "phone": phone,
  934. "userName": userName,
  935. "remrk": "已移交",
  936. "reason": "成交客户续费失败",
  937. "cluename": cluename,
  938. })
  939. if saleId != oldSaleId {
  940. //新增个人员变更
  941. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  942. "clue_id": clueId,
  943. "position_id": saleId,
  944. "change_field": "position_id",
  945. "change_type": "所属人变更",
  946. "old_value": common.If(oldsaleName != "", oldsaleName, "/"),
  947. "new_value": common.If(newPerson != "", newPerson, "/"),
  948. "createtime": nowTime,
  949. "BCPCID": common.GetRandom(32),
  950. "operator_id": -1,
  951. })
  952. if isFull {
  953. 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, newSeatNumber, nowTime, nowTime, clueId)
  954. } else {
  955. 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=1 WHERE id = ?`, nowTime, saleId, newSeatNumber, nowTime, clueId)
  956. }
  957. } else {
  958. if isFull {
  959. 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)
  960. } else {
  961. 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=1 WHERE id = ?`, nowTime, clueId)
  962. }
  963. }
  964. } else if saleId == 0 {
  965. //找不到人
  966. TiDb.UpdateOrDeleteBySql(`UPDATE dwd_f_crm_clue_info SET is_unfollow=0,updatetime=?,trailstatus="01",position_id=0,seatNumber="",is_task=1,tasktime=?,top_cluetype="532",sub_cluetype="537",taskstatus=0,tasksource="其他-成交客户续约失败",is_transfer=0,is_assign=0 WHERE id = ?`, nowTime, nowTime, clueId)
  967. if oldSaleId != 0 {
  968. //新增个人员变更
  969. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  970. "clue_id": clueId,
  971. "position_id": saleId,
  972. "change_field": "position_id",
  973. "change_type": "所属人变更",
  974. "old_value": common.If(oldsaleName != "", oldsaleName, "/"),
  975. "new_value": common.If(newPerson != "", newPerson, "/"),
  976. "createtime": nowTime,
  977. "BCPCID": common.GetRandom(32),
  978. "operator_id": -1,
  979. "SHUOMING": "业绩归属查不到人",
  980. })
  981. //再做一个记录变更
  982. }
  983. }
  984. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  985. "clue_id": clueId,
  986. "position_id": common.If(kcposition_id > 0, kcposition_id, -1),
  987. "change_type": "基本信息变更",
  988. "old_value": "成交客户",
  989. "change_field": "trailstatus",
  990. "new_value": "商机线索",
  991. "createtime": nowTime,
  992. "BCPCID": common.GetRandom(32),
  993. "operator_id": -1,
  994. })
  995. if saleId > 0 {
  996. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  997. "clue_id": clueId,
  998. "position_id": saleId,
  999. "change_type": "加入任务车",
  1000. "new_value": "线索自动分配-其他-成交客户续约失败",
  1001. "createtime": nowTime,
  1002. "BCPCID": common.GetRandom(32),
  1003. "operator_id": -1,
  1004. })
  1005. }
  1006. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  1007. "clue_id": clueId,
  1008. "position_id": common.If(kcposition_id > 0, kcposition_id, -1),
  1009. "change_type": "客户成功经理",
  1010. "change_field": "position_id",
  1011. "old_value": name,
  1012. "new_value": "/",
  1013. "createtime": nowTime,
  1014. "BCPCID": common.GetRandom(32),
  1015. "operator_id": -1,
  1016. })
  1017. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  1018. "clue_id": clueId,
  1019. "position_id": saleId,
  1020. "change_type": "移交销售",
  1021. "new_value": "成交客户续费失败,到期自动移交",
  1022. "createtime": nowTime,
  1023. "BCPCID": common.GetRandom(32),
  1024. "operator_id": -1,
  1025. })
  1026. TiDb.UpdateOrDeleteBySql(`UPDATE dwd_f_csm_customer_info SET is_transfer=1 WHERE clue_id = ?`, clueId)
  1027. if isFull {
  1028. //新增冻结记录
  1029. TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  1030. "clue_id": clueId,
  1031. "position_id": saleId,
  1032. "change_type": "线索冻结",
  1033. "new_value": "销售人员私海已达上限",
  1034. "createtime": nowTime,
  1035. "BCPCID": common.GetRandom(32),
  1036. "operator_id": -1,
  1037. })
  1038. //发送邮件
  1039. mailContent := ""
  1040. if cluename != "" {
  1041. if phone != "" {
  1042. if cluename == phone {
  1043. mailContent = phone
  1044. } else {
  1045. mailContent = fmt.Sprintf("%s(%s)", cluename, phone)
  1046. }
  1047. } else {
  1048. mailContent = cluename
  1049. }
  1050. } else {
  1051. mailContent = phone
  1052. }
  1053. HandOverFail(saleId, mailContent)
  1054. }
  1055. }
  1056. }
  1057. }
  1058. }
  1059. return true
  1060. }, `select ent_id,clue_id,position_id,name,is_renewal_protection,company_name from dwd_f_csm_customer_info where is_transfer = 0`)
  1061. //}, `select ent_id,clue_id,position_id,name,is_renewal_protection,company_name from dwd_f_csm_customer_info where clue_id =527993`)
  1062. //移交电销提醒
  1063. for i, v := range mailData {
  1064. ExitKcSend(i, v)
  1065. }
  1066. //移交电销销售提醒
  1067. for i, v := range salesEmailData {
  1068. ExitKcSaleSend(i, v)
  1069. }
  1070. log.Println("自动移交销售定时任务结束")
  1071. }
  1072. // 查找一部三部人员信息 返回人员信息 以及管理员信息
  1073. func FindDeptAdmin(positionId int64) (map[string]interface{}, map[string]interface{}, map[string]interface{}) {
  1074. //先判断那个部门的
  1075. userData1 := TiDb.SelectBySql(`SELECT
  1076. a.position_id,
  1077. a.name,
  1078. b.seat_number,
  1079. b.role_id,
  1080. a.bi_pcode,
  1081. a.dept_name,
  1082. a.resign
  1083. FROM
  1084. (SELECT *
  1085. FROM dwd_d_crm_department_level_succbi u1
  1086. WHERE id = (
  1087. SELECT MAX(id)
  1088. FROM dwd_d_crm_department_level_succbi u2
  1089. WHERE u1.position_id = u2.position_id
  1090. )
  1091. ORDER BY id desc) a
  1092. INNER JOIN (SELECT *
  1093. FROM dwd_f_crm_personnel_management u1
  1094. WHERE id = (
  1095. SELECT MAX(id)
  1096. FROM dwd_f_crm_personnel_management u2
  1097. WHERE u1.position_id = u2.position_id
  1098. )
  1099. ORDER BY id desc) b ON a.dept_name LIKE "%销售一部%"
  1100. AND a.position_id = b.position_id`)
  1101. userData3 := TiDb.SelectBySql(`SELECT
  1102. a.position_id,
  1103. a.name,
  1104. b.seat_number,
  1105. b.role_id,
  1106. a.bi_pcode,
  1107. a.dept_name,
  1108. a.resign
  1109. FROM
  1110. (SELECT *
  1111. FROM dwd_d_crm_department_level_succbi u1
  1112. WHERE id = (
  1113. SELECT MAX(id)
  1114. FROM dwd_d_crm_department_level_succbi u2
  1115. WHERE u1.position_id = u2.position_id
  1116. )
  1117. ORDER BY id desc) a
  1118. INNER JOIN (SELECT *
  1119. FROM dwd_f_crm_personnel_management u1
  1120. WHERE id = (
  1121. SELECT MAX(id)
  1122. FROM dwd_f_crm_personnel_management u2
  1123. WHERE u1.position_id = u2.position_id
  1124. )
  1125. ORDER BY id desc) b ON
  1126. a.dept_name LIKE "%销售三部"
  1127. AND a.position_id = b.position_id`)
  1128. if userData3 == nil || len(*userData3) == 0 || userData1 == nil || len(*userData1) == 0 {
  1129. log.Println("找不到一部三部员工信息")
  1130. return nil, nil, nil
  1131. }
  1132. //一部高级管理员信息
  1133. seniorAdmin1 := map[string]interface{}{}
  1134. //三部高级管理员信息
  1135. seniorAdmin3 := map[string]interface{}{}
  1136. //一部管理员信息
  1137. admin1 := map[string]map[string]interface{}{}
  1138. //返回当前人信息
  1139. admin := map[string]interface{}{}
  1140. for _, v := range *userData3 {
  1141. v["type"] = 3
  1142. id := gconv.Int64(v["position_id"])
  1143. roleId := gconv.Int64(v["role_id"])
  1144. resign := gconv.Int64(v["resign"])
  1145. if id == positionId && resign == 0 {
  1146. admin = v
  1147. }
  1148. if roleId == 8 {
  1149. v["orderStatus"] = 2
  1150. seniorAdmin3 = v
  1151. }
  1152. }
  1153. for _, v := range *userData1 {
  1154. v["type"] = 1
  1155. id := gconv.Int64(v["position_id"])
  1156. roleId := gconv.Int64(v["role_id"])
  1157. dept_name := gconv.String(v["dept_name"])
  1158. resign := gconv.Int64(v["resign"])
  1159. if id == positionId && resign == 0 {
  1160. admin = v
  1161. }
  1162. if roleId == 8 {
  1163. v["orderStatus"] = 2
  1164. seniorAdmin1 = v
  1165. } else if roleId == 3 {
  1166. admin1[dept_name] = v
  1167. }
  1168. }
  1169. //查看当前人属于哪个部门
  1170. if admin == nil {
  1171. //当前人不属于电销部的
  1172. admin = *(TiDb.FindOne("dwd_f_crm_personnel_management", map[string]interface{}{
  1173. "position_id": positionId,
  1174. "resign": 1,
  1175. }, "name", ""))
  1176. }
  1177. positiontype := gconv.Int64(admin["type"])
  1178. deptName := gconv.String(admin["dept_name"])
  1179. switch positiontype {
  1180. case 1:
  1181. roleId := gconv.Int64(admin["role_id"])
  1182. if roleId == 3 {
  1183. return admin, nil, seniorAdmin1
  1184. }
  1185. return admin, admin1[deptName], seniorAdmin1
  1186. case 3:
  1187. return admin, nil, seniorAdmin3
  1188. default:
  1189. return admin, nil, nil
  1190. }
  1191. }
  1192. // 邮箱获取
  1193. func GetMail(personName string) (string, string) {
  1194. data := Mysql.SelectBySql(`select name,mail,img from entniche_user where ent_id =?`, db.EntId)
  1195. if data == nil || len(*data) == 0 {
  1196. return "", ""
  1197. }
  1198. for _, m := range *data {
  1199. name := gconv.String(m["name"])
  1200. if name == personName {
  1201. //
  1202. return gconv.String(m["mail"]), gconv.String(m["img"])
  1203. }
  1204. }
  1205. return "", ""
  1206. }
  1207. // 退客成进销售 销售收邮件
  1208. func ExitKcSaleSend(positionId int64, infoList []map[string]interface{}) {
  1209. to := SaleMail(positionId)
  1210. //退出客成 即将退出客成信息 销售信息编辑
  1211. gmail := &mail.GmailAuth{
  1212. SmtpHost: db.Mail.SmtpHost,
  1213. SmtpPort: db.Mail.SmtpPort,
  1214. User: db.Mail.User,
  1215. Pwd: db.Mail.Pwd,
  1216. }
  1217. //正文拼接
  1218. startStr := `<html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, initial-scale=1.0">
  1219. <style>table{width:100%;border-collapse:collapse}th,td{border:1px solid#000;padding:8px;text-align:left}th{background-color:#f2f2f2}</style></head>
  1220. <body><p>以下客户已从或即将从客成系统退出,并移交销售跟进,请收悉,客户明细如下:</p>
  1221. <table><thead><tr><th>序号</th><th>线索名称</th><th>联系人</th><th>姓名</th><th>移交状态</th></tr></thead><tbody>`
  1222. for i, v := range infoList {
  1223. startStr += fmt.Sprintf(`<tr><td>%d</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>`, i+1, gconv.String(v["cluename"]), gconv.String(v["phone"]), gconv.String(v["userName"]), gconv.String(v["remrk"]))
  1224. }
  1225. endStr := `</tbody></table><p></body></html>`
  1226. startStr += endStr
  1227. if to != "" {
  1228. status := mail.GSendMail_q("剑鱼标讯", to, "", "", "成交客户续费失败移交销售通知", startStr, "", "", gmail)
  1229. if status {
  1230. log.Println("客成发邮件 send mail success", startStr, to)
  1231. }
  1232. }
  1233. }
  1234. // 客成人员变更发邮件
  1235. func CustomerChange() {
  1236. personMap := map[int64]string{}
  1237. personData := TiDb.SelectBySql(`select name,position_id from dwd_d_crm_department_level_succbi where ent_id=? and resign=0 and position_id>0`, db.EntId)
  1238. if personData != nil && len(*personData) > 0 {
  1239. for _, v := range *personData {
  1240. personMap[gconv.Int64(v["position_id"])] = gconv.String(v["name"])
  1241. }
  1242. }
  1243. startTime := cfg.LastKcChangeTime
  1244. if startTime == "" {
  1245. startTime = time.Now().Format(time.DateTime)
  1246. }
  1247. customMap1 := map[string][]map[string]interface{}{}
  1248. customMap2 := map[string][]map[string]interface{}{}
  1249. saleMap := map[int64][]map[string]interface{}{}
  1250. saleNobodyCustomMapMap := map[int64][]map[string]interface{}{}
  1251. TiDb.SelectByBath(100, func(l *[]map[string]interface{}) bool {
  1252. for _, v := range *l {
  1253. startTime = gconv.String(v["createtime"])
  1254. data := CustomerChangeHandle(v)
  1255. oldPerson := gconv.String(data["oldPerson"])
  1256. newPerson := gconv.String(data["newPerson"])
  1257. positionId := gconv.Int64(data["positionId"])
  1258. operatorId := gconv.Int64(data["operatorId"])
  1259. if oldPerson == "/" {
  1260. data["oldPerson"] = "-"
  1261. }
  1262. if positionId > 0 {
  1263. data["positionName"] = personMap[positionId]
  1264. }
  1265. if operatorId > 0 {
  1266. //手动分配 客成收邮件
  1267. data["operatorName"] = personMap[operatorId]
  1268. if newPerson != "" && newPerson != "/" {
  1269. customMap2[newPerson] = append(customMap2[newPerson], data)
  1270. }
  1271. if oldPerson != "" && oldPerson != "/" {
  1272. customMap1[oldPerson] = append(customMap1[oldPerson], data)
  1273. }
  1274. } else {
  1275. //自动分配 销售收邮件
  1276. if (oldPerson == "" || oldPerson == "/") && newPerson != "" && newPerson != "/" && positionId > 0 {
  1277. //之前没有可成人员
  1278. saleNobodyCustomMapMap[positionId] = append(saleNobodyCustomMapMap[positionId], data)
  1279. } else if newPerson != "" && newPerson != "/" && oldPerson != "" && oldPerson != "/" && positionId > 0 {
  1280. //之前有客成
  1281. saleMap[positionId] = append(saleMap[positionId], data)
  1282. }
  1283. }
  1284. }
  1285. return true
  1286. }, `select operator_id, clue_id,position_id,old_value,new_value,createtime from dwd_f_crm_clue_change_record where createtime>? and change_type="客户成功经理" order by createtime`, startTime)
  1287. //}, `select operator_id, clue_id,position_id,old_value,new_value,createtime from dwd_f_crm_clue_change_record where id=? order by createtime`, 22170775)
  1288. if len(customMap1) > 0 {
  1289. ChangeSendKc(customMap1, 1)
  1290. }
  1291. if len(customMap2) > 0 {
  1292. ChangeSendKc(customMap2, 2)
  1293. }
  1294. if len(saleMap) > 0 {
  1295. ChangeSendSale(saleMap, 2)
  1296. }
  1297. if len(saleNobodyCustomMapMap) > 0 {
  1298. ChangeSendSale(saleNobodyCustomMapMap, 1)
  1299. }
  1300. log.Println("11111", startTime)
  1301. cfg.LastKcChangeTime = startTime
  1302. common.WriteSysConfig(&cfg)
  1303. }
  1304. // 客户成功经理变更邮件提醒客成人员
  1305. func ChangeSendKc(data map[string][]map[string]interface{}, personType int64) {
  1306. for name, v := range data {
  1307. to, _ := GetMail(name)
  1308. //正文拼接
  1309. 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>
  1310. <table><thead><tr><th>序号</th><th>公司名称</th><th>联系人</th><th>姓名</th><th>变更前客户经理</th><th>变更后客户经理</th><th>操作人</th></tr></thead><tbody>`
  1311. for i, v := range v {
  1312. startStr += fmt.Sprintf(`<tr><td>%d</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>`, i+1, gconv.String(v["companyName"]), gconv.String(v["phone"]), gconv.String(v["userName"]), gconv.String(v["oldPerson"]), gconv.String(v["newPerson"]), gconv.String(v["operatorName"]))
  1313. }
  1314. endStr := `</tbody></table><p></body></html>`
  1315. startStr += endStr
  1316. if to != "" {
  1317. status := mail.GSendMail_q("剑鱼标讯", to, "", "", gconv.String(common.If(personType == 2, "您有新的客户,请及时跟进处理", "您的客户已转至其他客户成功经理负责")), startStr, "", "", &Gmail)
  1318. if status {
  1319. log.Println("客成发邮件 send mail success", startStr, to, "")
  1320. }
  1321. }
  1322. }
  1323. }
  1324. func ChangeSendSale(data map[int64][]map[string]interface{}, personType int64) {
  1325. log.Println("客成人员变更", personType, data)
  1326. if personType == 1 {
  1327. //客户成功经理从空变成有人
  1328. for _, v := range data {
  1329. for _, v1 := range v {
  1330. positionId := gconv.Int64(v1["positionId"])
  1331. to := SaleMail(positionId)
  1332. _, img := GetMail(gconv.String(v1["newPerson"]))
  1333. //抄送人查询
  1334. startStr := `<style> *,body,html{margin:10px;font-family:tahoma,arial,'Hiragino Sans GB','Microsoft YaHei',宋体,ans-serif;font-size:16px;}p{margin:15px;font-size:18px;}table{background-color: rgb(244, 244, 249);padding:5px 15px;border:solid 1px #ddd;margin: 20px 0px 20px 50px;vertical-align:top;display:inline-block;}.tit{width:120px;}td{padding: 5px;}.clear{clear: both;}</style>
  1335. <p>销售人员"%s"成交的客户已成功移交至客成,线索名称:%s,姓名:%s,手机号:%s,负责客户成功经理:%s</p>
  1336. <p>请引导客户添加客户成功经理企业微信:</p><div class='clear'>%s</div>`
  1337. endStr := fmt.Sprintf(startStr, gconv.String(v1["positionName"]), gconv.String(v1["clueName"]), gconv.String(v1["userName"]), gconv.String(v1["phone"]), gconv.String(v1["newPerson"]), common.If(img != "", fmt.Sprintf(`<img width="300" height="450" src="%s">`, img), ""))
  1338. if to != "" {
  1339. status := mail.GSendMail_q("剑鱼标讯", to, "", "", "成交客户已成功移交客成", endStr, "", "", &Gmail)
  1340. if status {
  1341. log.Println("客成发邮件 send mail success", endStr, to, "")
  1342. }
  1343. }
  1344. }
  1345. }
  1346. return
  1347. }
  1348. //客户成功经理从A变成了B
  1349. for positionId, v := range data {
  1350. to := SaleMail(positionId)
  1351. //正文拼接
  1352. 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>客户明细如下:
  1353. </p><table><thead><tr><th>序号</th><th>线索名称</th><th>联系人</th><th>姓名</th><th>变更前客户经理</th><th>变更后客户经理</th><th>销售人员</th></tr></thead><tbody>`
  1354. for i, v := range v {
  1355. startStr += fmt.Sprintf(`<tr><td>%d</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>`,
  1356. i+1, gconv.String(v["clueName"]), gconv.String(v["phone"]), gconv.String(v["userName"]), gconv.String(v["oldPerson"]), gconv.String(v["newPerson"]), gconv.String(v["positionName"]))
  1357. }
  1358. endStr := `</tbody></table><p></body></html>`
  1359. startStr += endStr
  1360. if to != "" {
  1361. status := mail.GSendMail_q("剑鱼标讯", to, "", "", "成交客户负责客户成功经理变更", startStr, "", "", &Gmail)
  1362. if status {
  1363. log.Println("客成发邮件 send mail success", startStr, to, "")
  1364. }
  1365. }
  1366. }
  1367. }
  1368. // 客成人员变更基本信息获取
  1369. func CustomerChangeHandle(data map[string]interface{}) map[string]interface{} {
  1370. clueId := gconv.Int64(data["clue_id"])
  1371. oldPerson := gconv.String(data["old_value"])
  1372. newPerson := gconv.String(data["new_value"])
  1373. operatorId := gconv.Int64(data["operator_id"])
  1374. companyName := ""
  1375. phone := ""
  1376. userName := ""
  1377. clueName := ""
  1378. clueData := TiDb.FindOne("dwd_f_crm_clue_info", map[string]interface{}{
  1379. "id": clueId,
  1380. }, "", "")
  1381. if clueData == nil || len(*clueData) == 0 {
  1382. return nil
  1383. }
  1384. uid := gconv.String((*clueData)["uid"])
  1385. phone = gconv.String((*clueData)["phone"])
  1386. userName = gconv.String((*clueData)["name"])
  1387. //positionId := gconv.Int64((*clueData)["position_id"])
  1388. positionId, _, _ := FindPositionIdClueId(uid)
  1389. clueName = gconv.String((*clueData)["cluename"])
  1390. customData := TiDb.FindOne("dwd_f_csm_customer_info", map[string]interface{}{
  1391. "clue_id": clueId,
  1392. }, "", "")
  1393. if customData != nil || len(*customData) != 0 {
  1394. companyName = gconv.String((*customData)["company_name"])
  1395. }
  1396. return map[string]interface{}{
  1397. "oldPerson": oldPerson,
  1398. "newPerson": newPerson,
  1399. "operatorId": operatorId,
  1400. "phone": phone,
  1401. "userName": userName,
  1402. "positionId": positionId,
  1403. "clueName": clueName,
  1404. "companyName": companyName,
  1405. }
  1406. }
  1407. // 查找订单实际业绩归属
  1408. func FindPositionIdClueId(uid string) (int64, string, string) {
  1409. personArr := getUserIdToUid(uid)
  1410. productArr, _ := KcProduct()
  1411. querySql := fmt.Sprintf(` SELECT
  1412. d.saler_name as salesperson ,c.position_id,f.dept_name,c.seat_number,b.product_type as productType,b.filter
  1413. FROM
  1414. jianyu.dataexport_order a INNER JOIN jianyu.jy_order_detail b on
  1415. a.order_code=b.order_code and a.user_id in (%s)
  1416. AND (
  1417. b.final_price > 0
  1418. OR (
  1419. b.final_price = 0
  1420. AND ( a.zero_type= "分期付款权益补充" OR a.zero_type= "原订单不支持开通多项权益" OR a.zero_type= "权益码兑换" )))
  1421. AND a.order_status = 1 and a.user_phone not like "%s"
  1422. AND ( a.refund_status != 1 OR a.refund_status IS NULL )
  1423. AND b.service_starttime < "2099-01-01"
  1424. AND b.product_type IN (%s )
  1425. AND ( b.service_type != 4 or b.service_type is NULL OR ( b.service_type = 4 AND TIMESTAMPDIFF(DAY, b.service_starttime, b.service_endtime )> 90 ) )
  1426. inner JOIN jianyu.order_sale_record d on b.order_code=d.ordercode and d.state=1
  1427. INNER JOIN jianyu.entniche_user e on d.ent_userId = e.id
  1428. INNER JOIN dwd_f_crm_personnel_management c on c.ent_id =? and e.name=c.name
  1429. inner join dwd_d_crm_department_level_succbi f on c.position_id=f.position_id
  1430. ORDER BY
  1431. b.service_endtime desc ,b.final_price DESC `, strings.Join(personArr, ","), "9%", strings.Join(productArr, ","))
  1432. log.Println("业绩归属查询:", querySql)
  1433. clueData := TiDb.SelectBySql(querySql, db.EntId)
  1434. if clueData == nil || len(*clueData) == 0 {
  1435. return 0, "", ""
  1436. }
  1437. for _, m := range *clueData {
  1438. productType := gconv.String(m["productType"])
  1439. if productType == "大会员" {
  1440. level := gconv.Int(m["service_type"])
  1441. if level == 4 {
  1442. continue
  1443. }
  1444. }
  1445. deptName := gconv.String(m["dept_name"])
  1446. if strings.Contains(deptName, "一部") || strings.Contains(deptName, "三部") {
  1447. return gconv.Int64(m["position_id"]), gconv.String(m["salesperson"]), gconv.String(m["seat_number"])
  1448. }
  1449. }
  1450. return 0, "", ""
  1451. }
  1452. func refundAutoHistory() {
  1453. data := TiDb.Find("dwd_f_crm_clue_autodraw_record", nil, "", "", -1, -1)
  1454. if data != nil {
  1455. for _, v := range *data {
  1456. seatNumber := gconv.String(v["seatNumber"])
  1457. adata := TiDb.Find("dwd_f_crm_personnel_management", map[string]interface{}{"seat_number": seatNumber}, "", "", -1, -1)
  1458. if adata != nil {
  1459. for _, vv := range *adata {
  1460. if common.IntAll(vv["resign"]) == 0 {
  1461. position_id := common.Int64All(vv["position_id"])
  1462. TiDb.Update("dwd_f_crm_clue_autodraw_record", map[string]interface{}{"seatNumber": seatNumber}, map[string]interface{}{"position_id": position_id})
  1463. break
  1464. }
  1465. }
  1466. }
  1467. }
  1468. }
  1469. }
  1470. func IsFreeze(source string, pay_money int, positionId, trailstatus string) bool {
  1471. log.Println(source, pay_money == 0, FindUpperLimit(gconv.String(
  1472. positionId), "", false), trailstatus)
  1473. if source == "0104" && pay_money == 0 && FindUpperLimit(gconv.String(
  1474. positionId), "", false) {
  1475. return true
  1476. } else if source == "0104" && pay_money > 0 && trailstatus == "08" && FindUpperLimit(gconv.String(
  1477. positionId), "", false) {
  1478. return true
  1479. }
  1480. return false
  1481. }
  1482. // 业绩归属查询
  1483. func FindSaleRecord(orderCode string) (dept string, positionId int64, position string) {
  1484. recordList := Mysql.SelectBySql(`
  1485. SELECT DISTINCT
  1486. a.saler_dept,
  1487. a.saler_name,
  1488. b.phone
  1489. FROM
  1490. order_sale_record a
  1491. INNER JOIN entniche_user b
  1492. on
  1493. a.ordercode = ? and a.ent_userId = b.id
  1494. ORDER BY
  1495. a.state,
  1496. a.money desc
  1497. `, orderCode)
  1498. if recordList != nil && len(*recordList) > 0 {
  1499. saler_dept := gconv.String((*recordList)[0]["saler_dept"])
  1500. if strings.Contains(saler_dept, "销售") {
  1501. saler_dept = "销售部"
  1502. } else if strings.Contains(saler_dept, "市场") {
  1503. saler_dept = "市场部"
  1504. } else if strings.Contains(saler_dept, "客户成功") && !strings.Contains(saler_dept, "客服") {
  1505. saler_dept = "客户成功部"
  1506. } else {
  1507. saler_dept = ""
  1508. }
  1509. positionid := PhoneToPositionId(gconv.String((*recordList)[0]["phone"]))
  1510. if positionid > 0 {
  1511. return saler_dept, positionid, gconv.String((*recordList)[0]["saler_name"])
  1512. }
  1513. }
  1514. return "", int64(0), ""
  1515. }
  1516. func PhoneToPositionId(phone string) int64 {
  1517. positionId := int64(0)
  1518. data := Base.SelectBySql(`SELECT
  1519. b.id
  1520. FROM
  1521. base_user a
  1522. INNER JOIN base_position b ON a.phone = ?
  1523. AND a.id = b.user_id
  1524. AND b.ent_id = 25917`, phone)
  1525. if data != nil && len(*data) > 0 {
  1526. positionId = gconv.Int64((*data)[0]["id"])
  1527. }
  1528. return positionId
  1529. }
  1530. func kcClue(userId, uId, seatNumber, cluename, top_cluetype, sub_cluetype,
  1531. name, phone, position, sourceCode, industry, follow_project_area,
  1532. role, item, subname, topname, remark, demand, department, departments, saleName, source string, positionId int64, isGroup, isCommerce int, keywords []string) bool {
  1533. clueId, uodateId1, uodateId2, uodateId3, uodateId4, uodateId5 := int64(0), int64(0), int64(0), int64(0), int64(0), int64(0)
  1534. nowTime := time.Now().Format("2006-01-02 15:04:05")
  1535. nowTimes := time.Unix(time.Now().Unix()+3600*12, 0).Format("2006-01-02 15:04:05")
  1536. if TiDb.ExecTx("保存线索", func(tx *sql.Tx) bool {
  1537. clueId = TiDb.InsertByTx(tx, "dwd_f_crm_clue_info", map[string]interface{}{
  1538. "userid": userId,
  1539. "uid": uId,
  1540. "seatNumber": seatNumber,
  1541. "position_id": positionId,
  1542. "is_assign": common.If(positionId > 0, 1, 0),
  1543. "comeintime": nowTime,
  1544. "createtime": nowTime,
  1545. "updatetime": nowTime,
  1546. "cluename": cluename,
  1547. "top_cluetype": top_cluetype,
  1548. "sub_cluetype": sub_cluetype,
  1549. "trailstatus": "01",
  1550. "name": name,
  1551. "phone": phone,
  1552. "position": position,
  1553. "department": common.If(sourceCode == "app_xzcyh", departments, department),
  1554. "industry": industry,
  1555. "follow_project_area": follow_project_area,
  1556. "role": role,
  1557. "comeinsource_private": 2,
  1558. "is_task": 1,
  1559. "task_time": nowTime,
  1560. "tasktime": common.If(item == "users", nowTimes, nowTime),
  1561. "taskstatus": 0,
  1562. "tasksource": "线索自动分配" + "-" + topname + "-" + subname,
  1563. "business_scope": common.If(sourceCode == "app_xzcyh", keywords, nil),
  1564. "company_nature": isGroup,
  1565. "company_verification": isCommerce,
  1566. "remark": remark,
  1567. "customer_demand": demand,
  1568. "FREEZE_TIME": nowTime,
  1569. "label": 1,
  1570. "labelChangeTime": time.Now().Format("2006-01-02"),
  1571. })
  1572. uodateId1 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  1573. "clue_id": clueId,
  1574. "position_id": positionId,
  1575. "change_type": "创建线索",
  1576. "new_value": "系统自动创建",
  1577. "createtime": nowTime,
  1578. "BCPCID": common.GetRandom(32),
  1579. "operator_id": -1,
  1580. })
  1581. uodateId2 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  1582. "clue_id": clueId,
  1583. "position_id": positionId,
  1584. "change_field": "position_id",
  1585. "change_type": "所属人变更",
  1586. "old_value": "/",
  1587. "new_value": saleName,
  1588. "createtime": nowTime,
  1589. "BCPCID": common.GetRandom(32),
  1590. "operator_id": -1,
  1591. })
  1592. uodateId3 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  1593. "clue_id": clueId,
  1594. "position_id": positionId,
  1595. "change_field": "trailstatus",
  1596. "change_type": "基本信息变更",
  1597. "old_value": "商机线索",
  1598. "new_value": "新增",
  1599. "createtime": nowTime,
  1600. "BCPCID": common.GetRandom(32),
  1601. "operator_id": -1,
  1602. })
  1603. uodateId5 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  1604. "clue_id": clueId,
  1605. "position_id": positionId,
  1606. "change_field": "top_cluetype",
  1607. "change_type": "基本信息变更",
  1608. "old_value": "/",
  1609. "new_value": topname,
  1610. "createtime": nowTime,
  1611. "BCPCID": common.GetRandom(32),
  1612. "operator_id": -1,
  1613. })
  1614. uodateId5 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  1615. "clue_id": clueId,
  1616. "position_id": positionId,
  1617. "change_field": "sub_cluetype", //222
  1618. "change_type": "基本信息变更",
  1619. "old_value": "/",
  1620. "new_value": subname,
  1621. "createtime": nowTime,
  1622. "BCPCID": common.GetRandom(32),
  1623. "operator_id": -1,
  1624. })
  1625. return clueId > -1 && uodateId1 > -1 && uodateId2 > -1 && uodateId3 > -1 && uodateId4 > -1 && uodateId5 > -1
  1626. }) {
  1627. log.Println("线索分配成功")
  1628. if TiDb.Count("dwd_f_userbase_contacts", map[string]interface{}{"phone": phone}) == 0 {
  1629. TiDb.Insert("dwd_f_userbase_contacts", map[string]interface{}{
  1630. "status": 1,
  1631. "is_delete": 1,
  1632. "createtime": nowTime,
  1633. "updatetime": nowTime,
  1634. "phone": phone,
  1635. "baseinfo_id": uId,
  1636. "SOURCE": source,
  1637. })
  1638. }
  1639. return true
  1640. }
  1641. return false
  1642. }
  1643. type OrderInfo struct {
  1644. Id int64
  1645. UserId string
  1646. CompanyName string
  1647. ProductType string
  1648. OrderCode string
  1649. PayMoney float64
  1650. ReturnMoney float64
  1651. UserPhone string
  1652. StartEnd string
  1653. DisKcName string
  1654. UserName string
  1655. SeriveList []string
  1656. SaleName string
  1657. }
  1658. // 客成发送邮箱
  1659. func KcSend(orderCode, personName string) {
  1660. log.Println("客成发邮件", orderCode)
  1661. orderInfo := KcOrderFormat(orderCode)
  1662. if orderInfo != nil {
  1663. tableAppend := ""
  1664. if len(orderInfo.SeriveList) > 0 {
  1665. tableAppend = fmt.Sprintf(db.KeCheng.Mail.ServiceList, strings.Join(orderInfo.SeriveList, ","))
  1666. }
  1667. if orderInfo.ReturnMoney > 0 {
  1668. tableAppend += fmt.Sprintf(db.KeCheng.Mail.ReturnMoney, orderInfo.ReturnMoney)
  1669. }
  1670. table := ""
  1671. orderInfo.DisKcName = personName
  1672. 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)
  1673. 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`)
  1674. 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)
  1675. adminMailStr := ""
  1676. if adminData != nil && len(*adminData) > 0 {
  1677. adminMailStr = gconv.String((*adminData)[0]["mail"])
  1678. }
  1679. //发送邮件
  1680. if personName == "" {
  1681. if adminData != nil && len(*adminData) > 0 {
  1682. //发送给管理员
  1683. if adminMailStr != "" {
  1684. gmail := &mail.GmailAuth{
  1685. SmtpHost: db.Mail.SmtpHost,
  1686. SmtpPort: db.Mail.SmtpPort,
  1687. User: db.Mail.User,
  1688. Pwd: db.Mail.Pwd,
  1689. }
  1690. status := mail.GSendMail_q("剑鱼标讯", adminMailStr, "", "", db.KeCheng.Title, fmt.Sprintf(db.KeCheng.Mail.Content, table), "", "", gmail)
  1691. if status {
  1692. log.Println("客成发邮件 send mail success", table, adminMailStr)
  1693. }
  1694. }
  1695. }
  1696. return
  1697. }
  1698. //当事人 管理员发送
  1699. if deptData != nil && len(*deptData) > 0 {
  1700. mailStr := gconv.String((*deptData)[0]["mail"])
  1701. if mailStr != "" || adminMailStr != "" {
  1702. if mailStr == adminMailStr {
  1703. adminMailStr = ""
  1704. }
  1705. gmail := &mail.GmailAuth{
  1706. SmtpHost: db.Mail.SmtpHost,
  1707. SmtpPort: db.Mail.SmtpPort,
  1708. User: db.Mail.User,
  1709. Pwd: db.Mail.Pwd,
  1710. }
  1711. status := true
  1712. if mailStr == "" {
  1713. status = mail.GSendMail_q("剑鱼标讯", adminMailStr, "", "", db.KeCheng.Title, fmt.Sprintf(db.KeCheng.Mail.Content, table), "", "", gmail)
  1714. } else {
  1715. status = mail.GSendMail_q("剑鱼标讯", mailStr, adminMailStr, "", db.KeCheng.Title, fmt.Sprintf(db.KeCheng.Mail.Content, table), "", "", gmail)
  1716. }
  1717. if status {
  1718. log.Println("客成发邮件 send mail success", table, mailStr, adminMailStr)
  1719. }
  1720. }
  1721. }
  1722. }
  1723. }
  1724. func ExitKcSend(personName string, infoList []map[string]interface{}) {
  1725. //退出客成 即将退出客成信息
  1726. 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)
  1727. 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`)
  1728. if personName == "" {
  1729. //没有客成人员
  1730. adminMailStr := ""
  1731. if adminData != nil && len(*adminData) > 0 {
  1732. adminMailStr = gconv.String((*adminData)[0]["mail"])
  1733. }
  1734. if adminMailStr != "" {
  1735. gmail := &mail.GmailAuth{
  1736. SmtpHost: db.Mail.SmtpHost,
  1737. SmtpPort: db.Mail.SmtpPort,
  1738. User: db.Mail.User,
  1739. Pwd: db.Mail.Pwd,
  1740. }
  1741. //正文拼接
  1742. 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>`
  1743. for i, v := range infoList {
  1744. 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"]))
  1745. }
  1746. endStr := `</tbody></table><p></body></html>`
  1747. startStr += endStr
  1748. status := mail.GSendMail_q("剑鱼标讯", adminMailStr, "", "", "客户退出客成系统通知", startStr, "", "", gmail)
  1749. if status {
  1750. log.Println("客成发邮件 send mail success", startStr, adminMailStr)
  1751. }
  1752. }
  1753. return
  1754. }
  1755. if deptData != nil && len(*deptData) > 0 {
  1756. mailStr := gconv.String((*deptData)[0]["mail"])
  1757. adminMailStr := ""
  1758. if adminData != nil && len(*adminData) > 0 {
  1759. adminMailStr = gconv.String((*adminData)[0]["mail"])
  1760. }
  1761. if mailStr != "" || adminMailStr != "" {
  1762. if mailStr == adminMailStr {
  1763. adminMailStr = ""
  1764. }
  1765. gmail := &mail.GmailAuth{
  1766. SmtpHost: db.Mail.SmtpHost,
  1767. SmtpPort: db.Mail.SmtpPort,
  1768. User: db.Mail.User,
  1769. Pwd: db.Mail.Pwd,
  1770. }
  1771. //正文拼接
  1772. 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>`
  1773. for i, v := range infoList {
  1774. 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"]))
  1775. }
  1776. endStr := `</tbody></table><p></body></html>`
  1777. startStr += endStr
  1778. status := true
  1779. if mailStr == "" {
  1780. status = mail.GSendMail_q("剑鱼标讯", adminMailStr, "", "", "客户退出客成系统通知", startStr, "", "", gmail)
  1781. } else {
  1782. status = mail.GSendMail_q("剑鱼标讯", mailStr, adminMailStr, "", "客户退出客成系统通知", startStr, "", "", gmail)
  1783. }
  1784. if status {
  1785. log.Println("客成发邮件 send mail success", startStr, mailStr)
  1786. }
  1787. }
  1788. }
  1789. }
  1790. // 客成邮件 订单信息初始化
  1791. func KcOrderFormat(orderCode string) *OrderInfo {
  1792. productArr, _ := KcProduct()
  1793. bigmemberService := map[int64]string{}
  1794. Mysql.SelectByBath(1, func(l *[]map[string]interface{}) bool {
  1795. bigmemberService[common.Int64All((*l)[0]["id"])] = gconv.String((*l)[0]["s_name"])
  1796. return true
  1797. }, `select id,s_name from jianyu.bigmember_service`)
  1798. orderData := Mysql.SelectBySql(fmt.Sprintf(`
  1799. SELECT
  1800. d.*,
  1801. SUM( c.return_money ) AS return_money
  1802. FROM
  1803. (
  1804. SELECT
  1805. a.order_code,
  1806. a.pay_money,
  1807. a.user_phone,
  1808. b.service_starttime,
  1809. b.service_endtime,
  1810. b.product_type,
  1811. a.filter,
  1812. a.user_id,
  1813. a.ent_id,
  1814. a.company_name,
  1815. a.create_person,
  1816. b.filter AS productFilter,
  1817. TIMESTAMPDIFF( DAY, b.service_starttime, b.service_endtime ) AS difference
  1818. FROM
  1819. jianyu.dataexport_order a
  1820. INNER JOIN jy_order_detail b ON a.order_code = "%s"
  1821. AND a.order_code = b.order_code
  1822. AND a.order_status = 1
  1823. AND b.product_type IN ( %s )
  1824. ORDER BY
  1825. difference DESC LIMIT 1
  1826. ) d
  1827. LEFT JOIN return_money_record c ON d.order_code = c.order_code
  1828. `, orderCode, strings.Join(productArr, ",")))
  1829. data := &OrderInfo{}
  1830. if orderData != nil && len(*orderData) > 0 {
  1831. orderData := (*orderData)[0]
  1832. id := common.Int64All(orderData["id"])
  1833. user_phone := gconv.String(orderData["user_phone"])
  1834. user_id := gconv.String(orderData["user_id"])
  1835. product_type := gconv.String(orderData["product_type"])
  1836. serviceList := []string{}
  1837. if product_type == "大会员" {
  1838. product_type_name, _, level := GetOrderProduct(product_type, gconv.String(orderData["productFilter"]))
  1839. product_type = product_type_name
  1840. if level == 0 {
  1841. for _, serversId := range strings.Split(gconv.String(gconv.Map(orderData["serversId"])), ",") {
  1842. if serviceName := bigmemberService[common.Int64All(serversId)]; serviceName != "" {
  1843. serviceList = append(serviceList, serviceName)
  1844. }
  1845. }
  1846. }
  1847. }
  1848. //联系人姓名
  1849. sqlStr := `SELECT
  1850. a.phone,
  1851. b.NAME AS bname
  1852. FROM
  1853. dwd_f_userbase_contacts a
  1854. INNER JOIN dwd_f_crm_clue_info b ON ( a.phone = ? AND a.baseinfo_id = b.uid )
  1855. LEFT JOIN dwd_f_csm_customer_info c ON ( b.id = c.clue_id)`
  1856. userName := ""
  1857. if user_phone != "" {
  1858. userData := TiDb.SelectBySql(sqlStr, user_phone)
  1859. if userData != nil && len(*userData) > 0 {
  1860. userName = gconv.String((*userData)[0]["bname"])
  1861. }
  1862. }
  1863. data = &OrderInfo{
  1864. Id: id,
  1865. CompanyName: gconv.String(orderData["company_name"]),
  1866. UserId: user_id,
  1867. ProductType: product_type,
  1868. OrderCode: orderCode,
  1869. PayMoney: common.Float64All(orderData["pay_money"]) / 100,
  1870. ReturnMoney: common.Float64All(orderData["return_money"]) / 100,
  1871. UserPhone: user_phone,
  1872. StartEnd: fmt.Sprintf("%s--%s", strings.Split(gconv.String(orderData["service_starttime"]), " ")[0], strings.Split(gconv.String(orderData["service_endtime"]), " ")[0]),
  1873. SeriveList: serviceList,
  1874. SaleName: gconv.String(orderData["create_person"]),
  1875. UserName: userName,
  1876. }
  1877. }
  1878. return data
  1879. }
  1880. func SaleMail(positionId int64) string {
  1881. person, admin, seniorAdmin := FindDeptAdmin(positionId)
  1882. personMail := ""
  1883. adminMail := ""
  1884. seniorAdminMail := ""
  1885. if person != nil {
  1886. personMail, _ = GetMail(gconv.String(person["name"]))
  1887. }
  1888. if admin != nil {
  1889. adminMail, _ = GetMail(gconv.String(admin["name"]))
  1890. }
  1891. if seniorAdmin != nil {
  1892. seniorAdminMail, _ = GetMail(gconv.String(seniorAdmin["name"]))
  1893. }
  1894. to, cc := "", ""
  1895. if personMail != "" {
  1896. to = personMail
  1897. if adminMail != "" && seniorAdminMail != "" {
  1898. if to != adminMail {
  1899. if to != seniorAdminMail {
  1900. cc = fmt.Sprintf("%s,%s", adminMail, seniorAdminMail)
  1901. }
  1902. } else {
  1903. if to != seniorAdminMail {
  1904. cc = seniorAdminMail
  1905. }
  1906. }
  1907. } else if seniorAdminMail != "" && to != seniorAdminMail {
  1908. cc = seniorAdminMail
  1909. }
  1910. } else {
  1911. if adminMail != "" {
  1912. to = adminMail
  1913. if seniorAdminMail != "" && to != seniorAdminMail {
  1914. cc = seniorAdminMail
  1915. }
  1916. } else {
  1917. to = seniorAdminMail
  1918. }
  1919. }
  1920. if to != "" && cc != "" {
  1921. to = fmt.Sprintf("%s|%s", to, cc)
  1922. }
  1923. return to
  1924. }
  1925. func FindPersonOne(positionId int64) map[string]interface{} {
  1926. personData := TiDb.SelectBySql(`SELECT
  1927. b.name,
  1928. b.position_id,
  1929. b.seat_number,
  1930. b.role_id,
  1931. a.dept_name
  1932. FROM
  1933. dwd_d_crm_department_level_succbi a
  1934. INNER JOIN dwd_f_crm_personnel_management b ON a.position_id = ?
  1935. AND a.position_id = b.position_id`, positionId)
  1936. if personData == nil || len(*personData) == 0 {
  1937. return nil
  1938. }
  1939. return (*personData)[0]
  1940. }
  1941. // 进客成商品查询
  1942. func KcProduct() ([]string, map[string]bool) {
  1943. var strArr []string
  1944. strMap := map[string]bool{}
  1945. productData := Mysql.SelectBySql(`SELECT id ,
  1946. CONCAT( '"', class_name,'"' ) as product
  1947. FROM
  1948. jy_product_class
  1949. WHERE
  1950. s_service = 1`)
  1951. if productData == nil && len(*productData) == 0 {
  1952. return strArr, strMap
  1953. }
  1954. for _, m := range *productData {
  1955. strMap[gconv.String(m["product"])] = true
  1956. strArr = append(strArr, gconv.String(m["product"]))
  1957. }
  1958. return strArr, strMap
  1959. }
  1960. func GetOrderProduct(productType string, file string) (string, int64, int64) {
  1961. fileJson := gconv.Map(file)
  1962. if fileJson == nil || len(fileJson) == 0 {
  1963. return "", 0, 0
  1964. }
  1965. productName := ""
  1966. level := int64(0)
  1967. switch productType {
  1968. case "大会员":
  1969. level = gconv.Int64(fileJson["comboId"])
  1970. if level == 0 {
  1971. level = gconv.Int64(fileJson["level"])
  1972. }
  1973. switch level {
  1974. case 0:
  1975. productName = "大会员自定义"
  1976. case 30190:
  1977. productName = "大会员商机版2.0(单省版)"
  1978. case 6:
  1979. productName = "大会员商机版2.0"
  1980. case 7:
  1981. productName = "大会员专家版2.0"
  1982. }
  1983. default:
  1984. productName = productType
  1985. }
  1986. productData := TiDb.FindOne("dwd_d_csm_product_access_code", map[string]interface{}{
  1987. "name": productName,
  1988. }, "", "")
  1989. if productData == nil || len(*productData) == 0 {
  1990. return productName, 0, level
  1991. }
  1992. return productName, gconv.Int64((*productData)["code"]), level
  1993. }
  1994. func GetTimeDifference(timeStr1, timeStr2 string) int {
  1995. // 解析时间字符串
  1996. t1, err1 := time.Parse(time.DateTime, timeStr1)
  1997. t2, err2 := time.Parse(time.DateTime, timeStr2)
  1998. if err1 != nil || err2 != nil {
  1999. fmt.Println("时间格式错误:", err1, err2)
  2000. return 0
  2001. }
  2002. // 计算时间差
  2003. daysDiff := gconv.Int(t2.Sub(t1).Hours() / 24)
  2004. fmt.Printf("两个时间相差 %.0f 天\n", daysDiff)
  2005. return daysDiff
  2006. }
  2007. func getOrderData(sql string) (map[string]map[string]interface{}, string) {
  2008. data := Mysql.SelectBySql(sql)
  2009. orderMap := map[string]map[string]interface{}{}
  2010. lastEndTime := ""
  2011. for _, v := range *data {
  2012. orderCode := gconv.String(v["order_code"])
  2013. product_type := gconv.String(v["productType"])
  2014. vip_starttime := gconv.String(v["service_starttime"])
  2015. vip_endtime := gconv.String(v["service_endtime"])
  2016. //判断一下服务周期
  2017. difference := GetTimeDifference(vip_starttime, vip_endtime)
  2018. _, productInt64, _ := GetOrderProduct(product_type, gconv.String(v["productFilter"]))
  2019. if productInt64 == 0 {
  2020. continue
  2021. }
  2022. t1, _ := time.Parse(time.DateTime, lastEndTime)
  2023. t2, _ := time.Parse(time.DateTime, vip_endtime)
  2024. //判断服务周期
  2025. if t2.Unix() > t1.Unix() {
  2026. lastEndTime = vip_endtime
  2027. }
  2028. if _, exists := orderMap[orderCode]; exists {
  2029. data := orderMap[orderCode]
  2030. //商品类型获取
  2031. oldDifference := gconv.Int(data["difference"])
  2032. if difference >= oldDifference {
  2033. //需要更换
  2034. v["difference"] = difference
  2035. v["product"] = productInt64
  2036. v["service_endtime"] = vip_endtime
  2037. v["service_starttime"] = vip_starttime
  2038. v["product_type"] = product_type
  2039. orderMap[orderCode] = v
  2040. }
  2041. } else {
  2042. v["difference"] = difference
  2043. v["product"] = productInt64
  2044. v["product_type"] = product_type
  2045. orderMap[orderCode] = v
  2046. }
  2047. }
  2048. return orderMap, lastEndTime
  2049. }