123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- package userAnalysis
- import (
- "context"
- "fmt"
- "github.com/gogf/gf/v2/frame/g"
- "github.com/gogf/gf/v2/util/gconv"
- "strings"
- "time"
- )
- type (
- hasOrderProductClass struct {
- Seven map[BaseUserId]bool
- One map[BaseUserId]bool
- }
- hasOrderClass struct {
- fullData map[string]*hasOrderProductClass
- now time.Time
- }
- )
- // TiDBOrderRange 订单分析
- func (ua *UserAnalysis) TiDBOrderRange(ctx context.Context) ([]*AnalysisRes, error) {
- if len(ua.UserMapping) == 0 {
- return nil, nil
- }
- order, err := g.DB("jianyu").Query(ctx, "SELECT user_id,order_status,product_type,create_time,pay_money,is_backstage_order,filter FROM dataexport_order")
- if err != nil {
- g.Log().Errorf(ctx, "读取订单异常")
- return nil, err
- }
- var (
- now = time.Now()
- hasPay = map[BaseUserId]bool{}
- unBuyVipMonth, unBuyMemberMonth, unBuyVip45Day = map[BaseUserId]bool{}, map[BaseUserId]bool{}, map[BaseUserId]bool{}
- vip, member = map[BaseUserId]int{}, map[BaseUserId]int{}
- vip45d = map[BaseUserId]int{} //45天加购未购超级订阅
- hoc = &hasOrderClass{}
- )
- hoc.init(now)
- 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 {
- hasPay[baseUserId] = true
- }
- t, err := time.ParseInLocation(time.DateTime, gconv.String(m["create_time"]), time.Local)
- if err != nil {
- continue
- }
- //统计是否有订单
- hoc.hasOrderStatic(product, t, baseUserId, m["filter"])
- //统计超级订阅、大会员当月加购未购
- if product == "VIP订阅" || product == "大会员" {
- var (
- pay_money = gconv.Int(m["pay_money"])
- is_backstage_order = gconv.Int(m["is_backstage_order"])
- )
- if now.Month() == t.Month() && now.Year() == t.Year() {
- if product == "VIP订阅" {
- if orderStatus <= 0 && pay_money == 0 && is_backstage_order == 0 {
- vip[baseUserId] += 0
- } else {
- vip[baseUserId] += 1
- }
- }
- if product == "大会员" {
- if orderStatus <= 0 && pay_money == 0 && is_backstage_order == 0 {
- member[baseUserId] += 0
- } else {
- member[baseUserId] += 1
- }
- }
- }
- //统计45天超级订阅加购未购
- if now.Sub(t).Hours()/24 <= 45 {
- if orderStatus <= 0 && pay_money == 0 && is_backstage_order == 0 {
- vip45d[baseUserId] += 0
- } else {
- vip45d[baseUserId] += 1
- }
- }
- }
- }
- for id, i := range vip {
- if i == 0 {
- unBuyVipMonth[id] = true
- }
- }
- for id, i := range vip45d {
- if i == 0 {
- unBuyVip45Day[id] = true
- }
- }
- for id, i := range member {
- if i == 0 {
- unBuyMemberMonth[id] = true
- }
- }
- r := []*AnalysisRes{
- {Name: "付费用户", Code: "hasPay", Data: hasPay},
- {Name: "本月加购未购超级订阅", Code: "unBuyVipMonth", Data: unBuyVipMonth},
- {Name: "45天加购未购超级订阅", Code: "unBuyVip45Day", Data: unBuyVip45Day},
- {Name: "本月加购未购大会员", Code: "unBuyMemberMonth", Data: unBuyMemberMonth}}
- r = append(r, hoc.getAnalysisRes()...)
- return r, nil
- }
- func (hs *hasOrderClass) init(t time.Time) {
- tmp := map[string]*hasOrderProductClass{}
- for _, code := range []string{"has_order_vip", "has_order_member", "has_order_areavip", "has_order_winner_report", "has_order_market_report", "has_order_buyer_report", "has_order_buyer_portrait_package", "has_order_attach_package", "has_order_ent_credit_report"} {
- tmp[code] = &hasOrderProductClass{
- Seven: map[BaseUserId]bool{},
- One: map[BaseUserId]bool{},
- }
- }
- for _, code := range []string{"wy", "clzl", "ywsj", "hjcg", "jjztb", "af", "gcsjzx", "fw", "bx", "cwsj", "zbdl", "glzx"} {
- tmp[fmt.Sprintf("has_order_applet_%s", code)] = &hasOrderProductClass{
- Seven: map[BaseUserId]bool{},
- One: map[BaseUserId]bool{},
- }
- }
- hs.now = t
- hs.fullData = tmp
- }
- func (hs *hasOrderClass) hasOrderStatic(product string, createTime time.Time, baseUserId BaseUserId, filterObj interface{}) {
- var sevenDay, oneDay bool
- if hs.now.AddDate(0, 0, -7).Before(createTime) {
- sevenDay = true
- if hs.now.AddDate(0, 0, -7).Before(createTime) {
- oneDay = true
- }
- }
- if !sevenDay {
- return
- }
- var key string
- switch product {
- case "VIP订阅":
- key = "has_order_vip"
- case "大会员", "大会员-补充包", "大会员-招标文件解读", "大会员-子账号", "大会员-AI中标预测包":
- key = "has_order_member"
- case "省份订阅包":
- key = "has_order_areavip"
- case "企业中标分析报告下载包":
- key = "has_order_winner_report"
- case "市场分析定制报告下载包":
- key = "has_order_market_report"
- case "业主采购分析报告下载包":
- key = "has_order_buyer_report"
- case "采购单位画像包":
- key = "has_order_buyer_portrait_package"
- case "附件下载包":
- key = "has_order_attach_package"
- case "投标企业信用报告":
- key = "has_order_ent_credit_report"
- default:
- //碎片化小程序
- if strings.Index(product, "|") != -1 {
- if filterMap := gconv.Map(filterObj); filterMap != nil && len(filterMap) > 0 {
- code := gconv.String(filterMap["industryCode"])
- key = fmt.Sprintf("has_order_applet_%s", code)
- }
- }
- }
- if ct := hs.fullData[key]; ct != nil {
- ct.Seven[baseUserId] = true
- if oneDay {
- ct.One[baseUserId] = true
- }
- }
- }
- func (hs *hasOrderClass) getAnalysisRes() []*AnalysisRes {
- var (
- hasOrder7day = map[BaseUserId]bool{}
- rData = []*AnalysisRes{}
- )
- for s, class := range hs.fullData {
- for id, _ := range class.Seven {
- hasOrder7day[id] = true
- }
- rData = append(rData, &AnalysisRes{fmt.Sprintf("近1天下单%s", s), fmt.Sprintf("%s_1_day", s), class.One, false})
- }
- rData = append(rData, &AnalysisRes{"近7天下单用户", "has_order_7_day", hasOrder7day, false})
- return nil
- }
|