Jelajahi Sumber

添加中间数据页面并处理聊天应用

yangg 8 bulan lalu
induk
melakukan
74ee480327

+ 21 - 18
src/components/webAi/js/ChatBox.js

@@ -124,6 +124,7 @@ export default {
       /* 查看 */
       viewDialogVisible: false,
       viewForm: null,
+      session_id:"",
     };
   },
   created() {
@@ -717,7 +718,7 @@ newChat() {
         }
       }
       const chatId = this.getUuid();
-      const wsUrl ='http://192.168.1.199:8082/api/chatbot/chat'//this.wsUrl//'http://58.246.234.210:7860/api/v1/run/3ef7369e-b617-40d2-9e2e-54f3ee76ed2e?stream=false'
+      const wsUrl ='http://120.46.190.49:8082/api/chatbot/chat'//this.wsUrl//'http://58.246.234.210:7860/api/v1/run/3ef7369e-b617-40d2-9e2e-54f3ee76ed2e?stream=false'
       let message = this.userInput.trim();
       if (message) {
         // Markdown换行:在每个换行符之前添加两个空格
@@ -750,17 +751,17 @@ newChat() {
           const response = await fetch(`${wsUrl}`, {
             method: "POST",
             headers: {
-              "Content-Type": "application/json",
-              "Access-Control-Allow-Origin": "*"
+              "Content-Type": "application/json"
             },
-            credentials: "include",
+           /*  mode: 'no-cors', */
+            /* credentials: "include", */
             body: JSON.stringify({
              /*  chatId: chatId, */
               message: message,
               /* output_type: "chat",
               input_type: "chat", */
               user_id:this.$store.state.user.id,
-              session_id:''
+              session_id:this.session_id||''
              /* tweaks:this.tweaks  {
                 "ChatInput-U82Vu": {},
                 "Prompt-b8Z1E": {},
@@ -775,26 +776,28 @@ newChat() {
               } */,
             }),
           });
-
-          if (!response.ok) {
+          const result = await response.json();
+          this.session_id=result.data.session_id
+          console.log(result.status);
+          if (result.status!==200) {
             const errorText = await response.text(); // 获取错误文本
             throw new Error(
               `HTTP error! status: ${response.status}, message: ${errorText}`
             );
           }
 
-          const result = await response.json();
+          
          // 等待思考动画完成
          await thinkingPromise;
          if(this.$route.name !== 'ai'){
            // 提取 additional_input 数据
-        const additionalInput = result.outputs?.[0]?.outputs?.[0]?.results?.message?.data?.additional_input;
+        const additionalInput = result.data.milvus_ids//outputs?.[0]?.outputs?.[0]?.results?.message?.data?.additional_input;
         
         // 处理字符串,提取 ID 值
-        this.idArray = additionalInput.split('\n')  // 按换行符分割
-          .map(line => line.trim())  // 去除每行首尾空白
-          .filter(line => line.startsWith('ID:'))  // 只保留以 'ID:' 开头的行
-          .map(line => line.substring(3).trim());  // 提取 'ID:' 后面的内容并去除空白
+        this.idArray = additionalInput/* .split('\n')  // 按换行符分割
+          .map(line => line.trim())  // 去除每行首尾空白 */
+          /* .filter(line => line.startsWith('ID:'))  // 只保留以 'ID:' 开头的行
+          .map(line => line.substring(3).trim());  // 提取 'ID:' 后面的内容并去除空白 */
 
         // 创建符合要求格式的对象
         const idObject = { ids: this.idArray };
@@ -869,13 +872,13 @@ newChat() {
     },
   
     async handleResponse(value, existingMessage) {
-      const data = value.outputs[0].outputs[0].results.message;
+      const data = value.data.response//outputs[0].outputs[0].results.message;
       
-      existingMessage.messageType = data.text_key;
-      existingMessage.time = data.timestamp;
+      existingMessage.messageType = data;
+      /* existingMessage.time = data.timestamp; */
       existingMessage.message = '';
       
-      let mainText = data.text;
+      let mainText = data;
       let sourceText = '';
 
       if (this.$route.name !== 'ai' && this.minioUrls && this.minioUrls.length > 0) {
@@ -885,7 +888,7 @@ newChat() {
         });
         sourceText += "</ol></div>";
       }
-
+      console.log(existingMessage, mainText);
       // 先进行主要内容的打字效果
       await this.typeMessage(existingMessage, mainText);
 

+ 7 - 0
src/router/index.js

@@ -346,6 +346,13 @@ export const asyncRoutes = [
         name: 'chatbot',
       
         meta: { title: '聊天应用',  noCache: true ,roles: ['admin']}
+      },
+      /* MiddleFuntion */
+      {
+        path: 'middPage/index',
+        component: () => import('@/views/middPage/index.vue'),
+        name: 'MiddleFuntion',
+        meta: { title: '中间数据',  noCache: true ,roles: ['admin']}
       }
     ]
   },

+ 30 - 2
src/views/dashboard/admin/components/BarChart.vue

@@ -6,6 +6,9 @@
 import echarts from "echarts";
 require("echarts/theme/macarons");
 import resize from "./mixins/resize";
+import {
+  selectTypeList
+} from "@/api/knowledge";
 
 export default {
   mixins: [resize],
@@ -21,6 +24,10 @@ export default {
     height: {
       type: String,
       default: "350px"
+    },
+    kenValue:{
+      type:Number,
+      default:null
     }
   },
   data() {
@@ -63,9 +70,17 @@ export default {
           Text: 36,
           Other: 11
         }
-      ]
+      ],
+      dirList:[]
     };
   },
