package service import ( "context" "errors" "net/http" "strings" "affiliate_dash/internal/model" ) func (s *DeliveryService) GetOrder(orderNo string, auth DeliveryLinkAuth) (*DeliveryOrderInfo, error) { info, _, _, err := s.prepareOrder(orderNo, false, &auth) return info, err } func (s *DeliveryService) GetMerchantOrder(merchantID uint, orderNo string) (*DeliveryOrderInfo, error) { openOrder, order, goodID, err := s.loadMerchantOrder(merchantID, orderNo) if err != nil { return nil, err } info, _, _, err := s.buildDeliveryState(openOrder, order, goodID, false) return info, err } func (s *DeliveryService) loadLinkedOrder(orderNo string, auth *DeliveryLinkAuth) (*OpenOrderQuery, *model.FulfillmentOrder, string, error) { openOrder, err := s.fulfillment.QueryOpenOrder(orderNo) if err != nil { return nil, nil, "", err } order, err := s.fulfillment.GetByOrderNo(orderNo) if err != nil { return nil, nil, "", err } if auth != nil { if err := s.authorizeDeliveryLink(order, *auth); err != nil { return nil, nil, "", err } } goodID := "" if openOrder.Product != nil { goodID = deliveryGoodID(s.channel, openOrder.Product.SKU) } return openOrder, order, goodID, nil } func (s *DeliveryService) loadMerchantOrder(merchantID uint, orderNo string) (*OpenOrderQuery, *model.FulfillmentOrder, string, error) { if merchantID == 0 { return nil, nil, "", errors.New("无效的商户") } openOrder, err := s.fulfillment.QueryOpenOrder(orderNo) if err != nil { return nil, nil, "", err } order, err := s.fulfillment.GetOrder(merchantID, orderNo) if err != nil { return nil, nil, "", err } if order.OrderStatus == model.OrderStatusDelivering { if synced, _ := s.SyncDeliveringOrder(context.Background(), order); synced { openOrder, _ = s.fulfillment.QueryOpenOrder(orderNo) order, _ = s.fulfillment.GetOrder(merchantID, orderNo) } } goodID := "" if openOrder != nil && openOrder.Product != nil { goodID = deliveryGoodID(s.channel, openOrder.Product.SKU) } return openOrder, order, goodID, nil } func (s *DeliveryService) buildDeliveryState(openOrder *OpenOrderQuery, order *model.FulfillmentOrder, goodID string, requireCanShip bool) (*DeliveryOrderInfo, *model.FulfillmentOrder, string, error) { if openOrder == nil || order == nil { return nil, nil, "", errors.New("订单不存在") } canShip, reason := CanFulfill(order) if !openOrder.CanShip { reason = openOrder.CannotShipReason canShip = false } if !canShip && reason == "" { reason = "订单暂不可发货" } if openOrder.Product == nil || openOrder.Product.SKU == "" { canShip = false reason = "订单缺少商品 SKU" } var ( deliveryProd *DeliveryProduct goodData map[string]interface{} ) providers, _ := s.router.ResolveProviders(order) if len(providers) > 0 { locked := resultDataString(order.ResultData, "provider") != "" matchedState, lastReason := s.tryPrepareProviders(order, openOrder, providers) // 已锁定渠道不可发时,清除锁定并按完整优先级重新选择 if matchedState == nil && locked { s.clearSelectedProvider(order) providers, _ = s.router.ResolveProviders(order) matchedState, lastReason = s.tryPrepareProviders(order, openOrder, providers) } if matchedState != nil { deliveryProd = matchedState.Product goodData = matchedState.Good if matchedState.Provider != "" { _ = s.persistOrderResultPatch(order, map[string]interface{}{ "provider": matchedState.Provider, }) } } else { canShip = false if reason == "" || reason == "订单暂不可发货" { reason = lastReason if reason == "" { reason = "未找到适用的履约渠道配置" } } } } else if goodID != "" { goodData, _ = s.goodsDetail(goodID) } if deliveryProd == nil && openOrder.Product != nil { deliveryProd = buildDeliveryProduct(openOrder.Product, goodData) } if requireCanShip && !canShip { return nil, nil, "", newDeliveryHTTPError(http.StatusBadRequest, reason) } providerOrderNo := strings.TrimSpace(openOrder.ProviderOrderNo) if providerOrderNo == "" { providerOrderNo = strings.TrimSpace(order.ProviderOrderNo) } if providerOrderNo == "" { providerOrderNo = resultDataString(order.ResultData, "lewan_order_no") } if providerOrderNo == "" { providerOrderNo = resultDataString(order.ResultData, "provider_order_no") } providerName := resultDataString(order.ResultData, "provider") if providerName == "" { if strings.TrimSpace(order.ProviderOrderNo) != "" || resultDataString(order.ResultData, "lewan_order_id") != "" { providerName = "lewan" } } roleName := openOrder.RoleName if roleName == "" { roleName = resultDataString(order.ResultData, "role_name") } gameChannel := openOrder.GameChannel if gameChannel == "" { gameChannel = resultDataString(order.ResultData, "game_channel") } // 若角色名或区服为空,尝试从关联的 rock_tokens 表反查并自动回填 if (roleName == "" || gameChannel == "") && s.fulfillment != nil && s.fulfillment.db != nil { var rockToken model.RockToken if err := s.fulfillment.db.Unscoped().Where("assigned_order_no = ?", order.OrderNo).First(&rockToken).Error; err == nil { patches := map[string]interface{}{} if roleName == "" && rockToken.ActualRoleName != "" { roleName = rockToken.ActualRoleName patches["role_name"] = roleName } if gameChannel == "" && rockToken.ActualChannel != "" { gameChannel = rockToken.ActualChannel patches["game_channel"] = gameChannel } if len(patches) > 0 { _ = s.persistOrderResultPatch(order, patches) } } } info := &DeliveryOrderInfo{ OrderNo: openOrder.OrderNo, Status: openOrder.Status, CanShip: canShip, CannotShipReason: reason, Product: deliveryProd, BuyerName: openOrder.BuyerName, Amount: openOrder.Amount, ProviderOrderNo: providerOrderNo, ProviderName: providerName, CreatedAt: openOrder.CreatedAt, ShippedAt: openOrder.ShippedAt, ShipFailReason: openOrder.ShipFailReason, GameChannel: gameChannel, GameUID: openOrder.GameUID, RoleName: roleName, PayScore: openOrder.PayScore, Data: requestDataMap(order.RequestData), Good: goodData, } return info, order, goodID, nil } // tryPrepareProviders 按优先级尝试 Prepare,返回第一个 CanShip 的渠道状态。 func (s *DeliveryService) tryPrepareProviders(order *model.FulfillmentOrder, openOrder *OpenOrderQuery, providers []FulfillmentProvider) (*DeliveryOrderState, string) { lastReason := "" for _, p := range providers { state, err := p.PrepareDelivery(context.Background(), order, openOrder) if err != nil || state == nil { continue } if state.Provider == "" { state.Provider = p.Name() } if state.CanShip { return state, "" } if state.CannotShipReason != "" { lastReason = state.CannotShipReason } } return nil, lastReason } func (s *DeliveryService) prepareOrder(orderNo string, requireCanShip bool, auth *DeliveryLinkAuth) (*DeliveryOrderInfo, *model.FulfillmentOrder, string, error) { orderNo = strings.TrimSpace(orderNo) if orderNo == "" { return nil, nil, "", errors.New("订单号不能为空") } openOrder, err := s.fulfillment.QueryOpenOrder(orderNo) if err != nil { return nil, nil, "", err } order, err := s.fulfillment.GetByOrderNo(orderNo) if err != nil { return nil, nil, "", err } if auth != nil { if err := s.authorizeDeliveryLink(order, *auth); err != nil { return nil, nil, "", err } } if order.OrderStatus == model.OrderStatusDelivering { if synced, _ := s.SyncDeliveringOrder(context.Background(), order); synced { openOrder, _ = s.fulfillment.QueryOpenOrder(orderNo) order, _ = s.fulfillment.GetByOrderNo(orderNo) } } return s.buildDeliveryState(openOrder, order, "", requireCanShip) }