jobOrderRange.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. package userAnalysis
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/gogf/gf/v2/frame/g"
  6. "github.com/gogf/gf/v2/util/gconv"
  7. "strings"
  8. "time"
  9. )
  10. type (
  11. hasOrderProductClass struct {
  12. Seven map[BaseUserId]bool
  13. One map[BaseUserId]bool
  14. }
  15. hasOrderClass struct {
  16. fullData map[string]*hasOrderProductClass
  17. now time.Time
  18. }
  19. )
  20. // TiDBOrderRange 订单分析
  21. func (ua *UserAnalysis) TiDBOrderRange(ctx context.Context) ([]*AnalysisRes, error) {
  22. if len(ua.UserMapping) == 0 {
  23. return nil, nil
  24. }
  25. 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")
  26. if err != nil {
  27. g.Log().Errorf(ctx, "读取订单异常")
  28. return nil, err
  29. }
  30. var (
  31. now = time.Now()
  32. hasPay = map[BaseUserId]bool{}
  33. unBuyVipMonth, unBuyMemberMonth, unBuyVip45Day = map[BaseUserId]bool{}, map[BaseUserId]bool{}, map[BaseUserId]bool{}
  34. vip, member = map[BaseUserId]int{}, map[BaseUserId]int{}
  35. vip45d = map[BaseUserId]int{} //45天加购未购超级订阅
  36. hoc = &hasOrderClass{}
  37. )
  38. hoc.init(now)
  39. for index, m := range order.List() {
  40. if index%10e4 == 0 {
  41. g.Log().Infof(context.TODO(), "TiDBOrderRange %d/%d", index, order.Size())
  42. }
  43. var (
  44. userId = gconv.String(m["user_id"])
  45. baseUserId BaseUserId
  46. product = gconv.String(m["product_type"])
  47. orderStatus = gconv.Int(m["order_status"])
  48. )
  49. baseUserId, ok := ua.UserMapping[userId]
  50. if !ok {
  51. continue
  52. }
  53. if orderStatus == 1 {
  54. hasPay[baseUserId] = true
  55. }
  56. t, err := time.ParseInLocation(time.DateTime, gconv.String(m["create_time"]), time.Local)
  57. if err != nil {
  58. continue
  59. }
  60. //统计是否有订单
  61. hoc.hasOrderStatic(product, t, baseUserId, m["filter"])
  62. //统计超级订阅、大会员当月加购未购
  63. if product == "VIP订阅" || product == "大会员" {
  64. var (
  65. pay_money = gconv.Int(m["pay_money"])
  66. is_backstage_order = gconv.Int(m["is_backstage_order"])
  67. )
  68. if now.Month() == t.Month() && now.Year() == t.Year() {
  69. if product == "VIP订阅" {
  70. if orderStatus <= 0 && pay_money == 0 && is_backstage_order == 0 {
  71. vip[baseUserId] += 0
  72. } else {
  73. vip[baseUserId] += 1
  74. }
  75. }
  76. if product == "大会员" {
  77. if orderStatus <= 0 && pay_money == 0 && is_backstage_order == 0 {
  78. member[baseUserId] += 0
  79. } else {
  80. member[baseUserId] += 1
  81. }
  82. }
  83. }
  84. //统计45天超级订阅加购未购
  85. if now.Sub(t).Hours()/24 <= 45 {
  86. if orderStatus <= 0 && pay_money == 0 && is_backstage_order == 0 {
  87. vip45d[baseUserId] += 0
  88. } else {
  89. vip45d[baseUserId] += 1
  90. }
  91. }
  92. }
  93. }
  94. for id, i := range vip {
  95. if i == 0 {
  96. unBuyVipMonth[id] = true
  97. }
  98. }
  99. for id, i := range vip45d {
  100. if i == 0 {
  101. unBuyVip45Day[id] = true
  102. }
  103. }
  104. for id, i := range member {
  105. if i == 0 {
  106. unBuyMemberMonth[id] = true
  107. }
  108. }
  109. r := []*AnalysisRes{
  110. {Name: "付费用户", Code: "hasPay", Data: hasPay},
  111. {Name: "本月加购未购超级订阅", Code: "unBuyVipMonth", Data: unBuyVipMonth},
  112. {Name: "45天加购未购超级订阅", Code: "unBuyVip45Day", Data: unBuyVip45Day},
  113. {Name: "本月加购未购大会员", Code: "unBuyMemberMonth", Data: unBuyMemberMonth}}
  114. r = append(r, hoc.getAnalysisRes()...)
  115. return r, nil
  116. }
  117. func (hs *hasOrderClass) init(t time.Time) {
  118. tmp := map[string]*hasOrderProductClass{}
  119. 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"} {
  120. tmp[code] = &hasOrderProductClass{
  121. Seven: map[BaseUserId]bool{},
  122. One: map[BaseUserId]bool{},
  123. }
  124. }
  125. for _, code := range []string{"wy", "clzl", "ywsj", "hjcg", "jjztb", "af", "gcsjzx", "fw", "bx", "cwsj", "zbdl", "glzx"} {
  126. tmp[fmt.Sprintf("has_order_applet_%s", code)] = &hasOrderProductClass{
  127. Seven: map[BaseUserId]bool{},
  128. One: map[BaseUserId]bool{},
  129. }
  130. }
  131. hs.now = t
  132. hs.fullData = tmp
  133. }
  134. func (hs *hasOrderClass) hasOrderStatic(product string, createTime time.Time, baseUserId BaseUserId, filterObj interface{}) {
  135. var sevenDay, oneDay bool
  136. if hs.now.AddDate(0, 0, -7).Before(createTime) {
  137. sevenDay = true
  138. if hs.now.AddDate(0, 0, -7).Before(createTime) {
  139. oneDay = true
  140. }
  141. }
  142. if !sevenDay {
  143. return
  144. }
  145. var key string
  146. switch product {
  147. case "VIP订阅":
  148. key = "has_order_vip"
  149. case "大会员", "大会员-补充包", "大会员-招标文件解读", "大会员-子账号", "大会员-AI中标预测包":
  150. key = "has_order_member"
  151. case "省份订阅包":
  152. key = "has_order_areavip"
  153. case "企业中标分析报告下载包":
  154. key = "has_order_winner_report"
  155. case "市场分析定制报告下载包":
  156. key = "has_order_market_report"
  157. case "业主采购分析报告下载包":
  158. key = "has_order_buyer_report"
  159. case "采购单位画像包":
  160. key = "has_order_buyer_portrait_package"
  161. case "附件下载包":
  162. key = "has_order_attach_package"
  163. case "投标企业信用报告":
  164. key = "has_order_ent_credit_report"
  165. default:
  166. //碎片化小程序
  167. if strings.Index(product, "|") != -1 {
  168. if filterMap := gconv.Map(filterObj); filterMap != nil && len(filterMap) > 0 {
  169. code := gconv.String(filterMap["industryCode"])
  170. key = fmt.Sprintf("has_order_applet_%s", code)
  171. }
  172. }
  173. }
  174. if ct := hs.fullData[key]; ct != nil {
  175. ct.Seven[baseUserId] = true
  176. if oneDay {
  177. ct.One[baseUserId] = true
  178. }
  179. }
  180. }
  181. func (hs *hasOrderClass) getAnalysisRes() []*AnalysisRes {
  182. var (
  183. hasOrder7day = map[BaseUserId]bool{}
  184. rData = []*AnalysisRes{}
  185. )
  186. for s, class := range hs.fullData {
  187. for id, _ := range class.Seven {
  188. hasOrder7day[id] = true
  189. }
  190. rData = append(rData, &AnalysisRes{fmt.Sprintf("近1天下单%s", s), fmt.Sprintf("%s_1_day", s), class.One, false})
  191. }
  192. rData = append(rData, &AnalysisRes{"近7天下单用户", "has_order_7_day", hasOrder7day, false})
  193. return nil
  194. }