fix(delivery): 绑定失败回退 DLC,并补齐乐玩角色名展示
乐玩写接口失败时清除渠道锁定改试 DLC;免扫码/查绑/提交路径回传 role_name 与 game_channel。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -415,7 +415,9 @@ func (s *DeliveryService) bindWithOrder(orderNo, gameAccount string, auth *Deliv
|
||||
var lastErr error
|
||||
var bindRes *ProviderBindResult
|
||||
var usedProvider FulfillmentProvider
|
||||
tried := map[string]bool{}
|
||||
for _, p := range providers {
|
||||
tried[p.Name()] = true
|
||||
res, err := p.Bind(context.Background(), order, gameAccount)
|
||||
if err == nil && res != nil {
|
||||
bindRes = res
|
||||
@@ -424,6 +426,29 @@ func (s *DeliveryService) bindWithOrder(orderNo, gameAccount string, auth *Deliv
|
||||
}
|
||||
lastErr = err
|
||||
}
|
||||
|
||||
// Prepare 可能因 GET 成功先锁住乐玩;随后写接口凭据/IP 校验失败时,清除锁定并尝试其余渠道(如 DLC)。
|
||||
if bindRes == nil {
|
||||
lockedName := resultDataString(order.ResultData, "provider")
|
||||
if lockedName != "" || lastErr != nil {
|
||||
s.clearSelectedProvider(order)
|
||||
fallbackProviders, _ := s.router.ResolveProviders(order)
|
||||
for _, p := range fallbackProviders {
|
||||
if tried[p.Name()] {
|
||||
continue
|
||||
}
|
||||
tried[p.Name()] = true
|
||||
res, err := p.Bind(context.Background(), order, gameAccount)
|
||||
if err == nil && res != nil {
|
||||
bindRes = res
|
||||
usedProvider = p
|
||||
break
|
||||
}
|
||||
lastErr = err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if bindRes == nil {
|
||||
if lastErr != nil {
|
||||
return nil, lastErr
|
||||
|
||||
@@ -181,11 +181,39 @@ func (p *LewanProvider) Bind(ctx context.Context, order *model.FulfillmentOrder,
|
||||
|
||||
// 3. 判断是否需要绑定
|
||||
if bindingAction != nil && !bindingAction.BindingRequired {
|
||||
// 角色已在乐玩绑定过,免扫码直接已绑定
|
||||
// 角色已在乐玩绑定过,免扫码直接已绑定;尽量补齐角色名/区服,便于领取页展示。
|
||||
roleName, gameChannel, boundRoleID := extractLewanRoleDisplay(lewanOrder, nil)
|
||||
if refreshRes, refreshErr := p.client.RefreshBinding(ctx, lewanOrderID); refreshErr == nil {
|
||||
rn, gc, rid := extractLewanRoleDisplay(nil, refreshRes)
|
||||
if rn != "" {
|
||||
roleName = rn
|
||||
}
|
||||
if gc != "" {
|
||||
gameChannel = gc
|
||||
}
|
||||
if rid != "" {
|
||||
boundRoleID = rid
|
||||
}
|
||||
}
|
||||
if roleName != "" {
|
||||
patch["role_name"] = roleName
|
||||
}
|
||||
if gameChannel != "" {
|
||||
patch["game_channel"] = gameChannel
|
||||
}
|
||||
bindURL := strings.TrimSpace(bindingAction.BindingUrl)
|
||||
qrURL := ""
|
||||
if bindURL != "" {
|
||||
qrURL = qrCodeURL(bindURL)
|
||||
}
|
||||
return &ProviderBindResult{
|
||||
BindUUID: lewanOrderID,
|
||||
BindURL: bindURL,
|
||||
QRURL: qrURL,
|
||||
Bound: true,
|
||||
GameAccount: gameAccount,
|
||||
GameAccount: firstNonEmpty(boundRoleID, gameAccount),
|
||||
RoleName: roleName,
|
||||
GameChannel: gameChannel,
|
||||
Message: "账号已在平台授权,免扫码直接进入发货",
|
||||
Provider: ProviderLewan,
|
||||
PatchResultData: patch,
|
||||
@@ -231,10 +259,13 @@ func (p *LewanProvider) CheckBind(ctx context.Context, order *model.FulfillmentO
|
||||
orderDetail, getErr := p.client.GetOrder(ctx, lewanOrderID)
|
||||
if getErr == nil && orderDetail != nil {
|
||||
if orderDetail.Status != "WAITING_BINDING" {
|
||||
roleName, gameChannel, boundRoleID := extractLewanRoleDisplay(orderDetail, nil)
|
||||
return &ProviderBindResult{
|
||||
BindUUID: lewanOrderID,
|
||||
Bound: true,
|
||||
GameAccount: orderDetail.RoleID,
|
||||
GameAccount: firstNonEmpty(boundRoleID, orderDetail.RoleID),
|
||||
RoleName: roleName,
|
||||
GameChannel: gameChannel,
|
||||
Message: "绑定已完成",
|
||||
Provider: ProviderLewan,
|
||||
}, nil
|
||||
@@ -251,13 +282,27 @@ func (p *LewanProvider) CheckBind(ctx context.Context, order *model.FulfillmentO
|
||||
bound := false
|
||||
gameAccount := ""
|
||||
roleName := ""
|
||||
gameChannel := ""
|
||||
if refreshRes != nil && refreshRes.Binding != nil {
|
||||
bound = refreshRes.Binding.Matched
|
||||
gameAccount = refreshRes.Binding.RoleID
|
||||
roleName = refreshRes.Binding.RoleName
|
||||
gameChannel = firstNonEmpty(refreshRes.Binding.RoleArea, refreshRes.Binding.ServerName)
|
||||
}
|
||||
if refreshRes != nil && refreshRes.Order != nil && refreshRes.Order.Status != "WAITING_BINDING" {
|
||||
bound = true
|
||||
if refreshRes != nil && refreshRes.Order != nil {
|
||||
if refreshRes.Order.Status != "WAITING_BINDING" {
|
||||
bound = true
|
||||
}
|
||||
rn, gc, rid := extractLewanRoleDisplay(refreshRes.Order, nil)
|
||||
if roleName == "" {
|
||||
roleName = rn
|
||||
}
|
||||
if gameChannel == "" {
|
||||
gameChannel = gc
|
||||
}
|
||||
if gameAccount == "" {
|
||||
gameAccount = rid
|
||||
}
|
||||
}
|
||||
|
||||
msg := "绑定成功"
|
||||
@@ -270,6 +315,7 @@ func (p *LewanProvider) CheckBind(ctx context.Context, order *model.FulfillmentO
|
||||
Bound: bound,
|
||||
GameAccount: gameAccount,
|
||||
RoleName: roleName,
|
||||
GameChannel: gameChannel,
|
||||
Message: msg,
|
||||
Provider: ProviderLewan,
|
||||
}, nil
|
||||
@@ -323,8 +369,19 @@ func (p *LewanProvider) Submit(ctx context.Context, order *model.FulfillmentOrde
|
||||
}
|
||||
|
||||
roleName := ""
|
||||
gameChannel := ""
|
||||
if refreshRes != nil && refreshRes.Binding != nil {
|
||||
roleName = refreshRes.Binding.RoleName
|
||||
gameChannel = firstNonEmpty(refreshRes.Binding.RoleArea, refreshRes.Binding.ServerName)
|
||||
}
|
||||
if roleName == "" || gameChannel == "" {
|
||||
rn, gc, _ := extractLewanRoleDisplay(lewanOrder, nil)
|
||||
if roleName == "" {
|
||||
roleName = rn
|
||||
}
|
||||
if gameChannel == "" {
|
||||
gameChannel = gc
|
||||
}
|
||||
}
|
||||
|
||||
return &ProviderSubmitResult{
|
||||
@@ -334,6 +391,7 @@ func (p *LewanProvider) Submit(ctx context.Context, order *model.FulfillmentOrde
|
||||
GameAccount: map[string]interface{}{
|
||||
"game_account": gameAccount,
|
||||
"role_name": roleName,
|
||||
"game_channel": gameChannel,
|
||||
},
|
||||
UpstreamOrder: lewanOrder,
|
||||
PatchResultData: map[string]interface{}{
|
||||
@@ -345,6 +403,7 @@ func (p *LewanProvider) Submit(ctx context.Context, order *model.FulfillmentOrde
|
||||
"lewan_status": lewanOrder.Status,
|
||||
"game_uid": gameAccount,
|
||||
"role_name": roleName,
|
||||
"game_channel": gameChannel,
|
||||
"delivery": lewanOrder,
|
||||
},
|
||||
}, nil
|
||||
@@ -472,3 +531,35 @@ func (p *LewanProvider) SyncStatus(ctx context.Context, order *model.Fulfillment
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// extractLewanRoleDisplay 从乐玩订单/刷新结果提取角色名、区服与 RoleID,供领取页展示。
|
||||
func extractLewanRoleDisplay(
|
||||
order *lewan.LewanOrder,
|
||||
refresh *lewan.RefreshBindingResult,
|
||||
) (roleName, gameChannel, roleID string) {
|
||||
if refresh != nil && refresh.Binding != nil {
|
||||
roleName = strings.TrimSpace(refresh.Binding.RoleName)
|
||||
gameChannel = firstNonEmpty(refresh.Binding.RoleArea, refresh.Binding.ServerName)
|
||||
roleID = strings.TrimSpace(refresh.Binding.RoleID)
|
||||
}
|
||||
if refresh != nil && refresh.Order != nil && order == nil {
|
||||
order = refresh.Order
|
||||
}
|
||||
if order != nil {
|
||||
if roleID == "" {
|
||||
roleID = strings.TrimSpace(order.RoleID)
|
||||
}
|
||||
if order.Binding != nil {
|
||||
if roleName == "" {
|
||||
roleName = strings.TrimSpace(order.Binding.RoleName)
|
||||
}
|
||||
if gameChannel == "" {
|
||||
gameChannel = firstNonEmpty(order.Binding.RoleArea, order.Binding.ServerName)
|
||||
}
|
||||
if roleID == "" {
|
||||
roleID = strings.TrimSpace(order.Binding.RoleID)
|
||||
}
|
||||
}
|
||||
}
|
||||
return roleName, gameChannel, roleID
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user