fix: 修正自动导入完成提示
- 根据关联文档真实状态识别已完成的历史失败批次 - 完成后自动移除提示并低频复查失败或中断批次
This commit is contained in:
@@ -51,7 +51,7 @@ describe('documentImportBatchStatus', () => {
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
it('当前页面跟踪的批次完成后继续展示结果', async () => {
|
||||
it('当前页面跟踪的批次完成后移除提示', async () => {
|
||||
vi.useFakeTimers();
|
||||
apiMocks.get
|
||||
.mockResolvedValueOnce({
|
||||
@@ -73,10 +73,62 @@ describe('documentImportBatchStatus', () => {
|
||||
await vi.advanceTimersByTimeAsync(3000);
|
||||
await flushPromises();
|
||||
|
||||
expect(wrapper.find('.batch-status').exists()).toBe(false);
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
it('失败批次关联任务实际完成后不再展示提示', async () => {
|
||||
apiMocks.get.mockResolvedValue({
|
||||
data: {
|
||||
...createBatch('RUNNING', 0),
|
||||
actualCompleted: true,
|
||||
failedCount: 2,
|
||||
pendingCount: 0,
|
||||
status: 'PARTIAL_SUCCEEDED',
|
||||
},
|
||||
errorCode: 0,
|
||||
});
|
||||
|
||||
const wrapper = mount(DocumentImportBatchStatus, {
|
||||
props: { knowledgeId: 'knowledge-1' },
|
||||
});
|
||||
await flushPromises();
|
||||
|
||||
expect(wrapper.find('.batch-status').exists()).toBe(false);
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
it('失败批次低频复查后在关联任务完成时移除提示', async () => {
|
||||
vi.useFakeTimers();
|
||||
const failedBatch = {
|
||||
...createBatch('RUNNING', 0),
|
||||
actualCompleted: false,
|
||||
failedCount: 2,
|
||||
pendingCount: 0,
|
||||
status: 'PARTIAL_SUCCEEDED',
|
||||
};
|
||||
apiMocks.get
|
||||
.mockResolvedValueOnce({
|
||||
data: failedBatch,
|
||||
errorCode: 0,
|
||||
})
|
||||
.mockResolvedValueOnce({
|
||||
data: { ...failedBatch, actualCompleted: true },
|
||||
errorCode: 0,
|
||||
});
|
||||
|
||||
const wrapper = mount(DocumentImportBatchStatus, {
|
||||
props: { knowledgeId: 'knowledge-1' },
|
||||
});
|
||||
await flushPromises();
|
||||
|
||||
expect(wrapper.find('.batch-status').exists()).toBe(true);
|
||||
expect(wrapper.text()).toContain(
|
||||
'documentCollection.importDoc.batchCompleted',
|
||||
);
|
||||
|
||||
await vi.advanceTimersByTimeAsync(15_000);
|
||||
await flushPromises();
|
||||
|
||||
expect(apiMocks.get).toHaveBeenCalledTimes(2);
|
||||
expect(wrapper.find('.batch-status').exists()).toBe(false);
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
@@ -239,9 +291,7 @@ describe('documentImportBatchStatus', () => {
|
||||
|
||||
expect(apiMocks.get).toHaveBeenCalledTimes(3);
|
||||
expect(wrapper.find('.batch-status__load-error').exists()).toBe(false);
|
||||
expect(wrapper.text()).toContain(
|
||||
'documentCollection.importDoc.batchCompleted',
|
||||
);
|
||||
expect(wrapper.find('.batch-status').exists()).toBe(false);
|
||||
wrapper.unmount();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -8,6 +8,7 @@ import { ElAlert, ElButton, ElProgress } from 'element-plus';
|
||||
import { api } from '#/api/request';
|
||||
|
||||
interface BatchStatus {
|
||||
actualCompleted?: boolean;
|
||||
batchId: string;
|
||||
cancelledCount?: number;
|
||||
completedCount: number;
|
||||
@@ -53,6 +54,7 @@ let pollTimer: null | ReturnType<typeof setTimeout> = null;
|
||||
let disposed = false;
|
||||
let refreshGeneration = 0;
|
||||
let pollDelayMs = 3000;
|
||||
const TERMINAL_RECHECK_DELAY_MS = 15_000;
|
||||
|
||||
const canContinue = computed(
|
||||
() =>
|
||||
@@ -122,7 +124,7 @@ const interruptMetadata = computed(() => {
|
||||
return details.join(' · ');
|
||||
});
|
||||
|
||||
async function refresh(hideCompletedOnRestore = false) {
|
||||
async function refresh() {
|
||||
if (!props.knowledgeId) return;
|
||||
const currentGeneration = ++refreshGeneration;
|
||||
refreshing.value = true;
|
||||
@@ -142,10 +144,9 @@ async function refresh(hideCompletedOnRestore = false) {
|
||||
loadError.value = '';
|
||||
pollDelayMs = 3000;
|
||||
const restoredBatch = response.data || undefined;
|
||||
batch.value =
|
||||
hideCompletedOnRestore && restoredBatch?.status === 'COMPLETED'
|
||||
? undefined
|
||||
: restoredBatch;
|
||||
const completed =
|
||||
restoredBatch?.status === 'COMPLETED' || restoredBatch?.actualCompleted;
|
||||
batch.value = completed ? undefined : restoredBatch;
|
||||
} catch {
|
||||
if (!disposed && currentGeneration === refreshGeneration) {
|
||||
loadError.value = $t(
|
||||
@@ -175,13 +176,16 @@ function schedulePoll() {
|
||||
if (
|
||||
!batch.value ||
|
||||
batch.value.status === 'COMPLETED' ||
|
||||
batch.value.status === 'PARTIAL_SUCCEEDED' ||
|
||||
batch.value.status === 'INTERRUPTED' ||
|
||||
batch.value.status === 'CANCELLED'
|
||||
) {
|
||||
return;
|
||||
}
|
||||
pollTimer = setTimeout(refresh, 3000);
|
||||
const delay =
|
||||
batch.value.status === 'PARTIAL_SUCCEEDED' ||
|
||||
batch.value.status === 'INTERRUPTED'
|
||||
? TERMINAL_RECHECK_DELAY_MS
|
||||
: 3000;
|
||||
pollTimer = setTimeout(refresh, delay);
|
||||
}
|
||||
|
||||
async function continueBatch() {
|
||||
@@ -204,7 +208,7 @@ async function continueBatch() {
|
||||
|
||||
onMounted(() => {
|
||||
disposed = false;
|
||||
refresh(true);
|
||||
refresh();
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
@@ -222,7 +226,7 @@ watch(
|
||||
loadError.value = '';
|
||||
pollDelayMs = 3000;
|
||||
}
|
||||
refresh(knowledgeChanged);
|
||||
refresh();
|
||||
},
|
||||
);
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user