This commit is contained in:
liangzai
2026-01-12 16:43:08 +08:00
parent dc747139c9
commit 3c6e2683f5
110 changed files with 9630 additions and 481 deletions

View File

@@ -6,7 +6,6 @@ import (
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"ycc-server/common/globalkey"
"ycc-server/common/xerr"
"github.com/pkg/errors"
@@ -84,7 +83,6 @@ func (l *AdminGetOrderDetailLogic) AdminGetOrderDetail(req *types.AdminGetOrderD
// 查询清理日志
cleanupBuilder := l.svcCtx.QueryCleanupDetailModel.SelectBuilder().
Where("order_id = ?", order.Id).
Where("del_state = ?", globalkey.DelStateNo).
OrderBy("create_time DESC").
Limit(1)
cleanupDetails, err := l.svcCtx.QueryCleanupDetailModel.FindAll(l.ctx, cleanupBuilder, "")

View File

@@ -7,7 +7,6 @@ import (
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"ycc-server/common/globalkey"
"ycc-server/common/xerr"
"github.com/Masterminds/squirrel"
@@ -139,7 +138,6 @@ func (l *AdminGetOrderListLogic) AdminGetOrderList(req *types.AdminGetOrderListR
// 查询清理日志
cleanupBuilder := l.svcCtx.QueryCleanupDetailModel.SelectBuilder().
Where(squirrel.Eq{"order_id": notFoundOrderIds}).
Where("del_state = ?", globalkey.DelStateNo).
OrderBy("create_time DESC")
cleanupDetails, err := l.svcCtx.QueryCleanupDetailModel.FindAll(l.ctx, cleanupBuilder, "")
if err != nil && !errors.Is(err, model.ErrNotFound) {

View File

@@ -1,27 +1,30 @@
package admin_order
import (
"context"
"database/sql"
"fmt"
"time"
"context"
"database/sql"
"fmt"
"time"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"ycc-server/common/xerr"
"ycc-server/app/main/api/internal/svc"
"ycc-server/app/main/api/internal/types"
"ycc-server/app/main/model"
"ycc-server/common/xerr"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/google/uuid"
"github.com/google/uuid"
"github.com/pkg/errors"
"github.com/smartwalle/alipay/v3"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/sqlx"
)
const (
PaymentPlatformAlipay = "alipay"
PaymentPlatformWechat = "wechat"
OrderStatusPaid = "paid"
RefundNoPrefix = "refund-"
PaymentPlatformAlipay = "alipay"
PaymentPlatformWechat = "wechat"
PaymentPlatformTest = "test"
PaymentPlatformTestEmpty = "test_empty"
OrderStatusPaid = "paid"
RefundNoPrefix = "refund-"
)
type AdminRefundOrderLogic struct {
@@ -44,6 +47,11 @@ func (l *AdminRefundOrderLogic) AdminRefundOrder(req *types.AdminRefundOrderReq)
return nil, err
}
// 检查是否为测试支付平台test 或 test_empty如果是则模拟退款成功
if order.PaymentPlatform == PaymentPlatformTest || order.PaymentPlatform == PaymentPlatformTestEmpty {
return l.handleTestRefund(order, req)
}
// 根据支付平台处理退款
switch order.PaymentPlatform {
case PaymentPlatformAlipay:
@@ -75,29 +83,39 @@ func (l *AdminRefundOrderLogic) getAndValidateOrder(orderId string, refundAmount
return order, nil
}
// handleTestRefund 处理测试支付平台退款(模拟退款成功)
func (l *AdminRefundOrderLogic) handleTestRefund(order *model.Order, req *types.AdminRefundOrderReq) (*types.AdminRefundOrderResp, error) {
refundNo := l.generateRefundNo(order.OrderNo)
// 创建模拟的平台退款ID
platformRefundId := fmt.Sprintf("MOCK_REFUND_%s_%d", order.OrderNo, time.Now().Unix())
logx.Infof("测试支付平台模拟退款:订单 %s退款金额 %.2f,跳过实际退款接口调用", order.OrderNo, req.RefundAmount)
// 直接标记为退款成功
err := l.createRefundRecordAndUpdateOrder(order, req, refundNo, platformRefundId, model.OrderStatusRefunded, model.OrderRefundStatusSuccess)
if err != nil {
return nil, err
}
return &types.AdminRefundOrderResp{
Status: model.OrderStatusRefunded,
RefundNo: refundNo,
Amount: req.RefundAmount,
}, nil
}
// handleAlipayRefund 处理支付宝退款
func (l *AdminRefundOrderLogic) handleAlipayRefund(order *model.Order, req *types.AdminRefundOrderReq) (*types.AdminRefundOrderResp, error) {
refundNo := l.generateRefundNo(order.OrderNo)
// 调用支付宝退款接口
var refundResp *alipay.TradeRefundRsp
refundResp, err := l.svcCtx.AlipayService.AliRefund(l.ctx, order.OrderNo, req.RefundAmount)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "AdminRefundOrder, 支付宝退款失败 err: %v", err)
}
refundNo := l.generateRefundNo(order.OrderNo)
if refundResp.IsSuccess() {
// 支付宝退款成功,创建成功记录
err = l.createRefundRecordAndUpdateOrder(order, req, refundNo, refundResp.TradeNo, model.OrderStatusRefunded, model.OrderRefundStatusSuccess)
if err != nil {
return nil, err
}
return &types.AdminRefundOrderResp{
Status: model.OrderStatusRefunded,
RefundNo: refundNo,
Amount: req.RefundAmount,
}, nil
} else {
if !refundResp.IsSuccess() {
// 支付宝退款失败,创建失败记录但不更新订单状态
err = l.createRefundRecordOnly(order, req, refundNo, refundResp.TradeNo, model.OrderRefundStatusFailed)
if err != nil {
@@ -105,10 +123,24 @@ func (l *AdminRefundOrderLogic) handleAlipayRefund(order *model.Order, req *type
}
return nil, errors.Wrapf(xerr.NewErrMsg(fmt.Sprintf("退款失败: %v", refundResp.Msg)), "AdminRefundOrder, 支付宝退款失败")
}
// 支付宝退款成功,创建成功记录
err = l.createRefundRecordAndUpdateOrder(order, req, refundNo, refundResp.TradeNo, model.OrderStatusRefunded, model.OrderRefundStatusSuccess)
if err != nil {
return nil, err
}
return &types.AdminRefundOrderResp{
Status: model.OrderStatusRefunded,
RefundNo: refundNo,
Amount: req.RefundAmount,
}, nil
}
// handleWechatRefund 处理微信退款
func (l *AdminRefundOrderLogic) handleWechatRefund(order *model.Order, req *types.AdminRefundOrderReq) (*types.AdminRefundOrderResp, error) {
refundNo := l.generateRefundNo(order.OrderNo)
// 调用微信退款接口
err := l.svcCtx.WechatPayService.WeChatRefund(l.ctx, order.OrderNo, req.RefundAmount, order.Amount)
if err != nil {
@@ -116,7 +148,6 @@ func (l *AdminRefundOrderLogic) handleWechatRefund(order *model.Order, req *type
}
// 微信退款是异步的创建pending状态的退款记录
refundNo := l.generateRefundNo(order.OrderNo)
err = l.createRefundRecordAndUpdateOrder(order, req, refundNo, "", model.OrderStatusRefunding, model.OrderRefundStatusPending)
if err != nil {
return nil, err
@@ -131,20 +162,20 @@ func (l *AdminRefundOrderLogic) handleWechatRefund(order *model.Order, req *type
// createRefundRecordAndUpdateOrder 创建退款记录并更新订单状态
func (l *AdminRefundOrderLogic) createRefundRecordAndUpdateOrder(order *model.Order, req *types.AdminRefundOrderReq, refundNo, platformRefundId, orderStatus, refundStatus string) error {
return l.svcCtx.OrderModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
err := l.svcCtx.OrderModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
// 创建退款记录
refund := &model.OrderRefund{
Id: uuid.NewString(),
RefundNo: refundNo,
PlatformRefundId: l.createNullString(platformRefundId),
OrderId: order.Id,
UserId: order.UserId,
ProductId: order.ProductId,
RefundAmount: req.RefundAmount,
RefundReason: l.createNullString(req.RefundReason),
Status: refundStatus, // 使用传入的状态,不再硬编码
RefundTime: sql.NullTime{Time: time.Now(), Valid: true},
}
refund := &model.OrderRefund{
Id: uuid.NewString(),
RefundNo: refundNo,
PlatformRefundId: l.createNullString(platformRefundId),
OrderId: order.Id,
UserId: order.UserId,
ProductId: order.ProductId,
RefundAmount: req.RefundAmount,
RefundReason: l.createNullString(req.RefundReason),
Status: refundStatus, // 使用传入的状态,不再硬编码
RefundTime: sql.NullTime{Time: time.Now(), Valid: true},
}
if _, err := l.svcCtx.OrderRefundModel.Insert(ctx, session, refund); err != nil {
return fmt.Errorf("创建退款记录失败: %v", err)
@@ -158,22 +189,43 @@ func (l *AdminRefundOrderLogic) createRefundRecordAndUpdateOrder(order *model.Or
return nil
})
if err != nil {
return err
}
// 退款成功后,检查并处理代理订单(在事务外执行,避免影响退款流程)
if refundStatus == model.OrderRefundStatusSuccess {
// 检查代理订单是否已处理
agentOrder, err := l.svcCtx.AgentOrderModel.FindOneByOrderId(l.ctx, order.Id)
if err == nil && agentOrder != nil && agentOrder.ProcessStatus == 1 {
// 代理订单已处理,需要撤销收益
if cancelErr := l.svcCtx.AgentService.CancelAgentCommission(l.ctx, order.Id); cancelErr != nil {
logx.Errorf("撤销代理收益失败订单ID: %s, 错误: %v", order.Id, cancelErr)
// 不阻断退款流程,只记录日志(退款已成功,不能回滚)
} else {
logx.Infof("成功撤销代理收益订单ID: %s", order.Id)
}
}
}
return nil
}
// createRefundRecordOnly 仅创建退款记录,不更新订单状态(用于退款失败的情况)
func (l *AdminRefundOrderLogic) createRefundRecordOnly(order *model.Order, req *types.AdminRefundOrderReq, refundNo, platformRefundId, refundStatus string) error {
refund := &model.OrderRefund{
Id: uuid.NewString(),
RefundNo: refundNo,
PlatformRefundId: l.createNullString(platformRefundId),
OrderId: order.Id,
UserId: order.UserId,
ProductId: order.ProductId,
RefundAmount: req.RefundAmount,
RefundReason: l.createNullString(req.RefundReason),
Status: refundStatus,
RefundTime: sql.NullTime{Time: time.Now(), Valid: true},
}
refund := &model.OrderRefund{
Id: uuid.NewString(),
RefundNo: refundNo,
PlatformRefundId: l.createNullString(platformRefundId),
OrderId: order.Id,
UserId: order.UserId,
ProductId: order.ProductId,
RefundAmount: req.RefundAmount,
RefundReason: l.createNullString(req.RefundReason),
Status: refundStatus,
RefundTime: sql.NullTime{Time: time.Now(), Valid: true},
}
_, err := l.svcCtx.OrderRefundModel.Insert(l.ctx, nil, refund)
if err != nil {