优化了订单展示

This commit is contained in:
yml
2026-04-09 02:03:39 +08:00
parent e4ab1f559e
commit 98cc0c16fc
6 changed files with 321 additions and 29 deletions
+10
View File
@@ -7,6 +7,7 @@ import adminRouter from './routes/admin.js'
import claimsRouter from './routes/claims.js'
import webhooksRouter from './routes/webhooks.js'
import { ensureAdminUsersBootstrapped } from './services/admin/admin-auth-service.js'
import { repairAgisoOrderData } from './services/order/order-repair-service.js'
import { closeLocalOcrWorker, warmupLocalOcrWorker } from './services/session/ocr.js'
import { closeAllTencentBrowserSessions, warmupTencentBrowser } from './services/session/session.js'
import { logError, logInfo, logWarn } from './utils/logger.js'
@@ -17,6 +18,7 @@ const port = Number(runtimeConfig.server.port || 3000)
runDatabaseMigrations()
await ensureAdminUsersBootstrapped()
await repairHistoricalOrders()
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*')
@@ -89,6 +91,14 @@ async function bootstrapOcr() {
}
}
async function repairHistoricalOrders() {
try {
await repairAgisoOrderData()
} catch (error) {
logWarn('[startup]', `历史 Agiso 咸鱼订单修复跳过: ${formatStartupError(error)}`)
}
}
function formatStartupError(error) {
if (error instanceof Error && error.message) {
return error.message.split('\n')[0].trim()
@@ -924,7 +924,9 @@ function mapAdminTaskListItem(task) {
function mapAdminOrderListItem(item) {
const tasks = listTasksByOrderId(item.id)
const orderItems = listOrderItemsByOrderId(item.id)
const bindingSummary = buildOrderBindingSummary(tasks)
const itemSummary = summarizeOrderItems(orderItems)
return {
orderId: item.id,
@@ -935,12 +937,18 @@ function mapAdminOrderListItem(item) {
platformOrderId: item.platform_order_id,
orderStatus: item.order_status,
payStatus: item.pay_status,
buyerId: item.buyer_id || '',
buyerName: item.buyer_name,
receiverContact: item.receiver_contact || '',
totalAmount: formatFenToAmount(item.total_amount),
totalAmountFen: normalizeFen(item.total_amount),
currency: item.currency,
paidAt: item.paid_at,
createdAt: item.created_at,
updatedAt: item.updated_at,
itemCount: orderItems.length,
totalQuantity: orderItems.reduce((sum, orderItem) => sum + Math.max(1, Number(orderItem.quantity || 1)), 0),
itemSummary,
taskCount: Number(item.task_count || tasks.length || 0),
systemBindingStatus: bindingSummary.systemBindingStatus,
userBindingStatus: bindingSummary.userBindingStatus,
@@ -949,6 +957,23 @@ function mapAdminOrderListItem(item) {
}
}
function summarizeOrderItems(items) {
const normalizedItems = Array.isArray(items) ? items : []
if (normalizedItems.length === 0) {
return ''
}
const [firstItem] = normalizedItems
const firstLabel = String(firstItem?.sku_name || firstItem?.sku_code || '').trim()
if (normalizedItems.length === 1) {
return firstLabel
}
return `${firstLabel}${normalizedItems.length}`
}
function buildOrderBindingSummary(tasks) {
const normalizedTasks = Array.isArray(tasks) ? tasks : []
const totalTaskCount = normalizedTasks.length
@@ -2,6 +2,7 @@ import crypto from 'node:crypto'
import { runtimeConfig } from '../../config/runtime.js'
import { createWebhookEvent, updateWebhookEvent } from '../../repositories/webhook-event-repo.js'
import { enrichAgisoXianyuTradeOrder } from '../platforms/agiso/xianyu/order-detail-service.js'
import { upsertOrderFromWebhook } from './order-service.js'
import { createHttpError } from '../../utils/http.js'
import { logWebhook } from '../../utils/logger.js'
@@ -87,7 +88,11 @@ async function executeAgisoTradeWebhook(parsed, webhookEventId, { requestId = ''
})
}
const result = await upsertOrderFromWebhook(parsed)
const enriched = await enrichTradeBeforeUpsert(parsed, {
requestId,
webhookEventId,
})
const result = await upsertOrderFromWebhook(enriched.parsed)
updateWebhookEvent(webhookEventId, {
processed: true,
process_error: '',
@@ -103,22 +108,28 @@ async function executeAgisoTradeWebhook(parsed, webhookEventId, { requestId = ''
shopName: parsed.shopName,
eventKey: parsed.eventKey,
eventType: parsed.eventType,
platformOrderId: parsed.platformOrderId,
platformOrderId: enriched.parsed.platformOrderId,
orderId: result.order.id,
enriched: enriched.enriched,
enrichReason: enriched.reason || '',
totalAmountFen: Number(enriched.parsed.totalAmount || 0),
taskCount: result.tasks.length,
messageDeliveryCount: Array.isArray(result.messageDeliveries) ? result.messageDeliveries.length : 0,
})
return {
accepted: true,
provider: parsed.provider,
platform: parsed.platform,
shopId: parsed.shopId,
shopName: parsed.shopName,
platformRaw: parsed.platformRaw,
eventType: parsed.eventType,
platformOrderId: parsed.platformOrderId,
provider: enriched.parsed.provider,
platform: enriched.parsed.platform,
shopId: enriched.parsed.shopId,
shopName: enriched.parsed.shopName,
platformRaw: enriched.parsed.platformRaw,
eventType: enriched.parsed.eventType,
platformOrderId: enriched.parsed.platformOrderId,
orderId: result.order.id,
totalAmountFen: Number(enriched.parsed.totalAmount || 0),
enriched: enriched.enriched,
enrichReason: enriched.reason || '',
taskCount: result.tasks.length,
messageDeliveries: result.messageDeliveries || [],
tasks: result.tasks.map((task) => ({
@@ -156,6 +167,40 @@ async function executeAgisoTradeWebhook(parsed, webhookEventId, { requestId = ''
}
}
async function enrichTradeBeforeUpsert(parsed, { requestId = '', webhookEventId = null } = {}) {
if (parsed.provider !== 'agiso' || parsed.platform !== 'xianyu') {
return { parsed, enriched: false, reason: 'not_supported' }
}
if (Number(parsed.totalAmount || 0) > 0) {
return { parsed, enriched: false, reason: 'already_has_amount' }
}
const detailResult = await enrichAgisoXianyuTradeOrder(parsed, { requestId })
const nextParsed = detailResult?.parsed || parsed
logWebhook('[webhook-service/agiso]', 'Agiso webhook 订单补查结束', {
requestId,
webhookEventId,
provider: nextParsed.provider,
platform: nextParsed.platform,
shopId: nextParsed.shopId,
platformOrderId: nextParsed.platformOrderId,
enriched: Boolean(detailResult?.enriched),
reason: String(detailResult?.reason || ''),
totalAmountFen: Number(nextParsed.totalAmount || 0),
paidAt: nextParsed.paidAt || null,
errorMessage: String(detailResult?.errorMessage || ''),
})
return {
parsed: nextParsed,
enriched: Boolean(detailResult?.enriched),
reason: String(detailResult?.reason || ''),
errorMessage: String(detailResult?.errorMessage || ''),
}
}
function parseAgisoTradeRequest(requestLike) {
const query = normalizeRecord(requestLike.query)
const body = normalizeRecord(requestLike.body)