123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- package logic
- import (
- "context"
- "errors"
- "fmt"
- "github.com/gogf/gf/v2/frame/g"
- "github.com/gogf/gf/v2/os/gtime"
- "newuserGet/internal/dao"
- "newuserGet/internal/model/do"
- "newuserGet/internal/model/entity"
- "strings"
- "time"
- )
- func Task(ctx context.Context) {
- // get rule
- var rules []entity.NewUserSendRule
- err := dao.NewUserSendRule.Ctx(ctx).Scan(&rules)
- if err != nil {
- g.Log().Error(ctx, "获取规则失败", err)
- return
- }
- // 遍历规则
- for i := 0; i < len(rules); i++ {
- g.Log().Infof(ctx, "开始处理第%v个规则:id-%v name:%v \n", i, rules[i].Id, rules[i].Name)
- // 获取注册时间规则用户和过滤行为
- userList, err := getFromRegisterBehavior(ctx, rules[i])
- if err != nil {
- g.Log().Error(ctx, err)
- continue
- }
- if len(userList) == 0 {
- g.Log().Info(ctx, "当前规则getFromRegisterBehavior未获取到有效用户", rules[i].Id, rules[i].Name)
- continue
- }
- if rules[i].CallState != "" {
- // 过滤外呼状态
- userList, err = filterCallState(ctx, rules[i], userList)
- if err != nil {
- g.Log().Error(ctx, err)
- continue
- }
- if len(userList) == 0 {
- g.Log().Info(ctx, "当前规则filterCallState未获取到有效用户", rules[i].Id, rules[i].Name)
- continue
- }
- }
- // 过滤销售进程
- userList = filterTrailStatus(ctx, rules[i], userList)
- // 保存用户
- saveList := []do.NewUserSendLog{}
- for j := 0; j <= len(userList); j++ {
- saveList = append(saveList, do.NewUserSendLog{
- Phone: userList[j].Phone,
- UserId: userList[j].MgoId,
- CreateTime: gtime.Now(),
- })
- }
- g.Log().Infof(ctx, "完成--第%v个规则:id-%v name:%v \n", i, rules[i].Id, rules[i].Name)
- }
- }
- type User struct {
- Phone string `json:"phone"`
- MgoId string `json:"mgoId"`
- }
- const (
- OrSQL = "SELECT bitobj from pub_tags.dwd_d_tag ddt WHERE ddt.id in (%s) "
- BitMapSQL = "SELECT bitmapAnd((%s),(%s)) as userIds"
- QueryUserIdSQL = `SELECT
- DISTINCT dmp.mgoUserId as mgoId,dmp.phone as phone
- from
- pub_tags.dwd_mgo_position dmp
- WHERE
- bitmapHasAny( (%s),
- bitmapBuild([toUInt64(dmp.baseUserId)])) and dmp.mgoUserId!='' and dmp.phone!='';`
- CallStateNotDialed = "0" // 未拨打
- CallStateNotDeal = "notDeal" // 振铃未接通
- CallStateIvr = "ivr" // ivr
- CallStatDealing = "dealing" //已接听
- )
- // 通过时间和行为计算用户
- func getFromRegisterBehavior(ctx context.Context, rule entity.NewUserSendRule) (userList []*User, err error) {
- start := time.Now()
- defer func() {
- g.Log().Info(ctx, "getFromRegisterBehavior 耗时:", time.Since(start))
- }()
- // 时间标签并 之后与行为标签交
- // 处理注册时间标签
- if rule.RegisterTagIds == "" {
- return nil, errors.New("注册时间标签id为空")
- }
- regQuery := fmt.Sprintf(OrSQL, rule.RegisterTagIds)
- filterQuery := regQuery
- if rule.BehaviorTagIds != "" {
- //拼接行为标签sql
- behQuery := fmt.Sprintf(OrSQL, rule.BehaviorTagIds)
- filterQuery = fmt.Sprintf(BitMapSQL, regQuery, behQuery)
- }
- // 处理mgoid和手机号 拼接sql
- finalQuery := fmt.Sprintf(QueryUserIdSQL, filterQuery)
- g.Log().Info(ctx, "getFromRegisterBehavior 查询sql", finalQuery)
- err = dao.DwdDUserTag.DB().Raw(finalQuery).Scan(&userList)
- if err != nil {
- return nil, err
- }
- g.Log().Info(ctx, userList)
- return
- }
- // 外呼状态
- func filterCallState(ctx context.Context, rule entity.NewUserSendRule, userList []*User) (newUserList []*User, err error) {
- start := time.Now()
- defer func() {
- g.Log().Info(ctx, "filterCallState 耗时:", time.Since(start))
- }()
- callstateList := strings.Split(rule.CallState, ",")
- for i := 0; i < len(userList); i++ {
- for j := 0; j < len(callstateList); j++ {
- // 未拨打 判断不存在
- if callstateList[j] == CallStateNotDialed {
- exist, err := dao.VoiceRecord.Ctx(ctx).Where("CalledNo=?", userList[i].Phone).Exist()
- if err != nil {
- g.Log().Error(ctx, "filterCallState CallStateNotDialed err:", err)
- continue
- }
- if !exist {
- newUserList = append(newUserList, userList[i])
- continue
- }
- }
- // 已接听 至少一个记录
- if callstateList[j] == CallStatDealing {
- exist, err := dao.VoiceRecord.Ctx(ctx).Where("CalledNo=? and State=?", userList[i].Phone, CallStatDealing).Exist()
- if err != nil {
- g.Log().Error(ctx, "filterCallState CallStatDealing err:", err, userList[i])
- continue
- }
- if exist {
- newUserList = append(newUserList, userList[i])
- continue
- }
- }
- // 其他的 判断是否存在记录
- findState := strings.Split(callstateList[j], "#")
- exist, err := dao.VoiceRecord.Ctx(ctx).Where("CalledNo=?", userList[i].Phone).WhereNotIn(dao.VoiceRecord.Columns().CallState, findState).Exist()
- if err != nil {
- g.Log().Error(ctx, "filterCallState otherstate err:", err, findState, userList[i])
- continue
- }
- if !exist {
- continue
- }
- // 存在则查询是否包含其他记录
- exist, err = dao.VoiceRecord.Ctx(ctx).Where("CalledNo=?", userList[i].Phone).WhereNotIn(dao.VoiceRecord.Columns().CallState, findState).Exist()
- if err != nil {
- g.Log().Error(ctx, "filterCallState otherstate notin err:", err, findState, userList[i])
- continue
- }
- if !exist {
- newUserList = append(newUserList, userList[i])
- continue
- }
- }
- }
- return
- }
- // 跟进状态
- func filterTrailStatus(ctx context.Context, rule entity.NewUserSendRule, userList []*User) (newUserList []*User) {
- // 拒绝沟通 最后一次销售跟进状态为拒绝沟通
- // 无意向客户 最后一次跟进状态为无意向客户
- return
- }
|