Files
huangguo_server/models/v/rchgordmod/rchgorder.go
T
rootandClaude Opus 5 8679200f41 Initial commit
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 13:57:10 +08:00

776 lines
24 KiB
Go

/*
* @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
}