فهرست منبع

理解技术交底书添加根据附图提问

zhuliu 1 ماه پیش
والد
کامیت
3b12901695

+ 10 - 0
src/api/newApi/technicalDisclosure.js

@@ -70,4 +70,14 @@ export default {
     discoveryResultDetail(data){
         return axios.post('/xiaoshi/dify/generateDiscoveryResult/detail', data)
     },
+
+
+    //查询技术交底书附图列表
+    queryDiscoveryPicture(data){
+        return axios.post('/xiaoshi/dify/generateDiscoveryResult/queryPicture', data)
+    },
+    //上传技术交底书附图列表
+    uploadDiscoveryPicture(data){
+        return axios.post('/xiaoshi/dify/generateDiscoveryResult/uploadPicture', data)
+    },
 }

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 83 - 13
src/components/xiaoshi_AI/index.vue


+ 4 - 2
src/utils/model/observerDom/index.vue

@@ -1,7 +1,9 @@
 <template>
     <div style="width:100%;height:100%" :ref="'observerDom'+key">
-        <div v-if="show" v-html="html" v-bind="$attrs" v-on='$listeners' style="width:100%;height:100%"></div> 
-        <div v-else style="width:100%;height:100%" v-loading="true"></div>
+        <slot name="inner">
+            <div v-if="show" v-html="html" v-bind="$attrs" v-on='$listeners' style="width:100%;height:100%"></div> 
+            <div v-else style="width:100%;height:100%" v-loading="true"></div>
+        </slot>
     </div>
     
 </template>

+ 2 - 1
src/utils/model/upload/index.vue

