优化履约账号优先级配置

This commit is contained in:
yml2213
2026-05-26 12:44:01 +08:00
parent 2ff320c6ac
commit 6e85002724
26 changed files with 161 additions and 181 deletions
@@ -1,56 +1,18 @@
import { createHttpError } from "../../../utils/http.js";
import {
getCloudtentaclesSourceConfig,
getCloudtentaclesSourceByKey,
} from "../../platforms/cloudtentacles/source-config-service.js";
import {
getCloudtentaclesSessionState,
getCloudtentaclesSessionStateByKey,
} from "../../platforms/cloudtentacles/session-state-service.js";
import { getCloudtentaclesSourceByKey } from "../../platforms/cloudtentacles/source-config-service.js";
import { getCloudtentaclesSessionStateByKey } from "../../platforms/cloudtentacles/session-state-service.js";
import { normalizeStringArray } from "./domain.js";
export function resolvePersistedCloudtentaclesContext(sourceKey = "default") {
const source =
getCloudtentaclesSourceByKey(sourceKey) || getCloudtentaclesSourceConfig();
const session =
getCloudtentaclesSessionStateByKey(sourceKey) ||
getCloudtentaclesSessionState();
const token = String(session.token || "").trim();
if (!token) {
throw createHttpError(
"当前 cloudtentacles 没有可用 token,请先到平台配置完成登录校验",
{
statusCode: 409,
errorCode: "kuaishou_cloud_missing_cloud_token",
}
);
}
return {
baseUrl:
String(session.baseUrl || source.baseUrl || "").trim() ||
"https://123.207.217.176",
token,
deviceId: String(session.deviceId || source.deviceId || "-").trim() || "-",
deviceType: Number(session.deviceType ?? source.deviceType ?? 0),
};
}
/**
* 按优先级依次尝试 cloudSourceKey 和 fallbacks 列表中的账号,
* 按优先级依次尝试 cloudSourceKeys 列表中的账号,
* 找到第一个有可用 token 的账号返回其 context。
* 将实际使用的 resolvedSourceKey 也返回,确保后续操作(退号、发货等)
* 使用同一个 sourceKey,防止跨账号操作导致数据不一致。
*/
export function resolvePersistedCloudtentaclesContextWithFallback(
primarySourceKey = "default",
fallbacks: unknown[] = []
export function resolvePersistedCloudtentaclesContextBySourceKeys(
sourceKeys: unknown[] = []
) {
const candidates = [
String(primarySourceKey || "default").trim() || "default",
...normalizeStringArray(fallbacks),
];
const candidates = normalizeStringArray(sourceKeys);
const uniqueCandidates = [...new Set(candidates)];
@@ -101,7 +63,7 @@ export function resolvePersistedCloudtentaclesContextWithFallback(
throw (
lastError ||
createHttpError(
"所有 cloudtentacles 备选账号均不可用,请先到平台配置完成登录校验",
"所有 cloudtentacles 账号均不可用,请先到平台配置完成登录校验",
{ statusCode: 409, errorCode: "kuaishou_cloud_all_source_keys_exhausted" }
)
);
@@ -62,11 +62,7 @@ export function normalizeKuaishouCloudFlow(value: unknown) {
binding: {
prepareStatus:
String(binding.prepareStatus || "pending").trim() || "pending",
cloudSourceKey:
String(binding.cloudSourceKey || "default").trim() || "default",
cloudSourceKeyFallbacks: normalizeStringArray(
binding.cloudSourceKeyFallbacks
),
cloudSourceKeys: normalizeStringArray(binding.cloudSourceKeys),
resolvedSourceKey: String(binding.resolvedSourceKey || "").trim(),
skuId: Number(binding.skuId || 0) || 0,
skuName: String(binding.skuName || "").trim(),
@@ -35,7 +35,7 @@ import {
resolveKuaishouCloudVnKeyCandidates,
} from "./binding-resources.js";
import {
resolvePersistedCloudtentaclesContextWithFallback,
resolvePersistedCloudtentaclesContextBySourceKeys,
} from "./cloudtentacles-context.js";
import {
getTaskClaimExpiresAt,
@@ -55,8 +55,7 @@ export {
resolveKuaishouCloudBindUrlExpiresAt,
} from "./domain.js";
export {
resolvePersistedCloudtentaclesContext,
resolvePersistedCloudtentaclesContextWithFallback,
resolvePersistedCloudtentaclesContextBySourceKeys,
} from "./cloudtentacles-context.js";
export async function ensureTaskClaimLink(task: TaskRow) {
@@ -135,9 +134,8 @@ export async function prepareKuaishouCloudFulfillmentTask(
};
}
const cloudContext = resolvePersistedCloudtentaclesContextWithFallback(
flow.binding.cloudSourceKey || "default",
flow.binding.cloudSourceKeyFallbacks || []
const cloudContext = resolvePersistedCloudtentaclesContextBySourceKeys(
flow.binding.cloudSourceKeys
);
const [knapsack, skuList] = await Promise.all([
getCloudtentaclesKnapsack(cloudContext),
@@ -335,12 +333,10 @@ export async function refreshKuaishouCloudTaskBindUrl(
});
}
const effectiveSourceKey =
flow.binding.resolvedSourceKey || flow.binding.cloudSourceKey || "default";
const cloudContext = resolvePersistedCloudtentaclesContextWithFallback(
effectiveSourceKey,
flow.binding.cloudSourceKeyFallbacks || []
);
const cloudContext = resolvePersistedCloudtentaclesContextBySourceKeys([
flow.binding.resolvedSourceKey,
...flow.binding.cloudSourceKeys,
]);
const oldVnKey = flow.binding.vnKey;
const oldVnId = flow.binding.vnId;
const oldVnPhone = flow.binding.vnPhone;
@@ -707,12 +703,10 @@ export async function refreshKuaishouCloudTaskRoleInfo(
}
}
const effectiveSourceKey =
flow.binding.resolvedSourceKey || flow.binding.cloudSourceKey || "default";
const cloudContext = resolvePersistedCloudtentaclesContextWithFallback(
effectiveSourceKey,
flow.binding.cloudSourceKeyFallbacks || []
);
const cloudContext = resolvePersistedCloudtentaclesContextBySourceKeys([
flow.binding.resolvedSourceKey,
...flow.binding.cloudSourceKeys,
]);
const bindInfoResult = await getCloudtentaclesBindInfo({
...cloudContext,
key: flow.binding.vnKey,
@@ -18,7 +18,7 @@ import {
normalizeKuaishouCloudFlow,
type JsonObject,
} from "./domain.js";
import { resolvePersistedCloudtentaclesContextWithFallback } from "./cloudtentacles-context.js";
import { resolvePersistedCloudtentaclesContextBySourceKeys } from "./cloudtentacles-context.js";
import { normalizeActor, parseTaskContext } from "./task-context.js";
import type { TaskRow } from "../../../types/repository/rows.js";
@@ -37,12 +37,10 @@ export async function dispatchKuaishouCloudFulfillmentTask(
const now = nowIso();
const taskContext = parseTaskContext(task);
const flow = normalizeKuaishouCloudFlow(taskContext.kuaishouCloudFulfillment);
const effectiveSourceKey =
flow.binding.resolvedSourceKey || flow.binding.cloudSourceKey || "default";
const cloudContext = resolvePersistedCloudtentaclesContextWithFallback(
effectiveSourceKey,
flow.binding.cloudSourceKeyFallbacks || []
);
const cloudContext = resolvePersistedCloudtentaclesContextBySourceKeys([
flow.binding.resolvedSourceKey,
...flow.binding.cloudSourceKeys,
]);
if (!flow.binding.skuId || !flow.binding.vnId || !flow.binding.vnPhone) {
throw createHttpError(
@@ -178,12 +176,10 @@ export async function returnKuaishouCloudFulfillmentTask(
const now = nowIso();
const taskContext = parseTaskContext(task);
const flow = normalizeKuaishouCloudFlow(taskContext.kuaishouCloudFulfillment);
const effectiveSourceKey =
flow.binding.resolvedSourceKey || flow.binding.cloudSourceKey || "default";
const cloudContext = resolvePersistedCloudtentaclesContextWithFallback(
effectiveSourceKey,
flow.binding.cloudSourceKeyFallbacks || []
);
const cloudContext = resolvePersistedCloudtentaclesContextBySourceKeys([
flow.binding.resolvedSourceKey,
...flow.binding.cloudSourceKeys,
]);
if (!flow.binding.vnId || !flow.binding.vnKey) {
throw createHttpError("当前任务缺少可退还的虚拟号信息", {