index.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. <template>
  2. <ContentWrap>
  3. <!-- 搜索工作栏 -->
  4. <el-form
  5. class="-mb-15px"
  6. :model="queryParams"
  7. ref="queryFormRef"
  8. :inline="true"
  9. label-width="68px"
  10. >
  11. <el-form-item label="文档编号" prop="documentId">
  12. <el-input
  13. v-model="queryParams.documentId"
  14. placeholder="请输入文档编号"
  15. clearable
  16. @keyup.enter="handleQuery"
  17. class="!w-240px"
  18. />
  19. </el-form-item>
  20. <el-form-item label="是否启用" prop="status">
  21. <el-select
  22. v-model="queryParams.status"
  23. placeholder="请选择是否启用"
  24. clearable
  25. class="!w-240px"
  26. >
  27. <el-option
  28. v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
  29. :key="dict.value"
  30. :label="dict.label"
  31. :value="dict.value"
  32. />
  33. </el-select>
  34. </el-form-item>
  35. <el-form-item>
  36. <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
  37. <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
  38. <el-button
  39. type="primary"
  40. plain
  41. @click="openForm('create')"
  42. v-hasPermi="['ai:knowledge:create']"
  43. >
  44. <Icon icon="ep:plus" class="mr-5px" /> 新增
  45. </el-button>
  46. </el-form-item>
  47. </el-form>
  48. </ContentWrap>
  49. <!-- 列表 -->
  50. <ContentWrap>
  51. <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
  52. <el-table-column label="分段编号" align="center" prop="id" />
  53. <el-table-column type="expand">
  54. <template #default="props">
  55. <div
  56. class="content-expand"
  57. style="
  58. padding: 10px 20px;
  59. white-space: pre-wrap;
  60. line-height: 1.5;
  61. background-color: #f9f9f9;
  62. border-radius: 4px;
  63. border-left: 3px solid #409eff;
  64. "
  65. >
  66. <div
  67. class="content-title"
  68. style="margin-bottom: 8px; color: #606266; font-size: 14px; font-weight: bold"
  69. >
  70. 完整内容:
  71. </div>
  72. {{ props.row.content }}
  73. </div>
  74. </template>
  75. </el-table-column>
  76. <el-table-column
  77. label="切片内容"
  78. align="center"
  79. prop="content"
  80. min-width="250px"
  81. :show-overflow-tooltip="true"
  82. />
  83. <el-table-column label="字符数" align="center" prop="contentLength" />
  84. <el-table-column label="token 数量" align="center" prop="tokens" />
  85. <el-table-column label="召回次数" align="center" prop="retrievalCount" />
  86. <el-table-column label="是否启用" align="center" prop="status">
  87. <template #default="scope">
  88. <el-switch
  89. v-model="scope.row.status"
  90. :active-value="0"
  91. :inactive-value="1"
  92. @change="handleStatusChange(scope.row)"
  93. :disabled="!checkPermi(['ai:knowledge:update'])"
  94. />
  95. </template>
  96. </el-table-column>
  97. <el-table-column
  98. label="创建时间"
  99. align="center"
  100. prop="createTime"
  101. :formatter="dateFormatter"
  102. width="180px"
  103. />
  104. <el-table-column label="操作" align="center" min-width="120px">
  105. <template #default="scope">
  106. <el-button
  107. link
  108. type="primary"
  109. @click="openForm('update', scope.row.id)"
  110. v-hasPermi="['ai:knowledge:update']"
  111. >
  112. 编辑
  113. </el-button>
  114. <el-button
  115. link
  116. type="danger"
  117. @click="handleDelete(scope.row.id)"
  118. v-hasPermi="['ai:knowledge:delete']"
  119. >
  120. 删除
  121. </el-button>
  122. </template>
  123. </el-table-column>
  124. </el-table>
  125. <!-- 分页 -->
  126. <Pagination
  127. :total="total"
  128. v-model:page="queryParams.pageNo"
  129. v-model:limit="queryParams.pageSize"
  130. @pagination="getList"
  131. />
  132. </ContentWrap>
  133. <!-- 表单弹窗:添加/修改 -->
  134. <KnowledgeSegmentForm ref="formRef" @success="getList" />
  135. </template>
  136. <script setup lang="ts">
  137. import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
  138. import { dateFormatter } from '@/utils/formatTime'
  139. import { KnowledgeSegmentApi, KnowledgeSegmentVO } from '@/api/ai/knowledge/segment'
  140. import KnowledgeSegmentForm from './KnowledgeSegmentForm.vue'
  141. import { CommonStatusEnum } from '@/utils/constants'
  142. import { checkPermi } from '@/utils/permission'
  143. /** AI 知识库分段 列表 */
  144. defineOptions({ name: 'KnowledgeSegment' })
  145. const message = useMessage() // 消息弹窗
  146. const router = useRouter() // 路由
  147. const route = useRoute() // 路由
  148. const { t } = useI18n() // 国际化
  149. const loading = ref(true) // 列表的加载中
  150. const list = ref<KnowledgeSegmentVO[]>([]) // 列表的数据
  151. const total = ref(0) // 列表的总页数
  152. const queryParams = reactive({
  153. pageNo: 1,
  154. pageSize: 10,
  155. documentId: undefined,
  156. content: undefined,
  157. status: undefined
  158. })
  159. const queryFormRef = ref() // 搜索的表单
  160. /** 查询列表 */
  161. const getList = async () => {
  162. loading.value = true
  163. try {
  164. const data = await KnowledgeSegmentApi.getKnowledgeSegmentPage(queryParams)
  165. list.value = data.list
  166. total.value = data.total
  167. } finally {
  168. loading.value = false
  169. }
  170. }
  171. /** 搜索按钮操作 */
  172. const handleQuery = () => {
  173. queryParams.pageNo = 1
  174. getList()
  175. }
  176. /** 重置按钮操作 */
  177. const resetQuery = () => {
  178. queryFormRef.value.resetFields()
  179. handleQuery()
  180. }
  181. /** 添加/修改操作 */
  182. const formRef = ref()
  183. const openForm = (type: string, id?: number) => {
  184. formRef.value.open(type, id, queryParams.documentId)
  185. }
  186. /** 删除按钮操作 */
  187. const handleDelete = async (id: number) => {
  188. try {
  189. // 删除的二次确认
  190. await message.delConfirm()
  191. // 发起删除
  192. await KnowledgeSegmentApi.deleteKnowledgeSegment(id)
  193. message.success(t('common.delSuccess'))
  194. // 刷新列表
  195. await getList()
  196. } catch {}
  197. }
  198. /** 修改状态操作 */
  199. const handleStatusChange = async (row: KnowledgeSegmentVO) => {
  200. try {
  201. // 修改状态的二次确认
  202. const text = row.status === CommonStatusEnum.ENABLE ? '启用' : '禁用'
  203. await message.confirm('确认要"' + text + '"该分段吗?')
  204. // 发起修改状态
  205. await KnowledgeSegmentApi.updateKnowledgeSegmentStatus({ id: row.id, status: row.status })
  206. message.success(t('common.updateSuccess'))
  207. // 刷新列表
  208. await getList()
  209. } catch {
  210. // 取消后,进行恢复按钮
  211. row.status =
  212. row.status === CommonStatusEnum.ENABLE ? CommonStatusEnum.DISABLE : CommonStatusEnum.ENABLE
  213. }
  214. }
  215. /** 初始化 **/
  216. onMounted(() => {
  217. // 如果文档 ID 不存在,显示错误提示并关闭页面
  218. if (!route.query.documentId) {
  219. message.error('文档 ID 不存在,无法查看分段列表')
  220. // 关闭当前路由,返回到文档列表页面
  221. router.push({ name: 'AiKnowledgeDocument' })
  222. return
  223. }
  224. // 从路由参数中获取文档 ID
  225. queryParams.documentId = route.query.documentId as any
  226. getList()
  227. })
  228. </script>