|
@@ -109,9 +109,13 @@
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
<div class="tab-actions">
|
|
<div class="tab-actions">
|
|
|
|
|
+ <select class="form-select" v-if="activeTab=='all'" v-model="categoryId" @change="changeCategory" style="width: 250px;">
|
|
|
|
|
+ <option value="">选择分类</option>
|
|
|
|
|
+ <option v-for="cat in categories" :key="cat.id" :value="cat.id">{{ cat.name }}</option>
|
|
|
|
|
+ </select>
|
|
|
<div class="search-box">
|
|
<div class="search-box">
|
|
|
<i class="fas fa-search search-icon"></i>
|
|
<i class="fas fa-search search-icon"></i>
|
|
|
- <input type="text" v-model="searchQuery" class="search-input" placeholder="搜索知识...">
|
|
|
|
|
|
|
+ <input type="text" v-model="searchQuery" class="search-input" @input="searchData" placeholder="搜索知识...">
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
@@ -153,11 +157,14 @@
|
|
|
<div class="pagination-area">
|
|
<div class="pagination-area">
|
|
|
<el-pagination
|
|
<el-pagination
|
|
|
background
|
|
background
|
|
|
- layout="prev, pager, next"
|
|
|
|
|
- :total="1000">
|
|
|
|
|
|
|
+ :total="categoriesTotal"
|
|
|
|
|
+ style="text-align: right;"
|
|
|
|
|
+ :current-page="knowledgeParams.pageIndex"
|
|
|
|
|
+ :page-size="knowledgeParams.pageSize"
|
|
|
|
|
+ layout="total, prev, pager, next"
|
|
|
|
|
+ @current-change="knowledgeCurrentChange">
|
|
|
</el-pagination>
|
|
</el-pagination>
|
|
|
</div>
|
|
</div>
|
|
|
-
|
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<!-- 全部知识 Tab -->
|
|
<!-- 全部知识 Tab -->
|
|
@@ -165,7 +172,7 @@
|
|
|
<div class="knowledge-list">
|
|
<div class="knowledge-list">
|
|
|
<div v-for="item in knowledgeList" :key="item.id"
|
|
<div v-for="item in knowledgeList" :key="item.id"
|
|
|
class="knowledge-card"
|
|
class="knowledge-card"
|
|
|
- @click="showKnowledgeDetail(item)">
|
|
|
|
|
|
|
+ @click="showDocumentDetail(item)">
|
|
|
<!-- <div class="knowledge-icon" :style="{ background: item.iconBg }">{{ item.icon }}</div> -->
|
|
<!-- <div class="knowledge-icon" :style="{ background: item.iconBg }">{{ item.icon }}</div> -->
|
|
|
<div class="knowledge-content">
|
|
<div class="knowledge-content">
|
|
|
<div class="knowledge-header">
|
|
<div class="knowledge-header">
|
|
@@ -189,6 +196,17 @@
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+ <div class="pagination-area">
|
|
|
|
|
+ <el-pagination
|
|
|
|
|
+ background
|
|
|
|
|
+ :total="categoryTotal"
|
|
|
|
|
+ style="text-align: right;"
|
|
|
|
|
+ :current-page="documentsParams.pageIndex"
|
|
|
|
|
+ :page-size="documentsParams.pageSize"
|
|
|
|
|
+ layout="total, prev, pager, next"
|
|
|
|
|
+ @current-change="categoryPageCurrentChange">
|
|
|
|
|
+ </el-pagination>
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<!-- 问答记录 Tab -->
|
|
<!-- 问答记录 Tab -->
|
|
@@ -237,6 +255,17 @@
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+ <div class="pagination-area">
|
|
|
|
|
+ <el-pagination
|
|
|
|
|
+ background
|
|
|
|
|
+ :total="qaRecordsTotal"
|
|
|
|
|
+ style="text-align: right;"
|
|
|
|
|
+ :current-page="chatParams.pageIndex"
|
|
|
|
|
+ :page-size="chatParams.pageSize"
|
|
|
|
|
+ layout="total, prev, pager, next"
|
|
|
|
|
+ @current-change="chatPageCurrentChange">
|
|
|
|
|
+ </el-pagination>
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
@@ -279,6 +308,18 @@
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+ <div class="pagination-area">
|
|
|
|
|
+ <el-pagination
|
|
|
|
|
+ background
|
|
|
|
|
+ :total="trainingTasksTotal"
|
|
|
|
|
+ style="text-align: right;"
|
|
|
|
|
+ :current-page="trainingParams.pageIndex"
|
|
|
|
|
+ :page-size="trainingParams.pageSize"
|
|
|
|
|
+ layout="total, prev, pager, next"
|
|
|
|
|
+ @current-change="tasksPageCurrentChange">
|
|
|
|
|
+ </el-pagination>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
@@ -354,7 +395,7 @@
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
- <!-- Add Knowledge Modal -->
|
|
|
|
|
|
|
+ <!-- 添加知识弹窗 -->
|
|
|
<div v-if="showAddModal" class="modal-overlay" @click.self="showAddModal = false">
|
|
<div v-if="showAddModal" class="modal-overlay" @click.self="showAddModal = false">
|
|
|
<div class="modal add-modal">
|
|
<div class="modal add-modal">
|
|
|
<div class="modal-header">
|
|
<div class="modal-header">
|
|
@@ -393,6 +434,59 @@
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
+ <!-- 知识文本块列表弹窗 -->
|
|
|
|
|
+ <div v-if="showChunksModal" class="modal-overlay" @click.self="showChunksModal = false">
|
|
|
|
|
+ <div class="modal import-modal" style="min-width: 1000px;">
|
|
|
|
|
+ <div class="modal-header">
|
|
|
|
|
+ <div class="modal-title"><i class="fas fa-file-import"></i> {{ documentName }}</div>
|
|
|
|
|
+ <button class="modal-close" @click="showChunksModal = false"><i class="fas fa-times"></i></button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="modal-body">
|
|
|
|
|
+ <div class="knowledge-list" v-loading="chunkLoading" element-loading-background="rgba(0, 0, 0, 0.8)">
|
|
|
|
|
+ <div v-for="item in chunkList" :key="item.id"
|
|
|
|
|
+ class="knowledge-card"
|
|
|
|
|
+ @click="showKnowledgeDetail(item)">
|
|
|
|
|
+ <!-- <div class="knowledge-icon" :style="{ background: item.iconBg }">{{ item.icon }}</div> -->
|
|
|
|
|
+ <div class="knowledge-content">
|
|
|
|
|
+ <div class="knowledge-header">
|
|
|
|
|
+ <div class="knowledge-question">{{ item.sign_content }}</div>
|
|
|
|
|
+ <!-- <span class="knowledge-category" :style="{ background: item.iconBg }">{{ item.categoryName }}</span> -->
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="knowledge-answer">{{ item.answer }}</div>
|
|
|
|
|
+ <!-- <div class="knowledge-meta">
|
|
|
|
|
+ <span><i class="fas fa-eye"></i> {{ item.views }}次查看</span>
|
|
|
|
|
+ <span><i class="fas fa-thumbs-up"></i> {{ item.likes }}次好评</span>
|
|
|
|
|
+ <span><i class="fas fa-clock"></i> {{ item.time }}</span>
|
|
|
|
|
+ </div> -->
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="knowledge-actions" @click.stop>
|
|
|
|
|
+ <button class="btn btn-secondary btn-sm" @click="editKnowledge(item)">
|
|
|
|
|
+ <i class="fas fa-edit"></i>
|
|
|
|
|
+ </button>
|
|
|
|
|
+ <button class="btn btn-secondary btn-sm" @click="deleteKnowledge(item)">
|
|
|
|
|
+ <i class="fas fa-trash"></i>
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="pagination-area">
|
|
|
|
|
+ <el-pagination
|
|
|
|
|
+ background
|
|
|
|
|
+ :total="chunksTotal"
|
|
|
|
|
+ style="text-align: right;padding: 0px;"
|
|
|
|
|
+ :current-page="chunkParams.pageIndex"
|
|
|
|
|
+ :page-size="chunkParams.pageSize"
|
|
|
|
|
+ layout="total, prev, pager, next"
|
|
|
|
|
+ @current-change="chunkCurrentChange">
|
|
|
|
|
+ </el-pagination>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="modal-footer">
|
|
|
|
|
+ <button class="btn btn-secondary" @click="showChunksModal = false">关闭</button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
<!-- Knowledge Detail Modal -->
|
|
<!-- Knowledge Detail Modal -->
|
|
|
<div v-if="showDetailModal && selectedKnowledge" class="modal-overlay" @click.self="showDetailModal = false">
|
|
<div v-if="showDetailModal && selectedKnowledge" class="modal-overlay" @click.self="showDetailModal = false">
|
|
|
<div class="modal detail-modal">
|
|
<div class="modal detail-modal">
|
|
@@ -515,6 +609,7 @@
|
|
|
|
|
|
|
|
<div class="import-zone">
|
|
<div class="import-zone">
|
|
|
<el-upload
|
|
<el-upload
|
|
|
|
|
+ ref="uploadRef"
|
|
|
class="upload-demo"
|
|
class="upload-demo"
|
|
|
drag
|
|
drag
|
|
|
action=""
|
|
action=""
|
|
@@ -524,14 +619,14 @@
|
|
|
multiple>
|
|
multiple>
|
|
|
<div class="import-icon"><i class="fas fa-cloud-upload-alt"></i></div>
|
|
<div class="import-icon"><i class="fas fa-cloud-upload-alt"></i></div>
|
|
|
<div class="import-text">拖拽文件到此处,或点击上传</div>
|
|
<div class="import-text">拖拽文件到此处,或点击上传</div>
|
|
|
- <div class="import-formats">支持 Excel、CSV、JSON、PDF 格式</div>
|
|
|
|
|
|
|
+ <div class="import-formats">支持 Excel、CSV、JSON、PDF、TXT、DOC、MD 格式</div>
|
|
|
</el-upload>
|
|
</el-upload>
|
|
|
</div>
|
|
</div>
|
|
|
<div class="import-options">
|
|
<div class="import-options">
|
|
|
<div class="import-option" v-for="item in fileListRaw" :key="item.name">
|
|
<div class="import-option" v-for="item in fileListRaw" :key="item.name">
|
|
|
<i class="fas fa-file-excel"></i>
|
|
<i class="fas fa-file-excel"></i>
|
|
|
<span>{{ item.name }}</span>
|
|
<span>{{ item.name }}</span>
|
|
|
- <button icon="el-icon-edit"></button>
|
|
|
|
|
|
|
+ <i class="fas fa-times" style="color: #fff;cursor: pointer;" @click="delFile(item)"></i>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
@@ -555,7 +650,7 @@
|
|
|
|
|
|
|
|
<script setup>
|
|
<script setup>
|
|
|
import { ref, computed } from 'vue'
|
|
import { ref, computed } from 'vue'
|
|
|
-import { knowledgeDatasets,knowledgeDocuments,createKnowledge,chatMessages,baseTraining,creatTraining,baseStatistics } from '../api/knowledge'
|
|
|
|
|
|
|
+import { knowledgeDatasets,knowledgeDocuments,createKnowledge,chatMessages,baseTraining,creatTraining,baseStatistics,getAllChunks,getAllDocumnets,delDocuments,delChunk } from '../api/knowledge'
|
|
|
import { formatTimeAgo } from '@/utils/time'
|
|
import { formatTimeAgo } from '@/utils/time'
|
|
|
import { ElMessage } from 'element-plus'
|
|
import { ElMessage } from 'element-plus'
|
|
|
|
|
|
|
@@ -563,7 +658,10 @@ const showAddModal = ref(false)
|
|
|
const showDetailModal = ref(false)
|
|
const showDetailModal = ref(false)
|
|
|
const showImportModal = ref(false)
|
|
const showImportModal = ref(false)
|
|
|
const showTrainModal = ref(false)
|
|
const showTrainModal = ref(false)
|
|
|
|
|
+const showChunksModal = ref(false)
|
|
|
|
|
+const chunkLoading = ref(false)
|
|
|
const selectedKnowledge = ref(null)
|
|
const selectedKnowledge = ref(null)
|
|
|
|
|
+const selectedDocument = ref(null)
|
|
|
const activeTab = ref('categories')
|
|
const activeTab = ref('categories')
|
|
|
const searchQuery = ref('')
|
|
const searchQuery = ref('')
|
|
|
const qaFilter = ref('all')
|
|
const qaFilter = ref('all')
|
|
@@ -643,51 +741,126 @@ const getBaseStatistics = () => {
|
|
|
baseStatistics().then(res => {
|
|
baseStatistics().then(res => {
|
|
|
knowledgeStats.value = res.result
|
|
knowledgeStats.value = res.result
|
|
|
tabs.value[1].count = res.result.totalDocuments
|
|
tabs.value[1].count = res.result.totalDocuments
|
|
|
- console.log('res :>> ', res);
|
|
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
getBaseStatistics()
|
|
getBaseStatistics()
|
|
|
|
|
|
|
|
|
|
|
|
|
const changeTab = (tab)=>{
|
|
const changeTab = (tab)=>{
|
|
|
|
|
+ searchQuery.value = ''
|
|
|
|
|
+ categoryId.value = ''
|
|
|
activeTab.value = tab
|
|
activeTab.value = tab
|
|
|
- if(tab =='qa'){
|
|
|
|
|
- getChatMessages()
|
|
|
|
|
|
|
+ searchData()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const searchData = () => {
|
|
|
|
|
+ switch (activeTab.value) {
|
|
|
|
|
+ case 'categories':
|
|
|
|
|
+ getKnowledgeDatasets()
|
|
|
|
|
+ break
|
|
|
|
|
+ case 'all':
|
|
|
|
|
+ getCategoryList()
|
|
|
|
|
+ break
|
|
|
|
|
+ case 'qa':
|
|
|
|
|
+ getChatMessages()
|
|
|
|
|
+ break
|
|
|
|
|
+ case 'training':
|
|
|
|
|
+ getTraining()
|
|
|
|
|
+ break
|
|
|
|
|
+ default:
|
|
|
|
|
+ return '未知状态'
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
const categories = ref([])
|
|
const categories = ref([])
|
|
|
|
|
+const categoriesTotal = ref()
|
|
|
|
|
+const knowledgeParams=ref({
|
|
|
|
|
+ pageIndex: 1,
|
|
|
|
|
+ pageSize: 10,
|
|
|
|
|
+ keyword:'',
|
|
|
|
|
+})
|
|
|
// 获取知识分类
|
|
// 获取知识分类
|
|
|
const getKnowledgeDatasets = () => {
|
|
const getKnowledgeDatasets = () => {
|
|
|
- knowledgeDatasets({ pageIndex: 1, pageSize: 10 }).then(res => {
|
|
|
|
|
|
|
+ knowledgeParams.value.keyword = searchQuery.value
|
|
|
|
|
+ knowledgeDatasets(knowledgeParams.value).then(res => {
|
|
|
categories.value = res.result.data
|
|
categories.value = res.result.data
|
|
|
res.result.data.forEach(el => {
|
|
res.result.data.forEach(el => {
|
|
|
el.timeip = formatTimeAgo(el.updated_at)
|
|
el.timeip = formatTimeAgo(el.updated_at)
|
|
|
});
|
|
});
|
|
|
- tabs.value[0].count = res.result.total
|
|
|
|
|
- console.log('res :>> ', res);
|
|
|
|
|
|
|
+ tabs.value[0].count = categoriesTotal.value = res.result.total
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
getKnowledgeDatasets()
|
|
getKnowledgeDatasets()
|
|
|
|
|
+const knowledgeCurrentChange = (page) => {
|
|
|
|
|
+ knowledgeParams.value.pageIndex = page
|
|
|
|
|
+ getKnowledgeDatasets()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const changeCategory = () => {
|
|
|
|
|
+ getCategoryList(categoryId.value)
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
const knowledgeList = ref([])
|
|
const knowledgeList = ref([])
|
|
|
-// 获取知识分类下的知识
|
|
|
|
|
-const documentsParams = ref({})
|
|
|
|
|
|
|
+// 获取知识列表
|
|
|
|
|
+const categoryId = ref()
|
|
|
|
|
+const categoryTotal = ref()
|
|
|
|
|
+const documentsParams = ref({
|
|
|
|
|
+ pageIndex:1,
|
|
|
|
|
+ pageSize:10,
|
|
|
|
|
+ dataset_id:'',
|
|
|
|
|
+ keyword:''
|
|
|
|
|
+})
|
|
|
const openCategory = (category) => {
|
|
const openCategory = (category) => {
|
|
|
activeTab.value = 'all'
|
|
activeTab.value = 'all'
|
|
|
- searchQuery.value = category.name
|
|
|
|
|
showToastMessage(`正在加载 ${category.name} 分类...`, 'success')
|
|
showToastMessage(`正在加载 ${category.name} 分类...`, 'success')
|
|
|
- documentsParams.value = {
|
|
|
|
|
- pageIndex:1,
|
|
|
|
|
- pageSize:10,
|
|
|
|
|
- dataset_id:category.id
|
|
|
|
|
- }
|
|
|
|
|
- knowledgeDocuments(documentsParams.value).then(res => {
|
|
|
|
|
|
|
+ getCategoryList(category.id)
|
|
|
|
|
+}
|
|
|
|
|
+const getCategoryList = (id) => {
|
|
|
|
|
+ categoryId.value = id?id:''
|
|
|
|
|
+ documentsParams.value.dataset_id = id?id:''
|
|
|
|
|
+ documentsParams.value.keyword = searchQuery.value
|
|
|
|
|
+ getAllDocumnets(documentsParams.value).then(res => {
|
|
|
|
|
+ console.log(res)
|
|
|
knowledgeList.value = res.result.data
|
|
knowledgeList.value = res.result.data
|
|
|
- tabs.value[1].count = res.result.total
|
|
|
|
|
|
|
+ tabs.value[1].count = categoryTotal.value = res.result.total
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
+getCategoryList()
|
|
|
|
|
+const categoryPageCurrentChange = (page) => {
|
|
|
|
|
+ documentsParams.value.pageIndex = page
|
|
|
|
|
+ getCategoryList(categoryId.value)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 获取知识列表下的知识块
|
|
|
|
|
+const chunkList = ref([])
|
|
|
|
|
+const chunksTotal = ref()
|
|
|
|
|
+const chunkParams=ref({
|
|
|
|
|
+ pageIndex: 1,
|
|
|
|
|
+ pageSize: 10,
|
|
|
|
|
+ dataset_id:'',
|
|
|
|
|
+ document_id:'',
|
|
|
|
|
+})
|
|
|
|
|
+// 获取知识分类
|
|
|
|
|
+const getChunkDatasets = () => {
|
|
|
|
|
+ chunkLoading.value = true
|
|
|
|
|
+ getAllChunks(chunkParams.value).then(res => {
|
|
|
|
|
+ chunkLoading.value = false
|
|
|
|
|
+ chunkList.value = res.result.data
|
|
|
|
|
+ res.result.data.forEach(el => {
|
|
|
|
|
+ el.timeip = formatTimeAgo(el.updated_at)
|
|
|
|
|
+ });
|
|
|
|
|
+ chunksTotal.value = res.result.total
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+const chunkCurrentChange = (page) => {
|
|
|
|
|
+ chunkParams.value.pageIndex = page
|
|
|
|
|
+ getChunkDatasets()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
|
|
|
const qaRecords = ref([])
|
|
const qaRecords = ref([])
|
|
|
|
|
+const qaRecordsTotal = ref()
|
|
|
// 获取问答记录
|
|
// 获取问答记录
|
|
|
const chatParams=ref({
|
|
const chatParams=ref({
|
|
|
pageIndex: 1,
|
|
pageIndex: 1,
|
|
@@ -695,18 +868,24 @@ const chatParams=ref({
|
|
|
keyword:'',
|
|
keyword:'',
|
|
|
})
|
|
})
|
|
|
const getChatMessages = () => {
|
|
const getChatMessages = () => {
|
|
|
|
|
+ chatParams.value.keyword = searchQuery.value
|
|
|
chatMessages(chatParams.value).then(res => {
|
|
chatMessages(chatParams.value).then(res => {
|
|
|
- tabs.value[2].count = res.result.total
|
|
|
|
|
|
|
+ tabs.value[2].count = qaRecordsTotal.value = res.result.total
|
|
|
res.result.records.forEach(el => {
|
|
res.result.records.forEach(el => {
|
|
|
el.time = formatTimeAgo(el.createdAt)
|
|
el.time = formatTimeAgo(el.createdAt)
|
|
|
});
|
|
});
|
|
|
qaRecords.value = res.result.records
|
|
qaRecords.value = res.result.records
|
|
|
- console.log('res :>> ', res);
|
|
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
getChatMessages()
|
|
getChatMessages()
|
|
|
|
|
+const chatPageCurrentChange = (page) => {
|
|
|
|
|
+ chatParams.value.pageIndex = page
|
|
|
|
|
+ getChatMessages()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
|
|
|
const trainingTasks = ref([])
|
|
const trainingTasks = ref([])
|
|
|
|
|
+const trainingTasksTotal = ref()
|
|
|
//获取ai训练列表
|
|
//获取ai训练列表
|
|
|
const trainingParams=ref({
|
|
const trainingParams=ref({
|
|
|
pageIndex: 1,
|
|
pageIndex: 1,
|
|
@@ -714,18 +893,29 @@ const trainingParams=ref({
|
|
|
keyword:'',
|
|
keyword:'',
|
|
|
})
|
|
})
|
|
|
const getTraining = () => {
|
|
const getTraining = () => {
|
|
|
|
|
+ trainingParams.value.keyword = searchQuery.value
|
|
|
baseTraining(trainingParams.value).then(res => {
|
|
baseTraining(trainingParams.value).then(res => {
|
|
|
- tabs.value[3].count = res.result.total
|
|
|
|
|
|
|
+ tabs.value[3].count = trainingTasksTotal.value = res.result.total
|
|
|
trainingTasks.value = res.result.records
|
|
trainingTasks.value = res.result.records
|
|
|
- console.log('res :>> ', res);
|
|
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
getTraining()
|
|
getTraining()
|
|
|
|
|
+const tasksPageCurrentChange = (page) => {
|
|
|
|
|
+ trainingParams.value.pageIndex = page
|
|
|
|
|
+ getTraining()
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
|
|
+const uploadRef = ref(null)
|
|
|
const fileListRaw = ref([])
|
|
const fileListRaw = ref([])
|
|
|
|
|
+const removeUidSet = new Set()
|
|
|
const handleFileChange = (file, fileList) => {
|
|
const handleFileChange = (file, fileList) => {
|
|
|
// 提取所有原生File对象
|
|
// 提取所有原生File对象
|
|
|
- fileListRaw.value = fileList.map(item => item.raw)
|
|
|
|
|
|
|
+ console.log(fileList)
|
|
|
|
|
+ // fileListRaw.value = fileList.map(item => item.raw)
|
|
|
|
|
+ const exist = fileListRaw.value.some(f => f.uid === file.uid)
|
|
|
|
|
+ if (!exist) {
|
|
|
|
|
+ fileListRaw.value.push(file)
|
|
|
|
|
+ }
|
|
|
console.log('当前选中所有文件:', fileListRaw.value)
|
|
console.log('当前选中所有文件:', fileListRaw.value)
|
|
|
}
|
|
}
|
|
|
const trainKnowledge = ref({
|
|
const trainKnowledge = ref({
|
|
@@ -734,8 +924,11 @@ const trainKnowledge = ref({
|
|
|
description: '',
|
|
description: '',
|
|
|
})
|
|
})
|
|
|
const startTrain = async () => {
|
|
const startTrain = async () => {
|
|
|
|
|
+ if(trainKnowledge.value.datasetId==''||trainKnowledge.value.name==''||trainKnowledge.value.description==''){
|
|
|
|
|
+ return ElMessage.warning('请填写必填项')
|
|
|
|
|
+ }
|
|
|
if (fileListRaw.value.length === 0) {
|
|
if (fileListRaw.value.length === 0) {
|
|
|
- return ElMessage.warning('请先选择文件')
|
|
|
|
|
|
|
+ return ElMessage.warning('请选择文件')
|
|
|
}
|
|
}
|
|
|
const formData = new FormData()
|
|
const formData = new FormData()
|
|
|
const jsonBody = {
|
|
const jsonBody = {
|
|
@@ -746,20 +939,49 @@ const startTrain = async () => {
|
|
|
formData.append('data', JSON.stringify(jsonBody))
|
|
formData.append('data', JSON.stringify(jsonBody))
|
|
|
|
|
|
|
|
fileListRaw.value.forEach(file => {
|
|
fileListRaw.value.forEach(file => {
|
|
|
- formData.append('file', file)
|
|
|
|
|
|
|
+ formData.append('file', file.raw)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
try {
|
|
try {
|
|
|
await creatTraining(formData)
|
|
await creatTraining(formData)
|
|
|
- ElMessage.success('全部文件上传成功')
|
|
|
|
|
|
|
+ ElMessage.success('添加成功')
|
|
|
// 清空上传列表、缓存文件
|
|
// 清空上传列表、缓存文件
|
|
|
uploadRef.value.clearFiles()
|
|
uploadRef.value.clearFiles()
|
|
|
fileListRaw.value = []
|
|
fileListRaw.value = []
|
|
|
|
|
+ trainKnowledge.value = {
|
|
|
|
|
+ datasetId: '',
|
|
|
|
|
+ name: '',
|
|
|
|
|
+ description: '',
|
|
|
|
|
+ }
|
|
|
|
|
+ showTrainModal.value = false
|
|
|
|
|
+ getTraining()
|
|
|
} catch (err) {
|
|
} catch (err) {
|
|
|
- ElMessage.error(err?.message || '上传失败,请重试')
|
|
|
|
|
|
|
+ ElMessage.error(err?.message || '上传失败,请重试!')
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+const delFile = (targetItem) => {
|
|
|
|
|
+ fileListRaw.value = fileListRaw.value.filter(item => item.uid !== targetItem.uid)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const documentName = ref()
|
|
|
|
|
+const showDocumentDetail = (item) => {
|
|
|
|
|
+ selectedDocument.value = item
|
|
|
|
|
+ console.log(item)
|
|
|
|
|
+ showChunksModal.value = true
|
|
|
|
|
+ documentName.value = item.name
|
|
|
|
|
+ chunkParams.value.dataset_id = item.dataset_id
|
|
|
|
|
+ chunkParams.value.document_id = item.id
|
|
|
|
|
+ getChunkDatasets()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const showKnowledgeDetail = (item) => {
|
|
|
|
|
+ selectedKnowledge.value = item
|
|
|
|
|
+ showDetailModal.value = true
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
// const filteredCategories = computed(() => {
|
|
// const filteredCategories = computed(() => {
|
|
|
// if (!searchQuery.value) return categories.value
|
|
// if (!searchQuery.value) return categories.value
|
|
|
// return categories.value.filter(c => c.name.includes(searchQuery.value) || c.description.includes(searchQuery.value))
|
|
// return categories.value.filter(c => c.name.includes(searchQuery.value) || c.description.includes(searchQuery.value))
|
|
@@ -790,11 +1012,6 @@ const formatNumber = (num) => num.toLocaleString()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-const showKnowledgeDetail = (item) => {
|
|
|
|
|
- selectedKnowledge.value = item
|
|
|
|
|
- showDetailModal.value = true
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
const editKnowledge = (item) => {
|
|
const editKnowledge = (item) => {
|
|
|
showDetailModal.value = false
|
|
showDetailModal.value = false
|
|
|
showToastMessage('正在编辑知识...', 'success')
|
|
showToastMessage('正在编辑知识...', 'success')
|
|
@@ -929,7 +1146,7 @@ const showToastMessage = (message, type = 'success') => {
|
|
|
.knowledge-icon { width: 40px; height: 40px; border-radius: 10px; display: flex; align-items: center; justify-content: center; font-size: 18px; flex-shrink: 0; }
|
|
.knowledge-icon { width: 40px; height: 40px; border-radius: 10px; display: flex; align-items: center; justify-content: center; font-size: 18px; flex-shrink: 0; }
|
|
|
.knowledge-content { flex: 1; }
|
|
.knowledge-content { flex: 1; }
|
|
|
.knowledge-header { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
|
|
.knowledge-header { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
|
|
|
-.knowledge-question { font-size: 14px; font-weight: 600; }
|
|
|
|
|
|
|
+.knowledge-question { font-size: 14px; font-weight: 600; word-break: break-all;}
|
|
|
.knowledge-category { font-size: 10px; padding: 2px 8px; border-radius: 10px; }
|
|
.knowledge-category { font-size: 10px; padding: 2px 8px; border-radius: 10px; }
|
|
|
.knowledge-answer { font-size: 12px; color: var(--text-secondary); margin-bottom: 8px; line-height: 1.5; }
|
|
.knowledge-answer { font-size: 12px; color: var(--text-secondary); margin-bottom: 8px; line-height: 1.5; }
|
|
|
.knowledge-meta { display: flex; gap: 16px; font-size: 11px; color: var(--text-muted); }
|
|
.knowledge-meta { display: flex; gap: 16px; font-size: 11px; color: var(--text-muted); }
|