/* * @Description: 账户充值流水 * @Author: your name * @Date: 2019-08-29 20:45:27 * @LastEditTime: 2019-08-30 13:54:21 * @LastEditors: Please set LastEditors */ package wdordmod import ( "errors" "fmt" "time" "91porn-server/common/db" "91porn-server/common/log" "91porn-server/common/pageopt" "91porn-server/models" "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.WithdrawOrder // InitIndex 设置index func initIndex() { coll := coll(nil) many := []mongo.IndexModel{ { Keys: bson.D{{Key: "name", Value: 1}}, }, { Keys: bson.D{{Key: "amount", Value: 1}}, }, { Keys: bson.D{{Key: "oid", Value: 1}}, // Options: options.Index().SetUnique(true).SetSparse(true), }, { Keys: bson.D{{Key: "money", Value: 1}}, }, { Keys: bson.D{{Key: "payMoney", Value: 1}}, }, { Keys: bson.D{{Key: "createdAt", Value: 1}}, }, { Keys: bson.D{{Key: "updatedAt", 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: "withdrawType", Value: 1}, {Key: "createdAt", Value: -1}}, }, { Keys: bson.D{{Key: "status", Value: 1}, {Key: "createdAt", Value: -1}}, }, { Keys: bson.D{{Key: "payType", 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: "districtRemark", Value: 1}, {Key: "createdAt", Value: -1}}, }, } 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) } // InsertWithdrawOrder 订单写入 func InsertWithdrawOrder(t *db.MongoTool, w *WithdrawOrder) (id primitive.ObjectID, err error) { if w.CreatedAt.IsZero() { w.CreatedAt = time.Now() } ret, err := coll(t).InsertOne(w) if err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "InsertWithdrawOrder", table, "InsertOne", err), log.Any("w", w), ) return primitive.NilObjectID, err } return ret.InsertedID.(primitive.ObjectID), err } // FindOneAndUpate 查询 func FindOneAndUpate(id string, status int, set EditSelector) (w WithdrawOrder, err error) { oid, err := primitive.ObjectIDFromHex(id) if err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindOneAndUpate", table, "ObjectIDFromHex", err), log.Any("id", id), log.Any("status", status), log.Any("set", set), ) return } if err = coll(nil).FindOneAndUpdate(&w, bson.M{"_id": oid, "status": status}, bson.M{"$set": set}); err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindOneAndUpate", table, "FindOneAndUpdate", err), log.Any("id", id), log.Any("status", status), log.Any("set", set), ) } return } // FindWithdrawOrderByID 查询 func FindWithdrawOrderByID(id string) (w WithdrawOrder, err error) { oid, err := primitive.ObjectIDFromHex(id) if err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindWithdrawOrderByID", table, "ObjectIDFromHex", err), log.Any("id", id), ) return } if err = coll(nil).FindOneByID(&w, oid); err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindWithdrawOrderByID", table, "FindOneByID", err), log.Any("id", id), ) } if w.ID.IsZero() { //coll(nil).FindOne过滤了mongo.ErrNoDocuments err = OrderNotExistError{} } return } // FindWithdrawOrderByIDAndStatus 查询 func FindWithdrawOrderByIDAndStatus(id string, status int) (w WithdrawOrder, err error) { oid, err := primitive.ObjectIDFromHex(id) if err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindWithdrawOrderByIDAndStatus", table, "ObjectIDFromHex", err), log.Any("status", status), log.Any("id", id), ) return } if err = coll(nil).FindOne(&w, bson.M{"_id": oid, "status": status}); err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindWithdrawOrderByIDAndStatus", table, "FindOne", err), log.Any("status", status), log.Any("id", id), ) } if w.ID.IsZero() { //coll(nil).FindOne过滤了mongo.ErrNoDocuments err = OrderNotExistError{} } return } // FindOrders 查询充值订单 func FindOrdersByUID(uid uint64, pageNumber, pageSize uint64) (total int64, data []*WithdrawOrder, hasNext bool, err error) { data = make([]*WithdrawOrder, 0) f := bson.M{"uid": uid} skip := int64(pageSize * (pageNumber - 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:", "FindOrders", table, "Find", err), log.Any("cond", f), ) return } total, err = coll(nil).Count(f) if err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindOrders", table, "Count", err), log.Any("cond", f), ) } if len(data) > int(pageSize) { hasNext = true data = data[:pageSize] } return } // FindOrders 查询充值订单 func FindOrders(cond bson.M, opts *options.FindOptions) (total int64, data []*WithdrawOrder, err error) { if v, ok := cond["districtRemark"]; ok { cond["districtRemark"] = bson.M{"$regex": v, "$options": "i"} } data = make([]*WithdrawOrder, 0) if err = coll(nil).Find(&data, cond, opts); err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindOrders", 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:", "FindOrders", table, "Count", err), log.Any("cond", cond), ) } return } // UpdateWithPROCESSINGAndUNKNOWN 回调更改订单状态 func UpdateWithPROCESSINGAndUNKNOWN(t *db.MongoTool, id string, set EditSelector) 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:", "Update", table, "ObjectIDFromHex", err), log.Any("id", id), log.Any("set", set), ) return err } res, err := coll(t).UpdateOne(primitive.M{"_id": objID, "status": bson.M{"$in": []int{PROCESSING, UNKNOWN}}}, bson.M{"$set": set}) if 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 } if res.ModifiedCount <= 0 { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Update", table, "errors.New", "Invalid account"), log.Any("id", id), log.Any("set", set), ) return errors.New("Invalid account") } return nil } // Update 更新充值订单状态,OId func Update(t *db.MongoTool, id string, set EditSelector) 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:", "Update", table, "ObjectIDFromHex", err), log.Any("id", id), log.Any("set", set), ) return err } res, err := coll(t).UpdateOne(primitive.M{"_id": objID}, bson.M{"$set": set}) if 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 } if res.ModifiedCount <= 0 { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Update", table, "errors.New", "Invalid account"), log.Any("id", id), log.Any("set", set), ) return errors.New("Invalid account") } return nil } // 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.ZapLog.Warn("withdraw TotalMoney AggregateDecode failed", log.E(err)) return 0, err } return ret.Money, nil } // WithdrawAmontByTime 金币提现金额 提现类型,0:代理提现; 1:金币提现 李秋山确认 func WithdrawAmontByTime(start time.Time, end time.Time, types WithdrawTypes) (int64, error) { pipeline := []bson.M{ { "$match": bson.M{ // createdAt ∈ [startTime, endTime) "successAt": bson.M{"$gte": start, "$lt": end}, "withdrawType": types, }, }, { "$group": bson.M{ "_id": nil, "totalWithdrawAmount": bson.M{"$sum": "$money"}, //Money:提现金额 }, }, } var ret struct { TotalWithdrawAmount int64 `bson:"totalWithdrawAmount"` } if err := coll(nil).AggregateDecode(&ret, pipeline); err != nil { return 0, err } return ret.TotalWithdrawAmount, nil } // ChannelOrderCountMap channel->订单数 map func ChannelOrderCountMap(start, end time.Time) (map[string]int64, error) { filter := bson.M{ "createdAt": bson.M{ "$gte": start, "$lt": end, }, } 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 := bson.M{ "createdAt": bson.M{ "$gte": start, "$lt": end, }, } 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 } // ChannelCompleteOrderCountMap channel->完成订单数 map func ChannelCompleteOrderCountMap(start, end time.Time) (map[string]int64, error) { filter := bson.M{ "successAt": bson.M{ "$gte": start, "$lt": end, }, } 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 } // ChannelCompleteOrderAmountMap channel->完成订单的实际到账金额 map func ChannelCompleteOrderPayMoneyMap(start, end time.Time) (map[string]int64, error) { filter := bson.M{ "successAt": bson.M{ "$gte": start, "$lt": end, }, } 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 } // ChannelReceivedOrderCountMap channel->已出款订单数 map func ChannelReceivedOrderCountMap(start, end time.Time) (map[string]int64, error) { filter := bson.M{ "receivedAt": bson.M{ "$gte": start, "$lt": end, }, } 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 } // ChannelReceivedMoneyMap channel->已出款金额 map func ChannelReceivedMoneyMap(start, end time.Time) (map[string]int64, error) { filter := bson.M{ "receivedAt": bson.M{ "$gte": start, "$lt": end, }, } 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 } func UpdateOne(t *db.MongoTool, filter bson.M, update bson.M) (rr error) { n, err := coll(t).UpdateOne(filter, bson.M{"$set": update}) if err != nil { log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "update", table, "updateOne", err)) return err } if n.ModifiedCount <= 0 { return errors.New("not modified") } return nil }