diff --git a/src/components/page/crawlTaskMonitor.vue b/src/components/page/crawlTaskMonitor.vue index 16a9400..7c5fe9d 100644 --- a/src/components/page/crawlTaskMonitor.vue +++ b/src/components/page/crawlTaskMonitor.vue @@ -1,7 +1,5 @@ @@ -171,212 +151,107 @@ export default { list: [], addDialogVisible: false, addLoading: false, - runOnceLoading: false, runOnceLoadingId: null, - addForm: { - field: '', - runNow: false - } + addForm: { field: '', runNow: false } }; }, created() { this.fetchList(); }, methods: { - calcProgress(lastPage, totalPages) { - const current = Number(lastPage || 0); - const total = Number(totalPages || 0); - if (total <= 0) return 0; - let percent = (current / total) * 100; - if (percent > 100) percent = 100; - return Number(percent.toFixed(2)); + /** 停止态用灰条,避免 exception 大红;运行中未满用蓝,满格用绿 */ + progressStrokeColor(item) { + if (item.state !== 'running') return '#c0c4cc'; + if (item.progress >= 100) return '#67c23a'; + return '#409eff'; }, + // 数据标准化逻辑 normalizeItem(item) { - const totalPages = Number(item.total_pages || 0); - const lastPage = Number(item.last_page || 0); - const percent = this.calcProgress(lastPage, totalPages); - const stateNum = Number(item.state); - const stateClass = stateNum === 0 ? 'running' : 'paused'; - const source = (item.source || '').toUpperCase() === 'PUBMED' ? 'PubMed' : (item.source || '-'); + const total = Number(item.total_pages || 0); + const current = Number(item.last_page || 0); + let progress = total > 0 ? (current / total) * 100 : 0; + return { - id: item.expert_fetch_id || item.id || 0, - field: item.field || '', + id: item.expert_fetch_id || item.id, + task_name: item.field || '-', + source: (item.source || 'PubMed'), expert_count: item.expert_count || 0, - task_name: item.field ? `${item.field}`:'-', - source, - state: stateClass, - stateClass, - progress: percent, - create_time: item.ctime_text || '-', - update_time: item.last_time_text || '-', - duration: '', - total_pages: Number(item.total_pages || 0), - last_page: Number(item.last_page || 0), - duplicates: 0, - failed: 0 + total_pages: total, + last_page: current, + progress: Number(progress.toFixed(1)), + state: Number(item.state) === 0 ? 'running' : 'paused', + create_time: item.ctime_text || '-' }; }, async fetchList() { this.loading = true; try { const params = { - keyword: this.searchText || '', + keyword: this.searchText, pageIndex: this.currentPage, - pageSize: this.pageSize + pageSize: this.pageSize, + state: this.filterStatus !== '' ? this.filterStatus : undefined }; - if (this.filterStatus !== '') { - params.state = this.filterStatus; - } const res = await this.$api.post('api/expert_manage/getFetchList', params); - if (res && res.code === 0 && res.data) { - const rows = res.data.list || []; - this.list = rows.map(this.normalizeItem); - this.total = Number(res.data.total || rows.length || 0); - } else { - this.list = []; - this.total = 0; + if (res.code === 0) { + this.list = res.data.list.map(this.normalizeItem); + this.total = res.data.total; } - } catch (e) { - this.list = []; - this.total = 0; } finally { this.loading = false; } }, - handleFilter() { - this.currentPage = 1; - this.fetchList(); - }, - handleSearchClick() { - this.handleFilter(); - }, - handleSizeChange(val) { - this.pageSize = val; - this.currentPage = 1; - this.fetchList(); - }, - handlePageChange(val) { - this.currentPage = val; - this.fetchList(); - window.scrollTo({ top: 0, behavior: 'smooth' }); - }, - resetQuery() { - this.searchText = ''; - this.filterStatus = ''; - this.currentPage = 1; - this.fetchList(); - }, - openAddDialog() { - this.addDialogVisible = true; - }, - resetAddForm() { - this.addLoading = false; - this.runOnceLoading = false; - this.addForm = { - field: '', - runNow: false - }; - }, - async submitAddKeyword() { - const field = (this.addForm.field || '').trim(); - if (!field) { - this.$message.warning(this.$t('crawlTask.enterKeyword')); - return; - } - const runNow = !!this.addForm.runNow; - this.addLoading = true; - try { - const addRes = await this.$api.post('api/expert_manage/addFetchField', { field }); - if (!addRes || addRes.code !== 0) { - this.$message.error((addRes && addRes.msg) || this.$t('crawlTask.addKeywordFailed')); - return; - } - - this.$message.success(this.$t('crawlTask.addKeywordSuccess')); - this.addDialogVisible = false; - this.currentPage = 1; - await this.fetchList(); - - if (runNow) { - // 勾选“单次抓取”时,在列表对应行按钮上显示 loading - const lowerField = field.toLowerCase(); - const target = this.list.find( - (row) => ((row.field || '').trim().toLowerCase() === lowerField) - ); - this.runOnceLoading = true; - this.runOnceLoadingId = target ? target.id : null; - const runRes = await this.$api.post('api/expert_finder/fetchOneField', { field }); - if (!runRes || runRes.code !== 0) { - this.$message.warning((runRes && runRes.msg) || this.$t('crawlTask.runOnceFailed')); - } else { - this.$message.success(this.$t('crawlTask.runOnceSuccess')); - } - await this.fetchList(); - } - } catch (e) { - this.$message.error(this.$t('crawlTask.operationRetry')); - } finally { - this.addLoading = false; - this.runOnceLoading = false; - this.runOnceLoadingId = null; - this.loading = false; - } - }, async handleToggleTask(item) { - const isRunning = item.state === 'running'; - const newState = isRunning ? '1' : '0'; + const isNowRunning = item.state === 'running'; + const newState = isNowRunning ? '0' : '1'; try { - this.loading = true; const res = await this.$api.post('api/expert_manage/editFetchField', { expert_fetch_id: item.id, state: newState }); - if (res && res.code === 0) { - item.state = isRunning ? 'paused' : 'running'; - item.stateClass = item.state; - this.$message.success(isRunning ? this.$t('crawlTask.disabledMsg') : this.$t('crawlTask.enabledMsg')); + if (res.code === 0) { + this.$message.success(isNowRunning ? this.$t('crawlTask.taskRunningMsg') : this.$t('crawlTask.taskStoppedMsg')); } else { - this.$message.error((res && res.msg) || (isRunning ? this.$t('crawlTask.pauseFailed') : this.$t('crawlTask.resumeFailed'))); + item.state = isNowRunning ? 'paused' : 'running'; + this.$message.error(res.msg || this.$t('crawlTask.operationFail')); } } catch (e) { - this.$message.error(isRunning ? this.$t('crawlTask.pauseFailed') : this.$t('crawlTask.resumeFailed')); - } finally { - this.loading = false; + item.state = isNowRunning ? 'paused' : 'running'; } }, - handleRestart(item) { - item.state = 'running'; - item.stateClass = 'running'; - item.progress = 0; - this.$message.success(this.$t('crawlTask.restartSuccess')); - }, async handleRunOnce(item) { - const field = (item.field || item.task_name || '').trim(); - if (!field) { - this.$message.warning(this.$t('crawlTask.missingKeyword')); - return; - } this.runOnceLoadingId = item.id; try { - const res = await this.$api.post('/api/expert_finder/fetchOneField', { field }); - if (res && res.code === 0) { - this.$message.success(this.$t('crawlTask.runOnceSuccess')); - await this.fetchList(); - } else { - this.$message.error((res && res.msg) || this.$t('crawlTask.runOnceFailed')); + const res = await this.$api.post('/api/expert_finder/fetchOneField', { field: item.task_name }); + if (res.code === 0) { + this.$message.success(this.$t('crawlTask.runOnceQueued')); + this.fetchList(); } - } catch (e) { - this.$message.error(this.$t('crawlTask.runOnceFailed')); } finally { this.runOnceLoadingId = null; } }, - handleAction(msg, item) { - if (msg === 'logs') { - this.$message.info(`${this.$t('crawlTask.viewLogs')}: #${item.id}`); - return; - } - this.$message.info(msg); + // 其余分页/弹窗逻辑 + handleFilter() { this.currentPage = 1; this.fetchList(); }, + handleSearchClick() { this.handleFilter(); }, + handleSizeChange(val) { this.pageSize = val; this.fetchList(); }, + handlePageChange(val) { this.currentPage = val; this.fetchList(); }, + openAddDialog() { this.addDialogVisible = true; }, + resetAddForm() { this.addForm = { field: '', runNow: false }; this.addLoading = false; }, + async submitAddKeyword() { + if (!this.addForm.field.trim()) return this.$message.warning(this.$t('crawlTask.enterKeyword')); + this.addLoading = true; + try { + const res = await this.$api.post('api/expert_manage/addFetchField', { field: this.addForm.field }); + if (res.code === 0) { + this.$message.success(this.$t('crawlTask.addKeywordSuccess')); + if (this.addForm.runNow) { + await this.$api.post('api/expert_finder/fetchOneField', { field: this.addForm.field }); + } + this.addDialogVisible = false; + this.fetchList(); + } + } finally { this.addLoading = false; } } } }; @@ -384,145 +259,86 @@ export default { \ No newline at end of file