+  watch:{
+    kenValue:{
+      handler(val) {
+        this.init(val)
+      }
+    }
+  },
   mounted() {
     this.$nextTick(() => {
       this.initChart();
@@ -152,7 +167,20 @@ export default {
         Other: "#4ADEDE"
       };
       return colorMap[type];
-    }
+    },
+    /* 获取知识库目录 */
+    init(val){
+      const tList={
+        page: 1,
+        pageSize: 9999,
+        kb_id: val,
+      }
+      selectTypeList(tList).then(res=>{
+        console.log(res);
+        if(res.status!==200) return
+        this.dirList=res.data.dataList
+      })
+    },
   }
 };
 </script>

+ 74 - 53
src/views/dashboard/admin/components/recentFile.vue

@@ -1,60 +1,81 @@
 <template>
-    <div class="recent-file-list">
-      <el-table
-        :data="fileList"
-        style="width: 100%"
-        height="350"
-        :default-sort="{ prop: 'modified', order: 'descending' }"
-      >
-        <el-table-column prop="name" label="File name">
-          <template #default="scope">
-            <i :class="getFileIcon(scope.row.name)"></i>
-            {{ scope.row.name }}
-          </template>
-        </el-table-column>
-        <el-table-column prop="size" label="Size" width="120" />
-        <el-table-column prop="modified" label="Modified" width="180" sortable />
-        <el-table-column prop="category" label="Category" width="120" />
-      </el-table>
-    </div>
-  </template>
+  <div class="recent-file-list">
+    <el-table
+      :data="fileList"
+      style="width: 100%"
+      height="350"
+      :default-sort="{ prop: 'modified', order: 'descending' }"
+    >
+      <el-table-column prop="title" label="文档名称" align="center">
+        <!-- <template #default="scope">
+          <i :class="getFileIcon(scope.row.name)"></i>
+          {{ scope.row.name }}
+        </template> -->
+      </el-table-column>
+      <!-- <el-table-column prop="size" label="Size" width="120" /> -->
+      <el-table-column prop="create_time" label="创建时间"  sortable  align="center"/>
+      <el-table-column prop="status" label="文档状态" align="center" />
+    </el-table>
+  </div>
+</template>
   
   <script>
