增加飞飞领取短链

This commit is contained in:
yml2213
2026-07-07 21:13:37 +08:00
parent 4131d500f2
commit 58a902dd3b
12 changed files with 527 additions and 14 deletions
@@ -25,3 +25,19 @@ test('resolveKuaishouFeifeiClaimUrl does not expose local claim token fallback',
'',
)
})
test('resolveKuaishouFeifeiClaimUrl prefers internal short link', () => {
assert.equal(
resolveKuaishouFeifeiClaimUrl({
shortLink: {
code: 'AbCd1234',
url: 'https://ks.khhao.com/s/AbCd1234',
targetUrl: 'https://feifei.example.com/h5/bind?code=very-long',
},
h5: {
rechargeUrl: 'https://feifei.example.com/h5/bind?code=very-long',
},
}),
'https://ks.khhao.com/s/AbCd1234',
)
})
@@ -11,6 +11,11 @@ import {
} from '../../platforms/kuaishou-feifei/order-service.js'
import { consumeKuaishouIndustryVouchersForTask } from '../../platforms/kuaishou-industry/voucher-service.js'
import { buildKuaishouIndustryVoucherContext } from '../../platforms/kuaishou-industry/voucher-binding-service.js'
import {
SHORT_LINK_SOURCE_KUAISHOU_FEIFEI_CLAIM,
ensureShortLinkForTarget,
normalizeShortLinkPayload,
} from '../../short-links/short-link-service.js'
import type { TaskRow } from '../../../types/repository/rows.js'
type JsonObject = Record<string, any>
@@ -33,12 +38,10 @@ export async function prepareKuaishouFeifeiTask(task: TaskRow) {
const existingClaimUrl = resolveKuaishouFeifeiClaimUrl(flow)
if (flow.orderNo && existingClaimUrl) {
const nextFlow = await ensureKuaishouFeifeiFlowShortLink(flow, task)
const nextContext = {
...taskContext,
kuaishouFeifei: {
...flow,
claimUrl: existingClaimUrl,
},
kuaishouFeifei: nextFlow,
}
return updateTask(task.id, {
task_status: TASK_STATUS.LINK_GENERATED,
@@ -69,11 +72,11 @@ export async function prepareKuaishouFeifeiTask(task: TaskRow) {
})
}
const nextFlow = mergeKuaishouFeifeiOrder(flow, order, {
const nextFlow = await ensureKuaishouFeifeiFlowShortLink(mergeKuaishouFeifeiOrder(flow, order, {
platformOrderNo,
claimUrl: feifeiClaimUrl,
syncedAt: now,
})
}), task)
const updatedTask = await updateTask(task.id, {
task_status: TASK_STATUS.LINK_GENERATED,
user_action_status: 'pending_claim',
@@ -125,10 +128,10 @@ export async function syncKuaishouFeifeiTaskStatus(task: TaskRow) {
let resultCode = task.result_code
let resultMessage = task.result_message
let lastError = task.last_error
const nextFlow = mergeKuaishouFeifeiOrder(flow, order, {
const nextFlow = await ensureKuaishouFeifeiFlowShortLink(mergeKuaishouFeifeiOrder(flow, order, {
syncedAt: now,
claimUrl: resolveKuaishouFeifeiOrderClaimUrl(order) || resolveKuaishouFeifeiClaimUrl(flow),
})
}), task)
let nextIndustryVoucher = taskContext.kuaishouIndustryVoucher
if (order.rechargeStatus === 30) {
@@ -219,6 +222,7 @@ export function normalizeKuaishouFeifeiFlow(value: unknown) {
rechargeResultMessage: String(source.rechargeResultMessage || '').trim(),
claimUrl: String(source.claimUrl || '').trim(),
consumeStatus: String(source.consumeStatus || 'pending').trim(),
shortLink: normalizeShortLinkPayload(source.shortLink),
h5: {
entryUrl: String(h5.entryUrl || '').trim(),
rechargeUrl: String(h5.rechargeUrl || '').trim(),
@@ -230,12 +234,36 @@ export function normalizeKuaishouFeifeiFlow(value: unknown) {
export function resolveKuaishouFeifeiClaimUrl(value: unknown) {
const flow = normalizeKuaishouFeifeiFlow(value)
const h5ClaimUrl = flow.h5.rechargeUrl || flow.h5.entryUrl
if (h5ClaimUrl) {
return h5ClaimUrl
if (flow.shortLink?.url) {
return flow.shortLink.url
}
return isLocalClaimUrl(flow.claimUrl) ? '' : flow.claimUrl
return resolveKuaishouFeifeiDirectClaimUrl(flow)
}
export async function ensureKuaishouFeifeiClaimShortLink(task: TaskRow) {
if (!isKuaishouFeifeiTask(task)) {
return ''
}
const taskContext = parseTaskContext(task)
const flow = normalizeKuaishouFeifeiFlow(taskContext.kuaishouFeifei)
const nextFlow = await ensureKuaishouFeifeiFlowShortLink(flow, task)
const claimUrl = resolveKuaishouFeifeiClaimUrl(nextFlow)
if (JSON.stringify(flow.shortLink || null) === JSON.stringify(nextFlow.shortLink || null)) {
return claimUrl
}
await updateTask(task.id, {
context_json: JSON.stringify({
...taskContext,
kuaishouFeifei: nextFlow,
}),
updated_at: nowIso(),
})
return claimUrl
}
function mergeKuaishouFeifeiOrder(
@@ -257,6 +285,7 @@ function mergeKuaishouFeifeiOrder(
rechargeStatusLabel: order.rechargeStatusLabel,
rechargeResultMessage: order.rechargeResultMessage,
claimUrl: patch.claimUrl || flow.claimUrl,
shortLink: flow.shortLink,
h5: {
entryUrl: order.h5.entryUrl || flow.h5.entryUrl,
rechargeUrl: order.h5.rechargeUrl || flow.h5.rechargeUrl,
@@ -266,6 +295,45 @@ function mergeKuaishouFeifeiOrder(
}
}
async function ensureKuaishouFeifeiFlowShortLink(
flow: ReturnType<typeof normalizeKuaishouFeifeiFlow>,
task: TaskRow,
) {
const targetUrl = resolveKuaishouFeifeiDirectClaimUrl(flow)
if (!targetUrl) {
return flow
}
if (flow.shortLink?.url && flow.shortLink.targetUrl === targetUrl) {
return flow
}
const shortLink = await ensureShortLinkForTarget(targetUrl, {
source: SHORT_LINK_SOURCE_KUAISHOU_FEIFEI_CLAIM,
taskId: task.id,
})
return {
...flow,
shortLink,
}
}
function resolveKuaishouFeifeiDirectClaimUrl(
flow: ReturnType<typeof normalizeKuaishouFeifeiFlow>,
) {
const h5ClaimUrl = flow.h5.rechargeUrl || flow.h5.entryUrl
if (h5ClaimUrl) {
return h5ClaimUrl
}
if (flow.shortLink?.targetUrl) {
return flow.shortLink.targetUrl
}
return isLocalClaimUrl(flow.claimUrl) ? '' : flow.claimUrl
}
function resolveKuaishouFeifeiOrderClaimUrl(order: Awaited<ReturnType<typeof createKuaishouFeifeiOrder>>) {
return String(order.h5.rechargeUrl || order.h5.entryUrl || '').trim()
}