package service import ( "context" "encoding/json" "strings" "affiliate_dash/internal/model" ) func (s *DeliveryService) CancelUpstream(order *model.FulfillmentOrder) error { if order == nil || s.router == nil { return nil } if name := resultDataString(order.ResultData, "provider"); name != "" { if p := s.router.GetProvider(name); p != nil { return p.Cancel(context.Background(), order) } } if resultDataString(order.ResultData, "lewan_order_id") != "" { if p := s.router.GetProvider(ProviderLewan); p != nil { return p.Cancel(context.Background(), order) } } return nil } // SyncDeliveringOrder 主动向上游渠道查询处于 delivering 状态的订单结果,以补充 Webhook 丢失或延迟。 func (s *DeliveryService) SyncDeliveringOrder(ctx context.Context, order *model.FulfillmentOrder) (bool, error) { if order == nil || s.router == nil || order.OrderStatus != model.OrderStatusDelivering { return false, nil } if ctx == nil { ctx = context.Background() } providerName := resultDataString(order.ResultData, "provider") if providerName == "" && (resultDataString(order.ResultData, "lewan_order_id") != "" || resultDataString(order.ResultData, "lewan_order_no") != "" || strings.HasPrefix(order.ProviderOrderNo, "OMU")) { providerName = ProviderLewan } providers := make([]FulfillmentProvider, 0, 2) if providerName != "" { if p := s.router.GetProvider(providerName); p != nil { providers = append(providers, p) } } if len(providers) == 0 { resolved, _ := s.router.ResolveProviders(order) providers = resolved } for _, p := range providers { res, err := p.SyncStatus(ctx, order) if err != nil || res == nil { continue } if res.Status == "success" || res.Status == "failed" { input := ShipNotifyInput{ OrderNo: order.OrderNo, ShipStatus: res.Status, ProviderOrderNo: res.ProviderOrderNo, FailReason: res.FailReason, RawPayload: res.RawPayload, } if res.GameUID != "" { input.GameUID = &res.GameUID } if res.RoleName != "" { input.RoleName = &res.RoleName } if res.RoleArea != "" { input.GameChannel = &res.RoleArea } if _, err := s.fulfillment.HandleShipNotify(input); err != nil { return false, err } return true, nil } // 如果仍在发货中,且获得了游戏UID/角色名/区服,补充写入 ResultData patch := map[string]interface{}{} if res.GameUID != "" && resultDataString(order.ResultData, "game_uid") == "" { patch["game_uid"] = res.GameUID } if res.RoleName != "" && resultDataString(order.ResultData, "role_name") == "" { patch["role_name"] = res.RoleName } if res.RoleArea != "" && resultDataString(order.ResultData, "game_channel") == "" { patch["game_channel"] = res.RoleArea } if len(patch) > 0 { _ = s.persistOrderResultPatch(order, patch) } return false, nil } return false, nil } // persistOrderResultPatch 合并写入订单 result_data,不改变发货 stage。 func (s *DeliveryService) persistOrderResultPatch(order *model.FulfillmentOrder, patch map[string]interface{}) error { if order == nil || len(patch) == 0 { return nil } resultData := mergeResultData(order.ResultData, patch) if err := s.fulfillment.db.Model(&model.FulfillmentOrder{}). Where("id = ?", order.ID). Update("result_data", resultData).Error; err != nil { return err } order.ResultData = resultData return nil } func (s *DeliveryService) clearSelectedProvider(order *model.FulfillmentOrder) { if order == nil || strings.TrimSpace(order.ResultData) == "" { return } var raw map[string]interface{} if err := json.Unmarshal([]byte(order.ResultData), &raw); err != nil { return } if _, ok := raw["provider"]; !ok { return } delete(raw, "provider") b, err := json.Marshal(raw) if err != nil { return } resultData := string(b) _ = s.fulfillment.db.Model(&model.FulfillmentOrder{}). Where("id = ?", order.ID). Update("result_data", resultData).Error order.ResultData = resultData }