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 }