This commit is contained in:
2025-10-23 19:17:27 +08:00
parent 050809c471
commit 0acfb80849
9 changed files with 320 additions and 29 deletions

View File

@@ -35,6 +35,10 @@ service main {
@doc "订单退款"
@handler AdminRefundOrder
post /refund/:id (AdminRefundOrderReq) returns (AdminRefundOrderResp)
@doc "重新执行代理处理"
@handler AdminRetryAgentProcess
post /retry-agent-process/:id (AdminRetryAgentProcessReq) returns (AdminRetryAgentProcessResp)
}
type (
@@ -79,6 +83,8 @@ type (
PayTime string `json:"pay_time"` // 支付时间
RefundTime string `json:"refund_time"` // 退款时间
IsPromotion int64 `json:"is_promotion"` // 是否推广订单0-否1-是
IsAgentOrder bool `json:"is_agent_order"` // 是否是代理订单
AgentProcessStatus string `json:"agent_process_status"` // 代理事务处理状态not_agent-非代理订单success-处理成功failed-处理失败pending-待处理
}
// 详情请求
@@ -102,6 +108,8 @@ type (
RefundTime string `json:"refund_time"` // 退款时间
IsPromotion int64 `json:"is_promotion"` // 是否推广订单0-否1-是
UpdateTime string `json:"update_time"` // 更新时间
IsAgentOrder bool `json:"is_agent_order"` // 是否是代理订单
AgentProcessStatus string `json:"agent_process_status"` // 代理事务处理状态not_agent-非代理订单success-处理成功failed-处理失败pending-待处理
}
// 创建请求
@@ -164,4 +172,16 @@ type (
RefundNo string `json:"refund_no"` // 退款单号
Amount float64 `json:"amount"` // 退款金额
}
// 重新执行代理处理请求
AdminRetryAgentProcessReq {
Id int64 `path:"id"` // 订单ID
}
// 重新执行代理处理响应
AdminRetryAgentProcessResp {
Status string `json:"status"` // 执行状态success-成功already_processed-已处理failed-失败
Message string `json:"message"` // 执行结果消息
ProcessedAt string `json:"processed_at"` // 处理时间
}
)

View File

@@ -0,0 +1,29 @@
package admin_order
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"hm-server/app/main/api/internal/logic/admin_order"
"hm-server/app/main/api/internal/svc"
"hm-server/app/main/api/internal/types"
)
// 重新执行代理处理
func AdminRetryAgentProcessHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.AdminRetryAgentProcessReq
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := admin_order.NewAdminRetryAgentProcessLogic(r.Context(), svcCtx)
resp, err := l.AdminRetryAgentProcess(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}

View File

@@ -1,4 +1,6 @@
// Code generated by goctl. DO NOT EDIT.
// goctl 1.8.4
package handler
import (
@@ -310,6 +312,12 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
Path: "/refund/:id",
Handler: admin_order.AdminRefundOrderHandler(serverCtx),
},
{
// 重新执行代理处理
Method: http.MethodPost,
Path: "/retry-agent-process/:id",
Handler: admin_order.AdminRetryAgentProcessHandler(serverCtx),
},
{
// 更新订单
Method: http.MethodPut,

View File

@@ -47,6 +47,36 @@ func (l *AdminGetOrderDetailLogic) AdminGetOrderDetail(req *types.AdminGetOrderD
isPromotion = 1
}
// 判断是否为代理订单并获取代理处理状态
var isAgentOrder bool
var agentProcessStatus string
agentOrder, err := l.svcCtx.AgentOrderModel.FindOneByOrderId(l.ctx, order.Id)
if err == nil && agentOrder != nil {
isAgentOrder = true
// 查询代理佣金记录
commissions, err := l.svcCtx.AgentCommissionModel.FindAll(l.ctx,
l.svcCtx.AgentCommissionModel.SelectBuilder().Where("order_id = ?", order.Id), "")
if err != nil && !errors.Is(err, model.ErrNotFound) {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "AdminGetOrderDetail, 查询代理佣金失败 err: %v", err)
}
if len(commissions) > 0 {
agentProcessStatus = "success"
} else {
// 检查订单状态,如果是已支付但无佣金记录,则为待处理或失败
if order.Status == "paid" {
agentProcessStatus = "pending"
} else {
agentProcessStatus = "failed"
}
}
} else {
isAgentOrder = false
agentProcessStatus = "not_agent"
}
// 获取查询状态
var queryState string
builder := l.svcCtx.QueryModel.SelectBuilder().Where("order_id = ?", order.Id).Columns("query_state")
@@ -90,6 +120,8 @@ func (l *AdminGetOrderDetailLogic) AdminGetOrderDetail(req *types.AdminGetOrderD
UpdateTime: order.UpdateTime.Format("2006-01-02 15:04:05"),
IsPromotion: isPromotion,
QueryState: queryState,
IsAgentOrder: isAgentOrder,
AgentProcessStatus: agentProcessStatus,
}
// 处理可选字段