-  export default {
-    name: 'RecentFile',
-    data() {
-      return {
-        fileList: [
-          { name: 'dahsboard_design.fig', size: '2.4Mb', modified: 'Aug 5th,2022', category: 'Mac Image' },
-          { name: 'macbook_pro.jpg', size: '2.4Mb', modified: 'Aug 5th,2022', category: 'Mac Image' },
-          { name: 'index.html', size: '2.4Mb', modified: 'Aug 5th,2022', category: 'Mac Image' },
-          { name: 'code.zip', size: '2.4Mb', modified: 'Aug 5th,2022', category: 'Mac Image' },
-          { name: 'sound_bird.mp3', size: '2.4Mb', modified: 'Aug 5th,2022', category: 'Mac Image' },
-          { name: 'full_trailer_2.mp4', size: '2.4Mb', modified: 'Aug 5th,2022', category: 'Mac Image' },
-          { name: 'router.js', size: '2.4Mb', modified: 'Aug 5th,2022', category: 'Mac Image' },
-        ]
+import { searchlistDoc } from "@/api/document";
+export default {
+  name: "RecentFile",
+  data() {
+    return {
+      queryForm: {
+        page: 1,
+        pageSize: 100,
+        title: "",
+        category_id: "",
+        status: "",
+      },
+      fileList: [],
+    };
+  },
+  methods: {
+    getFileIcon(fileName) {
+      const extension = fileName.split(".").pop().toLowerCase();
+      switch (extension) {
+        case "fig":
+          return "el-icon-picture";
+        case "jpg":
+        case "png":
+          return "el-icon-picture-outline";
+        case "html":
+          return "el-icon-document";
+        case "zip":
+          return "el-icon-folder";
+        case "mp3":
+          return "el-icon-headset";
+        case "mp4":
+          return "el-icon-video-camera";
+        case "js":
+          return "el-icon-tickets";
+        default:
+          return "el-icon-document";
       }
     },
-    methods: {
-      getFileIcon(fileName) {
-        const extension = fileName.split('.').pop().toLowerCase()
-        switch (extension) {
-          case 'fig': return 'el-icon-picture'
-          case 'jpg': case 'png': return 'el-icon-picture-outline'
-          case 'html': return 'el-icon-document'
-          case 'zip': return 'el-icon-folder'
-          case 'mp3': return 'el-icon-headset'
-          case 'mp4': return 'el-icon-video-camera'
-          case 'js': return 'el-icon-tickets'
-          default: return 'el-icon-document'
-        }
-      }
-    }
-  }
-  </script>
+    init() {
+      searchlistDoc(this.queryForm).then((res) => {
+        // 假设 res.data.dataList 是包含所有文件信息的数组
+        const allFiles = res.data.dataList;
+
+        // 按创建时间降序排序
+        allFiles.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));
+
+        // 取前 10 条数据
+        this.fileList = allFiles.slice(0, 10);
+      });
+    },
+  },
+};
+</script>
   
   <style scoped>
-  .recent-file-list {
-    /* Add any additional styling here */
-  }
-  </style>
+.recent-file-list {
+  /* Add any additional styling here */
+}
+</style>

+ 64 - 19
src/views/dashboard/admin/index.vue

@@ -6,41 +6,52 @@
     <el-row :gutter="20">
       <el-col :span="16">
         <el-card class="box-card">
-          <div slot="header" class="clearfix">
+          <div slot="header" class="clearfixs header_sel">
             <span>知识库构成</span>
+            <div>
+              <el-select v-model="kenValue" placeholder="请选择">
+                <el-option
+                  v-for="item in kenList"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id"
+                >
+                </el-option>
+              </el-select>
+            </div>
           </div>
-          <BarChart style="height: 350px;"></BarChart>
+          <BarChart :kenValue="kenValue" style="height: 350px"></BarChart>
         </el-card>
       </el-col>
       <el-col :span="8">
         <el-card class="box-card">
-          <div slot="header" class="clearfix">
+          <div slot="header" class="clearfixs">
             <span>文件种类占比</span>
           </div>
-          <pie-chart style="height: 350px;"/>
+          <pie-chart style="height: 350px" />
         </el-card>
       </el-col>
     </el-row>
-    <el-row :gutter="20" style="margin-top: 20px;">
-      <el-col :span="8">
+    <el-row :gutter="20" style="margin-top: 20px">
+      <!-- <el-col :span="8">
         <el-card class="box-card">
-          <div slot="header" class="clearfix">
+          <div slot="header" class="clearfixs">
             <span>知识库热门标签</span>
           </div>
-          <TagCloud :tags="tags"  />
+          <TagCloud :tags="tags" />
         </el-card>
