2 Commits a9adb0dd55 ... c0613d1d66

Autore SHA1 Messaggio Data
  zhujing c0613d1d66 Merge remote-tracking branch 'origin/master' 3 settimane fa
  zhujing 49eaed8244 ai优化 3 settimane fa

+ 12 - 1
ui/smarttrade-platform/src/api/knowledge/index.js

@@ -29,6 +29,11 @@ export const getAllDocumnets = (params = {}) => {
     return get('/router/rest/knowledge/document/getAllDocumnets', query)
 }
 
+export const getDocumentDetail = (params = {}) => {
+    const { dataset_id,document_id, ...query } = params
+    return get(`/router/rest/knowledge/document/${dataset_id}/documents/${document_id}`, params)
+}
+
 export const delDocuments = (params = {}) => {
     const { dataset_id, document_id, ...query } = params
     return remove(`/router/rest/knowledge/document/${dataset_id}/documents/${document_id}`, params)
@@ -47,4 +52,10 @@ export const delChunk = (params = {}) => {
 export const editChunk = (data = {}) => {
     const { dataset_id,document_id,segment_id, ...query } = data
     return post(`/router/rest/knowledge/chunk/${dataset_id}/${document_id}/${segment_id}`, data)
-}
+}
+
+export const blocking = (data = {}) => post('/router/rest/chat/blocking', data,{
+    headers: {
+        'Authorization': 'Bearer app-KpoSEqve0ybB2Ej5PIJiBu2k'
+    }
+})

+ 1 - 1
ui/smarttrade-platform/src/utils/request.js

@@ -31,7 +31,7 @@ const service = axios.create({
   baseURL: BASE_URL,
   timeout: TIMEOUT,
   headers: {
-    'Content-Type': 'application/json;charset=utf-8'
+    'Content-Type': 'application/json;charset=utf-8',
   }
 })
 

+ 2 - 2
ui/smarttrade-platform/src/views/CustomersView.vue

@@ -41,13 +41,13 @@
       <div style="display: flex; gap: 8px;">
         <el-cascader class="form-select" style="width: auto; padding: 0;" placeholder="区域名称" :options="region"
           v-model="regionValue" clearable filterable @change="getRegion" />
-        <select v-model="industryFilter" class="form-select" style="width: auto; padding: 8px 16px;">
+        <!-- <select v-model="industryFilter" class="form-select" style="width: auto; padding: 8px 16px;">
           <option value="">全部行业</option>
           <option value="固态硬盘">固态硬盘</option>
           <option value="电子分销">电子分销</option>
           <option value="企业级存储">企业级存储</option>
         </select>
-        <button class="btn btn-secondary"><i class="fas fa-sliders-h"></i> 高级筛选</button>
+        <button class="btn btn-secondary"><i class="fas fa-sliders-h"></i> 高级筛选</button> -->
       </div>
     </div>
 

+ 89 - 43
ui/smarttrade-platform/src/views/KnowledgeView.vue

@@ -187,8 +187,8 @@
             </div> -->
           </div>
           <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>
             <el-popconfirm title="确认删除?" @confirm="deleteKnowledge(item)">
               <template #reference>
@@ -409,12 +409,16 @@
         </div>
         <div class="modal-body">
           <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 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 class="form-group">
             <label class="form-label">知识分类 <span class="required">*</span></label>
@@ -555,8 +559,8 @@
         </div>
         <div class="modal-footer">
           <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>
@@ -667,7 +671,7 @@
 
 <script setup>
 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 { ElMessage } from 'element-plus'
 
@@ -677,6 +681,8 @@ const showImportModal = ref(false)
 const showTrainModal = ref(false)
 const showChunksModal = ref(false)
 const chunkLoading = ref(false)
+const aiContentLoading = ref(false)
+const aiAnswerLoading = ref(false)
 const selectedKnowledge = ref(null)
 const selectedDocument = ref(null)
 const activeTab = ref('categories')
@@ -1035,38 +1041,6 @@ const showKnowledgeDetail = (item) => {
   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) => {
   chunkType.value = 'edit'
   newKnowledge.value.content = item.content
@@ -1077,8 +1051,15 @@ const editKnowledge = (item) => {
   newKnowledge.value.document_id=item.document_id
   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 = () =>{
@@ -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) => {
   showToastMessage('AI 正在优化答案...', 'success')
 }
@@ -1369,4 +1408,11 @@ const showToastMessage = (message, type = 'success') => {
 .pagination-area{
   padding: 40px 0;
 }
+.icon-spin {
+  animation: spin 1s linear infinite !important;
+}
+@keyframes spin {
+  0% { transform: rotate(0deg); }
+  100% { transform: rotate(360deg); }
+}
 </style>