Files
rootandClaude Opus 5 8679200f41 Initial commit
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 13:57:10 +08:00

655 lines
22 KiB
Go

/*
* @Description: In User Settings Edit
* @Author: your name
* @Date: 2019-08-29 19:55:45
* @LastEditTime: 2019-08-30 19:39:56
* @LastEditors: Please set LastEditors
*/
package txnmod
import (
"fmt"
"math"
"time"
"91porn-server/common/db"
"91porn-server/common/log"
"91porn-server/common/pageopt"
"91porn-server/common/timeutil"
"91porn-server/models"
"91porn-server/models/commod"
"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.Transaction
// InitIndex 设置index
func initIndex() {
coll := coll(nil)
many := []mongo.IndexModel{
{
Keys: bson.D{{Key: "uid", Value: 1}},
},
{
Keys: bson.D{{Key: "purchaseOrder", Value: 1}},
},
{
Keys: bson.D{{Key: "uid", Value: 1}, {Key: "createdAt", Value: -1}},
},
{
Keys: bson.D{{Key: "amount", Value: 1}},
},
{
Keys: bson.D{{Key: "actualAmount", Value: 1}},
},
{
Keys: bson.D{{Key: "createdAt", Value: 1}},
},
{
Keys: bson.D{{Key: "uniqueOrder", Value: 1}},
Options: options.Index().SetSparse(true).SetUnique(true),
},
{
Keys: bson.D{{Key: "tranType", Value: 1}, {Key: "createdAt", Value: -1}},
// Options: options.Index().SetUnique(true).SetSparse(true),
},
{
Keys: bson.D{{Key: "tranType", Value: 1}, {Key: "districtCode", Value: 1}, {Key: "promSeqe", Value: 1}, {Key: "createdAt", Value: -1}},
Options: options.Index().SetSparse(true),
},
{
Keys: bson.D{{Key: "tranType", Value: 1}, {Key: "districtCode", Value: 1}, {Key: "promSeqe", Value: 1}, {Key: "sysType", Value: 1}, {Key: "createdAt", Value: -1}},
Options: options.Index().SetSparse(true),
},
{
Keys: bson.D{{Key: "tranTypeInt", Value: 1}, {Key: "createdAt", Value: -1}},
},
{
Keys: bson.D{{Key: "tranTypeInt", Value: 1}, {Key: "districtCode", Value: 1}, {Key: "promSeqe", Value: 1}, {Key: "createdAt", Value: -1}},
Options: options.Index().SetSparse(true),
},
{
Keys: bson.D{{Key: "tranTypeInt", Value: 1}, {Key: "districtCode", Value: 1}, {Key: "promSeqe", Value: 1}, {Key: "sysType", Value: 1}, {Key: "createdAt", Value: -1}},
Options: options.Index().SetSparse(true),
},
{
Keys: bson.D{{Key: "isDirect", Value: 1}, {Key: "createdAt", Value: -1}},
Options: options.Index().SetSparse(true),
},
{
Keys: bson.D{{Key: "uid", Value: 1}, {Key: "tranTypeInt", Value: 1}, {Key: "money", Value: 1}, {Key: "fruitCoin", Value: 1}, {Key: "createdAt", Value: -1}},
Options: options.Index().SetSparse(true),
},
{
Keys: bson.D{{Key: "deductType", Value: 1}, {Key: "createdAt", Value: -1}},
Options: options.Index().SetSparse(true),
},
}
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)
}
// Insert 新增
func InsertTransactionLog(mt *db.MongoTool, t *TransactionLog) error {
//Insert 插入一条交易流水
t.CreatedAt = time.Now()
if _, err := coll(mt).InsertOne(t); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "InsertTransactionLog", table, "InsertOne", err))
return err
}
return nil
}
func InsertManyTransactionLog(mt *db.MongoTool, trans []TransactionLog) error {
ops := options.InsertMany().SetOrdered(false)
if _, err := coll(mt).InsertMany(trans, ops); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "InsertTransactionLog", table, "InsertOne", err))
return err
}
return nil
}
// FindMany 查询所有
func FindTransactionLogs(filter bson.M, opts *options.FindOptions) (total int64, data []*TransactionLog, err error) {
data = make([]*TransactionLog, 0)
if err = coll(nil).Find(&data, filter, opts); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindTransactionLogs", table, "Find", err),
log.Any("filter", filter),
)
return
}
total, err = coll(nil).Count(filter)
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindTransactionLogs", table, "Count", err),
log.Any("filter", filter),
)
}
return
}
// getTotalCnt 获取标签视频总数
func getTotalCnt(cond bson.M) (int64, error) {
total, err := coll(nil).Count(cond)
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "getTotalCnt", table, "Count", err),
log.Any("cond", cond),
)
return 0, err
}
return total, nil
}
// GetSkipSize 计算跳转
func getSkipSize(page, size uint64, cond bson.M) (uint64, uint64, int64, error) {
total, err := getTotalCnt(cond)
if err != nil {
return 0, 0, 0, err
}
totalpages := uint64(math.Ceil(float64(total) / float64(size)))
if page > totalpages {
page = totalpages
}
if page < 1 {
page = 1
}
return (page - 1) * size, totalpages, total, nil
}
// GetCoinLogs 条件获取金币日志(时间倒序)
func GetCoinLogs(page, size uint64, cond map[string]interface{}) ([]*TransactionLog, uint64, int64, error) {
if !hasLedgerUID(bson.M(cond)) {
// Preserve the existing global listing and export path until the fund
// collection has an approved index for cross-user time queries.
skip, totalPages, total, err := getSkipSize(page, size, bson.M(cond))
if err != nil {
return nil, 0, 0, err
}
opts := options.Find().SetSort(bson.D{{Key: "createdAt", Value: -1}}).
SetSkip(int64(skip)).SetLimit(int64(size))
var rows []*TransactionLog
err = coll(nil).Find(&rows, bson.M(cond), opts)
return rows, totalPages, total, err
}
return getLedgerCoinLogs(page, size, bson.M(cond))
}
func GetTranTypes() (data []interface{}, err error) {
data, err = coll(nil).Distinct("tranType", bson.M{})
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetTranTypes", table, "Distinct", err))
return nil, err
}
for _, kind := range []string{AiGirlfriendTransferIn.Key(), AiGirlfriendTransferOut.Key()} {
found := false
for _, existing := range data {
if existing == kind {
found = true
break
}
}
if !found {
data = append(data, kind)
}
}
return
}
// FindManyByTime 查询所有
func FindManyByTime(uid uint64, start time.Time, end time.Time) (data []*TransactionLog, err error) {
data = make([]*TransactionLog, 0)
opts := options.FindOptions{
Sort: bson.D{{Key: "createdAt", Value: -1}},
}
if err = coll(nil).Find(&data, bson.M{"uid": uid, "createdAt": bson.M{"$gte": start, "$lt": end}}, &opts); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindManyByTime", table, "Find", err),
log.Any("uid", uid),
log.Any("start", start),
log.Any("end", end),
)
return
}
return
}
// HasNext 查询所有
func HasNext(uid uint64, start time.Time) (hasNext bool, err error) {
var data TransactionLog
if err = coll(nil).FindOne(&data, bson.M{"uid": uid, "createdAt": bson.M{"$lt": start}}); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "HasNext", table, "FindOne", err),
log.Any("uid", uid),
log.Any("start", start),
)
return
}
return !data.ID.IsZero(), err
}
// LastTime 查询所有
func LastTime(uid uint64, end time.Time) (data TransactionLog, err error) {
opt := options.FindOneOptions{
Sort: bson.D{{Key: "createdAt", Value: -1}},
}
if err = coll(nil).FindOne(&data, bson.M{"uid": uid, "createdAt": bson.M{"$lt": end}}, &opt); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "LastTime", table, "FindOne", err),
log.Any("uid", uid),
log.Any("end", end),
)
return
}
return data, nil
}
func GetBuyVipCountMapByHour(discCode string, start, end time.Time, mats ...Matcher) ([]int, map[int]int64, int64, error) {
payVIP := PayVIP.Key()
mats = append(mats,
(&TranTypeMatch{&payVIP}).New(),
(&DistrictCodeMatch{&discCode}).New(),
(&CreatedAtGTEAndLTMatch{GTE: &start, LT: &end}).New())
filter := pageopt.MergeM(mats)
opt := (&options.FindOptions{}).SetProjection(M{
"createdAt": 1,
})
var list []struct {
CreatedAt time.Time `bson:"createdAt"` //创建时间
}
if err := coll(nil).Find(&list, filter, opt); err != nil {
log.Error("txnmod GetBuyVipCountMap error", log.E(err))
return nil, nil, 0, err
}
m := make(map[int]int64)
startH := start.Hour()
lastH := end.Hour() + (end.Day()-start.Day())*24
hs := make([]int, lastH-startH+1)
for i, j := startH, 0; i <= lastH; i++ {
hs[j] = i
m[i] = 0
j++
}
var total int64
for _, v := range list {
hour := v.CreatedAt.Hour() + (v.CreatedAt.Day()-start.Day())*24
m[hour] += 1
total++
}
return hs, m, total, nil
}
// FindIncome 查询所有
func FindIncome(uid uint64, pageNumebr, pageSize uint64) (data []*TransactionLog, hasNext bool, err error) {
data = make([]*TransactionLog, 0)
f := bson.M{"uid": uid, "actualAmount": bson.M{"$gt": 0}}
skip := int64(pageSize * (pageNumebr - 1))
limit := int64(pageSize + 1)
opts := options.FindOptions{
Skip: &skip,
Limit: &limit,
Sort: bson.D{{Key: "createdAt", Value: -1}},
}
if err = coll(nil).Find(&data, f, &opts); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindTransactionLogs", table, "Find", err),
log.Any("filter", f),
)
return
}
if len(data) > int(pageSize) {
hasNext = true
data = data[:pageSize]
}
return
}
// FindPoxyIncomeOfMonth 查询每月收益
func FindPoxyIncomeOfMonth(uid uint64) (totalMoney int64, totalPerfomance int64, err error) {
firstDay, lastDay := timeutil.MonthStartEndTime(time.Now())
pipelines := []bson.M{
{"$match": bson.M{"uid": uid, "tranTypeInt": ProxyIncome, "createdAt": bson.M{"$gte": firstDay, "$lt": lastDay}}},
{"$group": bson.M{"_id": nil, "totalMoney": bson.M{"$sum": "$actualAmount"}, "totalPerformance": bson.M{"$sum": "$performance"}}},
{"$project": bson.M{"totalMoney": 1, "totalPerformance": 1}},
}
type res struct {
TotalMoney int64 `bson:"totalMoney"`
TotalPerformance int64 `bson:"totalPerformance"`
}
data := make([]res, 0)
if err = coll(nil).Aggregate(&data, pipelines); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindIncomeOfMonth", table, "Aggregate", err), log.Any("uid", uid))
return
}
if len(data) > 0 {
totalMoney = data[0].TotalMoney
totalPerfomance = data[0].TotalPerformance
}
return
}
// FindTransactionLogsByTransType 查询所有
func FindTransactionLogsByTransType(uid uint64, pageNumber int64, pageSize int64, tranType TransType) (data []*TransactionLog, hasNext bool, err error) {
data = make([]*TransactionLog, 0)
skip := (pageNumber - 1) * pageSize
limit := pageSize + 1
opts := options.FindOptions{
Skip: &skip,
Limit: &limit,
Sort: bson.D{{Key: "createdAt", Value: -1}},
}
if err = coll(nil).Find(&data, bson.M{"uid": uid, "tranTypeInt": tranType}, &opts); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindTransactionLogsByTransType", table, "Find", err), log.Any("uid", uid))
return
}
if len(data) > int(pageSize) {
hasNext = true
data = data[:pageSize]
}
return
}
// GetProxyIncomeForToday 查询所有
func GetProxyIncomeForToday(uid uint64, start time.Time, end time.Time) (data []AgentIncomeRes, err error) {
pipelines := []bson.M{
{"$match": bson.M{"uid": uid, "tranTypeInt": ProxyIncome, "createdAt": bson.M{"$gte": start, "$lt": end}}},
{"$group": bson.M{"_id": "$agentLevel", "totalAmount": bson.M{"$sum": "$actualAmount"}, "totalPerformance": bson.M{"$sum": "$performance"}}},
{"$project": bson.M{"totalAmount": 1, "totalPerformance": 1}},
}
data = make([]AgentIncomeRes, 0)
if err = coll(nil).Aggregate(&data, pipelines); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetProxyIncomeOfDay", table, "Find", err), log.Any("uid", uid))
return
}
return
}
// GetIncomeByType 查询所有
func GetIncomeByType(uid uint64, tp TransType, start time.Time, end time.Time) (totalAmount float64, totalPer int64, err error) {
match := bson.M{"uid": uid, "tranTypeInt": tp, "createdAt": bson.M{"$gte": start, "$lt": end}}
log.Info(fmt.Sprintf("%v", match))
pipelines := []bson.M{
{"$match": match},
{"$group": bson.M{"_id": nil, "totalAmount": bson.M{"$sum": "$actualAmount"}, "totalPerformance": bson.M{"$sum": "$performance"}}},
{"$project": bson.M{"totalAmount": 1, "totalPerformance": 1}},
}
var res struct {
TotalAmount float64 `bson:"totalAmount"`
TotalPerformance int64 `bson:"totalPerformance"`
}
if err = coll(nil).AggregateDecode(&res, pipelines); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetProxyIncomeOfDay", table, "Find", err), log.Any("uid", uid))
return
}
totalAmount = res.TotalAmount
totalPer = res.TotalPerformance
return
}
// IsProxyExist 代理分成是否存在
func IsProxyExist(uid uint64, objId primitive.ObjectID) bool {
filter := bson.M{"uid": uid, "purchaseOrder": objId, "tranType": ProxyIncome.Key()}
count, err := coll(nil).Count(filter)
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "IsProxyExist", table, "Count", count), log.Any("uid", uid), log.Any("objId", objId))
//查询异常的时候, 默认不分成, 用户找来可以人工修复, 项目不能亏
return true
}
if count > 0 {
return true
}
return false
}
// Income 收益
func Income(uid uint64, start time.Time, end time.Time) (totalAmount float64, err error) {
return sumLedgerAmount(uid, start, end, true)
}
// Expenditure 支出
func Expenditure(uid uint64, start time.Time, end time.Time) (totalAmount float64, err error) {
return sumLedgerAmount(uid, start, end, false)
}
// Ibills 账单
func Ibills(uid uint64, pageNumebr, pageSize uint64, start time.Time, end time.Time) (data []TransactionLog, hasNext bool, err error) {
data = make([]TransactionLog, 0)
f := bson.M{
"uid": uid,
"createdAt": bson.M{"$gte": start, "$lt": end},
"tranTypeInt": bson.M{"$in": []TransType{
AiGirlfriendTransferIn, AiGirlfriendTransferOut, Rchg, PayVID, WithdrawTransfer, PayVIP, WithdrawRefund, AdminCreaditAmount, AdminDebitAmount, OfficialRech, MeetingCard,
GameCoin, ChaseScore, PayReward, Other, LouFeng, AudioBook, LouFengRefund, LouFengDiscount, GameRewards, VipCardGive,
LouFengMianFei, LuckyDraw, PayAvVID, TranType_WLSysGive, SignBoon, JewelBoxBoon, LouFengConsumerRebate, ChessRechargePolite,
JiuGongGeDraw, CurrencyGive, GoldCouplePayVID, BookLoufeng, Active2023Cost, Active2023Reward, RaffleDeduction, PrizeRecord,
DailyTaskAdsClick, DailyTaskUserInvite, OnceTaskBuyVIP, OnceTaskBindMobile, ReceiveIntegral, BuyVIP, IntegralExchangeVip,
ReceiveIntegral, ProxyIncome, WorksIncome, SendMsgDebitIncomeGold, SendMsgDebitIncomeGoldReturn, SendMsgDebitAmountGold,
SendMsgDebitAmountGoldReturn, AiChangefaceDebitGold, AiChangefaceDebitGoldReturn, AiChangefaceDebitInComeGold, AiChangefaceDebitIncomeGoldReturn,
AiChangeFaceImgDebitGold, AiChangeFaceImgReturnGold, AiUndressDebitFreeTimes, AiUndressDebitFreeTimesReturn, AiUndressDebitIncomeGold,
AiUndressDebitIncomeGoldReturn, AiChangeFaceImgDebitIncomeGold, AiChangeFaceImgReturnIncomeGold, AiChangeFaceImgDebitFreeTimes,
AiChangeFaceImgDebitFreeTimesReturn, AiUndress, AiUndressRefund, AiUndressInc, AiUndressIncBackend, AiUndressDebitGold, AiUndressDebitGoldReturn,
VipCardGiveAiUndressFreeCount, AdminAddDownloadCount, AdminDebitDownloadCount, BuyAdvanceVIP, BuyBalanceVIP, BuyGameAdvanceVIP,
BuyWhoringCard, ReSignDebitAmount, SuccessSignReturnAmount, GodCommentAward, IntegralExchangeAICount, AiMateCurrencyExchange,
AiImageToVideoDebitGold, AiImageToVideoDebitGoldReturn, AiImageToVideoDebitInComeGold, AiImageToVideoDebitIncomeGoldReturn,
AiTextToImageDebitGold, AiTextToImageDebitGoldReturn, AiTextToImageDebitInComeGold, AiTextToImageDebitIncomeGoldReturn, BuyAcg,
AiTextToNovelDebitGold, AiTextToNovelDebitGoldReturn, AiTextToNovelDebitInComeGold, AiTextToNovelDebitIncomeGoldReturn,
}},
//"amount": bson.M{"$ne": 0},
"$or": []bson.M{
bson.M{"amount": bson.M{"$ne": 0}},
bson.M{"integral": bson.M{"$ne": 0}},
bson.M{"tranTypeInt": bson.M{"$in": []TransType{AiGirlfriendTransferIn, AiGirlfriendTransferOut}}},
},
}
if pageSize == 0 || pageSize >= uint64(maxLedgerWindow) {
return nil, false, fmt.Errorf("invalid ledger page size")
}
if pageNumebr == 0 {
pageNumebr = 1
}
if pageNumebr-1 > uint64(maxLedgerWindow)/pageSize {
return nil, false, fmt.Errorf("ledger query window is too large; narrow the time range")
}
rows, err := findLedgerRows(f, int64(pageSize*(pageNumebr-1)), int64(pageSize+1))
if err != nil {
return nil, false, err
}
hasNext = len(rows) > int(pageSize)
if hasNext {
rows = rows[:pageSize]
}
for _, row := range rows {
data = append(data, *row)
}
return data, hasNext, nil
}
// HasNextMonth 查询当前月之前的最迟数据的的时间
func HasNextMonth(uid uint64, start time.Time) (data TransactionLog, err error) {
opt := options.FindOne()
opt.Sort = bson.D{{Key: "createdAt", Value: -1}}
err = coll(nil).FindOne(&data, bson.M{"uid": uid, "createdAt": bson.M{"$lt": start}})
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "HasNext", table, "FindOne", err),
log.Any("uid", uid),
log.Any("start", start),
)
return
}
return
}
func BuyLoufengCount(uid uint64) (int64, error) {
return coll(nil).Count(bson.M{"uid": uid, "tranTypeInt": bson.M{"$in": []TransType{LouFeng, BookLoufeng}}})
}
// 时间内购买VIP次数
func BuyVipCount(start, end time.Time, mats ...Matcher) (int64, error) {
payVIP := PayVIP.Key()
mats = append(mats, (&TranTypeMatch{&payVIP}).New(), (&CreatedAtGTEAndLTMatch{GTE: &start, LT: &end}).New())
filter := pageopt.MergeM(mats)
count, err := coll(nil).Count(filter)
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "BuyVipCount", table, "Count", err))
}
return count, err
}
// //产品购买记录
func BuyProductLog(uid uint64, tranTypeInt TransType, pids []primitive.ObjectID) (data []TransactionLog, err error) {
objIDs := make([]string, len(pids))
for i := range pids {
objIDs[i] = pids[i].Hex()
}
data = make([]TransactionLog, 0)
opt := options.FindOptions{
Sort: bson.D{{Key: "createdAt", Value: -1}},
}
f := bson.M{"uid": uid, "tranTypeInt": tranTypeInt, "productID": bson.M{"$in": objIDs}}
if err = coll(nil).Find(&data, f, &opt); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "BuyProductLog", table, "Find", err))
return
}
return
}
// 产品购买记录 单个
func BuyProductLogSingle(uid uint64, tranTypeInt TransType, pid string) (data TransactionLog, err error) {
f := bson.M{"uid": uid, "tranTypeInt": tranTypeInt, "productID": pid}
if err = coll(nil).FindOne(&data, f); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "BuyProductLogSingle", table, "Find", err))
return
}
return
}
// 产品购买记录
func BuyProductLogWithPage(uid uint64, tranTypeInt TransType, page commod.Page) (data []TransactionLog, hasNext bool, err error) {
data = make([]TransactionLog, 0)
skip := int64(page.Skip())
limit := int64(page.Limit() + 1)
opts := options.FindOptions{
Skip: &skip,
Limit: &limit,
Sort: bson.D{{Key: "createdAt", Value: -1}},
}
f := bson.M{"uid": uid, "tranTypeInt": tranTypeInt}
if tranTypeInt == PayAvVID {
f["productID"] = bson.M{"$exists": true}
}
if err = coll(nil).Find(&data, f, &opts); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "BuyProductLog", table, "Find", err))
return
}
if uint64(len(data)) > page.PageSize {
hasNext = true
data = data[:page.PageSize]
}
return
}
// Income 账单
func WorksIncomebills(uid uint64, pageNumebr, pageSize uint64) (data []TransactionLog, hasNext bool, err error) {
data = make([]TransactionLog, 0)
f := bson.M{"uid": uid, "tranTypeInt": WorksIncome}
skip := int64(pageSize * (pageNumebr - 1))
limit := int64(pageSize + 1)
opts := options.FindOptions{
Skip: &skip,
Limit: &limit,
Sort: bson.D{{Key: "createdAt", Value: -1}},
}
if err = coll(nil).Find(&data, f, &opts); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindTransactionLogs", table, "Find", err),
log.Any("filter", f),
)
return
}
if len(data) > int(pageSize) {
hasNext = true
data = data[:pageSize]
}
return
}
// 是否购买了某个产品
func IsBuyProduct(uid uint64, id primitive.ObjectID, tranTypeInt TransType) (bool, error) {
f := bson.M{"uid": uid, "productID": id.Hex(), "tranTypeInt": tranTypeInt}
count, err := coll(nil).Count(f)
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "BuyVipCount", table, "Count", count))
return false, err
}
return count > 0, nil
}
// QueryAll 条件查询列表
func QueryAll(filter bson.M, opts ...*options.FindOptions) ([]TransactionLog, error) {
var items []TransactionLog
return items, coll(nil).Find(&items, filter, opts...)
}
// TransStat 交易统计
func TransStat(start, end time.Time) ([]TransactionR, error) {
var items []TransactionR
f := bson.M{"createdAt": bson.M{"$gt": start, "$lte": end}, "tranTypeInt": LouFeng}
return items, coll(nil).Find(&items, f)
}
// IncomeLeaderboard 收益榜单
func IncomeLeaderboard(bind interface{}, filter bson.M, limit int) error {
pip := []bson.M{
{"$match": filter},
{"$group": bson.M{"_id": "$uid", "income": bson.M{"$sum": "$actualAmount"}}},
{"$sort": bson.M{"income": -1}},
{"$limit": limit},
}
if err := coll(nil).Aggregate(bind, pip); err != nil {
log.Info(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "IncomeLeaderboard", table, "Aggregate", err))
return err
}
return nil
}
// FindByCond 根据条件查询
func FindByCond(filter primitive.M) (TransactionLog, error) {
opt := options.FindOneOptions{
Sort: bson.D{{Key: "createdAt", Value: -1}},
}
var data TransactionLog
if err := coll(nil).FindOne(&data, filter, &opt); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "LastTime", table, "FindByCond", err),
log.Any("filter", filter),
)
return data, err
}
return data, nil
}
// CheckRepurchaseByTransTypes 判断是否购买过,返回yes/no
func CheckRepurchaseByTransTypes(uid uint64, types []TransType) (isRepurchase string, err error) {
if len(types) == 0 {
return "no", nil
}
has, err := coll(nil).Exists(bson.M{"uid": uid, "tranTypeInt": bson.M{"$in": types}})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CheckRepurchaseByTransTypes", table, "Exists", err),
log.Any("uid", uid),
log.Any("types", types),
)
return "no", err
}
if has {
return "yes", nil
}
return "no", nil
}