优化了自动发货和发货后的消息
This commit is contained in:
@@ -53,7 +53,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
autoDelivery: {
|
autoDelivery: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
endpoint: 'https://gw-api.agiso.com/aldsIdle/Alds/AldsSend',
|
endpoint: 'https://gw-api.agiso.com/aldsIdle/Order/DummySend',
|
||||||
apiVersion: '1',
|
apiVersion: '1',
|
||||||
aldsType: 1,
|
aldsType: 1,
|
||||||
ignoreAldsLog: false,
|
ignoreAldsLog: false,
|
||||||
@@ -72,6 +72,7 @@ module.exports = {
|
|||||||
accessToken: '',
|
accessToken: '',
|
||||||
appSecret: '',
|
appSecret: '',
|
||||||
messageTemplate: '您的订单 {platformOrderId} 已创建领取链接,请在 {expiredAt} 前完成领取:{claimUrl}',
|
messageTemplate: '您的订单 {platformOrderId} 已创建领取链接,请在 {expiredAt} 前完成领取:{claimUrl}',
|
||||||
|
autoDeliveryMessageTemplate: '您的订单 {platformOrderId} 已完成自动发货,请注意查收。',
|
||||||
shops: {},
|
shops: {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -270,6 +270,11 @@ function applyEnvOverrides(baseConfig) {
|
|||||||
nextConfig.platforms.agiso.messaging.messageTemplate = agisoMessageTemplate
|
nextConfig.platforms.agiso.messaging.messageTemplate = agisoMessageTemplate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const agisoAutoDeliveryMessageTemplate = String(process.env.AGISO_AUTO_DELIVERY_MESSAGE_TEMPLATE || '').trim()
|
||||||
|
if (agisoAutoDeliveryMessageTemplate) {
|
||||||
|
nextConfig.platforms.agiso.messaging.autoDeliveryMessageTemplate = agisoAutoDeliveryMessageTemplate
|
||||||
|
}
|
||||||
|
|
||||||
const agisoShops = parseJsonObject(process.env.AGISO_SHOPS_JSON)
|
const agisoShops = parseJsonObject(process.env.AGISO_SHOPS_JSON)
|
||||||
if (agisoShops) {
|
if (agisoShops) {
|
||||||
nextConfig.platforms.agiso.messaging.shops = normalizeAgisoMessagingShops(agisoShops)
|
nextConfig.platforms.agiso.messaging.shops = normalizeAgisoMessagingShops(agisoShops)
|
||||||
@@ -402,7 +407,7 @@ function normalizeAgisoMessagingShops(rawValue) {
|
|||||||
next.enabled = enabled
|
next.enabled = enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const key of ['shopName', 'accessToken', 'messageTemplate', 'appSecret', 'apiVersion', 'sendMessageEndpoint']) {
|
for (const key of ['shopName', 'accessToken', 'messageTemplate', 'autoDeliveryMessageTemplate', 'appSecret', 'apiVersion', 'sendMessageEndpoint']) {
|
||||||
const value = String(config[key] || '').trim()
|
const value = String(config[key] || '').trim()
|
||||||
if (value) {
|
if (value) {
|
||||||
next[key] = value
|
next[key] = value
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ export async function getAdminAgisoShopConfigs() {
|
|||||||
accessTokenMasked: maskSecret(config.accessToken),
|
accessTokenMasked: maskSecret(config.accessToken),
|
||||||
enabled: typeof config.enabled === 'boolean' ? config.enabled : null,
|
enabled: typeof config.enabled === 'boolean' ? config.enabled : null,
|
||||||
messageTemplate: String(config.messageTemplate || '').trim(),
|
messageTemplate: String(config.messageTemplate || '').trim(),
|
||||||
|
autoDeliveryMessageTemplate: String(config.autoDeliveryMessageTemplate || '').trim(),
|
||||||
appSecretConfigured: Boolean(String(config.appSecret || '').trim()),
|
appSecretConfigured: Boolean(String(config.appSecret || '').trim()),
|
||||||
apiVersion: String(config.apiVersion || '').trim(),
|
apiVersion: String(config.apiVersion || '').trim(),
|
||||||
sendMessageEndpoint: String(config.sendMessageEndpoint || '').trim(),
|
sendMessageEndpoint: String(config.sendMessageEndpoint || '').trim(),
|
||||||
@@ -70,6 +71,7 @@ export async function getAdminAgisoShopConfigs() {
|
|||||||
/** @param {AdminAgisoShopConfigSaveInput} [payload] */
|
/** @param {AdminAgisoShopConfigSaveInput} [payload] */
|
||||||
export function updateAdminAgisoShopConfigs(payload = /** @type {AdminAgisoShopConfigSaveInput} */ ({})) {
|
export function updateAdminAgisoShopConfigs(payload = /** @type {AdminAgisoShopConfigSaveInput} */ ({})) {
|
||||||
const rawItems = Array.isArray(payload.shops) ? payload.shops : []
|
const rawItems = Array.isArray(payload.shops) ? payload.shops : []
|
||||||
|
const currentMap = getAgisoShopConfigMap()
|
||||||
const nextMap = {}
|
const nextMap = {}
|
||||||
|
|
||||||
for (const item of rawItems) {
|
for (const item of rawItems) {
|
||||||
@@ -78,22 +80,33 @@ export function updateAdminAgisoShopConfigs(payload = /** @type {AdminAgisoShopC
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
const next = {}
|
const current = currentMap[shopId] || {}
|
||||||
|
const next = { ...current }
|
||||||
const shopName = String(item?.shopName || '').trim()
|
const shopName = String(item?.shopName || '').trim()
|
||||||
const accessToken = String(item?.accessToken || '').trim()
|
const accessToken = String(item?.accessToken || '').trim()
|
||||||
const messageTemplate = String(item?.messageTemplate || '').trim()
|
const messageTemplate = String(item?.messageTemplate || '').trim()
|
||||||
|
const autoDeliveryMessageTemplate = String(item?.autoDeliveryMessageTemplate || '').trim()
|
||||||
const appSecret = String(item?.appSecret || '').trim()
|
const appSecret = String(item?.appSecret || '').trim()
|
||||||
const apiVersion = String(item?.apiVersion || '').trim()
|
const apiVersion = String(item?.apiVersion || '').trim()
|
||||||
const sendMessageEndpoint = String(item?.sendMessageEndpoint || '').trim()
|
const sendMessageEndpoint = String(item?.sendMessageEndpoint || '').trim()
|
||||||
|
|
||||||
if (shopName) {
|
if (shopName) {
|
||||||
next.shopName = shopName
|
next.shopName = shopName
|
||||||
|
} else {
|
||||||
|
delete next.shopName
|
||||||
}
|
}
|
||||||
if (accessToken) {
|
if (accessToken) {
|
||||||
next.accessToken = accessToken
|
next.accessToken = accessToken
|
||||||
}
|
}
|
||||||
if (messageTemplate) {
|
if (messageTemplate) {
|
||||||
next.messageTemplate = messageTemplate
|
next.messageTemplate = messageTemplate
|
||||||
|
} else if (typeof item?.messageTemplate === 'string') {
|
||||||
|
delete next.messageTemplate
|
||||||
|
}
|
||||||
|
if (autoDeliveryMessageTemplate) {
|
||||||
|
next.autoDeliveryMessageTemplate = autoDeliveryMessageTemplate
|
||||||
|
} else if (typeof item?.autoDeliveryMessageTemplate === 'string') {
|
||||||
|
delete next.autoDeliveryMessageTemplate
|
||||||
}
|
}
|
||||||
if (appSecret) {
|
if (appSecret) {
|
||||||
next.appSecret = appSecret
|
next.appSecret = appSecret
|
||||||
@@ -128,6 +141,7 @@ export function updateAdminAgisoShopConfigs(payload = /** @type {AdminAgisoShopC
|
|||||||
accessTokenMasked: maskSecret(config.accessToken),
|
accessTokenMasked: maskSecret(config.accessToken),
|
||||||
enabled: typeof config.enabled === 'boolean' ? config.enabled : null,
|
enabled: typeof config.enabled === 'boolean' ? config.enabled : null,
|
||||||
messageTemplate: String(config.messageTemplate || '').trim(),
|
messageTemplate: String(config.messageTemplate || '').trim(),
|
||||||
|
autoDeliveryMessageTemplate: String(config.autoDeliveryMessageTemplate || '').trim(),
|
||||||
appSecretConfigured: Boolean(String(config.appSecret || '').trim()),
|
appSecretConfigured: Boolean(String(config.appSecret || '').trim()),
|
||||||
apiVersion: String(config.apiVersion || '').trim(),
|
apiVersion: String(config.apiVersion || '').trim(),
|
||||||
sendMessageEndpoint: String(config.sendMessageEndpoint || '').trim(),
|
sendMessageEndpoint: String(config.sendMessageEndpoint || '').trim(),
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ function normalizeAgisoShopConfigMap(rawValue) {
|
|||||||
next.enabled = enabled
|
next.enabled = enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const key of ['shopName', 'accessToken', 'messageTemplate', 'appSecret', 'apiVersion', 'sendMessageEndpoint', 'tradeDetailEndpoint']) {
|
for (const key of ['shopName', 'accessToken', 'messageTemplate', 'autoDeliveryMessageTemplate', 'appSecret', 'apiVersion', 'sendMessageEndpoint', 'tradeDetailEndpoint']) {
|
||||||
const value = String(config[key] || '').trim()
|
const value = String(config[key] || '').trim()
|
||||||
if (value) {
|
if (value) {
|
||||||
next[key] = value
|
next[key] = value
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import { runtimeConfig } from '../../../../config/runtime.js'
|
|||||||
import { listTasksByOrderId, updateTask } from '../../../../repositories/task-repo.js'
|
import { listTasksByOrderId, updateTask } from '../../../../repositories/task-repo.js'
|
||||||
import { createTaskEvent } from '../../../../repositories/task-event-repo.js'
|
import { createTaskEvent } from '../../../../repositories/task-event-repo.js'
|
||||||
import { getAgisoShopConfig } from '../shop-config-service.js'
|
import { getAgisoShopConfig } from '../shop-config-service.js'
|
||||||
|
import { queryAgisoXianyuOrderDetail } from './order-detail-service.js'
|
||||||
|
import { ensureAgisoXianyuAutoDeliveryMessageDeliveredForTask } from './message-service.js'
|
||||||
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'
|
||||||
@@ -113,7 +115,46 @@ export async function ensureAgisoXianyuAutoDeliveryForDeliveredTask({
|
|||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
const requestId = String(parsed?.RequestId || '').trim()
|
const requestId = String(parsed?.RequestId || '').trim()
|
||||||
logWebhook('[agiso/xianyu/auto-delivery]', 'Agiso 咸鱼自动发货成功', {
|
|
||||||
|
// DummySend 接口返回成功后,再查一次 Order/Detail 确认订单真的进入已发货状态 meow~
|
||||||
|
const confirmResult = await confirmAgisoXianyuAutoDeliveryShipped({
|
||||||
|
shopId: order.shop_id,
|
||||||
|
platformOrderId: order.platform_order_id,
|
||||||
|
requestId,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!confirmResult.shipped) {
|
||||||
|
logWebhook('[agiso/xianyu/auto-delivery]', 'Agiso 咸鱼自动发货接口返回成功,但订单状态未确认进入已发货', {
|
||||||
|
trigger,
|
||||||
|
orderId: order.id,
|
||||||
|
taskId: task.id,
|
||||||
|
shopId: order.shop_id,
|
||||||
|
platformOrderId: order.platform_order_id,
|
||||||
|
responseStatus: response.status,
|
||||||
|
requestId,
|
||||||
|
confirmOrderStatus: confirmResult.orderStatus,
|
||||||
|
confirmShipTime: confirmResult.shipTime,
|
||||||
|
confirmReason: confirmResult.reason,
|
||||||
|
}, { level: 'warn' })
|
||||||
|
|
||||||
|
return persistAgisoAutoDeliveryResult(task, {
|
||||||
|
status: 'failed',
|
||||||
|
trigger,
|
||||||
|
reason: 'delivery_not_confirmed',
|
||||||
|
order,
|
||||||
|
responseStatus: response.status,
|
||||||
|
response: parsed,
|
||||||
|
errorMessage: `接口返回成功,但订单状态未确认进入已发货 (orderStatus=${confirmResult.orderStatus}, shipTime=${confirmResult.shipTime})`,
|
||||||
|
detail: {
|
||||||
|
requestId,
|
||||||
|
aldsType: config.aldsType,
|
||||||
|
confirmOrderStatus: confirmResult.orderStatus,
|
||||||
|
confirmShipTime: confirmResult.shipTime,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
logWebhook('[agiso/xianyu/auto-delivery]', 'Agiso 咸鱼自动发货成功,订单已确认进入已发货状态', {
|
||||||
trigger,
|
trigger,
|
||||||
orderId: order.id,
|
orderId: order.id,
|
||||||
taskId: task.id,
|
taskId: task.id,
|
||||||
@@ -121,9 +162,11 @@ export async function ensureAgisoXianyuAutoDeliveryForDeliveredTask({
|
|||||||
platformOrderId: order.platform_order_id,
|
platformOrderId: order.platform_order_id,
|
||||||
responseStatus: response.status,
|
responseStatus: response.status,
|
||||||
requestId,
|
requestId,
|
||||||
|
confirmOrderStatus: confirmResult.orderStatus,
|
||||||
|
confirmShipTime: confirmResult.shipTime,
|
||||||
})
|
})
|
||||||
|
|
||||||
return persistAgisoAutoDeliveryResult(task, {
|
const result = await persistAgisoAutoDeliveryResult(task, {
|
||||||
status: 'success',
|
status: 'success',
|
||||||
trigger,
|
trigger,
|
||||||
reason: '',
|
reason: '',
|
||||||
@@ -133,8 +176,15 @@ export async function ensureAgisoXianyuAutoDeliveryForDeliveredTask({
|
|||||||
detail: {
|
detail: {
|
||||||
requestId,
|
requestId,
|
||||||
aldsType: config.aldsType,
|
aldsType: config.aldsType,
|
||||||
|
confirmOrderStatus: confirmResult.orderStatus,
|
||||||
|
confirmShipTime: confirmResult.shipTime,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 发货确认成功后,发送自定义消息通知 meow~
|
||||||
|
await sendAutoDeliveryMessage({ order, task })
|
||||||
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
const errorMessage = resolveAgisoAutoDeliveryErrorMessage(parsed, rawText, response.status)
|
const errorMessage = resolveAgisoAutoDeliveryErrorMessage(parsed, rawText, response.status)
|
||||||
@@ -411,3 +461,72 @@ function normalizeBooleanLike(value, fallbackValue) {
|
|||||||
function isPlainObject(value) {
|
function isPlainObject(value) {
|
||||||
return Object.prototype.toString.call(value) === '[object Object]'
|
return Object.prototype.toString.call(value) === '[object Object]'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DummySend 返回成功后,再查一次 Order/Detail 确认订单是否真的进入已发货状态 meow~
|
||||||
|
* 只有 ship_time > 0 或 orderStatus >= 3 才算发货确认通过
|
||||||
|
*/
|
||||||
|
async function confirmAgisoXianyuAutoDeliveryShipped({ shopId = '', platformOrderId = '', requestId = '' } = {}) {
|
||||||
|
try {
|
||||||
|
const detailResult = await queryAgisoXianyuOrderDetail({ shopId, platformOrderId, requestId })
|
||||||
|
|
||||||
|
if (detailResult.success && detailResult.shipped) {
|
||||||
|
return {
|
||||||
|
shipped: true,
|
||||||
|
orderStatus: detailResult.orderStatus,
|
||||||
|
shipTime: detailResult.shipTime,
|
||||||
|
reason: '',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
shipped: false,
|
||||||
|
orderStatus: detailResult.orderStatus || 0,
|
||||||
|
shipTime: detailResult.shipTime || 0,
|
||||||
|
reason: detailResult.success ? 'order_not_shipped' : detailResult.reason,
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
const message = error instanceof Error ? error.message : String(error || '订单发货状态确认失败')
|
||||||
|
logWebhook('[agiso/xianyu/auto-delivery]', '自动发货确认查询异常', {
|
||||||
|
requestId,
|
||||||
|
shopId,
|
||||||
|
platformOrderId,
|
||||||
|
errorMessage: message,
|
||||||
|
}, { level: 'warn' })
|
||||||
|
|
||||||
|
return {
|
||||||
|
shipped: false,
|
||||||
|
orderStatus: 0,
|
||||||
|
shipTime: 0,
|
||||||
|
reason: 'confirm_query_failed',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动发货成功后发送消息通知 meow~
|
||||||
|
*/
|
||||||
|
async function sendAutoDeliveryMessage({ order, task } = {}) {
|
||||||
|
try {
|
||||||
|
const result = await ensureAgisoXianyuAutoDeliveryMessageDeliveredForTask({ order, task })
|
||||||
|
logWebhook('[agiso/xianyu/auto-delivery]', '自动发货消息通知结果', {
|
||||||
|
orderId: order?.id,
|
||||||
|
taskId: task?.id,
|
||||||
|
platformOrderId: order?.platform_order_id,
|
||||||
|
sent: result.sent,
|
||||||
|
skipped: result.skipped,
|
||||||
|
reason: result.reason,
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
} catch (error) {
|
||||||
|
const message = error instanceof Error ? error.message : String(error || '发送自动发货消息通知失败')
|
||||||
|
logWebhook('[agiso/xianyu/auto-delivery]', '自动发货消息通知异常', {
|
||||||
|
orderId: order?.id,
|
||||||
|
taskId: task?.id,
|
||||||
|
platformOrderId: order?.platform_order_id,
|
||||||
|
errorMessage: message,
|
||||||
|
}, { level: 'warn' })
|
||||||
|
|
||||||
|
return { sent: false, skipped: true, reason: 'message_send_error' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,9 +10,53 @@ import {
|
|||||||
import { nowIso } from '../../../../utils/time.js'
|
import { nowIso } from '../../../../utils/time.js'
|
||||||
|
|
||||||
const AGISO_XIANYU_MESSAGE_CHANNEL = 'agiso_im'
|
const AGISO_XIANYU_MESSAGE_CHANNEL = 'agiso_im'
|
||||||
|
const AGISO_XIANYU_AUTO_DELIVERY_MESSAGE_CHANNEL = 'agiso_im_auto_delivery'
|
||||||
|
|
||||||
export async function ensureAgisoXianyuClaimMessageDeliveredForTask({ order, task, claimUrl, expiredAt }) {
|
export async function ensureAgisoXianyuClaimMessageDeliveredForTask({ order, task, claimUrl, expiredAt }) {
|
||||||
if (!order || !task || !claimUrl) {
|
const config = resolveAgisoXianyuMessagingConfig(order)
|
||||||
|
const messageContent = renderAgisoClaimMessage({
|
||||||
|
order,
|
||||||
|
task,
|
||||||
|
claimUrl,
|
||||||
|
expiredAt,
|
||||||
|
template: config.messageTemplate,
|
||||||
|
shopName: config.shopName,
|
||||||
|
})
|
||||||
|
|
||||||
|
return deliverAgisoXianyuMessageForTask({
|
||||||
|
order,
|
||||||
|
task,
|
||||||
|
channel: AGISO_XIANYU_MESSAGE_CHANNEL,
|
||||||
|
messageContent,
|
||||||
|
claimUrl,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function ensureAgisoXianyuAutoDeliveryMessageDeliveredForTask({ order, task } = {}) {
|
||||||
|
const config = resolveAgisoXianyuMessagingConfig(order)
|
||||||
|
const messageContent = renderAgisoAutoDeliveryMessage({
|
||||||
|
order,
|
||||||
|
task,
|
||||||
|
template: config.autoDeliveryMessageTemplate,
|
||||||
|
shopName: config.shopName,
|
||||||
|
})
|
||||||
|
|
||||||
|
return deliverAgisoXianyuMessageForTask({
|
||||||
|
order,
|
||||||
|
task,
|
||||||
|
channel: AGISO_XIANYU_AUTO_DELIVERY_MESSAGE_CHANNEL,
|
||||||
|
messageContent,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deliverAgisoXianyuMessageForTask({
|
||||||
|
order,
|
||||||
|
task,
|
||||||
|
channel,
|
||||||
|
messageContent,
|
||||||
|
claimUrl = '',
|
||||||
|
} = {}) {
|
||||||
|
if (!order || !task || !messageContent) {
|
||||||
return { sent: false, skipped: true, reason: 'missing_message_context' }
|
return { sent: false, skipped: true, reason: 'missing_message_context' }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,19 +72,11 @@ export async function ensureAgisoXianyuClaimMessageDeliveredForTask({ order, tas
|
|||||||
return { sent: false, skipped: true, reason: 'missing_endpoint_or_access_token_or_app_secret' }
|
return { sent: false, skipped: true, reason: 'missing_endpoint_or_access_token_or_app_secret' }
|
||||||
}
|
}
|
||||||
|
|
||||||
const successful = await findLatestSuccessfulMessageDeliveryByTask(task.id, AGISO_XIANYU_MESSAGE_CHANNEL)
|
const successful = await findLatestSuccessfulMessageDeliveryByTask(task.id, channel)
|
||||||
if (successful) {
|
if (successful) {
|
||||||
return { sent: false, skipped: true, reason: 'already_sent', deliveryId: successful.id }
|
return { sent: false, skipped: true, reason: 'already_sent', deliveryId: successful.id }
|
||||||
}
|
}
|
||||||
|
|
||||||
const messageContent = renderAgisoClaimMessage({
|
|
||||||
order,
|
|
||||||
task,
|
|
||||||
claimUrl,
|
|
||||||
expiredAt,
|
|
||||||
template: config.messageTemplate,
|
|
||||||
shopName: config.shopName,
|
|
||||||
})
|
|
||||||
const url = buildRequestUrl(endpoint)
|
const url = buildRequestUrl(endpoint)
|
||||||
const requestBody = buildRequestBody({
|
const requestBody = buildRequestBody({
|
||||||
tid: String(order.platform_order_id || ''),
|
tid: String(order.platform_order_id || ''),
|
||||||
@@ -57,7 +93,7 @@ export async function ensureAgisoXianyuClaimMessageDeliveredForTask({ order, tas
|
|||||||
platform: String(order.platform || '').trim() || 'unknown',
|
platform: String(order.platform || '').trim() || 'unknown',
|
||||||
shopId: String(order.shop_id || '').trim(),
|
shopId: String(order.shop_id || '').trim(),
|
||||||
shopName: String(order.shop_name || '').trim(),
|
shopName: String(order.shop_name || '').trim(),
|
||||||
channel: AGISO_XIANYU_MESSAGE_CHANNEL,
|
channel,
|
||||||
orderId: order.id,
|
orderId: order.id,
|
||||||
taskId: task.id,
|
taskId: task.id,
|
||||||
platformOrderId: order.platform_order_id,
|
platformOrderId: order.platform_order_id,
|
||||||
@@ -85,11 +121,12 @@ export async function ensureAgisoXianyuClaimMessageDeliveredForTask({ order, tas
|
|||||||
const rawText = await response.text()
|
const rawText = await response.text()
|
||||||
const parsed = safeParseJson(rawText)
|
const parsed = safeParseJson(rawText)
|
||||||
const success = isAgisoSendSuccess(response.status, parsed)
|
const success = isAgisoSendSuccess(response.status, parsed)
|
||||||
|
const errorMessage = success ? '' : resolveAgisoErrorMessage(parsed, rawText, response.status)
|
||||||
const updated = await updateMessageDelivery(delivery.id, {
|
const updated = await updateMessageDelivery(delivery.id, {
|
||||||
status: success ? 'success' : 'failed',
|
status: success ? 'success' : 'failed',
|
||||||
response_status: response.status,
|
response_status: response.status,
|
||||||
response_json: JSON.stringify(parsed ?? { rawText }),
|
response_json: JSON.stringify(parsed ?? { rawText }),
|
||||||
error_message: success ? '' : resolveAgisoErrorMessage(parsed, rawText, response.status),
|
error_message: errorMessage,
|
||||||
sent_at: success ? nowIso() : null,
|
sent_at: success ? nowIso() : null,
|
||||||
updated_at: nowIso(),
|
updated_at: nowIso(),
|
||||||
})
|
})
|
||||||
@@ -100,7 +137,7 @@ export async function ensureAgisoXianyuClaimMessageDeliveredForTask({ order, tas
|
|||||||
deliveryId: updated?.id || delivery.id,
|
deliveryId: updated?.id || delivery.id,
|
||||||
responseStatus: response.status,
|
responseStatus: response.status,
|
||||||
response: parsed ?? { rawText },
|
response: parsed ?? { rawText },
|
||||||
errorMessage: success ? '' : resolveAgisoErrorMessage(parsed, rawText, response.status),
|
errorMessage,
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const message = error instanceof Error ? error.message : String(error || '发送消息失败')
|
const message = error instanceof Error ? error.message : String(error || '发送消息失败')
|
||||||
@@ -174,15 +211,48 @@ function generateSign(params, appSecret) {
|
|||||||
|
|
||||||
function renderAgisoClaimMessage({ order, task, claimUrl, expiredAt, template, shopName = '' }) {
|
function renderAgisoClaimMessage({ order, task, claimUrl, expiredAt, template, shopName = '' }) {
|
||||||
const source = String(template || '').trim() || '您的订单 {platformOrderId} 已创建领取链接,请在 {expiredAt} 前完成领取:{claimUrl}'
|
const source = String(template || '').trim() || '您的订单 {platformOrderId} 已创建领取链接,请在 {expiredAt} 前完成领取:{claimUrl}'
|
||||||
const resolvedShopName = String(shopName || order.shop_name || order.shop_id || '').trim()
|
|
||||||
|
|
||||||
return source
|
return renderAgisoMessageTemplate({
|
||||||
.replaceAll('{platformOrderId}', String(order.platform_order_id || ''))
|
order,
|
||||||
.replaceAll('{taskNo}', String(task.task_no || ''))
|
task,
|
||||||
|
template: source,
|
||||||
|
shopName,
|
||||||
|
claimUrl,
|
||||||
|
expiredAt: String(expiredAt || '尽快'),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function renderAgisoAutoDeliveryMessage({ order, task, template, shopName = '' }) {
|
||||||
|
const source = String(template || '').trim() || '您的订单 {platformOrderId} 已完成自动发货,请注意查收。'
|
||||||
|
|
||||||
|
return renderAgisoMessageTemplate({
|
||||||
|
order,
|
||||||
|
task,
|
||||||
|
template: source,
|
||||||
|
shopName,
|
||||||
|
resultMessage: '自动发货成功',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderAgisoMessageTemplate({
|
||||||
|
order,
|
||||||
|
task,
|
||||||
|
template,
|
||||||
|
shopName = '',
|
||||||
|
claimUrl = '',
|
||||||
|
expiredAt = '',
|
||||||
|
resultMessage = '',
|
||||||
|
} = {}) {
|
||||||
|
const resolvedShopName = String(shopName || order?.shop_name || order?.shop_id || '').trim()
|
||||||
|
|
||||||
|
return String(template || '')
|
||||||
|
.replaceAll('{platformOrderId}', String(order?.platform_order_id || ''))
|
||||||
|
.replaceAll('{taskNo}', String(task?.task_no || ''))
|
||||||
.replaceAll('{shopName}', resolvedShopName)
|
.replaceAll('{shopName}', resolvedShopName)
|
||||||
.replaceAll('{shopId}', String(order.shop_id || ''))
|
.replaceAll('{shopId}', String(order?.shop_id || ''))
|
||||||
.replaceAll('{claimUrl}', claimUrl)
|
.replaceAll('{claimUrl}', String(claimUrl || ''))
|
||||||
.replaceAll('{expiredAt}', String(expiredAt || '尽快'))
|
.replaceAll('{expiredAt}', String(expiredAt || ''))
|
||||||
|
.replaceAll('{resultMessage}', String(resultMessage || ''))
|
||||||
}
|
}
|
||||||
|
|
||||||
function isAgisoSendSuccess(statusCode, payload) {
|
function isAgisoSendSuccess(statusCode, payload) {
|
||||||
|
|||||||
@@ -14,23 +14,68 @@ export async function enrichAgisoXianyuTradeOrder(parsed, { requestId = '' } = {
|
|||||||
return { parsed, enriched: false, reason: 'not_needed' }
|
return { parsed, enriched: false, reason: 'not_needed' }
|
||||||
}
|
}
|
||||||
|
|
||||||
const config = resolveAgisoXianyuTradeDetailConfig(parsed.shopId)
|
const detailResult = await queryAgisoXianyuOrderDetail({
|
||||||
|
shopId: parsed.shopId,
|
||||||
|
platformOrderId: parsed.platformOrderId,
|
||||||
|
requestId,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!detailResult.success) {
|
||||||
|
return {
|
||||||
|
parsed,
|
||||||
|
enriched: false,
|
||||||
|
reason: detailResult.reason,
|
||||||
|
errorMessage: detailResult.errorMessage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const detailPayload = detailResult.detailPayload
|
||||||
|
if (detailResult.totalAmountFen <= 0) {
|
||||||
|
return {
|
||||||
|
parsed: mergeEnrichedTrade(parsed, detailPayload, { keepOriginalAmount: true }),
|
||||||
|
enriched: false,
|
||||||
|
reason: 'amount_still_missing',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const merged = mergeEnrichedTrade(parsed, detailPayload)
|
||||||
|
logWebhook('[agiso/xianyu/order-detail]', 'Agiso 咸鱼订单详情补查成功', {
|
||||||
|
requestId,
|
||||||
|
platform: parsed.platform,
|
||||||
|
shopId: parsed.shopId,
|
||||||
|
platformOrderId: parsed.platformOrderId,
|
||||||
|
totalAmountFen: merged.totalAmount,
|
||||||
|
paidAt: merged.paidAt,
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
parsed: merged,
|
||||||
|
enriched: true,
|
||||||
|
totalAmountFen: merged.totalAmount,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function queryAgisoXianyuOrderDetail({ shopId = '', platformOrderId = '', requestId = '' } = {}) {
|
||||||
|
const normalizedShopId = String(shopId || '').trim()
|
||||||
|
const normalizedPlatformOrderId = String(platformOrderId || '').trim()
|
||||||
|
const config = resolveAgisoXianyuTradeDetailConfig(normalizedShopId)
|
||||||
|
|
||||||
if (!config.endpoint || !config.accessToken || !config.appSecret) {
|
if (!config.endpoint || !config.accessToken || !config.appSecret) {
|
||||||
logWebhook('[agiso/xianyu/order-detail]', '跳过 Agiso 咸鱼订单详情补查:缺少必要配置', {
|
logWebhook('[agiso/xianyu/order-detail]', '跳过 Agiso 咸鱼订单详情补查:缺少必要配置', {
|
||||||
requestId,
|
requestId,
|
||||||
platform: parsed.platform,
|
platform: 'xianyu',
|
||||||
shopId: parsed.shopId,
|
shopId: normalizedShopId,
|
||||||
platformOrderId: parsed.platformOrderId,
|
platformOrderId: normalizedPlatformOrderId,
|
||||||
hasEndpoint: Boolean(config.endpoint),
|
hasEndpoint: Boolean(config.endpoint),
|
||||||
hasAccessToken: Boolean(config.accessToken),
|
hasAccessToken: Boolean(config.accessToken),
|
||||||
hasAppSecret: Boolean(config.appSecret),
|
hasAppSecret: Boolean(config.appSecret),
|
||||||
}, { level: 'warn' })
|
}, { level: 'warn' })
|
||||||
|
|
||||||
return { parsed, enriched: false, reason: 'missing_config' }
|
return createFailedDetailResult('missing_config')
|
||||||
}
|
}
|
||||||
|
|
||||||
const requestBody = buildRequestBody({
|
const requestBody = buildRequestBody({
|
||||||
platformOrderId: parsed.platformOrderId,
|
platformOrderId: normalizedPlatformOrderId,
|
||||||
appSecret: config.appSecret,
|
appSecret: config.appSecret,
|
||||||
})
|
})
|
||||||
const requestHeaders = buildRequestHeaders({
|
const requestHeaders = buildRequestHeaders({
|
||||||
@@ -40,9 +85,9 @@ export async function enrichAgisoXianyuTradeOrder(parsed, { requestId = '' } = {
|
|||||||
|
|
||||||
logWebhook('[agiso/xianyu/order-detail]', '开始补查 Agiso 咸鱼订单详情', {
|
logWebhook('[agiso/xianyu/order-detail]', '开始补查 Agiso 咸鱼订单详情', {
|
||||||
requestId,
|
requestId,
|
||||||
platform: parsed.platform,
|
platform: 'xianyu',
|
||||||
shopId: parsed.shopId,
|
shopId: normalizedShopId,
|
||||||
platformOrderId: parsed.platformOrderId,
|
platformOrderId: normalizedPlatformOrderId,
|
||||||
endpoint: config.endpoint,
|
endpoint: config.endpoint,
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -55,92 +100,103 @@ export async function enrichAgisoXianyuTradeOrder(parsed, { requestId = '' } = {
|
|||||||
const rawText = await response.text()
|
const rawText = await response.text()
|
||||||
const payload = parseJsonObject(rawText, { preserveLargeIntegers: true })
|
const payload = parseJsonObject(rawText, { preserveLargeIntegers: true })
|
||||||
const detailPayload = extractAgisoDetailPayload(payload)
|
const detailPayload = extractAgisoDetailPayload(payload)
|
||||||
const detailAmountFen = resolveTotalAmountFen(detailPayload)
|
const delivery = resolveAgisoXianyuOrderDeliveryState(detailPayload)
|
||||||
|
const totalAmountFen = resolveTotalAmountFen(detailPayload)
|
||||||
|
|
||||||
if (response.status < 200 || response.status >= 300) {
|
if (response.status < 200 || response.status >= 300) {
|
||||||
const message = resolveAgisoDetailErrorMessage(payload, rawText, response.status)
|
const message = resolveAgisoDetailErrorMessage(payload, rawText, response.status)
|
||||||
logWebhook('[agiso/xianyu/order-detail]', 'Agiso 咸鱼订单详情补查失败', {
|
logWebhook('[agiso/xianyu/order-detail]', 'Agiso 咸鱼订单详情补查失败', {
|
||||||
requestId,
|
requestId,
|
||||||
platform: parsed.platform,
|
platform: 'xianyu',
|
||||||
shopId: parsed.shopId,
|
shopId: normalizedShopId,
|
||||||
platformOrderId: parsed.platformOrderId,
|
platformOrderId: normalizedPlatformOrderId,
|
||||||
responseStatus: response.status,
|
responseStatus: response.status,
|
||||||
errorMessage: message,
|
errorMessage: message,
|
||||||
}, { level: 'warn' })
|
}, { level: 'warn' })
|
||||||
|
|
||||||
return { parsed, enriched: false, reason: 'http_error', errorMessage: message }
|
return createFailedDetailResult('http_error', {
|
||||||
|
responseStatus: response.status,
|
||||||
|
payload,
|
||||||
|
detailPayload,
|
||||||
|
errorMessage: message,
|
||||||
|
totalAmountFen,
|
||||||
|
delivery,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isAgisoDetailSuccess(payload)) {
|
if (!isAgisoDetailSuccess(payload)) {
|
||||||
const message = resolveAgisoDetailErrorMessage(payload, rawText, response.status)
|
const message = resolveAgisoDetailErrorMessage(payload, rawText, response.status)
|
||||||
logWebhook('[agiso/xianyu/order-detail]', 'Agiso 咸鱼订单详情补查返回业务失败', {
|
logWebhook('[agiso/xianyu/order-detail]', 'Agiso 咸鱼订单详情补查返回业务失败', {
|
||||||
requestId,
|
requestId,
|
||||||
platform: parsed.platform,
|
platform: 'xianyu',
|
||||||
shopId: parsed.shopId,
|
shopId: normalizedShopId,
|
||||||
platformOrderId: parsed.platformOrderId,
|
platformOrderId: normalizedPlatformOrderId,
|
||||||
responseStatus: response.status,
|
responseStatus: response.status,
|
||||||
errorMessage: message,
|
errorMessage: message,
|
||||||
response: payload,
|
response: payload,
|
||||||
}, { level: 'warn' })
|
}, { level: 'warn' })
|
||||||
|
|
||||||
return { parsed, enriched: false, reason: 'business_error', errorMessage: message }
|
return createFailedDetailResult('business_error', {
|
||||||
|
responseStatus: response.status,
|
||||||
|
payload,
|
||||||
|
detailPayload,
|
||||||
|
errorMessage: message,
|
||||||
|
totalAmountFen,
|
||||||
|
delivery,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!detailPayload || typeof detailPayload !== 'object' || Object.keys(detailPayload).length === 0) {
|
if (!isPlainObject(detailPayload) || Object.keys(detailPayload).length === 0) {
|
||||||
logWebhook('[agiso/xianyu/order-detail]', 'Agiso 咸鱼订单详情补查未返回可用订单体', {
|
logWebhook('[agiso/xianyu/order-detail]', 'Agiso 咸鱼订单详情补查未返回可用订单体', {
|
||||||
requestId,
|
requestId,
|
||||||
platform: parsed.platform,
|
platform: 'xianyu',
|
||||||
shopId: parsed.shopId,
|
shopId: normalizedShopId,
|
||||||
platformOrderId: parsed.platformOrderId,
|
platformOrderId: normalizedPlatformOrderId,
|
||||||
responseStatus: response.status,
|
responseStatus: response.status,
|
||||||
}, { level: 'warn' })
|
}, { level: 'warn' })
|
||||||
|
|
||||||
return { parsed, enriched: false, reason: 'empty_detail_payload' }
|
return createFailedDetailResult('empty_detail_payload', {
|
||||||
|
responseStatus: response.status,
|
||||||
|
payload,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (detailAmountFen <= 0) {
|
if (totalAmountFen <= 0) {
|
||||||
logWebhook('[agiso/xianyu/order-detail]', 'Agiso 咸鱼订单详情已返回,但仍未解析出金额', {
|
logWebhook('[agiso/xianyu/order-detail]', 'Agiso 咸鱼订单详情已返回,但仍未解析出金额', {
|
||||||
requestId,
|
requestId,
|
||||||
platform: parsed.platform,
|
platform: 'xianyu',
|
||||||
shopId: parsed.shopId,
|
shopId: normalizedShopId,
|
||||||
platformOrderId: parsed.platformOrderId,
|
platformOrderId: normalizedPlatformOrderId,
|
||||||
responseStatus: response.status,
|
responseStatus: response.status,
|
||||||
detailKeys: Object.keys(detailPayload),
|
detailKeys: Object.keys(detailPayload),
|
||||||
}, { level: 'warn' })
|
}, { level: 'warn' })
|
||||||
|
|
||||||
return {
|
|
||||||
parsed: mergeEnrichedTrade(parsed, detailPayload, { keepOriginalAmount: true }),
|
|
||||||
enriched: false,
|
|
||||||
reason: 'amount_still_missing',
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const merged = mergeEnrichedTrade(parsed, detailPayload)
|
|
||||||
logWebhook('[agiso/xianyu/order-detail]', 'Agiso 咸鱼订单详情补查成功', {
|
|
||||||
requestId,
|
|
||||||
platform: parsed.platform,
|
|
||||||
shopId: parsed.shopId,
|
|
||||||
platformOrderId: parsed.platformOrderId,
|
|
||||||
totalAmountFen: merged.totalAmount,
|
|
||||||
paidAt: merged.paidAt,
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
parsed: merged,
|
success: true,
|
||||||
enriched: true,
|
reason: '',
|
||||||
totalAmountFen: merged.totalAmount,
|
errorMessage: '',
|
||||||
|
responseStatus: response.status,
|
||||||
|
payload: isPlainObject(payload) ? payload : {},
|
||||||
|
detailPayload,
|
||||||
|
totalAmountFen,
|
||||||
|
shipped: delivery.shipped,
|
||||||
|
shipTime: delivery.shipTime,
|
||||||
|
orderStatus: delivery.orderStatus,
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const message = error instanceof Error ? error.message : String(error || 'Agiso 咸鱼订单详情补查失败')
|
const message = error instanceof Error ? error.message : String(error || 'Agiso 咸鱼订单详情补查失败')
|
||||||
logWebhook('[agiso/xianyu/order-detail]', 'Agiso 咸鱼订单详情补查异常', {
|
logWebhook('[agiso/xianyu/order-detail]', 'Agiso 咸鱼订单详情补查异常', {
|
||||||
requestId,
|
requestId,
|
||||||
platform: parsed.platform,
|
platform: 'xianyu',
|
||||||
shopId: parsed.shopId,
|
shopId: normalizedShopId,
|
||||||
platformOrderId: parsed.platformOrderId,
|
platformOrderId: normalizedPlatformOrderId,
|
||||||
errorMessage: message,
|
errorMessage: message,
|
||||||
}, { level: 'warn' })
|
}, { level: 'warn' })
|
||||||
|
|
||||||
return { parsed, enriched: false, reason: 'request_failed', errorMessage: message }
|
return createFailedDetailResult('request_failed', {
|
||||||
|
errorMessage: message,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,6 +266,29 @@ function extractAgisoDetailPayload(payload) {
|
|||||||
return payload
|
return payload
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function resolveAgisoXianyuOrderDeliveryState(payload) {
|
||||||
|
const shipTime = normalizeTimestampValue(pickFirstNonEmpty([
|
||||||
|
payload?.ship_time,
|
||||||
|
payload?.shipTime,
|
||||||
|
payload?.ShipTime,
|
||||||
|
payload?.delivery_time,
|
||||||
|
payload?.deliveryTime,
|
||||||
|
]))
|
||||||
|
const orderStatus = normalizeInteger(
|
||||||
|
pickFirstNonEmpty([
|
||||||
|
payload?.order_status,
|
||||||
|
payload?.orderStatus,
|
||||||
|
payload?.status,
|
||||||
|
]),
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
shipped: shipTime > 0 || orderStatus >= 3,
|
||||||
|
shipTime,
|
||||||
|
orderStatus,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function resolveTotalAmountFen(payload) {
|
function resolveTotalAmountFen(payload) {
|
||||||
const fenAmount = normalizeFenInteger(pickFirstNonEmpty([
|
const fenAmount = normalizeFenInteger(pickFirstNonEmpty([
|
||||||
payload.payment,
|
payload.payment,
|
||||||
@@ -559,6 +638,33 @@ function normalizeFenInteger(value) {
|
|||||||
return Number.isFinite(parsed) && parsed > 0 ? Math.round(parsed) : 0
|
return Number.isFinite(parsed) && parsed > 0 ? Math.round(parsed) : 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeTimestampValue(value) {
|
||||||
|
const parsed = Number(value)
|
||||||
|
return Number.isFinite(parsed) && parsed > 0 ? Math.round(parsed) : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function createFailedDetailResult(reason, {
|
||||||
|
responseStatus = 0,
|
||||||
|
payload = {},
|
||||||
|
detailPayload = {},
|
||||||
|
errorMessage = '',
|
||||||
|
totalAmountFen = 0,
|
||||||
|
delivery = { shipped: false, shipTime: 0, orderStatus: 0 },
|
||||||
|
} = {}) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
reason: String(reason || '').trim(),
|
||||||
|
errorMessage: String(errorMessage || '').trim(),
|
||||||
|
responseStatus: Number(responseStatus || 0),
|
||||||
|
payload: isPlainObject(payload) ? payload : {},
|
||||||
|
detailPayload: isPlainObject(detailPayload) ? detailPayload : {},
|
||||||
|
totalAmountFen: Number(totalAmountFen || 0),
|
||||||
|
shipped: Boolean(delivery?.shipped),
|
||||||
|
shipTime: Number(delivery?.shipTime || 0),
|
||||||
|
orderStatus: Number(delivery?.orderStatus || 0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function pickFirstNonEmpty(values) {
|
function pickFirstNonEmpty(values) {
|
||||||
for (const value of values) {
|
for (const value of values) {
|
||||||
const normalized = String(value || '').trim()
|
const normalized = String(value || '').trim()
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ export {}
|
|||||||
* accessToken?: string
|
* accessToken?: string
|
||||||
* enabled?: boolean | null
|
* enabled?: boolean | null
|
||||||
* messageTemplate?: string
|
* messageTemplate?: string
|
||||||
|
* autoDeliveryMessageTemplate?: string
|
||||||
* appSecret?: string
|
* appSecret?: string
|
||||||
* apiVersion?: string
|
* apiVersion?: string
|
||||||
* sendMessageEndpoint?: string
|
* sendMessageEndpoint?: string
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ export {}
|
|||||||
* accessTokenMasked: string
|
* accessTokenMasked: string
|
||||||
* enabled: boolean | null
|
* enabled: boolean | null
|
||||||
* messageTemplate: string
|
* messageTemplate: string
|
||||||
|
* autoDeliveryMessageTemplate: string
|
||||||
* appSecretConfigured: boolean
|
* appSecretConfigured: boolean
|
||||||
* apiVersion: string
|
* apiVersion: string
|
||||||
* sendMessageEndpoint: string
|
* sendMessageEndpoint: string
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ export {}
|
|||||||
* shopName?: string
|
* shopName?: string
|
||||||
* accessToken?: string
|
* accessToken?: string
|
||||||
* messageTemplate?: string
|
* messageTemplate?: string
|
||||||
|
* autoDeliveryMessageTemplate?: string
|
||||||
* appSecret?: string
|
* appSecret?: string
|
||||||
* apiVersion?: string
|
* apiVersion?: string
|
||||||
* sendMessageEndpoint?: string
|
* sendMessageEndpoint?: string
|
||||||
@@ -91,6 +92,7 @@ export {}
|
|||||||
* apiVersion: string
|
* apiVersion: string
|
||||||
* sendMessageEndpoint: string
|
* sendMessageEndpoint: string
|
||||||
* messageTemplate: string
|
* messageTemplate: string
|
||||||
|
* autoDeliveryMessageTemplate: string
|
||||||
* shops: AgisoMessagingShopsConfig
|
* shops: AgisoMessagingShopsConfig
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ export interface AdminAgisoShopConfigItem {
|
|||||||
accessTokenMasked: string
|
accessTokenMasked: string
|
||||||
enabled: boolean | null
|
enabled: boolean | null
|
||||||
messageTemplate: string
|
messageTemplate: string
|
||||||
|
autoDeliveryMessageTemplate: string
|
||||||
appSecretConfigured: boolean
|
appSecretConfigured: boolean
|
||||||
apiVersion: string
|
apiVersion: string
|
||||||
sendMessageEndpoint: string
|
sendMessageEndpoint: string
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ type EditableShop = {
|
|||||||
accessToken: string
|
accessToken: string
|
||||||
enabled: boolean
|
enabled: boolean
|
||||||
messageTemplate: string
|
messageTemplate: string
|
||||||
|
autoDeliveryMessageTemplate: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
@@ -31,6 +32,7 @@ function createEmptyShop(): EditableShop {
|
|||||||
accessToken: '',
|
accessToken: '',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
messageTemplate: '',
|
messageTemplate: '',
|
||||||
|
autoDeliveryMessageTemplate: '',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,6 +44,7 @@ function mapEditableShop(item: AdminAgisoShopConfigItem): EditableShop {
|
|||||||
accessToken: item.accessToken,
|
accessToken: item.accessToken,
|
||||||
enabled: item.enabled !== false,
|
enabled: item.enabled !== false,
|
||||||
messageTemplate: item.messageTemplate,
|
messageTemplate: item.messageTemplate,
|
||||||
|
autoDeliveryMessageTemplate: item.autoDeliveryMessageTemplate,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,6 +85,7 @@ function importObservedShop(item: AdminAgisoObservedShopItem) {
|
|||||||
accessToken: '',
|
accessToken: '',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
messageTemplate: '',
|
messageTemplate: '',
|
||||||
|
autoDeliveryMessageTemplate: '',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,6 +97,7 @@ async function saveConfigs() {
|
|||||||
accessToken: item.accessToken.trim(),
|
accessToken: item.accessToken.trim(),
|
||||||
enabled: item.enabled,
|
enabled: item.enabled,
|
||||||
messageTemplate: item.messageTemplate.trim(),
|
messageTemplate: item.messageTemplate.trim(),
|
||||||
|
autoDeliveryMessageTemplate: item.autoDeliveryMessageTemplate.trim(),
|
||||||
}))
|
}))
|
||||||
.filter((item) => item.shopId && item.accessToken)
|
.filter((item) => item.shopId && item.accessToken)
|
||||||
|
|
||||||
@@ -174,13 +179,22 @@ onMounted(loadConfigs)
|
|||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label class="field-block field-wide">
|
<label class="field-block field-wide">
|
||||||
<span>消息模板</span>
|
<span>领取链接消息模板</span>
|
||||||
<textarea
|
<textarea
|
||||||
v-model="shop.messageTemplate"
|
v-model="shop.messageTemplate"
|
||||||
class="text-area"
|
class="text-area"
|
||||||
placeholder="留空则沿用全局 AGISO_MESSAGE_TEMPLATE"
|
placeholder="留空则沿用全局 AGISO_MESSAGE_TEMPLATE"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
<label class="field-block field-wide">
|
||||||
|
<span>自动发货消息模板</span>
|
||||||
|
<textarea
|
||||||
|
v-model="shop.autoDeliveryMessageTemplate"
|
||||||
|
class="text-area"
|
||||||
|
placeholder="留空则沿用全局 AGISO_AUTO_DELIVERY_MESSAGE_TEMPLATE"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="shop-actions">
|
<div class="shop-actions">
|
||||||
|
|||||||
@@ -224,6 +224,8 @@ function formatAutoDeliveryReason(value: string) {
|
|||||||
return 'Agiso 接口返回失败'
|
return 'Agiso 接口返回失败'
|
||||||
case 'request_error':
|
case 'request_error':
|
||||||
return '请求 Agiso 接口时发生异常'
|
return '请求 Agiso 接口时发生异常'
|
||||||
|
case 'delivery_not_confirmed':
|
||||||
|
return '接口返回成功,但订单状态未确认进入已发货'
|
||||||
case 'task_not_delivered':
|
case 'task_not_delivered':
|
||||||
return '当前任务尚未进入已交付状态'
|
return '当前任务尚未进入已交付状态'
|
||||||
case 'not_supported':
|
case 'not_supported':
|
||||||
|
|||||||
Reference in New Issue
Block a user