transferDx.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. package main
  2. import (
  3. "app.yhyue.com/moapp/jybase/common"
  4. "app.yhyue.com/moapp/jybase/date"
  5. "app.yhyue.com/moapp/jybase/mongodb"
  6. "database/sql"
  7. "errors"
  8. "fmt"
  9. "github.com/gogf/gf/v2/util/gconv"
  10. "go.mongodb.org/mongo-driver/bson"
  11. "log"
  12. "time"
  13. )
  14. // 子账号及免费账号移交电销
  15. func SubAndFreeAccountToDx(cusId, changeType int64) {
  16. //根据主账号客成id查询需要移交子账号、免费账号线索
  17. customerData := TiDb.SelectBySql("SELECT a.product_access,a.id,a.ent_id,b.uid,a.account_type,a.primary_id,b.id as clue_id,a.name as kcName,a.position_id FROM `dwd_f_csm_customer_info` a LEFT JOIN dwd_f_crm_clue_info b ON a.clue_id = b.id WHERE a.primary_id = ? AND a.is_transfer = 0", cusId)
  18. if customerData == nil || len(*customerData) == 0 {
  19. return
  20. }
  21. for _, val := range *customerData {
  22. //这个过程需要判断每个用户是否有其他身份下的主账号在客成中
  23. clueId := common.Int64All(val["clue_id"])
  24. uid := common.InterfaceToStr(val["uid"])
  25. currentEntId := common.Int64All(val["ent_id"])
  26. accountType := common.IntAll(val["account_type"]) //原来在客成的 账号类型 1:主账号 2:子账号 3:企业组织架构免费账号 4:非集团公司免费账号
  27. oldKcName := common.InterfaceToStr(val["name"])
  28. userPowerMap, err := GetPersonIdentityPower(uid, accountType, currentEntId, "")
  29. if err != nil {
  30. log.Printf("查询企业下子账号、员工其他身份下是否有会员权益失败: uid:%s\n", uid)
  31. continue
  32. }
  33. if userPowerMap == nil { //移出客成,进入公海
  34. changeReason := ""
  35. kcPositionId := common.Int64All(val["position_id"])
  36. switch changeType {
  37. case 1: //权益到期
  38. changeReason = "成交客户续约失败,关联线索移交销售"
  39. case 2: //退款
  40. changeReason = "成交客户申请退款,关联线索移交销售"
  41. case 3: //
  42. productName := GetProductName(gconv.Int64(val["customerData"]))
  43. changeReason = fmt.Sprintf("%s权限被企业删除", productName)
  44. }
  45. kcToOpenSeaUpdate(clueId, kcPositionId, changeType, changeReason)
  46. } else { //该用户在其他身份下有会员权益
  47. entId := common.Int64All(userPowerMap["entId"])
  48. mainCusData := common.ObjToMap(userPowerMap["customer"]) //主账号信息
  49. mainCompanyName := common.InterfaceToStr((*mainCusData)["company_name"])
  50. isGroup, isCommerce := GetCompanyTypeByClueId(mainCompanyName, clueId)
  51. newAccountType := common.IntAll(userPowerMap["newAccountType"])
  52. SubAndFreeAccountUpdate(*mainCusData, entId, clueId, newAccountType, isGroup, isCommerce, oldKcName)
  53. }
  54. }
  55. log.Printf("客户id:%d 下的子账号、免费账号移交完成", cusId)
  56. }
  57. func GetPersonIdentityPower(uid string, accountType int, currentEntId int64, cluename string) (map[string]interface{}, error) {
  58. //查询到该用户下得所有身份
  59. userEntData := TiDb.SelectBySql("SELECT ent_id,position_id,company_name,type,ent_user_id,userid,phone FROM data_service.user_system"+
  60. " WHERE uid = ? AND status = 1", uid)
  61. if userEntData == nil || len(*userEntData) == 0 {
  62. return nil, errors.New("为查询到用户身份信息")
  63. }
  64. allMemberType := []map[string]interface{}{}
  65. if accountType == 2 {
  66. log.Println("大会员子账号")
  67. }
  68. switch accountType {
  69. case 1, 2, 51, 52:
  70. for _, v := range *userEntData {
  71. newType := 0
  72. entId := common.Int64All(v["ent_id"])
  73. if entId == currentEntId && accountType != 51 {
  74. continue
  75. }
  76. userPhone := common.InterfaceToStr(v["phone"])
  77. entUserId := common.Int64All(v["ent_user_id"])
  78. if entId == 0 && common.IntAll(v["type"]) == 0 { //个人身份
  79. //判断个人身份是否存在个人大会员或者是子账号
  80. //identityCus := map[string]interface{}{}
  81. userId := common.InterfaceToStr(v["userid"])
  82. if userId == "" {
  83. continue
  84. }
  85. userData, ok := Mgo.FindOne("user", bson.M{"s_member_mainid": bson.M{"$exists": true}, "i_member_sub_status": 1, "i_member_status": bson.M{"$gt": 0}, "_id": mongodb.StringTOBsonId(userId)})
  86. if userData != nil && len(*userData) > 0 && ok {
  87. memberSubStatus := common.IntAll((*userData)["i_member_sub_status"])
  88. memberMainid := common.InterfaceToStr((*userData)["s_member_mainid"])
  89. if memberSubStatus == 1 && memberMainid != "" { //子账号
  90. newType = 2
  91. }
  92. if newType == 2 { //判断主账号是否在客成
  93. mainId := userId
  94. if newType == 2 {
  95. mainId = memberMainid
  96. }
  97. data := map[string]interface{}{
  98. "entId": entId,
  99. "newAccountType": newType,
  100. }
  101. userCus := TiDb.FindOne("dwd_f_csm_customer_info", bson.M{"ent_id": mainId, "is_transfer": 0, "account_type": 1}, "", "")
  102. if userCus == nil || len(*userCus) == 0 {
  103. log.Printf("查询主账号客户信息失败: userId:%s\n", mainId)
  104. continue
  105. }
  106. data["customer"] = userCus
  107. allMemberType = append(allMemberType, data)
  108. }
  109. }
  110. } else if entId != 0 && common.IntAll(v["type"]) == 1 { //企业身份
  111. //需要查询此人在不在企业下边
  112. if Mysql.Count("entniche_user", map[string]interface{}{
  113. "ent_id": entId,
  114. "id": entUserId,
  115. }) == 0 {
  116. continue
  117. }
  118. //判断该身份下时候是大会员企业管理管,或者是企业员工(是否有权益)
  119. //entName := common.InterfaceToStr(v["company_name"])
  120. entPowerData := Mysql.SelectBySql("SELECT a.wait_empower_id,b.phone,b.name as entName FROM `entniche_power` a LEFT JOIN entniche_info b ON a.ent_id = b.id WHERE a.ent_id = ? AND a.ent_user_id = ? AND a.status = 1", entId, entUserId)
  121. if entPowerData != nil && len(*entPowerData) > 0 {
  122. //entName = common.InterfaceToStr((*entPowerData)[0]["entName"])
  123. newType = 2
  124. }
  125. if newType == 0 {
  126. //是否有商机管理权益
  127. entchineData := Mysql.SelectBySql("SELECT a.power,b.name as entName FROM `entniche_user` a LEFT JOIN entniche_info b ON a.ent_id = b.id WHERE a.ent_id = ? AND a.power = 1 AND a.phone = ?", entId, userPhone)
  128. if entchineData != nil && len(*entchineData) > 0 {
  129. //entName = common.InterfaceToStr((*entchineData)[0]["entName"])
  130. newType = 2
  131. } else {
  132. newType = 3
  133. }
  134. }
  135. data := map[string]interface{}{
  136. "entId": entId,
  137. "newAccountType": newType,
  138. //"customer": string(jsonBytes)
  139. }
  140. //查询该身份企业是否在客成
  141. entCusData := TiDb.FindOne("dwd_f_csm_customer_info", bson.M{"ent_id": entId, "is_transfer": 0, "account_type": 1}, "", "")
  142. if entCusData == nil || len(*entCusData) == 0 {
  143. log.Printf("查询主账号客户信息失败: entId:%d\n", entId)
  144. continue
  145. }
  146. data["customer"] = entCusData
  147. allMemberType = append(allMemberType, data)
  148. }
  149. //被踢出企业 以后 归集表还没有处理
  150. if newType == 0 && (accountType == 51 || accountType == 52) && !isGroupCompany(cluename) {
  151. //是否是集团
  152. if cluename != "" {
  153. entCusData := TiDb.FindOne("dwd_f_csm_customer_info", bson.M{"company_name": cluename, "is_transfer": 0, "account_type": 1}, "", "")
  154. if entCusData == nil || len(*entCusData) == 0 {
  155. log.Printf("查询主账号客户信息失败: entId:%d\n", entId)
  156. continue
  157. }
  158. //查询该身份企业是否在客成
  159. data := map[string]interface{}{
  160. "ent_id": gconv.String((*entCusData)["ent_id"]),
  161. "newAccountType": 4,
  162. }
  163. data["customer"] = entCusData
  164. allMemberType = append(allMemberType, data)
  165. }
  166. }
  167. }
  168. case 3, 4: //说明改用身份下没有更高级的账号类型,只能是 3-4 4-3
  169. for _, vl := range *userEntData {
  170. entId := common.Int64All(vl["ent_id"])
  171. newType := 0
  172. if entId == 0 && common.IntAll(vl["type"]) == 0 { //个人身份
  173. continue
  174. }
  175. if entId == currentEntId {
  176. continue
  177. }
  178. entCusData := TiDb.FindOne("dwd_f_csm_customer_info", bson.M{"ent_id": entId, "is_transfer": 0, "account_type": 1}, "", "")
  179. if entCusData == nil || len(*entCusData) == 0 {
  180. log.Printf("查询主账号客户信息失败: entId:%d\n", entId)
  181. continue
  182. }
  183. //是否是集团
  184. if common.InterfaceToStr(vl["company_name"]) != "" {
  185. if c := TiDb.CountBySql(`select count(1) from group_company_name where company_name=?`, common.InterfaceToStr(vl["company_name"])); c > 0 {
  186. newType = 3
  187. } else {
  188. newType = 4
  189. }
  190. //查询该身份企业是否在客成
  191. if newType != 0 {
  192. data := map[string]interface{}{
  193. "entId": entId,
  194. "newAccountType": newType,
  195. }
  196. data["customer"] = entCusData
  197. allMemberType = append(allMemberType, data)
  198. }
  199. }
  200. }
  201. }
  202. if len(allMemberType) > 0 {
  203. minEntry := findMinAccountType(allMemberType)
  204. return minEntry, nil
  205. }
  206. return nil, nil
  207. }
  208. func findMinAccountType(data []map[string]interface{}) (minItem map[string]interface{}) {
  209. minVal := 0
  210. found := false
  211. for _, item := range data {
  212. if val, ok := item["newAccountType"].(int); ok {
  213. if !found || val < minVal {
  214. minVal = val
  215. minItem = item
  216. found = true
  217. }
  218. }
  219. }
  220. return
  221. }
  222. // 子账号、免费账号移交到电销公海
  223. func kcToOpenSeaUpdate(clueId, kcpositionId, changeType int64, changeReason string) { //changeType 1:续约失败 2:退款 3:权限被企业删除
  224. nowTime := time.Now().Format(date.Date_Full_Layout)
  225. ok := TiDb.ExecTx("退出客成系统,进入电销公海", func(tx *sql.Tx) bool {
  226. updateClueMap := map[string]interface{}{
  227. "is_assign": 0,
  228. "updatetime": nowTime,
  229. "comeintime_open": nowTime,
  230. "position_id": 0,
  231. "seatNumber": nil,
  232. "is_transfer": 0,
  233. }
  234. if changeType == 3 { //权限被企业删除 销售线索来源更新为“其他-产品权限被企业删除”
  235. updateClueMap["top_cluetype"] = "532"
  236. updateClueMap["sub_cluetype"] = "949"
  237. }
  238. ok1 := TiDb.UpdateByTx(tx, "dwd_f_crm_clue_info", map[string]interface{}{"id": clueId}, updateClueMap)
  239. ok2 := TiDb.UpdateByTx(tx, "dwd_f_csm_customer_info", map[string]interface{}{"clue_id": clueId}, map[string]interface{}{
  240. "is_transfer": 1,
  241. "account_type": nil,
  242. "primary_id": nil,
  243. })
  244. in1 := TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  245. "clue_id": clueId,
  246. "position_id": common.If(kcpositionId > 0, kcpositionId, -1),
  247. "change_type": "退回公海",
  248. "new_value": changeReason,
  249. "createtime": nowTime,
  250. "BCPCID": common.GetRandom(32),
  251. "operator_id": -1,
  252. })
  253. in2 := TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  254. "clue_id": clueId,
  255. "position_id": common.If(kcpositionId > 0, kcpositionId, -1),
  256. "change_type": "移交销售",
  257. "new_value": changeReason,
  258. "createtime": nowTime,
  259. "BCPCID": common.GetRandom(32),
  260. "operator_id": -1,
  261. })
  262. return ok1 && ok2 && in1 > 0 && in2 > 0
  263. })
  264. if !ok {
  265. log.Printf("子账号或免费账号移交销售失败:clueId:%d\n", clueId)
  266. }
  267. }
  268. // 从客成划转到另外一个客成
  269. func SubAndFreeAccountUpdate(data map[string]interface{}, entId, clueId int64, newAccountType, isGroup, isCommerce int, oldKcName string) {
  270. mainCusId := common.Int64All(data["id"])
  271. cusCompanyName := common.InterfaceToStr(data["company_name"])
  272. nowTime := time.Now().Format(date.Date_Full_Layout)
  273. kcPositionId := common.Int64All(data["position_id"])
  274. newKcName := common.InterfaceToStr(data["name"])
  275. ok := TiDb.ExecTx("更新线索、客成信息", func(tx *sql.Tx) bool {
  276. ok1 := TiDb.UpdateByTx(tx, "dwd_f_csm_customer_info", map[string]interface{}{"clue_id": clueId}, map[string]interface{}{
  277. "ent_id": entId,
  278. "company_name": cusCompanyName,
  279. "account_type": newAccountType,
  280. "primary_id": mainCusId,
  281. "transfertime": nowTime,
  282. //"service_starttime": data["service_starttime"],
  283. //"service_endtime": data["service_endtime"],
  284. "position_id": kcPositionId,
  285. "name": newKcName,
  286. "is_admin": 0,
  287. "is_renewal_protection": 0,
  288. "product_access": data["product_access"],
  289. "buy_subject": data["buy_subject"],
  290. })
  291. ok2 := TiDb.UpdateByTx(tx, "dwd_f_crm_clue_info", map[string]interface{}{"id": clueId}, map[string]interface{}{
  292. "updatetime": nowTime,
  293. "cluename": cusCompanyName,
  294. "company_nature": isGroup,
  295. "company_verification": isCommerce,
  296. })
  297. AddClueChange(clueId, kcPositionId, "position_id", "客户成功经理", gconv.String(data["name"]), newKcName, nowTime, common.GetRandom(32), "", "")
  298. AddClueChange(clueId, kcPositionId, "", "成交客户移交", "", "移交至客户成功组", nowTime, common.GetRandom(32), "客成切换", "")
  299. return ok1 && ok2
  300. })
  301. if !ok {
  302. log.Printf("子账号或免费账号移交销售失败:clueId:%d\n", clueId)
  303. }
  304. }
  305. func ChangeClueNameToKc(uid string, clueName string) error {
  306. //查询需要移交的主账号客成信息
  307. mainCusData := TiDb.FindOne("dwd_f_csm_customer_info", map[string]interface{}{"company_name": clueName, "is_transfer": 0, "account_type": 1}, "", "")
  308. if mainCusData == nil || len(*mainCusData) == 0 {
  309. log.Printf("该线索名称没有主账号在客成,不需要移交,线索名称:%s", clueName)
  310. return nil
  311. }
  312. mainEntId := common.Int64All((*mainCusData)["ent_id"])
  313. mainKcPositionId := common.Int64All((*mainCusData)["position_id"])
  314. mainKcName := common.InterfaceToStr((*mainCusData)["name"])
  315. //判断线索是否在客成
  316. cusData := map[string]interface{}{}
  317. data := TiDb.SelectBySql("SELECT a.cluename,a.id,b.id as cusId,b.is_transfer FROM dwd_f_crm_clue_info a LEFT JOIN dwd_f_csm_customer_info b ON a.id = b.clue_id WHERE a.uid = ? AND b.is_transfer = 0", uid)
  318. if data != nil && len(*data) > 0 {
  319. cusData = (*data)[0]
  320. }
  321. cusId := common.Int64All(cusData["cusId"])
  322. clueId := common.Int64All(cusData["id"])
  323. nowTime := time.Now().Format("2006-01-02 15:04:05")
  324. //判断之前该线索是否移交过客成
  325. if cusId != 0 { //该线索曾经移交过客成
  326. if common.IntAll(cusData["is_transfer"]) == 0 {
  327. return nil
  328. } else {
  329. up1 := TiDb.Update("dwd_f_csm_customer_info", map[string]interface{}{"clue_id": clueId}, bson.M{
  330. "is_transfer": 0,
  331. "is_renewal_protection": 0,
  332. "transfertime": nowTime,
  333. "ent_id": mainEntId,
  334. "company_name": clueName,
  335. "position_id": mainKcPositionId,
  336. "name": mainKcName,
  337. "is_admin": 0,
  338. "primary_id": cusId,
  339. "account_type": 4,
  340. "is_task": 0,
  341. })
  342. in := TiDb.Insert("dwd_f_crm_clue_change_record", map[string]interface{}{
  343. "clue_id": clueId,
  344. "position_id": mainKcPositionId,
  345. "change_type": "成交客户移交",
  346. "new_value": "移交至客户成功部",
  347. "createtime": nowTime,
  348. "BCPCID": common.GetRandom(32),
  349. "operator_id": -1,
  350. "change_reason": "留资公司名称与移交客成主账号线索名称一致",
  351. })
  352. up2 := TiDb.Update("dwd_f_crm_clue_info", bson.M{"id": clueId}, map[string]interface{}{"is_transfer": 1, "updatetime": nowTime})
  353. if up1 && up2 && in > 0 {
  354. return nil
  355. }
  356. return errors.New("更新客成信息出错")
  357. }
  358. } else {
  359. saveMap := map[string]interface{}{
  360. "clue_id": clueId,
  361. "transfertime": nowTime,
  362. "position_id": mainKcPositionId,
  363. "name": mainKcName,
  364. "ent_id": mainEntId,
  365. "is_task": 0,
  366. "tasktime": nowTime,
  367. "taskstatus": 0,
  368. "tasksource": "1",
  369. "is_admin": 0,
  370. "relationship_building_way": 1,
  371. "inventory_way": 1,
  372. "training_way": 1,
  373. "is_pre_sales_training": 0,
  374. "service_stage": 1,
  375. "company_name": clueName,
  376. "primary_id": cusId,
  377. "account_type": 4,
  378. }
  379. cId, ok, updateId1 := int64(-1), false, int64(-1)
  380. if TiDb.ExecTx("保存客户", func(tx *sql.Tx) bool {
  381. cId = TiDb.InsertByTx(tx, "dwd_f_csm_customer_info", saveMap)
  382. ok = TiDb.UpdateByTx(tx, "dwd_f_crm_clue_info", map[string]interface{}{"id": clueId}, map[string]interface{}{"is_transfer": 1, "updatetime": nowTime})
  383. updateId1 = TiDb.InsertByTx(tx, "dwd_f_crm_clue_change_record", map[string]interface{}{
  384. "clue_id": clueId,
  385. "position_id": mainKcPositionId,
  386. "change_type": "成交客户移交",
  387. "new_value": "移交至客户成功部",
  388. "createtime": nowTime,
  389. "BCPCID": common.GetRandom(32),
  390. "operator_id": -1,
  391. "change_reason": "留资公司名称与移交客成主账号线索名称一致",
  392. })
  393. return cId > -1 && ok && updateId1 > -1
  394. }) {
  395. return nil
  396. }
  397. return errors.New("移交客成失败")
  398. }
  399. }