后端迁移自动发货服务

This commit is contained in:
yml
2026-05-21 14:46:56 +08:00
parent 861b7e0034
commit aedc5d928e
3 changed files with 195 additions and 60 deletions
@@ -1,5 +1,3 @@
// @ts-nocheck
import crypto from 'node:crypto' import crypto from 'node:crypto'
import { runtimeConfig } from '../../../../config/runtime.js' import { runtimeConfig } from '../../../../config/runtime.js'
@@ -11,23 +9,125 @@ import { ensureAgisoXianyuAutoDeliveryMessageDeliveredForTask } from './message-
import { parseJsonObject } from '../../../../utils/json.js' import { parseJsonObject } from '../../../../utils/json.js'
import { logWebhook } from '../../../../utils/logger.js' import { logWebhook } from '../../../../utils/logger.js'
import { nowIso } from '../../../../utils/time.js' import { nowIso } from '../../../../utils/time.js'
import type { TaskRow } from '../../../../types/repository-rows.js'
const AGISO_DUMMY_SEND_ENDPOINT = 'https://gw-api.agiso.com/aldsIdle/Order/DummySend' const AGISO_DUMMY_SEND_ENDPOINT = 'https://gw-api.agiso.com/aldsIdle/Order/DummySend'
/** type JsonObject = Record<string, unknown>
* @typedef {{
* order?: Record<string, any> | null type AutoDeliveryOrder = {
* task?: Record<string, any> | null id?: number | string
* trigger?: string provider?: string
* }} EnsureAgisoXianyuAutoDeliveryInput platform?: string
*/ shop_id?: string
shop_name?: string
platform_order_id?: string
[key: string]: unknown
}
type SupportedAgisoOrder = AutoDeliveryOrder & {
id: number | string
provider: 'agiso'
platform: 'xianyu'
platform_order_id: string
}
type AutoDeliveryTask = Partial<TaskRow> & {
id?: number | string
delivery_status?: string
task_status?: string
context_json?: string | JsonObject | null
[key: string]: unknown
}
type AutoDeliveryTaskWithId = AutoDeliveryTask & {
id: number | string
}
type EnsureAgisoXianyuAutoDeliveryInput = {
order?: AutoDeliveryOrder | null
task?: AutoDeliveryTask | null
trigger?: string
}
type AutoDeliveryStatus = 'success' | 'failed' | 'skipped'
type FetchResponseLike = {
status: number
text: () => Promise<string>
}
type FetchLike = (
input: string | URL,
init?: RequestInit,
) => Promise<FetchResponseLike>
type AgisoAutoDeliveryConfirmInput = {
shopId?: string
platformOrderId?: string
requestId?: string
}
type AgisoAutoDeliveryConfirmResult = {
shipped: boolean
orderStatus: number
shipTime: number
reason: string
}
type AutoDeliveryMessageResult = {
sent: boolean
skipped?: boolean
reason?: string
[key: string]: unknown
}
type EnsureAgisoXianyuAutoDeliveryDeps = {
listTasksByOrderId?: (orderId: number | string) => Promise<AutoDeliveryTask[]>
fetch?: FetchLike
confirmAgisoXianyuAutoDeliveryShipped?: (
input: AgisoAutoDeliveryConfirmInput,
) => Promise<AgisoAutoDeliveryConfirmResult>
updateTask?: (
taskId: number | string,
patch: { context_json: string; updated_at: string },
) => Promise<AutoDeliveryTask | null>
createTaskEvent?: (
taskId: number | string,
eventType: string,
payload?: unknown,
createdAt?: string,
) => Promise<unknown>
nowIso?: () => string
ensureAgisoXianyuAutoDeliveryMessageDeliveredForTask?: (
input: { order?: AutoDeliveryOrder | null; task?: AutoDeliveryTask | null },
) => Promise<AutoDeliveryMessageResult>
}
type PersistAgisoAutoDeliveryResultInput = {
status: AutoDeliveryStatus
trigger?: string
reason?: string
order?: AutoDeliveryOrder | null
responseStatus?: number
response?: unknown
errorMessage?: string
detail?: JsonObject
}
type AgisoAutoDeliveryConfig = {
enabled: boolean
endpoint: string
apiVersion: string
appSecret: string
accessToken: string
}
/** @param {EnsureAgisoXianyuAutoDeliveryInput} input */
export async function ensureAgisoXianyuAutoDeliveryForDeliveredTask({ export async function ensureAgisoXianyuAutoDeliveryForDeliveredTask({
order, order,
task, task,
trigger = 'task_delivered', trigger = 'task_delivered',
} = {}) { }: EnsureAgisoXianyuAutoDeliveryInput = {}) {
return ensureAgisoXianyuAutoDeliveryForDeliveredTaskWithDeps({ order, task, trigger }) return ensureAgisoXianyuAutoDeliveryForDeliveredTaskWithDeps({ order, task, trigger })
} }
@@ -35,29 +135,30 @@ export async function ensureAgisoXianyuAutoDeliveryForDeliveredTaskWithDeps({
order, order,
task, task,
trigger = 'task_delivered', trigger = 'task_delivered',
} = {}, deps = {}) { }: EnsureAgisoXianyuAutoDeliveryInput = {}, deps: EnsureAgisoXianyuAutoDeliveryDeps = {}) {
const listOrderTasks = deps.listTasksByOrderId || listTasksByOrderId const listOrderTasks = deps.listTasksByOrderId || listTasksByOrderId
const sendRequest = deps.fetch || fetch const sendRequest = deps.fetch || (fetch as FetchLike)
const confirmShipped = deps.confirmAgisoXianyuAutoDeliveryShipped || confirmAgisoXianyuAutoDeliveryShipped const confirmShipped = deps.confirmAgisoXianyuAutoDeliveryShipped || confirmAgisoXianyuAutoDeliveryShipped
if (!isAgisoXianyuOrder(order) || !task?.id) { if (!isAgisoXianyuOrder(order) || !task?.id) {
return { sent: false, skipped: true, reason: 'not_supported', task } return { sent: false, skipped: true, reason: 'not_supported', task }
} }
if (String(task.delivery_status || '').trim() !== 'delivered') { const currentTask = task as AutoDeliveryTaskWithId
return { sent: false, skipped: true, reason: 'task_not_delivered', task } if (String(currentTask.delivery_status || '').trim() !== 'delivered') {
return { sent: false, skipped: true, reason: 'task_not_delivered', task: currentTask }
} }
const orderTasks = await listOrderTasks(order.id) const orderTasks = await listOrderTasks(order.id)
if (hasAgisoAutoDeliverySucceeded(orderTasks)) { if (hasAgisoAutoDeliverySucceeded(orderTasks)) {
return { sent: false, skipped: true, reason: 'already_sent', task } return { sent: false, skipped: true, reason: 'already_sent', task: currentTask }
} }
if (!isOrderReadyForAgisoAutoDelivery(orderTasks)) { if (!isOrderReadyForAgisoAutoDelivery(orderTasks)) {
logWebhook('[agiso/xianyu/auto-delivery]', '跳过自动发货:订单下仍有任务未完成交付', { logWebhook('[agiso/xianyu/auto-delivery]', '跳过自动发货:订单下仍有任务未完成交付', {
trigger, trigger,
orderId: order.id, orderId: order.id,
taskId: task.id, taskId: currentTask.id,
platformOrderId: order.platform_order_id, platformOrderId: order.platform_order_id,
taskStatuses: orderTasks.map((current) => ({ taskStatuses: orderTasks.map((current) => ({
taskId: current.id, taskId: current.id,
@@ -66,12 +167,12 @@ export async function ensureAgisoXianyuAutoDeliveryForDeliveredTaskWithDeps({
})), })),
}) })
return { sent: false, skipped: true, reason: 'waiting_other_tasks', task } return { sent: false, skipped: true, reason: 'waiting_other_tasks', task: currentTask }
} }
const config = resolveAgisoXianyuAutoDeliveryConfig(order) const config = resolveAgisoXianyuAutoDeliveryConfig(order)
if (!config.enabled) { if (!config.enabled) {
return persistAgisoAutoDeliveryResult(task, { return persistAgisoAutoDeliveryResult(currentTask, {
status: 'skipped', status: 'skipped',
trigger, trigger,
reason: 'auto_delivery_disabled', reason: 'auto_delivery_disabled',
@@ -80,7 +181,7 @@ export async function ensureAgisoXianyuAutoDeliveryForDeliveredTaskWithDeps({
} }
if (!config.endpoint || !config.accessToken || !config.appSecret) { if (!config.endpoint || !config.accessToken || !config.appSecret) {
return persistAgisoAutoDeliveryResult(task, { return persistAgisoAutoDeliveryResult(currentTask, {
status: 'skipped', status: 'skipped',
trigger, trigger,
reason: 'missing_config', reason: 'missing_config',
@@ -105,7 +206,7 @@ export async function ensureAgisoXianyuAutoDeliveryForDeliveredTaskWithDeps({
logWebhook('[agiso/xianyu/auto-delivery]', '开始执行 Agiso 咸鱼自动发货', { logWebhook('[agiso/xianyu/auto-delivery]', '开始执行 Agiso 咸鱼自动发货', {
trigger, trigger,
orderId: order.id, orderId: order.id,
taskId: task.id, taskId: currentTask.id,
shopId: order.shop_id, shopId: order.shop_id,
platformOrderId: order.platform_order_id, platformOrderId: order.platform_order_id,
endpoint: config.endpoint, endpoint: config.endpoint,
@@ -118,13 +219,13 @@ export async function ensureAgisoXianyuAutoDeliveryForDeliveredTaskWithDeps({
body: new URLSearchParams(requestBody).toString(), body: new URLSearchParams(requestBody).toString(),
}) })
const rawText = await response.text() const rawText = await response.text()
const parsed = parseJsonObject(rawText) const parsed = parseJsonObject(rawText) as JsonObject
const success = isAgisoAutoDeliverySuccess(response.status, parsed) const success = isAgisoAutoDeliverySuccess(response.status, parsed)
if (success) { if (success) {
const requestId = String(parsed?.RequestId || '').trim() const requestId = String(parsed?.RequestId || '').trim()
// 发货接口返回成功后,再查一次 Order/Detail 确认订单真的进入已发货状态 meow~ // 发货接口返回成功后,再查一次 Order/Detail 确认订单真的进入已发货状态
const confirmResult = await confirmShipped({ const confirmResult = await confirmShipped({
shopId: order.shop_id, shopId: order.shop_id,
platformOrderId: order.platform_order_id, platformOrderId: order.platform_order_id,
@@ -135,7 +236,7 @@ export async function ensureAgisoXianyuAutoDeliveryForDeliveredTaskWithDeps({
logWebhook('[agiso/xianyu/auto-delivery]', 'Agiso 咸鱼自动发货接口返回成功,但订单状态未确认进入已发货', { logWebhook('[agiso/xianyu/auto-delivery]', 'Agiso 咸鱼自动发货接口返回成功,但订单状态未确认进入已发货', {
trigger, trigger,
orderId: order.id, orderId: order.id,
taskId: task.id, taskId: currentTask.id,
shopId: order.shop_id, shopId: order.shop_id,
platformOrderId: order.platform_order_id, platformOrderId: order.platform_order_id,
responseStatus: response.status, responseStatus: response.status,
@@ -145,7 +246,7 @@ export async function ensureAgisoXianyuAutoDeliveryForDeliveredTaskWithDeps({
confirmReason: confirmResult.reason, confirmReason: confirmResult.reason,
}, { level: 'warn' }) }, { level: 'warn' })
return persistAgisoAutoDeliveryResult(task, { return persistAgisoAutoDeliveryResult(currentTask, {
status: 'failed', status: 'failed',
trigger, trigger,
reason: 'delivery_not_confirmed', reason: 'delivery_not_confirmed',
@@ -164,7 +265,7 @@ export async function ensureAgisoXianyuAutoDeliveryForDeliveredTaskWithDeps({
logWebhook('[agiso/xianyu/auto-delivery]', 'Agiso 咸鱼自动发货成功,订单已确认进入已发货状态', { logWebhook('[agiso/xianyu/auto-delivery]', 'Agiso 咸鱼自动发货成功,订单已确认进入已发货状态', {
trigger, trigger,
orderId: order.id, orderId: order.id,
taskId: task.id, taskId: currentTask.id,
shopId: order.shop_id, shopId: order.shop_id,
platformOrderId: order.platform_order_id, platformOrderId: order.platform_order_id,
responseStatus: response.status, responseStatus: response.status,
@@ -173,7 +274,7 @@ export async function ensureAgisoXianyuAutoDeliveryForDeliveredTaskWithDeps({
confirmShipTime: confirmResult.shipTime, confirmShipTime: confirmResult.shipTime,
}) })
const result = await persistAgisoAutoDeliveryResult(task, { const result = await persistAgisoAutoDeliveryResult(currentTask, {
status: 'success', status: 'success',
trigger, trigger,
reason: '', reason: '',
@@ -187,8 +288,8 @@ export async function ensureAgisoXianyuAutoDeliveryForDeliveredTaskWithDeps({
}, },
}, deps) }, deps)
// 发货确认成功后,发送自定义消息通知 meow~ // 发货确认成功后,发送自定义消息通知
await sendAutoDeliveryMessage({ order, task }, deps) await sendAutoDeliveryMessage({ order, task: currentTask }, deps)
return result return result
} }
@@ -197,7 +298,7 @@ export async function ensureAgisoXianyuAutoDeliveryForDeliveredTaskWithDeps({
logWebhook('[agiso/xianyu/auto-delivery]', 'Agiso 咸鱼自动发货失败', { logWebhook('[agiso/xianyu/auto-delivery]', 'Agiso 咸鱼自动发货失败', {
trigger, trigger,
orderId: order.id, orderId: order.id,
taskId: task.id, taskId: currentTask.id,
shopId: order.shop_id, shopId: order.shop_id,
platformOrderId: order.platform_order_id, platformOrderId: order.platform_order_id,
responseStatus: response.status, responseStatus: response.status,
@@ -205,7 +306,7 @@ export async function ensureAgisoXianyuAutoDeliveryForDeliveredTaskWithDeps({
response: parsed, response: parsed,
}, { level: 'warn' }) }, { level: 'warn' })
return persistAgisoAutoDeliveryResult(task, { return persistAgisoAutoDeliveryResult(currentTask, {
status: 'failed', status: 'failed',
trigger, trigger,
reason: 'request_failed', reason: 'request_failed',
@@ -219,13 +320,13 @@ export async function ensureAgisoXianyuAutoDeliveryForDeliveredTaskWithDeps({
logWebhook('[agiso/xianyu/auto-delivery]', 'Agiso 咸鱼自动发货异常', { logWebhook('[agiso/xianyu/auto-delivery]', 'Agiso 咸鱼自动发货异常', {
trigger, trigger,
orderId: order.id, orderId: order.id,
taskId: task.id, taskId: currentTask.id,
shopId: order.shop_id, shopId: order.shop_id,
platformOrderId: order.platform_order_id, platformOrderId: order.platform_order_id,
errorMessage, errorMessage,
}, { level: 'warn' }) }, { level: 'warn' })
return persistAgisoAutoDeliveryResult(task, { return persistAgisoAutoDeliveryResult(currentTask, {
status: 'failed', status: 'failed',
trigger, trigger,
reason: 'request_error', reason: 'request_error',
@@ -237,21 +338,22 @@ export async function ensureAgisoXianyuAutoDeliveryForDeliveredTaskWithDeps({
} }
} }
export function hasAgisoAutoDeliverySucceeded(tasks = []) { export function hasAgisoAutoDeliverySucceeded(tasks: AutoDeliveryTask[] = []): boolean {
return (Array.isArray(tasks) ? tasks : []).some((task) => { return (Array.isArray(tasks) ? tasks : []).some((task) => {
const context = parseTaskContext(task) const context = parseTaskContext(task)
return String(context?.agisoAutoDelivery?.status || '').trim() === 'success' const autoDelivery = isPlainObject(context.agisoAutoDelivery) ? context.agisoAutoDelivery : {}
return String(autoDelivery.status || '').trim() === 'success'
}) })
} }
export function isOrderReadyForAgisoAutoDelivery(tasks = []) { export function isOrderReadyForAgisoAutoDelivery(tasks: AutoDeliveryTask[] = []): boolean {
const normalizedTasks = Array.isArray(tasks) ? tasks.filter(Boolean) : [] const normalizedTasks = Array.isArray(tasks) ? tasks.filter(Boolean) : []
return normalizedTasks.length > 0 return normalizedTasks.length > 0
&& normalizedTasks.every((task) => String(task.delivery_status || '').trim() === 'delivered') && normalizedTasks.every((task) => String(task.delivery_status || '').trim() === 'delivered')
} }
function resolveAgisoXianyuAutoDeliveryConfig(order) { function resolveAgisoXianyuAutoDeliveryConfig(order: AutoDeliveryOrder): AgisoAutoDeliveryConfig {
const baseConfig = runtimeConfig.platforms?.agiso?.autoDelivery || {} const baseConfig = runtimeConfig.platforms.agiso.autoDelivery
const shopConfig = getAgisoShopConfig(String(order?.shop_id || '').trim()) || {} const shopConfig = getAgisoShopConfig(String(order?.shop_id || '').trim()) || {}
return { return {
@@ -263,7 +365,10 @@ function resolveAgisoXianyuAutoDeliveryConfig(order) {
} }
} }
function buildRequestHeaders({ accessToken, apiVersion }) { function buildRequestHeaders({
accessToken,
apiVersion,
}: { accessToken: string; apiVersion: string }): Record<string, string> {
return { return {
Authorization: `Bearer ${accessToken}`, Authorization: `Bearer ${accessToken}`,
ApiVersion: String(apiVersion || '1').trim() || '1', ApiVersion: String(apiVersion || '1').trim() || '1',
@@ -271,8 +376,11 @@ function buildRequestHeaders({ accessToken, apiVersion }) {
} }
} }
function buildRequestBody({ platformOrderId, appSecret }) { function buildRequestBody({
const payload = { platformOrderId,
appSecret,
}: { platformOrderId: string; appSecret: string }): Record<string, string> {
const payload: Record<string, string> = {
tid: String(platformOrderId || '').trim(), tid: String(platformOrderId || '').trim(),
timestamp: String(Math.floor(Date.now() / 1000)), timestamp: String(Math.floor(Date.now() / 1000)),
} }
@@ -281,7 +389,7 @@ function buildRequestBody({ platformOrderId, appSecret }) {
return payload return payload
} }
function generateSign(params, appSecret) { function generateSign(params: Record<string, string>, appSecret: string): string {
const sortedEntries = Object.entries(params).sort(([left], [right]) => left.localeCompare(right)) const sortedEntries = Object.entries(params).sort(([left], [right]) => left.localeCompare(right))
let raw = String(appSecret || '').trim() let raw = String(appSecret || '').trim()
@@ -294,7 +402,7 @@ function generateSign(params, appSecret) {
return crypto.createHash('md5').update(raw, 'utf8').digest('hex').toLowerCase() return crypto.createHash('md5').update(raw, 'utf8').digest('hex').toLowerCase()
} }
export function isAgisoAutoDeliverySuccess(statusCode, payload) { export function isAgisoAutoDeliverySuccess(statusCode: number, payload: unknown): boolean {
if (statusCode < 200 || statusCode >= 300) { if (statusCode < 200 || statusCode >= 300) {
return false return false
} }
@@ -303,24 +411,35 @@ export function isAgisoAutoDeliverySuccess(statusCode, payload) {
return true return true
} }
if (payload.IsSuccess === true) { const normalizedPayload = payload as JsonObject
if (normalizedPayload.IsSuccess === true) {
return true return true
} }
if (Number(payload.Error_Code) === 0) { if (Number(normalizedPayload.Error_Code) === 0) {
return true return true
} }
if (Number(payload.code) === 0) { if (Number(normalizedPayload.code) === 0) {
return true return true
} }
return false return false
} }
export function resolveAgisoAutoDeliveryErrorMessage(payload, rawText, statusCode) { export function resolveAgisoAutoDeliveryErrorMessage(
payload: unknown,
rawText: string,
statusCode: number,
): string {
if (payload && typeof payload === 'object') { if (payload && typeof payload === 'object') {
for (const value of [payload.Error_Msg, payload.msg, payload.message, payload.error]) { const normalizedPayload = payload as JsonObject
for (const value of [
normalizedPayload.Error_Msg,
normalizedPayload.msg,
normalizedPayload.message,
normalizedPayload.error,
]) {
const normalized = String(value || '').trim() const normalized = String(value || '').trim()
if (normalized) { if (normalized) {
return normalized return normalized
@@ -332,11 +451,11 @@ export function resolveAgisoAutoDeliveryErrorMessage(payload, rawText, statusCod
return text || `Agiso 咸鱼自动发货失败,HTTP ${statusCode}` return text || `Agiso 咸鱼自动发货失败,HTTP ${statusCode}`
} }
export function resolveAgisoAutoDeliveryEndpoint(value) { export function resolveAgisoAutoDeliveryEndpoint(value: unknown): string {
return AGISO_DUMMY_SEND_ENDPOINT return AGISO_DUMMY_SEND_ENDPOINT
} }
async function persistAgisoAutoDeliveryResult(task, { async function persistAgisoAutoDeliveryResult(task: AutoDeliveryTaskWithId, {
status, status,
trigger, trigger,
reason, reason,
@@ -345,7 +464,7 @@ async function persistAgisoAutoDeliveryResult(task, {
response = {}, response = {},
errorMessage = '', errorMessage = '',
detail = {}, detail = {},
} = {}, deps = {}) { }: PersistAgisoAutoDeliveryResultInput, deps: EnsureAgisoXianyuAutoDeliveryDeps = {}) {
const getNowIso = deps.nowIso || nowIso const getNowIso = deps.nowIso || nowIso
const patchTask = deps.updateTask || updateTask const patchTask = deps.updateTask || updateTask
const insertTaskEvent = deps.createTaskEvent || createTaskEvent const insertTaskEvent = deps.createTaskEvent || createTaskEvent
@@ -392,7 +511,7 @@ async function persistAgisoAutoDeliveryResult(task, {
} }
} }
function parseTaskContext(task) { function parseTaskContext(task: AutoDeliveryTask | null | undefined): JsonObject {
const value = task?.context_json const value = task?.context_json
if (!value) { if (!value) {
@@ -410,14 +529,14 @@ function parseTaskContext(task) {
} }
} }
function isAgisoXianyuOrder(order) { function isAgisoXianyuOrder(order: AutoDeliveryOrder | null | undefined): order is SupportedAgisoOrder {
return String(order?.provider || '').trim() === 'agiso' return String(order?.provider || '').trim() === 'agiso'
&& String(order?.platform || '').trim() === 'xianyu' && String(order?.platform || '').trim() === 'xianyu'
&& Boolean(String(order?.platform_order_id || '').trim()) && Boolean(String(order?.platform_order_id || '').trim())
&& Number(order?.id || 0) > 0 && Number(order?.id || 0) > 0
} }
function normalizeBooleanLike(value, fallbackValue) { function normalizeBooleanLike(value: unknown, fallbackValue: boolean): boolean {
if (typeof value === 'boolean') { if (typeof value === 'boolean') {
return value return value
} }
@@ -438,15 +557,19 @@ function normalizeBooleanLike(value, fallbackValue) {
return fallbackValue return fallbackValue
} }
function isPlainObject(value) { function isPlainObject(value: unknown): value is JsonObject {
return Object.prototype.toString.call(value) === '[object Object]' return Object.prototype.toString.call(value) === '[object Object]'
} }
/** /**
* Order/Detail meow~ * Order/Detail
* ship_time > 0 orderStatus >= 3 * ship_time > 0 orderStatus >= 3
*/ */
async function confirmAgisoXianyuAutoDeliveryShipped({ shopId = '', platformOrderId = '', requestId = '' } = {}) { async function confirmAgisoXianyuAutoDeliveryShipped({
shopId = '',
platformOrderId = '',
requestId = '',
}: AgisoAutoDeliveryConfirmInput = {}): Promise<AgisoAutoDeliveryConfirmResult> {
try { try {
const detailResult = await queryAgisoXianyuOrderDetail({ shopId, platformOrderId, requestId }) const detailResult = await queryAgisoXianyuOrderDetail({ shopId, platformOrderId, requestId })
@@ -484,9 +607,12 @@ async function confirmAgisoXianyuAutoDeliveryShipped({ shopId = '', platformOrde
} }
/** /**
* meow~ *
*/ */
async function sendAutoDeliveryMessage({ order, task } = {}, deps = {}) { async function sendAutoDeliveryMessage(
{ order, task }: { order?: AutoDeliveryOrder | null; task?: AutoDeliveryTask | null } = {},
deps: EnsureAgisoXianyuAutoDeliveryDeps = {},
): Promise<AutoDeliveryMessageResult> {
try { try {
const deliverMessage = deps.ensureAgisoXianyuAutoDeliveryMessageDeliveredForTask const deliverMessage = deps.ensureAgisoXianyuAutoDeliveryMessageDeliveredForTask
|| ensureAgisoXianyuAutoDeliveryMessageDeliveredForTask || ensureAgisoXianyuAutoDeliveryMessageDeliveredForTask
+1 -1
View File
@@ -20,6 +20,6 @@
"data", "data",
"src/**/*.test.js", "src/**/*.test.js",
"src/services/session/**", "src/services/session/**",
"src/services/platforms/agiso/**" "src/services/platforms/agiso/**/*.js"
] ]
} }
@@ -320,6 +320,15 @@
- `npm run typecheck` - `npm run typecheck`
- `npm run build` - `npm run build`
- `npm test` 共 131 个用例通过 - `npm test` 共 131 个用例通过
47. Agiso 自动发货服务迁移到 `.ts`
- `src/services/platforms/agiso/xianyu/auto-delivery-service.ts`
48. 自动发货订单 / 任务形态、依赖注入、HTTP 响应、发货确认结果、上下文落库 payload 已显式类型化
49. `tsconfig.json` 已将 Agiso 新增 `.ts` 文件纳入 `typecheck`,旧 Agiso `.js` 文件继续暂时排除
50. Docker 内验证通过:
- `src/services/platforms/agiso/xianyu/auto-delivery-service.test.js` 共 9 个用例通过
- `npm run typecheck`
- `npm run build`
- `npm test` 共 131 个用例通过
## 下一步建议 ## 下一步建议