|
@@ -187,8 +187,8 @@
|
|
|
</div> -->
|
|
</div> -->
|
|
|
</div>
|
|
</div>
|
|
|
<div class="knowledge-actions" @click.stop>
|
|
<div class="knowledge-actions" @click.stop>
|
|
|
- <button class="btn btn-secondary btn-sm" @click="editDocument(item)">
|
|
|
|
|
- <i class="fas fa-edit"></i>
|
|
|
|
|
|
|
+ <button class="btn btn-secondary btn-sm" @click="detailDocument(item)">
|
|
|
|
|
+ <i class="fas fa-eye"></i>
|
|
|
</button>
|
|
</button>
|
|
|
<el-popconfirm title="确认删除?" @confirm="deleteKnowledge(item)">
|
|
<el-popconfirm title="确认删除?" @confirm="deleteKnowledge(item)">
|
|
|
<template #reference>
|
|
<template #reference>
|
|
@@ -409,12 +409,16 @@
|
|
|
</div>
|
|
</div>
|
|
|
<div class="modal-body">
|
|
<div class="modal-body">
|
|
|
<div class="form-group">
|
|
<div class="form-group">
|
|
|
- <label class="form-label">问题/关键词 <span class="required">*</span></label>
|
|
|
|
|
- <input type="text" class="form-input" v-model="newKnowledge.content" placeholder="例如:MOQ最小起订量是多少?">
|
|
|
|
|
|
|
+ <div style="display: flex;align-items: center;margin-bottom: 6px;justify-content: space-between;">
|
|
|
|
|
+ <label class="form-label">问题/关键词 <span class="required">*</span></label><button class="btn btn-primary" @click="aiOptimize('content')" style="margin-left: 10px;padding: 4px 8px;border-radius: 4px;" :disabled="aiContentLoading"><i class="fas fa-sync" :class="{'icon-spin': aiContentLoading}"></i> AI优化</button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <textarea class="form-textarea" v-model="newKnowledge.content" rows="2" placeholder="例如:MOQ最小起订量是多少?" :disabled="aiContentLoading"></textarea>
|
|
|
</div>
|
|
</div>
|
|
|
<div class="form-group">
|
|
<div class="form-group">
|
|
|
- <label class="form-label">答案/内容 <span class="required">*</span></label>
|
|
|
|
|
- <textarea class="form-textarea" v-model="newKnowledge.answer" rows="4" placeholder="输入详细答案..."></textarea>
|
|
|
|
|
|
|
+ <div style="display: flex;align-items: center;margin-bottom: 6px;justify-content: space-between;">
|
|
|
|
|
+ <label class="form-label">答案/内容 <span class="required">*</span></label><button class="btn btn-primary" @click="aiOptimize('answer')" style="margin-left: 10px;padding: 4px 8px;border-radius: 4px;" :disabled="aiAnswerLoading"><i class="fas fa-sync" :class="{'icon-spin': aiAnswerLoading}"></i> AI优化</button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <textarea class="form-textarea" v-model="newKnowledge.answer" rows="4" placeholder="输入详细答案..." :disabled="aiAnswerLoading"></textarea>
|
|
|
</div>
|
|
</div>
|
|
|
<div class="form-group">
|
|
<div class="form-group">
|
|
|
<label class="form-label">知识分类 <span class="required">*</span></label>
|
|
<label class="form-label">知识分类 <span class="required">*</span></label>
|
|
@@ -555,8 +559,8 @@
|
|
|
</div>
|
|
</div>
|
|
|
<div class="modal-footer">
|
|
<div class="modal-footer">
|
|
|
<button class="btn btn-secondary" @click="showDetailModal = false">关闭</button>
|
|
<button class="btn btn-secondary" @click="showDetailModal = false">关闭</button>
|
|
|
- <button class="btn btn-secondary" @click="editKnowledge(selectedKnowledge)"><i class="fas fa-edit"></i> 编辑</button>
|
|
|
|
|
- <button class="btn btn-primary" @click="optimizeAnswer(selectedKnowledge)"><i class="fas fa-sync"></i> 优化答案</button>
|
|
|
|
|
|
|
+ <button class="btn btn-primary" @click="editKnowledge(selectedKnowledge)"><i class="fas fa-edit"></i> 编辑</button>
|
|
|
|
|
+ <!-- <button class="btn btn-primary" @click="optimizeAnswer(selectedKnowledge)"><i class="fas fa-sync"></i> 优化答案</button> -->
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
@@ -667,7 +671,7 @@
|
|
|
|
|
|
|
|
<script setup>
|
|
<script setup>
|
|
|
import { ref, computed } from 'vue'
|
|
import { ref, computed } from 'vue'
|
|
|
-import { knowledgeDatasets,knowledgeDocuments,createKnowledge,createChunk,editChunk,chatMessages,baseTraining,creatTraining,baseStatistics,getAllChunks,getAllDocumnets,delDocuments,delChunk } from '../api/knowledge'
|
|
|
|
|
|
|
+import { knowledgeDatasets,knowledgeDocuments,createKnowledge,createChunk,editChunk,chatMessages,baseTraining,creatTraining,baseStatistics,getAllChunks,getAllDocumnets,delDocuments,delChunk,getDocumentDetail,blocking } from '../api/knowledge'
|
|
|
import { formatTimeAgo } from '@/utils/time'
|
|
import { formatTimeAgo } from '@/utils/time'
|
|
|
import { ElMessage } from 'element-plus'
|
|
import { ElMessage } from 'element-plus'
|
|
|
|
|
|
|
@@ -677,6 +681,8 @@ const showImportModal = ref(false)
|
|
|
const showTrainModal = ref(false)
|
|
const showTrainModal = ref(false)
|
|
|
const showChunksModal = ref(false)
|
|
const showChunksModal = ref(false)
|
|
|
const chunkLoading = ref(false)
|
|
const chunkLoading = ref(false)
|
|
|
|
|
+const aiContentLoading = ref(false)
|
|
|
|
|
+const aiAnswerLoading = ref(false)
|
|
|
const selectedKnowledge = ref(null)
|
|
const selectedKnowledge = ref(null)
|
|
|
const selectedDocument = ref(null)
|
|
const selectedDocument = ref(null)
|
|
|
const activeTab = ref('categories')
|
|
const activeTab = ref('categories')
|
|
@@ -1035,38 +1041,6 @@ const showKnowledgeDetail = (item) => {
|
|
|
showDetailModal.value = true
|
|
showDetailModal.value = true
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-// const filteredCategories = computed(() => {
|
|
|
|
|
-// if (!searchQuery.value) return categories.value
|
|
|
|
|
-// return categories.value.filter(c => c.name.includes(searchQuery.value) || c.description.includes(searchQuery.value))
|
|
|
|
|
-// })
|
|
|
|
|
-
|
|
|
|
|
-// const filteredKnowledge = computed(() => {
|
|
|
|
|
-// if (!searchQuery.value) return knowledgeList.value
|
|
|
|
|
-// return knowledgeList.value.filter(k =>
|
|
|
|
|
-// k.question.includes(searchQuery.value) ||
|
|
|
|
|
-// k.answer.includes(searchQuery.value) ||
|
|
|
|
|
-// k.tags.some(t => t.includes(searchQuery.value))
|
|
|
|
|
-// )
|
|
|
|
|
-// })
|
|
|
|
|
-
|
|
|
|
|
-const filteredQA = computed(() => {
|
|
|
|
|
- let result = qaRecords.value
|
|
|
|
|
- if (qaFilter.value !== 'all') {
|
|
|
|
|
- result = result.filter(qa => qa.sourceType === qaFilter.value)
|
|
|
|
|
- }
|
|
|
|
|
- if (qaRating.value !== 'all') {
|
|
|
|
|
- result = result.filter(qa => qa.rating === qaRating.value)
|
|
|
|
|
- }
|
|
|
|
|
- return result
|
|
|
|
|
-})
|
|
|
|
|
-
|
|
|
|
|
-const formatNumber = (num) => num.toLocaleString()
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
const editKnowledge = (item) => {
|
|
const editKnowledge = (item) => {
|
|
|
chunkType.value = 'edit'
|
|
chunkType.value = 'edit'
|
|
|
newKnowledge.value.content = item.content
|
|
newKnowledge.value.content = item.content
|
|
@@ -1077,8 +1051,15 @@ const editKnowledge = (item) => {
|
|
|
newKnowledge.value.document_id=item.document_id
|
|
newKnowledge.value.document_id=item.document_id
|
|
|
showAddModal.value = true
|
|
showAddModal.value = true
|
|
|
}
|
|
}
|
|
|
-const editDocument = (item) => {
|
|
|
|
|
-
|
|
|
|
|
|
|
+const detailDocument = (item) => {
|
|
|
|
|
+ console.log(item)
|
|
|
|
|
+ let params = {
|
|
|
|
|
+ dataset_id:item.dataset_id,
|
|
|
|
|
+ document_id:item.id,
|
|
|
|
|
+ }
|
|
|
|
|
+ getDocumentDetail(params).then(res => {
|
|
|
|
|
+ console.log(555)
|
|
|
|
|
+ })
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const getDocument = () =>{
|
|
const getDocument = () =>{
|
|
@@ -1117,6 +1098,64 @@ const addKnowledge = () => {
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+const aiOptimize = (type) => {
|
|
|
|
|
+ let params = {
|
|
|
|
|
+ query:'',
|
|
|
|
|
+ response_mode:'blocking',
|
|
|
|
|
+ user:1,
|
|
|
|
|
+ appId:'app-KpoSEqve0ybB2Ej5PlJiBu2k',
|
|
|
|
|
+ conversation_id:'',
|
|
|
|
|
+ inputs:{},
|
|
|
|
|
+ }
|
|
|
|
|
+ if(type =='content'){
|
|
|
|
|
+ if(aiContentLoading.value) return
|
|
|
|
|
+ aiContentLoading.value = true
|
|
|
|
|
+ if(!newKnowledge.value.content){
|
|
|
|
|
+ return ElMessage.error('请输入问题/关键词')
|
|
|
|
|
+ }
|
|
|
|
|
+ newKnowledge.value.content = newKnowledge.value.content.split('\n')[0]
|
|
|
|
|
+ params.query = '你的任务是优化用户输入的问句,用于知识库问答检索。要求:1. 只输出优化后的问题,不要任何解释、前言、总结;2. 扩充同义问法、口语变体,提升检索命中;3. 保持原意不变,句式自然;4、给出一个方案即可。以下是用户原始问题:' + newKnowledge.value.content
|
|
|
|
|
+ blocking(params).then(res => {
|
|
|
|
|
+ aiContentLoading.value = false
|
|
|
|
|
+ if(res.success){
|
|
|
|
|
+ newKnowledge.value.content += '\n' + res.result.answer
|
|
|
|
|
+ }else{
|
|
|
|
|
+ return ElMessage.error('请求超时,请稍后再试')
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ }else{
|
|
|
|
|
+ if(aiAnswerLoading.value) return
|
|
|
|
|
+ aiAnswerLoading.value = true
|
|
|
|
|
+ if(!newKnowledge.value.answer){
|
|
|
|
|
+ return ElMessage.error('请输入答案/内容')
|
|
|
|
|
+ }
|
|
|
|
|
+ newKnowledge.value.answer = newKnowledge.value.answer.split('\n')[0]
|
|
|
|
|
+ params.query = '你的任务是优化用户输入的回答,用于知识库问答检索。要求:1. 只输出优化后的回答,不要任何解释、前言、总结;2. 扩充同义问法、口语变体,提升检索命中;3. 保持原意不变,句式自然;4、给出一个方案即可。以下是用户原始回答:' + newKnowledge.value.answer
|
|
|
|
|
+ blocking(params).then(res => {
|
|
|
|
|
+ aiAnswerLoading.value = false
|
|
|
|
|
+ if(res.success){
|
|
|
|
|
+ newKnowledge.value.answer += '\n' + res.result.answer
|
|
|
|
|
+ }else{
|
|
|
|
|
+ return ElMessage.error('请求超时,请稍后再试')
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+const filteredQA = computed(() => {
|
|
|
|
|
+ let result = qaRecords.value
|
|
|
|
|
+ if (qaFilter.value !== 'all') {
|
|
|
|
|
+ result = result.filter(qa => qa.sourceType === qaFilter.value)
|
|
|
|
|
+ }
|
|
|
|
|
+ if (qaRating.value !== 'all') {
|
|
|
|
|
+ result = result.filter(qa => qa.rating === qaRating.value)
|
|
|
|
|
+ }
|
|
|
|
|
+ return result
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+const formatNumber = (num) => num.toLocaleString()
|
|
|
|
|
+
|
|
|
const optimizeAnswer = (item) => {
|
|
const optimizeAnswer = (item) => {
|
|
|
showToastMessage('AI 正在优化答案...', 'success')
|
|
showToastMessage('AI 正在优化答案...', 'success')
|
|
|
}
|
|
}
|
|
@@ -1369,4 +1408,11 @@ const showToastMessage = (message, type = 'success') => {
|
|
|
.pagination-area{
|
|
.pagination-area{
|
|
|
padding: 40px 0;
|
|
padding: 40px 0;
|
|
|
}
|
|
}
|
|
|
|
|
+.icon-spin {
|
|
|
|
|
+ animation: spin 1s linear infinite !important;
|
|
|
|
|
+}
|
|
|
|
|
+@keyframes spin {
|
|
|
|
|
+ 0% { transform: rotate(0deg); }
|
|
|
|
|
+ 100% { transform: rotate(360deg); }
|
|
|
|
|
+}
|
|
|
</style>
|
|
</style>
|