增加履约高级配置
This commit is contained in:
@@ -45,6 +45,16 @@ import {
|
||||
} from "./task-context.js";
|
||||
import type { TaskRow } from "../../../types/repository/rows.js";
|
||||
|
||||
type CloudDeliveryPlanItem = {
|
||||
cloudSkuId: number;
|
||||
cloudSkuName: string;
|
||||
quantity: number;
|
||||
skuItem: JsonObject | null;
|
||||
knapsackItem: JsonObject | null;
|
||||
knapsackCount: number;
|
||||
missingCount: number;
|
||||
};
|
||||
|
||||
export {
|
||||
isKuaishouCloudBindUrlFresh,
|
||||
isKuaishouCloudTask,
|
||||
@@ -167,8 +177,18 @@ export async function prepareKuaishouCloudFulfillmentTask(
|
||||
},
|
||||
};
|
||||
|
||||
const knapsackItem = resolvedBinding.knapsackItem;
|
||||
let usedKnapsack = Number(knapsackItem?.count || 0) > 0;
|
||||
const deliveryPlan = resolveKuaishouCloudDeliveryPlan(flowWithResolvedBinding, {
|
||||
skuItems: Array.isArray(skuList.items) ? skuList.items : [],
|
||||
knapsackItems: Array.isArray(knapsack.items) ? knapsack.items : [],
|
||||
});
|
||||
if (deliveryPlan.items.length === 0) {
|
||||
throw createHttpError("当前任务缺少 cloud 发货物品配置", {
|
||||
statusCode: 409,
|
||||
errorCode: "kuaishou_cloud_missing_delivery_items",
|
||||
});
|
||||
}
|
||||
|
||||
let usedKnapsack = deliveryPlan.items.every((item) => item.missingCount <= 0);
|
||||
let purchaseTriggered = false;
|
||||
let assetBefore = 0;
|
||||
let assetAfter = 0;
|
||||
@@ -182,11 +202,12 @@ export async function prepareKuaishouCloudFulfillmentTask(
|
||||
}
|
||||
|
||||
const asset = await getCloudtentaclesAsset(cloudContext);
|
||||
const targetSku = resolvedBinding.skuItem;
|
||||
|
||||
if (!targetSku) {
|
||||
const missingSku = deliveryPlan.items.find(
|
||||
(item) => item.missingCount > 0 && !item.skuItem
|
||||
);
|
||||
if (missingSku) {
|
||||
throw createHttpError(
|
||||
`cloudtentacles 未找到 SKU ${flowWithResolvedBinding.binding.skuId}`,
|
||||
`cloudtentacles 未找到 SKU ${missingSku.cloudSkuId}`,
|
||||
{
|
||||
statusCode: 404,
|
||||
errorCode: "kuaishou_cloud_sku_not_found",
|
||||
@@ -195,7 +216,11 @@ export async function prepareKuaishouCloudFulfillmentTask(
|
||||
}
|
||||
|
||||
assetBefore = Number(asset.asset || 0) || 0;
|
||||
const targetPrice = Number(targetSku.price || 0) || 0;
|
||||
const targetPrice = deliveryPlan.items.reduce(
|
||||
(sum, item) =>
|
||||
sum + Math.max(0, item.missingCount) * Number(item.skuItem?.price || 0),
|
||||
0
|
||||
);
|
||||
const requiredAsset =
|
||||
targetPrice + flowWithResolvedBinding.purchase.minAssetReserve;
|
||||
if (assetBefore < requiredAsset) {
|
||||
@@ -204,7 +229,10 @@ export async function prepareKuaishouCloudFulfillmentTask(
|
||||
flow: flowWithResolvedBinding,
|
||||
assetBefore,
|
||||
requiredAsset,
|
||||
skuName: targetSku.name,
|
||||
skuName: deliveryPlan.items
|
||||
.filter((item) => item.missingCount > 0)
|
||||
.map((item) => item.cloudSkuName || `SKU ${item.cloudSkuId}`)
|
||||
.join("、"),
|
||||
});
|
||||
throw createHttpError(
|
||||
`余额不足,当前 ${assetBefore},至少需要 ${requiredAsset}`,
|
||||
@@ -215,11 +243,17 @@ export async function prepareKuaishouCloudFulfillmentTask(
|
||||
);
|
||||
}
|
||||
|
||||
await buyCloudtentaclesSku({
|
||||
...cloudContext,
|
||||
id: flowWithResolvedBinding.binding.skuId,
|
||||
count: 1,
|
||||
});
|
||||
for (const item of deliveryPlan.items) {
|
||||
if (item.missingCount <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
await buyCloudtentaclesSku({
|
||||
...cloudContext,
|
||||
id: item.cloudSkuId,
|
||||
count: item.missingCount,
|
||||
});
|
||||
}
|
||||
purchaseTriggered = true;
|
||||
|
||||
const assetResult = await getCloudtentaclesAsset(cloudContext);
|
||||
@@ -265,6 +299,13 @@ export async function prepareKuaishouCloudFulfillmentTask(
|
||||
purchaseTriggered,
|
||||
assetBefore,
|
||||
assetAfter,
|
||||
items: deliveryPlan.items.map((item) => ({
|
||||
cloudSkuId: item.cloudSkuId,
|
||||
cloudSkuName: item.cloudSkuName,
|
||||
requiredCount: item.quantity,
|
||||
knapsackCount: item.knapsackCount,
|
||||
purchasedCount: Math.max(0, item.missingCount),
|
||||
})),
|
||||
purchaseAt: purchaseTriggered
|
||||
? now
|
||||
: flowWithResolvedBinding.purchase.purchaseAt,
|
||||
@@ -296,6 +337,13 @@ export async function prepareKuaishouCloudFulfillmentTask(
|
||||
vnPhoneMasked: maskPhone(preparedBinding.vnPhone),
|
||||
purchaseTriggered,
|
||||
usedKnapsack,
|
||||
deliveryItems: deliveryPlan.items.map((item) => ({
|
||||
cloudSkuId: item.cloudSkuId,
|
||||
cloudSkuName: item.cloudSkuName,
|
||||
quantity: item.quantity,
|
||||
knapsackCount: item.knapsackCount,
|
||||
purchasedCount: Math.max(0, item.missingCount),
|
||||
})),
|
||||
resolvedByName: resolvedBinding.resolvedByName,
|
||||
actor,
|
||||
},
|
||||
@@ -766,6 +814,69 @@ export async function refreshKuaishouCloudTaskRoleInfo(
|
||||
};
|
||||
}
|
||||
|
||||
function resolveKuaishouCloudDeliveryPlan(
|
||||
flow: JsonObject,
|
||||
{
|
||||
skuItems = [],
|
||||
knapsackItems = [],
|
||||
}: { skuItems?: unknown[]; knapsackItems?: unknown[] } = {}
|
||||
): { items: CloudDeliveryPlanItem[] } {
|
||||
const normalizedSkuItems = Array.isArray(skuItems)
|
||||
? skuItems.filter(isCloudSkuLikeItem)
|
||||
: [];
|
||||
const normalizedKnapsackItems = Array.isArray(knapsackItems)
|
||||
? knapsackItems.filter(isCloudSkuLikeItem)
|
||||
: [];
|
||||
const deliveryItems = Array.isArray(flow.deliveryItems)
|
||||
? flow.deliveryItems
|
||||
: [];
|
||||
|
||||
return {
|
||||
items: deliveryItems
|
||||
.map((item: unknown) => {
|
||||
const source = item && typeof item === "object" ? item as JsonObject : {};
|
||||
const cloudSkuId = Number(source.cloudSkuId || source.skuId || 0) || 0;
|
||||
const quantity = Number(source.quantity || 1) || 1;
|
||||
if (!cloudSkuId || !Number.isInteger(quantity) || quantity <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const skuItem =
|
||||
normalizedSkuItems.find(
|
||||
(sku) => Number(sku.id || 0) === cloudSkuId
|
||||
) || null;
|
||||
const knapsackItem =
|
||||
normalizedKnapsackItems.find(
|
||||
(sku) => Number(sku.id || 0) === cloudSkuId
|
||||
) || null;
|
||||
const knapsackCount = Math.max(0, Number(knapsackItem?.count || 0) || 0);
|
||||
const cloudSkuName = String(
|
||||
source.cloudSkuName ||
|
||||
source.skuName ||
|
||||
skuItem?.name ||
|
||||
knapsackItem?.name ||
|
||||
""
|
||||
).trim();
|
||||
|
||||
return {
|
||||
cloudSkuId,
|
||||
cloudSkuName,
|
||||
quantity,
|
||||
skuItem,
|
||||
knapsackItem,
|
||||
knapsackCount,
|
||||
missingCount: Math.max(0, quantity - knapsackCount),
|
||||
};
|
||||
})
|
||||
.filter((item): item is CloudDeliveryPlanItem => Boolean(item)),
|
||||
};
|
||||
}
|
||||
|
||||
function isCloudSkuLikeItem(item: unknown): item is JsonObject {
|
||||
const current = item && typeof item === "object" ? item as JsonObject : {};
|
||||
return Number(current.id || 0) > 0;
|
||||
}
|
||||
|
||||
export {
|
||||
dispatchKuaishouCloudFulfillmentTask,
|
||||
returnKuaishouCloudFulfillmentTask,
|
||||
|
||||
Reference in New Issue
Block a user