index.vue 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100
  1. <template>
  2. <div class="container">
  3. <div class="main-container">
  4. <!-- <div class="rt-container" v-if="tabs.length > 0"> -->
  5. <div class="rt-container">
  6. <a-tabs :active-key="activeKey" @change="handleTabChange">
  7. <!-- 数据集 -->
  8. <a-tab-pane key="1" :title="$t('knowledgeLib.tab_1')">
  9. <a-scrollbar class="rt-container-main" :style="{ height: documentHeight + 'px' }" style="overflow: auto">
  10. <!-- <a-scrollbar class="rt-container-main" style="overflow: auto"> -->
  11. <a-card
  12. ref="account"
  13. class="general-card"
  14. title=""
  15. style="height: calc(100% - 25px); overflow-y: auto; padding-top: 20px"
  16. >
  17. <a-row>
  18. <a-col :flex="1" :span="12">
  19. <a-form
  20. :model="formModel"
  21. :label-col-props="{ span: 6 }"
  22. :wrapper-col-props="{ span: 18 }"
  23. label-align="left"
  24. >
  25. <a-row :gutter="16">
  26. <a-col :span="24" style="margin-bottom: 10px; display: flex; justify-content: space-between">
  27. <a-popover position="bottom" v-model="checkedArr.length" trigger="click">
  28. <a-button :disabled="checkedArr.length == 0" border>
  29. <!-- 批量 -->
  30. {{ $t('knowledgeLib.select_all') }}
  31. <icon-down style="margin-left: 4px" />
  32. </a-button>
  33. <template #content>
  34. <p>
  35. <a-button type="text" class="button" style="color: #2a2a2b" @click="enableDisable(1)">
  36. <template #icon>
  37. <icon-play-circle />
  38. </template>
  39. <!-- 启用 -->
  40. {{ $t('knowledgeLib.select_enable') }}
  41. </a-button>
  42. </p>
  43. <p>
  44. <a-button type="text" class="button" style="color: #2a2a2b" @click="enableDisable(0)">
  45. <template #icon>
  46. <icon-record color="" />
  47. </template>
  48. <!-- 禁用 -->
  49. {{ $t('knowledgeLib.select_disable') }}
  50. </a-button>
  51. </p>
  52. <p>
  53. <a-button type="text" class="button" style="color: #2a2a2b" @click="addBlock(1)">
  54. <template #icon>
  55. <icon-check-circle />
  56. </template>
  57. <!-- 启动 -->
  58. {{ $t('knowledgeLib.select_start') }}
  59. </a-button>
  60. </p>
  61. <p>
  62. <a-button type="text" class="button" style="color: #2a2a2b" @click="addBlock(2)">
  63. <template #icon>
  64. <icon-close-circle />
  65. </template>
  66. <!-- 取消 -->
  67. {{ $t('knowledgeLib.select_cancel') }}
  68. </a-button>
  69. </p>
  70. <a-divider style="margin: 10px 0" />
  71. <p>
  72. <a-button type="text" class="button" style="color: #2a2a2b" @click="addBlock(3)">
  73. <template #icon>
  74. <icon-delete />
  75. </template>
  76. <!-- 删除 -->
  77. {{ $t('knowledgeLib.select_delete') }}
  78. </a-button>
  79. </p>
  80. </template>
  81. </a-popover>
  82. <span>
  83. <!-- 搜索 -->
  84. <a-input-search
  85. :placeholder="$t('knowledgeLib.search_placeholder')"
  86. style="width: 200px; margin-right: 10px"
  87. v-model="keywords"
  88. @change="search"
  89. />
  90. <!--新建-->
  91. <add :kbobj="kbobj" @changeFetchData="changeFetchData" />
  92. </span>
  93. </a-col>
  94. </a-row>
  95. </a-form>
  96. </a-col>
  97. </a-row>
  98. <a-divider style="margin-top: 0" />
  99. <a-row style="margin-bottom: 16px">
  100. <a-col :span="12">
  101. <a-space> </a-space>
  102. </a-col>
  103. <a-col :span="12" style="display: flex; align-items: center; justify-content: end">
  104. <!-- 刷新 -->
  105. <a-tooltip :content="$t('knowledgeLib.tips_fresh')">
  106. <div class="action-icon">
  107. <icon-refresh size="18" />
  108. </div>
  109. </a-tooltip>
  110. <a-dropdown @select="handleSelectDensity">
  111. <!-- 密度 -->
  112. <a-tooltip :content="$t('knowledgeLib.tips_density')">
  113. <div class="action-icon">
  114. <icon-line-height size="18" />
  115. </div>
  116. </a-tooltip>
  117. <template #content>
  118. <a-doption
  119. v-for="item in densityList"
  120. :key="item.value"
  121. :value="item.value"
  122. :class="{ active: item.value === size }"
  123. >
  124. <span>{{ item.name }}</span>
  125. </a-doption>
  126. </template>
  127. </a-dropdown>
  128. </a-col>
  129. </a-row>
  130. <a-table
  131. row-key="id"
  132. :loading="loading"
  133. :pagination="pagination"
  134. :columns="cloneColumns"
  135. :data="renderData"
  136. :bordered="false"
  137. :size="size"
  138. @page-change="onPageChange"
  139. :max-height="documentHeight"
  140. :scroll="{ x: 1000 }"
  141. :row-selection="{
  142. type: 'checkbox',
  143. showCheckedAll: true,
  144. onlyCurrent: false
  145. }"
  146. @select-all="selectTabAll"
  147. @selection-change="selectTabChange"
  148. >
  149. <template #name="{ record }">
  150. <a-link @click="handlePreview(record)">
  151. <icon-file style="margin-right: 4px" />
  152. {{ record.name }}
  153. </a-link>
  154. </template>
  155. <template #create_time="{ record }">
  156. <span>{{ parseTime(record.create_time) }}</span>
  157. </template>
  158. <template #status="{ record }">
  159. <a-switch
  160. v-model="record.status"
  161. size="small"
  162. checked-value="1"
  163. unchecked-value="0"
  164. @change="handleChangeStatus(record)"
  165. />
  166. </template>
  167. <template #run="{ record }">
  168. <div style="display: flex; align-items: center">
  169. <div style="width: 100px">
  170. <a-popover position="lt" title="" v-if="record.run == '4'">
  171. <a-tag :loading="record.loading" :color="'red'" border>
  172. <!-- 失败 -->
  173. {{ $t('knowledgeLib.status_fail') }}
  174. </a-tag>
  175. <template #content>
  176. <div class="popover-content">
  177. <!-- 流程开始于: -->
  178. <p>{{ $t('knowledgeLib.popover_label_1') }}:{{ record.process_begin_at }}</p>
  179. <!-- 过程持续时间 -->
  180. <p>{{ $t('knowledgeLib.popover_label_2') }}:{{ record.process_duation.toFixed(2) }}</p>
  181. <div>
  182. <!-- 进度消息: -->
  183. <p>
  184. {{ $t('knowledgeLib.popover_label_3') }}:<span
  185. v-html="record.progress_msg.replace(/\n/g, '<br/>')"
  186. ></span>
  187. </p>
  188. </div>
  189. </div>
  190. </template>
  191. </a-popover>
  192. <a-popover position="lt" title="" v-if="record.run == '3'">
  193. <a-tag :loading="record.loading" :color="'blue'" border>
  194. <!-- 完成 -->
  195. {{ $t('knowledgeLib.table_status_finish') }}
  196. </a-tag>
  197. <template #content>
  198. <div class="popover-content">
  199. <p>{{ $t('knowledgeLib.popover_label_1') }}:{{ record.process_begin_at }}</p>
  200. <p>{{ $t('knowledgeLib.popover_label_2') }}:{{ record.process_duation.toFixed(2) }}</p>
  201. <div>
  202. <p>
  203. {{ $t('knowledgeLib.popover_label_3') }}:<span
  204. v-html="record.progress_msg.replace(/\n/g, '<br/>')"
  205. ></span>
  206. </p>
  207. </div>
  208. </div>
  209. </template>
  210. </a-popover>
  211. <a-popover position="lt" title="" v-if="record.run == '1'">
  212. <a-tag :loading="record.loading" :color="'blue'" border>
  213. <!-- 解析中... -->
  214. {{ $t('knowledgeLib.table_status_running') }}
  215. </a-tag>
  216. <template #content>
  217. <div class="popover-content">
  218. <p>{{ $t('knowledgeLib.popover_label_1') }}:{{ record.process_begin_at }}</p>
  219. <p>{{ $t('knowledgeLib.popover_label_2') }}:{{ record.process_duation.toFixed(2) }}</p>
  220. <div>
  221. <p>
  222. {{ $t('knowledgeLib.popover_label_3') }}:<span
  223. v-html="record.progress_msg.replace(/\n/g, '<br/>')"
  224. ></span>
  225. </p>
  226. </div>
  227. </div>
  228. </template>
  229. </a-popover>
  230. <a-popover position="lt" title="" v-if="record.run == '2'">
  231. <a-tag :loading="record.loading" :color="'gold'" border>
  232. <!-- 取消 -->
  233. {{ $t('knowledgeLib.table_status_cancel') }}
  234. </a-tag>
  235. <template #content>
  236. <div class="popover-content">
  237. <p>{{ $t('knowledgeLib.popover_label_1') }}:{{ record.process_begin_at }}</p>
  238. <p>{{ $t('knowledgeLib.popover_label_2') }}:{{ record.process_duation.toFixed(2) }}</p>
  239. <div>
  240. <p>
  241. {{ $t('knowledgeLib.popover_label_3') }}:<span
  242. v-html="record.progress_msg.replace(/\n/g, '<br/>')"
  243. ></span>
  244. </p>
  245. </div>
  246. </div>
  247. </template>
  248. </a-popover>
  249. <a-popover position="lt" title="" v-if="record.run == '0'">
  250. <a-tag :loading="record.loading" :color="'green'" border>
  251. <!-- 未启动 -->
  252. {{ $t('knowledgeLib.table_status_stop') }}
  253. </a-tag>
  254. <template #content>
  255. <div class="popover-content">
  256. <p>{{ $t('knowledgeLib.popover_label_1') }}:{{ record.process_begin_at }}</p>
  257. <p>{{ $t('knowledgeLib.popover_label_2') }}:{{ record.process_duation.toFixed(2) }}</p>
  258. <div>
  259. <p>
  260. {{ $t('knowledgeLib.popover_label_3') }}:<span
  261. v-html="record.progress_msg.replace(/\n/g, '<br/>')"
  262. ></span>
  263. </p>
  264. </div>
  265. </div>
  266. </template>
  267. </a-popover>
  268. </div>
  269. <div>
  270. <a-button type="text" size="large" @click="run(record)" :loading="record.loading">
  271. <template #icon>
  272. <icon-sync v-if="record.run == '4'" />
  273. <icon-sync v-if="record.run == '3'" />
  274. <icon-sync style="color: green" v-if="record.run == '2'" />
  275. <a-button status="warning" shape="circle" v-if="record.run == '1'" size="small">
  276. <icon-close />
  277. </a-button>
  278. <icon-play-circle style="color: green" v-if="record.run == '0'" />
  279. </template>
  280. </a-button>
  281. </div>
  282. </div>
  283. </template>
  284. <template #action="{ record }">
  285. <!-- 解析方法 -->
  286. <a-tooltip :content="$t('knowledgeLib.action_tip_parser')">
  287. <a-button type="text" :disabled="record.run == '1'" @click="handleClick(record)" size="small">
  288. <template #icon>
  289. <icon-tool />
  290. </template>
  291. </a-button>
  292. </a-tooltip>
  293. <edit :item="record" @upTabdateItem="upTabdateItem" />
  294. <!-- 确定删除吗 -->
  295. <a-popconfirm :content="$t('knowledgeLib.delete_confirm')" type="warning" @ok="deleteItem(record)">
  296. <!-- 删除 -->
  297. <a-tooltip :content="$t('knowledgeLib.action_tip_delete')">
  298. <a-button type="text" size="small" :disabled="record.run == '1'">
  299. <template #icon>
  300. <icon-delete />
  301. </template>
  302. </a-button>
  303. </a-tooltip>
  304. </a-popconfirm>
  305. <!-- 下载 -->
  306. <a-tooltip :content="$t('knowledgeLib.action_tip_download')">
  307. <a-button
  308. type="text"
  309. size="small"
  310. :disabled="record.run == '1'"
  311. @click="onDownloadDocument(record)"
  312. >
  313. <template #icon>
  314. <icon-download />
  315. </template>
  316. </a-button>
  317. </a-tooltip>
  318. <!--
  319. <a-button
  320. type="text"
  321. size="small"
  322. :disabled="record.run == '1'"
  323. @click="previewArea(record)"
  324. >
  325. <template #icon>
  326. <icon-eye />
  327. </template>
  328. </a-button> -->
  329. </template>
  330. </a-table>
  331. </a-card>
  332. </a-scrollbar>
  333. </a-tab-pane>
  334. <!-- 测试 -->
  335. <a-tab-pane key="2" :title="$t('knowledgeLib.tab_2')">
  336. <a-scrollbar class="rt-container-main" :style="{ height: documentHeight + 'px' }" style="overflow: hidden">
  337. <test ref="testForm"></test>
  338. </a-scrollbar>
  339. </a-tab-pane>
  340. <!-- 配置 -->
  341. <a-tab-pane key="3" :title="$t('knowledgeLib.tab_3')">
  342. <a-scrollbar class="rt-container-main" :style="{ height: documentHeight + 'px' }" style="overflow: auto">
  343. <config
  344. ref="configForm"
  345. :kbtenantInfo="kbtenantInfo"
  346. @cancleConfig="cancleConfig"
  347. @saveConfig="saveConfig"
  348. ></config>
  349. </a-scrollbar>
  350. </a-tab-pane>
  351. </a-tabs>
  352. </div>
  353. </div>
  354. <tool ref="toolForm" :kbtenantInfo="kbtenantInfo" :item="setObj" :kbdetail="kbdetail" />
  355. </div>
  356. </template>
  357. <script setup>
  358. import { computed, ref, reactive, watch, nextTick, onBeforeMount, onMounted, onBeforeUnmount } from 'vue';
  359. import { useI18n } from 'vue-i18n';
  360. import useLoading from './loading';
  361. import {
  362. queryKbList,
  363. queryKbDocumentList,
  364. deleteKnow,
  365. queryKbdetail,
  366. kbdocumentrm,
  367. kbdocumentrun,
  368. kbdocumentchangeStatus,
  369. downloadFile,
  370. changeStatus
  371. } from '../../../../apis/rgflow-dify';
  372. import { toSyncOwnKnowledge } from './asyc.js';
  373. import cloneDeep from 'lodash/cloneDeep';
  374. // import Sortable from 'sortablejs';
  375. import add from './add.vue';
  376. import edit from './edit.vue';
  377. import addKnow from './addKnow.vue';
  378. import config from './config.vue';
  379. import test from './test.vue';
  380. import tool from './tool.vue';
  381. // import docx from '@/views/dmx/knowledgeLib/components/docx.vue';
  382. // import excel from '@/views/dmx/knowledgeLib/components/excel.vue';
  383. // import txtPdf from '@/views/dmx/knowledgeLib/components/txtPdf.vue';
  384. import { Message, Modal } from '@arco-design/web-vue';
  385. import { documentHeight, parseTime, getTableColumns } from './utils';
  386. const props = defineProps({
  387. kb_id: {
  388. type: String,
  389. default: ''
  390. }
  391. });
  392. const account = ref(null);
  393. const generateFormModel = () => {
  394. return {
  395. number: '',
  396. name: '',
  397. contentType: '',
  398. filterType: '',
  399. createdTime: [],
  400. status: ''
  401. };
  402. };
  403. const { loading, setLoading } = useLoading(true);
  404. const { t } = useI18n();
  405. const renderData = ref([]);
  406. const formModel = ref(generateFormModel());
  407. const cloneColumns = ref([]);
  408. const showColumns = ref([]);
  409. let setObj = reactive({});
  410. const size = ref('medium');
  411. let visible = ref(false);
  412. let listloading = ref(false);
  413. let keywords = ref('');
  414. let activeKey = ref('1');
  415. let detailsShow = ref(false);
  416. let checkedAll = ref(false);
  417. let checkedArr = ref([]);
  418. let selectedTab = ref(0);
  419. let testForm = ref(null);
  420. let configForm = ref(null);
  421. let documenttype = ref('docx');
  422. let previewSrc = ref('');
  423. let kbId = ref('');
  424. let kbobj = reactive({});
  425. let kbdetail = reactive({});
  426. let parser_ids = reactive({});
  427. let seeObj = reactive({});
  428. let toolForm = ref(null);
  429. let kbtenantInfo = reactive({
  430. asr_id: 'paraformer-realtime-8k-v1',
  431. embd_id: 'BAAI/bge-large-zh-v1.5',
  432. img2txt_id: 'qwen-vl-max',
  433. llm_id: 'qwen-plus',
  434. name: 'wanghaos Kingdom',
  435. parser_ids:
  436. 'naive:General,qa:Q&A,resume:Resume,manual:Manual,table:Table,paper:Paper,book:Book,laws:Laws,presentation:Presentation,picture:Picture,one:One',
  437. rerank_id: 'BAAI/bge-reranker-v2-m3',
  438. role: 'owner',
  439. tenant_id: '948fc6fa41ab11ef8fb80242ac120004',
  440. parser_idObj: {}
  441. });
  442. let tabs = ref([]);
  443. let timer = null; // 定时器
  444. const selectTab = (item) => {
  445. // selectedTab.value = index;
  446. checkedArr.value = [];
  447. kbobj = item;
  448. kbId = kbobj.id;
  449. basePagination.page = 1;
  450. fetchData({
  451. kb_id: kbobj.id,
  452. ...basePagination
  453. });
  454. getKbdetail(kbobj.id);
  455. };
  456. const toTargetKnowledge = () => {
  457. if (tabs.value.length) {
  458. const index = tabs.value.findIndex((item) => item.id == props.kb_id);
  459. if (index !== -1) {
  460. selectTab(tabs.value[index]);
  461. }
  462. }
  463. };
  464. const getAut = (val) => {
  465. // const roleData = JSON.parse(getUserResources());
  466. // const roleBtn = roleData.map((item: any) => item.component);
  467. // return roleBtn.includes(val);
  468. return true;
  469. };
  470. const basePagination = {
  471. page: 1,
  472. page_size: 10
  473. };
  474. const pagination = reactive({
  475. ...basePagination
  476. });
  477. const densityList = computed(() => [
  478. {
  479. name: t('knowledgeLib.font_size.mini'),
  480. value: 'mini'
  481. },
  482. {
  483. name: t('knowledgeLib.font_size.small'),
  484. value: 'small'
  485. },
  486. {
  487. name: t('knowledgeLib.font_size.medium'),
  488. value: 'medium'
  489. },
  490. {
  491. name: t('knowledgeLib.font_size.large'),
  492. value: 'large'
  493. }
  494. ]);
  495. // const columns = computed(() => [
  496. // {
  497. // title: '名称',
  498. // dataIndex: 'name',
  499. // slotName: 'name',
  500. // width: 300
  501. // },
  502. // {
  503. // title: '分快数',
  504. // dataIndex: 'chunk_num',
  505. // width: 90
  506. // },
  507. // {
  508. // title: '上传时间',
  509. // dataIndex: 'create_time',
  510. // slotName: 'create_time',
  511. // width: 200
  512. // },
  513. // {
  514. // title: '解析方法',
  515. // dataIndex: 'parser_id',
  516. // slotName: 'parser_id',
  517. // width: 150
  518. // },
  519. // {
  520. // title: '启用',
  521. // dataIndex: 'status',
  522. // slotName: 'status',
  523. // width: 100
  524. // },
  525. // {
  526. // title: '解析状态',
  527. // dataIndex: 'run',
  528. // slotName: 'run',
  529. // width: 100
  530. // },
  531. // {
  532. // title: '操作',
  533. // dataIndex: 'action',
  534. // slotName: 'action',
  535. // width: 200,
  536. // minWidth: 200
  537. // }
  538. // ]);
  539. const columns = computed(() => {
  540. return getTableColumns(t);
  541. });
  542. const contentTypeOptions = computed(() => [
  543. {
  544. label: '图文',
  545. value: 'img'
  546. },
  547. {
  548. label: '横版短视频',
  549. value: 'horizontalVideo'
  550. },
  551. {
  552. label: '竖版小视频',
  553. value: 'verticalVideo'
  554. }
  555. ]);
  556. const filterTypeOptions = computed(() => [
  557. {
  558. label: '人工筛选',
  559. value: 'artificial'
  560. },
  561. {
  562. label: '规则筛选',
  563. value: 'rules'
  564. }
  565. ]);
  566. const statusOptions = computed(() => [
  567. {
  568. label: '已上线',
  569. value: 'online'
  570. },
  571. {
  572. label: '已下线',
  573. value: 'offline'
  574. }
  575. ]);
  576. const fetchData = async (params) => {
  577. setLoading(true);
  578. try {
  579. const data = await queryKbDocumentList(params);
  580. if (data.retcode == '0') {
  581. parser_ids = kbtenantInfo.parser_ids.split(',').reduce((acc, pair) => {
  582. const [key, value] = pair.split(':');
  583. acc[key] = value;
  584. return acc;
  585. }, {});
  586. kbtenantInfo.parser_idObj = parser_ids;
  587. renderData.value = data.data.docs || [];
  588. renderData.value = renderData.value.map((item) => {
  589. return {
  590. ...item,
  591. loading: false,
  592. parser_id: parser_ids[item.parser_id]
  593. };
  594. });
  595. pagination.page = params.page;
  596. pagination.current = params.page;
  597. pagination.total = data.data.total;
  598. // 定时器查询文档
  599. documentList();
  600. }
  601. } catch (err) {
  602. // you can report use errorHandler or other
  603. } finally {
  604. setLoading(false);
  605. }
  606. };
  607. const documentList = async () => {
  608. let params = { ...basePagination, kb_id: kbobj.id };
  609. const data = await queryKbDocumentList(params);
  610. if (data.retcode == '0') {
  611. parser_ids = kbtenantInfo.parser_ids.split(',').reduce((acc, pair) => {
  612. const [key, value] = pair.split(':');
  613. acc[key] = value;
  614. return acc;
  615. }, {});
  616. kbtenantInfo.parser_idObj = parser_ids;
  617. renderData.value = data.data.docs || [];
  618. renderData.value = renderData.value.map((item) => {
  619. return {
  620. ...item,
  621. loading: false,
  622. parser_id: parser_ids[item.parser_id]
  623. };
  624. });
  625. }
  626. };
  627. const search = () => {
  628. basePagination.page = 1;
  629. fetchData({
  630. kb_id: kbobj.id,
  631. ...basePagination,
  632. keywords: keywords.value
  633. });
  634. };
  635. const handleClick = (data) => {
  636. Object.assign(setObj, data);
  637. toolForm.value.handleClick(data);
  638. };
  639. const onPageChange = (current) => {
  640. basePagination.page = current;
  641. fetchData({ ...basePagination, kb_id: kbobj.id });
  642. };
  643. const selectTabAll = (val) => {
  644. checkedAll.value = val;
  645. };
  646. const selectTabChange = (val) => {
  647. checkedArr.value = val;
  648. };
  649. const knowledgeData = async (params = { page: 1, page_size: 10 }) => {
  650. listloading.value = true;
  651. try {
  652. const { data } = await queryKbList(params);
  653. tabs.value = data;
  654. if (tabs.value.length > 0 && tabs.value[0]) {
  655. // kbobj = tabs.value[0];
  656. // kbId = kbobj.id;
  657. // activeKey.value = '1';
  658. // basePagination.page = 1;
  659. fetchData({
  660. kb_id: props.kb_id,
  661. ...basePagination
  662. });
  663. toTargetKnowledge();
  664. // getKbdetail(kbobj.id);
  665. getKbdetail(props.kb_id);
  666. } else {
  667. }
  668. } catch (err) {
  669. // you can report use errorHandler or other
  670. } finally {
  671. listloading.value = false;
  672. }
  673. };
  674. const getKbdetail = async (kb_id) => {
  675. // 查询知识库详情
  676. const data = await queryKbdetail({
  677. kb_id: kb_id
  678. });
  679. kbdetail = data.data;
  680. testForm.value.changekbid(kbdetail.id);
  681. configForm.value.changekbObj(kbdetail);
  682. };
  683. const getknowledge = async (id) => {
  684. setLoading(true);
  685. try {
  686. const { data } = await queryKbList({ page: 1, page_size: 10 });
  687. tabs.value = data;
  688. if (tabs.value.length > 0) {
  689. // 定位到新增的知识库单元
  690. selectedTab.value = tabs.value.findIndex((item) => item.id == id);
  691. getKbdetail(id); // 获取详情
  692. kbobj.id = id;
  693. activeKey.value = '3';
  694. }
  695. } catch (err) {
  696. // you can report use errorHandler or other
  697. } finally {
  698. setLoading(false);
  699. }
  700. };
  701. const deleteKnowledge = (id) => {
  702. Modal.confirm({
  703. title: '提示信息',
  704. content: '确认删除吗',
  705. okText: '确定',
  706. cancelText: '取消',
  707. hideTitle: true,
  708. onOk: async () => {
  709. let data = await deleteKnow({
  710. kb_id: id
  711. });
  712. if (data.retcode == 0) {
  713. Message.success('删除成功');
  714. knowledgeData();
  715. }
  716. },
  717. onCancel: () => {}
  718. });
  719. };
  720. const reset = () => {
  721. formModel.value = generateFormModel();
  722. };
  723. function handleTabChange(key) {
  724. activeKey.value = key;
  725. }
  726. const handleSelectDensity = (val, e) => {
  727. size.value = val;
  728. };
  729. const cancleConfig = () => {
  730. activeKey.value = '1';
  731. let id = tabs.value[selectedTab.value].id;
  732. // basePagination.page = 1;
  733. // fetchData({
  734. // kb_id: id,
  735. // ...basePagination,
  736. // });
  737. };
  738. const saveConfig = async () => {
  739. activeKey.value = '1';
  740. let id = tabs.value[selectedTab.value].id;
  741. const { data } = await queryKbList({ page: 1, page_size: 10 });
  742. tabs.value = data;
  743. fetchData({
  744. kb_id: id,
  745. ...basePagination
  746. });
  747. getKbdetail(id); // 获取详情
  748. };
  749. const enableDisable = async (type) => {
  750. Promise.all(
  751. checkedArr.value.map(async (item) => {
  752. await changeStatus({
  753. doc_id: item,
  754. status: type
  755. });
  756. })
  757. ).then(() => {
  758. Message.success('更新成功');
  759. getKbList();
  760. });
  761. };
  762. //批量启用删除禁用
  763. const addBlock = async (type) => {
  764. if (type != 3) {
  765. //启动和取消
  766. let data = await kbdocumentrun({
  767. doc_ids: checkedArr.value,
  768. run: type
  769. });
  770. if (data.retcode == 0) {
  771. checkedArr.value.forEach(async (item) => {
  772. tabs.value.forEach(async (items) => {
  773. if (items.id == item) {
  774. items.loading = true;
  775. }
  776. });
  777. });
  778. getKbList();
  779. } else {
  780. // Message.error('解析失败');
  781. // row.run = '1';
  782. }
  783. } else {
  784. //批量删除
  785. Modal.confirm({
  786. title: '提示信息',
  787. content: '确认删除吗',
  788. okText: '确定',
  789. cancelText: '取消',
  790. hideTitle: true,
  791. onOk: async () => {
  792. let data = await kbdocumentrm({ doc_id: checkedArr.value });
  793. if (data.retcode == 0) {
  794. Message.success('删除成功');
  795. getKbList();
  796. // 同步数据
  797. toSyncOwnKnowledge(props.kb_id);
  798. }
  799. },
  800. onCancel: () => {}
  801. });
  802. }
  803. };
  804. const getKbList = async () => {
  805. await fetchData({
  806. kb_id: tabs.value[selectedTab.value].id,
  807. ...basePagination
  808. });
  809. };
  810. const exchangeArray = (array, beforeIdx, newIdx, isDeep = false) => {
  811. const newArray = isDeep ? cloneDeep(array) : array;
  812. if (beforeIdx > -1 && newIdx > -1) {
  813. // 先替换后面的,然后拿到替换的结果替换前面的
  814. newArray.splice(beforeIdx, 1, newArray.splice(newIdx, 1, newArray[beforeIdx]).pop());
  815. }
  816. return newArray;
  817. };
  818. function upTabdateItem(id, newName) {
  819. const itemToUpdate = renderData.value.find((item) => item.id === id);
  820. if (itemToUpdate) {
  821. itemToUpdate.name = newName;
  822. }
  823. }
  824. const deleteItem = async (row) => {
  825. let data = await kbdocumentrm({ doc_id: row.id });
  826. if (data.retcode == 0) {
  827. Message.success('删除成功');
  828. fetchData({
  829. kb_id: kbobj.id,
  830. ...basePagination
  831. });
  832. }
  833. };
  834. const onDownloadDocument = async (record) => {
  835. await downloadFile({
  836. url: `/api/v1/document/get/${record.id}`,
  837. filename: record.name
  838. });
  839. };
  840. const previewArea = async (row) => {
  841. Object.assign(seeObj, row);
  842. let type = row.name.split('.')[1];
  843. if (type == 'pdf') {
  844. documenttype.value = 'txtPdf';
  845. } else if (type == 'docx') {
  846. documenttype.value = 'docx';
  847. } else if (type == 'xlsx') {
  848. documenttype.value = 'excel';
  849. } else if (type == 'txt') {
  850. documenttype.value = 'txtPdf';
  851. } else {
  852. return false;
  853. }
  854. previewSrc.value = `${import.meta.env.VITE_API_BASE_URL}/v1/document/get/${row.id}`;
  855. // previewSrc.value = `${ httpUrl }/v1/document/get/${row.id}`
  856. visible.value = true;
  857. };
  858. const handleChangeStatus = async (row) => {
  859. // console.log(row);
  860. let data = await kbdocumentchangeStatus({
  861. doc_id: row.id,
  862. status: row.status
  863. });
  864. if (data.retcode == 0) {
  865. Message.success('操作成功');
  866. }
  867. };
  868. const run = async (row) => {
  869. row.loading = true;
  870. let run;
  871. if (row.run == '0') {
  872. run = '1';
  873. } else if (row.run == '1') {
  874. run = '2';
  875. } else if (row.run == '2') {
  876. run = '1';
  877. } else {
  878. run = '1';
  879. }
  880. let data = await kbdocumentrun({
  881. doc_ids: [row.id],
  882. run: run
  883. });
  884. if (data.retcode == 0) {
  885. // 定时器查询当前列表
  886. fetchData({
  887. kb_id: tabs.value[selectedTab.value].id,
  888. ...basePagination
  889. });
  890. } else {
  891. // Message.error('解析失败');
  892. // row.run = '1';
  893. }
  894. row.loading = false;
  895. };
  896. const changeFetchData = async (row) => {
  897. basePagination.page = 1;
  898. fetchData({
  899. kb_id: kbobj.id,
  900. ...basePagination
  901. });
  902. };
  903. const handlePreview = (file) => {
  904. if (file.type == 'doc') {
  905. window.open(`${window.RGFLOW_BASE_URL}/document/${file.id}?ext=docx&prefix=document`);
  906. } else if (file.type == 'pdf') {
  907. window.open(`${window.RGFLOW_BASE_URL}/v1/document/get/${file.id}`);
  908. }
  909. };
  910. watch(
  911. () => columns.value,
  912. (val) => {
  913. // alert(columns.value)
  914. cloneColumns.value = cloneDeep(val);
  915. cloneColumns.value.forEach((item, index) => {
  916. item.checked = true;
  917. });
  918. showColumns.value = cloneDeep(cloneColumns.value);
  919. },
  920. { deep: true, immediate: true }
  921. );
  922. onBeforeMount(async () => {
  923. // const {data} = await queryKbtenantInfo();
  924. // Object.assign(kbtenantInfo,data);
  925. // console.log(kbtenantInfo,'kbtenantInfo的数据');
  926. });
  927. onMounted(() => {
  928. knowledgeData();
  929. });
  930. onBeforeUnmount(() => {
  931. clearInterval(timer);
  932. });
  933. </script>
  934. <style scoped lang="css">
  935. .container {
  936. /* padding: 0 20px 20px 20px; */
  937. height: 100%;
  938. .main-container {
  939. display: flex;
  940. width: 100%;
  941. height: 100%;
  942. .lf-container {
  943. display: flex;
  944. flex-direction: column;
  945. align-items: center;
  946. border-radius: 8px;
  947. background: var(--color-bg-2);
  948. width: 200px;
  949. .lf-container-top {
  950. display: flex;
  951. margin: 10px 0;
  952. }
  953. .lf-container-down {
  954. display: flex;
  955. flex-direction: column;
  956. box-sizing: border-box;
  957. width: 90%;
  958. height: calc(100% - 80px);
  959. border: 1px solid var(--color-fill-3);
  960. border-radius: 8px;
  961. margin-bottom: 10px;
  962. .tab {
  963. cursor: pointer;
  964. box-sizing: border-box;
  965. margin: 10px 10px;
  966. padding: 0 10px;
  967. padding-right: 20%;
  968. font-size: 14px;
  969. height: 40px;
  970. line-height: 40px;
  971. list-style: none;
  972. position: relative;
  973. color: var(--color-text-1);
  974. border: 1px solid var(--color-neutral-3);
  975. background: var(--color-bg-2);
  976. border-radius: 8px;
  977. overflow: hidden; /* 确保超出容器的文本被隐藏 */
  978. white-space: nowrap; /* 防止文本换行 */
  979. text-overflow: ellipsis; /* 超出部分显示省略号 */
  980. }
  981. .tab:hover {
  982. color: #2a2a2b;
  983. border: 1px solid var(--color-neutral-3);
  984. background: #e8e8ea;
  985. box-shadow: 0 1px 2px -2px rgba(0, 0, 0, 0.16), 0 3px 6px 0 rgba(0, 0, 0, 0.12),
  986. 0 5px 12px 4px rgba(0, 0, 0, 0.09);
  987. }
  988. .tab.active {
  989. color: #2a2a2b;
  990. border: 1px solid var(--color-neutral-1);
  991. background: #e8e8ea;
  992. cursor: pointer;
  993. }
  994. }
  995. }
  996. .rt-container {
  997. position: relative;
  998. //background: #626aea;
  999. /* margin-left: 20px; */
  1000. /* width: calc(100% - 200px); */
  1001. overflow: hidden;
  1002. .rt-container-main {
  1003. overflow: auto;
  1004. }
  1005. .details {
  1006. position: absolute;
  1007. top: 0;
  1008. left: 0;
  1009. width: 100%;
  1010. height: 100%;
  1011. background: #ffffff;
  1012. .details-header {
  1013. display: flex;
  1014. justify-content: space-between;
  1015. margin-top: 10px;
  1016. padding-right: 20px;
  1017. }
  1018. }
  1019. }
  1020. }
  1021. }
  1022. :deep(.arco-table-th) {
  1023. &:last-child {
  1024. .arco-table-th-item-title {
  1025. margin-left: 16px;
  1026. }
  1027. }
  1028. }
  1029. .action-icon {
  1030. margin-left: 12px;
  1031. cursor: pointer;
  1032. }
  1033. .active {
  1034. color: #0960bd;
  1035. background-color: #e3f4fc;
  1036. }
  1037. .setting {
  1038. display: flex;
  1039. align-items: center;
  1040. width: 200px;
  1041. .title {
  1042. margin-left: 12px;
  1043. cursor: pointer;
  1044. }
  1045. }
  1046. .popover-content {
  1047. max-height: 500px;
  1048. overflow: auto;
  1049. }
  1050. </style>