修复接口内容缺失
This commit is contained in:
@@ -475,6 +475,13 @@ function rowKeyForMatch(row: ProductRiskShopQueueItem) {
|
||||
return `${name}\u0001${id}`
|
||||
}
|
||||
|
||||
function removeMatchedRowsLocally(rows: ProductRiskShopQueueItem[]) {
|
||||
if (!rows.length) return
|
||||
const keys = new Set(rows.map((row) => rowKeyForMatch(row)))
|
||||
matchedItems.value = matchedItems.value.filter((row) => !keys.has(rowKeyForMatch(row)))
|
||||
saveMatchedItemsToStorage()
|
||||
}
|
||||
|
||||
async function removeMatchedRow(row: ProductRiskShopQueueItem) {
|
||||
const key = rowKeyForMatch(row)
|
||||
const backup = [...matchedItems.value]
|
||||
@@ -608,14 +615,24 @@ function isTaskTerminalById(taskId?: number) {
|
||||
return s === 'SUCCESS' || s === 'FAILED'
|
||||
}
|
||||
|
||||
const currentSectionItems = computed(() =>
|
||||
historyItems.value.filter(
|
||||
const currentSectionItems = computed(() => {
|
||||
const out = historyItems.value.filter(
|
||||
(row) =>
|
||||
row.taskId &&
|
||||
pollingTaskIds.value.includes(row.taskId) &&
|
||||
!isTaskTerminalById(row.taskId),
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
const existingTaskIds = new Set(out.map((row) => row.taskId).filter((id): id is number => typeof id === 'number'))
|
||||
for (const taskId of pollingTaskIds.value) {
|
||||
if (existingTaskIds.has(taskId)) continue
|
||||
const snapshot = taskSnapshots.value[taskId]
|
||||
const items = snapshot?.items || []
|
||||
const first = items[0]
|
||||
if (first) out.push(first)
|
||||
}
|
||||
return out
|
||||
})
|
||||
|
||||
const historySectionItems = computed(() =>
|
||||
historyItems.value.filter(
|
||||
@@ -706,6 +723,37 @@ function stopPolling() {
|
||||
}
|
||||
}
|
||||
|
||||
async function waitForTaskTerminal(taskId: number) {
|
||||
while (true) {
|
||||
const batch = await getProductRiskTasksBatch([taskId])
|
||||
const detail = (batch.items || []).find((d) => d.task?.id === taskId)
|
||||
const status = detail?.task?.status || ''
|
||||
|
||||
if (detail) {
|
||||
taskSnapshots.value = {
|
||||
...taskSnapshots.value,
|
||||
[taskId]: detail,
|
||||
}
|
||||
saveTaskSnapshotsToStorage()
|
||||
}
|
||||
if (status) {
|
||||
taskDetails.value[taskId] = status
|
||||
saveTaskDetailsToStorage()
|
||||
}
|
||||
|
||||
if (status === 'SUCCESS' || status === 'FAILED') {
|
||||
removePollingTask(taskId)
|
||||
await loadHistory()
|
||||
await loadDashboard()
|
||||
return status
|
||||
}
|
||||
|
||||
await new Promise<void>((resolve) => {
|
||||
window.setTimeout(() => resolve(), getPollIntervalMs())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async function confirmAdd() {
|
||||
const name = shopInput.value.trim()
|
||||
if (!name) {
|
||||
@@ -808,9 +856,14 @@ async function runMatch() {
|
||||
}
|
||||
}
|
||||
|
||||
function statusText(item: ProductRiskHistoryItem) {
|
||||
function resolvedTaskStatus(item: ProductRiskHistoryItem) {
|
||||
const tid = item.taskId
|
||||
const st = tid ? taskStatusOf(tid) : item.taskStatus
|
||||
if (!tid) return item.taskStatus || ''
|
||||
return taskStatusOf(tid) || item.taskStatus || ''
|
||||
}
|
||||
|
||||
function statusText(item: ProductRiskHistoryItem) {
|
||||
const st = resolvedTaskStatus(item)
|
||||
if (st === 'SUCCESS') return '已完成'
|
||||
if (st === 'FAILED') return '失败'
|
||||
if (st === 'RUNNING') return '执行中'
|
||||
@@ -819,17 +872,15 @@ function statusText(item: ProductRiskHistoryItem) {
|
||||
}
|
||||
|
||||
function statusClass(item: ProductRiskHistoryItem) {
|
||||
const tid = item.taskId
|
||||
const st = tid ? taskStatusOf(tid) : item.taskStatus
|
||||
const st = resolvedTaskStatus(item)
|
||||
if (st === 'SUCCESS' || item.success) return 'success'
|
||||
if (st === 'FAILED') return 'failed'
|
||||
return 'running'
|
||||
}
|
||||
|
||||
function canDownload(item: ProductRiskHistoryItem) {
|
||||
if (!item.resultId) return false
|
||||
const tid = item.taskId
|
||||
const st = tid ? taskStatusOf(tid) : item.taskStatus
|
||||
if (!item.resultId || !item.downloadUrl) return false
|
||||
const st = resolvedTaskStatus(item)
|
||||
return st === 'SUCCESS' || item.success === true
|
||||
}
|
||||
|
||||
@@ -894,26 +945,27 @@ async function pushToPythonQueue() {
|
||||
}
|
||||
pushing.value = true
|
||||
queuePayloadText.value = ''
|
||||
let createdTaskId: number | null = null
|
||||
try {
|
||||
const created = await createProductRiskTask(toPush)
|
||||
createdTaskId = created.taskId
|
||||
taskSnapshots.value = {
|
||||
...taskSnapshots.value,
|
||||
[created.taskId]: {
|
||||
task: { id: created.taskId, status: 'RUNNING' },
|
||||
items: created.items,
|
||||
},
|
||||
}
|
||||
saveTaskSnapshotsToStorage()
|
||||
addPollingTask(created.taskId)
|
||||
for (let i = 0; i < toPush.length; i++) {
|
||||
const item = toPush[i]
|
||||
const created = await createProductRiskTask([item])
|
||||
const taskId = created.taskId
|
||||
taskSnapshots.value = {
|
||||
...taskSnapshots.value,
|
||||
[taskId]: {
|
||||
task: { id: taskId, status: 'RUNNING' },
|
||||
items: created.items,
|
||||
},
|
||||
}
|
||||
saveTaskSnapshotsToStorage()
|
||||
addPollingTask(taskId)
|
||||
ensurePolling(true)
|
||||
|
||||
const payload = {
|
||||
type: 'product-risk-resolve-run',
|
||||
ts: Date.now(),
|
||||
data: {
|
||||
taskId: created.taskId,
|
||||
taskId,
|
||||
items: [item],
|
||||
country_codes: [...orderedCountryCodes.value],
|
||||
risk_listing_filter: productRiskListingFilter.value,
|
||||
@@ -922,18 +974,32 @@ async function pushToPythonQueue() {
|
||||
queuePayloadText.value = JSON.stringify(payload, null, 2)
|
||||
const pushResult = await api.enqueue_json(payload)
|
||||
if (!pushResult?.success) {
|
||||
removePollingTask(created.taskId)
|
||||
removePollingTask(taskId)
|
||||
queuePushResult.value = `第 ${i + 1}/${toPush.length} 条推送失败:${pushResult?.error || '未知错误'}`
|
||||
ElMessage.error(queuePushResult.value)
|
||||
return
|
||||
}
|
||||
queuePushResult.value = `任务 ${created.taskId}:已入队 ${i + 1}/${toPush.length} 条店铺,当前队列长度:${pushResult.queue_size ?? '-'}`
|
||||
|
||||
removeMatchedRowsLocally([item])
|
||||
queuePushResult.value = toPush.length > 1
|
||||
? `任务 ${taskId}:第 ${i + 1}/${toPush.length} 条店铺已入队,等待执行完成...`
|
||||
: `任务 ${taskId} 已入队,等待执行完成...`
|
||||
|
||||
const finalStatus = await waitForTaskTerminal(taskId)
|
||||
if (finalStatus !== 'SUCCESS') {
|
||||
queuePushResult.value = `任务 ${taskId} 执行失败,已停止后续店铺推送`
|
||||
ElMessage.error(queuePushResult.value)
|
||||
return
|
||||
}
|
||||
|
||||
queuePushResult.value = i + 1 < toPush.length
|
||||
? `任务 ${taskId} 已完成,继续推送下一条(${i + 1}/${toPush.length})`
|
||||
: `任务 ${taskId} 已完成`
|
||||
}
|
||||
ElMessage.success(`已创建任务 ${created.taskId},${toPush.length} 条店铺已逐条入队`)
|
||||
ElMessage.success(`已按顺序完成 ${toPush.length} 条店铺推送`)
|
||||
await loadHistory()
|
||||
ensurePolling(true)
|
||||
} catch (e) {
|
||||
if (createdTaskId != null) removePollingTask(createdTaskId)
|
||||
queuePushResult.value = e instanceof Error ? e.message : '推送异常'
|
||||
ElMessage.error(queuePushResult.value)
|
||||
} finally {
|
||||
|
||||
Reference in New Issue
Block a user