|
@@ -2,243 +2,46 @@ package main
|
|
|
|
|
|
import (
|
|
|
"context"
|
|
|
+ "fmt"
|
|
|
"github.com/gogf/gf/v2/frame/g"
|
|
|
- "github.com/gogf/gf/v2/util/gconv"
|
|
|
- "strings"
|
|
|
"time"
|
|
|
- "workTasks/common"
|
|
|
+ "workTasks/userSign/userAnalysis"
|
|
|
)
|
|
|
|
|
|
-type UserAnalysis struct {
|
|
|
- UserMapping map[string]BaseUserId
|
|
|
-
|
|
|
- BinPhone, BindMail map[BaseUserId]bool
|
|
|
- Vip, Vip15, Vip30 map[BaseUserId]bool
|
|
|
- Member, MemberExpire map[BaseUserId]bool
|
|
|
- hasPay map[BaseUserId]bool
|
|
|
- UnBuyVip30, UnBuyMember30 map[BaseUserId]bool
|
|
|
+func main() {
|
|
|
+ runOnce(context.TODO())
|
|
|
}
|
|
|
-type BaseUserId int64
|
|
|
|
|
|
-func (ua *UserAnalysis) MgoUserRange(ctx context.Context) {
|
|
|
- sess := common.MG.DB().GetMgoConn()
|
|
|
- defer common.MG.DB().DestoryMongoConn(sess)
|
|
|
- //个人身份
|
|
|
- it := sess.DB("qfw").C("user").Select(g.Map{"base_user_id": 1, "s_phone": 1, "s_m_phone": 1, "s_email": 1, "l_registedate": 1, "i_vip_status": 1, "l_vip_endtime": 1, "i_member_status": 1}).Iter()
|
|
|
- var (
|
|
|
- index int64
|
|
|
- now = time.Now()
|
|
|
- )
|
|
|
- for m := make(map[string]interface{}); it.Next(&m); {
|
|
|
- index++
|
|
|
- if index%10e4 == 0 {
|
|
|
- g.Log().Infof(context.TODO(), "MgoUserRange %d", index)
|
|
|
- }
|
|
|
- var (
|
|
|
- base_user_id = BaseUserId(gconv.Int64(m["base_user_id"]))
|
|
|
- s_phone = gconv.String(m["s_phone"])
|
|
|
- s_m_phone = gconv.String(m["s_m_phone"])
|
|
|
- s_email = gconv.String(m["s_email"])
|
|
|
- //registedate = time.Unix(gconv.Int64(m["l_registedate"]), 0)
|
|
|
- )
|
|
|
- //绑定手机号用户
|
|
|
- if len(s_phone) == 11 || len(s_m_phone) == 11 {
|
|
|
- ua.BinPhone[base_user_id] = true
|
|
|
- }
|
|
|
- //绑定邮箱用户
|
|
|
- if s_email != "" && strings.Contains(s_email, "@") {
|
|
|
- ua.BindMail[base_user_id] = true
|
|
|
- }
|
|
|
- //超级订阅用户处理
|
|
|
- if vip_status := gconv.Int(m["i_vip_status"]); vip_status > 0 {
|
|
|
- ua.Vip[base_user_id] = true
|
|
|
- if timeStamp := gconv.Int64(m["l_vip_endtime"]); timeStamp > 0 {
|
|
|
- var vip_endtime = time.Unix(timeStamp, 0)
|
|
|
- if vip_endtime.AddDate(0, 0, -15).Before(now) {
|
|
|
- ua.Vip15[base_user_id] = true
|
|
|
- }
|
|
|
- if vip_endtime.AddDate(0, 0, -30).Before(now) {
|
|
|
- ua.Vip30[base_user_id] = true
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- //大会员处理
|
|
|
- if member_status := gconv.Int(m["i_member_status"]); member_status > 0 {
|
|
|
- ua.Member[base_user_id] = true
|
|
|
- } else if member_status != 0 {
|
|
|
- ua.MemberExpire[base_user_id] = true
|
|
|
- }
|
|
|
+func runOnce(ctx context.Context) {
|
|
|
+ manager := userAnalysis.NewManager()
|
|
|
+ if err := manager.LoadMapping(); err != nil {
|
|
|
+ g.Log().Errorf(ctx, "加载对应关系异常 %v", err)
|
|
|
}
|
|
|
- g.Log().Infof(ctx, "MgoUserRange 加载%d挑数据完成", index)
|
|
|
- //企业身份
|
|
|
-}
|
|
|
-
|
|
|
-func (ua *UserAnalysis) MgoEntUserRange(ctx context.Context) {
|
|
|
- sess := common.MG.DB().GetMgoConn()
|
|
|
- defer common.MG.DB().DestoryMongoConn(sess)
|
|
|
-
|
|
|
- var (
|
|
|
- Vip, Vip15, Vip30 = map[int64]bool{}, map[int64]bool{}, map[int64]bool{}
|
|
|
- Member, MemberExpire = map[int64]bool{}, map[int64]bool{}
|
|
|
- )
|
|
|
- //企业身份
|
|
|
- it := sess.DB("qfw").C("ent_user").Select(g.Map{"i_userid": 1, "l_registedate": 1, "i_vip_status": 1, "l_vip_endtime": 1, "i_member_status": 1}).Iter()
|
|
|
- var (
|
|
|
- index int64
|
|
|
- now = time.Now()
|
|
|
- )
|
|
|
- for m := make(map[string]interface{}); it.Next(&m); {
|
|
|
- index++
|
|
|
- if index%10e4 == 0 {
|
|
|
- g.Log().Infof(context.TODO(), "MgoUserRange %d", index)
|
|
|
- }
|
|
|
- var (
|
|
|
- entUserId = gconv.Int64(m["i_userid"])
|
|
|
- )
|
|
|
- //超级订阅用户处理
|
|
|
- if vip_status := gconv.Int(m["i_vip_status"]); vip_status > 0 {
|
|
|
- Vip[entUserId] = true
|
|
|
- if timeStamp := gconv.Int64(m["l_vip_endtime"]); timeStamp > 0 {
|
|
|
- var vip_endtime = time.Unix(timeStamp, 0)
|
|
|
- if vip_endtime.AddDate(0, 0, -15).Before(now) {
|
|
|
- Vip15[entUserId] = true
|
|
|
- }
|
|
|
- if vip_endtime.AddDate(0, 0, -30).Before(now) {
|
|
|
- Vip30[entUserId] = true
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- //大会员处理
|
|
|
- if member_status := gconv.Int(m["i_member_status"]); member_status > 0 {
|
|
|
- Member[entUserId] = true
|
|
|
- } else if member_status != 0 {
|
|
|
- MemberExpire[entUserId] = true
|
|
|
- }
|
|
|
+ var allRes []*userAnalysis.AnalysisRes
|
|
|
+ //订单分析
|
|
|
+ if res, err := manager.TiDBOrderRange(ctx); err == nil && len(res) > 0 {
|
|
|
+ allRes = append(allRes, res...)
|
|
|
}
|
|
|
- g.Log().Infof(ctx, "MgoUserRange 加载%d挑数据完成", index)
|
|
|
- //根据entUserId获取
|
|
|
- baseUserIdMapping := func() map[int64]BaseUserId {
|
|
|
- var (
|
|
|
- all = map[int64]bool{}
|
|
|
- rData = map[int64]BaseUserId{}
|
|
|
- )
|
|
|
- for i, _ := range Member {
|
|
|
- all[i] = true
|
|
|
- }
|
|
|
- for i, _ := range Vip {
|
|
|
- all[i] = true
|
|
|
- }
|
|
|
- doQuery := func(entUserId []int64) map[int64]BaseUserId {
|
|
|
- return nil
|
|
|
- }
|
|
|
-
|
|
|
- var query []int64
|
|
|
- for i, _ := range all {
|
|
|
- query = append(query, i)
|
|
|
- if i >= 500 {
|
|
|
- for m, n := range doQuery(query) {
|
|
|
- rData[m] = n
|
|
|
- }
|
|
|
- query = []int64{}
|
|
|
- }
|
|
|
- }
|
|
|
- if len(query) > 0 {
|
|
|
- for m, n := range doQuery(query) {
|
|
|
- rData[m] = n
|
|
|
- }
|
|
|
- }
|
|
|
- return rData
|
|
|
- }()
|
|
|
- //Vip, Vip15, Vip30
|
|
|
- for entId, _ := range Vip {
|
|
|
- if baseUserId, ok := baseUserIdMapping[entId]; ok {
|
|
|
- ua.Vip[baseUserId] = true
|
|
|
- }
|
|
|
- }
|
|
|
- for entId, _ := range Vip15 {
|
|
|
- if baseUserId, ok := baseUserIdMapping[entId]; ok {
|
|
|
- ua.Vip15[baseUserId] = true
|
|
|
- }
|
|
|
- }
|
|
|
- for entId, _ := range Vip30 {
|
|
|
- if baseUserId, ok := baseUserIdMapping[entId]; ok {
|
|
|
- ua.Vip30[baseUserId] = true
|
|
|
- }
|
|
|
- }
|
|
|
- for entId, _ := range Member {
|
|
|
- if baseUserId, ok := baseUserIdMapping[entId]; ok {
|
|
|
- ua.Member[baseUserId] = true
|
|
|
- }
|
|
|
+ //会员状态分析
|
|
|
+ if res, err := manager.GetMgoUserRes(ctx); err == nil && len(res) > 0 {
|
|
|
+ allRes = append(allRes, res...)
|
|
|
}
|
|
|
- for entId, _ := range MemberExpire {
|
|
|
- if baseUserId, ok := baseUserIdMapping[entId]; ok {
|
|
|
- ua.MemberExpire[baseUserId] = true
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
|
|
|
-func (ua *UserAnalysis) TiDBOrderRange(ctx context.Context) {
|
|
|
- order, err := g.DB().Query(ctx, "SELECT user_id,order_status,product_type,create_time,order_money FROM dataexport_order")
|
|
|
- if err != nil {
|
|
|
- g.Log().Errorf(ctx, "读取订单异常")
|
|
|
- }
|
|
|
var (
|
|
|
- now = time.Now()
|
|
|
- vip, member = map[BaseUserId]int{}, map[BaseUserId]int{}
|
|
|
+ sourceArr = []string{"pc", "wx", "app"}
|
|
|
+ nowTime = time.Now()
|
|
|
+ unActiveTime = []int{30, 90}
|
|
|
)
|
|
|
- for index, m := range order.List() {
|
|
|
- if index%10e4 == 0 {
|
|
|
- g.Log().Infof(context.TODO(), "TiDBOrderRange %d/%d", index, order.Size())
|
|
|
- }
|
|
|
- var (
|
|
|
- userId = gconv.String(m["user_id"])
|
|
|
- baseUserId BaseUserId
|
|
|
- product = gconv.String(m["product_type"])
|
|
|
- orderStatus = gconv.Int(m["order_status"])
|
|
|
- )
|
|
|
- baseUserId, ok := ua.UserMapping[userId]
|
|
|
- if !ok {
|
|
|
- continue
|
|
|
- }
|
|
|
- if orderStatus == 1 {
|
|
|
- ua.hasPay[baseUserId] = true
|
|
|
- }
|
|
|
- if orderStatus == -1 {
|
|
|
- continue
|
|
|
- }
|
|
|
- //统计超级订阅、大会员当月加购未购
|
|
|
- if product == "VIP订阅" || product == "大会员" {
|
|
|
- var order_money = gconv.Int(m["order_money"])
|
|
|
- t, err := time.ParseInLocation(time.DateTime, gconv.String(m["create_time"]), time.Local)
|
|
|
- if err != nil {
|
|
|
- continue
|
|
|
- }
|
|
|
- if now.Month() == t.Month() && now.Year() == t.Year() {
|
|
|
- if product == "VIP订阅" {
|
|
|
- if orderStatus <= 0 && order_money == 0 {
|
|
|
- vip[baseUserId] += 0
|
|
|
- } else {
|
|
|
- vip[baseUserId] += 1
|
|
|
- }
|
|
|
- }
|
|
|
- if product == "大会员" {
|
|
|
- if orderStatus <= 0 && order_money == 0 {
|
|
|
- member[baseUserId] += 0
|
|
|
- } else {
|
|
|
- member[baseUserId] += 1
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- for id, i := range vip {
|
|
|
- if i == 0 {
|
|
|
- ua.UnBuyVip30[id] = true
|
|
|
+ //活跃用户分析
|
|
|
+ for _, source := range sourceArr {
|
|
|
+ if res, err := manager.ActiveUserLoad(ctx, nowTime.AddDate(0, 0, -30), source); err == nil && len(res) > 0 {
|
|
|
+ allRes = append(allRes, &userAnalysis.AnalysisRes{Name: fmt.Sprintf("30天%s活跃用户", source), Code: fmt.Sprintf("active-%s-%d", source, 30), Data: res})
|
|
|
}
|
|
|
}
|
|
|
- for id, i := range member {
|
|
|
- if i == 0 {
|
|
|
- ua.UnBuyMember30[id] = true
|
|
|
+ //未活跃用户占比
|
|
|
+ for _, day := range unActiveTime {
|
|
|
+ if res, err := manager.UnActiveUserLoad(ctx, nowTime.AddDate(0, 0, -day)); err == nil && len(res) > 0 {
|
|
|
+ allRes = append(allRes, &userAnalysis.AnalysisRes{Name: fmt.Sprintf("%d天未活跃用户", day), Code: "hasPay", Data: res})
|
|
|
}
|
|
|
}
|
|
|
}
|