可以接收到咸鱼的订单创建连接

This commit is contained in:
yml
2026-04-08 23:20:21 +08:00
parent a2b09c89e8
commit c2ec3aa6d2
10 changed files with 608 additions and 64 deletions
@@ -15,6 +15,7 @@ const loading = ref(true)
const actionLoadingId = ref<number | null>(null)
const errorMessage = ref('')
const items = ref<AdminWebhookEventListItem[]>([])
const provider = ref('')
const platform = ref('')
const processed = ref('')
const relatedOrderId = ref('')
@@ -34,6 +35,7 @@ async function loadEvents(page = pagination.value.page) {
const response = await fetchAdminWebhookEvents({
page,
pageSize: pagination.value.pageSize,
provider: provider.value.trim(),
platform: platform.value.trim(),
processed: processed.value.trim(),
relatedOrderId: relatedOrderId.value.trim(),
@@ -77,6 +79,21 @@ async function submitReplay(item: AdminWebhookEventListItem) {
}
}
function formatRequestTimestamp(value: string) {
const normalized = String(value || '').trim()
if (!/^\d{10,13}$/.test(normalized)) {
return normalized || '-'
}
const epochMs = normalized.length === 13 ? Number(normalized) : Number(normalized) * 1000
return formatAdminDateTime(new Date(epochMs).toISOString())
}
function formatAmount(item: AdminWebhookEventListItem) {
return item.totalAmount ? `${item.totalAmount} ${item.currency}` : '-'
}
onMounted(loadEvents)
</script>
@@ -90,7 +107,8 @@ onMounted(loadEvents)
</header>
<section class="filter-bar">
<input v-model="platform" class="text-input" placeholder="平台,如 agiso" />
<input v-model="provider" class="text-input" placeholder="服务商,如 agiso" />
<input v-model="platform" class="text-input" placeholder="业务平台,如 xianyu / taobao" />
<select v-model="processed" class="text-input select-input">
<option v-for="option in adminWebhookProcessedOptions" :key="option.value" :value="option.value">
{{ option.label }}
@@ -113,11 +131,11 @@ onMounted(loadEvents)
<thead>
<tr>
<th>ID</th>
<th>平台</th>
<th>事件类型</th>
<th>验签</th>
<th>处理结果</th>
<th>订单</th>
<th>来源</th>
<th>事件摘要</th>
<th>订单与店铺</th>
<th>验签与处理</th>
<th>请求来源</th>
<th>时间</th>
<th>操作</th>
</tr>
@@ -127,15 +145,70 @@ onMounted(loadEvents)
<td>
<RouterLink :to="`/admin/webhook-events/${item.eventId}`">{{ item.eventId }}</RouterLink>
</td>
<td>{{ item.platform }}</td>
<td>{{ formatAdminWebhookEventType(item.eventType) }}</td>
<td><AdminStatusTag :status="item.signatureValid ? 'success' : 'failed'" /></td>
<td>
<AdminStatusTag :status="item.processed ? 'success' : 'failed'" />
<span v-if="!item.processed && item.processError" class="error-inline">{{ item.processError }}</span>
<div class="cell-stack">
<div class="cell-title">{{ item.provider }} / {{ item.platform }}</div>
<div v-if="item.platformRaw && item.platformRaw !== item.platform" class="cell-subtle">
原始平台{{ item.platformRaw }}
</div>
<div class="meta-chip-row">
<span class="meta-chip">店铺 {{ item.shopName || item.shopId || '-' }}</span>
<span v-if="item.shopId" class="meta-chip">ID {{ item.shopId }}</span>
</div>
</div>
</td>
<td>
<div class="cell-stack">
<div class="cell-title">{{ formatAdminWebhookEventType(item.eventType) }}</div>
<div v-if="item.messageText" class="cell-subtle">{{ item.messageText }}</div>
<div class="meta-chip-row">
<span v-if="item.aopic" class="meta-chip">aopic {{ item.aopic }}</span>
<span v-if="item.itemCount" class="meta-chip">商品 {{ item.itemCount }}</span>
</div>
<div class="mono-inline">Key: {{ item.eventKey }}</div>
</div>
</td>
<td>
<div class="cell-stack">
<div class="cell-title">平台单{{ item.platformOrderId || '-' }}</div>
<div class="cell-subtle">买家{{ item.buyerName || item.buyerId || '-' }}</div>
<div class="cell-subtle">金额{{ formatAmount(item) }}</div>
<div class="meta-chip-row">
<span class="meta-chip">
关联订单
<template v-if="item.relatedOrderId">
<RouterLink class="inline-link" :to="`/admin/orders/${item.relatedOrderId}`">{{ item.relatedOrderId }}</RouterLink>
</template>
<template v-else>-</template>
</span>
<span class="meta-chip">任务 {{ item.taskCount }}</span>
</div>
</div>
</td>
<td>
<div class="cell-stack">
<div class="tag-row">
<AdminStatusTag :status="item.signatureValid ? 'success' : 'failed'" />
<AdminStatusTag :status="item.processed ? 'success' : 'failed'" />
</div>
<div class="cell-subtle">签名{{ item.requestSign || '-' }}</div>
<div v-if="item.processError" class="error-inline">{{ item.processError }}</div>
</div>
</td>
<td>
<div class="cell-stack">
<div class="cell-title">{{ item.sourceHost || '-' }}</div>
<div class="cell-subtle">IP{{ item.sourceIp || '-' }}</div>
<div class="cell-subtle line-clamp-2">UA{{ item.userAgent || '-' }}</div>
<div class="cell-subtle">请求时间{{ formatRequestTimestamp(item.requestTimestamp) }}</div>
</div>
</td>
<td>
<div class="cell-stack">
<div class="cell-title">{{ formatAdminDateTime(item.createdAt) }}</div>
<div class="cell-subtle">事件 ID #{{ item.eventId }}</div>
</div>
</td>
<td>{{ item.relatedOrderId || '-' }}</td>
<td>{{ formatAdminDateTime(item.createdAt) }}</td>
<td>
<el-button
v-if="hasAdminRole('admin')"
@@ -183,6 +256,49 @@ onMounted(loadEvents)
align-items: center;
}
.cell-stack {
display: grid;
gap: 6px;
}
.cell-title {
color: #0f172a;
font-weight: 700;
line-height: 1.4;
}
.cell-subtle {
color: #64748b;
font-size: 12px;
line-height: 1.5;
}
.meta-chip-row,
.tag-row {
display: flex;
flex-wrap: wrap;
gap: 6px;
align-items: center;
}
.meta-chip {
display: inline-flex;
align-items: center;
gap: 4px;
min-height: 24px;
padding: 0 8px;
border-radius: 999px;
color: #475467;
background: #f8fafc;
border: 1px solid rgba(148, 163, 184, 0.24);
font-size: 12px;
}
.inline-link {
color: #175cd3;
font-weight: 700;
}
.table-card,
.empty-block,
.error-copy {
@@ -198,9 +314,9 @@ onMounted(loadEvents)
.error-inline {
display: block;
margin-top: 6px;
color: #b42318;
font-size: 12px;
line-height: 1.5;
}
.text-input {
@@ -234,4 +350,18 @@ onMounted(loadEvents)
color: #64748b;
font-size: 13px;
}
.mono-inline {
color: #475467;
font-size: 12px;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, monospace;
word-break: break-all;
}
.line-clamp-2 {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
</style>