增加履约高级配置
This commit is contained in:
@@ -131,6 +131,12 @@ export async function syncDeliveryTasksForOrderWithDeps(
|
||||
const cloudtentaclesConfig = parseJsonObject(fulfillmentConfig.cloudtentacles)
|
||||
const kuaishouConsumeConfig = parseJsonObject(fulfillmentConfig.kuaishouConsume)
|
||||
const kuaishouShopConfig = parseJsonObject(fulfillmentConfig.kuaishouShop)
|
||||
const deliveryItems = normalizeCloudDeliveryItems(cloudtentaclesConfig)
|
||||
const primaryDeliveryItem = deliveryItems[0] || {
|
||||
cloudSkuId: Number(cloudtentaclesConfig.skuId || 0) || 0,
|
||||
cloudSkuName: String(cloudtentaclesConfig.skuName || '').trim(),
|
||||
quantity: 1,
|
||||
}
|
||||
|
||||
for (let index = 0; index < quantity; index += 1) {
|
||||
const createdAt = getNowIso()
|
||||
@@ -172,6 +178,7 @@ export async function syncDeliveryTasksForOrderWithDeps(
|
||||
configId: String(fulfillmentConfig.configId || '').trim(),
|
||||
internalSkuCode: item.sku_code,
|
||||
internalSkuName: item.sku_name,
|
||||
deliveryItems,
|
||||
ticket: {
|
||||
code: '',
|
||||
status: 'pending',
|
||||
@@ -186,8 +193,8 @@ export async function syncDeliveryTasksForOrderWithDeps(
|
||||
binding: {
|
||||
prepareStatus: 'pending',
|
||||
cloudSourceKeys: normalizeStringArray(cloudtentaclesConfig.cloudSourceKeys),
|
||||
skuId: Number(cloudtentaclesConfig.skuId || 0) || 0,
|
||||
skuName: String(cloudtentaclesConfig.skuName || '').trim(),
|
||||
skuId: primaryDeliveryItem.cloudSkuId,
|
||||
skuName: primaryDeliveryItem.cloudSkuName,
|
||||
vnKey: '1',
|
||||
vnId: 0,
|
||||
vnPhone: '',
|
||||
@@ -394,6 +401,68 @@ function normalizeStringArray(value: unknown): string[] {
|
||||
)
|
||||
}
|
||||
|
||||
function normalizeCloudDeliveryItems(value: JsonObject): Array<{
|
||||
cloudSkuId: number
|
||||
cloudSkuName: string
|
||||
quantity: number
|
||||
}> {
|
||||
const rawItems = Array.isArray(value.deliveryItems) ? value.deliveryItems : []
|
||||
const items = rawItems
|
||||
.map((item) => normalizeCloudDeliveryItem(item))
|
||||
.filter((item): item is { cloudSkuId: number; cloudSkuName: string; quantity: number } => Boolean(item))
|
||||
|
||||
if (items.length > 0) {
|
||||
return mergeCloudDeliveryItems(items)
|
||||
}
|
||||
|
||||
const cloudSkuId = Number(value.skuId || 0) || 0
|
||||
if (!cloudSkuId) {
|
||||
return []
|
||||
}
|
||||
|
||||
return [{
|
||||
cloudSkuId,
|
||||
cloudSkuName: String(value.skuName || '').trim(),
|
||||
quantity: 1,
|
||||
}]
|
||||
}
|
||||
|
||||
function normalizeCloudDeliveryItem(value: unknown) {
|
||||
const source = value && typeof value === 'object' && !Array.isArray(value)
|
||||
? value as JsonObject
|
||||
: {}
|
||||
const cloudSkuId = Number(source.cloudSkuId || source.skuId || 0) || 0
|
||||
if (!Number.isInteger(cloudSkuId) || cloudSkuId <= 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
const quantity = Number(source.quantity || 1) || 1
|
||||
return {
|
||||
cloudSkuId,
|
||||
cloudSkuName: String(source.cloudSkuName || source.skuName || '').trim(),
|
||||
quantity: Number.isInteger(quantity) && quantity > 0 ? quantity : 1,
|
||||
}
|
||||
}
|
||||
|
||||
function mergeCloudDeliveryItems(
|
||||
items: Array<{ cloudSkuId: number; cloudSkuName: string; quantity: number }>,
|
||||
) {
|
||||
const merged = new Map<number, { cloudSkuId: number; cloudSkuName: string; quantity: number }>()
|
||||
|
||||
for (const item of items) {
|
||||
const existing = merged.get(item.cloudSkuId)
|
||||
if (existing) {
|
||||
existing.quantity += item.quantity
|
||||
existing.cloudSkuName = existing.cloudSkuName || item.cloudSkuName
|
||||
continue
|
||||
}
|
||||
|
||||
merged.set(item.cloudSkuId, { ...item })
|
||||
}
|
||||
|
||||
return Array.from(merged.values())
|
||||
}
|
||||
|
||||
function isTaskRow(task: TaskRow | DeliveryTaskRow | null | undefined): task is TaskRow {
|
||||
return Boolean(task && Number(task.id || 0) > 0)
|
||||
}
|
||||
|
||||
@@ -32,6 +32,13 @@ test('mapKuaishouCloudFulfillmentItemsToBindings maps 91kaquan rules', () => {
|
||||
profileKey: 'kuaishou_ct_assisted',
|
||||
enabled: true,
|
||||
priority: 100,
|
||||
deliveryItems: [
|
||||
{
|
||||
cloudSkuId: 28,
|
||||
cloudSkuName: '',
|
||||
quantity: 1,
|
||||
},
|
||||
],
|
||||
config: {
|
||||
flowType: 'kuaishou_cloud_fulfillment',
|
||||
configId: '',
|
||||
@@ -39,6 +46,13 @@ test('mapKuaishouCloudFulfillmentItemsToBindings maps 91kaquan rules', () => {
|
||||
cloudSourceKeys: ['account_a', 'account_b'],
|
||||
skuId: 28,
|
||||
skuName: '',
|
||||
deliveryItems: [
|
||||
{
|
||||
cloudSkuId: 28,
|
||||
cloudSkuName: '',
|
||||
quantity: 1,
|
||||
},
|
||||
],
|
||||
vnKey: '1',
|
||||
autoBuyEnabled: true,
|
||||
minAssetReserve: 0,
|
||||
@@ -63,3 +77,32 @@ test('mapKuaishouCloudFulfillmentItemsToBindings maps 91kaquan rules', () => {
|
||||
],
|
||||
)
|
||||
})
|
||||
|
||||
test('mapKuaishouCloudFulfillmentItemsToBindings maps package delivery items', () => {
|
||||
const [binding] = mapKuaishouCloudFulfillmentItemsToBindings({
|
||||
items: [
|
||||
{
|
||||
enabled: true,
|
||||
internalSkuCode: 'package-1',
|
||||
internalSkuName: '套餐 1',
|
||||
externalSkuCode: 'P001',
|
||||
cloudSourceKeys: ['account_a'],
|
||||
deliveryItems: [
|
||||
{ cloudSkuId: 73, cloudSkuName: '物品 A', quantity: 1 },
|
||||
{ cloudSkuId: 76, cloudSkuName: '物品 B', quantity: 50 },
|
||||
],
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
assert.deepEqual(binding?.deliveryItems, [
|
||||
{ cloudSkuId: 73, cloudSkuName: '物品 A', quantity: 1 },
|
||||
{ cloudSkuId: 76, cloudSkuName: '物品 B', quantity: 50 },
|
||||
])
|
||||
assert.deepEqual(binding?.config.cloudtentacles.deliveryItems, [
|
||||
{ cloudSkuId: 73, cloudSkuName: '物品 A', quantity: 1 },
|
||||
{ cloudSkuId: 76, cloudSkuName: '物品 B', quantity: 50 },
|
||||
])
|
||||
assert.equal(binding?.config.cloudtentacles.skuId, 73)
|
||||
assert.equal(binding?.config.cloudtentacles.skuName, '物品 A')
|
||||
})
|
||||
|
||||
@@ -12,6 +12,12 @@ const KUAISHOU_CLOUD_FULFILLMENT_FILE_PATH = path.join(
|
||||
|
||||
type JsonObject = Record<string, any>;
|
||||
|
||||
type DeliveryItem = {
|
||||
cloudSkuId: number;
|
||||
cloudSkuName: string;
|
||||
quantity: number;
|
||||
};
|
||||
|
||||
export function getKuaishouCloudFulfillmentFilePath() {
|
||||
return KUAISHOU_CLOUD_FULFILLMENT_FILE_PATH;
|
||||
}
|
||||
@@ -42,13 +48,19 @@ export function mapKuaishouCloudFulfillmentItemsToBindings(config: JsonObject =
|
||||
profileKey: "kuaishou_ct_assisted",
|
||||
enabled: item.enabled !== false,
|
||||
priority: normalizePriority(item.priority),
|
||||
deliveryItems: normalizeDeliveryItems(item),
|
||||
config: {
|
||||
flowType: "kuaishou_cloud_fulfillment",
|
||||
configId: String(item.id || "").trim(),
|
||||
cloudtentacles: {
|
||||
cloudSourceKeys: normalizeStringArray(item.cloudSourceKeys),
|
||||
skuId: normalizePositiveInteger(item.cloudSkuId),
|
||||
skuName: String(item.cloudSkuName || "").trim(),
|
||||
skuId:
|
||||
normalizeDeliveryItems(item)[0]?.cloudSkuId ||
|
||||
normalizePositiveInteger(item.cloudSkuId),
|
||||
skuName:
|
||||
normalizeDeliveryItems(item)[0]?.cloudSkuName ||
|
||||
String(item.cloudSkuName || "").trim(),
|
||||
deliveryItems: normalizeDeliveryItems(item),
|
||||
vnKey: "1",
|
||||
autoBuyEnabled: item.autoBuyEnabled !== false,
|
||||
minAssetReserve: normalizeNonNegativeInteger(item.minAssetReserve, 0),
|
||||
@@ -109,6 +121,7 @@ function normalizeKuaishouCloudFulfillmentItem(rawValue: unknown) {
|
||||
|
||||
const internalSkuCode = String(rawValue.internalSkuCode || "").trim();
|
||||
const cloudSkuId = normalizePositiveInteger(rawValue.cloudSkuId);
|
||||
const deliveryItems = normalizeDeliveryItems(rawValue);
|
||||
const cloudSourceKeys = normalizeStringArray(rawValue.cloudSourceKeys);
|
||||
const externalSkuCode = String(rawValue.externalSkuCode || "").trim();
|
||||
const externalItemId = String(rawValue.externalItemId || "").trim();
|
||||
@@ -128,7 +141,7 @@ function normalizeKuaishouCloudFulfillmentItem(rawValue: unknown) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!cloudSkuId) {
|
||||
if (deliveryItems.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -157,8 +170,11 @@ function normalizeKuaishouCloudFulfillmentItem(rawValue: unknown) {
|
||||
rawValue.resolvedSkuName || rawValue.internalSkuName || ""
|
||||
).trim(),
|
||||
cloudSourceKeys,
|
||||
cloudSkuId,
|
||||
cloudSkuName: String(rawValue.cloudSkuName || "").trim(),
|
||||
cloudSkuId: deliveryItems[0]?.cloudSkuId || cloudSkuId,
|
||||
cloudSkuName:
|
||||
deliveryItems[0]?.cloudSkuName ||
|
||||
String(rawValue.cloudSkuName || "").trim(),
|
||||
deliveryItems,
|
||||
vnKey: "1",
|
||||
autoBuyEnabled: rawValue.autoBuyEnabled !== false,
|
||||
minAssetReserve: normalizeNonNegativeInteger(rawValue.minAssetReserve, 0),
|
||||
@@ -185,6 +201,64 @@ function normalizeNonNegativeInteger(value: unknown, fallback: number) {
|
||||
return Number.isInteger(parsed) && parsed >= 0 ? parsed : fallback;
|
||||
}
|
||||
|
||||
function normalizeDeliveryItems(value: JsonObject): DeliveryItem[] {
|
||||
const rawItems = Array.isArray(value.deliveryItems) ? value.deliveryItems : [];
|
||||
const items = rawItems
|
||||
.map((item: unknown) => normalizeDeliveryItem(item))
|
||||
.filter(Boolean) as DeliveryItem[];
|
||||
|
||||
if (items.length > 0) {
|
||||
return mergeDeliveryItems(items);
|
||||
}
|
||||
|
||||
const cloudSkuId = normalizePositiveInteger(value.cloudSkuId);
|
||||
if (!cloudSkuId) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
{
|
||||
cloudSkuId,
|
||||
cloudSkuName: String(value.cloudSkuName || "").trim(),
|
||||
quantity: 1,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
function normalizeDeliveryItem(value: unknown): DeliveryItem | null {
|
||||
if (!isPlainObject(value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const cloudSkuId = normalizePositiveInteger(value.cloudSkuId || value.skuId);
|
||||
if (!cloudSkuId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
cloudSkuId,
|
||||
cloudSkuName: String(value.cloudSkuName || value.skuName || "").trim(),
|
||||
quantity: normalizePositiveInteger(value.quantity) || 1,
|
||||
};
|
||||
}
|
||||
|
||||
function mergeDeliveryItems(items: DeliveryItem[]): DeliveryItem[] {
|
||||
const merged = new Map<number, DeliveryItem>();
|
||||
|
||||
for (const item of items) {
|
||||
const existing = merged.get(item.cloudSkuId);
|
||||
if (existing) {
|
||||
existing.quantity += item.quantity;
|
||||
existing.cloudSkuName = existing.cloudSkuName || item.cloudSkuName;
|
||||
continue;
|
||||
}
|
||||
|
||||
merged.set(item.cloudSkuId, { ...item });
|
||||
}
|
||||
|
||||
return Array.from(merged.values());
|
||||
}
|
||||
|
||||
function normalizePriority(value: unknown) {
|
||||
const parsed = Number(value);
|
||||
if (!Number.isFinite(parsed)) {
|
||||
|
||||
Reference in New Issue
Block a user