-      </el-col>
-      <el-col :span="16">
+      </el-col> -->
+      <el-col :span="24">
         <el-card class="box-card">
-          <div slot="header" class="clearfix">
+          <div slot="header" class="clearfixs">
             <span>最近访问的文件</span>
           </div>
-          <RecentFile style="height: 350px;"/>
+          <RecentFile style="height: 350px" />
         </el-card>
       </el-col>
     </el-row>
 
-    <transaction-table />
+  <!--   <transaction-table /> -->
   </div>
 </template>
 
@@ -54,8 +65,11 @@ import BarChart from "./components/BarChart";
 import TransactionTable from "./components/TransactionTable";
 import TodoList from "./components/TodoList";
 import BoxCard from "./components/BoxCard";
-import TagCloud from './components/tagCloud.vue'
-import RecentFile from './components/recentFile.vue'
+import TagCloud from "./components/tagCloud.vue";
+import RecentFile from "./components/recentFile.vue";
+import {
+  listBuckets,
+} from "@/api/knowledge";
 
 const lineChartData = {
   newVisitis: {
@@ -89,18 +103,44 @@ export default {
     TodoList,
     BoxCard,
     TagCloud,
-    RecentFile
+    RecentFile,
   },
   data() {
     return {
       lineChartData: lineChartData.newVisitis,
-      tags: ['Figma', 'Adobe XD', 'PSD Editor', 'Employer', 'Online Jobs', 'Remote Work', 'Salary', 'Tips', 'Income', 'Develop', 'App', 'Digital', 'Marketing', 'CEO']
+      tags: [
+        "Figma",
+        "Adobe XD",
+        "PSD Editor",
+        "Employer",
+        "Online Jobs",
+        "Remote Work",
+        "Salary",
+        "Tips",
+        "Income",
+        "Develop",
+        "App",
+        "Digital",
+        "Marketing",
+        "CEO",
+      ],
+      kenList:[],
+      kenValue:0,
     };
   },
+  mounted(){
+    this.init()
+  },
   methods: {
     handleSetLineChartData(type) {
       this.lineChartData = lineChartData[type];
     },
+    init(){
+      listBuckets({ user_id: this.$store.state.user.id }).then(res=>{
+        if (res.status !== 200) return;
+          this.kenList = res.data;
+      })
+    },
   },
 };
 </script>
@@ -118,12 +158,17 @@ export default {
     border: 0;
     right: 0;
   }
-  .clearfix{
-    span{
+  .clearfixs {
+    span {
       font-size: 16px;
       font-weight: 600;
     }
   }
+  .header_sel{
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+  }
 
   .chart-wrapper {
     background: #fff;

+ 175 - 0
src/views/middPage/index.vue

@@ -0,0 +1,175 @@
+<template>
+    <div class="midd-page">
+      <el-table :data="filteredTableData" style="width: 100%">
+        <el-table-column
+          label="工作类型"
+          prop="workType"
+          :filters="workTypeFilters"
+          :filter-method="filterWorkType"
+          filter-placement="bottom-end"
+        >
+          <template #default="scope">
+            <el-select v-model="scope.row.workType" placeholder="请选择" v-if="scope.row.isEdit">
+              <el-option label="类型1" value="type1"></el-option>
+              <el-option label="类型2" value="type2"></el-option>
+              <el-option label="类型3" value="type3"></el-option>
+            </el-select>
+            <span v-else>{{ scope.row.workType }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="项目"
+          prop="project"
+          :filters="projectFilters"
+          :filter-method="filterProject"
+          filter-placement="bottom-end"
+        >
+          <template #default="scope">
+            <el-input v-model="scope.row.project" v-if="scope.row.isEdit"></el-input>
+            <span v-else>{{ scope.row.project }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="说明" prop="description">
+          <template #default="scope">
+            <el-input v-model="scope.row.description" v-if="scope.row.isEdit"></el-input>
+            <span v-else>{{ scope.row.description }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="范例" prop="example">
+          <template #default="scope">
+            <el-input v-model="scope.row.example" v-if="scope.row.isEdit"></el-input>
+            <span v-else>
+                {{ scope.row.example }}
+                <i class="el-icon-edit" @click="openExampleDialog(scope.row)" style="cursor: pointer; margin-left: 5px;"></i>
+            </span>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作">
+          <template #default="scope">
+            <el-button size="small" @click="handleEdit(scope.$index, scope.row)" v-if="!scope.row.isEdit">
+              编辑
+            </el-button>
+            <el-button size="small" type="success" @click="handleSave(scope.$index, scope.row)" v-else>
+              保存
+            </el-button>
+            <el-button size="small" type="danger" @click="handleDelete(scope.$index, scope.row)">
+              删除
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <el-button type="primary" @click="handleAdd" style="margin-top: 20px;">新增行</el-button>
+      <el-dialog :visible.sync="dialogVisible" title="编辑范例" width="30%">
+      <el-input v-model="currentExample" type="textarea" :rows="4"></el-input>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="dialogVisible = false">取消</el-button>
+          <el-button type="primary" @click="saveExample">确定</el-button>
+        </span>
+      </template>
+    </el-dialog>
+    </div>
+  </template>
+  
+  <script>
+  export default {
+    name: 'MiddPage',
+    data() {
+      return {
+        tableData: [
+          { workType: '复制', project: 'indication', description: '器械在文献中使用的适应症,按照器械分析,也需要添加器械使用部位以区分', example: 't1d: n=191;', isEdit: false },
+          { workType: '总结', project: 'Study Design/ Method', description: '患者/试验者的人种,国家地区,以查阅是否存在数据上人种差异', example: 'white non-hispanic: n=247;african american:n=25;hispanic or latino: n=34', isEdit: false },
+          { workType: '总结和数据提取;', project: 'Alternative device(treatment)', description: 'Device name + model name如无,可写疗法(以评价的器械的替代疗法)', example: 'Capillary blood by BMG;Venous blood by YSI(此处为CGM的替代疗法)', isEdit: false },
+        ],
+        workTypeFilters: [
+          { text: '类型1', value: 'type1' },
+          { text: '类型2', value: 'type2' },
+          { text: '类型3', value: 'type3' },
+        ],
+        projectFilters: [],
+        activeFilters: {
+          workType: [],
+          project: [],
+        },
+        dialogVisible: false,
+      currentExample: '',
+      currentRow: null,
+      }
+    },
+    computed: {
+      filteredTableData() {
+        return this.tableData.filter(data => {
+          return (!this.activeFilters.workType.length || this.activeFilters.workType.includes(data.workType)) &&
+                 (!this.activeFilters.project.length || this.activeFilters.project.includes(data.project));
+        });
+      },
+    },
+    created() {
+      this.updateProjectFilters();
+    },
+    methods: {
+        openExampleDialog(row) {
+            console.log(112);
+      this.dialogVisible = true;
+      this.currentExample = row.example;
+      this.currentRow = row;
+    },
+    saveExample() {
+      if (this.currentRow) {
+        this.currentRow.example = this.currentExample;
+      }
+      this.dialogVisible = false;
+    },
+      handleEdit(index, row) {
+        row.isEdit = true;
+      },
+      handleSave(index, row) {
+        row.isEdit = false;
+        this.updateProjectFilters();
+        // 在这里可以添加保存到后端的逻辑
+      },
+      handleDelete(index, row) {
+        this.tableData.splice(index, 1);
+        this.updateProjectFilters();
+        // 在这里可以添加从后端删除的逻辑
+      },
+      handleAdd() {
+        this.tableData.push({
+          workType: '',
+          project: '',
+          description: '',
+          example: '',
+          isEdit: true
+        });
+      },
+      filterWorkType(value, row) {
+        return row.workType === value;
+      },
+      filterProject(value, row) {
+        return row.project === value;
+      },
+      updateProjectFilters() {
+        const projects = [...new Set(this.tableData.map(item => item.project))];
+        this.projectFilters = projects.map(project => ({ text: project, value: project }));
+      },
+    },
+    watch: {
+      tableData: {
+        handler() {
+          this.updateProjectFilters();
+        },
+        deep: true
+      }
+    }
+  }
+  </script>
+  
+  <style scoped>
+  .midd-page {
+    padding: 20px;
+  }
+  .el-icon-edit {
+  font-size: 14px;
+  color: #409EFF;
+}
+  </style>