package service import ( "bytes" "encoding/json" "errors" "fmt" "io" "net/http" "strings" ) func (s *DeliveryService) goodsDetail(goodID string) (map[string]interface{}, error) { var out struct { Good map[string]interface{} `json:"good"` } if err := s.signProxy("/public/goods/detail", "POST", map[string]interface{}{ "good_id": goodID, }, &out); err != nil { return nil, err } return out.Good, nil } func (s *DeliveryService) accountBound(bindUUID, goodID string) (map[string]interface{}, error) { var out struct { GameAccount map[string]interface{} `json:"gameAccount"` Snake map[string]interface{} `json:"game_account"` } if err := s.signProxy("/public/games/account-bound", "POST", map[string]interface{}{ "bind_uuid": bindUUID, "bindUuid": bindUUID, "goodId": goodID, "good_id": goodID, }, &out); err != nil { return nil, err } if out.GameAccount == nil { out.GameAccount = out.Snake } if out.GameAccount == nil { return nil, errors.New("账号尚未绑定,请扫码完成绑定后再提交") } return out.GameAccount, nil } func (s *DeliveryService) createOrderQueue(goodID, orderNo string) (string, error) { var out struct { Orders []map[string]interface{} `json:"orders"` } if err := s.signProxy("/public/users/orders-queue", "POST", map[string]interface{}{ "good_id": goodID, "quantity": 1, "order_sn": orderNo, }, &out); err != nil { return "", err } if len(out.Orders) == 0 { return "", errors.New("发货服务未返回队列订单") } orderID := firstNonEmpty(stringFromMap(out.Orders[0], "_id"), stringFromMap(out.Orders[0], "id")) if orderID == "" { return "", errors.New("发货服务未返回队列订单 ID") } return orderID, nil } func (s *DeliveryService) patchOrderQueue(orderID, gameAccount, bindUUID string) error { var out map[string]interface{} return s.signProxy("/public/users/orders-queue", "PATCH", map[string]interface{}{ "order_id": orderID, "game_account": gameAccount, "bind_uuid": bindUUID, }, &out) } func (s *DeliveryService) createUpstreamOrder(orderID, gameAccount, goodID, orderNo string) (map[string]interface{}, error) { var out struct { Order map[string]interface{} `json:"order"` } if err := s.signProxy("/public/users/orders", "POST", map[string]interface{}{ "order_id": orderID, "game_account": gameAccount, "good_id": goodID, "h5_prefix": s.channel, "order_sn": orderNo, }, &out); err != nil { return nil, err } if out.Order == nil { out.Order = map[string]interface{}{"order_id": orderID, "order_sn": orderNo} } return out.Order, nil } func (s *DeliveryService) signProxy(path, method string, data interface{}, out interface{}) error { payload, err := json.Marshal(map[string]interface{}{ "path": path, "method": strings.ToUpper(method), "data": data, }) if err != nil { return err } req, err := http.NewRequest(http.MethodPost, s.bffBaseURL+"/sign-proxy", bytes.NewReader(payload)) if err != nil { return err } req.Header.Set("Content-Type", "application/json") resp, err := s.httpClient.Do(req) if err != nil { return fmt.Errorf("发货服务请求失败:%w", err) } defer resp.Body.Close() body, _ := io.ReadAll(io.LimitReader(resp.Body, 1<<20)) var envelope struct { Code interface{} `json:"code"` Message string `json:"message"` Data json.RawMessage `json:"data"` } if err := json.Unmarshal(body, &envelope); err != nil { return fmt.Errorf("发货服务响应无法解析:%s", truncateDeliveryText(string(body))) } if resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusMultipleChoices || !isZeroCode(envelope.Code) { if envelope.Message != "" { return errors.New(envelope.Message) } return fmt.Errorf("发货服务请求失败:HTTP %d", resp.StatusCode) } if out == nil || len(envelope.Data) == 0 || string(envelope.Data) == "null" { return nil } if err := json.Unmarshal(envelope.Data, out); err != nil { return fmt.Errorf("发货服务数据无法解析:%w", err) } return nil }