diff --git a/api/proto/vas/proto/op.go b/api/proto/vas/proto/op.go index d98e89b1..b09e86c8 100644 --- a/api/proto/vas/proto/op.go +++ b/api/proto/vas/proto/op.go @@ -38,3 +38,7 @@ type OpCoinOrderListData struct { //Offset int `json:"offset"` //More int `json:"more"` } + +type DealOneCoinOrderReq struct { + CoinOrderId string `json:"coin_order_id"` +} diff --git a/app/mix/controller/init.go b/app/mix/controller/init.go index 661d50dd..d979d6f7 100644 --- a/app/mix/controller/init.go +++ b/app/mix/controller/init.go @@ -214,6 +214,7 @@ func Init(r *gin.Engine) { vasPayGroup.POST("withdraw_page", middleware.JSONParamValidator(vasproto.WithdrawPageReq{}), WithdrawPage) vasPayGroup.POST("withdraw_send_verifycode", middleware.JSONParamValidator(vasproto.WithdrawSendVerifycodeReq{}), WithdrawSendVerifycode) vasPayGroup.POST("withdraw_apply", middleware.JSONParamValidator(vasproto.WithdrawApplyReq{}), WithdrawApply) + vasPayGroup.POST("deal_one_coin_order", middleware.JSONParamValidator(vasproto.DealOneCoinOrderReq{}), DealOneCoinOrder) extVasPayGroup := r.Group("/ext/vas") extVasPayGroup.POST("alipay_callback", AlipayCallback) diff --git a/app/mix/controller/vas.go b/app/mix/controller/vas.go index 763c2294..123eb7df 100644 --- a/app/mix/controller/vas.go +++ b/app/mix/controller/vas.go @@ -257,3 +257,15 @@ func WithdrawApply(ctx *gin.Context) { } ReplyOk(ctx, nil) } + +// 处理一个订单 +func DealOneCoinOrder(ctx *gin.Context) { + req := ctx.MustGet("client_req").(*vasproto.DealOneCoinOrderReq) + ec := service.DefaultService.DealOneCoinOrder(ctx, req) + if ec != errcode.ErrCodeVasSrvOk { + logger.Error("DealOneCoinOrder fail, req: %v, ec: %v", util.ToJson(req), ec) + ReplyErrCodeMsg(ctx, ec) + return + } + ReplyOk(ctx, nil) +} diff --git a/app/mix/dao/mysql.go b/app/mix/dao/mysql.go index a7e78fc7..b3cd6528 100644 --- a/app/mix/dao/mysql.go +++ b/app/mix/dao/mysql.go @@ -71,6 +71,7 @@ const ( TableConsumeHistoryWithdraw = "vas_ch_withdraw" // 提现明细 TableVasUserUnlock = "vas_user_unlock" // 用增解锁 TableWithdrawOrder = "vas_withdraw_order" // 提现订单表 + TableWithdrawDiamondsHis = "vas_withdraw_diamonds_his" // 提现金币历史 TableVasUserMembershipUnlock = "vas_user_membership_unlock" // 会员资格解锁 ) @@ -344,6 +345,23 @@ func (m *Mysql) IncDiamonds(ctx *gin.Context, tx *sqlx.Tx, mid, dias int64) erro return err } +// 增加提现钻石 +func (m *Mysql) IncWithdrawDiamonds(ctx *gin.Context, tx *sqlx.Tx, mid, dias int64) error { + var err error + sqlStr := "update " + TableWallet + " set withdraw_diamonds=withdraw_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("IncWithdrawDiamonds 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 @@ -428,6 +446,23 @@ func (m *Mysql) GetCoinOrders(ctx *gin.Context, tx *sqlx.Tx, mid, st, et int64) return } +// 更新订单状态 +func (m *Mysql) UpdateCoinOrderStatus(ctx *gin.Context, tx *sqlx.Tx, orderId string, status int32) error { + var err error + sqlStr := "update " + TableCoinOrder + " set order_status=?,ut=? where id=?" + if tx != nil { + _, err = tx.ExecContext(ctx, sqlStr, status, time.Now().Unix(), orderId) + } else { + db := m.getDBVas() + _, err = db.ExecContext(ctx, sqlStr, status, time.Now().Unix(), orderId) + } + if err != nil { + logger.Error("UpdateCoinOrderStatus fail, orderId: %v, status: %v, err: %v", orderId, status, err) + return err + } + return err +} + // 获取金币订单 for update func (m *Mysql) GetCoinOrderByIdForUpdate(ctx *gin.Context, tx *sqlx.Tx, id string) (order *dbstruct.CoinOrder, err error) { var tmpOrder dbstruct.CoinOrder @@ -777,3 +812,26 @@ func (m *Mysql) GetWithdrawOrdersByMid(ctx *gin.Context, tx *sqlx.Tx, mid, st, e } return } + +// 创建提现订单 +func (m *Mysql) CreateWithdrawDiamondsHis(ctx *gin.Context, tx *sqlx.Tx, h *dbstruct.WithdrawDiamondsHis) error { + var err error + sqlStr := "insert into " + TableWithdrawDiamondsHis + + " (mid, income_ch_id, order_id, ct, before_withdraw_diamonds, after_withdraw_diamonds, `change`) " + + " values (?,?,?,?,?,?,?) " + if tx != nil { + _, err = tx.ExecContext(ctx, sqlStr, + h.GetMid(), h.GetIncomeChId(), h.GetOrderId(), h.GetCt(), h.GetBeforeWithdrawDiamonds(), h.GetAfterWithdrawDiamonds(), h.GetChange(), + ) + } else { + db := m.getDBVas() + _, err = db.ExecContext(ctx, sqlStr, + h.GetMid(), h.GetIncomeChId(), h.GetOrderId(), h.GetCt(), h.GetBeforeWithdrawDiamonds(), h.GetAfterWithdrawDiamonds(), h.GetChange(), + ) + } + if err != nil { + logger.Error("CreateWithdrawDiamondsHis fail, h: %v, err: %v", util.ToJson(h), err) + return err + } + return err +} diff --git a/app/mix/service/logic/vas.go b/app/mix/service/logic/vas.go index 603ce6c4..2e14e394 100644 --- a/app/mix/service/logic/vas.go +++ b/app/mix/service/logic/vas.go @@ -1940,13 +1940,25 @@ func (v *Vas) WithdrawApply(ctx *gin.Context, req *vasproto.WithdrawApplyReq) (t } // 结算订单 -func (v *Vas) DealOneCoinOrder(ctx *gin.Context, coinOrder *dbstruct.CoinOrder) { +func (v *Vas) DealOneCoinOrder(ctx *gin.Context, coinOrderId string) (err error) { + coinOrder, err := v.store.GetCoinOrderById(ctx, nil, coinOrderId) + if err != nil { + logger.Error("GetCoinOrderById fail, id: %v, err: %v", coinOrderId, err) + return + } + if coinOrder == nil { + err = errs.ErrVasOrderNotExists + logger.Error("GetCoinOrderById fail nil, id: %v, err: %v", coinOrderId, err) + return + } + // 判断时间,小于7天不处理 if time.Now().Unix()-coinOrder.GetCt() < 7*86400 { logger.Info("DealOneCoinOrder ct fail, coinOrder: %v", coinOrder.ToString()) return } if coinOrder.GetOrderStatus() >= dbstruct.VasCoinOrderStatusFinish { + err = errors.New("repeat deal") logger.Info("DealOneCoinOrder status fail, coinOrder: %v", coinOrder.ToString()) return } @@ -1969,15 +1981,59 @@ func (v *Vas) DealOneCoinOrder(ctx *gin.Context, coinOrder *dbstruct.CoinOrder) }() // 把金币订单对应的收入记录拿出来 - //chList, err := v.store.GetIncomeCHList(ctx, tx, coinOrder.GetID()) - //if err != nil { - // logger.Error("GetIncomeCHList fail, orderId: %v, err: %v", coinOrder.GetID(), err) - // return - //} + chList, err := v.store.GetIncomeCHList(ctx, tx, coinOrder.GetID()) + if err != nil { + logger.Error("GetIncomeCHList fail, orderId: %v, err: %v", coinOrder.GetID(), err) + return + } - // 更新钱包 + // 处理 + for _, ch := range chList { + if ch.GetMid() == common.OfficialMid { + continue + } + + // 获取钱包 + wallet, errIn := v.store.GetWalletForUpdate(ctx, tx, ch.GetMid()) + if errIn != nil { + logger.Error("GetWalletForUpdate fail, mid: %v, err: %v", ch.GetMid(), errIn) + err = errIn + return + } + + // 添加记录 + h := &dbstruct.WithdrawDiamondsHis{ + Mid: goproto.Int64(ch.GetMid()), + IncomeChId: goproto.Int64(ch.GetId()), + OrderId: goproto.String(ch.GetOrderId()), + Ct: goproto.Int64(time.Now().Unix()), + BeforeWithdrawDiamonds: goproto.Int64(wallet.GetWithdrawDiamonds()), + AfterWithdrawDiamonds: goproto.Int64(wallet.GetWithdrawDiamonds() + ch.GetChange()), + Change: goproto.Int64(ch.GetChange()), + } + errIn = v.store.CreateWithdrawDiamondsHis(ctx, tx, h) + if errIn != nil { + logger.Error("CreateWithdrawDiamondsHis fail, mid: %v, err: %v", ch.GetMid(), errIn) + err = errIn + return + } + + // 更新钱包 + errIn = v.store.IncWithdrawDiamonds(ctx, tx, ch.GetMid(), ch.GetChange()) + if errIn != nil { + logger.Error("IncWithdrawDiamonds fail, mid: %v, change: %v, err: %v", ch.GetMid(), ch.GetChange(), errIn) + err = errIn + return + } + } // 更新订单状态 + err = v.store.UpdateCoinOrderStatus(ctx, tx, coinOrder.GetID(), dbstruct.VasCoinOrderStatusFinish) + if err != nil { + logger.Error("UpdateCoinOrderStatus fail, orderId: %v, err: %v", coinOrder.GetID(), err) + return + } + return } // 解锁会员资格 @@ -2038,7 +2094,7 @@ func (v *Vas) UnlockMembership(ctx *gin.Context, mid int64, product *dbstruct.Pr // 加钻石 var ( - TotalDias = int64(float64(product.RealPrice) * 0.01) + TotalDias = int64(float64(product.RealPrice) * 0.1) InviterDias = int64(0) OfficialDias = int64(0) ) diff --git a/app/mix/service/vasservice.go b/app/mix/service/vasservice.go index 7e98c9d5..66455888 100644 --- a/app/mix/service/vasservice.go +++ b/app/mix/service/vasservice.go @@ -494,3 +494,13 @@ func (s *Service) OpCoinOrderList(ctx *gin.Context, req *vasproto.OpCoinOrderLis } return } + +func (s *Service) DealOneCoinOrder(ctx *gin.Context, req *vasproto.DealOneCoinOrderReq) (ec errcode.ErrCode) { + err := _DefaultVas.DealOneCoinOrder(ctx, req.CoinOrderId) + ec, err = errs.DealVasErr(err) + if err != nil { + logger.Error("DealOneCoinOrder fail, req: %v, err: %v", util.ToJson(req), err) + return + } + return +} diff --git a/dbstruct/vas.sql b/dbstruct/vas.sql index ea40cdaa..ecc858c3 100644 --- a/dbstruct/vas.sql +++ b/dbstruct/vas.sql @@ -139,6 +139,22 @@ CREATE INDEX ix_mid_applytime ON vas_withdraw_order (mid, apply_time); +CREATE TABLE `vas_withdraw_diamonds_his` +( + `id` bigint AUTO_INCREMENT COMMENT 'id', + `mid` bigint NOT NULL COMMENT '用户id', + `income_ch_id` bigint NOT NULL COMMENT '收入明细中的id', + `order_id` varchar(128) NOT NULL COMMENT '金币订单id', + `ct` bigint DEFAULT NULL COMMENT '时间', + `before_withdraw_diamonds` bigint DEFAULT NULL COMMENT 'before', + `after_withdraw_diamonds` bigint DEFAULT NULL COMMENT 'after', + `change` bigint DEFAULT NULL COMMENT '增加的可提现钻石数', + PRIMARY KEY (`id`) +); +CREATE INDEX ix_mid ON vas_withdraw_diamonds_his (mid); +CREATE INDEX ix_ct ON vas_withdraw_diamonds_his (ct); +CREATE INDEX ix_order_id ON vas_withdraw_diamonds_his (order_id); +CREATE INDEX ix_chid ON vas_withdraw_diamonds_his (income_ch_id); CREATE TABLE `vas_user_membership_unlock` ( `id` bigint AUTO_INCREMENT COMMENT 'id', diff --git a/dbstruct/vas_mysql.go b/dbstruct/vas_mysql.go index c16bb628..df488789 100644 --- a/dbstruct/vas_mysql.go +++ b/dbstruct/vas_mysql.go @@ -519,6 +519,13 @@ type ConsumeHistory struct { Ct *int64 `json:"ct" db:"ct"` } +func (p *ConsumeHistory) GetId() int64 { + if p != nil && p.Id != nil { + return *p.Id + } + return 0 +} + func (p *ConsumeHistory) GetMid() int64 { if p != nil && p.Mid != nil { return *p.Mid @@ -787,6 +794,66 @@ func (p *WithdrawOrder) GetOpTime() int64 { return 0 } +// 处理记录 +type WithdrawDiamondsHis struct { + Mid *int64 `json:"mid" bson:"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"` + BeforeWithdrawDiamonds *int64 `json:"before_withdraw_diamonds" db:"before_withdraw_diamonds"` + AfterWithdrawDiamonds *int64 `json:"after_withdraw_diamonds" db:"after_withdraw_diamonds"` + Change *int64 `json:"change" db:"change"` +} + +func (p *WithdrawDiamondsHis) GetMid() int64 { + if p != nil && p.Mid != nil { + return *p.Mid + } + return 0 +} + +func (p *WithdrawDiamondsHis) GetIncomeChId() int64 { + if p != nil && p.IncomeChId != nil { + return *p.IncomeChId + } + return 0 +} + +func (p *WithdrawDiamondsHis) GetOrderId() string { + if p != nil && p.OrderId != nil { + return *p.OrderId + } + return "" +} + +func (p *WithdrawDiamondsHis) GetCt() int64 { + if p != nil && p.Ct != nil { + return *p.Ct + } + return 0 +} + +func (p *WithdrawDiamondsHis) GetBeforeWithdrawDiamonds() int64 { + if p != nil && p.BeforeWithdrawDiamonds != nil { + return *p.BeforeWithdrawDiamonds + } + return 0 +} + +func (p *WithdrawDiamondsHis) GetAfterWithdrawDiamonds() int64 { + if p != nil && p.AfterWithdrawDiamonds != nil { + return *p.AfterWithdrawDiamonds + } + return 0 +} + +func (p *WithdrawDiamondsHis) GetChange() int64 { + if p != nil && p.Change != nil { + return *p.Change + } + return 0 +} + type UserVasMembershipUnlock struct { Id *int64 `json:"id" db:"id"` Mid *int64 `json:"mid" db:"mid"`