This commit is contained in:
lwl0608 2024-03-19 17:41:51 +08:00
parent 9bd1c77f4a
commit acd49e99a2
4 changed files with 255 additions and 12 deletions

View File

@ -548,7 +548,7 @@ func (m *Mysql) Get(ctx *gin.Context, tx *sqlx.Tx, id string) (order *dbstruct.C
// 待添加微信的订单
func (m *Mysql) GetWaitWechatAddCoinOrders(ctx *gin.Context, tx *sqlx.Tx, mid int64, statusList []int32, offset, limit int) (list []*dbstruct.CoinOrder, err error) {
list = make([]*dbstruct.CoinOrder, 0)
sqlStr := fmt.Sprintf("select * from %s where uid=? and product_id=? and order_status in (%s) limit ? offset ?", TableCoinOrder, util.Convert2SqlArr(statusList))
sqlStr := fmt.Sprintf("select * from %s where uid=? and product_id=? and order_status in (%s) order by ct desc limit ? offset ?", TableCoinOrder, util.Convert2SqlArr(statusList))
if tx != nil {
err = tx.SelectContext(ctx, &list, sqlStr, mid, dbstruct.ProductIdContactWechat, limit, offset)
} else {

View File

@ -2452,6 +2452,10 @@ func (v *Vas) RefundOrder(ctx *gin.Context, req *vasproto.RefundOrderReq) error
switch product.Type {
case dbstruct.ProductTypeMoneyMembership:
return v.refundMembership(ctx, order, req)
case dbstruct.ProductTypeCoins:
return v.refundCoins(ctx, order, req)
case dbstruct.ProductTypeMoneyContact:
return v.refundMoneyContactWechat(ctx, order, req)
default:
return errors.New("invalid product")
}
@ -2702,6 +2706,240 @@ func (v *Vas) refundMembership(ctx *gin.Context, order *dbstruct.Order, req *vas
return nil
}
func (v *Vas) refundCoins(ctx *gin.Context, order *dbstruct.Order, req *vasproto.RefundOrderReq) error {
switch order.GetOrderStatus() {
case dbstruct.VasOrderStatusNone, dbstruct.VasOrderStatusInit:
return errors.New("订单还未支付,无法退款")
case dbstruct.VasOrderStatusRefund:
return errors.New("已退款,请勿重复操作")
}
var (
mid = order.GetMid()
orderId = order.GetID()
)
// 开启事务
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.OrderOpLogActionUpdate,
Operator: req.Operator,
Detail: fmt.Sprintf("金币退款"),
BeforeStatus: order.GetOrderStatus(),
AfterStatus: dbstruct.VasOrderStatusRefund,
},
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
}
}()
// 用户的充值退款记录
chargeChList, err := v.store.GetChargeCHList(ctx, tx, orderId)
if err != nil {
logger.Error("GetChargeCHList fail, orderId: %v, err: %v", orderId, err)
return err
}
if len(chargeChList) <= 0 || len(chargeChList) > 1 {
err = errors.New("invalid charge ch list")
logger.Error("invalid charge ch list, orderId: %v, err: %v", orderId, err)
return err
}
chargeCh := chargeChList[0]
chargeChNew := &dbstruct.ConsumeHistory{
Mid: goproto.Int64(chargeCh.GetMid()),
Uid: goproto.Int64(chargeCh.GetUid()),
Did: goproto.String(chargeCh.GetDid()),
Type: goproto.Int32(chargeCh.GetType()),
SType: goproto.Int32(dbstruct.CHSTypeChargeRefundCoins),
TypeId: goproto.String(chargeCh.GetTypeId()),
OrderId: goproto.String(chargeCh.GetOrderId()),
Change: goproto.Int64(-chargeCh.GetChange()),
Ct: goproto.Int64(time.Now().Unix()),
}
err = v.store.CreateConsumeHistory(ctx, tx, chargeChNew)
if err != nil {
logger.Error("CreateConsumeHistory fail, chargeChNew: %v, err: %v", util.ToJson(chargeChNew), err)
return err
}
// 修改订单状态 xx -> 已退款
err = v.store.UpdateOrderStatus(ctx, tx, orderId, order.GetOrderStatus(), dbstruct.VasOrderStatusRefund)
if err != nil {
logger.Error("UpdateOrderStatus fail, err: %v", err)
return err
}
// 扣用户金币
err = v.store.DecCoins(ctx, tx, mid, util.AbsInt64(chargeCh.GetChange()))
if err != nil {
logger.Error("DecCoins fail, mid: %v, change: %v, err: %v", mid, util.AbsInt64(chargeCh.GetChange()), err)
return err
}
// 退款
switch order.GetPayType() {
case vasproto.PayTypeAlipay, vasproto.PayTypeAlipayH5:
alipayCli := alipaycli.GetAlipayClientByAppId(order.GetOid3())
resp, err := alipayCli.RefundOne(ctx, &alipaycli.RefundOneParam{
OutTradeNo: orderId,
RefundAmount: order.GetPayAmount(),
RefundReason: "发货A退款",
})
if err != nil {
logger.Error("alipayCli.RefundOne fail, orderId: %v, resp: %v, err: %v", orderId, util.ToJson(resp), err)
return err
}
case vasproto.PayTypeWxpayNative, vasproto.PayTypeWxpayJsapi, vasproto.PayTypeWxpayH5:
wxpayCli := wxpaycli.GetDefaultWxpayClient()
resp, err := wxpayCli.RefundOne(ctx, &wxpaycli.RefundOneParam{
OutTradeNo: orderId,
RefundAmount: order.GetPayAmount(),
RefundReason: "发货A退款",
})
if err != nil {
logger.Error("wxpayCli.RefundOne fail, orderId: %v, resp: %v, err: %v", orderId, util.ToJson(resp), err)
return err
}
}
return nil
}
func (v *Vas) refundMoneyContactWechat(ctx *gin.Context, order *dbstruct.Order, req *vasproto.RefundOrderReq) error {
switch order.GetOrderStatus() {
case dbstruct.VasOrderStatusNone, dbstruct.VasOrderStatusInit:
return errors.New("订单还未支付,无法退款")
case dbstruct.VasOrderStatusRefund:
return errors.New("已退款,请勿重复操作")
}
var (
mid = order.GetMid()
orderId = order.GetID()
)
// 开启事务
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.OrderOpLogActionUpdate,
Operator: req.Operator,
Detail: fmt.Sprintf("微信退款"),
BeforeStatus: order.GetOrderStatus(),
AfterStatus: dbstruct.VasOrderStatusRefund,
},
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
}
}()
// 用户的充值退款记录
chargeChList, err := v.store.GetChargeCHList(ctx, tx, orderId)
if err != nil {
logger.Error("GetChargeCHList fail, orderId: %v, err: %v", orderId, err)
return err
}
if len(chargeChList) <= 0 || len(chargeChList) > 1 {
err = errors.New("invalid charge ch list")
logger.Error("invalid charge ch list, orderId: %v, err: %v", orderId, err)
return err
}
chargeCh := chargeChList[0]
chargeChNew := &dbstruct.ConsumeHistory{
Mid: goproto.Int64(chargeCh.GetMid()),
Uid: goproto.Int64(chargeCh.GetUid()),
Did: goproto.String(chargeCh.GetDid()),
Type: goproto.Int32(chargeCh.GetType()),
SType: goproto.Int32(dbstruct.CHSTypeChargeRefundContactWechat),
TypeId: goproto.String(chargeCh.GetTypeId()),
OrderId: goproto.String(chargeCh.GetOrderId()),
Change: goproto.Int64(-chargeCh.GetChange()),
Ct: goproto.Int64(time.Now().Unix()),
}
err = v.store.CreateConsumeHistory(ctx, tx, chargeChNew)
if err != nil {
logger.Error("CreateConsumeHistory fail, chargeChNew: %v, err: %v", util.ToJson(chargeChNew), err)
return err
}
// 修改订单状态 xx -> 已退款
err = v.store.UpdateOrderStatus(ctx, tx, orderId, order.GetOrderStatus(), dbstruct.VasOrderStatusRefund)
if err != nil {
logger.Error("UpdateOrderStatus fail, err: %v", err)
return err
}
// 扣用户金币
err = v.store.DecCoins(ctx, tx, mid, util.AbsInt64(chargeCh.GetChange()))
if err != nil {
logger.Error("DecCoins fail, mid: %v, change: %v, err: %v", mid, util.AbsInt64(chargeCh.GetChange()), err)
return err
}
// 退款
switch order.GetPayType() {
case vasproto.PayTypeAlipay, vasproto.PayTypeAlipayH5:
alipayCli := alipaycli.GetAlipayClientByAppId(order.GetOid3())
resp, err := alipayCli.RefundOne(ctx, &alipaycli.RefundOneParam{
OutTradeNo: orderId,
RefundAmount: order.GetPayAmount(),
RefundReason: "发货A退款",
})
if err != nil {
logger.Error("alipayCli.RefundOne fail, orderId: %v, resp: %v, err: %v", orderId, util.ToJson(resp), err)
return err
}
case vasproto.PayTypeWxpayNative, vasproto.PayTypeWxpayJsapi, vasproto.PayTypeWxpayH5:
wxpayCli := wxpaycli.GetDefaultWxpayClient()
resp, err := wxpayCli.RefundOne(ctx, &wxpaycli.RefundOneParam{
OutTradeNo: orderId,
RefundAmount: order.GetPayAmount(),
RefundReason: "发货A退款",
})
if err != nil {
logger.Error("wxpayCli.RefundOne fail, orderId: %v, resp: %v, err: %v", orderId, util.ToJson(resp), err)
return err
}
}
return nil
}
// 金币订单退款
func (v *Vas) RefundCoinOrder(ctx *gin.Context, req *vasproto.RefundCoinOrderReq) error {
// 获取订单
@ -2715,13 +2953,13 @@ func (v *Vas) RefundCoinOrder(ctx *gin.Context, req *vasproto.RefundCoinOrderReq
switch order.GetProductId() {
case dbstruct.ProductIdContactWechat:
return v.refundContactWechat(ctx, order, req)
return v.refundCoinContactWechat(ctx, order, req)
default:
return errors.New("invalid product")
}
}
func (v *Vas) refundContactWechat(ctx *gin.Context, order *dbstruct.CoinOrder, req *vasproto.RefundCoinOrderReq) error {
func (v *Vas) refundCoinContactWechat(ctx *gin.Context, order *dbstruct.CoinOrder, req *vasproto.RefundCoinOrderReq) error {
switch order.GetOrderStatus() {
case dbstruct.VasCoinOrderStatusNone, dbstruct.VasOrderStatusInit:
return errors.New("订单还未成功支付,无法退款")
@ -2749,7 +2987,7 @@ func (v *Vas) refundContactWechat(ctx *gin.Context, order *dbstruct.CoinOrder, r
OrderId: orderId,
Action: dbstruct.OrderOpLogActionUpdate,
Operator: req.Operator,
Detail: fmt.Sprintf("微信联系方式"),
Detail: fmt.Sprintf("微信联系方式退款"),
BeforeStatus: order.GetOrderStatus(),
AfterStatus: dbstruct.VasCoinOrderStatusRefund,
},

View File

@ -282,16 +282,20 @@ func (s *Service) chListCharge(ctx *gin.Context, chList []*dbstruct.ConsumeHisto
case dbstruct.CHSTypeChargeOp:
item.Desc = "运营充值"
item.Change = changeMark + fmt.Sprintf("%d金币", chDB.GetChange())
case dbstruct.CHSTypeChargeRefund:
item.Desc = "退款"
item.Change = changeMark + fmt.Sprintf("%d金币", chDB.GetChange())
case dbstruct.CHSTypeChargeRefundCoins:
item.Desc = "金币退款"
item.Change = fmt.Sprintf("%d金币", chDB.GetChange())
case dbstruct.CHSTypeChargeRefundMembership:
item.Desc = "会员退款"
item.Change = fmt.Sprintf("%d金币", chDB.GetChange())
case dbstruct.CHSTypeChargeMembership:
item.Desc = "会员充值"
item.Change = changeMark + fmt.Sprintf("%d金币", chDB.GetChange())
case dbstruct.CHSTypeChargeRefundContactWechat:
item.Desc = "微信联系方式退款"
item.Change = fmt.Sprintf("%d金币", chDB.GetChange())
}
list = append(list, item)
}
return

View File

@ -495,11 +495,12 @@ const (
CHSTypeCostMembership = 10003 // 消费明细,会员资格解锁(伪金币记录,会员资格解锁中间无转金币过程)
CHSTypeCostRefundMembership = 10004 // 消费明细,会员资格解锁退款(伪金币记录,会员资格解锁中间无转金币过程)
CHSTypeChargeUser = 20001 // 充值明细,用户自己冲
CHSTypeChargeOp = 20002 // 充值明细OP充值
CHSTypeChargeRefund = 20003 // 充值明细,现金退款
CHSTypeChargeRefundMembership = 20004 // 充值明细,会员退款
CHSTypeChargeMembership = 20005 // 充值明细,会员充值
CHSTypeChargeUser = 20001 // 充值明细,用户自己冲
CHSTypeChargeOp = 20002 // 充值明细OP充值
CHSTypeChargeRefundCoins = 20003 // 充值明细,金币退款
CHSTypeChargeRefundMembership = 20004 // 充值明细,会员退款
CHSTypeChargeMembership = 20005 // 充值明细,会员充值
CHSTypeChargeRefundContactWechat = 20006 // 充值明细,微信金币退款
CHSTypeIncomeContact = 30001 // 收入明细,联系方式
CHSTypeIncomeInvite = 30002 // 收入明细,邀请分成