修改交易服务函数命名;调整 docker compose 脚本;

This commit is contained in:
2025-08-14 18:10:04 +08:00
parent 47b6d2433f
commit 5541e16f0d
9 changed files with 172 additions and 124 deletions

View File

@@ -4,8 +4,6 @@ import (
"context"
"errors"
"fmt"
"github.com/shopspring/decimal"
wecahtpaycore "github.com/wechatpay-apiv3/wechatpay-go/core"
"io"
"log/slog"
"net/http"
@@ -21,16 +19,14 @@ import (
"platform/web/tasks"
"time"
"github.com/shopspring/decimal"
wecahtpaycore "github.com/wechatpay-apiv3/wechatpay-go/core"
"github.com/smartwalle/alipay/v3"
"github.com/wechatpay-apiv3/wechatpay-go/services/payments/native"
"gorm.io/gorm"
)
var ComplementEvents = []trade2.CompleteEvent{
ResourceOnTradeComplete{},
UserOnTradeComplete{},
}
var Trade = &tradeService{}
type tradeService struct {
@@ -258,67 +254,92 @@ func (s *tradeService) CreateTrade(uid int32, now time.Time, data *CreateTradeDa
}, nil
}
func (s *tradeService) OnTradeCompleted(data *OnTradeCompletedData) error {
// 更新交易状态
var trade = new(m.Trade)
var err = g.Redsync.WithLock(tradeLockKey(data.TradeNo), func() error {
return q.Q.Transaction(func(q *q.Query) (err error) {
trade, err = completeTrade(q, data)
return
})
func (s *tradeService) CompleteTrade(data *CheckTradeData) error {
return g.Redsync.WithLock(tradeLockKey(data.TradeNo), func() error {
// 检查订单状态
result, err := s.ConfirmTradeCompleted(data)
if err != nil {
return core.NewServErr("确认交易状态失败", err)
}
// 更新交易状态
trade, err := completeTrade(&OnTradeCompletedData{data.TradeNo, *result})
if err != nil {
return core.NewServErr("处理交易失败", err)
}
// 处理交易完成事件
err = afterTradeComplete(trade)
if err != nil {
return core.NewServErr("处理交易完成事件失败", err)
}
return nil
})
if err != nil {
return core.NewServErr("处理交易失败", err)
}
// 处理交易完成事件
err = completeTradeAfter(trade)
if err != nil {
return core.NewServErr("处理交易完成事件失败", err)
}
return nil
}
func completeTrade(q *q.Query, data *OnTradeCompletedData) (*m.Trade, error) {
var tradeNo = data.TradeNo
var transId = data.TransId
var payment = data.Payment
var acquirer = data.Acquirer
var paidAt = data.Time
func (s *tradeService) OnTradeCompleted(data *OnTradeCompletedData) error {
return g.Redsync.WithLock(tradeLockKey(data.TradeNo), func() error {
// 获取交易信息
trade, err := q.Trade.
Where(q.Trade.InnerNo.Eq(tradeNo)).
Take()
if err != nil {
return nil, core.NewBizErr("获取交易信息失败", err)
}
// 更新交易状态
trade, err := completeTrade(data)
if err != nil {
return core.NewServErr("处理交易失败", err)
}
// 检查交易状态
switch trade2.Status(trade.Status) {
case trade2.StatusCanceled:
return nil, core.NewBizErr("交易已取消")
case trade2.StatusSuccess:
return nil, core.NewBizErr("交易已完成")
case trade2.StatusPending:
}
// 处理交易完成事件
err = afterTradeComplete(trade)
if err != nil {
return core.NewServErr("处理交易完成事件失败", err)
}
// 更新交易信息
trade.Status = int32(trade2.StatusSuccess)
trade.OuterNo = &transId
trade.Payment = payment
trade.Acquirer = u.P(int32(acquirer))
trade.CompletedAt = u.P(orm.LocalDateTime(paidAt))
_, err = q.Trade.
Where(q.Trade.InnerNo.Eq(tradeNo)).
Updates(trade)
if err != nil {
return nil, core.NewServErr("更新交易信息失败", err)
}
return trade, nil
return nil
})
}
func completeTradeAfter(trade *m.Trade) error {
func completeTrade(data *OnTradeCompletedData) (*m.Trade, error) {
var trade = new(m.Trade)
var err = q.Q.Transaction(func(tx *q.Query) error {
var tradeNo = data.TradeNo
var transId = data.TransId
var payment = data.Payment
var acquirer = data.Acquirer
var paidAt = data.Time
// 获取交易信息
trade, err := q.Trade.
Where(q.Trade.InnerNo.Eq(tradeNo)).
Take()
if err != nil {
return core.NewBizErr("获取交易信息失败", err)
}
// 检查交易状态
switch trade2.Status(trade.Status) {
case trade2.StatusCanceled:
return core.NewBizErr("交易已取消")
case trade2.StatusSuccess:
return core.NewBizErr("交易已完成")
case trade2.StatusPending:
}
// 更新交易信息
trade.Status = int32(trade2.StatusSuccess)
trade.OuterNo = &transId
trade.Payment = payment
trade.Acquirer = u.P(int32(acquirer))
trade.CompletedAt = u.P(orm.LocalDateTime(paidAt))
_, err = q.Trade.
Where(q.Trade.InnerNo.Eq(tradeNo)).
Updates(trade)
if err != nil {
return core.NewServErr("更新交易信息失败", err)
}
return nil
})
return trade, err
}
func afterTradeComplete(trade *m.Trade) error {
// 恢复购买信息
productData, err := g.Redis.Get(context.Background(), tradeProductKey(trade.InnerNo)).Result()
@@ -327,6 +348,11 @@ func completeTradeAfter(trade *m.Trade) error {
}
// 执行资源创建
var ComplementEvents = []trade2.CompleteEvent{
ResourceOnTradeComplete{},
UserOnTradeComplete{},
}
for _, event := range ComplementEvents {
info, ok := event.Check(trade2.Type(trade.Type))
if !ok {
@@ -348,7 +374,7 @@ func completeTradeAfter(trade *m.Trade) error {
}
func (s *tradeService) CancelTrade(tradeNo string, method trade2.Method, now time.Time) error {
err := g.Redsync.WithLock(tradeLockKey(tradeNo), func() error {
return g.Redsync.WithLock(tradeLockKey(tradeNo), func() error {
switch method {
case trade2.MethodAlipay:
@@ -356,11 +382,11 @@ func (s *tradeService) CancelTrade(tradeNo string, method trade2.Method, now tim
OutTradeNo: tradeNo,
})
if err != nil {
return err
return core.NewServErr("上游取消交易失败", err)
}
if resp.Code != alipay.CodeSuccess {
slog.Warn("支付宝交易取消失败", "code", resp.Code, "sub_code", resp.SubCode, "msg", resp.Msg)
return errors.New("交易取消失败")
slog.Error("支付宝交易取消失败", "code", resp.Code, "sub_code", resp.SubCode, "msg", resp.Msg)
return errors.New("上游取消交易失败")
}
case trade2.MethodWeChat:
@@ -369,12 +395,16 @@ func (s *tradeService) CancelTrade(tradeNo string, method trade2.Method, now tim
OutTradeNo: &tradeNo,
})
if err != nil {
return err
return core.NewServErr("上游取消交易失败", err)
}
if resp.Response.StatusCode != http.StatusNoContent {
body, _ := io.ReadAll(resp.Response.Body)
slog.Warn("微信交易取消失败", "code", resp.Response.StatusCode, "body", string(body))
return errors.New("交易取消失败")
body, err := io.ReadAll(resp.Response.Body)
if err != nil {
slog.Error("读取微信交易取消响应失败", "error", err)
return core.NewServErr("上游取消交易失败", err)
}
slog.Error("微信交易取消失败", "code", resp.Response.StatusCode, "body", string(body))
return errors.New("上游取消交易失败")
}
case trade2.MethodSft, trade2.MethodSftAlipay, trade2.MethodSftWeChat:
@@ -390,61 +420,56 @@ func (s *tradeService) CancelTrade(tradeNo string, method trade2.Method, now tim
return ErrTransactionNotSupported
}
err := q.Q.Transaction(func(q *q.Query) error {
return cancelTrade(q, tradeNo, now)
})
err := cancelTrade(tradeNo, now)
if err != nil {
return err
}
return nil
})
if err != nil {
return core.NewServErr("处理交易取消失败", err)
}
return nil
}
func (s *tradeService) OnTradeCanceled(q *q.Query, tradeNo string, now time.Time) error {
func (s *tradeService) OnTradeCanceled(tradeNo string, now time.Time) error {
err := g.Redsync.WithLock(tradeLockKey(tradeNo), func() error {
return cancelTrade(q, tradeNo, now)
return cancelTrade(tradeNo, now)
})
if err != nil {
return core.NewServErr("处理交易取消失败", err)
}
return nil
}
func cancelTrade(q *q.Query, tradeNo string, now time.Time) error {
// 获取交易信息
var status trade2.Status
err := q.Trade.
Where(q.Trade.InnerNo.Eq(tradeNo)).
Select(q.Trade.Status).
Scan(&status)
if err != nil {
return core.NewBizErr("获取交易信息失败", err)
}
func cancelTrade(tradeNo string, now time.Time) error {
return q.Q.Transaction(func(q *q.Query) error {
// 获取交易信息
var status trade2.Status
err := q.Trade.
Where(q.Trade.InnerNo.Eq(tradeNo)).
Select(q.Trade.Status).
Scan(&status)
if err != nil {
return core.NewBizErr("获取交易信息失败", err)
}
// 检查交易状态
switch status {
case trade2.StatusCanceled:
return core.NewBizErr("交易已取消")
case trade2.StatusSuccess:
return core.NewBizErr("交易已完成")
case trade2.StatusPending:
}
// 检查交易状态
switch status {
case trade2.StatusCanceled:
return core.NewBizErr("交易已取消")
case trade2.StatusSuccess:
return core.NewBizErr("交易已完成")
case trade2.StatusPending:
}
// 更新交易状态
_, err = q.Trade.
Where(q.Trade.InnerNo.Eq(tradeNo)).
UpdateSimple(
q.Trade.Status.Value(int32(trade2.StatusCanceled)),
q.Trade.CanceledAt.Value(orm.LocalDateTime(now)),
)
if err != nil {
return core.NewServErr("更新交易状态失败", err)
}
return nil
// 更新交易状态
_, err = q.Trade.
Where(q.Trade.InnerNo.Eq(tradeNo)).
UpdateSimple(
q.Trade.Status.Value(int32(trade2.StatusCanceled)),
q.Trade.CanceledAt.Value(orm.LocalDateTime(now)),
)
if err != nil {
return core.NewServErr("更新交易状态失败", err)
}
return nil
})
}
func (s *tradeService) RefundTrade(tradeNo string, method trade2.Method) error {