task.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. package logic
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "github.com/gogf/gf/v2/frame/g"
  7. "github.com/gogf/gf/v2/os/gtime"
  8. "newuserGet/internal/dao"
  9. "newuserGet/internal/model/do"
  10. "newuserGet/internal/model/entity"
  11. "strings"
  12. "time"
  13. )
  14. func Task(ctx context.Context) {
  15. // get rule
  16. var rules []entity.NewUserSendRule
  17. err := dao.NewUserSendRule.Ctx(ctx).Scan(&rules)
  18. if err != nil {
  19. g.Log().Error(ctx, "获取规则失败", err)
  20. return
  21. }
  22. // 遍历规则
  23. for i := 0; i < len(rules); i++ {
  24. g.Log().Infof(ctx, "开始处理第%v个规则:id-%v name:%v \n", i, rules[i].Id, rules[i].Name)
  25. // 获取注册时间规则用户和过滤行为
  26. userList, err := getFromRegisterBehavior(ctx, rules[i])
  27. if err != nil {
  28. g.Log().Error(ctx, err)
  29. continue
  30. }
  31. if len(userList) == 0 {
  32. g.Log().Info(ctx, "当前规则getFromRegisterBehavior未获取到有效用户", rules[i].Id, rules[i].Name)
  33. continue
  34. }
  35. if rules[i].CallState != "" {
  36. // 过滤外呼状态
  37. userList, err = filterCallState(ctx, rules[i], userList)
  38. if err != nil {
  39. g.Log().Error(ctx, err)
  40. continue
  41. }
  42. if len(userList) == 0 {
  43. g.Log().Info(ctx, "当前规则filterCallState未获取到有效用户", rules[i].Id, rules[i].Name)
  44. continue
  45. }
  46. }
  47. // 过滤销售进程
  48. userList = filterTrailStatus(ctx, rules[i], userList)
  49. // 保存用户
  50. saveList := []do.NewUserSendLog{}
  51. for j := 0; j <= len(userList); j++ {
  52. saveList = append(saveList, do.NewUserSendLog{
  53. Phone: userList[j].Phone,
  54. UserId: userList[j].MgoId,
  55. CreateTime: gtime.Now(),
  56. })
  57. }
  58. g.Log().Infof(ctx, "完成--第%v个规则:id-%v name:%v \n", i, rules[i].Id, rules[i].Name)
  59. }
  60. }
  61. type User struct {
  62. Phone string `json:"phone"`
  63. MgoId string `json:"mgoId"`
  64. }
  65. const (
  66. OrSQL = "SELECT bitobj from pub_tags.dwd_d_tag ddt WHERE ddt.id in (%s) "
  67. BitMapSQL = "SELECT bitmapAnd((%s),(%s)) as userIds"
  68. QueryUserIdSQL = `SELECT
  69. DISTINCT dmp.mgoUserId as mgoId,dmp.phone as phone
  70. from
  71. pub_tags.dwd_mgo_position dmp
  72. WHERE
  73. bitmapHasAny( (%s),
  74. bitmapBuild([toUInt64(dmp.baseUserId)])) and dmp.mgoUserId!='' and dmp.phone!='';`
  75. CallStateNotDialed = "0" // 未拨打
  76. CallStateNotDeal = "notDeal" // 振铃未接通
  77. CallStateIvr = "ivr" // ivr
  78. CallStatDealing = "dealing" //已接听
  79. )
  80. // 通过时间和行为计算用户
  81. func getFromRegisterBehavior(ctx context.Context, rule entity.NewUserSendRule) (userList []*User, err error) {
  82. start := time.Now()
  83. defer func() {
  84. g.Log().Info(ctx, "getFromRegisterBehavior 耗时:", time.Since(start))
  85. }()
  86. // 时间标签并 之后与行为标签交
  87. // 处理注册时间标签
  88. if rule.RegisterTagIds == "" {
  89. return nil, errors.New("注册时间标签id为空")
  90. }
  91. regQuery := fmt.Sprintf(OrSQL, rule.RegisterTagIds)
  92. filterQuery := regQuery
  93. if rule.BehaviorTagIds != "" {
  94. //拼接行为标签sql
  95. behQuery := fmt.Sprintf(OrSQL, rule.BehaviorTagIds)
  96. filterQuery = fmt.Sprintf(BitMapSQL, regQuery, behQuery)
  97. }
  98. // 处理mgoid和手机号 拼接sql
  99. finalQuery := fmt.Sprintf(QueryUserIdSQL, filterQuery)
  100. g.Log().Info(ctx, "getFromRegisterBehavior 查询sql", finalQuery)
  101. err = dao.DwdDUserTag.DB().Raw(finalQuery).Scan(&userList)
  102. if err != nil {
  103. return nil, err
  104. }
  105. g.Log().Info(ctx, userList)
  106. return
  107. }
  108. // 外呼状态
  109. func filterCallState(ctx context.Context, rule entity.NewUserSendRule, userList []*User) (newUserList []*User, err error) {
  110. start := time.Now()
  111. defer func() {
  112. g.Log().Info(ctx, "filterCallState 耗时:", time.Since(start))
  113. }()
  114. callstateList := strings.Split(rule.CallState, ",")
  115. for i := 0; i < len(userList); i++ {
  116. for j := 0; j < len(callstateList); j++ {
  117. // 未拨打 判断不存在
  118. if callstateList[j] == CallStateNotDialed {
  119. exist, err := dao.VoiceRecord.Ctx(ctx).Where("CalledNo=?", userList[i].Phone).Exist()
  120. if err != nil {
  121. g.Log().Error(ctx, "filterCallState CallStateNotDialed err:", err)
  122. continue
  123. }
  124. if !exist {
  125. newUserList = append(newUserList, userList[i])
  126. continue
  127. }
  128. }
  129. // 已接听 至少一个记录
  130. if callstateList[j] == CallStatDealing {
  131. exist, err := dao.VoiceRecord.Ctx(ctx).Where("CalledNo=? and State=?", userList[i].Phone, CallStatDealing).Exist()
  132. if err != nil {
  133. g.Log().Error(ctx, "filterCallState CallStatDealing err:", err, userList[i])
  134. continue
  135. }
  136. if exist {
  137. newUserList = append(newUserList, userList[i])
  138. continue
  139. }
  140. }
  141. // 其他的 判断是否存在记录
  142. findState := strings.Split(callstateList[j], "#")
  143. exist, err := dao.VoiceRecord.Ctx(ctx).Where("CalledNo=?", userList[i].Phone).WhereNotIn(dao.VoiceRecord.Columns().CallState, findState).Exist()
  144. if err != nil {
  145. g.Log().Error(ctx, "filterCallState otherstate err:", err, findState, userList[i])
  146. continue
  147. }
  148. if !exist {
  149. continue
  150. }
  151. // 存在则查询是否包含其他记录
  152. exist, err = dao.VoiceRecord.Ctx(ctx).Where("CalledNo=?", userList[i].Phone).WhereNotIn(dao.VoiceRecord.Columns().CallState, findState).Exist()
  153. if err != nil {
  154. g.Log().Error(ctx, "filterCallState otherstate notin err:", err, findState, userList[i])
  155. continue
  156. }
  157. if !exist {
  158. newUserList = append(newUserList, userList[i])
  159. continue
  160. }
  161. }
  162. }
  163. return
  164. }
  165. // 跟进状态
  166. func filterTrailStatus(ctx context.Context, rule entity.NewUserSendRule, userList []*User) (newUserList []*User) {
  167. // 拒绝沟通 最后一次销售跟进状态为拒绝沟通
  168. // 无意向客户 最后一次跟进状态为无意向客户
  169. return
  170. }