diff --git a/app/mix/dao/mysql.go b/app/mix/dao/mysql.go index cd8f6e55..052699bc 100644 --- a/app/mix/dao/mysql.go +++ b/app/mix/dao/mysql.go @@ -385,6 +385,23 @@ func (m *Mysql) IncWithdrawDiamonds(ctx *gin.Context, tx *sqlx.Tx, mid, dias int return err } +// 扣钻石 +func (m *Mysql) DecDiamonds(ctx *gin.Context, tx *sqlx.Tx, mid, dias int64) error { + var err error + sqlStr := "update " + TableWallet + " set diamonds=diamonds-? where id=?" + if tx != nil { + _, err = tx.ExecContext(ctx, sqlStr, dias, mid) + } else { + db := m.getDBVas() + _, err = db.ExecContext(ctx, sqlStr, dias, mid) + } + if err != nil { + logger.Error("DecDiamonds fail, mid: %v, dias: %v, err: %v", mid, dias, err) + return err + } + return err +} + // 扣提现钻石 func (m *Mysql) DecWithdrawDiamonds(ctx *gin.Context, tx *sqlx.Tx, mid, dias int64) error { var err error diff --git a/app/mix/service/logic/vas.go b/app/mix/service/logic/vas.go index bafbec39..4b9f8948 100644 --- a/app/mix/service/logic/vas.go +++ b/app/mix/service/logic/vas.go @@ -2276,7 +2276,6 @@ func (v *Vas) dealOneMembershipOrder(ctx *gin.Context, tx *sqlx.Tx, order *dbstr // 解锁会员资格 func (v *Vas) UnlockMembership(ctx *gin.Context, mid int64, product *dbstruct.Product, order *dbstruct.Order, wallet *dbstruct.Wallet) (orderId string, err error) { - var ( did = util.DerefString(order.Did) productId = product.Id @@ -2425,3 +2424,148 @@ func (v *Vas) UnlockMembership(ctx *gin.Context, mid int64, product *dbstruct.Pr } return } + +// 订单退款,只退充值 +func (v *Vas) RefundOrder(ctx *gin.Context, orderId string) error { + order, err := v.store.GetOrderById(ctx, nil, orderId) + if err != nil { + return err + } + if order == nil { + return errs.ErrVasOrderNotExists + } + + switch order.GetProductId() { + case dbstruct.ProductIdMembership: + + } + + return nil +} + +func (v *Vas) refundMembership(ctx *gin.Context, order *dbstruct.Order) error { + switch order.GetOrderStatus() { + case dbstruct.VasOrderStatusNone, dbstruct.VasOrderStatusInit: + return errors.New("订单还未支付,无法退款") + case dbstruct.VasOrderStatusRefund: + return errors.New("已退款,请勿重复操作") + } + + var ( + orderId = order.GetID() + isFinish = order.GetOrderStatus() == dbstruct.VasOrderStatusFinish + ) + + // 开启事务 + tx, err := v.store.VasBegin(ctx) + if err != nil { + logger.Error("vas begin fail, err: %v", err) + return err + } + defer func() { + if order != nil { + _ = v.AddOplogOrder( + ctx, + &dbstruct.OplogOrder{ + OrderId: orderId, + Action: dbstruct.OrderOpLogActionAdd, + Operator: req.Operator, + Detail: fmt.Sprintf("后台充值%d金币", coins), + BeforeStatus: dbstruct.VasOrderStatusNone, + AfterStatus: util.DerefInt32(order.OrderStatus), + }, + err, + ) + } + + if err != nil { + logger.Error("global err, req: %v, err: %v", util.ToJson(req), err) + } + errTx := v.store.DealTxCR(tx, err) + if errTx != nil { + logger.Error("DealTxCR fail, err: %v", errTx) + return + } + }() + + // 修改订单状态 xx -> 已退款 + err = v.store.UpdateOrderStatus(ctx, tx, orderId, order.GetOrderStatus(), dbstruct.VasOrderStatusRefund) + if err != nil { + return err + } + + // 获取收入记录 + chListTmp, err := v.store.GetIncomeCHList(ctx, tx, orderId) + if err != nil { + return err + } + chList := make([]*dbstruct.ConsumeHistory, 0) + for _, ch := range chListTmp { + if ch.GetMid() == common.OfficialMid { + continue + } + chList = append(chList, ch) + } + if len(chList) > 1 { + err = errors.New("收入记录错误,请找开发同学排查") + return err + } + + // 有分成的情况 + if len(chList) > 0 { + ch := chList[0] + uid := ch.GetUid() + if uid <= 0 { + err = errors.New("收入uid错误") + logger.Error("invalid uid: %v", uid) + return err + } + + // 主播钱包 + wallet, err := v.store.GetWalletForUpdate(ctx, tx, uid) + if err != nil { + return err + } + + // 扣主播金币 + change := ch.GetChange() + err = v.store.DecDiamonds(ctx, tx, uid, change) + if err != nil { + return err + } + + // 扣金币的收入记录 + chNew := &dbstruct.ConsumeHistory{ + Mid: goproto.Int64(uid), + Uid: goproto.Int64(ch.GetMid()), + Did: goproto.String(ch.GetDid()), + Type: goproto.Int32(dbstruct.CHTypeIncome), + SType: goproto.Int32(dbstruct.CHSTypeIncomeRefund), + TypeId: goproto.String(ch.GetTypeId()), + OrderId: goproto.String(ch.GetOrderId()), + Change: goproto.Int64(-change), + Before: goproto.Int64(wallet.GetDiamonds()), + After: goproto.Int64(wallet.GetDiamonds() - change), + Ct: goproto.Int64(time.Now().Unix()), + } + err = v.store.CreateConsumeHistory(ctx, tx, chNew) + if err != nil { + logger.Error("CreateConsumeHistory fail, ch: %v, err: %v", util.ToJson(chNew), err) + return err + } + + // 如果已结算,扣提现钻石 + if isFinish { + // 扣提现钻石 + err = v.store.DecWithdrawDiamonds(ctx, tx, uid, change) + if err != nil { + logger.Error("DecWithdrawDiamonds fail, uid: %v, change: %v, err: %v", uid, change, err) + return err + } + + } + } + + // 扣主播金币 + v.store.DecDiamonds(ctx, tx) +} diff --git a/dbstruct/vas_mysql.go b/dbstruct/vas_mysql.go index adc77539..f7aaa04e 100644 --- a/dbstruct/vas_mysql.go +++ b/dbstruct/vas_mysql.go @@ -500,6 +500,7 @@ const ( CHSTypeIncomeContact = 30001 // 收入明细,联系方式 CHSTypeIncomeInvite = 30002 // 收入明细,邀请分成 + CHSTypeIncomeRefund = 30003 // 收入明细,退款 CHSTypeWithdrawDiamondAuto = 40001 // 自动提现明细 )