修改多文件
This commit is contained in:
@@ -224,9 +224,14 @@ import {
|
||||
} from '@/shared/api/java-modules'
|
||||
import { getPywebviewApi, type UploadedJavaFile } from '@/shared/bridges/pywebview'
|
||||
|
||||
interface SessionDeleteBrandItem extends DeleteBrandResultItem {
|
||||
_pushed?: boolean
|
||||
_completed?: boolean
|
||||
}
|
||||
|
||||
interface StoredCurrentTask {
|
||||
taskId: number
|
||||
items: DeleteBrandResultItem[]
|
||||
items: SessionDeleteBrandItem[]
|
||||
createdAt: number
|
||||
queuePushResult?: string
|
||||
queuePayloadText?: string
|
||||
@@ -318,6 +323,84 @@ const historySectionItems = computed(() =>
|
||||
);
|
||||
const hasVisibleItems = computed(() => currentSectionItems.value.length > 0 || historySectionItems.value.length > 0)
|
||||
|
||||
function persistSessionTasks() {
|
||||
if (typeof window !== 'undefined') {
|
||||
window.localStorage.setItem(getStorageKey(), JSON.stringify(sessionTasks.value))
|
||||
}
|
||||
}
|
||||
|
||||
function isMultiFileTask(taskId?: number) {
|
||||
if (!taskId) return false
|
||||
const sessionTask = sessionTasks.value.find(t => t.taskId === taskId)
|
||||
return (sessionTask?.items.length || 0) > 1
|
||||
}
|
||||
|
||||
function findSessionTask(taskId?: number) {
|
||||
if (!taskId) return null
|
||||
return sessionTasks.value.find(t => t.taskId === taskId) || null
|
||||
}
|
||||
|
||||
function isSameDeleteBrandItem(left: Pick<DeleteBrandResultItem, 'resultId' | 'fileKey' | 'sourceFilename'> | null | undefined,
|
||||
right: Pick<DeleteBrandResultItem, 'resultId' | 'fileKey' | 'sourceFilename'> | null | undefined) {
|
||||
if (!left || !right) return false
|
||||
if (left.resultId != null && right.resultId != null) {
|
||||
return left.resultId === right.resultId
|
||||
}
|
||||
if (left.fileKey && right.fileKey) {
|
||||
return left.fileKey === right.fileKey
|
||||
}
|
||||
return left.sourceFilename === right.sourceFilename
|
||||
}
|
||||
|
||||
function findSessionItem(taskId: number | undefined, item: DeleteBrandResultItem) {
|
||||
const sessionTask = findSessionTask(taskId)
|
||||
if (!sessionTask) return null
|
||||
return sessionTask.items.find(i => isSameDeleteBrandItem(i, item)) || null
|
||||
}
|
||||
|
||||
function updateCompletedItemsFromProgress(taskId: number | undefined) {
|
||||
if (!taskId) return false
|
||||
|
||||
const sessionTask = findSessionTask(taskId)
|
||||
if (!sessionTask) return false
|
||||
|
||||
let changed = false
|
||||
const info = taskDetails.value[taskId]?.line_progress?.info
|
||||
|
||||
// 多文件任务优先依据后端 finished_files 同步已完成文件数量。
|
||||
// 规则:按 sessionTask.items 的顺序,标记「已推送」中的前 N 个为 completed。
|
||||
if (isMultiFileTask(taskId) && info?.finished_files != null && info.finished_files >= 0) {
|
||||
const pushedItems = sessionTask.items.filter(i => i._pushed)
|
||||
const shouldCompleted = Math.max(0, Math.min(info.finished_files, pushedItems.length))
|
||||
|
||||
for (let i = 0; i < shouldCompleted; i += 1) {
|
||||
if (!pushedItems[i]._completed) {
|
||||
pushedItems[i]._completed = true
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 兼容单文件/兜底:当当前文件行进度到达末行时,标记活动文件完成。
|
||||
if (info?.file_name && info.current_line != null && info.total_lines != null && info.total_lines > 0) {
|
||||
if (info.current_line >= info.total_lines) {
|
||||
const activeItem = currentSectionItems.value.find(item => getItemKey(item) === activeItemKey.value)
|
||||
const sessionItem = activeItem && activeItem.taskId === taskId
|
||||
? findSessionItem(taskId, activeItem)
|
||||
: sessionTask.items.find(i => i.sourceFilename === info.file_name)
|
||||
if (sessionItem && !sessionItem._completed) {
|
||||
sessionItem._completed = true
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
persistSessionTasks()
|
||||
}
|
||||
return changed
|
||||
}
|
||||
|
||||
function getTaskStatus(taskId?: number) {
|
||||
if (!taskId) return ''
|
||||
return taskDetails.value[taskId]?.task?.status || ''
|
||||
@@ -342,14 +425,20 @@ function shouldShowProgress(item: DeleteBrandResultItem) {
|
||||
function normalizeDeleteBrandItems(items: DeleteBrandResultItem[]) {
|
||||
return items.map((item) => {
|
||||
if (item.matchStatus === 'MATCHED') {
|
||||
return item
|
||||
return {
|
||||
...item,
|
||||
_pushed: false,
|
||||
_completed: false,
|
||||
} as SessionDeleteBrandItem
|
||||
}
|
||||
return {
|
||||
...item,
|
||||
matched: false,
|
||||
openStoreUrl: undefined,
|
||||
error: item.error || undefined,
|
||||
}
|
||||
_pushed: false,
|
||||
_completed: false,
|
||||
} as SessionDeleteBrandItem
|
||||
})
|
||||
}
|
||||
|
||||
@@ -404,11 +493,14 @@ function formatProgress(taskId: number) {
|
||||
if (info.file_index && info.file_total) parts.push(`文件:${info.file_index}/${info.file_total}`)
|
||||
if (info.file_name) parts.push(`当前文件:${info.file_name}`)
|
||||
if (info.current_line != null && info.total_lines != null) {
|
||||
parts.push(`进度:${info.current_line}/${info.total_lines}`)
|
||||
parts.push(`${isMultiFileTask(taskId) ? '当前文件进度' : '进度'}:${info.current_line}/${info.total_lines}`)
|
||||
}
|
||||
if (info.current_country) parts.push(`国家:${info.current_country}`)
|
||||
if (info.current_asin) parts.push(`ASIN:${info.current_asin}`)
|
||||
if (info.finished_files != null) parts.push(`已完成文件:${info.finished_files}`)
|
||||
if (info.finished_files != null) {
|
||||
const total = info.file_total && info.file_total > 0 ? `/${info.file_total}` : ''
|
||||
parts.push(`已完成文件:${info.finished_files}${total}`)
|
||||
}
|
||||
return parts.join('|')
|
||||
}
|
||||
|
||||
@@ -446,34 +538,41 @@ function getPollingTaskIds() {
|
||||
function getQueueStatus(item: DeleteBrandResultItem) {
|
||||
const taskId = item.taskId
|
||||
if (!taskId) return ''
|
||||
const sessionTask = sessionTasks.value.find(t => t.taskId === taskId)
|
||||
const sessionTask = findSessionTask(taskId)
|
||||
if (!sessionTask) return ''
|
||||
|
||||
const sessionItem = findSessionItem(taskId, item)
|
||||
const status = getTaskStatus(taskId)
|
||||
if (status === 'SUCCESS' || status === 'FAILED' || item.taskStatus === 'SUCCESS' || item.taskStatus === 'FAILED') {
|
||||
const info = taskDetails.value[taskId]?.line_progress
|
||||
const multiFileTask = isMultiFileTask(taskId)
|
||||
|
||||
if (!multiFileTask && (status === 'SUCCESS' || status === 'FAILED' || item.taskStatus === 'SUCCESS' || item.taskStatus === 'FAILED')) {
|
||||
return '已被全局判定为终态'
|
||||
}
|
||||
|
||||
const sessionItem = sessionTask.items.find(i => i.resultId === item.resultId || i.sourceFilename === item.sourceFilename)
|
||||
|
||||
const info = taskDetails.value[taskId]?.line_progress
|
||||
|
||||
// 此时这个特定文件是否正好被后端报了进度名
|
||||
if (status === 'RUNNING' && info?.has_progress && info?.info?.file_name === item.sourceFilename) {
|
||||
return '处理中'
|
||||
}
|
||||
|
||||
// 查查是否已经完结了这个特定文件
|
||||
const detail = taskDetails.value[taskId]
|
||||
if (detail?.items) {
|
||||
// 后端返回的 items 是 `resultJson` 解析来的,里面只含有已经做完的!
|
||||
const finished = detail.items.find((i: DeleteBrandResultItem) => i.sourceFilename === item.sourceFilename)
|
||||
if (finished) {
|
||||
return '本文件解析完毕'
|
||||
if (sessionItem?._completed) {
|
||||
return '本文件解析完毕'
|
||||
}
|
||||
|
||||
if (multiFileTask && status === 'SUCCESS') {
|
||||
return '本文件解析完毕'
|
||||
}
|
||||
|
||||
if (!multiFileTask) {
|
||||
const detail = taskDetails.value[taskId]
|
||||
if (detail?.items) {
|
||||
const finished = detail.items.find((i: DeleteBrandResultItem) => isSameDeleteBrandItem(i, item))
|
||||
if (finished && status === 'SUCCESS') {
|
||||
return '本文件解析完毕'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sessionItem && (sessionItem as any)._pushed) {
|
||||
if (sessionItem?._pushed) {
|
||||
return '已入队'
|
||||
}
|
||||
|
||||
@@ -497,12 +596,14 @@ function mergeTaskDetailItemsIntoSession(detail: DeleteBrandTaskDetailVo) {
|
||||
|
||||
let changed = false
|
||||
const mergedItems = sessionTask.items.map((item) => {
|
||||
const latest = detail.items?.find((candidate) => candidate.resultId === item.resultId || candidate.sourceFilename === item.sourceFilename)
|
||||
const latest = detail.items?.find((candidate) => isSameDeleteBrandItem(candidate, item))
|
||||
if (!latest) return item
|
||||
const merged = {
|
||||
...item,
|
||||
...latest,
|
||||
success: item.success ?? latest.success,
|
||||
_pushed: item._pushed,
|
||||
_completed: item._completed,
|
||||
}
|
||||
if (JSON.stringify(merged) !== JSON.stringify(item)) {
|
||||
changed = true
|
||||
@@ -516,8 +617,8 @@ function mergeTaskDetailItemsIntoSession(detail: DeleteBrandTaskDetailVo) {
|
||||
changed = true
|
||||
}
|
||||
|
||||
if (changed && typeof window !== 'undefined') {
|
||||
window.localStorage.setItem(getStorageKey(), JSON.stringify(sessionTasks.value))
|
||||
if (changed) {
|
||||
persistSessionTasks()
|
||||
}
|
||||
return changed
|
||||
}
|
||||
@@ -536,6 +637,9 @@ async function refreshTaskDetails(taskIds?: number[]) {
|
||||
if (mergeTaskDetailItemsIntoSession(detail)) {
|
||||
changed = true
|
||||
}
|
||||
if (updateCompletedItemsFromProgress(id)) {
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
@@ -833,6 +937,8 @@ function findNextAutoRunnableItem() {
|
||||
return currentSectionItems.value.find((item) => {
|
||||
if (!item.openStoreUrl) return false
|
||||
if (getItemKey(item) === activeItemKey.value) return false
|
||||
const sessionItem = findSessionItem(item.taskId, item)
|
||||
if (sessionItem?._completed) return false
|
||||
return getQueueStatus(item) === '未入队'
|
||||
})
|
||||
}
|
||||
@@ -870,9 +976,10 @@ async function runItem(item: DeleteBrandResultItem, options?: { auto?: boolean }
|
||||
if (pushResult?.success) {
|
||||
qpr = `已推送文件 ${item.sourceFilename},当前队列长度:${pushResult.queue_size ?? '-'}`
|
||||
|
||||
const sessionItem = sessionTask.items.find(i => i.resultId === item.resultId || i.sourceFilename === item.sourceFilename)
|
||||
const sessionItem = findSessionItem(taskId, item)
|
||||
if (sessionItem) {
|
||||
(sessionItem as any)._pushed = true
|
||||
sessionItem._pushed = true
|
||||
sessionItem._completed = false
|
||||
}
|
||||
activeItemKey.value = getItemKey(item)
|
||||
saveSessionTask(taskId, sessionTask.items, qpr, queuePayloadText.value)
|
||||
@@ -892,10 +999,21 @@ async function maybeAutoAdvance() {
|
||||
if (currentKey) {
|
||||
const currentItem = currentSectionItems.value.find(item => getItemKey(item) === currentKey)
|
||||
if (currentItem) {
|
||||
const taskId = currentItem.taskId
|
||||
const multiFileTask = isMultiFileTask(taskId)
|
||||
if (multiFileTask) {
|
||||
updateCompletedItemsFromProgress(taskId)
|
||||
}
|
||||
const status = getQueueStatus(currentItem)
|
||||
if (status === '已入队' || status === '处理中') {
|
||||
return
|
||||
}
|
||||
if (multiFileTask) {
|
||||
const sessionItem = findSessionItem(taskId, currentItem)
|
||||
if (sessionItem && !sessionItem._completed) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user