Files
affiliate_dash/backend/internal/service/delivery_provider.go
T
yml2213 24fa6a97a0 refactor(delivery): 按职责拆分 delivery.go(1162 → 最大 249 行)
纯文件级移动,无行为变更:
- delivery.go            常量、DeliveryService 结构、构造与依赖注入
- delivery_types.go      对外 DTO 与 deliveryHTTPError
- delivery_provider.go   渠道取消/同步与 result_data 维护
- delivery_query.go      订单查询与发货状态构建
- delivery_bind.go       绑定与绑定结果查询
- delivery_submit.go     提交发货与提交阶段状态机
- deliveryGoodID 并入 delivery_helpers.go,链接管理并入 delivery_link.go

校验:拆分前后 55 个 func/type/const 声明完全一致(无缺失、无多出、无重复)。
2026-10-06 19:43:05 +08:00

136 lines
3.9 KiB
Go

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
}