优化快手云领取发货校验
This commit is contained in:
@@ -43,6 +43,7 @@ import {
|
|||||||
resolveKuaishouCloudVnKeyCandidates,
|
resolveKuaishouCloudVnKeyCandidates,
|
||||||
resolvePersistedCloudtentaclesContext,
|
resolvePersistedCloudtentaclesContext,
|
||||||
} from './kuaishou-cloud-helpers.js'
|
} from './kuaishou-cloud-helpers.js'
|
||||||
|
import { syncKuaishouCloudRoleInfoBeforeDispatch } from '../../fulfillment/kuaishou-cloud/dispatch-role-sync.js'
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
AdminEntityIdInput,
|
AdminEntityIdInput,
|
||||||
@@ -273,31 +274,49 @@ export async function dispatchAdminTaskKuaishouCloudFulfillment(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const synced = await syncKuaishouCloudRoleInfoBeforeDispatch(task, {
|
||||||
|
now,
|
||||||
|
actor: session
|
||||||
|
? {
|
||||||
|
userId: Number(session.userId || 0) || 0,
|
||||||
|
username: String(session.username || '').trim(),
|
||||||
|
role: String(session.role || '').trim(),
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
source: 'admin_task_dispatch',
|
||||||
|
errorCodePrefix: 'admin_task_kuaishou_cloud',
|
||||||
|
cloudContext,
|
||||||
|
taskContext,
|
||||||
|
flow,
|
||||||
|
})
|
||||||
|
const syncedFlow = synced.flow
|
||||||
|
const syncedTaskContext = synced.taskContext
|
||||||
|
|
||||||
const dispatchResult = await useCloudtentaclesSku({
|
const dispatchResult = await useCloudtentaclesSku({
|
||||||
...cloudContext,
|
...cloudContext,
|
||||||
id: flow.binding.skuId,
|
id: syncedFlow.binding.skuId,
|
||||||
virtualNumberId: flow.binding.vnId,
|
virtualNumberId: syncedFlow.binding.vnId,
|
||||||
phone: flow.binding.vnPhone,
|
phone: syncedFlow.binding.vnPhone,
|
||||||
})
|
})
|
||||||
|
|
||||||
const nextContext = {
|
const nextContext = {
|
||||||
...taskContext,
|
...syncedTaskContext,
|
||||||
kuaishouCloudFulfillment: {
|
kuaishouCloudFulfillment: {
|
||||||
...flow,
|
...syncedFlow,
|
||||||
ticket: {
|
ticket: {
|
||||||
...flow.ticket,
|
...syncedFlow.ticket,
|
||||||
code: ticketCode || persistedTicketCode,
|
code: ticketCode || persistedTicketCode,
|
||||||
capturedAt: ticketCode ? now : flow.ticket.capturedAt,
|
capturedAt: ticketCode ? now : syncedFlow.ticket.capturedAt,
|
||||||
capturedBy: ticketCode && session
|
capturedBy: ticketCode && session
|
||||||
? {
|
? {
|
||||||
userId: Number(session.userId || 0) || 0,
|
userId: Number(session.userId || 0) || 0,
|
||||||
username: String(session.username || '').trim(),
|
username: String(session.username || '').trim(),
|
||||||
role: String(session.role || '').trim(),
|
role: String(session.role || '').trim(),
|
||||||
}
|
}
|
||||||
: flow.ticket.capturedBy,
|
: syncedFlow.ticket.capturedBy,
|
||||||
},
|
},
|
||||||
dispatch: {
|
dispatch: {
|
||||||
...flow.dispatch,
|
...syncedFlow.dispatch,
|
||||||
status: 'success',
|
status: 'success',
|
||||||
dispatchAt: now,
|
dispatchAt: now,
|
||||||
dispatchBy: session
|
dispatchBy: session
|
||||||
@@ -325,9 +344,9 @@ export async function dispatchAdminTaskKuaishouCloudFulfillment(
|
|||||||
|
|
||||||
await createTaskEvent(task.id, 'kuaishou_cloud_dispatched', {
|
await createTaskEvent(task.id, 'kuaishou_cloud_dispatched', {
|
||||||
ticketCodeMasked: maskCode(ticketCode || persistedTicketCode),
|
ticketCodeMasked: maskCode(ticketCode || persistedTicketCode),
|
||||||
skuId: flow.binding.skuId,
|
skuId: syncedFlow.binding.skuId,
|
||||||
vnId: flow.binding.vnId,
|
vnId: syncedFlow.binding.vnId,
|
||||||
vnPhoneMasked: maskPhone(flow.binding.vnPhone),
|
vnPhoneMasked: maskPhone(syncedFlow.binding.vnPhone),
|
||||||
sendType: dispatchResult.sendType,
|
sendType: dispatchResult.sendType,
|
||||||
note: dispatchResult.note,
|
note: dispatchResult.note,
|
||||||
}, now)
|
}, now)
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ export async function getClaimContext(token: unknown) {
|
|||||||
|
|
||||||
export function buildClaimDetailPayload({ claimToken, task, order, orderItem }: ClaimContext) {
|
export function buildClaimDetailPayload({ claimToken, task, order, orderItem }: ClaimContext) {
|
||||||
const kuaishouCloudFulfillment = mapClaimKuaishouCloudFulfillment(task, order)
|
const kuaishouCloudFulfillment = mapClaimKuaishouCloudFulfillment(task, order)
|
||||||
|
const displaySkuName = resolveClaimOrderItemDisplaySkuName(orderItem, kuaishouCloudFulfillment)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
tokenStatus: claimToken.status,
|
tokenStatus: claimToken.status,
|
||||||
@@ -119,7 +120,7 @@ export function buildClaimDetailPayload({ claimToken, task, order, orderItem }:
|
|||||||
orderItem: {
|
orderItem: {
|
||||||
orderItemId: orderItem.id,
|
orderItemId: orderItem.id,
|
||||||
skuCode: orderItem.sku_code,
|
skuCode: orderItem.sku_code,
|
||||||
skuName: orderItem.sku_name,
|
skuName: displaySkuName,
|
||||||
quantity: orderItem.quantity,
|
quantity: orderItem.quantity,
|
||||||
},
|
},
|
||||||
session: null as null,
|
session: null as null,
|
||||||
@@ -135,6 +136,33 @@ export function buildClaimDetailPayload({ claimToken, task, order, orderItem }:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resolveClaimOrderItemDisplaySkuName(
|
||||||
|
orderItem: OrderItemRow,
|
||||||
|
kuaishouCloudFulfillment: JsonObject | null,
|
||||||
|
) {
|
||||||
|
const fulfillment = isPlainObject(kuaishouCloudFulfillment) ? kuaishouCloudFulfillment : {}
|
||||||
|
const binding = isPlainObject(fulfillment.binding) ? fulfillment.binding : {}
|
||||||
|
const ticket = isPlainObject(fulfillment.ticket) ? fulfillment.ticket : {}
|
||||||
|
const skuCode = String(orderItem.sku_code || '').trim()
|
||||||
|
const rawSkuName = String(orderItem.sku_name || '').trim()
|
||||||
|
const candidates = [
|
||||||
|
fulfillment.internalSkuName,
|
||||||
|
binding.skuName,
|
||||||
|
ticket.goodsTitle,
|
||||||
|
rawSkuName,
|
||||||
|
skuCode,
|
||||||
|
]
|
||||||
|
|
||||||
|
for (const value of candidates) {
|
||||||
|
const normalized = String(value || '').trim()
|
||||||
|
if (normalized && !isOrderItemIdentifierName(normalized, skuCode)) {
|
||||||
|
return normalized
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rawSkuName || skuCode
|
||||||
|
}
|
||||||
|
|
||||||
export function mapClaimKuaishouCloudFulfillment(task: TaskRow, order: OrderRow) {
|
export function mapClaimKuaishouCloudFulfillment(task: TaskRow, order: OrderRow) {
|
||||||
if (String(task?.executor_key || '').trim() !== 'kuaishou_ct_assisted') {
|
if (String(task?.executor_key || '').trim() !== 'kuaishou_ct_assisted') {
|
||||||
return null
|
return null
|
||||||
@@ -229,6 +257,24 @@ function parseTaskContext(task: TaskRow): JsonObject {
|
|||||||
return parseTaskContextValue(task)
|
return parseTaskContextValue(task)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isOrderItemIdentifierName(value: string, skuCode: string) {
|
||||||
|
const normalized = String(value || '').trim()
|
||||||
|
if (!normalized) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
const normalizedSkuCode = String(skuCode || '').trim()
|
||||||
|
if (normalizedSkuCode && normalized === normalizedSkuCode) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return /^\d{8,}$/.test(normalized)
|
||||||
|
}
|
||||||
|
|
||||||
|
function isPlainObject(value: unknown): value is JsonObject {
|
||||||
|
return Object.prototype.toString.call(value) === '[object Object]'
|
||||||
|
}
|
||||||
|
|
||||||
async function expireClaimContext(claimToken: ClaimTokenRow, task: TaskRow) {
|
async function expireClaimContext(claimToken: ClaimTokenRow, task: TaskRow) {
|
||||||
const now = nowIso()
|
const now = nowIso()
|
||||||
const nextClaimToken = await updateClaimToken(claimToken.id, {
|
const nextClaimToken = await updateClaimToken(claimToken.id, {
|
||||||
|
|||||||
@@ -0,0 +1,216 @@
|
|||||||
|
import { createTaskEvent } from "../../../repositories/task-event-repo.js";
|
||||||
|
import { updateTask } from "../../../repositories/task-repo.js";
|
||||||
|
import type { TaskRow } from "../../../types/repository/rows.js";
|
||||||
|
import { createHttpError } from "../../../utils/http.js";
|
||||||
|
import { getCloudtentaclesBindInfo } from "../../platforms/cloudtentacles/virtual-number-service.js";
|
||||||
|
import {
|
||||||
|
normalizeKuaishouCloudFlow,
|
||||||
|
normalizeKuaishouCloudRoleInfo,
|
||||||
|
type JsonObject,
|
||||||
|
} from "./domain.js";
|
||||||
|
|
||||||
|
export async function syncKuaishouCloudRoleInfoBeforeDispatch(
|
||||||
|
task: TaskRow,
|
||||||
|
input: JsonObject = {}
|
||||||
|
) {
|
||||||
|
const now = String(input.now || "").trim() || new Date().toISOString();
|
||||||
|
const source =
|
||||||
|
String(input.source || "system_before_dispatch").trim() ||
|
||||||
|
"system_before_dispatch";
|
||||||
|
const errorCodePrefix =
|
||||||
|
String(input.errorCodePrefix || "kuaishou_cloud").trim() ||
|
||||||
|
"kuaishou_cloud";
|
||||||
|
const cloudContext =
|
||||||
|
input.cloudContext && typeof input.cloudContext === "object"
|
||||||
|
? input.cloudContext
|
||||||
|
: {};
|
||||||
|
const taskContext =
|
||||||
|
input.taskContext && typeof input.taskContext === "object"
|
||||||
|
? input.taskContext
|
||||||
|
: {};
|
||||||
|
const flow = normalizeKuaishouCloudFlow(
|
||||||
|
input.flow || taskContext.kuaishouCloudFulfillment
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!flow.binding.vnId || !flow.binding.vnKey) {
|
||||||
|
throw createHttpError("当前任务缺少可同步角色的虚拟号信息,暂时不能发货", {
|
||||||
|
statusCode: 409,
|
||||||
|
errorCode: `${errorCodePrefix}_dispatch_missing_bind_info_context`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const bindInfoResult = await getCloudtentaclesBindInfo({
|
||||||
|
...cloudContext,
|
||||||
|
key: flow.binding.vnKey,
|
||||||
|
id: flow.binding.vnId,
|
||||||
|
});
|
||||||
|
const roleInfo = normalizeKuaishouCloudRoleInfo(bindInfoResult.bindInfo);
|
||||||
|
|
||||||
|
if (!roleInfo.name || !roleInfo.rid) {
|
||||||
|
throw createHttpError(
|
||||||
|
"cloudtentacles 还没有同步到客户绑定角色,请稍后刷新角色信息后再发货",
|
||||||
|
{
|
||||||
|
statusCode: 409,
|
||||||
|
errorCode: `${errorCodePrefix}_dispatch_role_not_ready`,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const confirmedRoleName = String(
|
||||||
|
flow.binding.roleName || flow.role.name || task.role_name || ""
|
||||||
|
).trim();
|
||||||
|
const confirmedRoleId = String(
|
||||||
|
flow.binding.roleId || flow.role.rid || task.role_id || ""
|
||||||
|
).trim();
|
||||||
|
const roleMatches = isSameKuaishouCloudRole(
|
||||||
|
{
|
||||||
|
name: confirmedRoleName,
|
||||||
|
rid: confirmedRoleId,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: roleInfo.name,
|
||||||
|
rid: roleInfo.rid,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!roleMatches) {
|
||||||
|
await createTaskEvent(
|
||||||
|
task.id,
|
||||||
|
"kuaishou_cloud_dispatch_role_mismatch",
|
||||||
|
{
|
||||||
|
source,
|
||||||
|
vnId: flow.binding.vnId,
|
||||||
|
confirmedRoleName,
|
||||||
|
confirmedRoleId,
|
||||||
|
cloudtentaclesRoleName: roleInfo.name,
|
||||||
|
cloudtentaclesRoleId: roleInfo.rid,
|
||||||
|
actor: input.actor || null,
|
||||||
|
},
|
||||||
|
now
|
||||||
|
);
|
||||||
|
|
||||||
|
throw createHttpError(
|
||||||
|
`cloudtentacles 当前绑定角色(${roleInfo.name}/${roleInfo.rid})与客户确认角色(${confirmedRoleName || "-"}/${confirmedRoleId || "-"})不一致,请重新刷新角色后再发货`,
|
||||||
|
{
|
||||||
|
statusCode: 409,
|
||||||
|
errorCode: `${errorCodePrefix}_dispatch_role_mismatch`,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextFlow = normalizeKuaishouCloudFlow({
|
||||||
|
...flow,
|
||||||
|
binding: {
|
||||||
|
...flow.binding,
|
||||||
|
roleName: roleInfo.name,
|
||||||
|
roleId: roleInfo.rid,
|
||||||
|
},
|
||||||
|
role: {
|
||||||
|
...flow.role,
|
||||||
|
status: "ready",
|
||||||
|
name: roleInfo.name,
|
||||||
|
rid: roleInfo.rid,
|
||||||
|
refreshedAt: now,
|
||||||
|
errorMessage: "",
|
||||||
|
rawInfo: roleInfo.rawInfo,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const nextContext = {
|
||||||
|
...taskContext,
|
||||||
|
kuaishouCloudFulfillment: nextFlow,
|
||||||
|
};
|
||||||
|
|
||||||
|
const updatedTask = await updateTask(task.id, {
|
||||||
|
role_id: roleInfo.rid,
|
||||||
|
role_name: roleInfo.name,
|
||||||
|
context_json: JSON.stringify(nextContext),
|
||||||
|
updated_at: now,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!updatedTask) {
|
||||||
|
throw createHttpError("发货前角色信息同步失败", {
|
||||||
|
statusCode: 500,
|
||||||
|
errorCode: `${errorCodePrefix}_dispatch_role_update_failed`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await createTaskEvent(
|
||||||
|
task.id,
|
||||||
|
"kuaishou_cloud_role_info_synced_before_dispatch",
|
||||||
|
{
|
||||||
|
source,
|
||||||
|
roleName: roleInfo.name,
|
||||||
|
roleId: roleInfo.rid,
|
||||||
|
vnId: flow.binding.vnId,
|
||||||
|
actor: input.actor || null,
|
||||||
|
},
|
||||||
|
now
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
task: updatedTask,
|
||||||
|
taskContext: nextContext,
|
||||||
|
flow: nextFlow,
|
||||||
|
roleInfo,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function isSameKuaishouCloudRole(
|
||||||
|
confirmedRole: { name: string; rid: string },
|
||||||
|
cloudtentaclesRole: { name: string; rid: string }
|
||||||
|
) {
|
||||||
|
if (confirmedRole.rid && cloudtentaclesRole.rid) {
|
||||||
|
return confirmedRole.rid === cloudtentaclesRole.rid;
|
||||||
|
}
|
||||||
|
|
||||||
|
const confirmedName = normalizeKuaishouCloudRoleNameForCompare(
|
||||||
|
confirmedRole.name
|
||||||
|
);
|
||||||
|
const cloudtentaclesName = normalizeKuaishouCloudRoleNameForCompare(
|
||||||
|
cloudtentaclesRole.name
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!confirmedName || !cloudtentaclesName) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return confirmedName === cloudtentaclesName;
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeKuaishouCloudRoleNameForCompare(value: unknown) {
|
||||||
|
const name = String(value || "").trim();
|
||||||
|
if (!name) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
const parts = name
|
||||||
|
.split("-")
|
||||||
|
.map((part) => part.trim())
|
||||||
|
.filter(Boolean);
|
||||||
|
const devicePart = parts[0] || "";
|
||||||
|
const channelPart = parts[1] || "";
|
||||||
|
if (
|
||||||
|
parts.length >= 3 &&
|
||||||
|
isKuaishouCloudDevicePart(devicePart) &&
|
||||||
|
isKuaishouCloudChannelPart(channelPart)
|
||||||
|
) {
|
||||||
|
return normalizeTextForCompare(parts.slice(2).join("-"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return normalizeTextForCompare(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isKuaishouCloudDevicePart(value: string) {
|
||||||
|
return ["安卓", "android", "ios", "苹果"].includes(value.toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
function isKuaishouCloudChannelPart(value: string) {
|
||||||
|
return ["qq", "微信", "vx", "wechat", "v"].includes(value.toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeTextForCompare(value: unknown) {
|
||||||
|
return String(value || "")
|
||||||
|
.trim()
|
||||||
|
.toLowerCase()
|
||||||
|
.replace(/\s+/g, "");
|
||||||
|
}
|
||||||
@@ -19,6 +19,7 @@ import {
|
|||||||
type JsonObject,
|
type JsonObject,
|
||||||
} from "./domain.js";
|
} from "./domain.js";
|
||||||
import { resolvePersistedCloudtentaclesContextBySourceKeys } from "./cloudtentacles-context.js";
|
import { resolvePersistedCloudtentaclesContextBySourceKeys } from "./cloudtentacles-context.js";
|
||||||
|
import { syncKuaishouCloudRoleInfoBeforeDispatch } from "./dispatch-role-sync.js";
|
||||||
import { normalizeActor, parseTaskContext } from "./task-context.js";
|
import { normalizeActor, parseTaskContext } from "./task-context.js";
|
||||||
import type { TaskRow } from "../../../types/repository/rows.js";
|
import type { TaskRow } from "../../../types/repository/rows.js";
|
||||||
|
|
||||||
@@ -68,25 +69,36 @@ export async function dispatchKuaishouCloudFulfillmentTask(
|
|||||||
return { task, flow };
|
return { task, flow };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const synced = await syncKuaishouCloudRoleInfoBeforeDispatch(task, {
|
||||||
|
now,
|
||||||
|
actor,
|
||||||
|
source: options.source || "system_before_dispatch",
|
||||||
|
cloudContext,
|
||||||
|
taskContext,
|
||||||
|
flow,
|
||||||
|
});
|
||||||
|
const syncedFlow = synced.flow;
|
||||||
|
const syncedTaskContext = synced.taskContext;
|
||||||
|
|
||||||
const dispatchResult = await useCloudtentaclesSku({
|
const dispatchResult = await useCloudtentaclesSku({
|
||||||
...cloudContext,
|
...cloudContext,
|
||||||
id: flow.binding.skuId,
|
id: syncedFlow.binding.skuId,
|
||||||
virtualNumberId: flow.binding.vnId,
|
virtualNumberId: syncedFlow.binding.vnId,
|
||||||
phone: flow.binding.vnPhone,
|
phone: syncedFlow.binding.vnPhone,
|
||||||
});
|
});
|
||||||
|
|
||||||
const nextContext = {
|
const nextContext = {
|
||||||
...taskContext,
|
...syncedTaskContext,
|
||||||
kuaishouCloudFulfillment: {
|
kuaishouCloudFulfillment: {
|
||||||
...flow,
|
...syncedFlow,
|
||||||
ticket: {
|
ticket: {
|
||||||
...flow.ticket,
|
...syncedFlow.ticket,
|
||||||
code: ticketCode || persistedTicketCode,
|
code: ticketCode || persistedTicketCode,
|
||||||
capturedAt: ticketCode ? now : flow.ticket.capturedAt,
|
capturedAt: ticketCode ? now : syncedFlow.ticket.capturedAt,
|
||||||
capturedBy: ticketCode && actor ? actor : flow.ticket.capturedBy,
|
capturedBy: ticketCode && actor ? actor : syncedFlow.ticket.capturedBy,
|
||||||
},
|
},
|
||||||
dispatch: {
|
dispatch: {
|
||||||
...flow.dispatch,
|
...syncedFlow.dispatch,
|
||||||
status: "success",
|
status: "success",
|
||||||
dispatchAt: now,
|
dispatchAt: now,
|
||||||
dispatchBy: actor,
|
dispatchBy: actor,
|
||||||
@@ -127,9 +139,9 @@ export async function dispatchKuaishouCloudFulfillmentTask(
|
|||||||
{
|
{
|
||||||
source: String(options.source || "system").trim() || "system",
|
source: String(options.source || "system").trim() || "system",
|
||||||
ticketCodeMasked: maskCode(ticketCode || persistedTicketCode),
|
ticketCodeMasked: maskCode(ticketCode || persistedTicketCode),
|
||||||
skuId: flow.binding.skuId,
|
skuId: syncedFlow.binding.skuId,
|
||||||
vnId: flow.binding.vnId,
|
vnId: syncedFlow.binding.vnId,
|
||||||
vnPhoneMasked: maskPhone(flow.binding.vnPhone),
|
vnPhoneMasked: maskPhone(syncedFlow.binding.vnPhone),
|
||||||
sendType: dispatchResult.sendType,
|
sendType: dispatchResult.sendType,
|
||||||
note: dispatchResult.note,
|
note: dispatchResult.note,
|
||||||
actor,
|
actor,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { createHttpError } from '../../../utils/http.js'
|
import { createHttpError } from '../../../utils/http.js'
|
||||||
|
import { logInfo } from '../../../utils/logger.js'
|
||||||
import { cloudtentaclesRequest } from './http-client.js'
|
import { cloudtentaclesRequest } from './http-client.js'
|
||||||
import { resolveCloudtentaclesConfig } from './helpers.js'
|
import { resolveCloudtentaclesConfig } from './helpers.js'
|
||||||
|
|
||||||
@@ -67,12 +68,23 @@ export async function listCloudtentaclesDeliveryRecords(
|
|||||||
|
|
||||||
const data = isPlainObject(result.payload?.data) ? result.payload.data : {}
|
const data = isPlainObject(result.payload?.data) ? result.payload.data : {}
|
||||||
const values = Array.isArray(data.values) ? data.values : []
|
const values = Array.isArray(data.values) ? data.values : []
|
||||||
|
const total = normalizeNonNegativeInteger(data.total, values.length)
|
||||||
|
|
||||||
|
logInfo('[cloudtentacles/records]', '发货记录查询完成', {
|
||||||
|
page,
|
||||||
|
size,
|
||||||
|
recordCode: normalizePositiveInteger(payload.recordCode, 4),
|
||||||
|
startDate,
|
||||||
|
endDate,
|
||||||
|
total,
|
||||||
|
returnedCount: values.length,
|
||||||
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
baseUrl: config.baseUrl,
|
baseUrl: config.baseUrl,
|
||||||
page,
|
page,
|
||||||
size,
|
size,
|
||||||
total: normalizeNonNegativeInteger(data.total, values.length),
|
total,
|
||||||
items: values.map(mapCloudtentaclesDeliveryRecord),
|
items: values.map(mapCloudtentaclesDeliveryRecord),
|
||||||
raw: data,
|
raw: data,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user