回收遇无权限号码直接清空任务绑定不再重试:已手动退号的旧绑定一次性收敛,发货收尾视号码已释放

This commit is contained in:
yml2213
2026-08-08 14:59:23 +08:00
parent 2b3954d0e3
commit 5a1c5a3759
2 changed files with 128 additions and 78 deletions
@@ -60,11 +60,31 @@ export async function returnKuaishouCloudFulfillmentTask(
return { task, flow }
}
await backCloudtentaclesVirtualNumber({
...cloudContext,
key: flow.binding.vnKey,
id: flow.binding.vnId,
})
try {
await backCloudtentaclesVirtualNumber({
...cloudContext,
key: flow.binding.vnKey,
id: flow.binding.vnId,
})
} catch (error) {
// 号码已被上游回收/手动退回/账号换 token 无权限:视为已释放,继续完成核销收尾
if (isNumberAlreadyReleasedError(error)) {
await createTaskEvent(
task.id,
'kuaishou_cloud_number_already_released',
{
source: String(options.source || 'system').trim() || 'system',
vnId: flow.binding.vnId,
vnPhoneMasked: maskPhone(flow.binding.vnPhone),
errorMessage: error instanceof Error ? error.message : String(error || ''),
actor,
},
now
)
} else {
throw error
}
}
const ticketCode = String(flow.ticket.code || '').trim()
let consumeStatus = 'pending'
@@ -236,8 +256,7 @@ export async function returnKuaishouCloudFulfillmentTask(
}
}
function hasKuaishouIndustryVoucherContext(value: JsonObject): boolean {
const voucher = isPlainObject(value.kuaishouIndustryVoucher)
function hasKuaishouIndustryVoucherContext(value: JsonObject): boolean { const voucher = isPlainObject(value.kuaishouIndustryVoucher)
? value.kuaishouIndustryVoucher
: {}
const voucherCode = String(voucher.voucherCode || voucher.eticketId || '').trim()
@@ -249,3 +268,16 @@ function hasKuaishouIndustryVoucherContext(value: JsonObject): boolean {
function isPlainObject(value: unknown): value is JsonObject {
return Boolean(value) && typeof value === 'object' && !Array.isArray(value)
}
/** 号码已被上游回收/手动退回/账号换 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('已退还')
)
}