This commit is contained in:
zhu
2026-05-09 17:48:31 +08:00
parent 30f9467cc8
commit 186840ba23
10 changed files with 330 additions and 118 deletions

View File

@@ -18,6 +18,7 @@ const {
isScanning,
crawlState,
handleScan,
handleCancelCrawl,
elapsedSeconds
} = useScan()
@@ -29,12 +30,6 @@ const shouldShowCrawlProgress = computed<boolean>(() =>
crawlState.value != null
);
/**
* 取消爬取
*/
const handleCancelCrawl = () => {
}
/**
* 获取进度样式

View File

@@ -1,49 +1,87 @@
import {onMounted, onUnmounted, ref} from "vue";
import {platformConfigs} from "@/config/platforms";
import {CrawlTaskState} from "@/types";
import {sendBackgroundMessage} from "@/shared/message";
import { onMounted, onUnmounted, ref } from 'vue';
import { platformConfigs } from '@/config/platforms';
import type { CrawlTaskState } from '@/types';
import { sendBackgroundMessage } from '@/shared/message';
const CRAWL_TASK_STORAGE_KEY = 'crawlTaskState';
const ACTIVE_STATUSES = new Set(['running', 'paused']);
export const useScan = () => {
//选中id
const selectedPlatformId = ref(platformConfigs[0]?.id ?? '');
//防抖
const isScanning = ref<boolean>(false)
//步骤数据
const isScanning = ref<boolean>(false);
const crawlState = ref<CrawlTaskState | null>(null);
//爬取时间
const elapsedSeconds = ref<number>(0)
const elapsedSeconds = ref<number>(0);
let timer: number | undefined;
/**
* 开始爬取
*/
const handleScan = async () => {
if (isScanning.value) return
isScanning.value = true
if (isScanning.value) {
return;
}
isScanning.value = true;
try {
updateSeconds()
//定时器
timer = window.setInterval(() => {
updateSeconds();
}, 1000);
//发送
ensureElapsedTimer();
const response = await sendBackgroundMessage<CrawlTaskState>({
action: 'START_CRAWL',
payload: {platformId: selectedPlatformId.value},
payload: { platformId: selectedPlatformId.value },
});
if (response.data) {
crawlState.value = response.data;
if (response.ok) {
syncCrawlState(response.data ?? null);
} else {
console.error('[crawl] start failed', response.error);
}
} finally {
isScanning.value = false;
}
};
const handleCancelCrawl = async () => {
const response = await sendBackgroundMessage<CrawlTaskState | null>({ action: 'CANCEL_CRAWL' });
if (response.ok) {
syncCrawlState(response.data ?? null);
return;
}
console.error('[crawl] cancel failed', response.error);
await refreshCrawlState();
};
function syncCrawlState(state: CrawlTaskState | null) {
crawlState.value = state;
updateSeconds();
if (state && ACTIVE_STATUSES.has(state.status)) {
ensureElapsedTimer();
return;
}
clearElapsedTimer();
}
function ensureElapsedTimer() {
if (timer !== undefined) {
return;
}
timer = window.setInterval(() => {
updateSeconds();
}, 1000);
}
function clearElapsedTimer() {
if (timer === undefined) {
return;
}
window.clearInterval(timer);
timer = undefined;
}
/**
* 更新时间
*/
function updateSeconds() {
if (!crawlState.value) {
elapsedSeconds.value = 0;
@@ -53,33 +91,54 @@ export const useScan = () => {
elapsedSeconds.value = Math.max(0, Math.floor((Date.now() - crawlState.value.startedAt) / 1000));
}
/**
* 同步爬取状态
*/
async function refreshCrawlState() {
const response = await sendBackgroundMessage<CrawlTaskState | null>({action: 'GET_CRAWL_STATE'});
const response = await sendBackgroundMessage<CrawlTaskState | null>({ action: 'GET_CRAWL_STATE' });
if (response.data) {
crawlState.value = response.data ?? null;
updateSeconds();
if (response.ok) {
syncCrawlState(response.data ?? null);
}
}
function handleStorageChanged(changes: Record<string, chrome.storage.StorageChange>, areaName: string) {
if (areaName !== 'local') {
return;
}
const change = changes[CRAWL_TASK_STORAGE_KEY];
if (!change) {
return;
}
syncCrawlState(isCrawlTaskState(change.newValue) ? change.newValue : null);
}
onMounted(async () => {
await refreshCrawlState()
})
await refreshCrawlState();
if (typeof chrome !== 'undefined' && chrome.storage?.onChanged) {
chrome.storage.onChanged.addListener(handleStorageChanged);
}
});
onUnmounted(() => {
if (timer) {
window.clearInterval(timer);
clearElapsedTimer();
if (typeof chrome !== 'undefined' && chrome.storage?.onChanged) {
chrome.storage.onChanged.removeListener(handleStorageChanged);
}
})
});
return {
selectedPlatformId,
isScanning,
crawlState,
handleScan,
handleCancelCrawl,
elapsedSeconds,
}
}
};
};
function isCrawlTaskState(value: unknown): value is CrawlTaskState {
return typeof value === 'object' && value !== null && 'id' in value && 'steps' in value;
}