失效号码清理下沉到刷新流程:所有触发路径(claim轮询/91交付/回收/后台)遇无权限号码统一清空绑定,不再反复打上游
This commit is contained in:
@@ -484,8 +484,21 @@ export async function refreshKuaishouCloudTaskBindUrl(task: TaskRow, options: Js
|
|||||||
mode: 'reuse_existing_vn',
|
mode: 'reuse_existing_vn',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch (error) {
|
||||||
// 同号取链失败则走退号换号
|
// 号码已退/已回收/无权限:直接清空绑定,不再走退号换号(避免反复打上游)
|
||||||
|
if (isNumberAlreadyReleasedError(error)) {
|
||||||
|
return clearKuaishouCloudStaleBinding(task, {
|
||||||
|
taskContext,
|
||||||
|
flow,
|
||||||
|
now,
|
||||||
|
actor,
|
||||||
|
source,
|
||||||
|
error,
|
||||||
|
claimUrl: claimLinkState.claimUrl,
|
||||||
|
token: claimLinkState.token || task.claim_token || '',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 其他错误走退号换号
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -512,6 +525,19 @@ export async function refreshKuaishouCloudTaskBindUrl(task: TaskRow, options: Js
|
|||||||
now,
|
now,
|
||||||
)
|
)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
// 号码已退/已回收/无权限:直接清空绑定(不再尝试取新号),避免反复打上游
|
||||||
|
if (isNumberAlreadyReleasedError(error)) {
|
||||||
|
return clearKuaishouCloudStaleBinding(task, {
|
||||||
|
taskContext,
|
||||||
|
flow,
|
||||||
|
now,
|
||||||
|
actor,
|
||||||
|
source,
|
||||||
|
error,
|
||||||
|
claimUrl: claimLinkState.claimUrl,
|
||||||
|
token: claimLinkState.token || task.claim_token || '',
|
||||||
|
})
|
||||||
|
}
|
||||||
oldNumberBackError = error instanceof Error ? error.message : String(error || '退号失败')
|
oldNumberBackError = error instanceof Error ? error.message : String(error || '退号失败')
|
||||||
const wrapped = wrapCloudtentaclesOperationError(error, {
|
const wrapped = wrapCloudtentaclesOperationError(error, {
|
||||||
action: 'vn_back',
|
action: 'vn_back',
|
||||||
@@ -743,3 +769,110 @@ async function markKuaishouCloudBindUrlRefreshFailed(
|
|||||||
|
|
||||||
return updatedTask
|
return updatedTask
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 号码已被上游回收/手动退回/账号换 token 后无操作权限:重试无意义,应清空任务绑定 */
|
||||||
|
function isNumberAlreadyReleasedError(error: unknown) {
|
||||||
|
const message = error instanceof Error ? error.message : String(error || '')
|
||||||
|
return (
|
||||||
|
message.includes('权限不足') ||
|
||||||
|
message.includes('没有权限') ||
|
||||||
|
message.includes('不存在') ||
|
||||||
|
message.includes('已释放') ||
|
||||||
|
message.includes('已回收') ||
|
||||||
|
message.includes('已退还')
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清空任务侧已失效的旧绑定(号码已退/已回收/无权限),任务下次领取时自动重新取号。
|
||||||
|
* 所有调用路径(claim 轮询 probe、open-91 交付、回收任务、后台刷新)统一收敛,
|
||||||
|
* 避免对失效号码反复打上游。
|
||||||
|
*/
|
||||||
|
async function clearKuaishouCloudStaleBinding(
|
||||||
|
task: TaskRow,
|
||||||
|
{
|
||||||
|
taskContext,
|
||||||
|
flow,
|
||||||
|
now,
|
||||||
|
actor,
|
||||||
|
source,
|
||||||
|
error,
|
||||||
|
claimUrl,
|
||||||
|
token,
|
||||||
|
}: {
|
||||||
|
taskContext: JsonObject
|
||||||
|
flow: ReturnType<typeof normalizeKuaishouCloudFlow>
|
||||||
|
now: string
|
||||||
|
actor: unknown
|
||||||
|
source: string
|
||||||
|
error: unknown
|
||||||
|
claimUrl: string
|
||||||
|
token: string
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
const errorMessage = error instanceof Error ? error.message : String(error || '绑定已失效')
|
||||||
|
const oldVnId = flow.binding.vnId
|
||||||
|
const oldVnPhone = flow.binding.vnPhone
|
||||||
|
const nextContext = {
|
||||||
|
...taskContext,
|
||||||
|
kuaishouCloudFulfillment: {
|
||||||
|
...flow,
|
||||||
|
binding: {
|
||||||
|
...flow.binding,
|
||||||
|
prepareStatus: 'pending',
|
||||||
|
vnId: 0,
|
||||||
|
vnPhone: '',
|
||||||
|
bindUrl: '',
|
||||||
|
bindPreparedAt: null,
|
||||||
|
bindExpiresAt: null,
|
||||||
|
bindProbeAt: now,
|
||||||
|
bindProbeStatus: 'stale_cleared',
|
||||||
|
bindProbeMessage: errorMessage,
|
||||||
|
roleName: '',
|
||||||
|
roleId: '',
|
||||||
|
},
|
||||||
|
role: {
|
||||||
|
status: 'pending',
|
||||||
|
name: '',
|
||||||
|
rid: '',
|
||||||
|
refreshedAt: now,
|
||||||
|
errorMessage: '旧绑定号码已失效,已清空绑定,将重新取号',
|
||||||
|
rawInfo: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatedTask = await updateTask(task.id, {
|
||||||
|
task_status:
|
||||||
|
normalizeTaskStatus(task.task_status) === TASK_STATUS.ROLE_CONFIRMED
|
||||||
|
? task.task_status
|
||||||
|
: TASK_STATUS.PENDING_BINDING_PREPARE,
|
||||||
|
role_id: '',
|
||||||
|
role_name: '',
|
||||||
|
last_error: `旧绑定号码已失效(${errorMessage}),已清空绑定`,
|
||||||
|
context_json: JSON.stringify(nextContext),
|
||||||
|
updated_at: now,
|
||||||
|
})
|
||||||
|
|
||||||
|
await createTaskEvent(
|
||||||
|
task.id,
|
||||||
|
'kuaishou_cloud_stale_binding_cleared',
|
||||||
|
{
|
||||||
|
source,
|
||||||
|
oldVnId,
|
||||||
|
oldVnPhoneMasked: maskPhone(oldVnPhone),
|
||||||
|
cloudSourceKey: flow.binding.resolvedSourceKey || flow.binding.cloudSourceKeys[0] || '',
|
||||||
|
errorMessage,
|
||||||
|
actor,
|
||||||
|
},
|
||||||
|
now
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
task: updatedTask || task,
|
||||||
|
claimUrl,
|
||||||
|
token,
|
||||||
|
flow: normalizeKuaishouCloudFlow(nextContext.kuaishouCloudFulfillment),
|
||||||
|
mode: 'stale_cleared',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user