作者 dong

修复bug

@@ -33,12 +33,12 @@ @@ -33,12 +33,12 @@
33 <a-col :xxl="4" :xl="6" :lg="6" :md="6" :sm="12" :xs="24"> 33 <a-col :xxl="4" :xl="6" :lg="6" :md="6" :sm="12" :xs="24">
34 <a-card class="add-knowledge-card" @click="handleAddKnowled"> 34 <a-card class="add-knowledge-card" @click="handleAddKnowled">
35 <div class="flex"> 35 <div class="flex">
36 - <Icon icon="ant-design:plus-outlined" class="add-knowledge-card-icon" size="20"></Icon> 36 + <Icon icon="ant-design:plus-outlined" class="add-knowledge-card-icon" size="20" />
37 <span class="add-knowledge-card-title">创建知识库</span> 37 <span class="add-knowledge-card-title">创建知识库</span>
38 </div> 38 </div>
39 </a-card> 39 </a-card>
40 </a-col> 40 </a-col>
41 - <a-col v-if="knowledgeList && knowledgeList.length>0" :xxl="4" :xl="6" :lg="6" :md="6" :sm="12" :xs="24" v-for="item in knowledgeList"> 41 + <a-col v-if="knowledgeList && knowledgeList.length > 0" :xxl="4" :xl="6" :lg="6" :md="6" :sm="12" :xs="24" v-for="item in knowledgeList">
42 <a-card class="knowledge-card pointer" @click="handleDocClick(item.id)"> 42 <a-card class="knowledge-card pointer" @click="handleDocClick(item.id)">
43 <div class="knowledge-header"> 43 <div class="knowledge-header">
44 <div class="flex"> 44 <div class="flex">
@@ -53,26 +53,26 @@ @@ -53,26 +53,26 @@
53 <span>{{ item.descr || '暂无描述' }}</span> 53 <span>{{ item.descr || '暂无描述' }}</span>
54 </div> 54 </div>
55 <div class="knowledge-footer"> 55 <div class="knowledge-footer">
56 - <Icon class="knowledge-footer-icon" icon="ant-design:deployment-unit-outlined" size="14"></Icon> 56 + <Icon class="knowledge-footer-icon" icon="ant-design:deployment-unit-outlined" size="14" />
57 <span>{{ item.embedId_dictText }}</span> 57 <span>{{ item.embedId_dictText }}</span>
58 </div> 58 </div>
59 <div class="knowledge-btn"> 59 <div class="knowledge-btn">
60 <a-dropdown placement="bottomRight" :trigger="['click']" :getPopupContainer="(node) => node.parentNode"> 60 <a-dropdown placement="bottomRight" :trigger="['click']" :getPopupContainer="(node) => node.parentNode">
61 <div class="ant-dropdown-link pointer model-icon" @click.prevent.stop> 61 <div class="ant-dropdown-link pointer model-icon" @click.prevent.stop>
62 - <Icon icon="ant-design:ellipsis-outlined" size="16"></Icon> 62 + <Icon icon="ant-design:ellipsis-outlined" size="16" />
63 </div> 63 </div>
64 <template #overlay> 64 <template #overlay>
65 <a-menu> 65 <a-menu>
66 <a-menu-item key="vectorization" @click.prevent.stop="handleVectorization(item.id)"> 66 <a-menu-item key="vectorization" @click.prevent.stop="handleVectorization(item.id)">
67 - <Icon icon="ant-design:retweet-outlined" size="16"></Icon> 67 + <Icon icon="ant-design:retweet-outlined" size="16" />
68 向量化 68 向量化
69 </a-menu-item> 69 </a-menu-item>
70 <a-menu-item key="text" @click.prevent.stop="handleEditClick(item)"> 70 <a-menu-item key="text" @click.prevent.stop="handleEditClick(item)">
71 - <Icon class="pointer" icon="ant-design:edit-outlined" size="16"></Icon> 71 + <Icon class="pointer" icon="ant-design:edit-outlined" size="16" />
72 编辑 72 编辑
73 </a-menu-item> 73 </a-menu-item>
74 <a-menu-item key="file" @click.prevent.stop="handleDelete(item)"> 74 <a-menu-item key="file" @click.prevent.stop="handleDelete(item)">
75 - <Icon class="pointer" icon="ant-design:delete-outlined" size="16"></Icon> 75 + <Icon class="pointer" icon="ant-design:delete-outlined" size="16" />
76 删除 76 删除
77 </a-menu-item> 77 </a-menu-item>
78 </a-menu> 78 </a-menu>
@@ -95,9 +95,9 @@ @@ -95,9 +95,9 @@
95 size="small" 95 size="small"
96 /> 96 />
97 <!--添加知识库弹窗--> 97 <!--添加知识库弹窗-->
98 - <KnowledgeBaseModal @register="registerModal" @success="reload"></KnowledgeBaseModal> 98 + <KnowledgeBaseModal @register="registerModal" @success="reload" />
99 <!-- 知识库文档弹窗 --> 99 <!-- 知识库文档弹窗 -->
100 - <AiragKnowledgeDocListModal @register="docListRegister"></AiragKnowledgeDocListModal> 100 + <AiragKnowledgeDocListModal @register="docListRegister" />
101 </div> 101 </div>
102 </template> 102 </template>
103 103
@@ -112,7 +112,7 @@ @@ -112,7 +112,7 @@
112 import JDictSelectTag from '@/components/Form/src/jeecg/components/JDictSelectTag.vue'; 112 import JDictSelectTag from '@/components/Form/src/jeecg/components/JDictSelectTag.vue';
113 import AiragKnowledgeDocListModal from './components/AiragKnowledgeDocListModal.vue'; 113 import AiragKnowledgeDocListModal from './components/AiragKnowledgeDocListModal.vue';
114 import Icon from '@/components/Icon'; 114 import Icon from '@/components/Icon';
115 - import { useMessage } from "@/hooks/web/useMessage"; 115 + import { useMessage } from '@/hooks/web/useMessage';
116 116
117 export default { 117 export default {
118 name: 'KnowledgeBaseList', 118 name: 'KnowledgeBaseList',
@@ -190,7 +190,7 @@ @@ -190,7 +190,7 @@
190 pageNo: pageNo.value, 190 pageNo: pageNo.value,
191 pageSize: pageSize.value, 191 pageSize: pageSize.value,
192 column: 'createTime', 192 column: 'createTime',
193 - order: 'desc' 193 + order: 'desc',
194 }; 194 };
195 Object.assign(params, queryParam); 195 Object.assign(params, queryParam);
196 196
@@ -255,15 +255,17 @@ @@ -255,15 +255,17 @@
255 * @param id 255 * @param id
256 */ 256 */
257 async function handleVectorization(id) { 257 async function handleVectorization(id) {
258 - rebuild({ knowIds: id }).then((res) =>{  
259 - if(res.success){  
260 - createMessage.success("向量化成功!"); 258 + rebuild({ knowIds: id })
  259 + .then((res) => {
  260 + if (res.success) {
  261 + createMessage.success('向量化成功!');
261 reload(); 262 reload();
262 - }else{  
263 - createMessage.warning("向量化失败!"); 263 + } else {
  264 + createMessage.warning('向量化失败!');
264 } 265 }
265 - }).catch(err=>{  
266 - createMessage.warning("向量化失败!"); 266 + })
  267 + .catch((err) => {
  268 + createMessage.warning('向量化失败!');
267 }); 269 });
268 } 270 }
269 271
@@ -346,17 +348,17 @@ @@ -346,17 +348,17 @@
346 color: #676f83; 348 color: #676f83;
347 } 349 }
348 350
349 - .knowledge-footer{ 351 + .knowledge-footer {
350 font-size: 12px; 352 font-size: 12px;
351 overflow: hidden; 353 overflow: hidden;
352 text-overflow: ellipsis; 354 text-overflow: ellipsis;
353 white-space: nowrap; 355 white-space: nowrap;
354 margin-top: 16px; 356 margin-top: 16px;
355 - .knowledge-footer-icon{ 357 + .knowledge-footer-icon {
356 position: relative; 358 position: relative;
357 - top: 2px 359 + top: 2px;
358 } 360 }
359 - span{ 361 + span {
360 margin-left: 2px; 362 margin-left: 2px;
361 } 363 }
362 } 364 }
@@ -389,7 +391,7 @@ @@ -389,7 +391,7 @@
389 margin-bottom: 20px; 391 margin-bottom: 20px;
390 background: #fcfcfd; 392 background: #fcfcfd;
391 border: 1px solid #f0f0f0; 393 border: 1px solid #f0f0f0;
392 - box-shadow: 0 2px 4px rgba(0,0,0,0.1); 394 + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
393 transition: all 0.3s ease; 395 transition: all 0.3s ease;
394 border-radius: 10px; 396 border-radius: 10px;
395 display: inline-flex; 397 display: inline-flex;
@@ -407,14 +409,14 @@ @@ -407,14 +409,14 @@
407 } 409 }
408 .add-knowledge-card-title { 410 .add-knowledge-card-title {
409 font-size: 16px; 411 font-size: 16px;
410 - color:#1f2329; 412 + color: #1f2329;
411 font-weight: 400; 413 font-weight: 400;
412 align-self: center; 414 align-self: center;
413 } 415 }
414 } 416 }
415 417
416 .add-knowledge-card:hover { 418 .add-knowledge-card:hover {
417 - box-shadow: 0 6px 12px rgba(0,0,0,0.15); 419 + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
418 } 420 }
419 421
420 .knowledge-card { 422 .knowledge-card {
@@ -424,11 +426,11 @@ @@ -424,11 +426,11 @@
424 border-radius: 10px; 426 border-radius: 10px;
425 background: #fcfcfd; 427 background: #fcfcfd;
426 border: 1px solid #f0f0f0; 428 border: 1px solid #f0f0f0;
427 - box-shadow: 0 2px 4px rgba(0,0,0,0.1); 429 + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
428 transition: all 0.3s ease; 430 transition: all 0.3s ease;
429 } 431 }
430 .knowledge-card:hover { 432 .knowledge-card:hover {
431 - box-shadow: 0 6px 12px rgba(0,0,0,0.15); 433 + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
432 .knowledge-btn { 434 .knowledge-btn {
433 display: block; 435 display: block;
434 } 436 }
@@ -452,17 +454,17 @@ @@ -452,17 +454,17 @@
452 } 454 }
453 } 455 }
454 456
455 - .model-icon{ 457 + .model-icon {
456 background-color: unset; 458 background-color: unset;
457 border: none; 459 border: none;
458 margin-right: 2px; 460 margin-right: 2px;
459 } 461 }
460 - .model-icon:hover{ 462 + .model-icon:hover {
461 color: #000000; 463 color: #000000;
462 - background-color: rgba(0,0,0,0.05); 464 + background-color: rgba(0, 0, 0, 0.05);
463 border: none; 465 border: none;
464 } 466 }
465 - .ant-dropdown-link{ 467 + .ant-dropdown-link {
466 font-size: 14px; 468 font-size: 14px;
467 height: 24px; 469 height: 24px;
468 padding: 0 7px; 470 padding: 0 7px;
@@ -471,7 +473,7 @@ @@ -471,7 +473,7 @@
471 text-align: center; 473 text-align: center;
472 } 474 }
473 475
474 - .ellipsis{ 476 + .ellipsis {
475 overflow: hidden; 477 overflow: hidden;
476 text-overflow: ellipsis; 478 text-overflow: ellipsis;
477 white-space: nowrap; 479 white-space: nowrap;
@@ -24,7 +24,7 @@ export const searchFormSchema: FormSchema[] = [ @@ -24,7 +24,7 @@ export const searchFormSchema: FormSchema[] = [
24 { 24 {
25 label: '问题', 25 label: '问题',
26 field: 'question', 26 field: 'question',
27 - component: 'JInput', 27 + component: 'Input',
28 }, 28 },
29 // 新增知识库选择字段 29 // 新增知识库选择字段
30 { 30 {
@@ -23,40 +23,40 @@ export const listKnowledge = async () => { @@ -23,40 +23,40 @@ export const listKnowledge = async () => {
23 const res = await defHttp.get({ url: Api.listKnowledge }); 23 const res = await defHttp.get({ url: Api.listKnowledge });
24 return res; 24 return res;
25 } catch (error) { 25 } catch (error) {
26 - console.error("Error fetching knowledge list:", error); 26 + console.error('Error fetching knowledge list:', error);
27 return []; 27 return [];
28 } 28 }
29 -} 29 +};
30 30
31 export const list = async (params) => { 31 export const list = async (params) => {
32 try { 32 try {
33 const res = await defHttp.get({ 33 const res = await defHttp.get({
34 url: Api.list, 34 url: Api.list,
35 - params: { ...params, size: 1000 } 35 + params: { ...params, size: 1000 },
36 }); 36 });
37 37
38 if (res?.records && Array.isArray(res.records)) { 38 if (res?.records && Array.isArray(res.records)) {
39 - res.records = res.records.map(item => ({ 39 + res.records = res.records.map((item) => ({
40 ...item, 40 ...item,
41 ...item.metadata, 41 ...item.metadata,
42 question: item.question || '', 42 question: item.question || '',
43 answer: item.answer || '', 43 answer: item.answer || '',
44 knowledgeName: item.knowledgeName || '', 44 knowledgeName: item.knowledgeName || '',
45 - knowledgeId: item.knowledgeId || '' 45 + knowledgeId: item.knowledgeId || '',
46 })); 46 }));
47 } 47 }
48 return res; 48 return res;
49 } catch (error) { 49 } catch (error) {
50 - console.error("Error fetching question embeddings:", error); 50 + console.error('Error fetching question embeddings:', error);
51 return { 51 return {
52 records: [], 52 records: [],
53 total: 0, 53 total: 0,
54 size: 10, 54 size: 10,
55 current: 1, 55 current: 1,
56 - pages: 0 56 + pages: 0,
57 }; 57 };
58 } 58 }
59 -} 59 +};
60 60
61 export const deleteOne = (params, handleSuccess) => { 61 export const deleteOne = (params, handleSuccess) => {
62 return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => { 62 return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
@@ -13,19 +13,19 @@ export const columns: BasicColumn[] = [ @@ -13,19 +13,19 @@ export const columns: BasicColumn[] = [
13 title: '知识库', 13 title: '知识库',
14 align: 'center', 14 align: 'center',
15 dataIndex: 'knowledgeName', 15 dataIndex: 'knowledgeName',
16 - width: 150 16 + width: 150,
17 }, 17 },
18 { 18 {
19 title: '问题', 19 title: '问题',
20 align: 'center', 20 align: 'center',
21 dataIndex: 'question', 21 dataIndex: 'question',
22 - width: 250 22 + width: 250,
23 }, 23 },
24 { 24 {
25 title: '回答', 25 title: '回答',
26 align: 'center', 26 align: 'center',
27 dataIndex: 'answer', 27 dataIndex: 'answer',
28 - width: 300 28 + width: 300,
29 }, 29 },
30 ]; 30 ];
31 31
@@ -39,20 +39,20 @@ export const searchFormSchema: FormSchema[] = [ @@ -39,20 +39,20 @@ export const searchFormSchema: FormSchema[] = [
39 labelField: 'name', 39 labelField: 'name',
40 valueField: 'id', 40 valueField: 'id',
41 }, 41 },
42 - colProps: { span: 8 } 42 + colProps: { span: 8 },
43 }, 43 },
44 { 44 {
45 field: 'question', 45 field: 'question',
46 label: '问题', 46 label: '问题',
47 component: 'Input', 47 component: 'Input',
48 - colProps: { span: 8 } 48 + colProps: { span: 8 },
49 }, 49 },
50 { 50 {
51 field: 'answer', 51 field: 'answer',
52 label: '回答', 52 label: '回答',
53 component: 'Input', 53 component: 'Input',
54 colProps: { span: 8 }, 54 colProps: { span: 8 },
55 - } 55 + },
56 ]; 56 ];
57 57
58 export const formSchema: FormSchema[] = [ 58 export const formSchema: FormSchema[] = [
@@ -71,14 +71,15 @@ export const formSchema: FormSchema[] = [ @@ -71,14 +71,15 @@ export const formSchema: FormSchema[] = [
71 api: listKnowledge, 71 api: listKnowledge,
72 labelField: 'name', 72 labelField: 'name',
73 valueField: 'id', 73 valueField: 'id',
74 - } 74 + showSearch: true,
  75 + },
75 }, 76 },
76 { 77 {
77 field: 'question', 78 field: 'question',
78 label: '问题', 79 label: '问题',
79 component: 'Input', 80 component: 'Input',
80 required: true, 81 required: true,
81 - colProps: { span: 24 } 82 + colProps: { span: 24 },
82 }, 83 },
83 { 84 {
84 field: 'answer', 85 field: 'answer',
@@ -90,16 +91,16 @@ export const formSchema: FormSchema[] = [ @@ -90,16 +91,16 @@ export const formSchema: FormSchema[] = [
90 showCount: true, 91 showCount: true,
91 autoSize: { 92 autoSize: {
92 minRows: 5, 93 minRows: 5,
93 - maxRows: 10  
94 - }  
95 - }  
96 - } 94 + maxRows: 10,
  95 + },
  96 + },
  97 + },
97 ]; 98 ];
98 99
99 export const superQuerySchema = { 100 export const superQuerySchema = {
100 knowledgeId: { title: '知识库', order: 0, view: 'text', type: 'string' }, 101 knowledgeId: { title: '知识库', order: 0, view: 'text', type: 'string' },
101 question: { title: '问题', order: 1, view: 'text', type: 'string' }, 102 question: { title: '问题', order: 1, view: 'text', type: 'string' },
102 - answer: { title: '回答', order: 2, view: 'text', type: 'string' } 103 + answer: { title: '回答', order: 2, view: 'text', type: 'string' },
103 }; 104 };
104 105
105 export function getBpmFormSchema(_formData): FormSchema[] { 106 export function getBpmFormSchema(_formData): FormSchema[] {
@@ -4,17 +4,11 @@ @@ -4,17 +4,11 @@
4 <template #tableTitle> 4 <template #tableTitle>
5 <a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined">新增</a-button> 5 <a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined">新增</a-button>
6 <a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls">导出</a-button> 6 <a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls">导出</a-button>
7 - <a-button  
8 - type="primary"  
9 - preIcon="ant-design:import-outlined"  
10 - @click="handleOpenImportModal"  
11 - >导入ZIP</a-button> 7 + <a-button type="primary" preIcon="ant-design:import-outlined" @click="handleOpenImportModal">导入ZIP</a-button>
12 <a-dropdown v-if="selectedRowKeys.length > 0"> 8 <a-dropdown v-if="selectedRowKeys.length > 0">
13 <template #overlay> 9 <template #overlay>
14 <a-menu> 10 <a-menu>
15 - <a-menu-item key="1" @click="batchHandleDelete">  
16 - <Icon icon="ant-design:delete-outlined" />删除  
17 - </a-menu-item> 11 + <a-menu-item key="1" @click="batchHandleDelete"> <Icon icon="ant-design:delete-outlined" />删除 </a-menu-item>
18 </a-menu> 12 </a-menu>
19 </template> 13 </template>
20 <a-button>批量操作<Icon icon="mdi:chevron-down" /></a-button> 14 <a-button>批量操作<Icon icon="mdi:chevron-down" /></a-button>
@@ -36,30 +30,13 @@ @@ -36,30 +30,13 @@
36 :okButtonProps="{ disabled: !selectedKnowledgeId || !currentFile }" 30 :okButtonProps="{ disabled: !selectedKnowledgeId || !currentFile }"
37 > 31 >
38 <BasicForm @register="registerImportForm" :showActionButtonGroup="false" /> 32 <BasicForm @register="registerImportForm" :showActionButtonGroup="false" />
39 - <div style="margin-top: 20px;margin-left: 5%">  
40 - <input  
41 - type="file"  
42 - ref="fileInput"  
43 - accept=".zip"  
44 - @change="handleFileChange"  
45 - style="display: none"  
46 - >  
47 - <a-button  
48 - type="primary"  
49 - @click="triggerFileInput"  
50 - >  
51 - <UploadOutlined /> 选择ZIP文件  
52 - </a-button>  
53 - <div v-if="currentFile" style="margin-top: 8px;">  
54 - 已选择文件: {{ currentFile.name }} ({{ formatFileSize(currentFile.size) }})  
55 - </div>  
56 - <div v-if="uploadProgress > 0" style="margin-top: 8px;"> 33 + <div style="margin-top: 20px; margin-left: 5%">
  34 + <input type="file" ref="fileInput" accept=".zip" @change="handleFileChange" style="display: none" />
  35 + <a-button type="primary" @click="triggerFileInput"> <UploadOutlined /> 选择ZIP文件 </a-button>
  36 + <div v-if="currentFile" style="margin-top: 8px"> 已选择文件: {{ currentFile.name }} ({{ formatFileSize(currentFile.size) }}) </div>
  37 + <div v-if="uploadProgress > 0" style="margin-top: 8px">
57 上传进度: {{ uploadProgress }}% 38 上传进度: {{ uploadProgress }}%
58 - <a-progress  
59 - :percent="uploadProgress"  
60 - :stroke-color="progressColor"  
61 - :status="uploadStatus"  
62 - /> 39 + <a-progress :percent="uploadProgress" :stroke-color="progressColor" :status="uploadStatus" />
63 </div> 40 </div>
64 </div> 41 </div>
65 </BasicModal> 42 </BasicModal>
@@ -67,32 +44,32 @@ @@ -67,32 +44,32 @@
67 </template> 44 </template>
68 45
69 <script lang="ts" setup> 46 <script lang="ts" setup>
70 -import { ref, reactive } from 'vue';  
71 -import { UploadOutlined } from '@ant-design/icons-vue';  
72 -import { BasicTable, useTable, TableAction } from '/@/components/Table';  
73 -import { BasicModal } from '/@/components/Modal';  
74 -import { BasicForm, useForm } from '/@/components/Form';  
75 -import { useModal } from '/@/components/Modal';  
76 -import { useListPage } from '/@/hooks/system/useListPage';  
77 -import { message } from 'ant-design-vue';  
78 -import QuestionEmbeddingModal from './components/QuestionEmbeddingModal.vue';  
79 -import { columns, searchFormSchema } from './QuestionEmbedding.data';  
80 -import { list, deleteOne, batchDelete, getImportZipUrl, getExportUrl, listKnowledge } from './QuestionEmbedding.api';  
81 -import { useUserStore } from '/@/store/modules/user';  
82 -import { getToken } from '/@/utils/auth'; 47 + import { ref, reactive } from 'vue';
  48 + import { UploadOutlined } from '@ant-design/icons-vue';
  49 + import { BasicTable, TableAction } from '/@/components/Table';
  50 + import { BasicModal } from '/@/components/Modal';
  51 + import { BasicForm, useForm } from '/@/components/Form';
  52 + import { useModal } from '/@/components/Modal';
  53 + import { useListPage } from '/@/hooks/system/useListPage';
  54 + import { message } from 'ant-design-vue';
  55 + import QuestionEmbeddingModal from './components/QuestionEmbeddingModal.vue';
  56 + import { columns, searchFormSchema } from './QuestionEmbedding.data';
  57 + import { list, deleteOne, batchDelete, getImportZipUrl, getExportUrl, listKnowledge } from './QuestionEmbedding.api';
  58 + import { useUserStore } from '/@/store/modules/user';
  59 + import { getToken } from '/@/utils/auth';
83 60
84 -const queryParam = reactive<any>({});  
85 -const [registerModal, { openModal }] = useModal();  
86 -const importModalVisible = ref(false);  
87 -const selectedKnowledgeId = ref('');  
88 -const fileInput = ref<HTMLInputElement | null>(null);  
89 -const currentFile = ref<File | null>(null);  
90 -const uploadProgress = ref(0);  
91 -const progressColor = ref('#1890ff');  
92 -const uploadStatus = ref<'normal' | 'exception' | 'active' | 'success'>('normal'); 61 + const queryParam = reactive<any>({});
  62 + const [registerModal, { openModal }] = useModal();
  63 + const importModalVisible = ref(false);
  64 + const selectedKnowledgeId = ref('');
  65 + const fileInput = ref<HTMLInputElement | null>(null);
  66 + const currentFile = ref<File | null>(null);
  67 + const uploadProgress = ref(0);
  68 + const progressColor = ref('#1890ff');
  69 + const uploadStatus = ref<'normal' | 'exception' | 'active' | 'success'>('normal');
93 70
94 -// 知识库选择表单  
95 -const [registerImportForm] = useForm({ 71 + // 知识库选择表单
  72 + const [registerImportForm] = useForm({
96 labelWidth: 100, 73 labelWidth: 100,
97 showActionButtonGroup: false, 74 showActionButtonGroup: false,
98 schemas: [ 75 schemas: [
@@ -108,13 +85,13 @@ const [registerImportForm] = useForm({ @@ -108,13 +85,13 @@ const [registerImportForm] = useForm({
108 valueField: 'id', 85 valueField: 'id',
109 onChange: (value: string) => { 86 onChange: (value: string) => {
110 selectedKnowledgeId.value = value; 87 selectedKnowledgeId.value = value;
111 - } 88 + },
112 }, 89 },
113 }, 90 },
114 ], 91 ],
115 -}); 92 + });
116 93
117 -const { tableContext, onExportXls } = useListPage({ 94 + const { tableContext, onExportXls } = useListPage({
118 tableProps: { 95 tableProps: {
119 title: '问答向量库', 96 title: '问答向量库',
120 api: list, 97 api: list,
@@ -122,38 +99,38 @@ const { tableContext, onExportXls } = useListPage({ @@ -122,38 +99,38 @@ const { tableContext, onExportXls } = useListPage({
122 formConfig: { 99 formConfig: {
123 schemas: searchFormSchema, 100 schemas: searchFormSchema,
124 autoSubmitOnEnter: true, 101 autoSubmitOnEnter: true,
125 - showAdvancedButton: true 102 + showAdvancedButton: true,
126 }, 103 },
127 actionColumn: { 104 actionColumn: {
128 width: 120, 105 width: 120,
129 - fixed: 'right' 106 + fixed: 'right',
130 }, 107 },
131 - beforeFetch: (params) => Object.assign(params, queryParam) 108 + beforeFetch: (params) => Object.assign(params, queryParam),
132 }, 109 },
133 exportConfig: { 110 exportConfig: {
134 name: '问答向量库', 111 name: '问答向量库',
135 - url: getExportUrl  
136 - }  
137 -}); 112 + url: getExportUrl,
  113 + },
  114 + });
138 115
139 -const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext; 116 + const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
140 117
141 -function handleOpenImportModal() { 118 + function handleOpenImportModal() {
142 importModalVisible.value = true; 119 importModalVisible.value = true;
143 selectedKnowledgeId.value = ''; 120 selectedKnowledgeId.value = '';
144 resetFileInput(); 121 resetFileInput();
145 -} 122 + }
146 123
147 -function handleImportCancel() { 124 + function handleImportCancel() {
148 importModalVisible.value = false; 125 importModalVisible.value = false;
149 resetFileInput(); 126 resetFileInput();
150 -} 127 + }
151 128
152 -function triggerFileInput() { 129 + function triggerFileInput() {
153 fileInput.value?.click(); 130 fileInput.value?.click();
154 -} 131 + }
155 132
156 -function handleFileChange(e: Event) { 133 + function handleFileChange(e: Event) {
157 const input = e.target as HTMLInputElement; 134 const input = e.target as HTMLInputElement;
158 if (input.files && input.files.length > 0) { 135 if (input.files && input.files.length > 0) {
159 currentFile.value = input.files[0]; 136 currentFile.value = input.files[0];
@@ -162,35 +139,35 @@ function handleFileChange(e: Event) { @@ -162,35 +139,35 @@ function handleFileChange(e: Event) {
162 console.log('文件选择成功:', { 139 console.log('文件选择成功:', {
163 name: currentFile.value.name, 140 name: currentFile.value.name,
164 size: currentFile.value.size, 141 size: currentFile.value.size,
165 - type: currentFile.value.type 142 + type: currentFile.value.type,
166 }); 143 });
167 } else { 144 } else {
168 currentFile.value = null; 145 currentFile.value = null;
169 } 146 }
170 -} 147 + }
171 148
172 -function resetFileInput() { 149 + function resetFileInput() {
173 if (fileInput.value) { 150 if (fileInput.value) {
174 fileInput.value.value = ''; 151 fileInput.value.value = '';
175 } 152 }
176 currentFile.value = null; 153 currentFile.value = null;
177 uploadProgress.value = 0; 154 uploadProgress.value = 0;
178 uploadStatus.value = 'normal'; 155 uploadStatus.value = 'normal';
179 -} 156 + }
180 157
181 -function formatFileSize(bytes: number): string { 158 + function formatFileSize(bytes: number): string {
182 if (bytes === 0) return '0 Bytes'; 159 if (bytes === 0) return '0 Bytes';
183 const k = 1024; 160 const k = 1024;
184 const sizes = ['Bytes', 'KB', 'MB', 'GB']; 161 const sizes = ['Bytes', 'KB', 'MB', 'GB'];
185 const i = Math.floor(Math.log(bytes) / Math.log(k)); 162 const i = Math.floor(Math.log(bytes) / Math.log(k));
186 return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; 163 return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
187 -} 164 + }
188 165
189 -// 获取用户token  
190 -const userStore = useUserStore();  
191 -const token = getToken(); 166 + // 获取用户token
  167 + const userStore = useUserStore();
  168 + const token = getToken();
192 169
193 -async function handleImportSubmit() { 170 + async function handleImportSubmit() {
194 if (!selectedKnowledgeId.value || !currentFile.value) { 171 if (!selectedKnowledgeId.value || !currentFile.value) {
195 message.warning('请完整填写上传信息'); 172 message.warning('请完整填写上传信息');
196 return; 173 return;
@@ -205,14 +182,14 @@ async function handleImportSubmit() { @@ -205,14 +182,14 @@ async function handleImportSubmit() {
205 uploadStatus.value = 'active'; 182 uploadStatus.value = 'active';
206 183
207 // 使用fetch API并添加认证头 184 // 使用fetch API并添加认证头
208 - const response = await fetch("/jeecgboot" + getImportZipUrl, { 185 + const response = await fetch('/jeecgboot' + getImportZipUrl, {
209 method: 'POST', 186 method: 'POST',
210 body: formData, 187 body: formData,
211 headers: { 188 headers: {
212 'X-Access-Token': token, // JEECG标准认证头 189 'X-Access-Token': token, // JEECG标准认证头
213 - 'Authorization': `Bearer ${token}` // 备用认证头 190 + Authorization: `Bearer ${token}`, // 备用认证头
214 }, 191 },
215 - credentials: 'include' // 携带cookie 192 + credentials: 'include', // 携带cookie
216 }); 193 });
217 194
218 if (response.status === 401) { 195 if (response.status === 401) {
@@ -238,68 +215,66 @@ async function handleImportSubmit() { @@ -238,68 +215,66 @@ async function handleImportSubmit() {
238 message.error(error.message || '上传失败'); 215 message.error(error.message || '上传失败');
239 console.error('上传错误:', error); 216 console.error('上传错误:', error);
240 } 217 }
241 -} 218 + }
242 219
243 -function handleSuperQuery(params: any) { 220 + function handleSuperQuery(params: any) {
244 Object.assign(queryParam, params); 221 Object.assign(queryParam, params);
245 reload(); 222 reload();
246 -} 223 + }
247 224
248 -function handleAdd() { 225 + function handleAdd() {
249 openModal(true, { isUpdate: false, showFooter: true }); 226 openModal(true, { isUpdate: false, showFooter: true });
250 -} 227 + }
251 228
252 -function handleEdit(record: any) { 229 + function handleEdit(record: any) {
253 openModal(true, { record, isUpdate: true, showFooter: true }); 230 openModal(true, { record, isUpdate: true, showFooter: true });
254 -} 231 + }
255 232
256 -function handleDetail(record: any) { 233 + function handleDetail(record: any) {
257 openModal(true, { record, isUpdate: true, showFooter: false }); 234 openModal(true, { record, isUpdate: true, showFooter: false });
258 -} 235 + }
259 236
260 -async function handleDelete(record: any) { 237 + async function handleDelete(record: any) {
261 await deleteOne({ id: record.id }, handleSuccess); 238 await deleteOne({ id: record.id }, handleSuccess);
262 -} 239 + }
263 240
264 -async function batchHandleDelete() { 241 + async function batchHandleDelete() {
265 await batchDelete({ ids: selectedRowKeys.value }, handleSuccess); 242 await batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
266 -} 243 + }
267 244
268 -function handleSuccess() { 245 + function handleSuccess() {
269 selectedRowKeys.value = []; 246 selectedRowKeys.value = [];
270 reload(); 247 reload();
271 -} 248 + }
272 249
273 -function getTableAction(record: any) {  
274 - return [  
275 - { label: '编辑', onClick: handleEdit.bind(null, record) }  
276 - ];  
277 -} 250 + function getTableAction(record: any) {
  251 + return [{ label: '编辑', onClick: handleEdit.bind(null, record) }];
  252 + }
278 253
279 -function getDropDownAction(record: any) { 254 + function getDropDownAction(record: any) {
280 return [ 255 return [
281 { label: '详情', onClick: handleDetail.bind(null, record) }, 256 { label: '详情', onClick: handleDetail.bind(null, record) },
282 { 257 {
283 label: '删除', 258 label: '删除',
284 popConfirm: { 259 popConfirm: {
285 title: '确认删除此问答?', 260 title: '确认删除此问答?',
286 - confirm: handleDelete.bind(null, record)  
287 - }  
288 - } 261 + confirm: handleDelete.bind(null, record),
  262 + },
  263 + },
289 ]; 264 ];
290 -} 265 + }
291 </script> 266 </script>
292 267
293 <style scoped> 268 <style scoped>
294 -.upload-area { 269 + .upload-area {
295 margin-top: 20px; 270 margin-top: 20px;
296 padding: 20px; 271 padding: 20px;
297 border: 1px dashed #d9d9d9; 272 border: 1px dashed #d9d9d9;
298 border-radius: 4px; 273 border-radius: 4px;
299 text-align: center; 274 text-align: center;
300 cursor: pointer; 275 cursor: pointer;
301 -}  
302 -.upload-area:hover { 276 + }
  277 + .upload-area:hover {
303 border-color: #1890ff; 278 border-color: #1890ff;
304 -} 279 + }
305 </style> 280 </style>
@@ -39,6 +39,7 @@ @@ -39,6 +39,7 @@
39 async function handleSubmit() { 39 async function handleSubmit() {
40 try { 40 try {
41 const values = await validate(); 41 const values = await validate();
  42 + console.log(values);
42 setModalProps({ confirmLoading: true }); 43 setModalProps({ confirmLoading: true });
43 await saveOrUpdate(values, isUpdate.value); 44 await saveOrUpdate(values, isUpdate.value);
44 closeModal(); 45 closeModal();
@@ -182,6 +182,7 @@ @@ -182,6 +182,7 @@
182 * 编辑事件 182 * 编辑事件
183 */ 183 */
184 function handleEdit(record: Recordable) { 184 function handleEdit(record: Recordable) {
  185 + console.log('当前行数据:', record);
185 openModal(true, { 186 openModal(true, {
186 record, 187 record,
187 isUpdate: true, 188 isUpdate: true,
@@ -220,6 +221,7 @@ @@ -220,6 +221,7 @@
220 * 操作栏 221 * 操作栏
221 */ 222 */
222 function getTableAction(record) { 223 function getTableAction(record) {
  224 + console.log('record', record);
223 return [ 225 return [
224 { 226 {
225 label: '编辑', 227 label: '编辑',
@@ -199,6 +199,12 @@ export const formSchema: FormSchema[] = [ @@ -199,6 +199,12 @@ export const formSchema: FormSchema[] = [
199 }, 199 },
200 }, 200 },
201 }, 201 },
  202 + {
  203 + label: '',
  204 + field: 'docId',
  205 + component: 'Input',
  206 + show: false,
  207 + },
202 // TODO 主键隐藏字段,目前写死为ID 208 // TODO 主键隐藏字段,目前写死为ID
203 { 209 {
204 label: '', 210 label: '',
@@ -36,6 +36,7 @@ @@ -36,6 +36,7 @@
36 try { 36 try {
37 const metadata = typeof formData.metadata === 'string' ? JSON.parse(formData.metadata) : formData.metadata; 37 const metadata = typeof formData.metadata === 'string' ? JSON.parse(formData.metadata) : formData.metadata;
38 formData.docName = metadata.docName || '未命名'; 38 formData.docName = metadata.docName || '未命名';
  39 + formData.docId = metadata.docId || 'null';
39 40
40 // 关键修复:设置知识库ID 41 // 关键修复:设置知识库ID
41 formData.knowledgeId = metadata.knowledgeId; 42 formData.knowledgeId = metadata.knowledgeId;
@@ -53,19 +54,25 @@ @@ -53,19 +54,25 @@
53 //设置标题 54 //设置标题
54 const title = computed(() => (!unref(isUpdate) ? '新增' : !unref(isDetail) ? '详情' : '编辑')); 55 const title = computed(() => (!unref(isUpdate) ? '新增' : !unref(isDetail) ? '详情' : '编辑'));
55 //表单提交事件 56 //表单提交事件
56 - async function handleSubmit() { 57 + async function handleSubmit(record) {
  58 + console.log('22222222222222', record);
57 try { 59 try {
58 let values = await validate(); 60 let values = await validate();
  61 + console.log('表单数据:', values);
59 62
60 const metadata = { 63 const metadata = {
61 knowledgeId: values.knowledgeId, 64 knowledgeId: values.knowledgeId,
  65 + docId: values.docId,
62 }; 66 };
  67 + console.log('values', values);
63 // 仅保留需要的字段,其他由后端自动生成 68 // 仅保留需要的字段,其他由后端自动生成
64 const payload = { 69 const payload = {
65 id: values.id, 70 id: values.id,
66 docName: values.docName, // 文件名称 71 docName: values.docName, // 文件名称
67 text: values.text, // 文件内容 72 text: values.text, // 文件内容
68 metadata: metadata, 73 metadata: metadata,
  74 + knowledgeId: values.knowledgeId,
  75 + docId: values.docId,
69 }; 76 };
70 setModalProps({ confirmLoading: true }); 77 setModalProps({ confirmLoading: true });
71 //提交表单 78 //提交表单