This commit is contained in:
18278715334
2025-12-23 11:26:25 +08:00
parent 7f8554fa12
commit 446a5c7661
2 changed files with 458 additions and 6 deletions

View File

@@ -236,9 +236,18 @@ func (s *ComponentReportOrderService) GetOrderInfo(ctx context.Context, userID,
// CreatePaymentOrder 创建支付订单
func (s *ComponentReportOrderService) CreatePaymentOrder(ctx context.Context, req *CreatePaymentOrderRequest) (*CreatePaymentOrderResponse, error) {
s.logger.Info("========== 开始创建组件报告支付订单 ==========",
zap.String("user_id", req.UserID),
zap.String("product_id", req.ProductID),
zap.String("payment_type", req.PaymentType),
zap.String("platform", req.Platform),
zap.Strings("sub_product_codes", req.SubProductCodes),
)
// 获取产品信息
product, err := s.productRepo.GetByID(ctx, req.ProductID)
if err != nil {
s.logger.Error("获取产品信息失败", zap.Error(err), zap.String("product_id", req.ProductID))
return nil, fmt.Errorf("获取产品信息失败: %w", err)
}
@@ -317,11 +326,29 @@ func (s *ComponentReportOrderService) CreatePaymentOrder(ctx context.Context, re
// 设置为待支付状态
purchaseOrder.Status = entities.PurchaseOrderStatusCreated
s.logger.Info("创建购买订单",
zap.String("user_id", req.UserID),
zap.String("product_id", req.ProductID),
zap.String("product_code", product.Code),
zap.String("product_name", product.Name),
zap.String("order_amount", finalPrice.String()),
zap.String("platform", req.Platform),
zap.String("payment_type", req.PaymentType),
zap.String("subject", fmt.Sprintf("组件报告下载-%s", product.Name)),
)
createdPurchaseOrder, err := s.purchaseOrderRepo.Create(ctx, purchaseOrder)
if err != nil {
s.logger.Error("创建购买订单失败", zap.Error(err))
return nil, fmt.Errorf("创建购买订单失败: %w", err)
}
s.logger.Info("购买订单创建成功",
zap.String("purchase_order_id", createdPurchaseOrder.ID),
zap.String("order_no", createdPurchaseOrder.OrderNo),
zap.String("user_id", req.UserID),
)
// 创建相应的支付记录(未支付状态)
if req.PaymentType == "alipay" {
// 使用工厂方法创建支付宝订单
@@ -330,9 +357,23 @@ func (s *ComponentReportOrderService) CreatePaymentOrder(ctx context.Context, re
// 设置为待支付状态
alipayOrder.Status = entities.AlipayOrderStatusPending
_, err = s.alipayOrderRepo.Create(ctx, *alipayOrder)
s.logger.Info("创建支付宝支付订单",
zap.String("purchase_order_id", createdPurchaseOrder.ID),
zap.String("out_trade_no", outTradeNo),
zap.String("subject", fmt.Sprintf("组件报告下载-%s", product.Name)),
zap.String("amount", finalPrice.String()),
zap.String("platform", req.Platform),
)
createdAlipayOrder, err := s.alipayOrderRepo.Create(ctx, *alipayOrder)
if err != nil {
s.logger.Error("创建支付宝订单记录失败", zap.Error(err))
} else {
s.logger.Info("支付宝订单记录创建成功",
zap.String("alipay_order_id", createdAlipayOrder.ID),
zap.String("purchase_order_id", createdPurchaseOrder.ID),
zap.String("out_trade_no", outTradeNo),
)
}
} else {
// 使用工厂方法创建微信订单
@@ -341,9 +382,23 @@ func (s *ComponentReportOrderService) CreatePaymentOrder(ctx context.Context, re
// 设置为待支付状态
wechatOrder.Status = entities.WechatOrderStatusPending
_, err = s.wechatOrderRepo.Create(ctx, *wechatOrder)
s.logger.Info("创建微信支付订单",
zap.String("purchase_order_id", createdPurchaseOrder.ID),
zap.String("out_trade_no", outTradeNo),
zap.String("subject", fmt.Sprintf("组件报告下载-%s", product.Name)),
zap.String("amount", finalPrice.String()),
zap.String("platform", req.Platform),
)
createdWechatOrder, err := s.wechatOrderRepo.Create(ctx, *wechatOrder)
if err != nil {
s.logger.Error("创建微信订单记录失败", zap.Error(err))
} else {
s.logger.Info("微信订单记录创建成功",
zap.String("wechat_order_id", createdWechatOrder.ID),
zap.String("purchase_order_id", createdPurchaseOrder.ID),
zap.String("out_trade_no", outTradeNo),
)
}
}
@@ -352,18 +407,45 @@ func (s *ComponentReportOrderService) CreatePaymentOrder(ctx context.Context, re
var codeURL string
if req.PaymentType == "alipay" {
s.logger.Info("调用支付宝支付接口",
zap.String("out_trade_no", outTradeNo),
zap.String("platform", req.Platform),
zap.String("amount", finalPrice.String()),
zap.String("subject", fmt.Sprintf("组件报告下载-%s", product.Name)),
)
// 调用支付宝支付接口
payURL, err = s.aliPayService.CreateAlipayOrder(ctx, req.Platform, finalPrice,
fmt.Sprintf("组件报告下载-%s", product.Name), outTradeNo)
if err != nil {
s.logger.Error("创建支付宝支付订单失败",
zap.Error(err),
zap.String("out_trade_no", outTradeNo),
zap.String("platform", req.Platform),
zap.String("amount", finalPrice.String()))
return nil, fmt.Errorf("创建支付宝支付订单失败: %w", err)
}
s.logger.Info("支付宝支付订单创建成功",
zap.String("out_trade_no", outTradeNo),
zap.String("pay_url", payURL),
)
} else if req.PaymentType == "wechat" {
s.logger.Info("调用微信支付接口",
zap.String("out_trade_no", outTradeNo),
zap.String("amount", finalPrice.String()),
zap.String("subject", fmt.Sprintf("组件报告下载-%s", product.Name)),
)
// 调用微信支付接口
floatValue, _ := finalPrice.Float64() // 忽略第二个返回值
result, err := s.wechatPayService.CreateWechatOrder(ctx, floatValue,
fmt.Sprintf("组件报告下载-%s", product.Name), outTradeNo)
if err != nil {
s.logger.Error("创建微信支付订单失败",
zap.Error(err),
zap.String("out_trade_no", outTradeNo),
zap.String("amount", finalPrice.String()))
return nil, fmt.Errorf("创建微信支付订单失败: %w", err)
}
@@ -371,6 +453,11 @@ func (s *ComponentReportOrderService) CreatePaymentOrder(ctx context.Context, re
if resultMap, ok := result.(map[string]string); ok {
codeURL = resultMap["code_url"]
}
s.logger.Info("微信支付订单创建成功",
zap.String("out_trade_no", outTradeNo),
zap.String("code_url", codeURL),
)
}
// 创建一个临时下载记录,用于跟踪支付状态,但不生成报告文件
@@ -401,13 +488,16 @@ func (s *ComponentReportOrderService) CreatePaymentOrder(ctx context.Context, re
CodeURL: codeURL,
}
s.logger.Info("支付订单创建成功",
zap.String("order_id", download.ID),
s.logger.Info("========== 支付订单创建完成 ==========",
zap.String("download_id", download.ID),
zap.String("purchase_order_id", createdPurchaseOrder.ID),
zap.String("order_no", createdPurchaseOrder.OrderNo),
zap.String("user_id", req.UserID),
zap.String("product_id", req.ProductID),
zap.String("payment_type", req.PaymentType),
zap.String("out_trade_no", outTradeNo),
zap.String("amount", finalPrice.String()),
zap.Time("created_at", time.Now()),
)
return response, nil
@@ -510,12 +600,30 @@ func (s *ComponentReportOrderService) generateReportFile(ctx context.Context, do
// CheckPaymentStatus 检查支付状态
func (s *ComponentReportOrderService) CheckPaymentStatus(ctx context.Context, orderID string) (*CheckPaymentStatusResponse, error) {
s.logger.Info("========== 开始检查组件报告支付状态 ==========",
zap.String("order_id", orderID),
zap.Time("check_time", time.Now()),
)
// 获取下载记录信息
download, err := s.componentReportRepo.GetDownloadByID(ctx, orderID)
if err != nil {
s.logger.Error("获取下载记录信息失败",
zap.String("order_id", orderID),
zap.Error(err))
return nil, fmt.Errorf("获取下载记录信息失败: %w", err)
}
s.logger.Info("下载记录信息",
zap.String("order_id", orderID),
zap.String("user_id", download.UserID),
zap.String("product_id", download.ProductID),
zap.String("product_code", download.ProductCode),
zap.String("product_name", download.ProductName),
zap.Any("order_id", download.OrderID),
zap.Any("order_number", download.OrderNumber),
)
// 使用OrderID查询购买订单状态来判断支付状态
var paymentStatus string
var canDownload bool
@@ -527,6 +635,50 @@ func (s *ComponentReportOrderService) CheckPaymentStatus(ctx context.Context, or
s.logger.Error("查询购买订单失败", zap.Error(err), zap.String("order_id", *download.OrderID))
paymentStatus = "unknown"
} else {
// 如果购买订单状态是 Created待支付需要主动查询支付状态
if purchaseOrder.Status == entities.PurchaseOrderStatusCreated {
s.logger.Info("购买订单状态为待支付,主动查询支付状态",
zap.String("purchase_order_id", purchaseOrder.ID),
zap.String("order_no", purchaseOrder.OrderNo),
zap.String("pay_channel", purchaseOrder.PayChannel),
zap.String("payment_type", purchaseOrder.PaymentType),
zap.String("amount", purchaseOrder.Amount.String()),
zap.Time("query_start_time", time.Now()))
// 根据支付渠道查询支付状态
if purchaseOrder.PayChannel == "alipay" && s.aliPayService != nil {
s.logger.Info("开始查询支付宝订单状态",
zap.String("purchase_order_id", purchaseOrder.ID),
zap.String("order_no", purchaseOrder.OrderNo))
err = s.queryAlipayOrderStatusAndUpdate(ctx, purchaseOrder.ID)
if err != nil {
s.logger.Error("查询支付宝订单状态失败",
zap.String("purchase_order_id", purchaseOrder.ID),
zap.Error(err))
}
} else if purchaseOrder.PayChannel == "wechat" && s.wechatPayService != nil {
s.logger.Info("开始查询微信订单状态",
zap.String("purchase_order_id", purchaseOrder.ID),
zap.String("order_no", purchaseOrder.OrderNo))
err = s.queryWechatOrderStatusAndUpdate(ctx, purchaseOrder.ID)
if err != nil {
s.logger.Error("查询微信订单状态失败",
zap.String("purchase_order_id", purchaseOrder.ID),
zap.Error(err))
}
}
// 重新获取更新后的购买订单信息
updatedOrder, err := s.purchaseOrderRepo.GetByID(ctx, *download.OrderID)
if err == nil && updatedOrder != nil {
s.logger.Info("获取更新后的购买订单信息",
zap.String("purchase_order_id", updatedOrder.ID),
zap.String("order_no", updatedOrder.OrderNo),
zap.String("status", string(updatedOrder.Status)))
purchaseOrder = updatedOrder
}
}
// 根据购买订单状态设置支付状态
switch purchaseOrder.Status {
case entities.PurchaseOrderStatusPaid:
@@ -561,6 +713,13 @@ func (s *ComponentReportOrderService) CheckPaymentStatus(ctx context.Context, or
}
// 返回支付状态
s.logger.Info("========== 组件报告支付状态检查完成 ==========",
zap.String("order_id", orderID),
zap.String("payment_status", paymentStatus),
zap.Bool("can_download", canDownload),
zap.Time("check_complete_time", time.Now()),
)
return &CheckPaymentStatusResponse{
OrderID: download.ID,
PaymentStatus: paymentStatus,
@@ -738,6 +897,298 @@ type CheckPaymentStatusResponse struct {
CanDownload bool `json:"can_download"` // 是否可以下载
}
// queryAlipayOrderStatusAndUpdate 查询支付宝订单状态并更新
func (s *ComponentReportOrderService) queryAlipayOrderStatusAndUpdate(ctx context.Context, purchaseOrderID string) error {
s.logger.Info("========== 开始查询支付宝订单状态 ==========",
zap.String("purchase_order_id", purchaseOrderID),
)
// 查询支付宝订单 - 使用RechargeID字段关联
alipayOrder, err := s.alipayOrderRepo.GetByRechargeID(ctx, purchaseOrderID)
if err != nil {
s.logger.Error("查找支付宝订单失败",
zap.String("purchase_order_id", purchaseOrderID),
zap.Error(err))
return fmt.Errorf("查找支付宝订单失败: %w", err)
}
if alipayOrder == nil {
s.logger.Error("支付宝订单不存在",
zap.String("purchase_order_id", purchaseOrderID))
return fmt.Errorf("支付宝订单不存在")
}
s.logger.Info("支付宝订单信息",
zap.String("alipay_order_id", alipayOrder.ID),
zap.String("out_trade_no", alipayOrder.OutTradeNo),
zap.String("status", string(alipayOrder.Status)),
zap.String("amount", alipayOrder.Amount.String()),
)
// 只有pending状态才需要查询
if alipayOrder.Status != entities.AlipayOrderStatusPending {
s.logger.Info("支付宝订单状态不是待支付,跳过查询",
zap.String("out_trade_no", alipayOrder.OutTradeNo),
zap.String("status", string(alipayOrder.Status)))
return nil
}
s.logger.Info("主动查询支付宝订单状态",
zap.String("out_trade_no", alipayOrder.OutTradeNo),
zap.Time("query_time", time.Now()))
// 调用支付宝查询接口
alipayResp, err := s.aliPayService.QueryOrderStatus(ctx, alipayOrder.OutTradeNo)
if err != nil {
s.logger.Error("查询支付宝订单状态失败",
zap.String("out_trade_no", alipayOrder.OutTradeNo),
zap.Error(err))
return err
}
// 解析支付宝返回的状态
alipayStatus := alipayResp.TradeStatus
s.logger.Info("支付宝返回订单状态",
zap.String("out_trade_no", alipayOrder.OutTradeNo),
zap.String("alipay_status", string(alipayStatus)),
zap.String("trade_no", alipayResp.TradeNo),
zap.String("total_amount", alipayResp.TotalAmount),
zap.Time("response_time", time.Now()),
)
// 根据支付宝返回的状态更新本地订单
if alipayStatus == "TRADE_SUCCESS" || alipayStatus == "TRADE_FINISHED" {
s.logger.Info("========== 检测到支付宝支付成功 ==========",
zap.String("out_trade_no", alipayOrder.OutTradeNo),
zap.String("trade_no", alipayResp.TradeNo),
zap.String("total_amount", alipayResp.TotalAmount),
zap.Time("detected_time", time.Now()),
)
// 支付成功,更新支付宝订单状态
alipayOrder.MarkSuccess(alipayResp.TradeNo, "", "", alipayOrder.Amount, alipayOrder.Amount)
err = s.alipayOrderRepo.Update(ctx, *alipayOrder)
if err != nil {
s.logger.Error("更新支付宝订单状态失败",
zap.String("out_trade_no", alipayOrder.OutTradeNo),
zap.Error(err))
return err
}
s.logger.Info("支付宝订单状态更新成功",
zap.String("alipay_order_id", alipayOrder.ID),
zap.String("out_trade_no", alipayOrder.OutTradeNo),
zap.String("trade_no", alipayResp.TradeNo),
zap.String("status", "success"),
)
// 更新购买订单状态为已支付
purchaseOrder, err := s.purchaseOrderRepo.GetByID(ctx, purchaseOrderID)
if err == nil {
s.logger.Info("更新购买订单状态为已支付",
zap.String("purchase_order_id", purchaseOrderID),
zap.String("order_no", purchaseOrder.OrderNo),
zap.String("amount", alipayOrder.Amount.String()),
)
purchaseOrder.MarkPaid(alipayResp.TradeNo, "", "", alipayOrder.Amount, alipayOrder.Amount)
err = s.purchaseOrderRepo.Update(ctx, purchaseOrder)
if err != nil {
s.logger.Error("更新购买订单状态失败",
zap.String("purchase_order_id", purchaseOrderID),
zap.Error(err))
} else {
s.logger.Info("购买订单状态更新成功",
zap.String("purchase_order_id", purchaseOrderID),
zap.String("order_no", purchaseOrder.OrderNo),
zap.String("status", "paid"),
)
}
}
} else if alipayStatus == "TRADE_CLOSED" {
s.logger.Info("检测到支付宝交易已关闭",
zap.String("out_trade_no", alipayOrder.OutTradeNo),
zap.String("trade_no", alipayResp.TradeNo),
)
// 交易关闭,更新支付宝订单状态
alipayOrder.MarkClosed()
err = s.alipayOrderRepo.Update(ctx, *alipayOrder)
if err != nil {
s.logger.Error("更新支付宝订单状态失败",
zap.String("out_trade_no", alipayOrder.OutTradeNo),
zap.Error(err))
} else {
s.logger.Info("支付宝订单状态更新为已关闭",
zap.String("out_trade_no", alipayOrder.OutTradeNo),
zap.String("status", "closed"),
)
}
} else {
s.logger.Info("支付宝订单状态不是成功或关闭",
zap.String("out_trade_no", alipayOrder.OutTradeNo),
zap.String("alipay_status", string(alipayStatus)),
)
}
s.logger.Info("========== 支付宝订单状态查询处理完成 ==========",
zap.String("out_trade_no", alipayOrder.OutTradeNo),
zap.String("final_status", string(alipayStatus)),
)
return nil
}
// queryWechatOrderStatusAndUpdate 查询微信订单状态并更新
func (s *ComponentReportOrderService) queryWechatOrderStatusAndUpdate(ctx context.Context, purchaseOrderID string) error {
s.logger.Info("========== 开始查询微信订单状态 ==========",
zap.String("purchase_order_id", purchaseOrderID),
)
// 查询微信订单 - 使用RechargeID字段关联
wechatOrder, err := s.wechatOrderRepo.GetByRechargeID(ctx, purchaseOrderID)
if err != nil {
s.logger.Error("查找微信订单失败",
zap.String("purchase_order_id", purchaseOrderID),
zap.Error(err))
return fmt.Errorf("查找微信订单失败: %w", err)
}
if wechatOrder == nil {
s.logger.Error("微信订单不存在",
zap.String("purchase_order_id", purchaseOrderID))
return fmt.Errorf("微信订单不存在")
}
s.logger.Info("微信订单信息",
zap.String("wechat_order_id", wechatOrder.ID),
zap.String("out_trade_no", wechatOrder.OutTradeNo),
zap.String("status", string(wechatOrder.Status)),
zap.String("amount", wechatOrder.Amount.String()),
)
// 只有pending状态才需要查询
if wechatOrder.Status != entities.WechatOrderStatusPending {
s.logger.Info("微信订单状态不是待支付,跳过查询",
zap.String("out_trade_no", wechatOrder.OutTradeNo),
zap.String("status", string(wechatOrder.Status)))
return nil
}
s.logger.Info("主动查询微信订单状态",
zap.String("out_trade_no", wechatOrder.OutTradeNo),
zap.Time("query_time", time.Now()))
// 调用微信查询接口
transaction, err := s.wechatPayService.QueryOrderStatus(ctx, wechatOrder.OutTradeNo)
if err != nil {
s.logger.Error("查询微信订单状态失败",
zap.String("out_trade_no", wechatOrder.OutTradeNo),
zap.Error(err))
return err
}
// 解析微信返回的状态
tradeState := ""
transactionId := ""
if transaction.TradeState != nil {
tradeState = *transaction.TradeState
}
if transaction.TransactionId != nil {
transactionId = *transaction.TransactionId
}
s.logger.Info("微信返回订单状态",
zap.String("out_trade_no", wechatOrder.OutTradeNo),
zap.String("trade_state", tradeState),
zap.String("transaction_id", transactionId),
zap.Time("response_time", time.Now()),
)
// 根据微信返回的状态更新本地订单
if tradeState == "SUCCESS" {
s.logger.Info("========== 检测到微信支付成功 ==========",
zap.String("out_trade_no", wechatOrder.OutTradeNo),
zap.String("transaction_id", transactionId),
zap.String("amount", wechatOrder.Amount.String()),
zap.Time("detected_time", time.Now()),
)
// 支付成功,更新微信订单状态
wechatOrder.MarkSuccess(transactionId, "", "", wechatOrder.Amount, wechatOrder.Amount)
err = s.wechatOrderRepo.Update(ctx, *wechatOrder)
if err != nil {
s.logger.Error("更新微信订单状态失败",
zap.String("out_trade_no", wechatOrder.OutTradeNo),
zap.Error(err))
return err
}
s.logger.Info("微信订单状态更新成功",
zap.String("wechat_order_id", wechatOrder.ID),
zap.String("out_trade_no", wechatOrder.OutTradeNo),
zap.String("transaction_id", transactionId),
zap.String("status", "success"),
)
// 更新购买订单状态为已支付
purchaseOrder, err := s.purchaseOrderRepo.GetByID(ctx, purchaseOrderID)
if err == nil {
s.logger.Info("更新购买订单状态为已支付",
zap.String("purchase_order_id", purchaseOrderID),
zap.String("order_no", purchaseOrder.OrderNo),
zap.String("amount", wechatOrder.Amount.String()),
)
purchaseOrder.MarkPaid(transactionId, "", "", wechatOrder.Amount, wechatOrder.Amount)
err = s.purchaseOrderRepo.Update(ctx, purchaseOrder)
if err != nil {
s.logger.Error("更新购买订单状态失败",
zap.String("purchase_order_id", purchaseOrderID),
zap.Error(err))
} else {
s.logger.Info("购买订单状态更新成功",
zap.String("purchase_order_id", purchaseOrderID),
zap.String("order_no", purchaseOrder.OrderNo),
zap.String("status", "paid"),
)
}
}
} else if tradeState == "CLOSED" || tradeState == "REVOKED" {
s.logger.Info("检测到微信交易已关闭",
zap.String("out_trade_no", wechatOrder.OutTradeNo),
zap.String("transaction_id", transactionId),
zap.String("trade_state", tradeState),
)
// 交易关闭,更新微信订单状态
wechatOrder.MarkClosed()
err = s.wechatOrderRepo.Update(ctx, *wechatOrder)
if err != nil {
s.logger.Error("更新微信订单状态失败",
zap.String("out_trade_no", wechatOrder.OutTradeNo),
zap.Error(err))
} else {
s.logger.Info("微信订单状态更新为已关闭",
zap.String("out_trade_no", wechatOrder.OutTradeNo),
zap.String("status", "closed"),
)
}
} else {
s.logger.Info("微信订单状态不是成功或关闭",
zap.String("out_trade_no", wechatOrder.OutTradeNo),
zap.String("trade_state", tradeState),
)
}
s.logger.Info("========== 微信订单状态查询处理完成 ==========",
zap.String("out_trade_no", wechatOrder.OutTradeNo),
zap.String("final_status", tradeState),
)
return nil
}
// UserOrderResponse 用户订单响应
type UserOrderResponse struct {
ID string `json:"id"`

View File

@@ -280,8 +280,9 @@ func (h *ComponentReportOrderHandler) CheckPaymentStatus(c *gin.Context) {
}
c.JSON(http.StatusOK, gin.H{
"code": 200,
"data": response,
"success": true,
"data": response,
"message": "查询支付状态成功",
})
}