feat: update metas
This commit is contained in:
@@ -271,15 +271,20 @@ func (ctl *posts) Buy(ctx fiber.Ctx, id int64, user *model.Users) (*wechat.JSAPI
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, " failed to get post: %d", id)
|
return nil, errors.Wrapf(err, " failed to get post: %d", id)
|
||||||
}
|
}
|
||||||
|
payPrice := post.Price * int64(post.Discount) / 100
|
||||||
|
|
||||||
// create order
|
|
||||||
order, err := models.Orders.Create(ctx.Context(), user.ID, post.ID)
|
order, err := models.Orders.Create(ctx.Context(), user.ID, post.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "订单创建失败")
|
return nil, errors.Wrap(err, "订单创建失败")
|
||||||
}
|
}
|
||||||
|
|
||||||
payPrice := post.Price * int64(post.Discount) / 100
|
|
||||||
if user.Balance >= payPrice {
|
if user.Balance >= payPrice {
|
||||||
|
if err := models.Orders.SetMeta(ctx.Context(), order.ID, func(om fields.OrderMeta) fields.OrderMeta {
|
||||||
|
om.CostBalance = payPrice
|
||||||
|
return om
|
||||||
|
}); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "订单创建失败")
|
||||||
|
}
|
||||||
|
|
||||||
if err := ctl.job.Add(&jobs.BalancePayNotify{OrderNo: order.OrderNo}); err != nil {
|
if err := ctl.job.Add(&jobs.BalancePayNotify{OrderNo: order.OrderNo}); err != nil {
|
||||||
log.Errorf("add job error:%v", err)
|
log.Errorf("add job error:%v", err)
|
||||||
@@ -289,14 +294,15 @@ func (ctl *posts) Buy(ctx fiber.Ctx, id int64, user *model.Users) (*wechat.JSAPI
|
|||||||
return &wechat.JSAPIPayParams{
|
return &wechat.JSAPIPayParams{
|
||||||
AppId: "balance",
|
AppId: "balance",
|
||||||
}, nil
|
}, nil
|
||||||
} else {
|
|
||||||
payPrice = payPrice - user.Balance
|
|
||||||
err = models.Users.SetBalance(ctx.Context(), user.ID, 0)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "余额支付失败")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
payPrice = payPrice - user.Balance
|
||||||
|
if err := models.Orders.SetMeta(ctx.Context(), order.ID, func(om fields.OrderMeta) fields.OrderMeta {
|
||||||
|
om.CostBalance = user.Balance
|
||||||
|
return om
|
||||||
|
}); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "订单创建失败")
|
||||||
|
}
|
||||||
prePayResp, err := ctl.wepay.V3TransactionJsapi(ctx.Context(), func(bm *wepay.BodyMap) {
|
prePayResp, err := ctl.wepay.V3TransactionJsapi(ctx.Context(), func(bm *wepay.BodyMap) {
|
||||||
bm.
|
bm.
|
||||||
Expire(30 * time.Minute).
|
Expire(30 * time.Minute).
|
||||||
|
|||||||
@@ -68,8 +68,11 @@ func (w *BalancePayNotifyWorker) Work(ctx context.Context, job *Job[BalancePayNo
|
|||||||
order.Status = fields.OrderStatusCompleted
|
order.Status = fields.OrderStatusCompleted
|
||||||
|
|
||||||
meta := order.Meta.Data
|
meta := order.Meta.Data
|
||||||
meta.CostBalance = payPrice
|
|
||||||
order.Meta = fields.ToJson(meta)
|
if user.Balance-meta.CostBalance < 0 {
|
||||||
|
log.Errorf("User %d balance is not enough, current balance: %d, cost: %d", user.ID, user.Balance, payPrice)
|
||||||
|
return JobCancel(fmt.Errorf("User %d balance is not enough, current balance: %d, cost: %d", user.ID, user.Balance, payPrice))
|
||||||
|
}
|
||||||
|
|
||||||
log.Infof("Updated order details: %+v", order)
|
log.Infof("Updated order details: %+v", order)
|
||||||
tx, err := models.Transaction(ctx)
|
tx, err := models.Transaction(ctx)
|
||||||
|
|||||||
@@ -64,8 +64,13 @@ func (w *WechatPayNotifyWorker) Work(ctx context.Context, job *Job[WechatPayNoti
|
|||||||
return JobCancel(fmt.Errorf("Order already paid, currently status: %d", order.Status))
|
return JobCancel(fmt.Errorf("Order already paid, currently status: %d", order.Status))
|
||||||
}
|
}
|
||||||
|
|
||||||
needToPay := order.Price * int64(order.Discount) / 100
|
user, err := models.Users.GetByID(context.Background(), order.UserID)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "get user by id(%d) failed", order.UserID)
|
||||||
|
}
|
||||||
|
meta := order.Meta.Data
|
||||||
|
|
||||||
|
needToPay := order.Price*int64(order.Discount)/100 - meta.CostBalance
|
||||||
if int64(notify.Amount.Total) != needToPay {
|
if int64(notify.Amount.Total) != needToPay {
|
||||||
log.Errorf("Order %s amount mismatch: expected %d, got %d", job.Args.Notify.OutTradeNo, needToPay, notify.Amount.Total)
|
log.Errorf("Order %s amount mismatch: expected %d, got %d", job.Args.Notify.OutTradeNo, needToPay, notify.Amount.Total)
|
||||||
return fmt.Errorf("amount mismatch for order %s", job.Args.Notify.OutTradeNo)
|
return fmt.Errorf("amount mismatch for order %s", job.Args.Notify.OutTradeNo)
|
||||||
@@ -75,9 +80,9 @@ func (w *WechatPayNotifyWorker) Work(ctx context.Context, job *Job[WechatPayNoti
|
|||||||
order.Currency = notify.Amount.Currency
|
order.Currency = notify.Amount.Currency
|
||||||
order.PaymentMethod = notify.TradeType
|
order.PaymentMethod = notify.TradeType
|
||||||
order.Status = fields.OrderStatusCompleted
|
order.Status = fields.OrderStatusCompleted
|
||||||
order.Meta = fields.ToJson(fields.OrderMeta{
|
|
||||||
PayNotify: notify,
|
meta.PayNotify = notify
|
||||||
})
|
order.Meta = fields.ToJson(meta)
|
||||||
|
|
||||||
log.Infof("Updated order details: %+v", order)
|
log.Infof("Updated order details: %+v", order)
|
||||||
tx, err := models.Transaction(ctx)
|
tx, err := models.Transaction(ctx)
|
||||||
@@ -86,6 +91,13 @@ func (w *WechatPayNotifyWorker) Work(ctx context.Context, job *Job[WechatPayNoti
|
|||||||
}
|
}
|
||||||
defer tx.Rollback()
|
defer tx.Rollback()
|
||||||
|
|
||||||
|
// update user balance
|
||||||
|
err = models.Users.SetBalance(ctx, user.ID, user.Balance-meta.CostBalance)
|
||||||
|
if err != nil {
|
||||||
|
log.WithError(err).Error("SetBalance error")
|
||||||
|
return JobCancel(errors.Wrap(err, "set user balance failed"))
|
||||||
|
}
|
||||||
|
|
||||||
if err := models.Users.BuyPosts(context.Background(), order.UserID, order.PostID, order.Price); err != nil {
|
if err := models.Users.BuyPosts(context.Background(), order.UserID, order.PostID, order.Price); err != nil {
|
||||||
log.Errorf("BuyPosts error:%v", err)
|
log.Errorf("BuyPosts error:%v", err)
|
||||||
return errors.Wrap(err, "BuyPosts error")
|
return errors.Wrap(err, "BuyPosts error")
|
||||||
|
|||||||
@@ -186,6 +186,29 @@ func (m *ordersModel) Create(ctx context.Context, userId, postId int64) (*model.
|
|||||||
return model, nil
|
return model, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *ordersModel) SetMeta(ctx context.Context, id int64, metaFunc func(fields.OrderMeta) fields.OrderMeta) error {
|
||||||
|
order, err := m.GetByID(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
m.log.Errorf("error getting order by ID: %v", err)
|
||||||
|
return errors.Wrap(err, "failed to get order")
|
||||||
|
}
|
||||||
|
|
||||||
|
tbl := table.Orders
|
||||||
|
stmt := tbl.
|
||||||
|
UPDATE(tbl.Meta).
|
||||||
|
SET(fields.ToJson(metaFunc(order.Meta.Data))).
|
||||||
|
WHERE(
|
||||||
|
tbl.ID.EQ(Int64(id)),
|
||||||
|
)
|
||||||
|
m.log.Infof("sql: %s", stmt.DebugSql())
|
||||||
|
|
||||||
|
if _, err := stmt.ExecContext(ctx, db); err != nil {
|
||||||
|
m.log.Errorf("error set order meta: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// DeleteByID soft deletes an order by ID
|
// DeleteByID soft deletes an order by ID
|
||||||
func (m *ordersModel) SetStatus(ctx context.Context, orderNo string, status fields.OrderStatus) error {
|
func (m *ordersModel) SetStatus(ctx context.Context, orderNo string, status fields.OrderStatus) error {
|
||||||
tbl := table.Orders
|
tbl := table.Orders
|
||||||
|
|||||||
@@ -14,3 +14,7 @@ type OrderMeta struct {
|
|||||||
RefundNotify *wechat.V3DecryptRefundResult `json:"refund_notify"`
|
RefundNotify *wechat.V3DecryptRefundResult `json:"refund_notify"`
|
||||||
CostBalance int64 `json:"cost_balance"` // 余额支付的金额
|
CostBalance int64 `json:"cost_balance"` // 余额支付的金额
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m OrderMeta) ToJson() Json[OrderMeta] {
|
||||||
|
return ToJson(m)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user