|
21 | 21 | <div class="add-files-content"> |
22 | 22 | <div class="upload-header"> |
23 | 23 | <div class="source-selector"> |
24 | | - <div class="upload-mode-selector" @click="uploadMode = 'file'" :class="{ active: uploadMode === 'file' }"> |
25 | | - <FileOutlined /> 上传文件 |
26 | | - </div> |
27 | | - <div class="upload-mode-selector" @click="uploadMode = 'url'" :class="{ active: uploadMode === 'url' }"> |
28 | | - <LinkOutlined /> 输入网址 |
29 | | - </div> |
| 24 | + <a-segmented |
| 25 | + v-model:value="uploadMode" |
| 26 | + :options="uploadModeOptions" |
| 27 | + size="large" |
| 28 | + class="source-segmented" |
| 29 | + /> |
30 | 30 | </div> |
31 | 31 | <div class="config-controls"> |
32 | 32 | <a-button type="dashed" @click="showChunkConfigModal" v-if="!isGraphBased"> |
|
35 | 35 | </div> |
36 | 36 | </div> |
37 | 37 |
|
38 | | - <div class="ocr-config"> |
| 38 | + <div class="ocr-config" v-if="uploadMode === 'file'"> |
39 | 39 | <a-form layout="horizontal"> |
40 | 40 | <a-form-item label="使用OCR" name="enable_ocr"> |
41 | 41 | <div class="ocr-controls"> |
|
67 | 67 | </a-form> |
68 | 68 | </div> |
69 | 69 |
|
70 | | - <div class="qa-split-config" v-if="isQaSplitSupported"> |
71 | | - <a-form layout="horizontal"> |
72 | | - <a-form-item label="QA分割模式" name="use_qa_split"> |
73 | | - <div class="toggle-controls"> |
74 | | - <a-switch |
75 | | - v-model:checked="chunkParams.use_qa_split" |
76 | | - style="margin-right: 12px;" |
77 | | - /> |
78 | | - <span class="param-description"> |
79 | | - {{ chunkParams.use_qa_split ? '启用QA分割(忽略chunk大小设置)' : '使用普通分割模式' }} |
80 | | - </span> |
81 | | - </div> |
82 | | - </a-form-item> |
83 | | - <a-form-item |
84 | | - v-if="chunkParams.use_qa_split" |
85 | | - label="QA分隔符" |
86 | | - name="qa_separator" |
87 | | - > |
88 | | - <a-input |
89 | | - v-model:value="chunkParams.qa_separator" |
90 | | - placeholder="输入QA分隔符" |
91 | | - style="width: 200px; margin-right: 12px;" |
92 | | - /> |
93 | | - <span class="param-description"> |
94 | | - 用于分割不同QA对的分隔符,默认为3个换行符 |
95 | | - </span> |
96 | | - </a-form-item> |
97 | | - </a-form> |
98 | | - </div> |
99 | | - |
100 | 70 | <!-- PDF/图片OCR提醒 --> |
101 | 71 | <div v-if="uploadMode === 'file' && hasPdfOrImageFiles && !isOcrEnabled" class="ocr-warning-alert"> |
102 | 72 | ⚠️ 检测到PDF或图片文件,请启用OCR功能以提取文本内容 |
|
181 | 151 | </template> |
182 | 152 |
|
183 | 153 | <script setup> |
184 | | -import { ref, computed, onMounted } from 'vue'; |
| 154 | +import { ref, computed, onMounted, watch } from 'vue'; |
185 | 155 | import { message, Upload } from 'ant-design-vue'; |
186 | 156 | import { useUserStore } from '@/stores/user'; |
187 | 157 | import { useDatabaseStore } from '@/stores/database'; |
@@ -295,6 +265,24 @@ const chunkLoading = computed(() => store.state.chunkLoading); |
295 | 265 |
|
296 | 266 | // 上传模式 |
297 | 267 | const uploadMode = ref('file'); |
| 268 | +const previousOcrSelection = ref('disable'); |
| 269 | +
|
| 270 | +const uploadModeOptions = computed(() => [ |
| 271 | + { |
| 272 | + value: 'file', |
| 273 | + label: h('div', { class: 'segmented-option' }, [ |
| 274 | + h(FileOutlined, { class: 'option-icon' }), |
| 275 | + h('span', { class: 'option-text' }, '上传文件'), |
| 276 | + ]), |
| 277 | + }, |
| 278 | + { |
| 279 | + value: 'url', |
| 280 | + label: h('div', { class: 'segmented-option' }, [ |
| 281 | + h(LinkOutlined, { class: 'option-icon' }), |
| 282 | + h('span', { class: 'option-text' }, '输入网址'), |
| 283 | + ]), |
| 284 | + }, |
| 285 | +]); |
298 | 286 |
|
299 | 287 | // 文件列表 |
300 | 288 | const fileList = ref([]); |
@@ -349,6 +337,15 @@ const isOcrEnabled = computed(() => { |
349 | 337 | return chunkParams.value.enable_ocr !== 'disable'; |
350 | 338 | }); |
351 | 339 |
|
| 340 | +watch(uploadMode, (mode, previous) => { |
| 341 | + if (mode === 'url') { |
| 342 | + previousOcrSelection.value = chunkParams.value.enable_ocr; |
| 343 | + chunkParams.value.enable_ocr = 'disable'; |
| 344 | + } else if (mode === 'file' && previous === 'url') { |
| 345 | + chunkParams.value.enable_ocr = previousOcrSelection.value || 'disable'; |
| 346 | + } |
| 347 | +}); |
| 348 | +
|
352 | 349 | // 计算属性:是否有PDF或图片文件 |
353 | 350 | const hasPdfOrImageFiles = computed(() => { |
354 | 351 | if (fileList.value.length === 0) { |
@@ -647,45 +644,60 @@ const chunkData = async () => { |
647 | 644 |
|
648 | 645 | .source-selector { |
649 | 646 | display: flex; |
650 | | - gap: 12px; |
| 647 | + align-items: center; |
651 | 648 | } |
652 | 649 |
|
653 | | -.upload-mode-selector { |
654 | | - padding: 8px 16px; |
655 | | - border: 1px solid var(--gray-300); |
656 | | - border-radius: 6px; |
657 | | - cursor: pointer; |
658 | | - transition: all 0.3s; |
| 650 | +.config-controls { |
| 651 | + display: flex; |
| 652 | + align-items: center; |
| 653 | +} |
| 654 | +
|
| 655 | +.source-segmented { |
| 656 | + background-color: var(--gray-100); |
| 657 | + border-radius: 999px; |
| 658 | + padding: 4px; |
| 659 | + border: 1px solid var(--gray-200); |
659 | 660 | } |
660 | 661 |
|
661 | | -.upload-mode-selector:hover { |
662 | | - border-color: var(--main-color); |
| 662 | +.source-segmented :deep(.ant-segmented-item) { |
| 663 | + border-radius: 999px; |
| 664 | +} |
| 665 | +
|
| 666 | +.source-segmented :deep(.ant-segmented-item-label) { |
| 667 | + display: flex; |
| 668 | + align-items: center; |
| 669 | + gap: 8px; |
| 670 | + padding: 6px 16px; |
| 671 | + font-weight: 500; |
| 672 | + color: var(--gray-600); |
663 | 673 | } |
664 | 674 |
|
665 | | -.upload-mode-selector.active { |
666 | | - border-color: var(--main-color); |
| 675 | +.source-segmented :deep(.ant-segmented-thumb) { |
667 | 676 | background-color: var(--main-30); |
| 677 | + border-radius: 999px; |
| 678 | +} |
| 679 | +
|
| 680 | +.source-segmented :deep(.ant-segmented-item-selected .ant-segmented-item-label) { |
668 | 681 | color: var(--main-color); |
669 | 682 | } |
670 | 683 |
|
671 | | -.config-controls { |
| 684 | +.source-segmented :deep(.segmented-option) { |
672 | 685 | display: flex; |
673 | 686 | align-items: center; |
| 687 | + gap: 8px; |
| 688 | +} |
| 689 | +
|
| 690 | +.source-segmented :deep(.option-icon) { |
| 691 | + font-size: 16px; |
674 | 692 | } |
675 | 693 |
|
676 | | -.ocr-config, |
677 | | -.qa-split-config { |
| 694 | +.ocr-config { |
678 | 695 | margin-bottom: 20px; |
679 | 696 | padding: 16px; |
680 | 697 | background-color: var(--gray-50); |
681 | 698 | border-radius: 6px; |
682 | 699 | } |
683 | 700 |
|
684 | | -.toggle-controls { |
685 | | - display: flex; |
686 | | - align-items: center; |
687 | | -} |
688 | | -
|
689 | 701 | .param-description { |
690 | 702 | font-size: 12px; |
691 | 703 | color: var(--gray-600); |
|
0 commit comments