/* * @Description: 账户充值流水 * @Author: your name * @Date: 2019-08-29 20:45:27 * @LastEditTime: 2019-08-30 13:44:36 * @LastEditors: Please set LastEditors */ package rchgordmod import ( "context" "errors" "fmt" "time" "91porn-server/common/db" "91porn-server/common/log" "91porn-server/common/pageopt" "91porn-server/common/timeutil" "91porn-server/common/timeutil/timerange" "91porn-server/models" "91porn-server/models/v/usermod" "github.com/shopspring/decimal" "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.RechargeOrder func coll(t *db.MongoTool) *db.MongoTool { if t == nil { return mdb.Coll(table) } return t.Coll(table) } // InitARDIndex 设置账户充值流水表索引 func initIndex() { many := []mongo.IndexModel{ //batch set indexes //value is the type 1 or -1 { Keys: bson.D{{Key: "oid", Value: 1}}, // Options: options.Index().SetUnique(true).SetPartialFilterExpression(bson.M{"oid": bson.M{"$gt": ""}}), }, { Keys: bson.D{{Key: "channel", Value: 1}}, }, { Keys: bson.D{{Key: "createdAt", Value: 1}}, }, { Keys: bson.D{{Key: "updatedAt", Value: 1}}, }, { Keys: bson.D{{Key: "progressAt", Value: 1}}, }, { Keys: bson.D{{Key: "paymentAt", Value: 1}}, }, { Keys: bson.D{{Key: "failureAt", Value: 1}}, }, { Keys: bson.D{{Key: "successAt", Value: 1}}, }, { Keys: bson.D{{Key: "districtCode", Value: 1}, {Key: "createdAt", Value: -1}}, }, { Keys: bson.D{{Key: "isDirect", Value: 1}, {Key: "createdAt", Value: -1}}, }, { Keys: bson.D{{Key: "uid", Value: 1}, {Key: "createdAt", Value: -1}}, }, { Keys: bson.D{{Key: "traderId", Value: 1}}, }, { Keys: bson.D{{Key: "rechargeType", Value: 1}, {Key: "createdAt", Value: -1}}, }, { Keys: bson.D{{Key: "status", Value: 1}, {Key: "createdAt", Value: -1}}, }, { Keys: bson.D{{Key: "devType", Value: 1}, {Key: "createdAt", Value: -1}}, }, { Keys: bson.D{{Key: "uid", Value: 1}, {Key: "productType", Value: 1}, {Key: "status", 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}, {Key: "status", Value: 1}, }, Options: options.Index(). SetName("vip_experiment_order_statistics"). SetPartialFilterExpression(bson.M{"experimentId": bson.M{"$gt": ""}}), }, { Keys: bson.D{{Key: "sourcePage", Value: 1}, {Key: "createdAt", Value: -1}}, Options: options.Index(). SetName("order_source_created_at"). SetPartialFilterExpression(bson.M{"sourcePage": bson.M{"$gt": ""}}), }, } if _, err := coll(nil).CreateIndex(many); err != nil { panic(fmt.Sprintf("RechageOrderIndex err+%v", err)) } } // InsertRechargeOrder 插入一条充值订单 func InsertRechargeOrder(a *RechargeOrder) (err error) { a.CreatedAt = time.Now() a.UpdatedAt = a.CreatedAt res, err := coll(nil).InsertOne(a) if err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "InsertRechargeOrder", table, "InsertOne", err)) return } a.ID = res.InsertedID.(primitive.ObjectID) return } // FindRechargesOrders 查询充值订单 func FindRechargesOrders(cond bson.M, opts *options.FindOptions) (total int64, data []*RechargeOrder, err error) { data = make([]*RechargeOrder, 0) if err = coll(nil).Find(&data, cond, opts); err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindRechargesOrders", 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:", "FindRechargesOrders", table, "Count", err), log.Any("cond", cond), ) return } return } func FindOne(t *db.MongoTool, cond bson.M, opts ...*options.FindOneOptions) (data *RechargeOrder, err error) { if err = coll(nil).FindOne(&data, cond, opts...); err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindOne", table, "FindOne", err), log.Any("cond", cond), ) return } return } // FindRechargesOrders 查询充值订单 func FindMyOrders(uid, pgSz, pgCt uint64) (total int64, data []*RechargeOrder, hasNext bool, err error) { data = make([]*RechargeOrder, 0) opts := options.FindOptions{} skip := int64((pgCt - 1) * pgSz) limit := int64(pgSz + 1) opts.Skip = &skip opts.Limit = &limit opts.SetSort(bson.D{{Key: "createdAt", Value: -1}}) startTime := timeutil.BeforeMinute(20) cond := bson.M{ "$or": []bson.M{ {"uid": uid, "status": bson.M{"$gt": Processing}}, {"uid": uid, "status": bson.M{"$lte": Processing}, "createdAt": bson.M{"$gte": startTime}}, }, } if err = coll(nil).Find(&data, cond, &opts); err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindMyOrders", table, "Find", err), log.Any("uid", uid), log.Any("pgSz", pgSz), log.Any("pgCt", pgCt), ) return } total, err = coll(nil).Count(cond) if err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindMyOrders", table, "Count", err), log.Any("uid", uid), log.Any("pgSz", pgSz), log.Any("pgCt", pgCt), ) } if len(data) > int(pgSz) { hasNext = true data = data[:pgSz] } return } // Update 修改订单 func UpdateRechargeOrder(id string, set RechargeUpdateReq) error { set.UpdatedAt = time.Now() objID, err := primitive.ObjectIDFromHex(id) if err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UpdateRechargeOrder", table, "ObjectIDFromHex", err), log.Any("id", id), log.Any("set", set), ) return err } if _, err = coll(nil).UpdateOne(bson.M{"_id": objID}, bson.M{"$set": set}); err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UpdateRechargeOrder", table, "UpdateOne", err), log.Any("id", id), log.Any("set", set), ) return err } return nil } // CallBackModifyWithProcessing 回调修改订单 func CallBackModifyWithProcessing(ctx context.Context, t *db.MongoTool, id primitive.ObjectID, set EditSelector) error { set.UpdatedAt = time.Now() if _, err := coll(t).UpdateOne(bson.M{"_id": id, "status": Processing}, bson.M{"$set": set}); err != nil { log.WarnX(ctx, fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Update", table, "UpdateOne", err), log.Any("id", id), log.Any("set", set), ) return err } return nil } // Update 修改订单 func Update(t *db.MongoTool, id primitive.ObjectID, set EditSelector) error { set.UpdatedAt = time.Now() if _, err := coll(t).UpdateOne(bson.M{"_id": id}, bson.M{"$set": set}); err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Update", table, "UpdateOne", err), log.Any("id", id), log.Any("set", set), ) return err } return nil } // 根据第三方订单号修改 func UpdateBaseOnOidAndStatus(t *db.MongoTool, oid string, status int, set ReplaceEditSelector) error { set.UpdatedAt = time.Now() if _, err := coll(t).UpdateOne(bson.M{"oid": oid, "status": status}, bson.M{"$set": set}); err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UpdateBaseOnOid", table, "UpdateOne", err), log.Any("id", oid), log.Any("set", set), ) return err } return nil } func UpdateBaseOnOid(t *db.MongoTool, oid string, set ReplaceEditSelector) error { set.UpdatedAt = time.Now() if _, err := coll(t).UpdateOne(bson.M{"oid": oid}, bson.M{"$set": set}); err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UpdateBaseOnOid", table, "UpdateOne", err), log.Any("id", oid), log.Any("set", set), ) return err } return nil } // Upsert 新增或修改订单 func Upsert(t *db.MongoTool, oid string, upsert UpserSelector) (id primitive.ObjectID, err error) { updatedAt := time.Now() upsert.UpdatedAt = &updatedAt upertRest, err := coll(t).UpsertOne(bson.M{"oid": oid}, bson.M{"$setOnInsert": bson.M{"createdAt": time.Now()}, "$set": upsert}) if err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Upsert", table, "UpsertOne", err), log.Any("oid", oid), log.Any("upsert", upsert), ) } if tid, ok := upertRest.UpsertedID.(primitive.ObjectID); ok { id = tid } return } // FindRechargeByID 根据订单号查询订单 func FindRechargeOrderByID(id string) (r RechargeOrder, err error) { objID, err := primitive.ObjectIDFromHex(id) if err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindRechargeOrderByID", table, "ObjectIDFromHex", err), log.Any("id", id), ) return } if err = coll(nil).FindOne(&r, bson.M{"_id": objID}); err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindRechargeOrderByID", table, "FindOne", err), log.Any("objID", objID), ) } return } // FindRechargeByID 根据第三方订单号查询订单 func FindRechargeOrderByThirdOrderId(oid string) (r RechargeOrder, err error) { if err = coll(nil).FindOne(&r, bson.M{"oid": oid}); err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindRechargeOrderByID", table, "FindOne", err), log.Any("objID", oid), ) } return } // FindRechargeByIDForApp 根据第三方订单号查询订单ForApp func FindRechargeOrderByThirdOrderIdForApp(oid string) (r *RechargeOrderAppRes, err error) { if err = coll(nil).FindOne(&r, bson.M{"oid": oid}); err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindRechargeOrderByThirdOrderIdForApp", table, "FindOne", err), log.Any("objID", oid), ) } return } // TotalMoney 统计总订单金额 func TotalMoney(matchers ...Matcher) (int64, error) { var ret struct { Money int64 `bson:"money"` //充值金额 订单金额 李秋山确认 } filter := []bson.M{ { "$match": pageopt.MergeM(matchers), }, { "$group": bson.M{ "_id": nil, "money": bson.M{"$sum": "$money"}, }, }, } if err := coll(nil).AggregateDecode(&ret, filter); err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UsersTotalRecharge", table, "Aggregate", err), log.Any("matchers", matchers), ) return 0, err } return ret.Money, nil } // GetSuccessOrderUIDListByTime func GetSuccessOrderUIDListByTime(start time.Time, end time.Time) ([]uint64, error) { filter := (&SuccessAtGTEAndLTMatch{&start, &end}).New().Filter() list := make([]struct { UID uint64 `bson:"uid"` }, 0) if err := coll(nil).Find(&list, filter); err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetSuccessOrderUIDListByTime", table, "Find", err), log.Any("start", start), log.Any("end", end), ) return nil, err } uidList := make([]uint64, len(list)) for i, v := range list { uidList[i] = v.UID } return uidList, nil } // 根据uid获取用户的成功订单 func GetSuccessOrderUidList(uid, pageSize, pageNum uint64) (total int64, data []RechargeOrder, hasNext bool, err error) { filter := bson.M{"uid": uid} skip := int64((pageNum - 1) * pageSize) limit := int64(pageSize) opts := options.FindOptions{ Skip: &skip, Limit: &limit, Sort: bson.D{{Key: "createdAt", Value: -1}}, } if err = coll(nil).Find(&data, filter, &opts); err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindMyOrders", table, "Find", err), log.Any("uid", uid), log.Any("pgSz", pageSize), log.Any("pgCt", pageNum), ) return } total, err = coll(nil).Count(filter) if err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindMyOrders", table, "Count", err), log.Any("uid", uid), log.Any("pgSz", pageSize), log.Any("pgCt", pageNum), ) } return } // GetNewAndRechargeUIDSByTime 新增并充值uid List func GetNewAndRechargeUIDSByTime(createStart, createEnd, recStart, recEnd time.Time) ([]uint64, error) { createUIDList, err := usermod.UIDListByCreateTime(createStart, createEnd) if err != nil { return nil, err } filter := (&SuccessAtGTEAndLTMatch{&recStart, &recEnd}).New().Filter() recList := make([]struct { UID uint64 `bson:"uid"` }, 0) if err = coll(nil).Find(&recList, filter); err != nil { return nil, err } //充值用户 Map recUserMap := make(map[uint64]byte, len(recList)) for _, rec := range recList { recUserMap[rec.UID] = 1 } uidList := make([]uint64, 0, len(recUserMap)) for _, uid := range createUIDList { if _, ok := recUserMap[uid]; ok { uidList = append(uidList, uid) } } return uidList, nil } // GetChannelNewAndRechargeUIDSMapByTime 渠道新增并充值用户映射 func GetChannelNewAndRechargeUIDSMapByTime(start time.Time, end time.Time) (map[string][]uint64, error) { creatUserStartTime := timerange.LocDayRange(start).Head creatUserEndTime := timerange.LocDayRange(end).Tail chMap, err := usermod.ChannelMapByCreateTime(creatUserStartTime, creatUserEndTime) if err != nil { return nil, err } filter := (&SuccessAtGTEAndLTMatch{&start, &end}).New().Filter() list := make([]struct { UID uint64 `bson:"uid"` }, 0) if err = coll(nil).Find(&list, filter); err != nil { return nil, err } recUIDMap := make(map[uint64]byte, len(list)) for _, v := range list { recUIDMap[v.UID] = 1 } ret := make(map[string][]uint64) for uid, channel := range chMap { if _, ok := recUIDMap[uid]; ok { ret[channel] = append(ret[channel], uid) } } return ret, nil } // GetChannelNewAndRechargeAmountMapByTime 渠道新增并充值金额映射 func GetChannelNewAndRechargeAmountMapByTime(start time.Time, end time.Time) (map[string]int64, error) { creatUserStartTime := timerange.LocDayRange(start).Head creatUserEndTime := timerange.LocDayRange(end).Tail chMap, err := usermod.ChannelMapByCreateTime(creatUserStartTime, creatUserEndTime) if err != nil { return nil, err } filter := (&SuccessAtGTEAndLTMatch{GTE: &start, LT: &end}).New().Filter() list := make([]struct { UID uint64 `bson:"uid"` Money int64 `bson:"money"` }, 0) if err = coll(nil).Find(&list, filter); err != nil { return nil, err } moneyMap := make(map[uint64]int64, len(list)) for _, v := range list { moneyMap[v.UID] += v.Money } ret := make(map[string]int64) for uid, channel := range chMap { money := moneyMap[uid] ret[channel] += money } return ret, nil } // OnlineRechargeAmount OnlineRechargeAmount func RechargeAmount(start time.Time, end time.Time, mats ...Matcher) (int64, error) { mats = append(mats, (&SuccessAtGTEAndLTMatch{&start, &end}).New()) filter := pageopt.MergeM(mats) list := make([]struct { Money int64 `bson:"money"` }, 0) if err := coll(nil).Find(&list, filter); err != nil { return 0, err } var totalMoney int64 for _, v := range list { totalMoney += v.Money } return totalMoney, nil } // ChannelOrderCountMap channel->订单数 map func ChannelOrderCountMap(start, end time.Time) (map[string]int64, error) { filter := (&CreatedAtGTEAndLTMatch{GTE: &start, LT: &end}).New().Filter() var list []struct { ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` //流水id Channel string `json:"channel" bson:"channel"` //渠道类型 鲨鱼 金鱼 } if err := coll(nil).Find(&list, filter); err != nil { return nil, err } m := make(map[string]int64, len(list)) for _, v := range list { m[v.Channel] += 1 } return m, nil } // ChannelCompleteOrderCountMap channel->完成订单数 map func ChannelCompleteOrderCountMap(start, end time.Time) (map[string]int64, error) { filter := (&SuccessAtGTEAndLTMatch{&start, &end}).New().Filter() var list []struct { ID primitive.ObjectID `bson:"_id,omitempty"` //流水id Channel string `bson:"channel"` //渠道类型 鲨鱼 金鱼 } if err := coll(nil).Find(&list, filter); err != nil { return nil, err } m := make(map[string]int64, len(list)) for _, v := range list { m[v.Channel] += 1 } return m, nil } // ChannelOrderMoneyMap channel->订单金额 map func ChannelOrderMoneyMap(start, end time.Time) (map[string]int64, error) { filter := (&CreatedAtGTEAndLTMatch{GTE: &start, LT: &end}).New().Filter() var list []struct { Channel string `bson:"channel"` //渠道类型 鲨鱼 金鱼 Money int64 `bson:"money"` //充值金额 订单金额 李秋山确认 } if err := coll(nil).Find(&list, filter); err != nil { return nil, err } m := make(map[string]int64, len(list)) for _, v := range list { m[v.Channel] += v.Money } return m, nil } // ChannelCompleteOrderPayMoneyMap channel->完成订单的用户实际支付金额 map func ChannelCompleteOrderPayMoneyMap(start, end time.Time) (map[string]int64, error) { filter := (&SuccessAtGTEAndLTMatch{&start, &end}).New().Filter() var list []struct { Channel string `bson:"channel"` //渠道类型 鲨鱼 金鱼 PayMoney int64 `bson:"payMoney"` //实际到账金额 实际支付金额 李秋山确认 } if err := coll(nil).Find(&list, filter); err != nil { return nil, err } m := make(map[string]int64, len(list)) for _, v := range list { m[v.Channel] += v.PayMoney } return m, nil } var ChannelPaymentOrderCountMap = ChannelCompleteOrderCountMap var ChannelPaymentMoneyMap = ChannelCompleteOrderPayMoneyMap // SuccessRateMap 每小时成功率 func SuccessRateMap(channel string, start, end time.Time, scaleMinute int64) (map[int64]float64, error) { var list []struct { CreatedAt time.Time `bson:"createdAt"` //创建时间 Status int `bson:"status"` //1进行中 2付款失败 3付款成功 4已经退款 } matList := []pageopt.Matcher{ (&ChannelMatch{&channel}).New(), (&CreatedAtGTEAndLTMatch{GTE: &start, LT: &end}).New(), } filter := pageopt.MergeM(matList) opt := (&options.FindOptions{}).SetProjection(M{ "createdAt": 1, "status": 1, }) if err := coll(nil).Find(&list, filter, opt); err != nil { return nil, err } sucOrdCountMap := make(map[int64]int64) orderCountMap := make(map[int64]int64) successRateMap := make(map[int64]float64) tempTime := start for end.After(tempTime) { tim := timerange.RecentMinute(tempTime, scaleMinute) p := tim.Unix() sucOrdCountMap[p] = 0 orderCountMap[p] = 0 successRateMap[p] = 0.0 tempTime = tempTime.Add(time.Duration(scaleMinute) * time.Minute) } for _, v := range list { tim := timerange.RecentMinute(v.CreatedAt, scaleMinute) p := tim.Unix() if v.Status == SUCCESS { sucOrdCountMap[p] += 1 } orderCountMap[p] += 1 } lastTime := end if len(list) > 0 { lastTime = list[len(list)-1].CreatedAt } tempTime = start for lastTime.After(tempTime) { tim := timerange.RecentMinute(tempTime, scaleMinute) p := tim.Unix() if orderCountMap[p] != 0 { successRateMap[p] = float64(int(float64(sucOrdCountMap[p])/float64(orderCountMap[p])*1000)) / 10 } tempTime = tempTime.Add(time.Duration(scaleMinute) * time.Minute) } return successRateMap, nil } func GetSuccessRechargeCountMapByHour(discCode string, start, end time.Time, mats ...Matcher) ([]int, map[int]int64, int64, error) { mats = append(mats, (&DistrictCodeMatch{&discCode}).New(), (&SuccessAtGTEAndLTMatch{&start, &end}).New()) filter := pageopt.MergeM(mats) opt := (&options.FindOptions{}).SetProjection(M{ "successAt": 1, }) var list []struct { SuccessAt time.Time `bson:"successAt"` //创建时间 } if err := coll(nil).Find(&list, filter, opt); err != nil { log.Error("rchgordmod GetRechargeCountMapByHour error", log.E(err)) return nil, nil, 0, err } hs := []int{} m := make(map[int]int64) startH := start.Hour() lastH := end.Hour() + (end.Day()-start.Day())*24 for i := startH; i <= lastH; i++ { hs = append(hs, i) m[i] = 0 } var total int64 for _, v := range list { hour := v.SuccessAt.Hour() + (v.SuccessAt.Day()-start.Day())*24 m[hour] += 1 total++ } return hs, m, total, nil } func UpRechOrder(mt *db.MongoTool, tradeNo string, oid string, amount int64, progressAt time.Time) error { id, _ := primitive.ObjectIDFromHex(tradeNo) c, err := coll(nil).Count(bson.M{"_id": id}) if err != nil { return nil } if c <= 0 { return errors.New("tradeNo不存在") } tStr := time.Now().Local() filter := bson.M{"_id": id, "status": Processing} mur, err := coll(mt).UpdateOne(filter, bson.M{"$set": bson.M{ "status": SUCCESS, "statusDesc": "success", "oid": oid, "payMoney": amount, "updatedAt": tStr, "progressAt": progressAt, "successAt": progressAt, "paymentAt": progressAt, /*"finishedAt": tStr*/}}) if err != nil { log.Warn("transplat:UpRechOrder rchgOderColl.UpdateOne failed", log.E(err), log.Any("filter", filter)) return err } if mur.ModifiedCount != 1 { return errors.New("UpdateErr") } return nil } // 获取用户昨日棋牌充值金额 func GetUserChessSuccessOrderAmout(uid uint64, now time.Time) (int64, error) { /** TODO: 统计用户昨日棋牌充值总金额 查询条件 1.指定用户 2.棋牌充值 3.成功订单 4.订单时间(大于等于昨日凌晨时间;小于今日凌晨时间) */ match := bson.M{"uid": uid, "productType": 1, "status": 3, "paymentAt": bson.M{"$gte": timeutil.BeginningOfDay(now.AddDate(0, 0, -1)), "$lt": timeutil.BeginningOfDay(now)}, } pipelines := []bson.M{ {"$match": match}, {"$group": bson.M{"_id": nil, "totalAmount": bson.M{"$sum": "$payMoney"}}}, {"$project": bson.M{"totalAmount": 1}}, } var res struct { TotalAmount int64 `bson:"totalAmount"` } if err := coll(nil).AggregateDecode(&res, pipelines); err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetUserChessSuccessOrderAmout", table, "AggregateDecode", err), log.Any("uid", uid)) return 0, err } return decimal.NewFromInt(res.TotalAmount).Div(decimal.NewFromInt(100)).IntPart(), nil } // 首冲判定 func IsFirstRecharge(uid uint64) (bool, error) { filter := bson.M{"uid": uid, "productType": 1, "status": SUCCESS} count, err := coll(nil).Count(filter) if err != nil { return false, err } return count == 0, nil } func StatCenterSyncRecharge(start time.Time, size int64) ([]RechargeOrder, error) { end := time.Now().Add(-time.Second * 240) //等用户注册信息先同步 opt := (&options.FindOptions{}) opt.SetLimit(size) opt.SetSort(bson.M{"successAt": 1}) filter := bson.M{"status": 3, "successAt": bson.M{"$gt": start, "$lte": end}} data := make([]RechargeOrder, 0) return data, coll(nil).Find(&data, filter, opt) } func StatCenterSyncOrder(start time.Time, size int64) ([]RechargeOrder, error) { end := time.Now().Add(-time.Second * 240) //等用户注册信息先同步 opt := (&options.FindOptions{}) opt.SetLimit(size) opt.SetSort(bson.M{"createdAt": 1}) filter := bson.M{"createdAt": bson.M{"$gt": start, "$lte": end}} data := make([]RechargeOrder, 0) return data, coll(nil).Find(&data, filter, opt) } func GetOrderByTime(start, end time.Time) ([]RechargeStat, error) { filter := bson.M{"status": 3, "productType": bson.M{"$ne": 1}, "successAt": bson.M{"$gt": start, "$lte": end}} data := make([]RechargeStat, 0) return data, coll(nil).Find(&data, filter) } func NewStatCenterSyncRecharge(id string, size int64) ([]RechargeOrder, error) { _id, _ := primitive.ObjectIDFromHex(id) opt := (&options.FindOptions{}).SetLimit(size).SetSort(bson.M{"_id": 1}) filter := bson.M{"_id": bson.M{"$gt": _id}} data := make([]RechargeOrder, 0) return data, coll(nil).Find(&data, filter, opt) } // RefundCallBackModify 退款回调修改订单 func RefundCallBackModify(ctx context.Context, t *db.MongoTool, id primitive.ObjectID, set EditSelector) error { set.UpdatedAt = time.Now() if _, err := coll(t).UpdateOne(bson.M{"_id": id}, bson.M{"$set": set}); err != nil { log.WarnX(ctx, fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Update", table, "UpdateOne", err), log.Any("id", id), log.Any("set", set), ) return err } return nil }