This commit is contained in:
2025-12-24 12:32:25 +08:00
parent ce45ce3ed0
commit 311d7a9b01
7 changed files with 350 additions and 134 deletions

View File

@@ -524,8 +524,9 @@ func (s *ComponentReportOrderService) CreatePaymentOrder(ctx context.Context, re
}
// 返回支付响应包含支付URL
// 使用购买订单ID而不是下载记录ID以便前端可以正确检查支付状态
response := &CreatePaymentOrderResponse{
OrderID: download.ID,
OrderID: createdPurchaseOrder.ID, // 修改为购买订单ID
OrderNo: createdPurchaseOrder.OrderNo,
PaymentType: req.PaymentType,
Amount: finalPrice.String(),
@@ -601,7 +602,7 @@ func (s *ComponentReportOrderService) createFreeOrder(
}
return &CreatePaymentOrderResponse{
OrderID: download.ID,
OrderID: createdPurchaseOrder.ID, // 修改为购买订单ID
OrderNo: createdPurchaseOrder.OrderNo,
PaymentType: "free",
Amount: "0.00",
@@ -650,106 +651,90 @@ func (s *ComponentReportOrderService) CheckPaymentStatus(ctx context.Context, or
zap.Time("check_time", time.Now()),
)
// 获取下载记录信息
download, err := s.componentReportRepo.GetDownloadByID(ctx, orderID)
// 直接查询购买订单
purchaseOrder, err := s.purchaseOrderRepo.GetByID(ctx, orderID)
if err != nil {
s.logger.Error("获取下载记录信息失败",
zap.String("order_id", orderID),
zap.Error(err))
return nil, fmt.Errorf("获取下载记录信息失败: %w", err)
s.logger.Error("查询购买订单失败", zap.Error(err), zap.String("order_id", orderID))
return &CheckPaymentStatusResponse{
OrderID: orderID,
PaymentStatus: "unknown",
CanDownload: false,
}, nil
}
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),
)
// 如果订单不存在,返回未知状态
if purchaseOrder == nil {
s.logger.Error("购买订单不存在", zap.String("order_id", orderID))
return &CheckPaymentStatusResponse{
OrderID: orderID,
PaymentStatus: "unknown",
CanDownload: false,
}, nil
}
// 使用OrderID查询购买订单状态来判断支付状态
// 如果购买订单状态是 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, purchaseOrder.ID)
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
}
}
// 根据购买订单状态设置支付状态
var paymentStatus string
var canDownload bool
if download.OrderID != nil {
// 查询购买订单状态
purchaseOrder, err := s.purchaseOrderRepo.GetByID(ctx, *download.OrderID)
if err != nil {
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:
paymentStatus = "success"
canDownload = true
case entities.PurchaseOrderStatusCreated:
paymentStatus = "pending"
canDownload = false
case entities.PurchaseOrderStatusCancelled:
paymentStatus = "cancelled"
canDownload = false
case entities.PurchaseOrderStatusFailed:
paymentStatus = "failed"
canDownload = false
default:
paymentStatus = "unknown"
canDownload = false
}
}
} else {
switch purchaseOrder.Status {
case entities.PurchaseOrderStatusPaid:
paymentStatus = "success"
canDownload = true
case entities.PurchaseOrderStatusCreated:
paymentStatus = "pending"
canDownload = false
}
// 检查是否过期
if download.IsExpired() {
case entities.PurchaseOrderStatusCancelled:
paymentStatus = "cancelled"
canDownload = false
case entities.PurchaseOrderStatusFailed:
paymentStatus = "failed"
canDownload = false
default:
paymentStatus = "unknown"
canDownload = false
}
@@ -762,7 +747,7 @@ func (s *ComponentReportOrderService) CheckPaymentStatus(ctx context.Context, or
)
return &CheckPaymentStatusResponse{
OrderID: download.ID,
OrderID: orderID,
PaymentStatus: paymentStatus,
CanDownload: canDownload,
}, nil
@@ -770,41 +755,83 @@ func (s *ComponentReportOrderService) CheckPaymentStatus(ctx context.Context, or
// DownloadFile 下载文件
func (s *ComponentReportOrderService) DownloadFile(ctx context.Context, orderID string) (string, error) {
// 获取下载记录信息
download, err := s.componentReportRepo.GetDownloadByID(ctx, orderID)
s.logger.Info("开始下载文件", zap.String("order_id", orderID))
// 首先通过orderID查询购买订单
purchaseOrder, err := s.purchaseOrderRepo.GetByID(ctx, orderID)
if err != nil {
return "", fmt.Errorf("获取下载记录信息失败: %w", err)
s.logger.Error("查询购买订单失败", zap.Error(err), zap.String("order_id", orderID))
return "", fmt.Errorf("查询购买订单失败: %w", err)
}
// 使用OrderID查询购买订单状态来判断支付状态
var canDownload bool
if download.OrderID != nil {
// 查询购买订单状态
purchaseOrder, err := s.purchaseOrderRepo.GetByID(ctx, *download.OrderID)
if err != nil {
s.logger.Error("查询购买订单失败", zap.Error(err), zap.String("order_id", *download.OrderID))
canDownload = false
} else {
// 检查购买订单状态
canDownload = purchaseOrder.Status == entities.PurchaseOrderStatusPaid
if purchaseOrder == nil {
s.logger.Error("购买订单不存在", zap.String("order_id", orderID))
return "", fmt.Errorf("购买订单不存在")
}
// 检查购买订单状态
if purchaseOrder.Status != entities.PurchaseOrderStatusPaid {
s.logger.Error("订单未支付,无法下载文件",
zap.String("order_id", orderID),
zap.String("status", string(purchaseOrder.Status)))
return "", fmt.Errorf("订单未支付,无法下载文件")
}
// 获取产品信息
product, err := s.productRepo.GetByID(ctx, purchaseOrder.ProductID)
if err != nil {
s.logger.Error("获取产品信息失败", zap.Error(err), zap.String("product_id", purchaseOrder.ProductID))
return "", fmt.Errorf("获取产品信息失败: %w", err)
}
// 检查是否已有下载记录
download, err := s.componentReportRepo.GetDownloadByPaymentOrderID(ctx, orderID)
if err != nil {
s.logger.Warn("查询下载记录失败,将创建新记录", zap.Error(err), zap.String("order_id", orderID))
download = nil
}
// 如果没有下载记录,创建一个新的
if download == nil {
s.logger.Info("创建新的下载记录",
zap.String("order_id", orderID),
zap.String("user_id", purchaseOrder.UserID),
zap.String("product_id", purchaseOrder.ProductID))
// 创建新的下载记录
newDownload := &productEntities.ComponentReportDownload{
UserID: purchaseOrder.UserID,
ProductID: purchaseOrder.ProductID,
ProductCode: product.Code,
ProductName: product.Name,
OrderID: &purchaseOrder.ID,
OrderNumber: &purchaseOrder.OrderNo,
ExpiresAt: calculateExpiryTime(),
}
} else if download.OrderNumber != nil {
// 兼容旧的支付订单逻辑
canDownload = true // 简化处理,有支付订单号就认为已支付
} else {
canDownload = false
// 保存下载记录
err = s.componentReportRepo.Create(ctx, newDownload)
if err != nil {
s.logger.Error("创建下载记录失败", zap.Error(err))
return "", fmt.Errorf("创建下载记录失败: %w", err)
}
s.logger.Info("成功创建下载记录",
zap.String("order_id", orderID),
zap.String("download_id", newDownload.ID),
zap.String("product_id", newDownload.ProductID))
download = newDownload
}
// 检查是否过期
if download.IsExpired() {
canDownload = false
s.logger.Error("下载链接已过期",
zap.String("order_id", orderID),
zap.Time("expires_at", *download.ExpiresAt))
return "", fmt.Errorf("下载链接已过期,无法下载文件")
}
if !canDownload {
return "", fmt.Errorf("订单未支付或已过期,无法下载文件")
}
// 检查文件是否已存在
if download.FilePath != nil && *download.FilePath != "" {
// 文件已存在,直接返回文件路径
@@ -815,8 +842,10 @@ func (s *ComponentReportOrderService) DownloadFile(ctx context.Context, orderID
}
// 文件不存在,生成文件
s.logger.Info("开始生成报告文件", zap.String("order_id", orderID))
filePath, err := s.generateReportFile(ctx, download)
if err != nil {
s.logger.Error("生成报告文件失败", zap.Error(err), zap.String("order_id", orderID))
return "", fmt.Errorf("生成报告文件失败: %w", err)
}
@@ -882,6 +911,60 @@ func (s *ComponentReportOrderService) GetUserOrders(ctx context.Context, userID
return result, int64(len(result)), nil
}
// createDownloadRecordForPaidOrder 为已支付订单创建下载记录
func (s *ComponentReportOrderService) createDownloadRecordForPaidOrder(ctx context.Context, purchaseOrder *entities.PurchaseOrder) error {
s.logger.Info("开始为已支付订单创建下载记录",
zap.String("purchase_order_id", purchaseOrder.ID),
zap.String("order_no", purchaseOrder.OrderNo),
zap.String("user_id", purchaseOrder.UserID),
zap.String("product_id", purchaseOrder.ProductID))
// 检查是否已有下载记录
existingDownload, err := s.componentReportRepo.GetDownloadByPaymentOrderID(ctx, purchaseOrder.ID)
if err == nil && existingDownload != nil {
s.logger.Info("下载记录已存在,跳过创建",
zap.String("purchase_order_id", purchaseOrder.ID),
zap.String("download_id", existingDownload.ID))
return nil
}
// 获取产品信息
product, err := s.productRepo.GetByID(ctx, purchaseOrder.ProductID)
if err != nil {
s.logger.Error("获取产品信息失败",
zap.Error(err),
zap.String("product_id", purchaseOrder.ProductID))
return fmt.Errorf("获取产品信息失败: %w", err)
}
// 创建新的下载记录
download := &productEntities.ComponentReportDownload{
UserID: purchaseOrder.UserID,
ProductID: purchaseOrder.ProductID,
ProductCode: product.Code,
ProductName: product.Name,
OrderID: &purchaseOrder.ID,
OrderNumber: &purchaseOrder.OrderNo,
ExpiresAt: calculateExpiryTime(), // 30天后过期
}
// 保存下载记录
err = s.componentReportRepo.Create(ctx, download)
if err != nil {
s.logger.Error("创建下载记录失败", zap.Error(err))
return fmt.Errorf("创建下载记录失败: %w", err)
}
s.logger.Info("成功为已支付订单创建下载记录",
zap.String("purchase_order_id", purchaseOrder.ID),
zap.String("order_no", purchaseOrder.OrderNo),
zap.String("download_id", download.ID),
zap.String("product_id", download.ProductID),
zap.String("user_id", download.UserID))
return nil
}
// calculateExpiryTime 计算下载有效期从创建日起30天
func calculateExpiryTime() *time.Time {
now := time.Now()
@@ -944,18 +1027,33 @@ func (s *ComponentReportOrderService) queryAlipayOrderStatusAndUpdate(ctx contex
zap.String("purchase_order_id", purchaseOrderID),
)
// 查询支付宝订单 - 使用RechargeID字段关联
alipayOrder, err := s.alipayOrderRepo.GetByRechargeID(ctx, purchaseOrderID)
// 首先获取购买订单信息
purchaseOrder, err := s.purchaseOrderRepo.GetByID(ctx, purchaseOrderID)
if err != nil {
s.logger.Error("查找购买订单失败",
zap.String("purchase_order_id", purchaseOrderID),
zap.Error(err))
return fmt.Errorf("查找购买订单失败: %w", err)
}
if purchaseOrder == nil {
s.logger.Error("购买订单不存在",
zap.String("purchase_order_id", purchaseOrderID))
return fmt.Errorf("购买订单不存在")
}
// 使用购买订单ID查询支付宝订单RechargeID字段存储的是购买订单ID
alipayOrder, err := s.alipayOrderRepo.GetByRechargeID(ctx, purchaseOrder.ID)
if err != nil {
s.logger.Error("查找支付宝订单失败",
zap.String("purchase_order_id", purchaseOrderID),
zap.String("purchase_order_id", purchaseOrder.ID),
zap.Error(err))
return fmt.Errorf("查找支付宝订单失败: %w", err)
}
if alipayOrder == nil {
s.logger.Error("支付宝订单不存在",
zap.String("purchase_order_id", purchaseOrderID))
zap.String("purchase_order_id", purchaseOrder.ID))
return fmt.Errorf("支付宝订单不存在")
}
@@ -1044,6 +1142,17 @@ func (s *ComponentReportOrderService) queryAlipayOrderStatusAndUpdate(ctx contex
zap.String("order_no", purchaseOrder.OrderNo),
zap.String("status", "paid"),
)
// 支付成功后,自动创建下载记录
err = s.createDownloadRecordForPaidOrder(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))
}
}
}
} else if alipayStatus == "TRADE_CLOSED" {
@@ -1086,18 +1195,33 @@ func (s *ComponentReportOrderService) queryWechatOrderStatusAndUpdate(ctx contex
zap.String("purchase_order_id", purchaseOrderID),
)
// 查询微信订单 - 使用RechargeID字段关联
wechatOrder, err := s.wechatOrderRepo.GetByRechargeID(ctx, purchaseOrderID)
// 首先获取购买订单信息
purchaseOrder, err := s.purchaseOrderRepo.GetByID(ctx, purchaseOrderID)
if err != nil {
s.logger.Error("查找购买订单失败",
zap.String("purchase_order_id", purchaseOrderID),
zap.Error(err))
return fmt.Errorf("查找购买订单失败: %w", err)
}
if purchaseOrder == nil {
s.logger.Error("购买订单不存在",
zap.String("purchase_order_id", purchaseOrderID))
return fmt.Errorf("购买订单不存在")
}
// 使用购买订单ID查询微信订单RechargeID字段存储的是购买订单ID
wechatOrder, err := s.wechatOrderRepo.GetByRechargeID(ctx, purchaseOrder.ID)
if err != nil {
s.logger.Error("查找微信订单失败",
zap.String("purchase_order_id", purchaseOrderID),
zap.String("purchase_order_id", purchaseOrder.ID),
zap.Error(err))
return fmt.Errorf("查找微信订单失败: %w", err)
}
if wechatOrder == nil {
s.logger.Error("微信订单不存在",
zap.String("purchase_order_id", purchaseOrderID))
zap.String("purchase_order_id", purchaseOrder.ID))
return fmt.Errorf("微信订单不存在")
}
@@ -1193,6 +1317,17 @@ func (s *ComponentReportOrderService) queryWechatOrderStatusAndUpdate(ctx contex
zap.String("order_no", purchaseOrder.OrderNo),
zap.String("status", "paid"),
)
// 支付成功后,自动创建下载记录
err = s.createDownloadRecordForPaidOrder(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))
}
}
}
} else if tradeState == "CLOSED" || tradeState == "REVOKED" {