@@ -0,0 +1,55 @@
|
||||
package prdcthsomod
|
||||
|
||||
import (
|
||||
"91porn-server/models/commod"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
// PaymentLogBody 商品交易订单请求参数
|
||||
type PaymentLogBody struct {
|
||||
ProductID primitive.ObjectID `bson:"productID" json:"productID" binding:"required" ` //产品id
|
||||
Name string `bson:"name" json:"name" binding:"required" ` //商品名字
|
||||
Amount int64 `bson:"amount" json:"amount" binding:"required"` //成交价格
|
||||
ProductType int `bson:"productType" json:"productType"` //产品类型
|
||||
}
|
||||
|
||||
// ProductHistoryQueryReq 通用查询参数
|
||||
type ProductHistoryQueryReq struct {
|
||||
UID *uint64 `form:"uid" json:"uid,omitempty" bson:"uid"` // 用户id
|
||||
ProductType *commod.ProductType `form:"productType" json:"productType" ` // 产品类型 // 0-会员卡 21-预售卡
|
||||
AdvanceOrderStatus *int `form:"advanceOrderStatus" json:"advanceOrderStatus"` // 预售订单状态 // 2-预付成功 4-尾款支付成功
|
||||
Start *time.Time `form:"start" json:"start"` // 开始时间
|
||||
End *time.Time `form:"end" json:"end"` // 结束时间
|
||||
commod.Page
|
||||
}
|
||||
|
||||
type ProductHistoryQueryResp struct {
|
||||
Total int64 `json:"total"`
|
||||
List []*ProductHistory `json:"list"`
|
||||
}
|
||||
|
||||
func (req *ProductHistoryQueryReq) GetCond() bson.M {
|
||||
cond := bson.M{}
|
||||
if req.UID != nil {
|
||||
cond["uid"] = *req.UID
|
||||
}
|
||||
if req.ProductType != nil {
|
||||
cond["productType"] = *req.ProductType
|
||||
}
|
||||
if req.AdvanceOrderStatus != nil {
|
||||
cond["advanceOrderStatus"] = *req.AdvanceOrderStatus
|
||||
}
|
||||
if req.Start != nil && req.End != nil {
|
||||
cond["createdAt"] = bson.M{"$gte": req.Start, "$lt": req.End}
|
||||
}
|
||||
return cond
|
||||
}
|
||||
|
||||
func (req *ProductHistoryQueryReq) GetOpt() *options.FindOptions {
|
||||
opt := options.Find().SetSkip(req.Skip64()).SetLimit(req.Limit64()).SetSort(bson.D{{Key: "createdAt", Value: -1}})
|
||||
return opt
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package prdcthsomod
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
)
|
||||
|
||||
type M = bson.M
|
||||
|
||||
// PayVipTotalAmountByCreatedTime 购买VIP的总金额
|
||||
func PayVipTotalAmountByCreatedTime(start time.Time, end time.Time) (int64, error) {
|
||||
filter := M{
|
||||
"createdAt": M{
|
||||
"$gte": start,
|
||||
"$lt": end,
|
||||
},
|
||||
"productType": VIP,
|
||||
}
|
||||
list := make([]struct {
|
||||
Amount int64 `bson:"amount"`
|
||||
}, 0)
|
||||
if err := coll(nil).Find(&list, filter); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
var totalAmount int64
|
||||
for _, v := range list {
|
||||
totalAmount += v.Amount
|
||||
}
|
||||
return totalAmount, nil
|
||||
}
|
||||
|
||||
// PayVipUIDSByCreatedTime 购买VIP的用户UID
|
||||
func PayVipUIDSByCreatedTime(start time.Time, end time.Time) ([]uint64, error) {
|
||||
filter := M{
|
||||
"createdAt": M{
|
||||
"$gte": start,
|
||||
"$lt": end,
|
||||
},
|
||||
"productType": VIP,
|
||||
}
|
||||
list := make([]struct {
|
||||
UID uint64 `bson:"uid"`
|
||||
}, 0)
|
||||
if err := coll(nil).Find(&list, filter); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uidList := make([]uint64, len(list))
|
||||
for i, v := range list {
|
||||
uidList[i] = v.UID
|
||||
}
|
||||
return uidList, nil
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
package prdcthsomod
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/models"
|
||||
"91porn-server/models/commod"
|
||||
"91porn-server/models/v/productmod"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
const table = models.ProductHistory
|
||||
|
||||
// initIndex 设置index
|
||||
func initIndex() {
|
||||
coll := coll(nil)
|
||||
many := []mongo.IndexModel{
|
||||
{
|
||||
Keys: bson.D{{Key: "uid", Value: 1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "productID", Value: 1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "name", Value: 1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "amount", Value: 1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "productType", Value: 1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "status", Value: 1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "createdAt", Value: 1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "updatedAt", Value: 1}},
|
||||
},
|
||||
// 用户运营导出预售状态相关的订单
|
||||
{
|
||||
Keys: bson.D{{Key: "advanceOrderStatus", Value: 1}, {Key: "createdAt", Value: -1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "deductType", Value: 1}, {Key: "createdAt", Value: -1}},
|
||||
Options: options.Index().SetSparse(true),
|
||||
},
|
||||
{
|
||||
Keys: bson.D{
|
||||
{Key: "experimentId", Value: 1},
|
||||
{Key: "experimentVariant", Value: 1},
|
||||
{Key: "productID", Value: 1},
|
||||
},
|
||||
Options: options.Index().
|
||||
SetName("vip_experiment_gold_order_statistics").
|
||||
SetPartialFilterExpression(bson.M{"experimentId": bson.M{"$gt": ""}}),
|
||||
},
|
||||
}
|
||||
if _, err := coll.CreateIndex(many); err != nil {
|
||||
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
|
||||
}
|
||||
}
|
||||
|
||||
func coll(t *db.MongoTool) *db.MongoTool {
|
||||
if t == nil {
|
||||
return mdb.Coll(table)
|
||||
}
|
||||
return t.Coll(table)
|
||||
}
|
||||
|
||||
func IsBoughtVIP(uid uint64) (bool, error) {
|
||||
p := ProductHistory{}
|
||||
if err := coll(nil).FindOne(&p, bson.M{"uid": uid, "productType": VIP}); err != nil {
|
||||
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "IsBoughtVIP", table, "FindOne", err), log.Any("uid", uid))
|
||||
return false, err
|
||||
}
|
||||
return p.UID != 0, nil
|
||||
}
|
||||
|
||||
// GetUserLastVip 获取用户最后充值的VIP
|
||||
func GetUserLastVip(uid uint64) (productID primitive.ObjectID, productName string, amount int64) {
|
||||
p := ProductHistory{}
|
||||
opt := options.FindOne().SetSort(bson.D{{Key: "createdAt", Value: -1}})
|
||||
if err := coll(nil).FindOne(&p, bson.M{"uid": uid, "productType": bson.M{"$in": []commod.ProductType{productmod.VIP, productmod.NewUser, productmod.AdvanceCard}}}, opt); err != nil {
|
||||
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "IsBoughtVIP", table, "FindOne", err), log.Any("uid", uid))
|
||||
return primitive.NilObjectID, "", 0
|
||||
}
|
||||
if p.ProductType == productmod.AdvanceCard {
|
||||
return productID, "", 0
|
||||
}
|
||||
if p.IsUpgrade {
|
||||
// 假设A:100 B:300 C:500 如果A连续升到B,不这么处理,就会变成B=》C要付款300,实际应该给200差价就好
|
||||
return p.ProductID, p.Name, p.PurchasePrice
|
||||
}
|
||||
return p.ProductID, p.Name, p.Amount
|
||||
}
|
||||
|
||||
// InsertProductHistory 插入一条数据
|
||||
func InsertProductHistory(t *db.MongoTool, p *ProductHistory) error {
|
||||
p.CreatedAt = time.Now()
|
||||
p.UpdatedAt = time.Now()
|
||||
res, err := coll(t).InsertOne(p)
|
||||
if err != nil {
|
||||
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "InsertProductHistory", table, "InsertOne", err))
|
||||
return err
|
||||
}
|
||||
p.ID = res.InsertedID.(primitive.ObjectID)
|
||||
return nil
|
||||
}
|
||||
|
||||
func InsertManyProductHistory(t *db.MongoTool, p []ProductHistory) error {
|
||||
if _, err := coll(t).InsertMany(p); err != nil {
|
||||
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "InsertProductHistory", table, "InsertOne", err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// FindProductHistorys 查询所有ProductHistory类型
|
||||
func FindProductHistorys(cond bson.M, opts *options.FindOptions) (total int64, data []*ProductHistory, err error) {
|
||||
data = make([]*ProductHistory, 0)
|
||||
if err = coll(nil).Find(&data, cond, opts); err != nil {
|
||||
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindProductHistorys", table, "Find", err), log.Any("cond", cond))
|
||||
return
|
||||
}
|
||||
total, err = coll(nil).Count(cond)
|
||||
if err != nil {
|
||||
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindProductHistorys", table, "Count", err), log.Any("cond", cond))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// FindList
|
||||
func FindList(cond bson.M, opts *options.FindOptions) (data []*ProductHistory, err error) {
|
||||
data = make([]*ProductHistory, 0)
|
||||
if err = coll(nil).Find(&data, cond, opts); err != nil {
|
||||
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindList", table, "Find", err), log.Any("cond", cond))
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func FindUserProductHistory(uid uint64) (list []ProductHistory, err error) {
|
||||
f := bson.M{"uid": uid, "productType": bson.M{"$in": []commod.ProductType{productmod.VIP, productmod.OTHER,
|
||||
productmod.MeetingCard, productmod.VideoDiscount,
|
||||
productmod.VideoFreeCard, productmod.VideoDiscount, productmod.VideoFreeCard,
|
||||
}}}
|
||||
opts := options.Find().SetSort(bson.D{{Key: "createdAt", Value: -1}})
|
||||
if err = coll(nil).Find(&list, f, opts); err != nil {
|
||||
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindProductHistorys", table, "Find", err), log.Any("query", f))
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func FindUserProductHistoryByType(uid uint64) (list []ProductHistory, err error) {
|
||||
f := bson.M{"uid": uid, "productType": bson.M{"$in": []commod.ProductType{productmod.GameAdvanceCard}}}
|
||||
opts := options.Find().SetSort(bson.D{{Key: "createdAt", Value: -1}})
|
||||
if err = coll(nil).Find(&list, f, opts); err != nil {
|
||||
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindProductHistorys", table, "Find", err), log.Any("query", f))
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// FindProductHistorysByUID 查询所有ProductHistory类型
|
||||
func FindProductHistorysByUID(uid, pageNumber, pageSizse uint64) (total int64, data []*ProductHistory, hasNext bool, err error) {
|
||||
data = make([]*ProductHistory, 0)
|
||||
f := bson.M{"uid": uid, "productType": bson.M{"$in": []commod.ProductType{productmod.VIP, productmod.OTHER,
|
||||
productmod.MeetingCard, productmod.VideoDiscount,
|
||||
productmod.VideoFreeCard, productmod.VideoDiscount, productmod.VideoFreeCard,
|
||||
}}}
|
||||
skip := int64(pageSizse * (pageNumber - 1))
|
||||
limit := int64(pageSizse + 1)
|
||||
opts := options.FindOptions{
|
||||
Skip: &skip,
|
||||
Limit: &limit,
|
||||
Sort: bson.D{{Key: "createdAt", Value: -1}},
|
||||
}
|
||||
total, err = coll(nil).Count(f)
|
||||
if err != nil {
|
||||
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %ss fail error:%+v:", "FindProductHistorys", table, "Count", err), log.Any("query", f))
|
||||
}
|
||||
if err = coll(nil).Find(&data, f, &opts); err != nil {
|
||||
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindProductHistorys", table, "Find", err), log.Any("query", f))
|
||||
return
|
||||
}
|
||||
if len(data) > int(pageSizse) {
|
||||
hasNext = true
|
||||
data = data[:pageSizse]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// FindMany FindMany
|
||||
func FindMany(start, end time.Time, opts *options.FindOptions) (data []*ProductStat, err error) {
|
||||
cond := bson.M{"createdAt": bson.M{"$gte": start, "$lt": end}}
|
||||
data = make([]*ProductStat, 0)
|
||||
if err = coll(nil).Find(&data, cond, opts); err != nil {
|
||||
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindProductHistorys", table, "Find", err), log.Any("cond", cond))
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package prdcthsomod
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/models/commod"
|
||||
"91porn-server/models/v/productmod"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
const (
|
||||
VIP = commod.VIP //product 0
|
||||
VIDEO = commod.VIDEO //VIDEO视频
|
||||
MODEL = commod.MODEL //MODEL嫩模
|
||||
GAME = commod.GAME //GAME 游戏币
|
||||
MeetingCard = commod.MeetingCard //约会卡
|
||||
OTHER = commod.OTHER //OTHER 1
|
||||
VideoDiscount = commod.VideoDiscount //视频折扣卡
|
||||
VideoFreeCard = commod.VideoFreeCard //视频免费卡
|
||||
CoinMonthCard = commod.CoinMonthCard //金币月卡
|
||||
Media = commod.Media //动漫整本
|
||||
AdvanceCard = commod.AdvanceCard // 预售卡
|
||||
GameAdvanceCard = commod.GameAdvanceCard // 游戏售卡
|
||||
WhoringCard = commod.WhoringCard // 白嫖卡
|
||||
ImGroup = commod.WhoringCard // 加入群 24
|
||||
)
|
||||
const (
|
||||
COMPLETE = iota //COMPLETE 交易完成
|
||||
CANCEL //CANCEL 交易撤销
|
||||
)
|
||||
|
||||
var mdb *db.MongoDB
|
||||
|
||||
type DiscDoc = commod.DiscDoc
|
||||
|
||||
// ProductHistory 商品交易订单
|
||||
type ProductHistory struct {
|
||||
ID primitive.ObjectID `bson:"_id,omitempty" json:"id" ` // 交易订单号
|
||||
UID uint64 `bson:"uid" json:"uid"` // 用户id
|
||||
ProductID primitive.ObjectID `bson:"productID" json:"productID" ` // 产品id
|
||||
Name string `bson:"name" json:"name" ` // 商品名字
|
||||
Amount int64 `bson:"amount" json:"amount" ` // 花费的余额
|
||||
Income int64 `bson:"income" json:"income"` // 花费的收益
|
||||
ProductType commod.ProductType `bson:"productType" json:"productType" ` // 产品类型 // 0-会员卡 21-预售卡
|
||||
AdvanceOrderStatus int `bson:"advanceOrderStatus" json:"advanceOrderStatus"` // 预售订单状态 // 2-预付成功 4-尾款支付成功
|
||||
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"` // 更新时间
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` // 创建时间
|
||||
SysType string `json:"sysType" bson:"sysType"` // 设备系统类型 ios pc android
|
||||
GameCode string `json:"gameCode" bson:"gameCode"` // 购买游戏码
|
||||
ProductSnapShot *productmod.Product `json:"productSnapShot" bson:"productSnapShot"` // 产品购买时快照
|
||||
IsUpgrade bool `json:"isUpgrade" bson:"isUpgrade"` // 是否VIP升级
|
||||
CurrentVipName string `json:"currentVipName" bson:"currentVipName"` // 当前VIP名称
|
||||
CurrentVipPrice int64 `json:"currentVipPrice" bson:"currentVipPrice"` // 当前VIP价格
|
||||
PurchasePrice int64 `json:"purchasePrice" bson:"purchasePrice"` // 原价购买价格
|
||||
ExperimentID string `json:"experimentId,omitempty" bson:"experimentId,omitempty"` // VIP卡片A/B实验ID
|
||||
ExperimentVariant string `json:"experimentVariant,omitempty" bson:"experimentVariant,omitempty"` // VIP卡片A/B实验分组
|
||||
SessionID string `json:"sessionId,omitempty" bson:"sessionId,omitempty"` // VIP卡片页面会话ID
|
||||
DiscDoc `bson:",inline"`
|
||||
}
|
||||
|
||||
type ProductHistoryExport struct {
|
||||
ID primitive.ObjectID `bson:"_id,omitempty" json:"id" xlsx:"交易订单号"` // 交易订单号
|
||||
UID uint64 `bson:"uid" json:"uid" xlsx:"用户id"` // 用户id
|
||||
ProductID primitive.ObjectID `bson:"productID" json:"productID" xlsx:"会员卡id"` // 会员卡id
|
||||
Name string `bson:"name" json:"name" xlsx:"商品名字"` // 商品名字
|
||||
Duration int `bson:"duration" json:"duration" xlsx:"会员卡持续天数"` // 会员卡持续天数
|
||||
VipLevel int `bson:"vipLevel" json:"vipLevel" xlsx:"购买时的会员卡等级"` // 购买时的会员卡等级
|
||||
IsUpgrade bool `json:"isUpgrade" bson:"isUpgrade" xlsx:"是否VIP升级"` // 是否VIP升级
|
||||
OriginalPrice int64 `bson:"originalPrice" json:"originalPrice" xlsx:"原价(金币)"` // 原价(金币)
|
||||
DiscountedPriceIos int64 `bson:"discountedPriceIos,omitempty" json:"discountedPriceIos,omitempty" xlsx:"ios现价/升级价(金币)"` // ios现价/升级价(金币)
|
||||
DiscountedPriceAnd int64 `bson:"discountedPriceAnd,omitempty" json:"discountedPriceAnd,omitempty" xlsx:"安卓现价/升级价(金币)"` // 安卓现价/升级价(金币)
|
||||
Amount int64 `bson:"amount" json:"amount" xlsx:"花费的金币"` // 花费的余额
|
||||
Income int64 `bson:"income" json:"income" xlsx:"花费的收益"` // 花费的收益
|
||||
ProductType string `bson:"productType" json:"productType" xlsx:"产品类型"` // 产品类型 // 0-会员卡 21-预售卡
|
||||
AdvanceOrderStatus string `bson:"advanceOrderStatus" json:"advanceOrderStatus" xlsx:"预售订单状态"` // 预售订单状态 // 2-预付成功 4-尾款支付成功
|
||||
SysType string `json:"sysType" bson:"sysType" xlsx:"设备系统类型"` // 设备系统类型 ios pc android
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt" xlsx:"创建时间"` // 创建时间
|
||||
}
|
||||
|
||||
func Init() {
|
||||
mdb = db.Init(table)
|
||||
initIndex()
|
||||
}
|
||||
|
||||
type ProductStat struct {
|
||||
ID primitive.ObjectID `bson:"_id,omitempty" json:"id" ` //交易订单号
|
||||
ProductID primitive.ObjectID `bson:"productID" json:"productID" ` //产品id
|
||||
Amount int64 `bson:"amount" json:"amount" ` //成交价格
|
||||
Income int64 `bson:"income" json:"income"` //花费的作品收益
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt"`
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package prdcthsomod
|
||||
|
||||
import (
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
// VIPExperimentGoldOrderStat contains successful VIP card purchases paid with coins.
|
||||
type VIPExperimentGoldOrderStat struct {
|
||||
Variant string `json:"variant" bson:"variant"`
|
||||
ProductID primitive.ObjectID `json:"productId" bson:"productId"`
|
||||
GoldPaidOrders int `json:"goldPaidOrders" bson:"goldPaidOrders"`
|
||||
GoldPaidAmount int64 `json:"goldPaidAmount" bson:"goldPaidAmount"`
|
||||
}
|
||||
|
||||
func VIPExperimentGoldOrderStatistics(experimentID string) ([]VIPExperimentGoldOrderStat, error) {
|
||||
var raw []struct {
|
||||
ID struct {
|
||||
Variant string `bson:"variant"`
|
||||
ProductID primitive.ObjectID `bson:"productId"`
|
||||
} `bson:"_id"`
|
||||
GoldPaidOrders int `bson:"goldPaidOrders"`
|
||||
GoldPaidAmount int64 `bson:"goldPaidAmount"`
|
||||
}
|
||||
err := coll(nil).Aggregate(&raw, []bson.M{
|
||||
{"$match": bson.M{"experimentId": experimentID}},
|
||||
{"$group": bson.M{
|
||||
"_id": bson.M{
|
||||
"variant": "$experimentVariant",
|
||||
"productId": "$productID",
|
||||
},
|
||||
"goldPaidOrders": bson.M{"$sum": 1},
|
||||
"goldPaidAmount": bson.M{"$sum": bson.M{"$add": bson.A{
|
||||
bson.M{"$ifNull": bson.A{"$amount", 0}},
|
||||
bson.M{"$ifNull": bson.A{"$income", 0}},
|
||||
}}},
|
||||
}},
|
||||
{"$sort": bson.D{{Key: "_id.variant", Value: 1}, {Key: "goldPaidOrders", Value: -1}}},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := make([]VIPExperimentGoldOrderStat, 0, len(raw))
|
||||
for _, item := range raw {
|
||||
result = append(result, VIPExperimentGoldOrderStat{
|
||||
Variant: item.ID.Variant,
|
||||
ProductID: item.ID.ProductID,
|
||||
GoldPaidOrders: item.GoldPaidOrders,
|
||||
GoldPaidAmount: item.GoldPaidAmount,
|
||||
})
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
Reference in New Issue
Block a user