index.vue 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. <!--
  2. - Copyright (c) 2024 LangChat. TyCoding All Rights Reserved.
  3. -
  4. - Licensed under the GNU Affero General Public License, Version 3 (the "License");
  5. - you may not use this file except in compliance with the License.
  6. - You may obtain a copy of the License at
  7. -
  8. - https://www.gnu.org/licenses/agpl-3.0.html
  9. -
  10. - Unless required by applicable law or agreed to in writing, software
  11. - distributed under the License is distributed on an "AS IS" BASIS,
  12. - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. - See the License for the specific language governing permissions and
  14. - limitations under the License.
  15. -->
  16. <script lang="ts" setup>
  17. import DocList from './DocsList/index.vue';
  18. import DocsSlice from './DocsSlice/index.vue';
  19. import SvgIcon from '@/components/SvgIcon/index.vue';
  20. import DocsSliceSearch from './DocsSliceSearch/index.vue';
  21. import ImportFile from './ImportFile/index.vue';
  22. import { onMounted, ref } from 'vue';
  23. import { NIcon } from 'naive-ui';
  24. import { useRouter } from 'vue-router';
  25. import { renderIcon } from '@/utils';
  26. import {
  27. AlbumsOutline,
  28. ArrowUndoOutline,
  29. CloudUploadOutline,
  30. DocumentTextOutline,
  31. SearchOutline,
  32. } from '@vicons/ionicons5';
  33. import { getById } from '@/api/aigc/knowledge';
  34. const router = useRouter();
  35. const active = ref('import-file');
  36. const menuOptions = ref([
  37. {
  38. label: '数据导入',
  39. key: 'import-file',
  40. icon: renderIcon(CloudUploadOutline),
  41. },
  42. {
  43. label: '文档管理',
  44. key: 'doc-list',
  45. icon: renderIcon(DocumentTextOutline),
  46. },
  47. ]);
  48. const knowledge = ref<any>({});
  49. onMounted(async () => {
  50. const id = router.currentRoute.value.params.id;
  51. knowledge.value = await getById(String(id));
  52. active.value = menuOptions.value[0].key;
  53. menuOptions.value.push(
  54. {
  55. label: '切片管理',
  56. key: 'slice-list',
  57. icon: renderIcon(AlbumsOutline),
  58. },
  59. {
  60. label: '向量搜索',
  61. key: 'slice-search',
  62. icon: renderIcon(SearchOutline),
  63. }
  64. );
  65. });
  66. function handleSelect(key: string) {
  67. active.value = key;
  68. }
  69. function handleReturn() {
  70. router.back();
  71. }
  72. </script>
  73. <template>
  74. <div class="mt-2" style="height: calc(100vh - 130px) !important">
  75. <n-grid :x-gap="13" class="h-full" cols="2 s:2 m:2 l:24 xl:24 2xl:24" responsive="screen">
  76. <n-gi class="bg-white p-4 rounded-md" span="5">
  77. <n-button block class="mb-4" dashed size="small" type="primary" @click="handleReturn">
  78. 知识库列表
  79. <template #icon>
  80. <n-icon>
  81. <ArrowUndoOutline />
  82. </n-icon>
  83. </template>
  84. </n-button>
  85. <div class="flex items-center gap-2">
  86. <div class="relative bg-blue-100 p-2 rounded">
  87. <SvgIcon class="text-lg" icon="ep:document" />
  88. </div>
  89. <span class="font-semibold text-[16px]">{{ knowledge.name }}</span>
  90. </div>
  91. <div class="text-[13px] text-gray-400 mt-3">{{ knowledge.des }}</div>
  92. <n-divider class="my-3" />
  93. <div class="my-3 flex flex-col gap-2">
  94. <div class="text-xs">知识库ID</div>
  95. <n-input v-model:value="knowledge.id" />
  96. </div>
  97. <div class="my-3 flex flex-col gap-2">
  98. <div class="text-xs">关联向量数据库</div>
  99. <div v-if="knowledge.embedStore == null" class="py-2 text-gray-400"
  100. >没有配置关联向量数据库</div
  101. >
  102. <n-input v-else v-model:value="knowledge.embedStore.name" />
  103. </div>
  104. <div class="my-3 flex flex-col gap-2">
  105. <div class="text-xs">关联向量化模型</div>
  106. <div v-if="knowledge.embedModel == null" class="py-2 text-gray-400"
  107. >没有配置关联向量化模型</div
  108. >
  109. <n-input v-else v-model:value="knowledge.embedModel.name" />
  110. </div>
  111. </n-gi>
  112. <n-gi class="h-full bg-white p-4 overflow-y-auto rounded-md" span="19">
  113. <n-tabs v-model:value="active" class="flex items-center mb-6" @update:value="handleSelect">
  114. <n-tab v-for="item in menuOptions" :key="item.key" :name="item.key">
  115. <component :is="item.icon" />
  116. <span class="pl-2 font-bold">{{ item.label }}</span>
  117. </n-tab>
  118. </n-tabs>
  119. <n-tabs />
  120. <DocList v-if="active == 'doc-list'" />
  121. <DocsSlice v-if="active == 'slice-list'" />
  122. <DocsSliceSearch v-if="active == 'slice-search'" />
  123. <ImportFile v-if="active == 'import-file'" :data="knowledge" />
  124. </n-gi>
  125. </n-grid>
  126. </div>
  127. </template>
  128. <style lang="less" scoped></style>