From 3f53a6c7d0443587b26fa578d3f50ff78046c497 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A7=8B=E4=BA=8E=E5=88=9D=E8=A7=81?= <752204717@qq.com> Date: Mon, 30 Mar 2026 13:07:33 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=B3=E9=94=AE=E5=AD=97=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/index.js | 4 +- src/components/common/Sidebar.vue | 21 +- src/components/common/langs/en.js | 93 +++- src/components/common/langs/zh.js | 93 +++- src/components/page/autoPromotion.vue | 95 +++- src/components/page/autoPromotionLogs.vue | 90 ++- .../autoPromotion/AutoPromotionWizard.vue | 29 +- .../AutoPromotionWizardContent.vue | 165 +++++- .../page/components/email/TmrEmailEditor.vue | 411 ++++++++------ src/components/page/crawlTaskMonitor.vue | 511 ++++++++++++++++++ src/components/page/expertDatabase.vue | 26 +- src/components/page/mailboxMould.vue | 1 + src/router/index.js | 7 + 13 files changed, 1349 insertions(+), 197 deletions(-) create mode 100644 src/components/page/crawlTaskMonitor.vue diff --git a/src/api/index.js b/src/api/index.js index 487fb66..525753d 100644 --- a/src/api/index.js +++ b/src/api/index.js @@ -19,8 +19,8 @@ const service = axios.create({ // baseURL: 'https://submission.tmrjournals.com/', //正式 记得切换 // baseURL: 'http://www.tougao.com/', //测试本地 记得切换 // baseURL: 'http://192.168.110.110/tougao/public/index.php/', - baseURL: '/api', //本地 - // baseURL: '/', //正式 + // baseURL: '/api', //本地 + baseURL: '/', //正式 }); diff --git a/src/components/common/Sidebar.vue b/src/components/common/Sidebar.vue index eb8db1a..7ecebb4 100644 --- a/src/components/common/Sidebar.vue +++ b/src/components/common/Sidebar.vue @@ -157,9 +157,18 @@ - - {{ $t('sidebar.expertDatabase') }} - + + + + {{ $t('sidebar.expertList') }} + + + {{ $t('sidebar.crawlTasks') }} + + + {{ $t('sidebar.mailboxManagement') }} @@ -181,12 +190,6 @@ {{ $t('sidebar.ReArticles') }} - - {{ $t('sidebar.scholarCrawlers') }} - - - {{ $t('sidebar.crawlerKeywords') }} - Management System diff --git a/src/components/common/langs/en.js b/src/components/common/langs/en.js index c5c0802..6867b42 100644 --- a/src/components/common/langs/en.js +++ b/src/components/common/langs/en.js @@ -278,6 +278,9 @@ const en = { scholarCrawlers: 'Scholar Crawlers', crawlerKeywords: 'Crawl Keywords', expertDatabase: 'Expert Database', + keywordManagement: 'Keyword Management', + crawlTasks: 'Crawl Tasks', + expertList: 'Expert List', autoPromotion: 'Auto Promotion', ReArticles: 'Rejected Manuscripts', // 被拒稿件 editorialBoard: 'Boss System', @@ -295,6 +298,7 @@ const en = { expertDatabase: { fieldSelectPlaceholder: 'Please select field', keywordPlaceholder: 'Name / Email / Affiliation', + fieldPlaceholder: 'Please enter field', searchBtn: 'Search', resetBtn: 'Reset', downloadExcelBtn: 'Download Excel', @@ -311,7 +315,7 @@ const en = { emailLabel: 'Email:', acquisitionTimeLabel: 'Acquisition Time:' }, - exportWarn: 'Please select a research area or enter a keyword before exporting.', + exportWarn: 'Please select a research area, enter a keyword, or enter a field before exporting.', exportFailed: 'Export failed' }, mailboxConfig: { @@ -583,6 +587,83 @@ colTitle: 'Template title', crawlFail: 'Failed to start crawl', exportFail: 'Failed to export', }, + crawlTask: { + pageTitle: 'Task Monitor', + pageDesc: 'View currently running and completed crawl tasks.', + exportData: 'Export Data', + startCrawl: 'Start Crawl', + searchPlaceholder: 'Search by keyword...', + searchBtn: 'Search', + allKeywords: 'All Keywords', + enabled: 'Enabled', + disabled: 'Disabled', + allStatus: 'All Status', + statusCrawling: 'Crawling', + statusDone: 'Done', + statusPaused: 'Paused', + statusError: 'Error', + source: 'Source', + startTime: 'Start Time', + endTime: 'End Time', + progress: 'Progress', + totalPages: 'Total Pages', + crawledPages: 'Crawled Pages', + expertCountLabel: 'Experts Stored', + expertCount: 'Expert Count', + created: 'Created', + completed: 'Completed', + updated: 'Updated', + viewDetail: 'View Detail', + viewLogs: 'View Logs', + pause: 'Pause', + resume: 'Resume', + restart: 'Restart', + delete: 'Delete', + deleteConfirm: 'Are you sure to delete this task? This cannot be undone.', + confirmTitle: 'Confirm', + confirmOk: 'OK', + confirmCancel: 'Cancel', + operationSuccess: 'Operation succeeded', + operationFail: 'Operation failed', + operationRetry: 'Operation failed, please try again later', + crawlStarted: 'Crawl task started', + crawlFail: 'Failed to start crawl', + exportFail: 'Failed to export', + detailTitle: 'Task Detail', + basicInfo: 'Basic Information', + taskName: 'Task Name', + status: 'Status', + resultSummary: 'Result Summary', + totalFound: 'Total Found', + newAdded: 'New Added', + duplicates: 'Duplicates', + failed: 'Failed', + logsTitle: 'Run Logs', + noLogs: 'No logs yet', + noData: 'No tasks', + emptyResult: 'No matching task records found', + addKeyword: 'Add Keyword', + keyword: 'Keyword', + keywordPlaceholder: 'Enter keyword, e.g.: Infectious Diseases', + runOnce: 'Single Crawl', + runOnceBtn: 'Single Crawl', + runOnceLoading: 'Crawling...', + yes: 'Yes', + no: 'No', + cancel: 'Cancel', + confirm: 'OK', + enterKeyword: 'Please enter a keyword', + addKeywordSuccess: 'Keyword added successfully', + addKeywordFailed: 'Failed to add keyword', + runOnceSuccess: 'Single crawl triggered', + runOnceFailed: 'Failed to trigger single crawl', + disabledMsg: 'Disabled', + enabledMsg: 'Enabled', + pauseFailed: 'Failed to pause', + resumeFailed: 'Failed to resume', + missingKeyword: 'Missing keyword, cannot perform single crawl', + restartSuccess: 'Sync restarted (local mock)', + }, mailboxSend: { title: 'Write mail', to: 'To:', @@ -955,6 +1036,16 @@ colTitle: 'Template title', styleName: 'Style Name', defaultStyle: 'Default', changeTemplate: 'Change Template', + selectPromotionFields: 'Select Promotion Fields', + choosePromotionFields: 'Choose Fields', + selectedCount: 'Selected {count}', + selectAll: 'Select All', + clearAll: 'Clear All', + selectPromotionFieldsTip: 'Multiple selection supported; leave empty for no field restriction.', + fieldSearchPlaceholder: 'Search promotion fields', + noFieldMatch: 'No matching fields', + confirm: 'Confirm', + fieldsSaved: 'Promotion fields saved', confirmAndEnable: 'Confirm and Enable', onlySaveConfig: 'Save configuration only', enableNowNextDay: 'Enable auto promotion now (starts next day)' diff --git a/src/components/common/langs/zh.js b/src/components/common/langs/zh.js index 9c473c9..a57f900 100644 --- a/src/components/common/langs/zh.js +++ b/src/components/common/langs/zh.js @@ -266,6 +266,9 @@ const zh = { scholarCrawlers: '学者数据库', crawlerKeywords: '抓取关键词配置', expertDatabase: '专家库', + keywordManagement: '关键词管理', + crawlTasks: '抓取任务', + expertList: '专家列表', autoPromotion: '自动推广', ReArticles: '被拒稿件', // 被拒稿件 editorialBoard: '编委管理', @@ -284,6 +287,7 @@ const zh = { expertDatabase: { fieldSelectPlaceholder: '请选择研究领域', keywordPlaceholder: '姓名 / 邮箱 / 单位', + fieldPlaceholder: '请输入领域 field', searchBtn: '搜索', resetBtn: '重置', downloadExcelBtn: '下载 Excel', @@ -300,7 +304,7 @@ const zh = { emailLabel: '邮箱:', acquisitionTimeLabel: '采集时间:' }, - exportWarn: '请选择研究领域或输入关键词后再导出。', + exportWarn: '请选择研究领域或输入关键词或领域 field 后再导出。', exportFailed: '导出失败' }, mailboxConfig: { @@ -572,6 +576,83 @@ const zh = { crawlFail: '启动抓取失败', exportFail: '导出失败', }, + crawlTask: { + pageTitle: '任务监控', + pageDesc: '查看当前正在运行和已完成的抓取任务。', + exportData: '导出数据', + startCrawl: '开始抓取', + searchPlaceholder: '按关键词搜索...', + searchBtn: '搜索', + allKeywords: '全部关键词', + enabled: '启用', + disabled: '停用', + allStatus: '全部状态', + statusCrawling: '抓取中', + statusDone: '已完成', + statusPaused: '已暂停', + statusError: '异常', + source: '来源', + startTime: '开始时间', + endTime: '结束时间', + progress: '进度', + totalPages: '总页数', + crawledPages: '已抓取页数', + expertCountLabel: '入库专家数', + expertCount: '专家数量', + created: '创建', + completed: '完成', + updated: '更新', + viewDetail: '查看详情', + viewLogs: '查看日志', + pause: '暂停', + resume: '继续', + restart: '重新抓取', + delete: '删除', + deleteConfirm: '确定删除该任务吗?删除后无法恢复。', + confirmTitle: '提示', + confirmOk: '确定', + confirmCancel: '取消', + operationSuccess: '操作成功', + operationFail: '操作失败', + operationRetry: '操作失败,请稍后重试', + crawlStarted: '抓取任务已启动', + crawlFail: '启动抓取失败', + exportFail: '导出失败', + detailTitle: '任务详情', + basicInfo: '基本信息', + taskName: '任务名称', + status: '状态', + resultSummary: '抓取结果', + totalFound: '发现总数', + newAdded: '新增', + duplicates: '重复', + failed: '失败', + logsTitle: '运行日志', + noLogs: '暂无日志', + noData: '暂无任务', + emptyResult: '未发现匹配的任务记录', + addKeyword: '新建关键词', + keyword: '关键词', + keywordPlaceholder: '请输入关键词,如:Infectious Diseases', + runOnce: '单次抓取', + runOnceBtn: '单次抓取', + runOnceLoading: '抓取中...', + yes: '是', + no: '否', + cancel: '取消', + confirm: '确定', + enterKeyword: '请输入关键词', + addKeywordSuccess: '新增关键词成功', + addKeywordFailed: '新增关键词失败', + runOnceSuccess: '已触发单次抓取', + runOnceFailed: '单次抓取触发失败', + disabledMsg: '已停用', + enabledMsg: '已启用', + pauseFailed: '暂停失败', + resumeFailed: '恢复失败', + missingKeyword: '缺少关键词,无法执行单次抓取', + restartSuccess: '已重启同步(本地模拟)', + }, mailboxSend: { title: '写邮件', to: '收件人:', @@ -940,6 +1021,16 @@ const zh = { styleName: '风格名称', defaultStyle: '默认风格', changeTemplate: '更换模版', + selectPromotionFields: '选择推广领域', + choosePromotionFields: '选择领域', + selectedCount: '已选 {count} 项', + selectAll: '全选', + clearAll: '取消全选', + selectPromotionFieldsTip: '可多选;未选择则不限制推广领域。', + fieldSearchPlaceholder: '搜索推广领域', + noFieldMatch: '没有匹配的领域', + confirm: '确定', + fieldsSaved: '推广领域已保存', confirmAndEnable: '确认并开启', onlySaveConfig: '仅保存配置', enableNowNextDay: '立即激活自动推广(次日开始自动推广)' diff --git a/src/components/page/autoPromotion.vue b/src/components/page/autoPromotion.vue index 4f1bdd8..1f4b7bb 100644 --- a/src/components/page/autoPromotion.vue +++ b/src/components/page/autoPromotion.vue @@ -98,6 +98,10 @@ :visible.sync="showWizardDialog" :config="wizardConfig" :wizardStartDate.sync="wizardStartDate" + :selectedFieldIds.sync="selectedFieldIds" + :availableFields="availableFields" + :fieldsLoading="fieldsLoading" + :fieldsSaving="fieldsSaving" :currentJournalName="wizardJournal ? wizardJournal.title : ''" :selectedTemplateThumbHtml="selectedTemplateThumbHtml" :selectedTemplateName="selectedTemplateName" @@ -105,6 +109,7 @@ :saving="saving" :title="`${$t('autoPromotion.journalManage')}: ${wizardJournal ? wizardJournal.title : ''}`" @open-template-selector="openTemplateSelector" + @confirm-fields="savePromotionFieldsNow" @cancel="showWizardDialog = false" @confirm="saveWizardConfig" /> @@ -150,6 +155,10 @@ export default { selectedTemplateThumbHtml: '', selectedTemplateName: '', selectedStyleName: '', + selectedFieldIds: [], + availableFields: [], + fieldsLoading: false, + fieldsSaving: false, templateDialogInitialStyleId: '', templateDialogInitialTemplateId: '', templateNameMap: {}, @@ -306,6 +315,81 @@ export default { ? this.$t('autoPromotion.goManagePlan') : this.$t('autoPromotion.startPlan'); }, + findArray(obj) { + if (Array.isArray(obj)) return obj; + if (!obj || typeof obj !== 'object') return null; + const keys = ['list', 'fields', 'rows', 'items', 'data', 'result']; + for (const k of keys) { + if (Array.isArray(obj[k])) return obj[k]; + } + const values = Object.values(obj); + if (values.length && Array.isArray(values[0])) return values[0]; + return null; + }, + async loadPromotionFields(journalId) { + this.fieldsLoading = true; + this.availableFields = []; + this.selectedFieldIds = []; + try { + const availableRes = await this.$api.post('api/email_client/getAvailableFields', { journal_id: String(journalId) }); + console.log('[getAvailableFields] raw response:', JSON.stringify(availableRes)); + + const availablePayload = (availableRes && availableRes.data) || availableRes || {}; + let availableArr = this.findArray(availablePayload); + if (!availableArr) { + availableArr = Array.isArray(availablePayload) ? availablePayload : []; + } + + this.availableFields = availableArr.map((item, idx) => { + const id = item.expert_fetch_id || item.fetch_id || item.id || item.field_id || (idx + 1); + const label = item.field || item.title || item.name || item.label || String(id); + return { id: String(id), label }; + }); + console.log('[getAvailableFields] parsed fields:', this.availableFields.length, this.availableFields.slice(0, 3)); + } catch (e) { + console.error('[getAvailableFields] error:', e); + this.availableFields = []; + } + + try { + const selectedRes = await this.$api.post('api/email_client/getJournalPromotionFields', { journal_id: String(journalId) }); + console.log('[getJournalPromotionFields] raw response:', JSON.stringify(selectedRes)); + + const selectedPayload = (selectedRes && selectedRes.data) || selectedRes || {}; + let selectedArr = this.findArray(selectedPayload); + + if (selectedArr) { + this.selectedFieldIds = selectedArr.map((it) => { + return String(it.expert_fetch_id || it.fetch_id || it.id || it.field_id || it); + }); + } else if (typeof selectedPayload === 'string') { + this.selectedFieldIds = selectedPayload.split(',').map((s) => s.trim()).filter(Boolean); + } else if (typeof selectedPayload.fetch_ids === 'string') { + this.selectedFieldIds = selectedPayload.fetch_ids.split(',').map((s) => s.trim()).filter(Boolean); + } + console.log('[getJournalPromotionFields] parsed selected:', this.selectedFieldIds); + } catch (e) { + console.error('[getJournalPromotionFields] error:', e); + this.selectedFieldIds = []; + } + + this.fieldsLoading = false; + }, + async savePromotionFieldsNow() { + if (!this.wizardJournal || !this.wizardJournal.journal_id) return; + this.fieldsSaving = true; + try { + await this.$api.post('api/email_client/setJournalPromotionFields', { + journal_id: String(this.wizardJournal.journal_id), + fetch_ids: (this.selectedFieldIds || []).join(',') + }); + this.$message.success(this.$t('autoPromotion.fieldsSaved')); + } catch (e) { + this.$message.error(this.$t('autoPromotion.saveFailed')); + } finally { + this.fieldsSaving = false; + } + }, async handleSolicitAction(journal) { if (!this.isSolicitConfigured(journal)) { @@ -344,7 +428,7 @@ export default { this.openDetail(journal); }, - openWizardForJournal(journal) { + async openWizardForJournal(journal) { this.wizardJournal = journal; const s = journal.solicit || {}; this.wizardConfig = { @@ -355,6 +439,11 @@ export default { this.selectedTemplateName = s.templateName || ''; this.selectedStyleName = s.styleName || ''; this.selectedTemplateThumbHtml = `
${s.html || ''}
`; + this.selectedFieldIds = []; + this.availableFields = []; + if (journal && journal.journal_id) { + await this.loadPromotionFields(journal.journal_id); + } this.showWizardDialog = true; }, @@ -387,6 +476,10 @@ export default { start_promotion: this.wizardConfig.enabled ? '1' : '0', user_id: userId }); + await this.$api.post('api/email_client/setJournalPromotionFields', { + journal_id: String(this.wizardJournal.journal_id), + fetch_ids: (this.selectedFieldIds || []).join(',') + }); await this.refreshJournalByDetail(this.wizardJournal); this.$message.success(this.$t('autoPromotion.configSaved')); this.showWizardDialog = false; diff --git a/src/components/page/autoPromotionLogs.vue b/src/components/page/autoPromotionLogs.vue index 4281b68..eb2f421 100644 --- a/src/components/page/autoPromotionLogs.vue +++ b/src/components/page/autoPromotionLogs.vue @@ -40,6 +40,10 @@ mode="inline" :config="config" :wizardStartDate.sync="wizardStartDate" + :selectedFieldIds.sync="selectedFieldIds" + :availableFields="availableFields" + :fieldsLoading="fieldsLoading" + :fieldsSaving="fieldsSaving" :currentJournalName="currentJournalName" :selectedTemplateThumbHtml="selectedTemplateThumbHtml" :selectedTemplateName="selectedTemplateName" @@ -47,6 +51,7 @@ :saving="saving" :title="$t('autoPromotion.title')" @open-template-selector="showTemplateDialog = true" + @confirm-fields="savePromotionFieldsNow" @confirm="completeInitialization" /> @@ -204,6 +209,10 @@ :visible.sync="showWizardDialog" :config="config" :wizardStartDate.sync="wizardStartDate" + :selectedFieldIds.sync="selectedFieldIds" + :availableFields="availableFields" + :fieldsLoading="fieldsLoading" + :fieldsSaving="fieldsSaving" :currentJournalName="currentJournalName" :selectedTemplateThumbHtml="selectedTemplateThumbHtml" :selectedTemplateName="selectedTemplateName" @@ -211,6 +220,7 @@ :saving="saving" :title="$t('autoPromotion.title')" @open-template-selector="showTemplateDialog = true" + @confirm-fields="savePromotionFieldsNow" @cancel="showWizardDialog = false" @confirm="completeInitialization" /> @@ -328,6 +338,10 @@ export default { templateDialogInitialStyleId: '', templateDialogInitialTemplateId: '', togglingTaskId: '', + selectedFieldIds: [], + availableFields: [], + fieldsLoading: false, + fieldsSaving: false, previewForm: { id: '', email: '', @@ -453,6 +467,9 @@ export default { this.loading = true; try { await this.fetchJournalDetail(); + if (this.selectedJournalId) { + this.loadPromotionFields(this.selectedJournalId); + } if (this.config.initialized) { await this.fetchTemplates(); await this.fetchList(); @@ -524,13 +541,74 @@ export default { }, // 打开向导弹窗:用于“修改期刊自动推广配置” - openWizardDialog() { - this.showWizardDialog = true; + findArray(obj) { + if (Array.isArray(obj)) return obj; + if (!obj || typeof obj !== 'object') return null; + const keys = ['list', 'fields', 'rows', 'items', 'data', 'result']; + for (const k of keys) { + if (Array.isArray(obj[k])) return obj[k]; + } + const values = Object.values(obj); + if (values.length && Array.isArray(values[0])) return values[0]; + return null; + }, + async loadPromotionFields(journalId) { + this.fieldsLoading = true; + this.availableFields = []; + this.selectedFieldIds = []; + try { + const availableRes = await this.$api.post('api/email_client/getAvailableFields', { journal_id: String(journalId) }); + const availablePayload = (availableRes && availableRes.data) || availableRes || {}; + let availableArr = this.findArray(availablePayload); + if (!availableArr) availableArr = Array.isArray(availablePayload) ? availablePayload : []; + this.availableFields = availableArr.map((item, idx) => { + const id = item.expert_fetch_id || item.fetch_id || item.id || item.field_id || (idx + 1); + const label = item.field || item.title || item.name || item.label || String(id); + return { id: String(id), label }; + }); + } catch (e) { + this.availableFields = []; + } + try { + const selectedRes = await this.$api.post('api/email_client/getJournalPromotionFields', { journal_id: String(journalId) }); + const selectedPayload = (selectedRes && selectedRes.data) || selectedRes || {}; + let selectedArr = this.findArray(selectedPayload); + if (selectedArr) { + this.selectedFieldIds = selectedArr.map((it) => String(it.expert_fetch_id || it.fetch_id || it.id || it.field_id || it)); + } else if (typeof selectedPayload === 'string') { + this.selectedFieldIds = selectedPayload.split(',').map((s) => s.trim()).filter(Boolean); + } else if (typeof selectedPayload.fetch_ids === 'string') { + this.selectedFieldIds = selectedPayload.fetch_ids.split(',').map((s) => s.trim()).filter(Boolean); + } + } catch (e) { + this.selectedFieldIds = []; + } + this.fieldsLoading = false; + }, + async savePromotionFieldsNow() { + if (!this.selectedJournalId) return; + this.fieldsSaving = true; + try { + await this.$api.post('api/email_client/setJournalPromotionFields', { + journal_id: String(this.selectedJournalId), + fetch_ids: (this.selectedFieldIds || []).join(',') + }); + this.$message.success(this.$t('autoPromotion.fieldsSaved')); + } catch (e) { + this.$message.error(this.$t('autoPromotion.saveFailed')); + } finally { + this.fieldsSaving = false; + } + }, + async openWizardDialog() { this.wizardStep = 0; - // 尽量从已加载的 config 里取开始日期(没有就保持空) if (this.config && this.config.start_date) { this.wizardStartDate = this.config.start_date; } + if (this.selectedJournalId) { + await this.loadPromotionFields(this.selectedJournalId); + } + this.showWizardDialog = true; }, // 切换期刊逻辑 @@ -622,10 +700,14 @@ export default { default_style_id: String(this.config.defaultStyleId || ''), start_promotion: this.config.enabled ? '1' : '0' }; - this.config.initialized = true; // 切换到管理模式 + this.config.initialized = true; this.showWizardDialog = false; this.fetchList(); await this.$api.post(API.saveConfig, payload); + await this.$api.post('api/email_client/setJournalPromotionFields', { + journal_id: String(this.selectedJournalId || ''), + fetch_ids: (this.selectedFieldIds || []).join(',') + }); this.$message.success(this.$t('autoPromotionLogs.configUpdated')); } finally { this.saving = false; diff --git a/src/components/page/components/autoPromotion/AutoPromotionWizard.vue b/src/components/page/components/autoPromotion/AutoPromotionWizard.vue index 8f14345..a3f9e66 100644 --- a/src/components/page/components/autoPromotion/AutoPromotionWizard.vue +++ b/src/components/page/components/autoPromotion/AutoPromotionWizard.vue @@ -3,7 +3,7 @@ v-if="mode === 'dialog'" :visible.sync="dialogVisible" :close-on-click-modal="false" - width="1000px" + width="1200px" top="5vh" destroy-on-close :title="title" @@ -16,7 +16,12 @@ :selectedTemplateThumbHtml="selectedTemplateThumbHtml" :selectedTemplateName="selectedTemplateName" :selectedStyleName="selectedStyleName" + :availableFields="availableFields" + :fieldsLoading="fieldsLoading" + :fieldsSaving="fieldsSaving" + :selectedFieldIds.sync="selectedFieldIdsProxy" @open-template-selector="emitOpenTemplateSelector" + @confirm-fields="emitConfirmFields" @update:wizardStartDate="onWizardStartDateUpdate" /> @@ -43,7 +48,12 @@ :selectedTemplateThumbHtml="selectedTemplateThumbHtml" :selectedTemplateName="selectedTemplateName" :selectedStyleName="selectedStyleName" + :availableFields="availableFields" + :fieldsLoading="fieldsLoading" + :fieldsSaving="fieldsSaving" + :selectedFieldIds.sync="selectedFieldIdsProxy" @open-template-selector="emitOpenTemplateSelector" + @confirm-fields="emitConfirmFields" @update:wizardStartDate="onWizardStartDateUpdate" /> + + +
+ + {{ $t('autoPromotion.selectAll') }} + {{ $t('autoPromotion.clearAll') }} +
+
+ + + {{ f.label }} + + +
+ {{ $t('autoPromotion.noFieldMatch') }} +
+
+ + {{ $t('autoPromotion.cancel') }} + {{ $t('autoPromotion.confirm') }} + +
- - \ No newline at end of file +} + + + \ No newline at end of file diff --git a/src/components/page/crawlTaskMonitor.vue b/src/components/page/crawlTaskMonitor.vue new file mode 100644 index 0000000..e6d12f6 --- /dev/null +++ b/src/components/page/crawlTaskMonitor.vue @@ -0,0 +1,511 @@ + + + + + \ No newline at end of file diff --git a/src/components/page/expertDatabase.vue b/src/components/page/expertDatabase.vue index f134573..cb4e0b1 100644 --- a/src/components/page/expertDatabase.vue +++ b/src/components/page/expertDatabase.vue @@ -29,6 +29,15 @@ style="width: 260px" /> + + + + @@ -107,6 +116,7 @@ export default { query: { major_id: null, keyword: '', + field: '', pageIndex: 1, pageSize: 10 }, @@ -167,6 +177,7 @@ export default { const params = { major_id: this.query.major_id, keyword: this.query.keyword, + field: this.query.field, pageIndex: this.query.pageIndex, pageSize: this.query.pageSize }; @@ -202,6 +213,7 @@ export default { this.query = { major_id: null, keyword: '', + field: '', pageIndex: 1, pageSize: 10 }; @@ -217,7 +229,7 @@ export default { this.fetchList(); }, async handleExport() { - if (!this.query.major_id && !this.query.keyword) { + if (!this.query.major_id && !this.query.keyword && !this.query.field) { this.$message.warning(this.$t('expertDatabase.exportWarn')); return; } @@ -225,7 +237,8 @@ export default { try { const params = { major_id: this.query.major_id, - keyword: this.query.keyword + keyword: this.query.keyword, + field: this.query.field }; const res = await this.$api.post('api/expert_manage/exportExcel', params); if (res && res.code === 0 && res.data && res.data.file_url) { @@ -259,6 +272,11 @@ export default { margin: 0 20px; margin-left: 0; } +.form-line-break { + flex-basis: 100%; + width: 100%; + height: 0; +} .actions { white-space: nowrap; } @@ -269,11 +287,11 @@ export default { margin-top: 15px; text-align: right; } -/deep/ .dark-table-header th { +::v-deep .dark-table-header th { background-color: #f5f7fa; font-weight: 600; } -/deep/ .el-form-item--mini.el-form-item, +::v-deep .el-form-item--mini.el-form-item, .el-form-item--small.el-form-item { margin-bottom: 0; } diff --git a/src/components/page/mailboxMould.vue b/src/components/page/mailboxMould.vue index 737528e..4189eaa 100644 --- a/src/components/page/mailboxMould.vue +++ b/src/components/page/mailboxMould.vue @@ -395,5 +395,6 @@ export default { padding: 10px; border: 1px solid #eee; background: #fff; + box-sizing: border-box; } diff --git a/src/router/index.js b/src/router/index.js index b99d0bb..a3091a8 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1097,6 +1097,13 @@ export default new Router({ title: 'Scholar Database' } }, + { + path: '/crawlTaskMonitor', + component: () => import('../components/page/crawlTaskMonitor'), + meta: { + title: 'Crawl Task Monitor' + } + }, { path: '/scholarCrawlersKeywords', component: () => import('../components/page/scholarCrawlersKeywords'),