@@ -244,8 +244,9 @@ export default {
       if (this.accept) {
         var arr = this.accept.split(/,|,/g);
         var fileType = file.name.substring(file.name.lastIndexOf("."));
+        var mime = file.raw.type.substring(0,file.raw.type.indexOf("/")+1)
         var index = arr.findIndex((item) => {
-          return item == fileType;
+          return item == fileType || item.indexOf(mime) == 0
         });
         if (index == -1) {
           this.discontent.push(file);

+ 186 - 0
src/views/AITools/technicalDisclosure/dialog/imageList.vue

@@ -0,0 +1,186 @@
+<template>
+  <div class="imageListDialog">
+    <el-dialog   
+        title="附图列表"
+        :visible.sync="visible"
+        width="700px"
+        append-to-body
+        :close-on-click-modal="false"
+        :before-close="handleClose">
+          <div class="imageList">
+            <div class="imageWrap" v-for="(item,index) in imageList" :key="item.guid">
+                <div class="choose">
+                     <el-checkbox-group v-model="checkList">
+                        <el-checkbox :label="item.guid">{{ index + 1 }}</el-checkbox>
+                    </el-checkbox-group>
+                </div>
+                <div class="img">
+                    <el-image style="width:100%;height:100%" :src="$commonJS.checkViewer(item.guid)" fit="contain" :preview-src-list="[$commonJS.checkViewer(item.guid)]" :lazy="index>14?true:false"></el-image> 
+                </div>
+                
+                <div class="name noWrap" :title="item.originalName">{{ item.originalName }}</div>
+            </div>
+          </div>
+        <div slot="footer" class="dialog-footer btns">
+            <div>
+                <el-button v-if="canUpload" size="small" type="primary" @click="uploadImage" >上传附图</el-button>
+            </div>
+            <div>
+                <el-button size="small" @click="handleClose">取 消</el-button>
+                <el-button size="small" type="primary" @click="submit">确 定</el-button>
+            </div>
+        </div>
+      </el-dialog>
+
+      <el-dialog   
+        title="附图上传"
+        :visible.sync="uploadVisible"
+        width="700px"
+        append-to-body
+        :close-on-click-modal="false"
+        :before-close="uploadClose">
+        <div>
+            <myUpload :file-list="uploadImages" @on-change="onchangeFile" accept="image/*" @on-remove="onRemove" style="height: 180px;" :multiple="true" :autoUpload="true"></myUpload> 
+        </div>
+        <div slot="footer" class="dialog-footer">
+            <el-button size="small" @click="uploadClose">取 消</el-button>
+            <el-button size="small" type="primary" @click="uploadSubmit">确 定</el-button>
+        </div>
+      </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  components: {},
+  props: {
+    guids:{
+        type:Array,
+        default:()=>{
+            return []
+        }
+    },
+    imageList:{
+        type:Array,
+        default:()=>{
+            return []
+        }
+    },
+    canUpload:{
+        type:Boolean,
+        default:true
+    }
+  },
+  data() {
+    return {
+        visible:false,
+        checkList:this.guids,
+        uploadVisible:false,
+        uploadImages:[],
+        uploadImagesGuids:[]
+    };
+  },
+  watch: {
+    guids(val){
+        this.checkList = val
+    },
+  },
+  computed: {},
+  created() {},
+  mounted() {},
+  methods: {
+    open(){
+        this.visible = true
+    },
+    handleClose(){
+        this.visible = false
+    },
+    submit(){
+        if(this.checkList.length>10){
+            this.$message.warning('最多可以选择10张附图!!!')
+            return
+        }
+        this.$emit('getImageGuid',this.checkList)
+        this.handleClose()
+    },
+    uploadImage(){
+        this.uploadVisible = true
+    },
+    /**
+     * 上传文件处理
+     *  */
+    uploadClose(){
+        this.$set(this,'uploadImages',[])
+        this.uploadVisible = false
+    },
+    uploadSubmit(){
+        this.$emit('uploadFileGuid',this.uploadImages)
+        this.uploadClose()
+    },
+    // 上传的文件监听
+    onchangeFile(file, fileList) {
+        if(!this.uploadImages){
+            this.$set(this,'uploadImages',[])
+        }
+        if (file.guid) {
+            let index = this.uploadImages.findIndex(item => {
+                return item.uid == file.uid
+            })
+            if (index != -1) {
+                this.uploadImages.splice(index, 1, file)
+            }
+        } else {
+            this.uploadImages.push(
+              {
+                name:file.raw.name,
+                uid:file.raw.uid
+              }
+            )
+        }
+
+    },
+    // 删除上传的文件
+    onRemove(file, fileList) {
+        let index = this.uploadImages.findIndex(item => {
+            return item.uid == file.uid
+        })
+        if (index != -1) {
+            this.uploadImages.splice(index, 1)
+        }
+    },
+  },
+};
+</script>
+<style lang="scss">
+
+.imageList{
+    display: flex;
+    align-items: center;
+    flex-wrap: wrap;
+    .imageWrap{
+        width: 170px;
+        height: 160px;
+        padding: 10px;
+        margin: 0 10px 10px 10px;
+        border: 1px dashed;
+        display: flex;
+        flex-direction: column;
+        .img{
+            width: 110px;
+            height: 100px;
+            margin: 10px auto;
+        }
+        .name{
+            text-align: center;
+        }
+    }
+
+}
+
+.btns{
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+}
+
+</style>

+ 162 - 6
src/views/AITools/technicalDisclosure/technicalDisclosure.vue

@@ -244,11 +244,42 @@
             </div>
             <!-- AI对话框 -->
             <div class="AIChat" :style="showHistory?'height:100%':'height:auto'">
-              <xiaoshiAI style="width:100%;max-width:100%" :AItype="4" :slotDataFunction="slotDataFunction" :chat_id="chat_id" :params="AIParams" :API_KEY="API_KEY" :chatApi="chat_api" :defaultShowHistory="showHistory" @getShowHistory="getShowHistory" @getConversationId="getConversationId">
+              <xiaoshiAI style="width:100%;max-width:100%" :AItype="4" :slotDataFunction="slotDataFunction" :chat_id="chat_id" :params="AIParams" :API_KEY="API_KEY" :chatApi="chat_api" :defaultShowHistory="showHistory" @getShowHistory="getShowHistory" @getConversationId="getConversationId" @sendMessage="hasSendMessage">
+                <template slot="tools" v-if="AIModel == 'chat'">
+                  <div class="tools">
+                    <!-- <div class="chooseImage" @click="chooseImage">选择附图</div> -->
+                    <div class="imgs">
+                      <div class="img" v-for="(imgSrc,index) in imgGuids" :key="imgSrc">
+                        <div class="operate"><i class="el-icon-error" @click.stop="delImgGuid(imgSrc,index)"></i></div>
+                        <el-image  style="width: 100%; height: 100%"  :src="$commonJS.checkViewer(imgSrc)"  fit="contain" :preview-src-list="[$commonJS.checkViewer(imgSrc)]"></el-image>
+                      </div>
+                    </div>
+                  </div>
+                </template>
                 <template slot="questionBtn">
                   <div>
-                    <el-button size="mini" :type="AIModel=='chat'?'success':'info'" round @click="changeAIModel('chat')">AI对话</el-button>
-                    <el-button size="mini" :type="AIModel=='edit'?'success':'info'" round @click="changeAIModel('edit')">AI修改</el-button>
+                    <!-- <el-button v-if="AIModel == 'chat'" size="mini" round @click="chooseImage" class="margin-right_10">选择附图</el-button> -->
+                    <!-- <el-button size="mini" :type="AIModel=='chat'?'success':'info'" round @click="changeAIModel('chat')">AI对话</el-button>
+                    <el-button size="mini" :type="AIModel=='edit'?'success':'info'" round @click="changeAIModel('edit')">AI修改</el-button> -->
+                    <el-popover
+                      placement="top-start"
+                      title=""
+                      width="200"
+                      trigger="click"
+                      popper-class="technicalDisclosurePopover"
+                      ref="btn_popover"
+                    >
+                      <el-radio-group v-model="AIModel" @input="changeAIModel">
+                        <div :class="['radio_btn',AIModel=='chat'?'active':'']">
+                          <el-radio label="chat">问问题</el-radio>
+                        </div>
+                        <div :class="['radio_btn',AIModel=='edit'?'active':'']">
+                          <el-radio label="edit">修改技术交底书理解结果</el-radio>
+                        </div>
+                      </el-radio-group>
+                      <el-button title="切换AI对话场景" size="mini" type="success" round slot="reference">{{AIModel=='chat'?'问问题':"修改技术交底书理解结果"}}</el-button>
+                    </el-popover>
+                    <el-button title="选择附图" v-if="AIModel == 'chat'" size="mini" icon="el-icon-picture-outline-round" circle class="margin-left_10" @click="chooseImage"></el-button>
                   </div>
                 </template>
                 <template v-if="AIModel == 'edit'" v-slot:answer="data">
@@ -396,6 +427,8 @@
         </div>
       </div>
     </template>
+
+    <imageListDialog ref="imageListDialog" :guids="imgGuids" :imageList="imageList" @getImageGuid="getImageGuid" @uploadFileGuid="getUploadFileGuid"></imageListDialog>
   </div>
 </template>
 
@@ -403,11 +436,13 @@
 import vabOnlyOffice from '@/components/VabOnlyOffice/index.vue'
 import xiaoshiAI from '@/components/xiaoshi_AI'
 import conversationRecords from '../components/conversationRecords.vue';
+import imageListDialog from './dialog/imageList.vue'
 export default {
   components: {
     vabOnlyOffice,
     xiaoshiAI,
-    conversationRecords
+    conversationRecords,
+    imageListDialog
   },
   props: {
   },
@@ -500,7 +535,9 @@ export default {
           show:false,
           filename:'',
           percentage:0
-        }
+        },
+        imgGuids:[],
+        imageList:[],
     };
   },
   watch: {
@@ -539,13 +576,20 @@ export default {
       this.showHistory = val
     },
     changeAIModel(val){
+      let dom = this.$refs.btn_popover
+      if(dom){
+        dom.doClose()
+      }
       this.AIModel = val
       if(this.AIModel == 'chat'){
         this.chat_id = this.currentConversation.dialogueConversationId
         this.AIParams.type = 31
+        this.AIParams.fileGuids = this.imgGuids
       }else if(this.AIModel == 'edit'){
         this.chat_id = this.currentConversation.aiUpdateConversationId
         this.AIParams.type = 32
+        this.imgGuids = []
+        this.AIParams.fileGuids = []
       }
     },
     addData(field,parentData){
@@ -671,6 +715,8 @@ export default {
         this.currentConversation = obj
         return
       }
+      this.$set(this,'imgGuids',[])
+      this.$set(this,'imageList',[])
       this.currentConversation = obj
       this.AIParams.confessionSessionId = obj.id
       this.chat_id = ''
@@ -693,9 +739,53 @@ export default {
       this.getOption()
       if(generate){
         this.generateDiscoveryResult()
+      }else{
+        this.getImageList()
       }
       
     },
+    hasSendMessage(){
+      this.imgGuids = []
+      this.AIParams.fileGuids = []
+    },
+    getUploadFileGuid(value){
+      var params = {
+        confessionSessionId:this.currentConversation.id,
+        fileGuids:value.map(item=>item.guid)
+      }
+      this.$api.uploadDiscoveryPicture(params).then(response=>{
+        if(response.code == 200){
+          var addImage = value.map(item=>{
+            return {
+              originalName:item.name,
+              guid:item.guid,
+              type:item.name.substring(item.name.lastIndexOf('.')+1)
+            }
+          })
+          this.imageList.push(...addImage)
+        }
+      })
+    },
+    chooseImage(){
+      this.$refs.imageListDialog.open()
+    },
+    getImageGuid(value){
+      this.imgGuids = value
+      this.AIParams.fileGuids = this.imgGuids
+    },
+    delImgGuid(guid,index){
+      this.imgGuids.splice(index,1)
+    },
+    getImageList(){
+      var params = {
+        confessionSessionId:this.currentConversation.id
+      }
+      this.$api.queryDiscoveryPicture(params).then(response=>{
+        if(response.code == 200){
+          this.$set(this,'imageList', response.data)
+        }
+      })
+    },
     async generateDiscoveryResult(){
       let params = {
         confessionSessionId:this.currentConversation.id
@@ -711,6 +801,7 @@ export default {
         if(response.code == 200){
           this.currentConversation.discoveryResult = response.data
           this.technicalContent=response.data
+          this.getImageList()
           loading.close();
         }
       }).catch(error=>{
@@ -1116,12 +1207,65 @@ export default {
         }
       }
       .kongbai{
-        height:176px
+        height:210px;
       }
       .AIChat{
         width: 100%;
         position:absolute;
         bottom: 5px;
+        .chooseImage{
+          border: 1px solid #e5e5e5;
+          padding: 7px 12px;
+          border-radius: 32px;
+          cursor: pointer;
+          color: #5d5d5f;
+          width: 60px;
+          &:hover{
+            color: #3498db;
+            border-color: #3498db;
+          }
+        }
+        .tools{
+          display: flex;
+          align-items: flex-end;
+          flex-wrap: nowrap;
+          padding:0 30px;
+          font-size: 14px;
+          margin-top: 10px;
+          margin-bottom: -10px;
+          
+          .imgs{
+            flex:1;
+            width: 100%;
+            display: flex;
+            align-items: flex-end;
+            flex-wrap: nowrap;
+            overflow-x: auto;
+            padding-bottom: 5px;
+            .img{
+              min-width: 50px;
+              max-width: 50px;
+              height:50px;
+              padding: 10px 12px;
+              background: white;
+              border-radius: 12px;
+              margin-right: 8px;
+              position:relative;
+              .operate{
+                position: absolute;
+                right: 5px;
+                top: 5px;
+                z-index: 99999;
+                display: none;
+              }
+              &:hover{
+                .operate{
+                  display: block;
+                }
+              }
+            }
+          }
+        }
       }
     }
     .newConversation{
@@ -1238,6 +1382,18 @@ export default {
   }
 </style>
 <style lang="scss">
+.technicalDisclosurePopover{
+  .radio_btn{
+    padding: 8px;
+    margin-bottom: 2px;
+    border-radius: 10px;
+    width: 100%;
+    cursor: pointer;
+    &:hover{
+      background: #f5f5f5;
+    }
+  }
+}
   .style3{
     .layout_suggestions{
       p{

+ 1 - 1
src/views/layout/components/UserBar.vue

@@ -5,7 +5,7 @@
       <span v-if="$permission.FunPermissions('xiaoshi/AIHelper')">
         <el-dropdown @command="toAI($event)">
           <el-link :underline="true" :type="belong=='AI'?'primary':'default'" class="el-dropdown-link">
-            <span class="AI">小世AI工具</span><i class="el-icon-arrow-down el-icon--right AI" style="font-size:20px"></i>
+            <span class="AI">小世AI</span><i class="el-icon-arrow-down el-icon--right AI" style="font-size:20px"></i>
             </el-link>
           <el-dropdown-menu slot="dropdown">
             <el-dropdown-item command="/technicalDisclosure">技术交底书解析</el-dropdown-item>