View File

@@ -102,6 +102,8 @@ func (l *AdminGetOrderListLogic) AdminGetOrderList(req *types.AdminGetOrderListR
// 并发获取产品信息和查询状态
productMap := make(map[int64]string)
queryStateMap := make(map[int64]string)
agentOrderMap := make(map[int64]bool) // 代理订单映射
agentProcessStatusMap := make(map[int64]string) // 代理处理状态映射
var mu sync.Mutex
// 批量获取查询状态
@@ -160,6 +162,60 @@ func (l *AdminGetOrderListLogic) AdminGetOrderList(req *types.AdminGetOrderListR
}
}
}
// 批量获取代理订单状态
agentOrders, err := l.svcCtx.AgentOrderModel.FindAll(l.ctx,
l.svcCtx.AgentOrderModel.SelectBuilder().Where(squirrel.Eq{"order_id": orderIds}), "")
if err != nil && !errors.Is(err, model.ErrNotFound) {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "AdminGetOrderList, 批量查询代理订单失败 err: %v", err)
}
// 记录代理订单
for _, agentOrder := range agentOrders {
agentOrderMap[agentOrder.OrderId] = true
}
// 对于代理订单,查询代理处理状态
if len(agentOrders) > 0 {
agentOrderIds := make([]int64, 0, len(agentOrders))
for _, agentOrder := range agentOrders {
agentOrderIds = append(agentOrderIds, agentOrder.OrderId)
}
// 查询代理佣金记录
commissions, err := l.svcCtx.AgentCommissionModel.FindAll(l.ctx,
l.svcCtx.AgentCommissionModel.SelectBuilder().Where(squirrel.Eq{"order_id": agentOrderIds}), "")
if err != nil && !errors.Is(err, model.ErrNotFound) {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "AdminGetOrderList, 批量查询代理佣金失败 err: %v", err)
}
// 记录有佣金记录的订单为处理成功
processedOrderIds := make(map[int64]bool)
for _, commission := range commissions {
processedOrderIds[commission.OrderId] = true
}
// 创建订单状态映射,避免重复查找
orderStatusMap := make(map[int64]string)
for _, order := range orders {
orderStatusMap[order.Id] = order.Status
}
// 设置代理处理状态
for _, agentOrder := range agentOrders {
orderId := agentOrder.OrderId
if processedOrderIds[orderId] {
agentProcessStatusMap[orderId] = "success"
} else {
// 检查订单状态,如果是已支付但无佣金记录,则为待处理或失败
if orderStatusMap[orderId] == "paid" {
agentProcessStatusMap[orderId] = "pending"
} else {
agentProcessStatusMap[orderId] = "failed"
}
}
}
}
}
// 并发获取产品信息
@@ -222,6 +278,16 @@ func (l *AdminGetOrderListLogic) AdminGetOrderList(req *types.AdminGetOrderListR
if err == nil && promotionOrder != nil {
item.IsPromotion = 1
}
// 设置代理订单相关字段
if agentOrderMap[order.Id] {
item.IsAgentOrder = true
item.AgentProcessStatus = agentProcessStatusMap[order.Id]
} else {
item.IsAgentOrder = false
item.AgentProcessStatus = "not_agent"
}
resp.Items = append(resp.Items, item)
}

