custom.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. package service
  2. import (
  3. "context"
  4. "database/sql"
  5. "fmt"
  6. "log"
  7. "strings"
  8. "time"
  9. qu "app.yhyue.com/moapp/jybase/common"
  10. "app.yhyue.com/moapp/jybase/date"
  11. "bp.jydev.jianyu360.cn/BaseService/userCenter/rpc/pb"
  12. cm "bp.jydev.jianyu360.cn/CRM/application/api/common"
  13. "bp.jydev.jianyu360.cn/CRM/application/entity"
  14. baseC "bp.jydev.jianyu360.cn/CRM/baseCenter/rpc/pb"
  15. "github.com/gogf/gf/v2/util/gconv"
  16. )
  17. // 客户相关
  18. type CustomService struct {
  19. BaseUserId int64
  20. PositionId int64
  21. EntUserId int64
  22. EntId int64
  23. AppId string
  24. AccountId int64
  25. EntDeptId int64
  26. CustomType int64 //客户类型
  27. CustomDetailType int64 //客户细分类型
  28. Summary string //概要信息
  29. CustomAllName string //客户全称
  30. CustomAbbreviation string //客户简称
  31. CustomLevel int64 //客户级别
  32. CustomIndustry int64 //客户行业
  33. CustomDetailIndustry int64 //客户细分行业
  34. Province string //省份
  35. City string //城市
  36. District string //地区
  37. Address string //详细地址
  38. CompanyPhone string //公司电话
  39. NextfollowUpTime int64 //下次跟进时间戳
  40. Types int64 //处理方式 1自办;2转办
  41. User []int64 //转办用户
  42. EmployCustomId int64 //客户收录id
  43. EmployInfoId int64 //资讯收录id
  44. Remarks string //备注
  45. CreateName string //创建人
  46. Source string
  47. OwnerId string //潜客收录id(人脉)
  48. BusinessId string //商机收录id(人脉)
  49. }
  50. // Add 创建客户
  51. func (this *CustomService) Add(ctx context.Context) (int64, string) {
  52. nowtime := time.Now().Format(date.Date_Full_Layout)
  53. nextFollowTime := time.Unix(this.NextfollowUpTime, 0).Format(date.Date_Full_Layout)
  54. args := []interface{}{}
  55. argsTask := []interface{}{}
  56. argsTaskTeam := []interface{}{}
  57. //判断处理方式
  58. //转办
  59. baseUserIdArr := []int64{}
  60. customId, taskId := int64(-1), int64(-1)
  61. groupId := ""
  62. if this.Types == 2 {
  63. transferArr := []int64{}
  64. for _, v := range this.User {
  65. i_entuserid := v
  66. resp, err := cm.UserCenterRpc.IdentityByEntUserId(ctx, &pb.IdentityReq{
  67. Id: i_entuserid,
  68. })
  69. if err != nil {
  70. log.Println("获取用户职位id信息出错", i_entuserid, "的信息出错", err)
  71. return -1, groupId
  72. } else if resp == nil {
  73. log.Println("entuser用户", i_entuserid, "没有找到职位信息")
  74. return -1, groupId
  75. }
  76. transferArr = append(transferArr, resp.PositionId)
  77. baseUserIdArr = append(baseUserIdArr, resp.UserId)
  78. }
  79. //客户
  80. args = append(args, this.PositionId, this.EntId, this.EntUserId, this.EmployInfoId, this.EmployCustomId, this.CustomType, this.CustomDetailType, this.CustomAllName, this.CustomAbbreviation, this.Summary, qu.If(this.CustomLevel == 0, nil, this.CustomLevel), this.CustomIndustry, this.CustomDetailIndustry, qu.If(this.Province == "", nil, this.Province), qu.If(this.City == "", nil, this.City), qu.If(this.District == "", nil, this.District), qu.If(this.Address == "", nil, this.Address), qu.If(this.CompanyPhone == "", nil, this.CompanyPhone), qu.If(this.Remarks == "", nil, this.Remarks), this.CreateName, nowtime, this.Source, this.OwnerId, this.BusinessId)
  81. //任务
  82. argsTask = append(argsTask, this.EntId, this.CustomAllName+"的跟进任务", 3, this.PositionId, 1, nowtime, 1, 0, qu.If(this.NextfollowUpTime == 0, nil, nextFollowTime), nil, nil)
  83. customId, taskId = SaveCustom(ctx, args, argsTask, argsTaskTeam, this.EmployInfoId, this.EmployCustomId, this.OwnerId, this.BusinessId, this.PositionId, this.CreateName, transferArr, this.EntId, this.EntUserId, this.EntDeptId)
  84. if customId < 0 {
  85. return -1, groupId
  86. }
  87. } else if this.Types == 1 {
  88. //客户
  89. args = append(args, this.PositionId, this.EntId, this.EntUserId, this.EmployInfoId, this.EmployCustomId, this.CustomType, this.CustomDetailType, this.CustomAllName, this.CustomAbbreviation, this.Summary, qu.If(this.CustomLevel == 0, nil, this.CustomLevel), this.CustomIndustry, this.CustomDetailIndustry, qu.If(this.Province == "", nil, this.Province), qu.If(this.City == "", nil, this.City), qu.If(this.District == "", nil, this.District), qu.If(this.Address == "", nil, this.Address), qu.If(this.CompanyPhone == "", nil, this.CompanyPhone), qu.If(this.Remarks == "", nil, this.Remarks), this.CreateName, nowtime, this.Source, this.OwnerId, this.BusinessId)
  90. //任务s
  91. argsTask = append(argsTask, this.EntId, this.CustomAllName+"的跟进任务", 3, this.PositionId, 2, nowtime, 1, 0, qu.If(this.NextfollowUpTime == 0, nil, nextFollowTime), nil, nil)
  92. //任务团队
  93. argsTaskTeam = append(argsTaskTeam, this.PositionId, this.EntUserId, this.CreateName, 1, nowtime)
  94. //存库
  95. customId, taskId = SaveCustom(ctx, args, argsTask, argsTaskTeam, this.EmployInfoId, this.EmployCustomId, this.OwnerId, this.BusinessId, this.PositionId, this.CreateName, []int64{}, this.EntId, this.EntUserId, this.EntDeptId)
  96. if customId < 0 {
  97. return -1, groupId
  98. }
  99. baseUserIdArr = append(baseUserIdArr, this.BaseUserId)
  100. //自办 创建 群聊
  101. // gp := &Group{
  102. // EntId: this.EntId,
  103. // PositionId: this.PositionId,
  104. // UserIdArr: []int64{},
  105. // AppId: this.AppId,
  106. // EntUserId: this.EntUserId,
  107. // AccountId: this.AccountId,
  108. // }
  109. // groupId = gp.GroupAdd()
  110. } else if this.Types == 3 {
  111. transferArr := []int64{}
  112. transferArr = append(transferArr, this.PositionId)
  113. //客户
  114. args = append(args, this.PositionId, this.EntId, this.EntUserId, this.EmployInfoId, this.EmployCustomId, this.CustomType, this.CustomDetailType, this.CustomAllName, this.CustomAbbreviation, this.Summary, qu.If(this.CustomLevel == 0, nil, this.CustomLevel), this.CustomIndustry, this.CustomDetailIndustry, qu.If(this.Province == "", nil, this.Province), qu.If(this.City == "", nil, this.City), qu.If(this.District == "", nil, this.District), qu.If(this.Address == "", nil, this.Address), qu.If(this.CompanyPhone == "", nil, this.CompanyPhone), qu.If(this.Remarks == "", nil, this.Remarks), this.CreateName, nowtime, this.Source, this.OwnerId, this.BusinessId)
  115. //任务
  116. argsTask = append(argsTask, this.EntId, this.CustomAllName+"的跟进任务", 3, this.PositionId, 1, nowtime, 1, 0, qu.If(this.NextfollowUpTime == 0, nil, nextFollowTime), nil, nil)
  117. customId, taskId = SaveCustom(ctx, args, argsTask, argsTaskTeam, this.EmployInfoId, this.EmployCustomId, this.OwnerId, this.BusinessId, this.PositionId, this.CreateName, transferArr, this.EntId, this.EntUserId, this.EntDeptId)
  118. if customId < 0 {
  119. return -1, groupId
  120. }
  121. baseUserIdArr = append(baseUserIdArr, this.BaseUserId)
  122. }
  123. u := &User{BaseUserIds: baseUserIdArr}
  124. if this.Types != 3 {
  125. var kb strings.Builder
  126. var vb strings.Builder
  127. for k, v := range u.GetUserId(this.EntId) {
  128. kb.WriteString(k + ",")
  129. vb.WriteString(gconv.String(v) + ",")
  130. userId := strings.TrimRight(kb.String(), ",")
  131. positionId := strings.TrimRight(vb.String(), ",")
  132. next := strings.Replace(time.Unix(this.NextfollowUpTime, 0).Format(YYYYMMDDHHMM), " ", "%20", -1)
  133. pcHref := ""
  134. content := ""
  135. if this.Types == 1 {
  136. pcHref = fmt.Sprintf(cm.Push.Custom.Create.MyselfPcHref, positionId, taskId, customId)
  137. content = fmt.Sprintf(cm.Push.Custom.Create.MySelfContent, this.CreateName, strings.Replace(date.NowFormat(YYYYMMDDHHMM), " ", "%20", -1), next)
  138. } else if this.Types == 2 {
  139. pcHref = fmt.Sprintf(cm.Push.Custom.Create.TransferPcHref, positionId)
  140. content = fmt.Sprintf(cm.Push.Custom.Create.TransferContent, this.CreateName, strings.Replace(date.NowFormat(YYYYMMDDHHMM), " ", "%20", -1), next)
  141. }
  142. StationMailPush(userId, positionId, cm.Push.Custom.Create.Title, content, pcHref, cm.Push.Custom.Create.MobileHref, "11")
  143. }
  144. }
  145. return 1, groupId
  146. }
  147. func SaleCustomAdd(tx *sql.Tx, args []interface{}) int64 {
  148. fields := []string{"position_id", "ent_id", "ent_user_id", "employ_info_id", "employ_custom_id", "type", "subdivision_type", "full_name", "sort_name", "summary", "level_1", "industry", "subdivision_industry", "province", "city", "county", "address", "phone", "remark", "create_person", "create_time", "source", "connection_owner_id", "connection_business_id"}
  149. _, id := cm.CrmMysql.InsertBatchByTx(tx, entity.CUSTOM, fields, args)
  150. return id
  151. }
  152. // EmployUpdate 是否创建线索/机会/客户修改
  153. // return employ_info_id,employ_custom_id
  154. func EmployUpdate(tx *sql.Tx, employ_info_id, employ_custom_id, positionId int64, key string, entId, entUserId, entDeptId int64) (int64, int64) {
  155. tablename := ""
  156. id := int64(0)
  157. if employ_custom_id > 0 {
  158. tablename = entity.EMPLOY_CUSTOM
  159. id = employ_custom_id
  160. } else if employ_info_id > 0 {
  161. tablename = entity.EMPLOY_INFO
  162. id = employ_info_id
  163. }
  164. fmt.Println(tablename, id)
  165. if tablename == "" || id == 0 {
  166. return employ_info_id, employ_custom_id
  167. }
  168. //判断该条信息是不是当前资讯分配员的
  169. d := cm.CrmMysql.SelectBySqlByTx(tx, fmt.Sprintf(`select * from %v where id = ?`, tablename), id)
  170. fmt.Println(d)
  171. if d != nil && len(*d) > 0 {
  172. data := (*d)[0]
  173. position_id := gconv.Int64(data["position_id"])
  174. if position_id == positionId {
  175. cm.CrmMysql.UpdateByTx(tx, tablename, map[string]interface{}{"id": id, "position_id": positionId}, map[string]interface{}{key: 1, "is_handle": 1})
  176. } else {
  177. //判断是否已创建该条,但是是取消收录状态、如果是则改为已收录,不是则创建一条新的
  178. d2 := cm.CrmMysql.SelectBySqlByTx(tx, fmt.Sprintf(`select * from %v where source_id = ? and position_id =?`, tablename), data["source_id"], positionId)
  179. if d2 != nil && len(*d2) > 0 {
  180. //已创建
  181. qwe := cm.CrmMysql.UpdateByTx(tx, tablename, map[string]interface{}{
  182. "source_id": data["source_id"],
  183. "position_id": positionId,
  184. }, map[string]interface{}{
  185. key: 1,
  186. "status": 1,
  187. })
  188. log.Println(qwe, data["source_id"], positionId)
  189. } else {
  190. data["position_id"] = positionId
  191. data["ent_id"] = entId
  192. data["ent_dept_id"] = entDeptId
  193. data["ent_user_id"] = entUserId
  194. //当前咨询不是分配员的 创建该条
  195. if employ_custom_id > 0 {
  196. //
  197. data["is_handle"] = 1
  198. data["is_ignore"] = 0
  199. data["is_create_custom"] = 1
  200. } else if employ_info_id > 0 {
  201. data["is_handle"] = 1
  202. data["is_ignore"] = 0
  203. data["is_dis"] = 0
  204. data[key] = 1
  205. for _, v := range GetOtherKey(key) {
  206. data[v] = 0
  207. }
  208. }
  209. delete(data, "id")
  210. newId := cm.CrmMysql.InsertByTx(tx, tablename, data)
  211. if tablename == entity.EMPLOY_INFO {
  212. employ_info_id = newId
  213. } else if tablename == entity.EMPLOY_CUSTOM {
  214. employ_custom_id = newId
  215. }
  216. }
  217. }
  218. }
  219. return employ_info_id, employ_custom_id
  220. }
  221. func SaveCustom(ctx context.Context, argsCustom, argsTask, argsTaskTeam []interface{}, employ_info_id, employ_custom_id int64, ownerId, connectionBusinessId string, positionId int64, createPerson string, transferArr []int64, entId, entUserId, entDeptId int64) (int64, int64) {
  222. customId := int64(-1)
  223. taskId := int64(-1)
  224. //存库
  225. cm.CrmMysql.ExecTx("创建客户", func(tx *sql.Tx) bool {
  226. //修改状态
  227. employ_info_id_new, employ_custom_id_new := EmployUpdate(tx, employ_info_id, employ_custom_id, positionId, "is_create_custom", entId, entUserId, entDeptId)
  228. //插入客户
  229. //修改客户id、咨询id
  230. argsCustom[3] = employ_info_id_new
  231. argsCustom[4] = employ_custom_id_new
  232. customId = SaleCustomAdd(tx, argsCustom)
  233. //传过来的argTask没有来源id,需要append
  234. argsTask = append(argsTask, customId)
  235. //任务车存储
  236. taskId = TaskAdd(tx, argsTask, argsTaskTeam, transferArr, positionId)
  237. //插入台账
  238. ok2 := SaveLedger(ctx, positionId, customId, taskId, "创建客户", fmt.Sprintf("%s创建了客户", createPerson), createPerson)
  239. //人脉信息添加
  240. if ownerId != "" || connectionBusinessId != "" {
  241. SaveConnection(tx, positionId, connectionBusinessId, ownerId, entId, entDeptId, entUserId)
  242. }
  243. if customId > 0 && taskId > 0 && ok2 {
  244. return true
  245. }
  246. log.Println("SaveCustom err:", customId, taskId)
  247. return false
  248. })
  249. return customId, taskId
  250. }
  251. // SaveLedger 操作台帐相关
  252. func SaveLedger(ctx context.Context, positionId, businessId, taskId int64, types, content, createPerson string) bool {
  253. //操作台账
  254. resp, err := cm.BaseCenterRpc.LedgerAdd(ctx, &baseC.LedgerAddReq{
  255. PositionId: positionId,
  256. BusinessId: businessId, //业务id
  257. TaskId: taskId, //任务id
  258. Types: types, //类型
  259. Content: content, //内容
  260. CreateWay: 1, //创建方式 1:人 2:系统
  261. CreatePerson: createPerson,
  262. })
  263. if err != nil {
  264. log.Println("save ledger err:", err)
  265. return false
  266. }
  267. if resp == nil {
  268. log.Println("save ledger resp is nil")
  269. return false
  270. }
  271. return resp.State
  272. }
  273. // 消息漏斗保存
  274. func saveSalesFunnel(tx *sql.Tx, args []interface{}, tpl_id int64) int64 {
  275. fields := []string{`chance_id`, `task_id`, `chance_name`, `outline`, `next_follow_time`, `expected_transaction_amount`, `business_type`, `ent_id`, `employ_info_id`, `current_generation`, `current_generation_progress`, `generation`}
  276. //当前阶段
  277. stageId := int64(0)
  278. stageData := cm.CrmMysql.Find(entity.CONFIG_TPL_STAGE, map[string]interface{}{
  279. "tpl_id": tpl_id}, "id, `order`", "", -1, -1)
  280. if stageData != nil && len(*stageData) > 0 {
  281. var a1 []interface{}
  282. for _, m := range *stageData {
  283. stageId = gconv.Int64(m["id"])
  284. order := gconv.Int(m["order"])
  285. a1 = append(a1, args...)
  286. if order == 1 {
  287. a1 = append(a1, stageId)
  288. } else {
  289. a1 = append(a1, 0)
  290. }
  291. a1 = append(a1, 0)
  292. a1 = append(a1, stageId)
  293. //进度查询
  294. /*matterData := cm.CrmMysql.SelectBySql("select COUNT(1) as ratio from config_stage_matter where stage_id=? and is_must == 1", stageId)
  295. if matterData != nil && len(*matterData) > 0 {
  296. ratio := gconv.Int64((*matterData)[0]["ratio"])
  297. a1 = append(a1, ratio)
  298. } else {
  299. a1 = append(a1, 0)
  300. }*/
  301. }
  302. //当前阶段进展
  303. _, id := cm.CrmMysql.InsertBatchByTx(tx, entity.SALES_FUNNEL, fields, a1)
  304. return id
  305. /**/
  306. }
  307. return 0
  308. }
  309. func GetOtherKey(key string) []string {
  310. parameters := map[string][]string{
  311. "is_create_clue": {"is_create_chance", "is_create_custom"},
  312. "is_create_chance": {"is_create_clue", "is_create_custom"},
  313. "is_create_custom": {"is_create_chance", "is_create_clue"},
  314. }
  315. return parameters[key]
  316. }
  317. func SaveConnection(tx *sql.Tx, positionId int64, businessId, ownerId string, entId, entDeptId, entUserId int64) bool {
  318. if businessId != "" || ownerId != "" {
  319. table := entity.CONNECTION_STATUS
  320. sourceType := 2
  321. if businessId == "" {
  322. businessId = ownerId
  323. sourceType = 1
  324. }
  325. if cm.CrmMysql.Count(table, map[string]interface{}{
  326. "position_id": positionId,
  327. "relate_id": businessId,
  328. "itype": sourceType,
  329. }) > 0 {
  330. cm.CrmMysql.UpdateByTx(tx, table, map[string]interface{}{
  331. "position_id": positionId,
  332. "relate_id": businessId,
  333. "itype": sourceType,
  334. }, map[string]interface{}{
  335. "is_handle": 1,
  336. "relate_id": businessId,
  337. "update_time": time.Now().Format(date.Date_Full_Layout),
  338. "is_create": 1,
  339. })
  340. return true
  341. } else {
  342. id := cm.CrmMysql.InsertByTx(tx, table, map[string]interface{}{
  343. "position_id": positionId,
  344. "ent_id": entId,
  345. "ent_dept_id": entDeptId,
  346. "ent_user_id": entUserId,
  347. "relate_id": businessId,
  348. "is_handle": 1,
  349. "is_create": 1,
  350. "itype": sourceType,
  351. "create_time": time.Now().Format(date.Date_Full_Layout),
  352. "update_time": time.Now().Format(date.Date_Full_Layout),
  353. })
  354. return id > 0
  355. }
  356. }
  357. return true
  358. }