From 91a3bd53717cebda72047477f246e1b2dd3907c7 Mon Sep 17 00:00:00 2001 From: lwl0608 Date: Fri, 12 Apr 2024 10:01:49 +0800 Subject: [PATCH 1/3] add --- app/mix/dao/mongo.go | 24 +- app/mix/dao/mongo_vas.go | 90 ++++++ app/mix/service/logic/vas.go | 443 ------------------------------ app/mix/service/logic/vas_zone.go | 50 ++++ dbstruct/vas_mongo.go | 32 +++ dbstruct/vas_mysql.go | 36 +-- dbstruct/zone.go | 28 -- 7 files changed, 208 insertions(+), 495 deletions(-) create mode 100644 app/mix/service/logic/vas_zone.go diff --git a/app/mix/dao/mongo.go b/app/mix/dao/mongo.go index a566419c..943393a0 100644 --- a/app/mix/dao/mongo.go +++ b/app/mix/dao/mongo.go @@ -69,11 +69,13 @@ func NewMongo(cfg *conf.ConfigSt) (mongo *Mongo, err error) { // mongo const ( - DBVas = "vas" - COLProduct = "product" - COLUserVasInfo = "user_vas_info" - COLOpLogOrder = "oplog_order_%d" - COLOpLogCoinOrder = "oplog_coin_order_%d" + DBVas = "vas" + COLProduct = "product" + COLUserVasInfo = "user_vas_info" + COLOpLogOrder = "oplog_order_%d" + COLOpLogCoinOrder = "oplog_coin_order_%d" + COLZoneVas = "zone_vas" + COLZoneMomentPrice = "zone_moment_price" DBCatalog = "catalog" COLCatalog = "catalog" @@ -203,11 +205,21 @@ func (m *Mongo) getColProduct() *qmgo.Collection { return m.clientMix.Database(DBVas).Collection(COLProduct) } -// 商品表 +// 用户增值信息,微信价格等 func (m *Mongo) getColUserVasInfo() *qmgo.Collection { return m.clientMix.Database(DBVas).Collection(COLUserVasInfo) } +// 空间增值信息 +func (m *Mongo) getColZoneVas() *qmgo.Collection { + return m.clientMix.Database(DBVas).Collection(COLZoneVas) +} + +// 空间动态价格 +func (m *Mongo) getColZoneMomentPrice() *qmgo.Collection { + return m.clientMix.Database(DBVas).Collection(COLZoneMomentPrice) +} + // 订单操作记录 func (m *Mongo) getColOplogOrder(orderId string) *qmgo.Collection { orderIdInt64, _ := strconv.ParseInt(orderId[:13], 10, 64) diff --git a/app/mix/dao/mongo_vas.go b/app/mix/dao/mongo_vas.go index cdc0138f..966ac89a 100644 --- a/app/mix/dao/mongo_vas.go +++ b/app/mix/dao/mongo_vas.go @@ -35,6 +35,9 @@ func (m *Mongo) GetUserVasInfoByMid(ctx *gin.Context, mid int64) (*dbstruct.User err = nil return nil, nil } + if err != nil { + return nil, err + } return doc, nil } @@ -61,3 +64,90 @@ func (m *Mongo) UpdateUserVasInfo(ctx *gin.Context, req *vasproto.UpdateWechatRe } return err } + +// 空间增值信息 +func (m *Mongo) GetZoneVasById(ctx *gin.Context, id int64) (*dbstruct.ZoneVas, error) { + doc := new(dbstruct.ZoneVas) + col := m.getColZoneVas() + query := qmgo.M{ + "_id": id, + } + err := col.Find(ctx, query).One(&doc) + if err == qmgo.ErrNoSuchDocuments { + err = nil + return nil, nil + } + if err != nil { + return nil, err + } + return doc, nil +} + +func (m *Mongo) UpsertZoneVas(ctx *gin.Context, req *dbstruct.ZoneVas) error { + col := m.getColZoneVas() + _, err := col.Bulk().UpsertOne( + qmgo.M{ + "_id": req.Zid, + }, + qmgo.M{ + operator.SetOnInsert: qmgo.M{ + "ct": time.Now().Unix(), + "mid": req.Mid, + }, + operator.Set: qmgo.M{ + "ut": time.Now().Unix(), + "admission_price": req.AdmissionPrice, + "ironfanship_price": req.IronfanshipPrice, + "is_superfanship_enabled": req.IsSuperfanshipEnabled, + "superfanship_price": req.SuperfanshipPrice, + "superfanship_valid_period": req.SuperfanshipValidPeriod, + "is_superfanship_give_wechat": req.IsSuperfanshipGiveWechat, + }, + }, + ).Run(ctx) + if err != nil { + return err + } + return err +} + +// 空间动态价格 +func (m *Mongo) GetZoneMomentPriceById(ctx *gin.Context, id int64) (*dbstruct.ZoneMomentPrice, error) { + doc := new(dbstruct.ZoneMomentPrice) + col := m.getColZoneMomentPrice() + query := qmgo.M{ + "_id": id, + } + err := col.Find(ctx, query).One(&doc) + if err == qmgo.ErrNoSuchDocuments { + err = nil + return nil, nil + } + if err != nil { + return nil, err + } + return doc, nil +} + +func (m *Mongo) UpsertZoneMomentPrice(ctx *gin.Context, req *dbstruct.ZoneMomentPrice) error { + col := m.getColZoneMomentPrice() + _, err := col.Bulk().UpsertOne( + qmgo.M{ + "_id": req.MomentId, + }, + qmgo.M{ + operator.SetOnInsert: qmgo.M{ + "ct": time.Now().Unix(), + "mid": req.Mid, + }, + operator.Set: qmgo.M{ + "ut": time.Now().Unix(), + "price": req.Price, + }, + }, + ).Run(ctx) + if err != nil { + return err + } + return err +} diff --git a/app/mix/service/logic/vas.go b/app/mix/service/logic/vas.go index 3f32dca4..4318b9ba 100644 --- a/app/mix/service/logic/vas.go +++ b/app/mix/service/logic/vas.go @@ -559,200 +559,6 @@ func (v *Vas) PreUnlockContact(ctx *gin.Context, req *vasproto.PreUnlockContactR return } -// 解锁联系方式 -func (v *Vas) ConfirmUnlockContact(ctx *gin.Context, req *vasproto.ConfirmUnlockContactReq) (contact string, err error) { - var ( - mid = req.Mid // 解锁人 - orderId = req.OrderId // 订单id - ) - - // 检查钱包 - _, has := v.CheckWalletExist(ctx, mid) - if !has { - err = errs.ErrVasWalletNotExist - return - } - - // 开启事务 - tx, err := v.store.VasBegin(ctx) - if err != nil { - logger.Error("vas begin fail, err: %v", err) - return - } - defer func() { - if err != nil { - logger.Error("global err, req: %v, err: %v", util.ToJson(req), err) - } - err = v.store.DealTxCR(tx, err) - if err != nil { - logger.Error("DealTxCR fail, err: %v", err) - return - } - }() - - // 锁定钉 订单检查 - order, err := v.store.GetCoinOrderByIdForUpdate(ctx, tx, orderId) - if err != nil { - logger.Error("GetCoinOrderByIdForUpdate fail, mid: %v, orderId: %v, err: %v", mid, orderId, err) - return - } - if order == nil { - err = errs.ErrVasNoEnoughCoin - logger.Error("invalid order, mid: %v, orderId: %v, err: %v", mid, orderId, err) - return - } - if order.GetMid() != mid { - err = errs.ErrVasOrderNotMatch - logger.Error("order not match, mid: %v, orderMid: %v, orderId: %v, err: %v", mid, order.GetMid(), orderId, err) - return - } - consumeCoins := order.GetCoins() - - // 锁钱包 余额检查 - wallet, err := v.store.GetWalletForUpdate(ctx, tx, mid) - if err != nil { - logger.Error("GetWalletForUpdate fail, mid: %v, orderId: %v, err: %v", mid, orderId, err) - return - } - if wallet == nil { - err = errs.ErrVasWalletNotExist - logger.Error("invalid wallet, mid: %v, orderId: %v, err: %v", mid, orderId, err) - return - } - if wallet.GetCoins() < consumeCoins { - err = errs.ErrVasNoEnoughCoin - logger.Error("coin not enough, mid: %v, orderId: %v, walletCoins: %v, orderCoins: %v", mid, orderId, wallet.GetCoins(), consumeCoins) - return - } - - // 扣钱 - err = v.store.DecCoins(ctx, tx, mid, consumeCoins) - if err != nil { - logger.Error("DecCoins fail, mid: %v, err: %v", mid, err) - return - } - - // 增加历史 - - return -} - -// 一步解锁联系方式 -func (v *Vas) OneStepUnlockContactV2(ctx *gin.Context, req *vasproto.OneStepUnlockContactReq) (contact string, err error) { - var ( - mid = req.Mid // 解锁人 - uid = req.Uid // 要解锁的人,即 mid 要解锁 uid 的联系方式 - contactProductId = req.ContactProductId // 要解锁的联系方式 - ) - - // 获取uid增值信息 - uVasInfo, err := v.store.GetUserVasInfoByMid(ctx, uid) - if err != nil { - logger.Error("GetUserVasInfoByMid fail, mid: %v, uid: %v, err: %v", mid, uid, err) - return - } - if uVasInfo == nil { - err = errs.ErrVasUserVasNotExist - logger.Warn("no user_vas info, mid: %v, uid: %v, err: %v", mid, uid, err) - return - } - - // uid(网红)钱包 - streamerWallet, _ := v.CheckWalletExist(ctx, req.Uid) - // 官网钱包 - officialWallet, _ := v.CheckWalletExist(ctx, common.OfficialMid) - // 邀请人钱包 - inviterWallet, _ := v.CheckWalletExist(ctx, req.InviterMid) - - var ( - coinPrice int64 = 0 - ) - switch contactProductId { - case dbstruct.ProductIdContactWechat: - // 获取uid微信金币价格 - coinPrice = uVasInfo.WechatCoinPrice - default: - err = errs.ErrVasInvalidContactProduct - return - } - if coinPrice <= 0 { - err = errs.ErrVasInvalidCoinPrice - logger.Warn("invalid coin price, mid: %v, uid: %v, contactProductId: %v, coinPrice: %v", mid, uid, contactProductId, coinPrice) - return - } - - // 开启事务 - tx, err := v.store.VasBegin(ctx) - if err != nil { - logger.Error("vas begin fail, err: %v", err) - return - } - defer func() { - if err != nil { - logger.Error("global err, req: %v, err: %v", util.ToJson(req), err) - } - err = v.store.DealTxCR(tx, err) - if err != nil { - logger.Error("DealTxCR fail, err: %v", err) - return - } - contact = uVasInfo.WechatContact - }() - - // 锁钱包 余额检查 - wallet, err := v.store.GetWalletForUpdate(ctx, tx, mid) - if err != nil { - logger.Error("GetWalletForUpdate fail, mid: %v, uid: %v, err: %v", mid, uid, err) - return - } - if wallet == nil { - err = errs.ErrVasWalletNotExist - logger.Error("invalid wallet, mid: %v, err: %v", mid, err) - return - } - if wallet.GetCoins() < coinPrice { - err = errs.ErrVasNoEnoughCoin - logger.Error("coin not enough, mid: %v, walletCoins: %v, coinPrice: %v", mid, wallet.GetCoins(), coinPrice) - return - } - - l := v.NewOneStepUnlockContactLogic( - ctx, - tx, - req, - wallet, - streamerWallet, - officialWallet, - inviterWallet, - coinPrice, - ) - // 消费者逻辑 - err = l.DoConsumerLogic() - if err != nil { - logger.Error("DoConsumerLogic fail, err: %v", err) - return - } - // 网红逻辑 - err = l.DoStreamerLogic() - if err != nil { - logger.Error("DoStreamerLogic fail, err: %v", err) - return - } - // 官方逻辑 - err = l.DoOfficialLogic() - if err != nil { - logger.Error("DoOfficialLogic fail, err: %v", err) - return - } - // 邀请人逻辑 - err = l.DoInviterLogic() - if err != nil { - logger.Error("DoInviterLogic fail, err: %v", err) - return - } - return -} - // 一步解锁联系方式 func (v *Vas) OneStepUnlockContact(ctx *gin.Context, req *vasproto.OneStepUnlockContactReq) (lockType int32, orderId, retContact string, err error) { var ( @@ -1101,255 +907,6 @@ func (v *Vas) ConsumerFillContact(ctx *gin.Context, req *vasproto.ConsumerFillCo return } -// todo 获取待结算订单 -func (v *Vas) GetWaitSettleCoinOrders() (list []*dbstruct.CoinOrder, err error) { - return -} - -type OneStepUnlockContact struct { - v *Vas - ctx *gin.Context - tx *sqlx.Tx - req *vasproto.OneStepUnlockContactReq - consumerWallet *dbstruct.Wallet - streamerWallet *dbstruct.Wallet - officialWallet *dbstruct.Wallet - inviterWallet *dbstruct.Wallet - coinOrderId string - coinPrice int64 - streamerDias int64 - officialDias int64 - inviterDias int64 -} - -func (v *Vas) NewOneStepUnlockContactLogic(ctx *gin.Context, tx *sqlx.Tx, req *vasproto.OneStepUnlockContactReq, - consumerWallet, streamerWallet, officialWallet, inviterWallet *dbstruct.Wallet, coinPrice int64) *OneStepUnlockContact { - ret := &OneStepUnlockContact{ - v: v, - ctx: ctx, - tx: tx, - req: req, - consumerWallet: consumerWallet, - streamerWallet: streamerWallet, - officialWallet: officialWallet, - inviterWallet: inviterWallet, - coinOrderId: idgenerator.GenCoinOrderId(), - coinPrice: coinPrice, - } - var ( - totalDias = coinPrice - ) - ret.streamerDias = int64(float64(totalDias) * 0.8) - if req.InviterMid > 0 { - ret.officialDias = int64(float64(totalDias) * 0.2) - } else { - ret.officialDias = int64(float64(totalDias) * 0.15) - } - ret.inviterDias = totalDias - ret.streamerDias - ret.officialDias - return ret -} - -// 消费者逻辑 -func (l *OneStepUnlockContact) DoConsumerLogic() (err error) { - if l.consumerWallet == nil { - err = errors.New(fmt.Sprintf("invalid consumerWallet, mid: %v", l.req.Mid)) - return - } - - // 生成金币订单 - var ( - timeNow = time.Now().Unix() - ) - coinOrder := &dbstruct.CoinOrder{ - ID: goproto.String(l.coinOrderId), - Mid: goproto.Int64(l.req.Mid), - Uid: goproto.Int64(l.req.Uid), - ProductId: goproto.String(l.req.ContactProductId), - Coins: goproto.Int64(l.coinPrice), - OrderStatus: goproto.Int32(dbstruct.VasCoinOrderStatusPaySuccess), - Ct: goproto.Int64(timeNow), - Ut: goproto.Int64(timeNow), - Did: goproto.String(l.req.Did), - Version: goproto.String(l.req.Version), - OsVersion: goproto.String(l.req.Version), - DevType: goproto.Int32(l.req.DevType), - Channel: goproto.String(l.req.Channel), - Model: goproto.String(l.req.Model), - NetType: goproto.String(l.req.NetType), - Ip: goproto.String(l.req.Ip), - } - err = l.v.store.CreateCoinOrder(l.ctx, l.tx, coinOrder) - if err != nil { - logger.Error("CreateCoinOrder fail, order: %v, err: %v", util.ToJson(coinOrder), err) - return - } - - // 增加金币消费历史 - ch := &dbstruct.ConsumeHistory{ - Mid: goproto.Int64(l.req.Mid), - Uid: goproto.Int64(l.req.Uid), - Did: goproto.String(l.req.Did), - Type: goproto.Int32(dbstruct.CHTypeCost), - SType: goproto.Int32(dbstruct.CHSTypeCostContact), - TypeId: goproto.String(l.req.ContactProductId), - OrderId: goproto.String(l.coinOrderId), - Change: goproto.Int64(-l.coinPrice), - Before: goproto.Int64(util.DerefInt64(l.consumerWallet.Coins)), - After: goproto.Int64(util.DerefInt64(l.consumerWallet.Coins) - l.coinPrice), - Ct: goproto.Int64(timeNow), - } - err = l.v.store.CreateConsumeHistory(l.ctx, l.tx, ch) - if err != nil { - logger.Error("CreateConsumeHistory fail, ch: %v, err: %v", util.ToJson(ch), err) - return - } - - // 增加解锁记录 - userVasUnlock := &dbstruct.UserVasUnlock{ - Mid: goproto.Int64(l.req.Mid), - Uid: goproto.Int64(l.req.Uid), - ProductId: goproto.String(l.req.ContactProductId), - Ct: goproto.Int64(timeNow), - LockType: nil, - Status: nil, - Means: nil, - OrderId: nil, - } - err = l.v.store.CreateUserVasUnlock(l.ctx, l.tx, userVasUnlock) - if err != nil { - logger.Error("CreateUserVasUnlock fail, userVasUnlock: %v, err: %v", util.ToJson(userVasUnlock), err) - return - } - - // 扣钱 - err = l.v.store.DecCoins(l.ctx, l.tx, l.req.Mid, l.coinPrice) - if err != nil { - logger.Error("DecCoins fail, mid: %v, coinPrice: %v, err: %v", l.req.Mid, l.coinPrice, err) - return - } - return -} - -// 网红逻辑 -func (l *OneStepUnlockContact) DoStreamerLogic() (err error) { - if l.streamerWallet == nil { - err = errors.New(fmt.Sprintf("invalid streamerWallet, mid: %v", l.req.Uid)) - return - } - - // 收入历史 - var ( - timeNow = time.Now().Unix() - ) - ch := &dbstruct.ConsumeHistory{ - Mid: goproto.Int64(l.req.Uid), - Uid: goproto.Int64(l.req.Mid), - Did: goproto.String(l.req.Did), - Type: goproto.Int32(dbstruct.CHTypeIncome), - SType: goproto.Int32(dbstruct.CHSTypeIncomeContact), - TypeId: goproto.String(l.req.ContactProductId), - OrderId: goproto.String(l.coinOrderId), - Change: goproto.Int64(l.streamerDias), - Before: goproto.Int64(util.DerefInt64(l.streamerWallet.Diamonds)), - After: goproto.Int64(util.DerefInt64(l.streamerWallet.Diamonds) + l.streamerDias), - Ct: goproto.Int64(timeNow), - } - err = l.v.store.CreateConsumeHistory(l.ctx, l.tx, ch) - if err != nil { - logger.Error("CreateConsumeHistory fail, ch: %v, err: %v", util.ToJson(ch), err) - return - } - - // 加钻石 - err = l.v.store.IncDiamonds(l.ctx, l.tx, l.req.Uid, l.streamerDias) - if err != nil { - logger.Error("IncDiamonds fail, mid: %v, dias: %v, err: %v", l.req.Mid, l.streamerDias, err) - return - } - return -} - -// 官方逻辑 -func (l *OneStepUnlockContact) DoOfficialLogic() (err error) { - if l.officialWallet == nil { - err = errors.New("invalid officialWallet") - return - } - - // 收入历史 - var ( - timeNow = time.Now().Unix() - ) - ch := &dbstruct.ConsumeHistory{ - Mid: goproto.Int64(common.OfficialMid), - Uid: goproto.Int64(l.req.Mid), - Did: goproto.String(l.req.Did), - Type: goproto.Int32(dbstruct.CHTypeIncome), - SType: goproto.Int32(dbstruct.CHSTypeIncomeContact), - TypeId: goproto.String(l.req.ContactProductId), - OrderId: goproto.String(l.coinOrderId), - Change: goproto.Int64(l.officialDias), - Before: goproto.Int64(util.DerefInt64(l.officialWallet.Diamonds)), - After: goproto.Int64(util.DerefInt64(l.officialWallet.Diamonds) + l.officialDias), - Ct: goproto.Int64(timeNow), - } - err = l.v.store.CreateConsumeHistory(l.ctx, l.tx, ch) - if err != nil { - logger.Error("CreateConsumeHistory fail, ch: %v, err: %v", util.ToJson(ch), err) - return - } - - // 加钻石 - err = l.v.store.IncDiamonds(l.ctx, l.tx, common.OfficialMid, l.officialDias) - if err != nil { - logger.Error("IncDiamonds fail, mid: %v, dias: %v, err: %v", common.OfficialMid, l.officialDias, err) - return - } - return -} - -// 邀请人逻辑 -func (l *OneStepUnlockContact) DoInviterLogic() (err error) { - if l.req.InviterMid <= 0 { - return - } - if l.streamerWallet == nil { - err = errors.New(fmt.Sprintf("invalid streamerWallet, mid: %v", l.req.Uid)) - return - } - - // 收入历史 - var ( - timeNow = time.Now().Unix() - ) - ch := &dbstruct.ConsumeHistory{ - Mid: goproto.Int64(l.req.InviterMid), - Uid: goproto.Int64(l.req.Uid), - Did: goproto.String(l.req.Did), - Type: goproto.Int32(dbstruct.CHTypeIncome), - SType: goproto.Int32(dbstruct.CHSTypeIncomeContact), - TypeId: goproto.String(l.req.ContactProductId), - OrderId: goproto.String(l.coinOrderId), - Change: goproto.Int64(l.inviterDias), - Before: goproto.Int64(util.DerefInt64(l.inviterWallet.Diamonds)), - After: goproto.Int64(util.DerefInt64(l.inviterWallet.Diamonds) + l.inviterDias), - Ct: goproto.Int64(timeNow), - } - err = l.v.store.CreateConsumeHistory(l.ctx, l.tx, ch) - if err != nil { - logger.Error("CreateConsumeHistory fail, ch: %v, err: %v", util.ToJson(ch), err) - return - } - - // 加钻石 - err = l.v.store.IncDiamonds(l.ctx, l.tx, l.req.InviterMid, l.officialDias) - if err != nil { - logger.Error("IncDiamonds fail, mid: %v, dias: %v, err: %v", l.req.InviterMid, l.inviterDias, err) - return - } - return -} - // 添加金币订单操作历史 func (v *Vas) AddOplogCoinOrder(ctx *gin.Context, param *dbstruct.OplogCoinOrder, errIn error) (err error) { doc := &dbstruct.OplogCoinOrder{ diff --git a/app/mix/service/logic/vas_zone.go b/app/mix/service/logic/vas_zone.go new file mode 100644 index 00000000..7c11cfc4 --- /dev/null +++ b/app/mix/service/logic/vas_zone.go @@ -0,0 +1,50 @@ +package logic + +//import ( +// "github.com/gin-gonic/gin" +// vasproto "service/api/proto/vas/proto" +// zoneproto "service/api/proto/zone/proto" +// "service/dbstruct" +// "service/library/logger" +//) +// +//func (v *Vas) ZoneCreateOrder(ctx *gin.Context, req *zoneproto.ZoneCreateOrderReq) (data *zoneproto.ZoneCreateOrderData, err error) { +// var ( +// productId = req.ProductId +// calcPrice = int64(0) +// uid = int64(0) +// ) +// +// switch req.ProductId { +// case dbstruct.ProductIdH5ZoneMoment: +// // 获取空间动态 +// mp, err := v.store.GetZoneMomentPriceById(ctx, req.MomentId) +// if err != nil { +// logger.Error("GetZoneMomentPriceById ") +// } +// } +// +// createOrderReq := &vasproto.CreateOrderReq{ +// BaseRequest: req.BaseRequest, +// Ip: ctx.ClientIP(), +// ProductId: req.ProductId, +// PayType: req.PayType, +// From: req.From, +// CalcPrice: calcPrice, +// Uid: uid, +// } +// createOrderData, err := v.CreateOrder(ctx, createOrderReq) +// if err != nil { +// logger.Error("CreateOrder fail, err: %v", err) +// return nil, err +// } +// data = &zoneproto.ZoneCreateOrderData{ +// OrderId: createOrderData.OrderId, +// AlipayParamStr: createOrderData.AlipayParamStr, +// AlipayH5ParamStr: createOrderData.AlipayH5ParamStr, +// WxpayNativeParamStr: createOrderData.WxpayNativeParamStr, +// WxpayJsapiParamObj: createOrderData.WxpayJsapiParamObj, +// WxpayH5ParamStr: createOrderData.WxpayH5ParamStr, +// } +// return +//} diff --git a/dbstruct/vas_mongo.go b/dbstruct/vas_mongo.go index 9bf7c8a7..4b7b6bf8 100644 --- a/dbstruct/vas_mongo.go +++ b/dbstruct/vas_mongo.go @@ -65,3 +65,35 @@ type OplogOrder struct { BeforeStatus int32 `json:"before_status" bson:"before_status"` AfterStatus int32 `json:"after_status" bson:"after_status"` } + +const ( + SuperfanshipValidPeriodEternal = 0 // 永久生效 + SuperfanshipValidPeriodMonth = 1 // 30d + SuperfanshipValidPeriodSeason = 2 // 90d + SuperfanshipValidPeriodHalfYear = 3 // 180d + SuperfanshipValidPeriodYear = 4 // 366d +) + +// 空间增值相关,空间价格等 +type ZoneVas struct { + Zid int64 `json:"zid" bson:"_id"` + Mid int64 `json:"mid" bson:"mid"` // 主播mid + Ct int64 `json:"ct" bson:"ct"` // + Ut int64 `json:"ut" bson:"ut"` // + AdmissionPrice int64 `json:"admission_price" bson:"admission_price"` // 空间解锁价格, 单位: 分 + IronfanshipPrice int64 `json:"ironfanship_price" bson:"ironfanship_price"` // 铁粉解锁价格, 单位: 分 + IsSuperfanshipEnabled int `json:"is_superfanship_enabled" bson:"is_superfanship_enabled"` // 是否开启超粉空间 0: 关闭, 1: 开启 + SuperfanshipPrice int64 `json:"superfanship_price" bson:"superfanship_price"` // 超粉价格, 单位: 分 + SuperfanshipValidPeriod int `json:"superfanship_valid_period" bson:"superfanship_valid_period"` // 超粉有效期类型, SuperfanshipValidPeriod* + IsSuperfanshipGiveWechat int `json:"is_superfanship_give_wechat" bson:"is_superfanship_give_wechat"` // 是否开启超粉空间赠送微信 0: 不赠送, 1: 赠送 +} + +// 空间动态价格 +type ZoneMomentPrice struct { + MomentId int64 `json:"id" bson:"_id"` // 动态id + Zid int64 `json:"zid" bson:"zid"` // 空间id + Mid int64 `json:"mid" bson:"mid"` // 主播mid + Ct int64 `json:"ct" bson:"ct"` // + Ut int64 `json:"ut" bson:"ut"` // + Price int64 `json:"price" bson:"price"` // 动态价格,单位:分 +} diff --git a/dbstruct/vas_mysql.go b/dbstruct/vas_mysql.go index 0b1d5303..dfa3fcab 100644 --- a/dbstruct/vas_mysql.go +++ b/dbstruct/vas_mysql.go @@ -803,7 +803,7 @@ func (p *WithdrawOrder) GetOpTime() int64 { // 处理记录 type WithdrawDiamondsHis struct { - Mid *int64 `json:"mid" bson:"mid"` + Mid *int64 `json:"mid" db:"mid"` IncomeChId *int64 `json:"income_ch_id" db:"income_ch_id"` OrderId *string `json:"order_id" db:"order_id"` Ct *int64 `json:"ct" db:"ct"` @@ -900,25 +900,25 @@ const ( // 用户解锁空间详情 type ZoneUnlock struct { - Id *int64 `json:"id"` - Mid *int64 `json:"mid"` // 用户mid - Zid *int64 `json:"zid"` // 空间id - Consume *int64 `json:"consume"` // 空间总消费 - AdmissionCt *int64 `json:"admission_ct"` // 普通会员开通时间 - AdmissionUntil *int64 `json:"admission_until"` // 普通会员到期时间,时间戳,-1: 永久 - AdmissionOrderId *string `json:"admission_order_id"` // 普通会员订单 - IronfanshipCt *int64 `json:"ironfanship_ct"` // 铁粉开通时间id - IronfanshipUntil *int64 `json:"ironfanship_until"` // 铁粉到期时间,时间戳,-1:永久 - IronfanshipOrderId *string `json:"ironfanship_order_id"` // 铁粉订单 - SuperfanCt *int64 `json:"superfan_ct"` // 超粉开通时间id - SuperfanshipUntil *int64 `json:"superfanship_until"` // 超粉到期时间,时间戳,-1:永久 - SuperfanshipOrderId *string `json:"superfanship_order_id"` // 超粉订单id + Id *int64 `json:"id" db:"id"` + Mid *int64 `json:"mid" db:"mid"` // 用户mid + Zid *int64 `json:"zid" db:"zid"` // 空间id + Consume *int64 `json:"consume" db:"consume"` // 空间总消费 + AdmissionCt *int64 `json:"admission_ct" db:"admission_ct"` // 普通会员开通时间 + AdmissionUntil *int64 `json:"admission_until" db:"admission_until"` // 普通会员到期时间,时间戳,-1: 永久 + AdmissionOrderId *string `json:"admission_order_id" db:"admission_order_id"` // 普通会员订单 + IronfanshipCt *int64 `json:"ironfanship_ct" db:"ironfanship_ct"` // 铁粉开通时间id + IronfanshipUntil *int64 `json:"ironfanship_until" db:"ironfanship_until"` // 铁粉到期时间,时间戳,-1:永久 + IronfanshipOrderId *string `json:"ironfanship_order_id" db:"ironfanship_order_id"` // 铁粉订单 + SuperfanCt *int64 `json:"superfan_ct" db:"superfan_ct"` // 超粉开通时间id + SuperfanshipUntil *int64 `json:"superfanship_until" db:"superfanship_until"` // 超粉到期时间,时间戳,-1:永久 + SuperfanshipOrderId *string `json:"superfanship_order_id" db:"superfanship_order_id"` // 超粉订单id } // 空间成员列表 type ZoneMember struct { - Zid *int64 `json:"zid" bson:"zid"` // 空间id - Mid *int64 `json:"mid" bson:"mid"` // 用户id - MemberType *int32 `json:"member_type" bson:"member_type"` // 空间成员类型 ZoneMemberType* - Ct *int64 `json:"ct" bson:"ct"` // 成为成员的时间 + Zid *int64 `json:"zid" db:"zid"` // 空间id + Mid *int64 `json:"mid" db:"mid"` // 用户id + MemberType *int32 `json:"member_type" db:"member_type"` // 空间成员类型 ZoneMemberType* + Ct *int64 `json:"ct" db:"ct"` // 成为成员的时间 } diff --git a/dbstruct/zone.go b/dbstruct/zone.go index 29fb813a..5b3ae2bf 100644 --- a/dbstruct/zone.go +++ b/dbstruct/zone.go @@ -12,31 +12,3 @@ type Zone struct { Ut *int64 `json:"ut" bson:"ut"` // 更新时间 DelFlag *int64 `json:"del_flag" bson:"del_flag"` // 删除标记 } - -const ( - SuperfanshipValidPeriodEternal = 0 // 永久生效 - SuperfanshipValidPeriodMonth = 1 // 30d - SuperfanshipValidPeriodSeason = 2 // 90d - SuperfanshipValidPeriodHalfYear = 3 // 180d - SuperfanshipValidPeriodYear = 4 // 366d -) - -// 空间增值相关,空间价格等 -type ZoneVas struct { - Zid int64 `json:"zid" bson:"_id"` - Mid int64 `json:"mid" bson:"mid"` // 主播mid - AdmissionPrice int64 `json:"admission_price" bson:"admission_price"` // 空间解锁价格, 单位: 分 - IronfanshipPrice int64 `json:"ironfanship_price" bson:"ironfanship_price"` // 铁粉解锁价格, 单位: 分 - IsSuperfanshipEnabled int `json:"is_superfanship_enabled" bson:"is_superfanship_enabled"` // 是否开启超粉空间 0: 关闭, 1: 开启 - SuperfanshipPrice int64 `json:"superfanship_price" bson:"superfanship_price"` // 超粉价格, 单位: 分 - SuperfanshipValidPeriod int `json:"superfanship_valid_period" bson:"superfanship_valid_period"` // 超粉有效期类型, SuperfanshipValidPeriod* - IsSuperfanshipGiveWechat int `json:"is_superfanship_give_wechat" bson:"is_superfanship_give_wechat"` // 是否开启超粉空间赠送微信 0: 不赠送, 1: 赠送 -} - -// 空间动态价格 -type ZoneMomentPrice struct { - Id int64 `json:"id" bson:"_id"` // 动态id - Zid int64 `json:"zid" bson:"zid"` // 空间id - Mid int64 `json:"mid" bson:"mid"` // 主播mid - Price int64 `json:"price" bson:"price"` // 动态价格,单位:分 -} -- 2.41.0 From e986f9ba07d1f80da1a0ee15974067e1b1ea6c43 Mon Sep 17 00:00:00 2001 From: Leufolium Date: Fri, 12 Apr 2024 23:02:55 +0800 Subject: [PATCH 2/3] by Robin at 20240412 --- api/consts/status.go | 5 +++++ app/mix/service/utilservice.go | 11 ++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/api/consts/status.go b/api/consts/status.go index 279b19df..1de819e3 100644 --- a/api/consts/status.go +++ b/api/consts/status.go @@ -214,3 +214,8 @@ const ( IsHeaded_No = 0 //否 IsHeaded_Yes = 1 //是 ) + +// 从未更新的时间跨度 +const ( + DaysElapsedSinceTheLastZonesUpdate_Never = -1 +) diff --git a/app/mix/service/utilservice.go b/app/mix/service/utilservice.go index 769951f4..afea5a8d 100644 --- a/app/mix/service/utilservice.go +++ b/app/mix/service/utilservice.go @@ -763,8 +763,17 @@ func (s *Service) utilGetStreamerExtMapByMids(ctx *gin.Context, mids []int64, op streamerExt.CopyZones(zonesMap[mid]) // 计算空间更新时间距离现在时间跨度 nowTime := time.Now() + lastZoneMomentCt := int64(0) for _, zone := range zonesMap[mid] { - lastZoneMomentCreateDay := util.GetDayStartTimeStamp(time.Unix(util.DerefInt64(zone.LastZoneMomentCt), 0)) + if util.DerefInt64(zone.LastZoneMomentCt) > lastZoneMomentCt { + lastZoneMomentCt = util.DerefInt64(zone.LastZoneMomentCt) + } + } + if lastZoneMomentCt == 0 { + streamerExt.SetIsActiveWithinAWeek(consts.ZoneIsActiveWithinAWeek_No) + streamerExt.SetDaysElapsedSinceTheLastZonesUpdate(consts.DaysElapsedSinceTheLastZonesUpdate_Never) + } else { + lastZoneMomentCreateDay := util.GetDayStartTimeStamp(time.Unix(lastZoneMomentCt, 0)) today := util.GetDayStartTimeStamp(nowTime) daysElapsedSinceTheLastZonesUpdate := (today - lastZoneMomentCreateDay) / int64(86400) // 24 * 60 * 60 = 86400秒 streamerExt.SetDaysElapsedSinceTheLastZonesUpdate(daysElapsedSinceTheLastZonesUpdate) -- 2.41.0 From 0afe2c219331e5da91a54f608d44ecb45c51c022 Mon Sep 17 00:00:00 2001 From: Leufolium Date: Fri, 12 Apr 2024 23:05:46 +0800 Subject: [PATCH 3/3] by Robin at 20240412 --- app/mix/controller/zone_third_partner_api.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/mix/controller/zone_third_partner_api.go b/app/mix/controller/zone_third_partner_api.go index 58fc781c..96da98f8 100644 --- a/app/mix/controller/zone_third_partner_api.go +++ b/app/mix/controller/zone_third_partner_api.go @@ -16,7 +16,7 @@ func ApiCreateZoneThirdPartner(ctx *gin.Context) { ec := service.DefaultService.ApiCreateZoneThirdPartner(ctx, req) if ec != errcode.ErrCodeZoneThirdPartnerSrvOk { logger.Error("ApiCreateZoneThirdPartner fail, req: %v, ec: %v", util.ToJson(req), ec) - ReplyErrorMsg(ctx, "server error") + ReplyErrCodeMsg(ctx, ec) return } -- 2.41.0