diff --git a/frontend/crawlab-ui/src/components/core/autoprobe/AutoProbeFieldRule.vue b/frontend/crawlab-ui/src/components/core/autoprobe/AutoProbeFieldRule.vue deleted file mode 100644 index abbedd6f..00000000 --- a/frontend/crawlab-ui/src/components/core/autoprobe/AutoProbeFieldRule.vue +++ /dev/null @@ -1,53 +0,0 @@ - - - - - diff --git a/frontend/crawlab-ui/src/components/core/autoprobe/AutoProbePagePatternDetail.vue b/frontend/crawlab-ui/src/components/core/autoprobe/AutoProbePagePatternDetail.vue index 83eba773..d417b043 100644 --- a/frontend/crawlab-ui/src/components/core/autoprobe/AutoProbePagePatternDetail.vue +++ b/frontend/crawlab-ui/src/components/core/autoprobe/AutoProbePagePatternDetail.vue @@ -1,120 +1,125 @@ - + + + + diff --git a/frontend/crawlab-ui/src/components/index.ts b/frontend/crawlab-ui/src/components/index.ts index edab6953..a0821b45 100644 --- a/frontend/crawlab-ui/src/components/index.ts +++ b/frontend/crawlab-ui/src/components/index.ts @@ -20,12 +20,12 @@ import * as VariableNode from './ui/lexical/nodes/VariableNode'; import AssistantConsole from './core/ai/AssistantConsole.vue'; import AtomMaterialIcon from './ui/icon/AtomMaterialIcon.vue'; import AutoProbeFieldDetail from './core/autoprobe/AutoProbeFieldDetail.vue'; -import AutoProbeFieldRule from './core/autoprobe/AutoProbeFieldRule.vue'; import AutoProbeForm from './core/autoprobe/AutoProbeForm.vue'; import AutoProbeListDetail from './core/autoprobe/AutoProbeListDetail.vue'; import AutoProbePagePatternDetail from './core/autoprobe/AutoProbePagePatternDetail.vue'; import AutoProbePaginationDetail from './core/autoprobe/AutoProbePaginationDetail.vue'; import AutoProbePatternStats from './core/autoprobe/AutoProbePatternStats.vue'; +import AutoProbeSelector from './core/autoprobe/AutoProbeSelector.vue'; import AutoProbeTaskStatus from './core/autoprobe/AutoProbeTaskStatus.vue'; import BlockOptionsDropdownList from './ui/lexical/components/BlockOptionsDropdownList.vue'; import Box from './ui/box/Box.vue'; @@ -276,12 +276,12 @@ export { AssistantConsole as ClAssistantConsole, AtomMaterialIcon as ClAtomMaterialIcon, AutoProbeFieldDetail as ClAutoProbeFieldDetail, - AutoProbeFieldRule as ClAutoProbeFieldRule, AutoProbeForm as ClAutoProbeForm, AutoProbeListDetail as ClAutoProbeListDetail, AutoProbePagePatternDetail as ClAutoProbePagePatternDetail, AutoProbePaginationDetail as ClAutoProbePaginationDetail, AutoProbePatternStats as ClAutoProbePatternStats, + AutoProbeSelector as ClAutoProbeSelector, AutoProbeTaskStatus as ClAutoProbeTaskStatus, BlockOptionsDropdownList as ClBlockOptionsDropdownList, Box as ClBox, diff --git a/frontend/crawlab-ui/src/i18n/lang/en/components/autoprobe.ts b/frontend/crawlab-ui/src/i18n/lang/en/components/autoprobe.ts index f5d4a0ee..9323414c 100644 --- a/frontend/crawlab-ui/src/i18n/lang/en/components/autoprobe.ts +++ b/frontend/crawlab-ui/src/i18n/lang/en/components/autoprobe.ts @@ -74,12 +74,26 @@ const autoprobe: LComponentsAutoProbe = { }, pagePattern: { title: 'Page Pattern', + type: 'Type', name: 'Name', stats: 'Statistics', fields: 'Fields', lists: 'Lists', hasPagination: 'Has Pagination', notFound: 'Page pattern details not found', + fieldCount: 'Fields', + types: { + field: 'Field', + list: 'List', + pagination: 'Pagination', + }, + selector: 'Selector', + selectorType: 'Selector Type', + selectorTypes: { + css: 'CSS', + xpath: 'XPath', + regex: 'Regex', + }, }, }; diff --git a/frontend/crawlab-ui/src/i18n/lang/zh/components/autoprobe.ts b/frontend/crawlab-ui/src/i18n/lang/zh/components/autoprobe.ts index 4b35d9ec..7381eefb 100644 --- a/frontend/crawlab-ui/src/i18n/lang/zh/components/autoprobe.ts +++ b/frontend/crawlab-ui/src/i18n/lang/zh/components/autoprobe.ts @@ -74,12 +74,26 @@ const autoprobe: LComponentsAutoProbe = { }, pagePattern: { title: '页面模式', + type: '类型', name: '名称', stats: '统计', fields: '字段', lists: '列表', hasPagination: '有分页', notFound: '未找到页面模式详情', + fieldCount: '字段数', + types: { + field: '字段', + list: '列表', + pagination: '分页', + }, + selector: '选择器', + selectorType: '选择器类型', + selectorTypes: { + css: 'CSS', + xpath: 'XPath', + regex: '正则表达式', + }, }, }; diff --git a/frontend/crawlab-ui/src/interfaces/i18n/components/autoprobe.d.ts b/frontend/crawlab-ui/src/interfaces/i18n/components/autoprobe.d.ts index 39469c6f..d447fb81 100644 --- a/frontend/crawlab-ui/src/interfaces/i18n/components/autoprobe.d.ts +++ b/frontend/crawlab-ui/src/interfaces/i18n/components/autoprobe.d.ts @@ -74,11 +74,25 @@ interface LComponentsAutoProbe { }; pagePattern: { title: string; + type: string; name: string; stats: string; fields: string; lists: string; hasPagination: string; notFound: string; + fieldCount: string; + types: { + field: string; + list: string; + pagination: string; + }; + selector: string; + selectorType: string; + selectorTypes: { + css: string; + xpath: string; + regex: string; + }; }; } diff --git a/frontend/crawlab-ui/src/interfaces/models/autoprobe.d.ts b/frontend/crawlab-ui/src/interfaces/models/autoprobe.d.ts index 67ba68be..e10281b5 100644 --- a/frontend/crawlab-ui/src/interfaces/models/autoprobe.d.ts +++ b/frontend/crawlab-ui/src/interfaces/models/autoprobe.d.ts @@ -19,12 +19,14 @@ export declare global { type SelectorType = 'css' | 'xpath' | 'regex'; type ExtractType = 'text' | 'attribute' | 'html'; - type PaginationType = 'next' | 'load' | 'scroll'; - interface FieldRule { + interface BaseSelector { name: string; selector_type: SelectorType; selector: string; + } + + interface FieldRule extends BaseSelector { extraction_type: ExtractType; attribute_name?: string; default_value?: string; @@ -44,13 +46,7 @@ export declare global { item_pattern: ItemPattern; } - interface Pagination { - type: PaginationType; - selector_type?: SelectorType; - selector?: string; - max_pages?: number; - start_page?: number; - } + type Pagination = BaseSelector; interface PagePattern { name: string; @@ -84,7 +80,18 @@ export declare global { } interface AutoProbeNavItem extends NavItem { - type?: 'page_pattern' | 'fields' | 'lists' | 'pagination' | 'list' | 'item' | 'field'; + name?: string; + type?: + | 'page_pattern' + | 'fields' + | 'lists' + | 'pagination' + | 'list' + | 'item' + | 'field'; children?: AutoProbeNavItem[]; + fieldCount?: number; + field?: FieldRule; + pagination?: Pagination; } } diff --git a/frontend/crawlab-ui/src/views/autoprobe/detail/tabs/AutoProbeDetailTabPatterns.vue b/frontend/crawlab-ui/src/views/autoprobe/detail/tabs/AutoProbeDetailTabPatterns.vue index 77f9cae6..3fb6c363 100644 --- a/frontend/crawlab-ui/src/views/autoprobe/detail/tabs/AutoProbeDetailTabPatterns.vue +++ b/frontend/crawlab-ui/src/views/autoprobe/detail/tabs/AutoProbeDetailTabPatterns.vue @@ -37,8 +37,10 @@ const processListItem = (list: ListRule): AutoProbeNavItem => { children.push({ id: `${list.name}-${field.name}`, label: field.name, + name: field.name, icon: ['fa', 'tag'], type: 'field', + field, }); }); } @@ -53,6 +55,7 @@ const processListItem = (list: ListRule): AutoProbeNavItem => { return { id: list.name, label: `${list.name} (${children.length})`, + name: list.name, type: 'list', icon: ['fa', 'list'], children, @@ -69,8 +72,10 @@ const computedTreeItems = computed(() => { children.push({ id: field.name, label: field.name, + name: field.name, icon: ['fa', 'tag'], type: 'field', + field, }); }); } @@ -87,8 +92,10 @@ const computedTreeItems = computed(() => { children.push({ id: 'pagination', label: t('components.autoprobe.navItems.pagination'), + name: t('components.autoprobe.navItems.pagination'), type: 'pagination', - icon: ['fa', 'pager'], + icon: ['fa', 'ellipsis-h'], + pagination: pagePagination.value, }); } @@ -96,6 +103,7 @@ const computedTreeItems = computed(() => { { id: 'page', label: `${form.value.page_pattern.name} (${children.length})`, + name: form.value.page_pattern.name, type: 'page_pattern', icon: ['fa', 'network-wired'], children, @@ -120,10 +128,10 @@ const getFieldData = (fieldName: string) => { // Function to get data for a specific navigation item const getNavItemData = (item: AutoProbeNavItem) => { if (!pageData.value) return undefined; - + // Convert to Record to handle dynamic property access const data = pageData.value as Record; - + switch (item.type) { case 'field': // For fields, extract from page data by field name @@ -330,28 +338,25 @@ defineOptions({ name: 'ClAutoProbeDetailTabPatterns' });
{{ @@ -464,7 +469,6 @@ defineOptions({ name: 'ClAutoProbeDetailTabPatterns' }); .content { flex: 1; - padding: 16px; overflow: auto; .detail-panel { diff --git a/frontend/crawlab-ui/src/views/autoprobe/list/useAutoProbeList.tsx b/frontend/crawlab-ui/src/views/autoprobe/list/useAutoProbeList.tsx index cb558725..a2aa0620 100644 --- a/frontend/crawlab-ui/src/views/autoprobe/list/useAutoProbeList.tsx +++ b/frontend/crawlab-ui/src/views/autoprobe/list/useAutoProbeList.tsx @@ -11,7 +11,12 @@ import { FILTER_OP_CONTAINS, TABLE_COLUMN_NAME_ACTIONS, } from '@/constants'; -import { getIconByAction, onListFilterChangeByKey, translate } from '@/utils'; +import { + getIconByAction, + onListFilterChangeByKey, + setupAutoUpdate, + translate, +} from '@/utils'; import { ClNavLink, ClAutoProbeTaskStatus, @@ -30,7 +35,7 @@ const useAutoProbeList = () => { const { commit } = store; const { actionFunctions } = useList(ns, store); - const { deleteByIdConfirm } = actionFunctions; + const { getList, deleteByIdConfirm } = actionFunctions; // nav actions const navActions = computed(() => [ @@ -185,6 +190,8 @@ const useAutoProbeList = () => { ] as TableColumns ); + setupAutoUpdate(getList); + return { ...useList(ns, store), navActions, diff --git a/frontend/crawlab-ui/src/views/system/detail/tabs/SystemDetailTabModels.vue b/frontend/crawlab-ui/src/views/system/detail/tabs/SystemDetailTabModels.vue index 6cb9f840..a4b507cd 100644 --- a/frontend/crawlab-ui/src/views/system/detail/tabs/SystemDetailTabModels.vue +++ b/frontend/crawlab-ui/src/views/system/detail/tabs/SystemDetailTabModels.vue @@ -3,7 +3,12 @@ import { ref, computed, onBeforeMount } from 'vue'; import { ElSpace, ElMessage, ElMessageBox, ElCheckbox } from 'element-plus'; import { ClTag, ClNavLink, ClIcon } from '@/components'; import useRequest from '@/services/request'; -import { getDefaultPagination, plainClone, translate } from '@/utils'; +import { + EMPTY_OBJECT_ID, + getDefaultPagination, + plainClone, + translate, +} from '@/utils'; import { ACTION_DELETE, ACTION_EDIT, @@ -37,7 +42,7 @@ const updateDefaultProviderId = async (id: string) => { default_provider_id: id, }, }; - if (!settingAI.value) { + if (!settingAI.value?._id || settingAI.value._id === EMPTY_OBJECT_ID) { await post('/settings/ai', { data }); } else { await put('/settings/ai', { data });