View File

@@ -0,0 +1,56 @@
package admin_order
import (
"context"
"time"
"hm-server/app/main/api/internal/svc"
"hm-server/app/main/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type AdminRetryAgentProcessLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// 重新执行代理处理
func NewAdminRetryAgentProcessLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AdminRetryAgentProcessLogic {
return &AdminRetryAgentProcessLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *AdminRetryAgentProcessLogic) AdminRetryAgentProcess(req *types.AdminRetryAgentProcessReq) (resp *types.AdminRetryAgentProcessResp, err error) {
// 调用AgentService的重新执行代理处理方法
err = l.svcCtx.AgentService.RetryAgentProcess(l.ctx, req.Id)
if err != nil {
// 检查是否是"已经处理"的错误
if err.Error() == "代理处理已经成功,无需重新执行" {
return &types.AdminRetryAgentProcessResp{
Status: "already_processed",
Message: "代理处理已经成功,无需重新执行",
ProcessedAt: time.Now().Format("2006-01-02 15:04:05"),
}, nil
}
// 其他错误
logx.Errorf("重新执行代理处理失败订单ID: %d, 错误: %v", req.Id, err)
return &types.AdminRetryAgentProcessResp{
Status: "failed",
Message: err.Error(),
ProcessedAt: time.Now().Format("2006-01-02 15:04:05"),
}, nil
}
// 执行成功
return &types.AdminRetryAgentProcessResp{
Status: "success",
Message: "代理处理重新执行成功",
ProcessedAt: time.Now().Format("2006-01-02 15:04:05"),
}, nil
}

View File

@@ -12,6 +12,7 @@ import (
type AgentService struct {
config config.Config
OrderModel model.OrderModel
AgentModel model.AgentModel
AgentAuditModel model.AgentAuditModel
AgentClosureModel model.AgentClosureModel
@@ -30,7 +31,7 @@ type AgentService struct {
AgentWithdrawalModel model.AgentWithdrawalModel
}
func NewAgentService(c config.Config, agentModel model.AgentModel, agentAuditModel model.AgentAuditModel,
func NewAgentService(c config.Config, orderModel model.OrderModel, agentModel model.AgentModel, agentAuditModel model.AgentAuditModel,
agentClosureModel model.AgentClosureModel, agentCommissionModel model.AgentCommissionModel,
agentCommissionDeductionModel model.AgentCommissionDeductionModel, agentWalletModel model.AgentWalletModel, agentLinkModel model.AgentLinkModel, agentOrderModel model.AgentOrderModel, agentRewardsModel model.AgentRewardsModel,
agentMembershipConfigModel model.AgentMembershipConfigModel,
@@ -41,6 +42,7 @@ func NewAgentService(c config.Config, agentModel model.AgentModel, agentAuditMod
return &AgentService{
config: c,
OrderModel: orderModel,
AgentModel: agentModel,
AgentAuditModel: agentAuditModel,
AgentClosureModel: agentClosureModel,
@@ -271,6 +273,10 @@ func (l *AgentService) CommissionCost(ctx context.Context, descendantId int64, A
// 拥有则查看该上级设定的成本
agentMembershipUserConfigModel, findAgentMembershipUserConfigModelErr := l.AgentMembershipUserConfigModel.FindOneByAgentIdProductId(ctx, AncestorId, productID)
if findAgentMembershipUserConfigModelErr != nil {
// 如果上级没有配置该产品的定价规则,则跳过成本计算
if errors.Is(findAgentMembershipUserConfigModelErr, model.ErrNotFound) {
return 0, nil
}
return 0, findAgentMembershipUserConfigModelErr
}
@@ -301,6 +307,10 @@ func (l *AgentService) CommissionPricing(ctx context.Context, descendantId int64
// 拥有则查看该上级设定的成本
agentMembershipUserConfigModel, findAgentMembershipUserConfigModelErr := l.AgentMembershipUserConfigModel.FindOneByAgentIdProductId(ctx, AncestorId, productID)
if findAgentMembershipUserConfigModelErr != nil {
// 如果上级没有配置该产品的定价规则,则跳过成本计算
if errors.Is(findAgentMembershipUserConfigModelErr, model.ErrNotFound) {
return 0, nil
}
return 0, findAgentMembershipUserConfigModelErr
}
@@ -522,3 +532,57 @@ func (l *AgentService) GiveWithdrawReward(ctx context.Context, agentID int64, wi
return nil
}
// CheckAgentProcessStatus 检查代理处理事务是否已成功
func (l *AgentService) CheckAgentProcessStatus(ctx context.Context, orderID int64) (bool, error) {
// 检查是否存在代理订单记录
_, err := l.AgentOrderModel.FindOneByOrderId(ctx, orderID)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
// 没有代理订单记录,说明不是代理推广订单
return true, nil
}
return false, err
}
// 检查是否存在代理佣金记录
// 使用SelectBuilder查询该订单的佣金记录
selectBuilder := l.AgentCommissionModel.SelectBuilder()
selectBuilder = selectBuilder.Where("order_id = ?", orderID)
selectBuilder = selectBuilder.Where("del_state = ?", 0) // 未删除
commissions, err := l.AgentCommissionModel.FindAll(ctx, selectBuilder, "")
if err != nil {
return false, err
}
// 如果存在佣金记录,说明代理处理已成功
return len(commissions) > 0, nil
}
// RetryAgentProcess 重新执行代理处理事务
func (l *AgentService) RetryAgentProcess(ctx context.Context, orderID int64) error {
// 首先检查订单是否存在
order, err := l.OrderModel.FindOne(ctx, orderID)
if err != nil {
return err
}
// 检查订单状态是否为已支付
if order.Status != "paid" {
return errors.New("订单状态不是已支付,无法执行代理处理")
}
// 检查代理处理是否已经成功
alreadyProcessed, err := l.CheckAgentProcessStatus(ctx, orderID)
if err != nil {
return err
}
if alreadyProcessed {
return errors.New("代理处理已经成功,无需重新执行")
}
// 执行代理处理
return l.AgentProcess(ctx, order)
}

View File

@@ -192,7 +192,7 @@ func NewServiceContext(c config.Config) *ServiceContext {
apiRequestService := service.NewApiRequestService(c, featureModel, productFeatureModel, tianyuanapi)
verificationService := service.NewVerificationService(c, tianyuanapi, apiRequestService)
asynqService := service.NewAsynqService(c)
agentService := service.NewAgentService(c, agentModel, agentAuditModel, agentClosureModel,
agentService := service.NewAgentService(c, orderModel, agentModel, agentAuditModel, agentClosureModel,
agentCommissionModel, agentCommissionDeductionModel, agentWalletModel, agentLinkModel,
agentOrderModel, agentRewardsModel, agentMembershipConfigModel, agentMembershipRechargeOrderModel,
agentMembershipUserConfigModel, agentProductConfigModel, agentPlatformDeductionModel,

View File

@@ -1,4 +1,6 @@
// Code generated by goctl. DO NOT EDIT.
// goctl 1.8.4
package types
type ActiveReward struct {
@@ -433,20 +435,22 @@ type AdminGetOrderDetailReq struct {
}
type AdminGetOrderDetailResp struct {
Id int64 `json:"id"` // 订单ID
OrderNo string `json:"order_no"` // 商户订单号
PlatformOrderId string `json:"platform_order_id"` // 支付订单号
ProductName string `json:"product_name"` // 产品名称
PaymentPlatform string `json:"payment_platform"` // 支付方式
PaymentScene string `json:"payment_scene"` // 支付平台
Amount float64 `json:"amount"` // 金额
Status string `json:"status"` // 支付状态pending-待支付paid-已支付refunded-已退款closed-已关闭failed-支付失败
QueryState string `json:"query_state"` // 查询状态pending-待查询success-查询成功failed-查询失败 processing-查询中
CreateTime string `json:"create_time"` // 创建时间
PayTime string `json:"pay_time"` // 支付时间
RefundTime string `json:"refund_time"` // 退款时间
IsPromotion int64 `json:"is_promotion"` // 是否推广订单0-否1-是
UpdateTime string `json:"update_time"` // 更新时间
Id int64 `json:"id"` // 订单ID
OrderNo string `json:"order_no"` // 商户订单号
PlatformOrderId string `json:"platform_order_id"` // 支付订单号
ProductName string `json:"product_name"` // 产品名称
PaymentPlatform string `json:"payment_platform"` // 支付方式
PaymentScene string `json:"payment_scene"` // 支付平台
Amount float64 `json:"amount"` // 金额
Status string `json:"status"` // 支付状态pending-待支付paid-已支付refunded-已退款closed-已关闭failed-支付失败
QueryState string `json:"query_state"` // 查询状态pending-待查询success-查询成功failed-查询失败 processing-查询中
CreateTime string `json:"create_time"` // 创建时间
PayTime string `json:"pay_time"` // 支付时间
RefundTime string `json:"refund_time"` // 退款时间
IsPromotion int64 `json:"is_promotion"` // 是否推广订单0-否1-是
UpdateTime string `json:"update_time"` // 更新时间
IsAgentOrder bool `json:"is_agent_order"` // 是否是代理订单
AgentProcessStatus string `json:"agent_process_status"` // 代理事务处理状态not_agent-非代理订单success-处理成功failed-处理失败pending-待处理
}
type AdminGetOrderListReq struct {
@@ -680,6 +684,16 @@ type AdminResetPasswordResp struct {
Success bool `json:"success"` // 是否成功
}
type AdminRetryAgentProcessReq struct {
Id int64 `path:"id"` // 订单ID
}
type AdminRetryAgentProcessResp struct {
Status string `json:"status"` // 执行状态success-成功already_processed-已处理failed-失败
Message string `json:"message"` // 执行结果消息
ProcessedAt string `json:"processed_at"` // 处理时间
}
type AdminRoleApiInfo struct {
Id int64 `json:"id"`
RoleId int64 `json:"role_id"`
@@ -1581,19 +1595,21 @@ type NotificationListItem struct {
}
type OrderListItem struct {
Id int64 `json:"id"` // 订单ID
OrderNo string `json:"order_no"` // 商户订单号
PlatformOrderId string `json:"platform_order_id"` // 支付订单号
ProductName string `json:"product_name"` // 产品名称
PaymentPlatform string `json:"payment_platform"` // 支付方式
PaymentScene string `json:"payment_scene"` // 支付平台
Amount float64 `json:"amount"` // 金额
Status string `json:"status"` // 支付状态pending-待支付paid-已支付refunded-已退款closed-已关闭failed-支付失败
QueryState string `json:"query_state"` // 查询状态pending-待查询success-查询成功failed-查询失败 processing-查询中
CreateTime string `json:"create_time"` // 创建时间
PayTime string `json:"pay_time"` // 支付时间
RefundTime string `json:"refund_time"` // 退款时间
IsPromotion int64 `json:"is_promotion"` // 是否推广订单0-否1-是
Id int64 `json:"id"` // 订单ID
OrderNo string `json:"order_no"` // 商户订单号
PlatformOrderId string `json:"platform_order_id"` // 支付订单号
ProductName string `json:"product_name"` // 产品名称
PaymentPlatform string `json:"payment_platform"` // 支付方式
PaymentScene string `json:"payment_scene"` // 支付平台
Amount float64 `json:"amount"` // 金额
Status string `json:"status"` // 支付状态pending-待支付paid-已支付refunded-已退款closed-已关闭failed-支付失败
QueryState string `json:"query_state"` // 查询状态pending-待查询success-查询成功failed-查询失败 processing-查询中
CreateTime string `json:"create_time"` // 创建时间
PayTime string `json:"pay_time"` // 支付时间
RefundTime string `json:"refund_time"` // 退款时间
IsPromotion int64 `json:"is_promotion"` // 是否推广订单0-否1-是
IsAgentOrder bool `json:"is_agent_order"` // 是否是代理订单
AgentProcessStatus string `json:"agent_process_status"` // 代理事务处理状态not_agent-非代理订单success-处理成功failed-处理失败pending-待处理
}
type PaymentCheckReq struct {