From 9f6f67c8a854323593c1e5272fcfd8ee55cf10d3 Mon Sep 17 00:00:00 2001 From: yml Date: Tue, 14 Apr 2026 17:30:36 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=87=AA=E5=8A=A8=E5=8F=91?= =?UTF-8?q?=E8=B4=A7bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/backend/config/default.cjs | 7 - apps/backend/package.json | 3 +- .../scripts/test-agiso-auto-delivery.js | 288 ++++++++++++++++++ apps/backend/src/config/runtime.js | 19 -- .../services/admin/admin-task-read-helpers.js | 2 - .../agiso/xianyu/auto-delivery-service.js | 63 +--- .../xianyu/auto-delivery-service.test.js | 13 + apps/backend/src/types/admin-read-models.js | 1 - apps/backend/src/types/runtime-config.js | 7 - apps/frontend/src/types/admin.ts | 1 - .../src/views/admin/AdminTaskDetailView.vue | 2 - docs/xianyu_api/更新发货状态.md | 50 +++ docs/xianyu_api/自动发货.md | 86 ------ docs/商品识别与履约SKU配置.md | 77 ----- 14 files changed, 366 insertions(+), 253 deletions(-) create mode 100644 apps/backend/scripts/test-agiso-auto-delivery.js create mode 100644 docs/xianyu_api/更新发货状态.md delete mode 100644 docs/xianyu_api/自动发货.md delete mode 100644 docs/商品识别与履约SKU配置.md diff --git a/apps/backend/config/default.cjs b/apps/backend/config/default.cjs index 280dc3bd..104dc506 100644 --- a/apps/backend/config/default.cjs +++ b/apps/backend/config/default.cjs @@ -55,13 +55,6 @@ module.exports = { enabled: true, endpoint: 'https://gw-api.agiso.com/aldsIdle/Order/DummySend', apiVersion: '1', - aldsType: 1, - ignoreAldsLog: false, - ignoreBlackList: false, - ignoreOnOff: false, - ignoreRefundCheck: false, - ignoreRestricted: false, - ignoreTradeStatusCheck: false, }, messaging: { enabled: false, diff --git a/apps/backend/package.json b/apps/backend/package.json index 2ebad5f7..69055e27 100644 --- a/apps/backend/package.json +++ b/apps/backend/package.json @@ -6,11 +6,12 @@ "scripts": { "browser:install": "playwright install chromium", "browser:install:linux": "playwright install --with-deps chromium", + "agiso:auto-delivery:test": "node scripts/test-agiso-auto-delivery.js", "cleanup:dev-data": "node scripts/cleanup-dev-data.js", "seed:dev-data": "node scripts/seed-dev-data.js", "db:migrate": "node src/db/migrate.js", "dev": "node --watch-path=src --watch-path=config --watch-preserve-output src/index.js", - "test": "node --test", + "test": "node --test $(find src -name '*.test.js' -print)", "typecheck": "tsc -p tsconfig.json --noEmit", "start": "node src/index.js" }, diff --git a/apps/backend/scripts/test-agiso-auto-delivery.js b/apps/backend/scripts/test-agiso-auto-delivery.js new file mode 100644 index 00000000..2bb53ca6 --- /dev/null +++ b/apps/backend/scripts/test-agiso-auto-delivery.js @@ -0,0 +1,288 @@ +#!/usr/bin/env node + +import crypto from 'node:crypto' +import process from 'node:process' +import { fileURLToPath } from 'node:url' +import { setTimeout as sleep } from 'node:timers/promises' + +import { query, closeDb } from '../src/db/client.js' +import { parseJsonObject } from '../src/utils/json.js' +import { getAgisoShopConfig } from '../src/services/platforms/agiso/shop-config-service.js' +import { queryAgisoXianyuOrderDetail } from '../src/services/platforms/agiso/xianyu/order-detail-service.js' + +const DEFAULT_DUMMY_ENDPOINT = 'https://gw-api.agiso.com/aldsIdle/Order/DummySend' +const DEFAULT_POLL_SECONDS = [0, 3, 10] + +async function main() { + const options = parseArgs(process.argv.slice(2)) + if (options.help || !options.orderId) { + printHelp() + process.exit(options.help ? 0 : 1) + } + + const orderRecord = await resolveOrderRecord(options) + const shopId = orderRecord?.shop_id || options.shopId + const shopConfig = getAgisoShopConfig(shopId) || {} + const accessToken = String(shopConfig.accessToken || '').trim() + const appSecret = String(shopConfig.appSecret || process.env.AGISO_APP_SECRET || '').trim() + + if (!shopId) { + throw new Error('未提供 shopId,且数据库中也没有查到该订单对应的店铺') + } + + if (!accessToken) { + throw new Error(`店铺 ${shopId} 缺少 accessToken 配置,请检查 apps/backend/data/agiso-shops.json`) + } + + if (!appSecret) { + throw new Error('缺少 AGISO_APP_SECRET 或店铺级 appSecret 配置') + } + + printJson('测试输入', { + orderId: options.orderId, + shopId, + pollSeconds: options.pollSeconds, + orderRecord: orderRecord + ? { + id: Number(orderRecord.id || 0) || null, + platformOrderId: String(orderRecord.platform_order_id || '').trim(), + orderStatus: String(orderRecord.order_status || '').trim(), + payStatus: String(orderRecord.pay_status || '').trim(), + provider: String(orderRecord.provider || '').trim(), + platform: String(orderRecord.platform || '').trim(), + } + : null, + }) + + const beforeDetail = await queryAgisoXianyuOrderDetail({ + shopId, + platformOrderId: options.orderId, + requestId: `diag-before-${Date.now()}`, + }) + printJson('调用前订单详情', summarizeDetail(beforeDetail)) + + const result = await executeRequest({ + platformOrderId: options.orderId, + accessToken, + appSecret, + }) + printJson('接口响应 更新发货状态 DummySend', result) + + for (const seconds of options.pollSeconds) { + if (seconds > 0) { + await sleep(seconds * 1000) + } + + const detail = await queryAgisoXianyuOrderDetail({ + shopId, + platformOrderId: options.orderId, + requestId: `diag-after-${seconds}s-${Date.now()}`, + }) + printJson(`调用后订单详情 +${seconds}s`, summarizeDetail(detail)) + } +} + +function parseArgs(argv) { + const output = { + orderId: '', + shopId: '', + pollSeconds: [...DEFAULT_POLL_SECONDS], + help: false, + } + + for (let index = 0; index < argv.length; index += 1) { + const current = String(argv[index] || '').trim() + if (!current) { + continue + } + + if (!current.startsWith('--')) { + if (!output.orderId) { + output.orderId = current + continue + } + + throw new Error(`无法识别的参数:${current}`) + } + + if (current === '--help') { + output.help = true + continue + } + + const [rawKey, inlineValue = ''] = current.split('=', 2) + const key = rawKey.slice(2) + const nextValue = inlineValue || argv[index + 1] || '' + const shouldConsumeNext = !inlineValue && argv[index + 1] && !String(argv[index + 1]).startsWith('--') + + switch (key) { + case 'shop-id': + output.shopId = String(nextValue || '').trim() + break + case 'poll': + output.pollSeconds = parsePollSeconds(nextValue) + break + default: + throw new Error(`无法识别的参数:${current}`) + } + + if (shouldConsumeNext) { + index += 1 + } + } + + return output +} + +function parsePollSeconds(value) { + const normalized = String(value || '').trim() + if (!normalized) { + return [...DEFAULT_POLL_SECONDS] + } + + const parsed = normalized + .split(',') + .map((item) => Number(String(item || '').trim())) + .filter((item) => Number.isFinite(item) && item >= 0) + .map((item) => Math.floor(item)) + + if (parsed.length === 0) { + throw new Error(`poll 参数格式无效:${value}`) + } + + return parsed +} + +async function resolveOrderRecord(options) { + const explicitShopId = String(options.shopId || '').trim() + if (explicitShopId) { + const result = await query( + ` + SELECT * + FROM orders + WHERE provider = 'agiso' + AND platform = 'xianyu' + AND shop_id = $1 + AND platform_order_id = $2 + ORDER BY id DESC + LIMIT 1 + `, + [explicitShopId, options.orderId], + ) + + return result.rows[0] || null + } + + const result = await query( + ` + SELECT * + FROM orders + WHERE provider = 'agiso' + AND platform = 'xianyu' + AND platform_order_id = $1 + ORDER BY id DESC + LIMIT 2 + `, + [options.orderId], + ) + + if (result.rows.length > 1) { + throw new Error(`数据库里命中多条同订单号记录,请显式传入 --shop-id。订单号:${options.orderId}`) + } + + return result.rows[0] || null +} + +async function executeRequest(context) { + const timestamp = String(Math.floor(Date.now() / 1000)) + const requestBody = buildDummySendBody(context, timestamp) + const response = await fetch(DEFAULT_DUMMY_ENDPOINT, { + method: 'POST', + headers: { + Authorization: `Bearer ${context.accessToken}`, + ApiVersion: '1', + 'content-type': 'application/x-www-form-urlencoded; charset=utf-8', + }, + body: new URLSearchParams(requestBody).toString(), + }) + const rawText = await response.text() + const payload = parseJsonObject(rawText, { preserveLargeIntegers: true }) + + return { + endpoint: DEFAULT_DUMMY_ENDPOINT, + status: response.status, + requestBody, + response: payload, + rawText, + } +} + +function buildDummySendBody(context, timestamp) { + const payload = { + tid: context.platformOrderId, + timestamp, + } + + payload.sign = generateSign(payload, context.appSecret) + return payload +} + +function generateSign(params, appSecret) { + let raw = String(appSecret || '').trim() + for (const [key, value] of Object.entries(params).sort(([left], [right]) => left.localeCompare(right))) { + raw += `${key}${value}` + } + raw += String(appSecret || '').trim() + return crypto.createHash('md5').update(raw, 'utf8').digest('hex').toLowerCase() +} + +function summarizeDetail(detailResult) { + return { + success: Boolean(detailResult?.success), + reason: String(detailResult?.reason || '').trim(), + errorMessage: String(detailResult?.errorMessage || '').trim(), + responseStatus: Number(detailResult?.responseStatus || 0), + shipped: Boolean(detailResult?.shipped), + shipTime: Number(detailResult?.shipTime || 0), + orderStatus: Number(detailResult?.orderStatus || 0), + bizOrderId: String(detailResult?.detailPayload?.biz_order_id || '').trim(), + sellerNick: String(detailResult?.detailPayload?.seller_nick || '').trim(), + buyerNick: String(detailResult?.detailPayload?.buyer_nick || '').trim(), + sku: String(detailResult?.detailPayload?.sku || '').trim(), + itemTitle: String(detailResult?.detailPayload?.item?.title || '').trim(), + } +} + +function printJson(title, value) { + process.stdout.write(`\n=== ${title} ===\n`) + process.stdout.write(`${JSON.stringify(value, null, 2)}\n`) +} + +function printHelp() { + process.stdout.write(`用法: + node scripts/test-agiso-auto-delivery.js <订单号> [--shop-id <店铺ID>] [--poll 0,3,10] + +说明: + 1. 该脚本只测试正确的发货接口 DummySend。 + 2. 会先查 Order/Detail,再调用 DummySend,再按 poll 秒数轮询发货状态。 + +示例: + node scripts/test-agiso-auto-delivery.js 4502285714045005830 + node scripts/test-agiso-auto-delivery.js 4502285714045005830 --poll 0,5,15 + node scripts/test-agiso-auto-delivery.js 4502285714045005830 --shop-id 2209880145223 +`) +} + +const isNodeTestRunner = Array.isArray(process.execArgv) && process.execArgv.includes('--test') +const isDirectRun = !isNodeTestRunner && process.argv[1] && fileURLToPath(import.meta.url) === process.argv[1] + +if (isDirectRun) { + main() + .catch((error) => { + process.stderr.write(`${error instanceof Error ? error.stack || error.message : String(error)}\n`) + process.exitCode = 1 + }) + .finally(async () => { + await closeDb() + }) +} diff --git a/apps/backend/src/config/runtime.js b/apps/backend/src/config/runtime.js index 8720338f..c63e96a6 100644 --- a/apps/backend/src/config/runtime.js +++ b/apps/backend/src/config/runtime.js @@ -215,25 +215,6 @@ function applyEnvOverrides(baseConfig) { nextConfig.platforms.agiso.autoDelivery.apiVersion = agisoAutoDeliveryApiVersion } - const agisoAutoDeliveryAldsType = parseInteger(process.env.AGISO_AUTO_DELIVERY_ALDS_TYPE) - if (agisoAutoDeliveryAldsType !== null) { - nextConfig.platforms.agiso.autoDelivery.aldsType = agisoAutoDeliveryAldsType - } - - for (const [envKey, configKey] of [ - ['AGISO_AUTO_DELIVERY_IGNORE_ALDS_LOG', 'ignoreAldsLog'], - ['AGISO_AUTO_DELIVERY_IGNORE_BLACK_LIST', 'ignoreBlackList'], - ['AGISO_AUTO_DELIVERY_IGNORE_ON_OFF', 'ignoreOnOff'], - ['AGISO_AUTO_DELIVERY_IGNORE_REFUND_CHECK', 'ignoreRefundCheck'], - ['AGISO_AUTO_DELIVERY_IGNORE_RESTRICTED', 'ignoreRestricted'], - ['AGISO_AUTO_DELIVERY_IGNORE_TRADE_STATUS_CHECK', 'ignoreTradeStatusCheck'], - ]) { - const parsed = parseBoolean(process.env[envKey]) - if (parsed !== null) { - nextConfig.platforms.agiso.autoDelivery[configKey] = parsed - } - } - const agisoMessageAppSecret = String(process.env.AGISO_MESSAGE_APP_SECRET || '').trim() if (agisoMessageAppSecret) { nextConfig.platforms.agiso.messaging.appSecret = agisoMessageAppSecret diff --git a/apps/backend/src/services/admin/admin-task-read-helpers.js b/apps/backend/src/services/admin/admin-task-read-helpers.js index f89847da..bc5f48c6 100644 --- a/apps/backend/src/services/admin/admin-task-read-helpers.js +++ b/apps/backend/src/services/admin/admin-task-read-helpers.js @@ -306,7 +306,6 @@ export function buildOrderAgisoAutoDeliverySummary(order, tasks = []) { responseStatus: 0, errorMessage: '', requestId: '', - aldsType: null, updatedAt: null, sourceTaskId: null, sourceTaskNo: '', @@ -409,7 +408,6 @@ function mapAgisoAutoDeliveryContext(value) { responseStatus: Number(value.responseStatus || 0), errorMessage: String(value.errorMessage || '').trim(), requestId: String(value.requestId || '').trim(), - aldsType: Number(value.aldsType || 0) || null, updatedAt: value.updatedAt || null, } } diff --git a/apps/backend/src/services/platforms/agiso/xianyu/auto-delivery-service.js b/apps/backend/src/services/platforms/agiso/xianyu/auto-delivery-service.js index 684ef7c0..a62cd8a6 100644 --- a/apps/backend/src/services/platforms/agiso/xianyu/auto-delivery-service.js +++ b/apps/backend/src/services/platforms/agiso/xianyu/auto-delivery-service.js @@ -10,6 +10,8 @@ import { parseJsonObject } from '../../../../utils/json.js' import { logWebhook } from '../../../../utils/logger.js' import { nowIso } from '../../../../utils/time.js' +const AGISO_DUMMY_SEND_ENDPOINT = 'https://gw-api.agiso.com/aldsIdle/Order/DummySend' + /** * @typedef {{ * order?: Record | null @@ -82,15 +84,8 @@ export async function ensureAgisoXianyuAutoDeliveryForDeliveredTask({ apiVersion: config.apiVersion, }) const requestBody = buildRequestBody({ - tids: String(order.platform_order_id || '').trim(), + platformOrderId: String(order.platform_order_id || '').trim(), appSecret: config.appSecret, - aldsType: config.aldsType, - ignoreAldsLog: config.ignoreAldsLog, - ignoreBlackList: config.ignoreBlackList, - ignoreOnOff: config.ignoreOnOff, - ignoreRefundCheck: config.ignoreRefundCheck, - ignoreRestricted: config.ignoreRestricted, - ignoreTradeStatusCheck: config.ignoreTradeStatusCheck, }) logWebhook('[agiso/xianyu/auto-delivery]', '开始执行 Agiso 咸鱼自动发货', { @@ -100,7 +95,6 @@ export async function ensureAgisoXianyuAutoDeliveryForDeliveredTask({ shopId: order.shop_id, platformOrderId: order.platform_order_id, endpoint: config.endpoint, - aldsType: config.aldsType, }) try { @@ -116,7 +110,7 @@ export async function ensureAgisoXianyuAutoDeliveryForDeliveredTask({ if (success) { const requestId = String(parsed?.RequestId || '').trim() - // DummySend 接口返回成功后,再查一次 Order/Detail 确认订单真的进入已发货状态 meow~ + // 发货接口返回成功后,再查一次 Order/Detail 确认订单真的进入已发货状态 meow~ const confirmResult = await confirmAgisoXianyuAutoDeliveryShipped({ shopId: order.shop_id, platformOrderId: order.platform_order_id, @@ -144,10 +138,9 @@ export async function ensureAgisoXianyuAutoDeliveryForDeliveredTask({ order, responseStatus: response.status, response: parsed, - errorMessage: `接口返回成功,但订单状态未确认进入已发货 (orderStatus=${confirmResult.orderStatus}, shipTime=${confirmResult.shipTime})`, + errorMessage: `Agiso 发货状态更新接口已受理,但订单仍未进入已发货,请检查该订单是否允许无物流发货 (orderStatus=${confirmResult.orderStatus}, shipTime=${confirmResult.shipTime})`, detail: { requestId, - aldsType: config.aldsType, confirmOrderStatus: confirmResult.orderStatus, confirmShipTime: confirmResult.shipTime, }, @@ -175,7 +168,6 @@ export async function ensureAgisoXianyuAutoDeliveryForDeliveredTask({ response: parsed, detail: { requestId, - aldsType: config.aldsType, confirmOrderStatus: confirmResult.orderStatus, confirmShipTime: confirmResult.shipTime, }, @@ -250,17 +242,10 @@ function resolveAgisoXianyuAutoDeliveryConfig(order) { return { enabled: normalizeBooleanLike(baseConfig.enabled, true), - endpoint: String(baseConfig.endpoint || '').trim(), + endpoint: resolveAgisoAutoDeliveryEndpoint(baseConfig.endpoint), apiVersion: String(baseConfig.apiVersion || shopConfig.apiVersion || '1').trim() || '1', appSecret: String(shopConfig.appSecret || runtimeConfig.platforms?.agiso?.appSecret || '').trim(), accessToken: String(shopConfig.accessToken || '').trim(), - aldsType: normalizePositiveInteger(baseConfig.aldsType, 1), - ignoreAldsLog: normalizeBooleanLike(baseConfig.ignoreAldsLog, false), - ignoreBlackList: normalizeBooleanLike(baseConfig.ignoreBlackList, false), - ignoreOnOff: normalizeBooleanLike(baseConfig.ignoreOnOff, false), - ignoreRefundCheck: normalizeBooleanLike(baseConfig.ignoreRefundCheck, false), - ignoreRestricted: normalizeBooleanLike(baseConfig.ignoreRestricted, false), - ignoreTradeStatusCheck: normalizeBooleanLike(baseConfig.ignoreTradeStatusCheck, false), } } @@ -272,26 +257,9 @@ function buildRequestHeaders({ accessToken, apiVersion }) { } } -function buildRequestBody({ - tids, - appSecret, - aldsType, - ignoreAldsLog, - ignoreBlackList, - ignoreOnOff, - ignoreRefundCheck, - ignoreRestricted, - ignoreTradeStatusCheck, -}) { +function buildRequestBody({ platformOrderId, appSecret }) { const payload = { - tids: String(tids || '').trim(), - aldsType: String(normalizePositiveInteger(aldsType, 1)), - ignoreAldsLog: String(Boolean(ignoreAldsLog)), - ignoreBlackList: String(Boolean(ignoreBlackList)), - ignoreOnOff: String(Boolean(ignoreOnOff)), - ignoreRefundCheck: String(Boolean(ignoreRefundCheck)), - ignoreRestricted: String(Boolean(ignoreRestricted)), - ignoreTradeStatusCheck: String(Boolean(ignoreTradeStatusCheck)), + tid: String(platformOrderId || '').trim(), timestamp: String(Math.floor(Date.now() / 1000)), } @@ -350,6 +318,10 @@ export function resolveAgisoAutoDeliveryErrorMessage(payload, rawText, statusCod return text || `Agiso 咸鱼自动发货失败,HTTP ${statusCode}` } +export function resolveAgisoAutoDeliveryEndpoint(value) { + return AGISO_DUMMY_SEND_ENDPOINT +} + async function persistAgisoAutoDeliveryResult(task, { status, trigger, @@ -428,15 +400,6 @@ function isAgisoXianyuOrder(order) { && Number(order?.id || 0) > 0 } -function normalizePositiveInteger(value, fallbackValue) { - const parsed = Number(value) - if (Number.isFinite(parsed) && parsed > 0) { - return Math.floor(parsed) - } - - return fallbackValue -} - function normalizeBooleanLike(value, fallbackValue) { if (typeof value === 'boolean') { return value @@ -463,7 +426,7 @@ function isPlainObject(value) { } /** - * DummySend 返回成功后,再查一次 Order/Detail 确认订单是否真的进入已发货状态 meow~ + * 发货接口返回成功后,再查一次 Order/Detail 确认订单是否真的进入已发货状态 meow~ * 只有 ship_time > 0 或 orderStatus >= 3 才算发货确认通过 */ async function confirmAgisoXianyuAutoDeliveryShipped({ shopId = '', platformOrderId = '', requestId = '' } = {}) { diff --git a/apps/backend/src/services/platforms/agiso/xianyu/auto-delivery-service.test.js b/apps/backend/src/services/platforms/agiso/xianyu/auto-delivery-service.test.js index ad6d607d..5a99fcfd 100644 --- a/apps/backend/src/services/platforms/agiso/xianyu/auto-delivery-service.test.js +++ b/apps/backend/src/services/platforms/agiso/xianyu/auto-delivery-service.test.js @@ -5,6 +5,7 @@ import { hasAgisoAutoDeliverySucceeded, isOrderReadyForAgisoAutoDelivery, isAgisoAutoDeliverySuccess, + resolveAgisoAutoDeliveryEndpoint, resolveAgisoAutoDeliveryErrorMessage, } from './auto-delivery-service.js' @@ -58,3 +59,15 @@ test('resolveAgisoAutoDeliveryErrorMessage prefers structured payload message be 'fallback raw body', ) }) + +test('resolveAgisoAutoDeliveryEndpoint falls back to DummySend', () => { + assert.equal( + resolveAgisoAutoDeliveryEndpoint(''), + 'https://gw-api.agiso.com/aldsIdle/Order/DummySend', + ) + + assert.equal( + resolveAgisoAutoDeliveryEndpoint('https://gw-api.agiso.com/aldsIdle/Order/DummySend'), + 'https://gw-api.agiso.com/aldsIdle/Order/DummySend', + ) +}) diff --git a/apps/backend/src/types/admin-read-models.js b/apps/backend/src/types/admin-read-models.js index 1b427594..643e6c45 100644 --- a/apps/backend/src/types/admin-read-models.js +++ b/apps/backend/src/types/admin-read-models.js @@ -21,7 +21,6 @@ export {} * responseStatus: number * errorMessage: string * requestId: string - * aldsType: number | null * updatedAt: string | null * }} AdminAgisoAutoDeliveryStatus */ diff --git a/apps/backend/src/types/runtime-config.js b/apps/backend/src/types/runtime-config.js index ea38db69..1d075ea3 100644 --- a/apps/backend/src/types/runtime-config.js +++ b/apps/backend/src/types/runtime-config.js @@ -76,13 +76,6 @@ export {} * enabled: boolean * endpoint: string * apiVersion: string - * aldsType: number - * ignoreAldsLog: boolean - * ignoreBlackList: boolean - * ignoreOnOff: boolean - * ignoreRefundCheck: boolean - * ignoreRestricted: boolean - * ignoreTradeStatusCheck: boolean * } * messaging: { * enabled: boolean diff --git a/apps/frontend/src/types/admin.ts b/apps/frontend/src/types/admin.ts index 7d01b2c1..9788e3fa 100644 --- a/apps/frontend/src/types/admin.ts +++ b/apps/frontend/src/types/admin.ts @@ -174,7 +174,6 @@ export interface AdminAgisoAutoDeliveryStatus { responseStatus: number errorMessage: string requestId: string - aldsType: number | null updatedAt: string | null } diff --git a/apps/frontend/src/views/admin/AdminTaskDetailView.vue b/apps/frontend/src/views/admin/AdminTaskDetailView.vue index 31d72cba..e4b62d1a 100644 --- a/apps/frontend/src/views/admin/AdminTaskDetailView.vue +++ b/apps/frontend/src/views/admin/AdminTaskDetailView.vue @@ -159,7 +159,6 @@ function formatTaskEventPayload(payload: Record) { payload.reason ? `原因 ${payload.reason}` : '', payload.responseStatus ? `HTTP ${payload.responseStatus}` : '', payload.requestId ? `请求 ${payload.requestId}` : '', - payload.aldsType ? `发货类型 ${payload.aldsType}` : '', payload.errorMessage ? `错误 ${payload.errorMessage}` : '', ].filter(Boolean) @@ -442,7 +441,6 @@ onBeforeUnmount(clearScreenshotPreview)

原因:{{ formatAutoDeliveryReason(detail.task.agisoAutoDelivery.reason) }}

HTTP:{{ detail.task.agisoAutoDelivery.responseStatus }}

请求 ID:{{ detail.task.agisoAutoDelivery.requestId }}

-

发货类型:{{ detail.task.agisoAutoDelivery.aldsType }}

diff --git a/docs/xianyu_api/更新发货状态.md b/docs/xianyu_api/更新发货状态.md new file mode 100644 index 00000000..0dd10d06 --- /dev/null +++ b/docs/xianyu_api/更新发货状态.md @@ -0,0 +1,50 @@ + +更新发货状态 +简要描述: 接口调用示例 + +¥基础 +执行无物流发货,更新发货状态 +请求URL: + +https://gw-api.agiso.com/aldsIdle/Order/DummySend +请求方式: + +POST +公共Header: + +Authorization +是 +string +httpPost.addHeader("Authorization","Bearer "+ accessToken) +ApiVersion +是 +string +httpPost.addHeader("ApiVersion", "1") +公共参数: + +timestamp +是 +Date +时间戳,例如:1468476350。API服务端允许客户端请求最大时间误差为10分钟。 +sign +是 +string +API输入参数签名结果,签名算法参照下面的介绍。 +参数: + +tid +是 +Long +订单号 +返回示例 + + + { + "IsSuccess": true, + "Data": null + "Error_Code": 0, + "Error_Msg": "" + "AllowRetry": null, + "RequestId": "20221027142251106" + } + \ No newline at end of file diff --git a/docs/xianyu_api/自动发货.md b/docs/xianyu_api/自动发货.md deleted file mode 100644 index d930cbc6..00000000 --- a/docs/xianyu_api/自动发货.md +++ /dev/null @@ -1,86 +0,0 @@ -执行自动发货 -简要描述: 接口调用示例 - -¥高级 -调用该接口将根据您在自动发货后台设定的发货规则,进行一次发货逻辑的处理。该操作等同于在手动发货页面的操作。注意:该页面执行后,也会自动发送闲鱼消息,可以通过参数中的选项控制发货中的一些限制。 -请求URL: - -https://gw-api.agiso.com/aldsIdle/Alds/AldsSend -请求方式: - -POST -公共Header: - -Authorization -是 -string -httpPost.addHeader("Authorization","Bearer "+ accessToken) -ApiVersion -是 -string -httpPost.addHeader("ApiVersion", "1") -公共参数: - -timestamp -是 -Date -时间戳,例如:1468476350。API服务端允许客户端请求最大时间误差为10分钟。 -sign -是 -string -API输入参数签名结果,签名算法参照下面的介绍。 -参数: - -tids -是 -String -订单编号,多个订单编号间用,分隔开 -ignoreAldsLog -否 -Boolean -忽略发货记录 -默认值:'false',可选值'true'、'false' -ignoreBlackList -否 -Boolean -忽略黑名单 -默认值:'false',可选值'true'、'false' -ignoreOnOff -否 -Boolean -忽略发货开关 -默认值:'false',可选值'true'、'false' -ignoreRefundCheck -否 -Boolean -退款中也发 -默认值:'false',可选值'true'、'false' -ignoreRestricted -否 -Boolean -忽略限拍限购 -默认值:'false',可选值'true'、'false' -ignoreTradeStatusCheck -否 -Boolean -忽略订单状态验证 -默认值:'false',可选值'true'、'false' -aldsType -是 -Int -自动发货类型,具体查看底部备注 -返回示例 - - - { - "IsSuccess": true, - "Data": null - "Error_Code": 0, - "Error_Msg": "" - "AllowRetry": null, - "RequestId": "20221027142251106" - } - -备注 - -aldsType自动发货类型:付款后发货=1,确认收货后赠送=2 \ No newline at end of file diff --git a/docs/商品识别与履约SKU配置.md b/docs/商品识别与履约SKU配置.md deleted file mode 100644 index 6e5ce2de..00000000 --- a/docs/商品识别与履约SKU配置.md +++ /dev/null @@ -1,77 +0,0 @@ -# 商品识别与履约 SKU 配置 - -当前后端已支持把外部商品先识别为内部履约 SKU,再继续匹配库存或人工履约。 -配置来源已经统一为后台管理页和后端数据文件。 - -## 配置目标 - -- `match` 负责识别外部商品 -- `skuCode` 代表内部履约 SKU -- `profileKey` 决定后续走库存自动链路还是人工链路 - -## 推荐配置格式 - -后台保存后会写入后端数据文件: - -- `/app/data/order-fulfillment-bindings.json` - -配置结构如下: - -```json -[ - { - "provider": "agiso", - "platform": "xianyu", - "shopId": "2209880145223", - "skuCode": "sjz_hdl_test01", - "profileKey": "tencent_claim_redeem", - "priority": 10, - "config": { - "note": "三角洲行动腾讯兑换码自动领取" - }, - "match": { - "externalSkuCode": "6228372634012", - "externalItemId": "1040695550204", - "externalSkuName": "周边", - "config": { - "resolvedSkuName": "三角洲行动-自动领取" - } - } - }, - { - "provider": "agiso", - "platform": "xianyu", - "shopId": "2209880145223", - "skuCode": "danzai_manual_special", - "profileKey": "manual_review", - "priority": 20, - "match": { - "externalSkuCode": "7000000000001", - "externalSkuName": "需要人工发货的商品" - } - } -] -``` - -## 匹配顺序 - -系统会按下面顺序匹配外部商品: - -1. `externalSkuCode` -2. `externalItemId` -3. 归一化后的 `externalSkuName` -4. 名称包含关系兜底 - -其中店铺级规则优先于平台级和全局级规则。 - -## 当前落库行为 - -- 订单商品的 `sku_code` 会保存为内部履约 SKU -- 原始外部商品信息会保留在 `item_snapshot_json` -- 后续履约任务、库存预占、领取链接都会按内部履约 SKU 继续执行 - -## 生效方式 - -- 后台保存后会立即同步到 `sku_fulfillment_bindings` -- 同时会同步到 `product_match_rules` -- 未匹配到规则的商品会自动落到人工处理