소스 검색

Merge branch 'noveltySearch2' into product

zhuliu 7 달 전
부모
커밋
76b68131d7
50개의 변경된 파일11642개의 추가작업 그리고 8589개의 파일을 삭제
  1. 1 0
      public/index.html
  2. 2 0
      src/api/index.js
  3. 32 0
      src/api/newApi/examine.js
  4. 28 1
      src/api/newApi/file.js
  5. 38 0
      src/components/VabOnlyOffice/index.js
  6. 337 0
      src/components/VabOnlyOffice/index.vue
  7. 2 1
      src/config/index.js
  8. 1 0
      src/icons/svg/任务信息.svg
  9. 1 0
      src/icons/svg/分析报告信息.svg
  10. 1 0
      src/icons/svg/审核信息.svg
  11. 1 0
      src/icons/svg/审核历史.svg
  12. 1 0
      src/icons/svg/所属项目.svg
  13. 41 2
      src/router/index.js
  14. 17 1
      src/store/persisPlugin.js
  15. 4 0
      src/utils/axios.js
  16. 10 1
      src/utils/constants.js
  17. 5 1
      src/utils/model/index.js
  18. 116 0
      src/utils/model/observerDom/index.vue
  19. 2 15
      src/utils/permissions.js
  20. 186 0
      src/views/components/onlyOffice/addNewFile.vue
  21. 105 0
      src/views/components/onlyOffice/index.js
  22. 132 0
      src/views/components/onlyOffice/index.vue
  23. 70 8
      src/views/noveltySearch/components/dialog/reportTemplate/reportTemplateDialog.vue
  24. 26 0
      src/views/noveltySearch/components/exportReport/otherTemplate/index.vue
  25. 295 0
      src/views/noveltySearch/components/exportReport/otherTemplate/mixins/index.js
  26. 50 0
      src/views/noveltySearch/components/exportReport/otherTemplate/otherTemplate.vue
  27. 1 1
      src/views/patentMining/components/dialog/addAndEditProject.vue
  28. 88 31
      src/views/patentMining/components/fileMessage.vue
  29. 1 1
      src/views/patentMining/components/handleExamine/index.vue
  30. 4 0
      src/views/patentMining/components/mixins/index.js
  31. 1 1
      src/views/patentMining/components/view/card.vue
  32. 28 9
      src/views/report/components/dialog/addAndEditReport.vue
  33. 27 3
      src/views/report/components/dialog/exportReport.vue
  34. 4 0
      src/views/report/components/mixins/index.js
  35. 46 0
      src/views/report/components/reportFile/examineHistoryDialog.vue
  36. 81 2
      src/views/report/components/reportFile/reportFileTable.vue
  37. 1 1
      src/views/report/components/view/card.vue
  38. 1 1
      src/views/report/components/view/table.vue
  39. 391 0
      src/views/task/components/examine/components/examine.vue
  40. 135 0
      src/views/task/components/examine/components/examineHistory.vue
  41. 122 0
      src/views/task/components/examine/components/examineMessage.vue
  42. 64 0
      src/views/task/components/examine/components/mixins/index.js
  43. 136 0
      src/views/task/components/examine/components/openFile.vue
  44. 247 0
      src/views/task/components/examine/components/projectMessage.vue
  45. 54 0
      src/views/task/components/examine/components/taskMessage.vue
  46. 33 0
      src/views/task/components/examine/index.vue
  47. 21 5
      src/views/task/components/index.vue
  48. 8652 8504
      yarn.lock
  49. BIN
      小世系统(本地).zip
  50. BIN
      小世系统(生产).zip

+ 1 - 0
public/index.html

@@ -7,6 +7,7 @@
     <link rel="icon" href="<%= BASE_URL %>favicon.ico">
     <title><%= htmlWebpackPlugin.options.title %></title>
 </head>
+<script type="text/javascript" src="http://192.168.2.24:9997/web-apps/apps/api/documents/api.js"></script>
 <body>
 <div id="app" ></div>
 </body>

+ 2 - 0
src/api/index.js

@@ -21,6 +21,7 @@ import custom from "./newApi/custom";
 import otherPatentInformation from "./newApi/otherPatentInformation";
 import translate from "./newApi/translate";
 import noveltySearch from "./newApi/noveltySearch";
+import examine from "./newApi/examine";
 import IPREmail from "./newApi/IPREmail";
 
 export default {
@@ -44,5 +45,6 @@ export default {
   ...otherPatentInformation,
   ...translate,
   ...noveltySearch,
+  ...examine,
   ...IPREmail
 }

+ 32 - 0
src/api/newApi/examine.js

@@ -0,0 +1,32 @@
+import axios from "@/utils/axios";
+// 新系统文件新接口
+export default {
+    //保存新文件
+    AddFileExamineTask(data){
+        return axios.post('/xiaoshi/examine/addFileExamineTask', data)
+    },
+    /**
+     * 查询待审核文件
+     * @param {*} data 
+     * @returns 
+     */
+    getExamineMessage(data){
+        return axios.post('/xiaoshi/examine/getExamineMessage',data)
+    },
+    /**
+     * 查询审核历史
+     * @param {*} data 
+     * @returns 
+     */
+    getExamineHistory(data){
+        return axios.post('/xiaoshi/examine/getExamineHistory',data)
+    },
+    /**
+     * 提交审核结果
+     * @param {*} data 
+     * @returns 
+     */
+    submitResult(data){
+        return axios.post('/xiaoshi/examine/submitResult',data)
+    },
+}

+ 28 - 1
src/api/newApi/file.js

@@ -6,5 +6,32 @@ export default {
   },
   downLoadFile(params, prop = {}) {
     return axios.get('/fileManager/downloadFile', {params},prop)
-  }
+  },
+  //获取文件信息
+  getFileData(data){
+    return axios.post('/fileManager/getFileData', data)
+  },
+  //获取jwt加密
+  GetJWT(data){
+    return axios.post('/fms/jwt/Common/GetJWT', data)
+  },
+
+
+  //获取版本历史
+  queryFileVersion(data){
+    return axios.post('/fms/onlyOffice/queryFileVersionHistory', data)
+  },
+  //恢复版本历史
+  restoreVersion(data){
+    return axios.post('/fms/onlyOffice/restoreVersion', data)
+  },
+  //获取当前版本显示的数据
+  getCurrentVersionData(data){
+    return axios.post('/fms/onlyOffice/getCurrentVersionData', data)
+  },
+  //强制保存
+  onlyOffice_forceSave(data){
+    return axios.post('/fms/onlyOffice/forceSave', data)
+  },
+  
 };

+ 38 - 0
src/components/VabOnlyOffice/index.js

@@ -0,0 +1,38 @@
+
+import CryptoJS from "crypto-js";
+const SECRET_KEY = 'VI71S3cGtXg96HgFWzQhblz1KwMc1Jzk';
+
+
+export default{
+    methods: {
+        getJWT(json={id:1}){
+            let header = JSON.stringify(
+                {
+                    "alg": "HS256",
+                    "typ": "JWT"
+                }
+            )
+            let payload = JSON.stringify(
+                {
+                    ...json
+                }
+            )
+            let before_sign = this.base64UrlEncode(CryptoJS.enc.Utf8.parse(header))+'.'+this.base64UrlEncode(CryptoJS.enc.Utf8.parse(payload))
+            let signature = CryptoJS.HmacSHA256(before_sign,SECRET_KEY)
+            signature = this.base64UrlEncode(signature)
+            let final_sign = before_sign+'.'+signature
+            return final_sign
+        },
+        base64UrlEncode(str){
+            var encodedSource = CryptoJS.enc.Base64.stringify(str)
+            var reg = new RegExp('/','g')
+            encodedSource = encodedSource.replace(/=+$/,'').replace(/\+/g,'-').replace(reg,'_')
+            return encodedSource
+        },
+
+    },
+}
+
+
+
+

+ 337 - 0
src/components/VabOnlyOffice/index.vue

@@ -0,0 +1,337 @@
+<!--onlyoffice 编辑器-->
+<template>
+  <div style="height:100%;width:100%" v-loading="loading">
+    <div id='vabOnlyOffice' v-if="show"></div>
+  </div>
+ 
+</template>
+
+<script>
+import mixins from './index.js'
+  export default {
+    name: 'VabOnlyOffice',
+    components:{
+    },
+    mixins:[mixins],
+    props: {
+      option: {
+        type: Object,
+        default: () => {
+          return {}
+        },
+      },
+    },
+    data() {
+      return {
+        doctype: '',
+        docEditor: null,
+        loading:false,
+        show:true,
+        currentVersion:{},
+        historyData:[]
+      }
+    },
+    beforeDestroy() {
+      if (this.docEditor !== null) {
+        if(this.option.model != 'view'){
+          var params = {
+            c:'forcesave',
+            key:this.option.key,
+          }
+          this.$api.onlyOffice_forceSave(params).then(response=>{
+              if(response.code == 200){
+              }
+          })
+        }
+        
+        this.docEditor.destroyEditor();
+        this.docEditor = null;
+      }
+   },
+    watch: {
+      // option: {
+      //   handler: function(n) {
+      //     this.setEditor(n)
+      //     this.doctype = this.getFileType(n.fileType)
+      //   },
+      //   deep: true,
+      // },
+    },
+    mounted() {
+      if (this.option.url) {
+        this.setEditor(this.option)
+      }
+    },
+    methods: {
+      async setEditor(option) {
+        if (this.docEditor !== null) {
+          this.docEditor.destroyEditor();
+          this.docEditor = null;
+        }
+        var params = {
+          guid:this.option.id,
+        }
+        await this.$api.getCurrentVersionData(params).then(response=>{
+          if(response.code == 200){
+            if(response.data && response.data.fileType){
+              var obj = response.data
+              this.option.fileType=obj.fileType,
+              this.option.key=obj.key,
+              this.option.version = obj.version
+              this.option.url=this.$c.url+ (this.$c.env=='production'?'/api':'')+'/fileManager/downloadFile?fileId=' +obj.url
+            }
+          }
+        })
+        this.doctype = this.getFileType(option.fileType)
+        var user={
+          id:option.user.id,
+          name:option.user.name
+        }
+        
+        let callbackUrl = this.$c.url + (this.$c.env=='production'?'/api/fms':'') +`/onlyOffice/callback?guid=${option.id}`
+        if(option.title){
+          callbackUrl += `&fileName=${option.title}`
+        }
+        if(option.created){
+          callbackUrl += `&created=${option.created}`
+        }
+        if(user.id){
+          callbackUrl += `&user=${user.id}`
+        }
+        if(option.version){
+          callbackUrl += `&previousVersion=${option.version}`
+        }
+
+
+        let config = {
+          document: {
+            //后缀
+            fileType: option.fileType,
+            key: option.key ||'',
+            title: option.title,
+            permissions: {
+              edit: option.isEdit||true,//是否可以编辑: 只能查看,传false
+              print: option.isPrint ||true,
+              download: true,
+              fillForms: true,//是否可以填写表格,如果将mode参数设置为edit,则填写表单仅对文档编辑器可用。 默认值与edit或review参数的值一致。
+              review: true, //跟踪变化
+              comment:true,//是否可以注释文档
+              copy:true,
+              chat: true,
+            },
+            url: option.url,
+          },
+          documentType: this.doctype,
+          editorConfig: {
+            // callbackUrl: 'http://192.168.2.24:8803/Test/TestQuery',//"编辑word后保存时回调的地址,这个api需要自己写了,将编辑后的文件通过这个api保存到自己想要的位置
+            callbackUrl: callbackUrl,//"编辑word后保存时回调的地址,这个api需要自己写了,将编辑后的文件通过这个api保存到自己想要的位置
+            lang: option.lang,//语言设置
+            //定制
+            customization: {
+              comments:true,
+              about:false,
+              autosave: true,//是否自动保存
+              forcesave:true,
+              review: {
+                hideReviewDisplay: false,
+                showReviewChanges: false,
+                reviewDisplay: "markup",
+                trackChanges: true,
+                hoverMode: true,
+            },
+              help: false,
+              // "hideRightMenu": false,//定义在第一次加载时是显示还是隐藏右侧菜单。 默认值为false
+              //是否显示插件
+              plugins: false,
+              // "about": true,
+              // "feedback": false
+              // customer:{
+              //   logo:'https://www.xsip.cn/api/fileManager/downloadFile?fileId=9ba11d7c72d24387a8cb2f484c23e0a5',
+              //   address:'',
+              //   info:'',
+              //   logoDark:'https://www.xsip.cn/api/fileManager/downloadFile?fileId=9ba11d7c72d24387a8cb2f484c23e0a5',
+              //   mail:'',
+              //   name:'',
+              //   www:'',
+              // },
+              logo: {
+              //   image: "https://www.xsip.cn/api/fileManager/downloadFile?fileId=9ba11d7c72d24387a8cb2f484c23e0a5",
+              //   imageDark: "https://www.xsip.cn/api/fileManager/downloadFile?fileId=9ba11d7c72d24387a8cb2f484c23e0a5",
+              //   url: "",
+                visible: false,
+              },
+            },
+            user:user,
+            mode:option.model?option.model:'edit',
+            // "canCoAuthoring": true
+          },
+          events:{
+            onRequestHistory:this.onRequestHistory,//获取历史记录
+            onRequestHistoryData:this.onRequestHistoryData,//获取历史文件
+            onRequestRestore:this.onRequestRestore,//恢复
+            onRequestHistoryClose:this.onRequestHistoryClose,//关闭历史
+          },
+          width: '100%',
+          height: '100%',
+          // token:option.token||'',
+          // frameEditorId: "vabOnlyOffice",
+          // parentOrigin: window.location.origin,
+          // type: "desktop"
+        }
+        if(!config.token){
+          //获取token并赋值
+          var data = {
+            jsons:JSON.stringify(config)
+          }
+          this.loading = true
+          await this.$api.GetJWT(data).then(response=>{
+            if(response.code == 200){
+              config.token = response.data
+              this.option.token = response.data
+              this.loading = false
+            }
+          }).catch(error=>{
+            this.loading  = false
+          })
+          // config.token = this.getJWT(config)
+         
+        }
+       
+        // eslint-disable-next-line no-undef,no-unused-vars
+        this.docEditor = new DocsAPI.DocEditor('vabOnlyOffice', config)
+      },
+      async onRequestHistory(event){
+        var params = {
+          guid:this.option.id
+        }
+        var that = this
+        await this.$api.queryFileVersion(params).then(response=>{
+          if(response.code == 200){
+            that.currentVersion = response.data.currentVersion
+            that.historyData = response.data.history
+          }
+        })
+        
+        if((this.historyData && this.historyData.length == 0) || !this.historyData || !this.currentVersion){
+          that.docEditor.refreshHistory({
+            currentVersion:'',
+            history:[]
+          })
+          return
+        }
+        var currentVersion = this.currentVersion
+        this.option.version = currentVersion
+        var history = []
+        for(var i = 0;i<that.historyData.length;i++){
+          var item = that.historyData[i]
+            history.push(
+                {
+                  serverVersion:item.serverVersion,
+                  // changes:item.changes,
+                  created:item.created,
+                  user:item.user,
+                  version:item.version,
+                  key:item.key,
+                }
+              )
+        }
+        history.reverse()
+        this.docEditor.refreshHistory(
+          {
+            currentVersion:currentVersion,
+            history:history
+          }
+        )
+        return
+      },
+      async onRequestHistoryData(event){
+        const version = event.data
+        var obj = this.historyData.find(item=>{
+          return item.version == version
+        })
+        if(obj){
+          var obj1 = null
+          if(obj.previousVersion){
+            obj1 = this.historyData.find(item=>{
+              return item.version == obj.previousVersion
+            })
+          }
+          var obj2 = {
+            fileType:obj.fileType,
+            key:obj.key,
+            url:this.$c.url+ (this.$c.env=='production'?'/api':'')+'/fileManager/downloadFile?fileId=' +obj.url,
+            version:obj.version,
+            // previous:obj1?{
+            //   fileType:obj1.fileType,
+            //   key:obj1.key,
+            //   url:this.$c.url+ (this.$c.env=='production'?'/api':'')+'/fileManager/downloadFile?fileId=' +obj1.url,
+            // }:null,
+            // changesUrl:obj.changesUrl?(this.$c.url+ (this.$c.env=='production'?'/api':'')+'/fileManager/downloadFile?fileId=' +obj.changesUrl):""
+          }
+          var params = {
+            jsons:JSON.stringify(obj2)
+          }
+          this.loading = true
+          await this.$api.GetJWT(params).then(response=>{
+            if(response.code == 200){
+              obj2.token = response.data
+              this.option.token = response.data
+              this.loading = false
+            }
+          }).catch(error=>{
+            this.loading  = false
+          })
+          this.docEditor.setHistoryData(obj2)
+          }
+      },
+      //恢复
+      onRequestRestore(event){
+        const version = event.data.version
+        var params = {
+          userId:this.option.user.id,
+          userName:this.option.user.name,
+          restoreVersion:version,
+          previousVersion:this.option.version,
+          guid:this.option.id
+        }
+        this.$api.restoreVersion(params).then(response=>{
+          if(response.code == 200){
+            this.setEditor(this.option)
+          }
+        })
+      },
+      onRequestHistoryClose(event){
+        this.setEditor(this.option)
+      },
+      getFileType(fileType) {
+        let docType = ''
+        let fileTypesDoc = [
+            'doc', 'docm', 'docx', 'dot', 'dotm', 'dotx', 'epub', 'fodt', 'htm', 'html', 'mht', 'odt', 'ott', 'pdf', 'rtf', 'txt', 'djvu', 'xps',
+        ]
+        let fileTypesCsv = [
+            'csv', 'fods', 'ods', 'ots', 'xls', 'xlsm', 'xlsx', 'xlt', 'xltm', 'xltx',
+        ]
+        let fileTypesPPt = [
+            'fodp', 'odp', 'otp', 'pot', 'potm', 'potx', 'pps', 'ppsm', 'ppsx', 'ppt', 'pptm', 'pptx',
+        ]
+        if (fileTypesDoc.includes(fileType)) {
+            docType = 'text'
+        }
+        if (fileTypesCsv.includes(fileType)) {
+            docType = 'spreadsheet'
+        }
+        if (fileTypesPPt.includes(fileType)) {
+            docType = 'presentation'
+        }
+        return docType
+      },
+    },
+  }
+</script>
+<style>
+.extra #header-logo i{
+  background-image: url('../../assets/logo.png') !important;
+}
+</style>
+
+

+ 2 - 1
src/config/index.js

@@ -4,7 +4,8 @@ export default {
     updateTime:'2023-08-04 08:00:00',
     specialDays:['05-12','09-18','12-13'],
     host: window.location.host,
-    url:process.env.NODE_ENV === 'production' ? 'https://xsip.cn' : 'http://192.168.2.24:8803',
+    url:process.env.NODE_ENV === 'production' ? 'https://xsip.cn' : 'http://192.168.2.105:8803',
     staticURL: process.env.NODE_ENV === 'production' ? 'https://xsip.cn/onlinePreview' : 'http://192.168.2.24:8879/onlinePreview',
     WebSocketPath: process.env.NODE_ENV === 'production' ? 'wss://xsip.cn' : 'ws://192.168.2.24:8879',
+    WebSocketPathFMS: process.env.NODE_ENV === 'production' ? 'wss://xsip.cn' : 'ws://192.168.2.105:8803',
 }

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
src/icons/svg/任务信息.svg


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
src/icons/svg/分析报告信息.svg


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
src/icons/svg/审核信息.svg


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
src/icons/svg/审核历史.svg


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
src/icons/svg/所属项目.svg


+ 41 - 2
src/router/index.js

@@ -496,6 +496,17 @@ const routes = [
             },
             component: () => import('@/views/noveltySearch/components/exportReport/index.vue'),
           },
+          // 导出报告2
+          {
+            path: '/exportReportByFile',
+            name: 'exportReportByFile',
+            meta: {
+              title: '导出报告',
+              sign: 'exportReportByFile',
+              belong: 'AllReport',
+            },
+            component: () => import('@/views/noveltySearch/components/exportReport/otherTemplate/index.vue'),
+          },
           // 复用结果
           {
             path: '/reuseResults',
@@ -526,6 +537,16 @@ const routes = [
             },
             component: () => import('@/views/task/index.vue'),
           },
+          {
+            path: '/examine',
+            name:'examine',
+            meta: {
+              title: '审核任务处理',
+              sign: 'examine',
+              belong: 'myTask'
+            },
+            component: () => import('@/views/task/components/examine/index.vue'),
+          },
         ]
       },
       //场景可视化
@@ -681,7 +702,25 @@ const routes = [
           },
         ],
       },
-
+      //onlyoffice在线编辑
+      {
+        path: '/onlyOffice',
+        name: 'onlyOffice',
+        component: { render(c) { return c('router-view') } },
+        redirect: '/onlyOffice',
+        children: [
+          {
+            path: '/onlyOffice',
+            name:'onlyOffice',
+            meta: {
+              title: '在线编辑',
+              sign: 'onlyOffice',
+              belong: 'onlyOffice'
+            },
+            component: () => import('@/views/components/onlyOffice/index.vue'),
+          },
+        ],
+      },
     ]
   },
 ]
@@ -697,7 +736,7 @@ const router = new VueRouter({
 
 
 function savePreviousRoute(to){
-  if(to.meta.notReturn || to.path == '/login' || to.path == '/'){
+  if(to.meta.notReturn || to.path == '/login' || to.path == '/' || to.path == '/onlyOffice'){
     return
   }
   var redirectUrl = {

+ 17 - 1
src/store/persisPlugin.js

@@ -41,12 +41,28 @@ export default function(store){
     window.addEventListener('storage', function(e) {  
         var key = e.key
         if(key == 'changePermission'){
-            console.log(1)
             if(storage.getObj('vuex')){
                 console.log(2)
                 store.replaceState(storage.getObj('vuex'))
             }
             
         }
+        if(key == 'onlyOfficeFile'){
+            var data = localStorage.getItem('onlyOfficeFile')
+            if(!data){
+                return
+            }
+            var data1 = JSON.parse(data)
+            var message = this.$message({
+                message: '信息保存中,请不要立即下载',
+                type: 'warning',
+                duration:0
+            });
+              setTimeout(()=>{
+                message.close()
+                this.$message.success('信息保存成功')
+                localStorage.setItem('onlyOfficeFile',null)
+              },10000)
+        }
     });  
 }

+ 4 - 0
src/utils/axios.js

@@ -62,6 +62,10 @@ _axios.interceptors.response.use(
       loadingInstance.close()
     }
     let { code, message } = response.data
+    if(code != 0 && !code ){
+      isRefreshing = false
+      return response.data
+    }
     if (code === 200 || config.responseType === 'blob') {
       isRefreshing = false
       return response.data

+ 10 - 1
src/utils/constants.js

@@ -227,7 +227,7 @@ showType:[
     value:3
   },
 ],
-sourceId:process.env.NODE_ENV === 'production'?6:1,
+sourceId:6,
 
 //更新周期
 updateCycle:[
@@ -252,4 +252,13 @@ updateCycle:[
     value:'year'
   },
 ],
+
+taskStatus:{
+  1: '审核中',
+  2: '处理中',
+  3: '已完成',
+  4: '缺少资料',
+  5: '取消',
+  6: '确认结果中',
+}
 }

+ 5 - 1
src/utils/model/index.js

@@ -26,6 +26,9 @@ import myTabsItem from './tabs/tabsItem'
 //查新检索发明点弹窗
 import inventionPointDialog from '@/views/noveltySearch/components/dialog/inventionPoint/inventionPoint.vue'
 
+//可监视的dom
+import observerDom from './observerDom/index.vue'
+
 var models = {
   myCustomSvg,
   myTree,
@@ -50,7 +53,8 @@ var models = {
   //tab
   myTabs,
   myTabsItem,
-  inventionPointDialog
+  inventionPointDialog,
+  observerDom
 }
 export default {
   install(Vue) {

+ 116 - 0
src/utils/model/observerDom/index.vue

@@ -0,0 +1,116 @@
+<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>
+    </div>
+    
+</template>
+
+<script>
+import commonJS from '@/utils/common.js'
+export default {
+  components: {},
+  props: {
+    params:{
+        type:Object,
+        default:()=>{
+            return {}
+        }
+    },
+    url:{
+        type:String,
+        default:''
+    },
+    isObserver:{
+        type:Boolean,
+        default:true
+    },
+    fun:{
+        type:Function,
+        default:null
+    },
+    keys:{
+        type:String,
+        default:''
+    }
+  },
+  data() {
+    return {
+        show:true,
+        html:'',
+        observer:null,
+        key:this.keys || commonJS.uuid(24)
+    };
+  },
+  watch: {
+  },
+  computed: {},
+  created() {},
+  mounted() {
+    this.init()
+  },
+  beforeDestroy() {
+    // 取消对元素的观察
+    if (this.observer) {
+      this.observer.disconnect();
+    }
+  },
+  methods: {
+    init(){
+        if(!this.url && !this.fun){
+            return
+        }
+        if(!this.isObserver){
+            this.getHtml()
+            return
+        }
+        var that = this
+        // 创建一个 Intersection Observer 实例
+        this.observer = new IntersectionObserver((entries, observer) => {
+            entries.forEach(entry => {
+                if (entry.isIntersecting) {
+                    // 当元素进入视口时执行的逻辑
+                    that.getHtml()
+                    // 可以在这里执行懒加载、动画触发等操作
+                    observer.unobserve(entry.target); // 如果只需要触发一次,可以取消观察
+                    that.observer.disconnect();
+                }
+            });
+        }, {
+            root: null, // null 表示视口
+            rootMargin: '0px',
+            threshold: 0.3 // 当元素 10% 进入视口时触发
+        });
+
+        // 选择需要观察的元素
+        const elements = this.$refs['observerDom'+this.key];
+        this.observer.observe(elements);
+    },
+    async getHtml(){
+        if(!this.url && !this.fun){
+            return
+        }
+        this.show = false
+        if(this.url){
+            this.$api[this.url](this.params).then(async response=>{
+                if(response.code == 200){
+                    if(this.fun){
+                        this.html = await this.fun(response.data)
+                    }else{
+                        this.html = response.data
+                    }
+                    this.show = true
+                }
+            }).catch(error=>{
+                this.show = true
+            })
+            return
+        }
+        this.html = await this.fun()
+
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+</style>'

+ 2 - 15
src/utils/permissions.js

@@ -1,20 +1,7 @@
 import Store from '@/store'
 import Api from '@/api'
+// roleType:1是系统管理员,2是租户管理员,0是普通人员
 export default {
-  //专利数据库权限
-  // hasRole(projectId, roles){
-  //   if (!projectId) {
-  //     return true
-  //   }
-  //   const permissions = Store.getters && Store.getters.permissions
-  //   const p = permissions[projectId]
-  //   return p === 0 || roles.indexOf(p) !== -1
-  // },
- 
-  //专利数据库权限
-  // hasPermission(sign){
-  //   return (Store.state.admin.permission).indexOf(sign) !== -1
-  // },
   //报告权限
   reportPermission(reportId, roles){
     // return true
@@ -105,7 +92,7 @@ export default {
    */
   async producePermission(id,type){
     const user = Store.state.user.userinfo
-    if(user.roleType = 1 || user.roleType == 2){
+    if(user.roleType == 1 || user.roleType == 2){
       return true
     }
     if(!id || !type){

+ 186 - 0
src/views/components/onlyOffice/addNewFile.vue

@@ -0,0 +1,186 @@
+<template>
+  <div>
+    <el-dialog title="提交审核" :visible.sync="visible" width="500px" append-to-body destroy-on-close
+      :close-on-click-modal="false" :before-close="handleClose">
+      <div>
+        文件信息
+        <hr>
+        <el-form :model="fileForm" ref="fileForm" label-width="120px" >
+          <el-form-item label="文件名称:" prop="referencesName">
+            <el-input v-model="fileForm.referencesName" :disabled="true" placeholder="请输入文件名称"></el-input>
+          </el-form-item>
+          <!-- <el-form-item label="备注:" prop="remark">
+            <el-input v-model="fileForm.remark" placeholder="请输入备注" type="textarea"></el-input>
+          </el-form-item> -->
+        </el-form>
+      </div>
+      <div>
+        任务信息
+        <hr>
+        <el-form :model="taskForm" :rules="TaskRules" ref="form" label-width="120px">
+          <el-form-item label="任务名称:" prop="name">
+            <el-input v-model="taskForm.name" type="text" :disabled="true" placeholder="请输入任务名称" />
+          </el-form-item>
+          <el-form-item label="审核人:" prop="handler">
+            <el-select v-model="taskForm.handler" placeholder="请选择负责人" style="width: 100%;" filterable remote
+              :remote-method="querySearchPersonnel" v-SelectLazyLoading="personnelLoad"
+              :loading="personnelList.loading">
+                  <el-option v-for="item in personnelList.data" :key="item.id" :label="item.name" :value="item.id"></el-option>
+              </el-select>
+            <!-- <el-autocomplete v-model="taskForm.handlerName" value-key="name" v-SelectLazyLoading="personnelLoad"
+                :fetch-suggestions="querySearchPersonnel" placeholder="请输入审核人(外部审核人请直接输入邮箱)" :trigger-on-focus="false"
+                @select="handleSelectPersonnel" @blur="handleBlur(taskForm.handlerName)" style="width: 100%;"></el-autocomplete> -->
+          </el-form-item>
+          <el-form-item label="截止日期:" prop="deadLineTime">
+            <el-date-picker style="width:100%" v-model="taskForm.deadLineTime" value-format="yyyy-MM-dd HH:mm:ss"
+              type="datetime" placeholder="选择日期">
+            </el-date-picker>
+          </el-form-item>
+          <el-form-item label="备注:" prop="description">
+            <el-input v-model="taskForm.description" type="textarea" placeholder="输入备注" />
+          </el-form-item>
+        </el-form>
+      </div>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="handleClose">取 消</el-button>
+        <el-button type="primary" :loading="btnLoading" @click="submit">确 定</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  components: {},
+  props: {},
+  data() {
+    const isTime = (rule, value, callback) => {
+      if (this.isEndTime) {
+        this.isEndTimes = Date.parse(new Date)
+      }
+
+      let b = Date.parse(value)
+      if (value) {
+        if (b < this.isEndTimes) {
+          callback(new Error('禁止选择现在及以前时间,请重新选择'))
+        } else {
+          callback()
+        }
+      } else {
+        callback(new Error('请选择时间'))
+      }
+    }
+    return {
+        visible:false,
+        fileForm:{},
+        btnLoading:false,
+        taskForm:{},
+        isEndTime: true,
+        isEndTimes: null,
+        // 任务表单校验
+        TaskRules: {
+          name: [{ required: true, message: '请输入任务名称', trigger: 'blur' },],
+          handler: [{ required: true, message: '请选择审核人', trigger: 'change' },],
+          deadLineTime: [{ required: true, validator: isTime, trigger: 'change' }],
+        },
+        //人员列表懒加载
+        personnelList: {
+          queryParams: {
+            current: 1,
+            size: 10
+          },
+          loading: false,
+          name: '',
+          data: [],
+        },
+    };
+  },
+  watch: {},
+  computed: {},
+  created() {},
+  mounted() {},
+  methods: {
+    open(form = {},taskForm = {}){
+        this.fileForm = form
+        this.taskForm = taskForm
+        this.querySearchPersonnel()
+        this.visible = true
+    },
+    handleClose(){
+      this.$refs.form.resetFields()
+      this.visible = false
+      this.taskForm = {}
+    },
+    submit(){
+      this.btnLoading = true
+      // if (this.taskForm.handlerName.includes('@')) {//是邮箱为1
+      //   this.taskForm.handlerType = 1
+      // } else {//是id为0
+        this.taskForm.handlerType = 0
+      // }
+      var files = [this.fileForm]
+      var params = {
+        fileForm:{
+          projectId:this.fileForm.projectId,
+          files:files
+        },
+        taskForm:this.taskForm
+      }
+      this.$api.AddFileExamineTask(params).then(response=>{
+        if(response.code == 200){
+          this.$message.success('任务添加成功')
+          this.btnLoading = false
+          this.handleClose()
+        }
+      }).catch(error=>{
+        this.btnLoading = false
+      })
+    },
+     /**
+    * 人员
+    */
+    // 懒加载人员方法
+    personnelLoad() {
+      if (this.personnelList.queryParams.current * this.personnelList.queryParams.size >= this.personnelList.queryParams.total) {
+        return false
+      }
+      this.personnelList.queryParams.current++
+      this.questionPersonnel()
+    },
+    // 查询人员
+    async questionPersonnel() {
+      let params = {
+        ...this.personnelList.queryParams,
+        name:this.personnelList.name
+      }
+      await this.$api.getPermissionPersonnel(params).then(res => {
+        if (res.code == 200) {
+          this.personnelList.data.push(...res.data)
+          this.personnelList.queryParams.total = res.pageColumn.total
+          // this.personnelList.cb(this.personnelList.data);
+        }
+      })
+    },
+    //获取下拉建议人员数据
+    async querySearchPersonnel(queryString, cb) {
+      this.personnelList.queryParams.current = 1
+      this.personnelList.name = queryString
+      this.personnelList.data = []
+      this.personnelList.cb = cb
+      await this.questionPersonnel()
+    },
+    // 人员输入框失焦
+    handleBlur(val) {
+      if (this.taskForm.handlerName && this.taskForm.handlerName.includes('@')) {
+        this.taskForm.handler = val
+      }
+    },
+    // 人员输入框选择
+    handleSelectPersonnel(val) {
+      this.taskForm.handler=val.id
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+</style>

+ 105 - 0
src/views/components/onlyOffice/index.js

@@ -0,0 +1,105 @@
+
+import addNewFile from "./addNewFile.vue"
+import { mapGetters } from "vuex";
+export default{
+    components:{
+        addNewFile
+    },
+    computed:{
+        // ...mapGetters(['webSocket']),
+        userinfo(){
+            return this.$s.getObj('userinfo')
+        },
+    },
+    data() {
+        return {
+            fun:null,
+            isOtherComponent:null,
+            waitLoading:false
+        }
+    },
+    mounted() {
+        this.initWebSocket()
+    },
+    methods: {
+        initWebSocket() {
+            let webSocket = new WebSocket(`${this.$c.WebSocketPathFMS}/api/fms/ws/` + this.userinfo.id)
+            webSocket.onmessage = (e) => {
+              const { code, data, message } = JSON.parse(e.data)
+              if (code == 702) {//文件保存成功
+                // this.$message.success('文件保存成功')
+                this.waitLoading = false
+                if(this.fun){
+                    if(this.isOtherComponent){
+                        this.$emit(this.fun)
+                        this.isOtherComponent = null
+                    }else{
+                        this[this.fun]()
+                    }
+                    this.fun = null
+                }
+              }
+              if(code == 703){//恢复版本
+
+              }
+            }
+        },
+        //调用强制保存
+        async forceSave(){
+            var params = {
+                c:'forcesave',
+                key:this.option.key,
+            }
+            var data = null
+            await this.$api.onlyOffice_forceSave(params).then(response=>{
+                if(response.code == 200){
+                    data = response.data
+                }
+            })
+            return data
+        },
+        //请求文件保存
+        async requestSave(fun,type){
+            if(!fun){
+                return
+            }
+            var data = await this.forceSave()
+            if(data==1){
+                if(type){
+                    this.$emit(fun)
+                }else{
+                    this[fun]()
+                }
+                
+            }else if(data == 2){
+                this.waitLoading = true
+                this.isOtherComponent = type
+                this.fun = fun
+            }
+        },
+        //发起审核
+        examine(){
+            var title = this.option.title
+            var taskName = ''
+            if(title.endsWith('.'+this.option.fileType)){
+                title = title.slice(0, -(this.option.fileType.length+1))
+            }
+            taskName = title + '-' + this.option.user.name + '-' + '文件审核'
+            title = title + '-' + this.option.user.name + '.' + this.option.fileType
+            var form = {
+                referencesName:title,
+                guid:this.option.id,
+                projectId:this.file.projectId,
+                fileType:this.option.fileType
+            }
+            var taskForm = {
+                name:taskName
+            }
+            this.$refs.addNewFile.open(form,taskForm)
+        },
+    },
+}
+
+
+
+

+ 132 - 0
src/views/components/onlyOffice/index.vue

@@ -0,0 +1,132 @@
+<template>
+    <div class='qualityManual-container'>
+        <div class="menu_btn">
+            <el-button size="small" type="primary" @click="requestSave('examine')" :loading="waitLoading">提交审核</el-button>
+        </div>
+        <div v-if='show' class='qualityManual-container-office'>
+            <vab-only-office :option='option'/>
+        </div>
+        <addNewFile ref="addNewFile"></addNewFile>
+    </div>
+</template>
+<script>
+import vabOnlyOffice from '@/components/VabOnlyOffice/index.vue'
+import { formatDate } from "@/utils";
+import mixins from './index.js'
+export default {
+    components: {
+        vabOnlyOffice,
+    },
+    mixins:[mixins],
+    data() {
+        return {
+            //参考vabOnlyOffice组件参数配置
+            option: {
+                url: '',
+                isEdit: true,
+                fileType: '',
+                title: '',
+                lang: 'zh-CN',
+                isPrint: true,
+                user: {
+                    id: this.$s.getObj('userinfo').id,
+                    name: this.$s.getObj('userinfo').name
+                }
+            },
+            show: false,
+        }
+    },
+    computed:{
+        file(){
+            return this.$route.query
+        },
+    },
+    created(){
+    },
+    mounted() {
+        this.loadOnlyOffice()
+    },
+    deactivated(){
+    },
+    methods:{
+        loadOnlyOffice(){
+            if(!this.file.guid){
+                return
+            }
+            if(!this.file.fileType){
+                var fileIds = [this.file.guid]
+                this.$api.getFileData(fileIds).then(response=>{
+                    if(response && response.length>0){
+                        var data = response[0]
+                        this.file.fileType = data.type
+                        this.getOption()
+                    }
+                })
+            }else{
+                this.getOption()
+            }
+            // this.option.name = optionTemp.name
+            // this.option.id = optionTemp.id
+            // this.option.title = optionTemp.title
+            // this.option.url = optionTemp.url
+            // this.option.fileType = optionTemp.fileType
+            // this.option.token = optionTemp.token
+            // this.show = true
+        },
+        //刷新网页参数
+        reLoadQuery(data={}){
+            this.$router.replace({
+                path: '/onlyOffice',
+                query: {
+                    ...this.file,
+                    ...data
+                
+                }
+            })
+        },
+        getOption(){
+            this.option.name = this.file.title
+            this.option.id = this.file.guid
+            this.option.title = this.file.title
+            this.option.url = this.$c.url+ (this.$c.env=='production'?'/api':'')+'/fileManager/downloadFile?fileId=' + this.file.guid
+            this.option.fileType = this.file.fileType
+            this.option.key = this.file.guid
+            this.option.created = this.file.createTime || formatDate(new Date(),'YYYY-MM-DD HH:mm:ss')
+            this.$nextTick(()=>{
+                this.show = true
+            })
+            
+            // this.option.token = optionTemp.token
+        },
+        generateString(length) {
+            let result = '';
+            const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
+            const charactersLength = characters.length;
+            for (let i = 0; i < length; i++) {
+                result += characters.charAt(Math.floor(Math.random() * charactersLength));
+            }
+            return result;
+        }
+    }
+}
+</script>
+<style>
+  .qualityManual-container {
+    padding: 0 !important;
+    height: 100%;
+  }
+
+  .qualityManual-container-office {
+    width: 100%;
+    height: calc(100% - 50px);
+  }
+</style>
+<style lang="scss" scoped>
+  .menu_btn{
+    height: 45px;
+    padding: 0 20px;
+    display: flex;
+    align-items: center;
+    flex-direction: row-reverse;
+  }
+</style>

+ 70 - 8
src/views/noveltySearch/components/dialog/reportTemplate/reportTemplateDialog.vue

@@ -9,7 +9,8 @@
         :modal="false"
         v-loading="loading"
         :before-close="close">
-        <div style="height: calc(100vh - 350px)">
+        <div style="height: calc(100vh - 300px)">
+          
         <el-container>  
           <el-main class="height_100" :loading="loading">
             <el-table
@@ -75,6 +76,14 @@ export default {
   created() {},
   mounted() {},
   methods: {
+    otherTemplate(){
+      let router = this.$router.resolve({
+          path: '/exportReportByFile',
+          query: {
+          }
+      })
+      window.open(router.href, '_blank')
+    },
     open(projectId){
       this.projectId = projectId
       this.queryParams.current = 1
@@ -109,18 +118,71 @@ export default {
       this.getReportTemplate()
     },
     chooseReportTemplate(row){
-      let router = this.$router.resolve({
-          path: '/exportReport',
-          query: {
-            reportTemplateId: row.id,
-            // path:row.configMessage,
-            projectId: this.projectId,
+      var params = {
+          projectId:this.projectId,
+          templateId:row.id,
+      }
+      var message = this.$message({
+          message: '报告生成中...',
+          type: 'warning',
+          duration:0
+      });
+      this.loading = true
+      this.$api.editNoveltyReport(params).then(response=>{
+          if(response.code == 200){
+            message.close()
+            this.$message.success('报告生成成功')
+            this.loading = false
+            this.toEdit(response.data)
           }
+      }).catch(error=>{
+          message.close()
+          this.$message.error('报告生成失败')
+      })
+      // let router = this.$router.resolve({
+      //     path: '/exportReport',
+      //     query: {
+      //       reportTemplateId: row.id,
+      //       // path:row.configMessage,
+      //       projectId: this.projectId,
+      //     }
+      // })
+      // window.open(router.href, '_blank')
+    },
+    toEdit(id){
+      let params = {
+        projectId: this.projectId,
+        current:1,
+        size:1,
+        id:id
+      }
+      var api = 'queryNoveltyReport'
+      this.$api[api](params).then(res => {
+        if (res.code == 200) {
+          var data = res.data.data
+          if(data && data.length){
+            let router = this.$router.resolve({
+              path: '/onlyOffice',
+              query: {
+                  projectId:this.projectId,
+                  guid:data[0].fileGuid,
+                  title:data[0].referencesName
+              }
+            })
+            window.open(router.href, '_blank')
+          }
+          this.loading = false
+        }
+      }).catch(error => {
+        this.loading = false
       })
-      window.open(router.href, '_blank')
     },
   },
 };
 </script>
 <style lang="scss" scoped>
+.head{
+  display: flex;
+  justify-content: flex-end;
+}
 </style>

+ 26 - 0
src/views/noveltySearch/components/exportReport/otherTemplate/index.vue

@@ -0,0 +1,26 @@
+<template>
+  <div class="height_100">
+    <otherTemplate></otherTemplate>
+  </div>
+</template>
+
+<script>
+import otherTemplate from './otherTemplate.vue';
+export default {
+  components: {
+    otherTemplate
+  },
+  props: {},
+  data() {
+    return {
+    };
+  },
+  watch: {},
+  computed: {},
+  created() {},
+  mounted() {},
+  methods: {},
+};
+</script>
+<style lang="scss" scoped>
+</style>

+ 295 - 0
src/views/noveltySearch/components/exportReport/otherTemplate/mixins/index.js

@@ -0,0 +1,295 @@
+
+export default{
+    data() {
+        return {
+            json:{}
+        }
+    },
+    methods: {
+        
+        jsonToHtml(json){
+            var {width,height} = json.size
+            var slides = json.slides
+            var html = ''
+            for(let {item,index} in slides){
+                const { type, value } = item.fill
+                
+                var divStyle = ''
+                if (type === 'image') {
+                    divStyle = `background-image: url(${value.picBase6});`
+                }
+                else if (type === 'gradient') {
+                    divStyle = `background-image: radial-gradient(${value.rot}, ${value.colors[0].color}, ${value.colors[value.colors.length - 1].color});`
+                }
+                else {
+                    divStyle = `background-color:${value}`
+                }
+                var div =  `<div id='page${index+1}' style='width:${width}px;height:${height}px;position:relative; ${divStyle}'>`
+                const elements = item.elements
+                for(let el in elements){
+                    var style = 'position:absolute;'
+                    var content=el.content
+                    var tag = ''
+                    var obj = {}
+                    if (el.type === 'text') {
+                        obj = {
+                          width: el.width,
+                          height: el.height,
+                          left: el.left,
+                          top: el.top,
+                          'transform': rotate(el.rotate),
+                        //   defaultFontName: theme.value.fontName,
+                        //   defaultColor: theme.value.fontColor,
+                        //   content: el.content,
+                          'line-height': 1,
+                        //   outline: {
+                        //     color: el.borderColor,
+                        //     width: el.borderWidth,
+                        //     style: el.borderType === 'solid' ? 'solid' : 'dashed',
+                        //   },
+                          border:`${el.borderWidth} ${(el.borderType === 'solid' ? 'solid' : 'dashed')} ${el.borderColor}`,
+                          background: el.fillColor,
+                          'text-direction': el.isVertical,
+                          'writing-mode':el.isVertical,
+                          'box-shadow':el.shadow
+                        }
+                        tag = 'span'
+                        
+                      }
+                      else if (el.type === 'image') {
+                        obj = {
+                            src: el.src,
+                            width: el.width,
+                            height: el.height,
+                            left: el.left,
+                            top: el.top,
+                            'transform': rotate(el.rotate),
+                        }
+                        tag = 'image'
+                      }
+                      else if (el.type === 'audio') {
+                        tag = 'video'
+                        obj={
+                            src: el.blob,
+                            width: el.width,
+                            height: el.height,
+                            left: el.left,
+                            top: el.top,
+                            loop: false,
+                            autoplay: false,
+                          }
+                      }
+                      else if (el.type === 'video') {
+                        tag = 'video'
+                        obj={
+                            src:(el.blob || el.src),
+                            width: el.width,
+                            height: el.height,
+                            left: el.left,
+                            top: el.top,
+                            loop: false,
+                            autoplay: false,
+                          }
+                      }
+                      else if (el.type === 'shape') {
+                        // if (el.shapType === 'line' || /Connector/.test(el.shapType)) {
+                        //     let start = [0, 0]
+                        //     let end = [0, 0]
+                        
+                        //     if (!el.isFlipV && !el.isFlipH) { // 右下
+                        //       start = [0, 0]
+                        //       end = [el.width, el.height]
+                        //     }
+                        //     else if (el.isFlipV && el.isFlipH) { // 左上
+                        //       start = [el.width, el.height]
+                        //       end = [0, 0]
+                        //     }
+                        //     else if (el.isFlipV && !el.isFlipH) { // 右上
+                        //       start = [0, el.height]
+                        //       end = [el.width, 0]
+                        //     }
+                        //     else { // 左下
+                        //       start = [el.width, 0]
+                        //       end = [0, el.height]
+                        //     }
+                        //     tag = 'hr'
+                        //     obj= {
+                        //         width: el.borderWidth || 1,
+                        //         left: el.left,
+                        //         top: el.top,
+                        //         start,
+                        //         end,
+                        //         style: el.borderType === 'solid' ? 'solid' : 'dashed',
+                        //         color: el.borderColor,
+                        //         points: ['', el.shapType === 'straightConnector1' ? 'arrow' : '']
+                        //       }
+                        // }
+                        // else {
+                        //   const shape = shapeList.find(item => item.pptxShapeType === el.shapType)
+          
+                        //   const vAlignMap: { [key: string]: ShapeTextAlign } = {
+                        //     'mid': 'middle',
+                        //     'down': 'bottom',
+                        //     'up': 'top',
+                        //   }
+                          
+                        //   const element: PPTShapeElement = {
+                        //     type: 'shape',
+                        //     id: nanoid(10),
+                        //     width: el.width,
+                        //     height: el.height,
+                        //     left: el.left,
+                        //     top: el.top,
+                        //     viewBox: [200, 200],
+                        //     path: 'M 0 0 L 200 0 L 200 200 L 0 200 Z',
+                        //     fill: el.fillColor || 'none',
+                        //     fixedRatio: false,
+                        //     rotate: el.rotate,
+                        //     outline: {
+                        //       color: el.borderColor,
+                        //       width: el.borderWidth,
+                        //       style: el.borderType === 'solid' ? 'solid' : 'dashed',
+                        //     },
+                        //     text: {
+                        //       content: el.content,
+                        //       defaultFontName: theme.value.fontName,
+                        //       defaultColor: theme.value.fontColor,
+                        //       align: vAlignMap[el.vAlign] || 'middle',
+                        //     },
+                        //     flipH: el.isFlipH,
+                        //     flipV: el.isFlipV,
+                        //   }
+                        //   if (el.shadow) element.shadow = el.shadow
+              
+                        //   if (shape) {
+                        //     element.path = shape.path
+                        //     element.viewBox = shape.viewBox
+              
+                        //     if (shape.pathFormula) {
+                        //       element.pathFormula = shape.pathFormula
+                        //       element.viewBox = [el.width, el.height]
+              
+                        //       const pathFormula = SHAPE_PATH_FORMULAS[shape.pathFormula]
+                        //       if ('editable' in pathFormula) {
+                        //         element.path = pathFormula.formula(el.width, el.height, pathFormula.defaultValue)
+                        //         element.keypoint = pathFormula.defaultValue
+                        //       }
+                        //       else element.path = pathFormula.formula(el.width, el.height)
+                        //     }
+                        //   }
+                        //   if (el.shapType === 'custom') {
+                        //     element.special = true
+                        //     element.path = el.path!
+                        //     element.viewBox = [originWidth, originHeight]
+                        //   }
+              
+                        //   slide.elements.push(element)
+                        // }
+                      }
+                      else if (el.type === 'table') {
+                        const row = el.data.length
+                        const col = el.data[0].length
+                        tag = 'table'
+                        const obj = {
+                          fontname: theme.value.fontName,
+                          color: theme.value.fontColor,
+                        }
+                        content=''
+                        for (let i = 0; i < row; i++) {
+                          content+='<tr>'
+                          for (let j = 0; j < col; j++) {
+                            const cellData = el.data[i][j]
+                            content+='<td>'+ cellData.text + '</td>'
+                           
+                          }
+                          content+='</tr>'
+                        }
+                        obj={
+                            width: el.width,
+                            height: el.height,
+                            left: el.left,
+                            top: el.top,
+                            border:`2px solid #eeece1`,
+                            cellMinHeight: 36,
+                          }
+                      }
+                    //   else if (el.type === 'chart') {
+                    //     let labels: string[]
+                    //     let legends: string[]
+                    //     let series: number[][]
+            
+                    //     if (el.chartType === 'scatterChart' || el.chartType === 'bubbleChart') {
+                    //       const data = el.data
+                    //       labels = data[0].map(item => item + '')
+                    //       legends = ['系列1']
+                    //       series = [data[1]]
+                    //     }
+                    //     else {
+                    //       const data = el.data as ChartItem[]
+                    //       labels = Object.values(data[0].xlabels)
+                    //       legends = data.map(item => item.key)
+                    //       series = data.map(item => item.values.map(v => v.y))
+                    //     }
+            
+                    //     const options: ChartOptions = {}
+            
+                    //     let chartType: ChartType = 'bar'
+          
+                    //     switch (el.chartType) {
+                    //       case 'barChart':
+                    //       case 'bar3DChart':
+                    //         chartType = 'bar'
+                    //         if (el.barDir === 'bar') options.horizontalBars = true
+                    //         if (el.grouping === 'stacked' || el.grouping === 'percentStacked') options.stackBars = true
+                    //         break
+                    //       case 'lineChart':
+                    //       case 'line3DChart':
+                    //       case 'areaChart':
+                    //       case 'area3DChart':
+                    //       case 'scatterChart':
+                    //       case 'bubbleChart':
+                    //         chartType = 'line'
+                    //         if (el.chartType === 'areaChart' || el.chartType === 'area3DChart') options.showArea = true
+                    //         if (el.chartType === 'scatterChart' || el.chartType === 'bubbleChart') options.showLine = false
+                    //         break
+                    //       case 'pieChart':
+                    //       case 'pie3DChart':
+                    //       case 'doughnutChart':
+                    //         chartType = 'pie'
+                    //         if (el.chartType === 'doughnutChart') options.donut = true
+                    //         break
+                    //       default:
+                    //     }
+            
+                    //     slide.elements.push({
+                    //       type: 'chart',
+                    //       id: nanoid(10),
+                    //       chartType: chartType,
+                    //       width: el.width,
+                    //       height: el.height,
+                    //       left: el.left,
+                    //       top: el.top,
+                    //       rotate: 0,
+                    //       themeColor: [theme.value.themeColor],
+                    //       gridColor: theme.value.fontColor,
+                    //       data: {
+                    //         labels,
+                    //         legends,
+                    //         series,
+                    //       },
+                    //       options,
+                    //     })
+                    //   }
+                    //   else if (el.type === 'group' || el.type === 'diagram') {
+                    //     const elements = el.elements.map(_el => ({
+                    //       ..._el,
+                    //       left: _el.left + originLeft,
+                    //       top: _el.top + originTop,
+                    //     }))
+                    //     parseElements(elements)
+                    //   }
+                }
+            }
+        },
+    },
+}

+ 50 - 0
src/views/noveltySearch/components/exportReport/otherTemplate/otherTemplate.vue

@@ -0,0 +1,50 @@
+<template>
+  <div class="height_100">
+    <div v-if="show">
+        <!-- 展示html -->
+    </div>
+    <div v-else>
+        <!-- 上传文件 -->
+        <el-upload
+            class="upload-demo"
+            drag
+            action="#"
+            :on-change="onChange"
+        >
+            <i class="el-icon-upload"></i>
+            <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
+        </el-upload>
+    </div>
+  </div>
+</template>
+
+<script>
+// import {parse} from 'pptxtojson'
+export default {
+  components: {},
+  props: {},
+  data() {
+    return {
+        show:false
+    };
+  },
+  watch: {},
+  computed: {},
+  created() {},
+  mounted() {},
+  methods: {
+    onChange(file){
+        const reader = new FileReader()
+        var that = this
+        reader.onload = async e=>{
+            const json = await parse(e.target.result)
+            that.json = json
+            that.jsonToHtml(json)
+        }
+        reader.readAsArrayBuffer(file.raw)
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+</style>

+ 1 - 1
src/views/patentMining/components/dialog/addAndEditProject.vue

@@ -195,7 +195,7 @@
       </el-form>
       <span slot="footer" class="dialog-footer">
         <el-button @click="handleClose">取 消</el-button>
-        <el-button type="primary" v-if="!form.id" @click="handleExamine">提交审核</el-button>
+        <el-button type="primary" v-if="!form.id || form.state>3" @click="handleExamine">提交审核</el-button>
         <el-button type="primary" @click="submit">直接完成</el-button>
       </span>
     </el-dialog>

+ 88 - 31
src/views/patentMining/components/fileMessage.vue

@@ -26,20 +26,17 @@
           </el-table-column>
 
 
-          <el-table-column v-for="item in columnList" :key="item.value" :prop="item.value"
-            :render-header="$commonJS.renderHeaderMethods" :label="item.name" sortable align="center">
+          <el-table-column v-for="item in columnList" :key="item.value" :prop="item.value" v-loading="loading"
+            :render-header="$commonJS.renderHeaderMethods" :label="item.name" :sortable="item.ifSort?'custom':false" align="center">
             <template slot-scope="scope">
               <div v-if="['name'].includes(item.value)">
-                <!-- <el-link @click="handleItem(scope.row, item.value)"> -->
                 <span v-html="$commonJS.getColumnData(scope.row, item)"></span>
-                <!-- </el-link> -->
               </div>
               <div v-else-if="['ifFinal'].includes(item.value)"
                 v-html="$commonJS.getColumnData(scope.row, item, null, { data: ifFinal })"></div>
-              <!-- <div v-else-if="['type'].includes(item.value)"
-                v-html="$commonJS.getColumnData(scope.row, item, null, { data: taskType })"></div>
-              <div v-else-if="['status'].includes(item.value)"
-                v-html="$commonJS.getColumnData(scope.row, item, null, { data: taskStatus })"></div> -->
+              <div v-else-if="['statusOrResult'].includes(item.value)">
+                <observerDom v-if="!loading" url="getExamineHistory" :params="{fileGuid:scope.row.fileGuid,ifGetLast:true}" :fun="getData"></observerDom>
+              </div>
               <div v-else v-html="$commonJS.getColumnData(scope.row, item)"></div>
             </template>
           </el-table-column>
@@ -52,6 +49,7 @@
                   预览
                   <el-dropdown-menu slot="dropdown">
                     <el-dropdown-item command="1">下载</el-dropdown-item>
+                    <el-dropdown-item command="examineHistory">审核历史</el-dropdown-item>
                     <el-dropdown-item command="2" divided style="color: red;" v-if="scope.row.fileGuid && scope.row.source">删除</el-dropdown-item>
                   </el-dropdown-menu>
                 </el-dropdown>
@@ -68,6 +66,9 @@
     </el-container>
 
     <uploadFile ref="uploadFile" @isSuccess="isSuccess" :processId="processId"></uploadFile>
+
+    <!-- 审核历史 -->
+    <examineHistoryDialog ref="examineHistoryDialog"></examineHistoryDialog>
   </div>
 </template>
 
@@ -75,11 +76,14 @@
 import { optionsData } from './mixins/index2'
 import uploadFile from './dialog/uploadFile.vue'
 import {File} from '@/utils/model/menu/mixins'
+
+import examineHistoryDialog from '@/views/report/components/reportFile/examineHistoryDialog.vue'
 export default {
   props: ['id', 'processId'],
   mixins: [optionsData,File],
   components: {
-    uploadFile
+    uploadFile,
+    examineHistoryDialog
   },
   data() {
     return {
@@ -87,41 +91,75 @@ export default {
         false: '否',
         true: '是',
       },
+      loading:false,
       // 数据源
       tableData: [],
       // table栏位信息
       columnList: [
         {
-          name: "文件流程",
-          type: "String",
-          value: "path",
+            "name": "文件名称",
+            "type": "String",
+            "value": "name",
+            "field": "name",
+            "ifShow": true,
+            "ifHidden": false,
+            "ifSort": true
         },
         {
-          name: "文件上传人",
-          type: "Integer",
-          value: "createName",
+            "name": "状态/结果",
+            "type": "String",
+            "value": "statusOrResult",
+            "field": "statusOrResult",
+            "ifSort": false
         },
         {
-          name: "文件上传时间",
-          type: "DateTime",
-          value: "createTime",
+            "name": "流程节点",
+            "type": "String",
+            "value": "processName",
+            "field": "processName",
+            "ifShow": true,
+            "ifHidden": true,
+            "defaultHidden": true,
+            "ifSort": true
         },
         {
-          name: "文件类型",
-          type: "String",
-          value: "type",
+            "name": "最终文件",
+            "type": "Boolean",
+            "value": "ifFinal",
+            "field": "ifFinal",
+            "ifShow": true,
+            "ifHidden": true,
+            "defaultHidden": true,
+            "ifSort": true
         },
         {
-          name: "是否最终文件",
-          type: "DateTime",
-          value: "endFile",
+            "name": "描述",
+            "type": "String",
+            "value": "description",
+            "field": "description",
+            "ifShow": true,
+            "ifHidden": false,
+            "ifSort": true
         },
         {
-          name: "说明",
-          type: "DateTime",
-          value: "description",
+            "name": "创建人",
+            "type": "String",
+            "value": "createName",
+            "field": "createName",
+            "ifShow": true,
+            "ifHidden": false,
+            "ifSort": true
         },
-      ],
+        {
+            "name": "创建时间",
+            "type": "DateTime",
+            "value": "createTime",
+            "field": "createTime",
+            "ifShow": true,
+            "ifHidden": false,
+            "ifSort": true
+        }
+    ],
       // 分页信息
       queryParams: {
         current: 1,
@@ -150,13 +188,28 @@ export default {
   },
   async mounted() {
     // 获取table栏位
-    this.columnList = await this.$commonJS.getCustomField('patentDigProjectFiles')
+    // this.columnList = await this.$commonJS.getCustomField('patentDigProjectFiles')
     // 获取栏位
     // await this.getColumn()
     // 获取数据
     await this.getList()
   },
   methods: {
+    getData(data){
+      if(!data || data.length == 0){
+        return ''
+      }
+      var message = data[0]
+      if(message['status'] == 3){
+        return message.handleResult
+      }
+      if(message['status'] == 2){
+        return '审核中'
+      }
+      if(message['status'] == 5){
+        return '取消审核'
+      }
+    },
     // 新增/更新文件列表成功
     isSuccess(val) {
       this.getList()
@@ -215,15 +268,17 @@ export default {
         searchQuery: this.$commonJS.objectToString(searchOption || {}),//检索条件
         orderDTOList: this.sort,//排序信息
       }
-
+      this.loading = true
       this.$api.queryPatentDigProjectFiles(searchOption2).then(res => {
         if (res.code == 200) {
           this.tableData = res.data.data
           this.queryParams.total = this.tableData.length
+          this.loading = false
         }
       }).catch(error => {
         this.tableData = []
         this.queryParams.total = 0
+        this.loading = false
       })
     },
     // 搜索
@@ -278,7 +333,9 @@ export default {
         case '2'://删除
           this.handleDeletes(row)
           break;
-      
+        case 'examineHistory'://审核历史
+          this.$refs.examineHistoryDialog.open(row.fileGuid)
+          break;
         default:
           break;
       }

+ 1 - 1
src/views/patentMining/components/handleExamine/index.vue

@@ -1,6 +1,6 @@
 <template>
   <div>
-    <handleExamine :row=row style="height: 100%;"></handleExamine>
+    <handleExamine :row='row' style="height: 100%;"></handleExamine>
   </div>
 </template>
 

+ 4 - 0
src/views/patentMining/components/mixins/index.js

@@ -40,6 +40,10 @@ export default {
         this.$message.warning('项目审核中')
         return
       }
+      if(row.state >3){
+        this.$message.warning('该项目'+row.stateName)
+        return
+      }
       // 跳转详情页面
       this.$router.push({
         path: '/details',

+ 1 - 1
src/views/patentMining/components/view/card.vue

@@ -6,7 +6,7 @@
             <div slot="head">
               <div style="font-size:18px">
                 <!-- <span># {{ (itemIndex + 1) + ((queryParams.current - 1) * queryParams.size)}}</span> -->
-                <span>{{ item.name }}</span>
+                <span class="cursor_pointer" @click="handleItem(item)">{{ item.name }}</span>
               </div>
             </div>
             <div>

+ 28 - 9
src/views/report/components/dialog/addAndEditReport.vue

@@ -1175,7 +1175,7 @@ export default {
           this.$set(this.form,'signPatentNo',this.form.signPatentNo.trim())
           let formData = this.form
           if (!this.form.id) {//新增报告
-            this.$confirm('是否需要进行审核?', '提示', {
+            this.$confirm('是否需要提交审核?', '提示', {
               confirmButtonText: '是',
               cancelButtonText: '否',
               closeOnClickModal: false,
@@ -1191,18 +1191,37 @@ export default {
             });
 
           } else {//编辑报告
-            this.$api.updateReportProject(formData).then(response => {
-              if (response.code == 200) {
-                this.files = []
-                this.$message.success('报告更新成功')
-                this.$emit('getList', '更新成功')
-                this.handleClose()
-              }
-            })
+            if(this.form.status>3){
+              this.$confirm('是否需要提交审核?', '提示', {
+                confirmButtonText: '是',
+                cancelButtonText: '否',
+                closeOnClickModal: false,
+                distinguishCancelAndClose: true,
+              }).then(() => {//审核打开审核弹窗
+                this.showTask = true
+                this.$set(this.taskForm, 'name', this.form.name + '审核')
+              }).catch(action => {//不审核直接更新报告
+                // 调用更新报告公用,接口
+                this.updateReportProject(formData)
+              });
+              return
+            }
+            this.updateReportProject(formData)
           }
         }
       })
     },
+    //更新报告信息
+    updateReportProject(formData){
+      this.$api.updateReportProject(formData).then(response => {
+        if (response.code == 200) {
+          this.files = []
+          this.$message.success('报告更新成功')
+          this.$emit('getList', '更新成功')
+          this.handleClose()
+        }
+      })
+    },
     //关闭弹窗
     handleClose(val) {
       if (this.form.reportType == 7 && val) {

+ 27 - 3
src/views/report/components/dialog/exportReport.vue

@@ -1,7 +1,7 @@
 <template>
   <div>
     <el-dialog width="1000px" title="选择模板" :visible.sync="reportTemplate" :before-close="close" >
-        <div  v-loading="loadingTemplate" element-loading-text="报告导出中..." element-loading-spinner="el-icon-loading">
+        <div  v-loading="loadingTemplate" element-loading-text="报告生成中..." element-loading-spinner="el-icon-loading">
             <div class="height_100">
                 <el-container>
                     <el-main>
@@ -137,8 +137,32 @@ export default {
         this.$api.exportReport(params).then(response=>{
             if(response.code == 200){
                 this.loadingTemplate = false
-                downLoad2(response.data.data)
-                this.$message.success('导出成功')
+                var obj = this.tableData.find(item=>{return item.id == this.templateId})
+                var referencesName = ''
+                if(obj){
+                    referencesName = this.dictMessage[obj.reportType]
+                }
+                var form = {
+                    fileGuid:response.data.data,
+                    referencesName:referencesName + '报告',
+                    projectId:this.projectId
+                }
+                this.$api.addReferences(form).then(res => {
+                    if (res.code == 200) {
+                        //跳转到编辑界面
+                        let router = this.$router.resolve({
+                            path: '/onlyOffice',
+                            query: {
+                                projectId:this.projectId,
+                                guid:response.data.data,
+                                title:referencesName + '报告'
+                            }
+                        })
+                        window.open(router.href, '_blank')
+                    }
+                })
+                // downLoad2(response.data.data)
+                // this.$message.success('导出成功')
                 this.close()
             }
         }).catch(error=>{

+ 4 - 0
src/views/report/components/mixins/index.js

@@ -28,6 +28,10 @@ export default {
         this.$message.warning('项目审核中')
         return
       }
+      if(row.status >3){
+        this.$message.warning('该项目'+row.statusName)
+        return
+      }
       const router = this.$router.resolve({
         path: '/reportDetails',
         query: {

+ 46 - 0
src/views/report/components/reportFile/examineHistoryDialog.vue

@@ -0,0 +1,46 @@
+<template>
+  <el-dialog
+        title="审核历史"
+        :visible.sync="visible"
+        width="80%"
+        :before-close="handleClose"
+        :append-to-body="true" 
+        :close-on-click-modal="false">
+        <div v-if="visible">
+            <examineHistory :fileGuid="fileGuid" :taskId="taskId"></examineHistory>
+        </div>
+    </el-dialog>
+</template>
+
+<script>
+import examineHistory from '@/views/task/components/examine/components/examineHistory.vue';
+export default {
+  components: {
+    examineHistory
+  },
+  props: {},
+  data() {
+    return {
+        visible:false,
+        fileGuid:null,
+        taskId:null,
+    };
+  },
+  watch: {},
+  computed: {},
+  created() {},
+  mounted() {},
+  methods: {
+    open(fileGuid,taskId){
+        this.fileGuid = fileGuid || null
+        this.taskId = taskId || null
+        this.visible = true
+    },
+    handleClose(){
+        this.visible = false
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+</style>

+ 81 - 2
src/views/report/components/reportFile/reportFileTable.vue

@@ -36,6 +36,9 @@
                   <span v-html="$commonJS.getColumnData(scope.row, item)"></span>
                 </el-tooltip>
               </div>
+              <div v-else-if="['statusOrResult'].includes(item.value)">
+                <observerDom v-if="!loading" url="getExamineHistory" :params="{fileGuid:scope.row.fileGuid,ifGetLast:true}" :fun="getData"></observerDom>
+              </div>
               <div v-else v-html="$commonJS.getColumnData(scope.row, item)"></div>
             </template>
           </el-table-column>
@@ -44,11 +47,13 @@
             <template slot-scope="scope">
               <el-dropdown split-button type="primary" size="small" @command="handleCommand($event, scope.row)">
                 <span @click="handleCommand('e', scope.row)">{{scope.row.ifHaveFinalFile !== false?'编辑':'编辑报告内容'}}</span>
-
                 <el-dropdown-menu slot="dropdown" class="text-align_center">
                   <template v-if="scope.row.ifHaveFinalFile !== false">
+                    <el-dropdown-item command="onlineEdit">编辑文档内容</el-dropdown-item>
                     <el-dropdown-item command="0">下载</el-dropdown-item>
                     <el-dropdown-item command="1">预览</el-dropdown-item>
+                    <el-dropdown-item command="examineSubmit">提交审核</el-dropdown-item>
+                    <el-dropdown-item command="examineHistory">审核历史</el-dropdown-item>
                   </template>
                   <template v-else>
                     <el-dropdown-item command="generateReport">生成报告</el-dropdown-item>
@@ -89,12 +94,24 @@
         <el-button type="primary" @click="submit">确 定</el-button>
       </div>
     </el-dialog>
+    <!-- 审核历史 -->
+    <examineHistoryDialog ref="examineHistoryDialog"></examineHistoryDialog>
+
+    <!-- 提交审核 -->
+    <examineSubmitDialog ref="examineSubmitDialog"></examineSubmitDialog>
   </div>
 </template>
 
 <script>
 import { downLoad2 } from "@/utils"
+import examineHistoryDialog from './examineHistoryDialog.vue'
+
+import examineSubmitDialog from '@/views/components/onlyOffice/addNewFile.vue'
 export default {
+  components:{
+    examineHistoryDialog,
+    examineSubmitDialog
+  },
   props: ['projectId','queryApi','deleteApi'],
   data() {
     return {
@@ -119,6 +136,12 @@ export default {
           value: "type",
           noSort:true
         },
+        {
+          name: "状态/结果",
+          type: "String",
+          value: "statusOrResult",
+          noSort:true
+        },
         // {
         //   name: "所属项目",
         //   type: "String",
@@ -178,6 +201,21 @@ export default {
     this.getList()
   },
   methods: {
+    getData(data){
+      if(!data || data.length == 0){
+        return ''
+      }
+      var message = data[0]
+      if(message['status'] == 3){
+        return message.handleResult
+      }
+      if(message['status'] == 2){
+        return '审核中'
+      }
+      if(message['status'] == 5){
+        return '取消审核'
+      }
+    },
     init(){
       this.queryParams.current = 1
       this.getList()
@@ -351,11 +389,52 @@ export default {
         case 'generateReport'://生成报告
           this.generateReport(row)
           break;
-
+        case 'onlineEdit'://在线编辑文档
+          this.onlineEdit(row)
+          break;
+        case 'examineHistory'://审核历史
+          this.$refs.examineHistoryDialog.open(row.fileGuid)
+          break;
+        case 'examineSubmit'://提交审核
+          this.examineSubmit(row)
+          break;
         default:
           break;
       }
     },
+    examineSubmit(row){
+        var title = row.referencesName
+        var taskName = ''
+        if(title.endsWith('.'+row.type)){
+            title = title.slice(0, -(row.type.length+1))
+        }
+        taskName = title + '-' + row.createName + '-' + '文件审核'
+        title = title + '-' + row.createName + '.' + row.type
+        var form = {
+            referencesName:title,
+            guid:row.fileGuid,
+            projectId:this.projectId,
+            fileType:row.type
+        }
+        var taskForm = {
+            name:taskName
+        }
+        this.$refs.examineSubmitDialog.open(form,taskForm)
+    },
+    //在线编辑文档
+    onlineEdit(row){
+      let router = this.$router.resolve({
+        path: '/onlyOffice',
+        query: {
+            projectId:this.projectId,
+            guid:row.fileGuid,
+            fileType:row.type,
+            title:row.referencesName,
+            createTime:row.createTime
+        }
+      })
+      window.open(router.href, '_blank')
+    },
     //生成报告
     generateReport(row){
       var message = this.$message({

+ 1 - 1
src/views/report/components/view/card.vue

@@ -18,7 +18,7 @@
                 <el-dropdown-menu slot="dropdown" class="text-align_center">
                   <el-dropdown-item command="0">分享</el-dropdown-item>
                   <el-dropdown-item v-if="item.reportType == 7 && $permission.FunPermissions('xiaoshi/handlePerson')" command="matchCase">实际处理人</el-dropdown-item>
-                  <el-dropdown-item command="1" v-if="[2,3].includes(item.status) && item.reportType != 7">导出报告</el-dropdown-item>
+                  <el-dropdown-item command="1" v-if="[2,3].includes(item.status) && item.reportType != 7">生成报告</el-dropdown-item>
                   <el-dropdown-item command="2" v-if="[2,3].includes(item.status)">报告文档</el-dropdown-item>
                   <el-dropdown-item command="16" v-if="[1,2].includes(item.reportType)">检索记录</el-dropdown-item>
                   <el-dropdown-item command="3" v-if="[2].includes(item.status)&&[0,1,2,3].includes(item.reportType)">自定义字段</el-dropdown-item>

+ 1 - 1
src/views/report/components/view/table.vue

@@ -45,7 +45,7 @@
                 <el-dropdown-menu slot="dropdown" class="text-align_center">
                   <el-dropdown-item command="0">分享</el-dropdown-item>
                   <el-dropdown-item v-if="scope.row.reportType == 7 && $permission.FunPermissions('xiaoshi/handlePerson')" command="matchCase">实际处理人</el-dropdown-item>
-                  <el-dropdown-item command="1" v-if="[2,3].includes(scope.row.status) && scope.row.reportType != 7">导出报告</el-dropdown-item>
+                  <el-dropdown-item command="1" v-if="[2,3].includes(scope.row.status) && scope.row.reportType != 7">生成报告</el-dropdown-item>
                   <el-dropdown-item command="2" v-if="[2,3].includes(scope.row.status)">报告文档</el-dropdown-item>
                   <el-dropdown-item command="16" v-if="[1,2].includes(scope.row.reportType)">检索记录</el-dropdown-item>
                   <el-dropdown-item command="3" v-if="[2].includes(scope.row.status)&&[0,1,2,3].includes(scope.row.reportType)">自定义字段</el-dropdown-item>

+ 391 - 0
src/views/task/components/examine/components/examine.vue

@@ -0,0 +1,391 @@
+<template>
+  <div class="height_100">
+    <el-container>
+        <el-aside width="140px" v-show="!showFile">
+            <div class="title">审核任务处理</div>
+            <div v-for="(item,index) in menu" :key="index" :class="['menuItem',clickDom==item.id?'menuItem_active':'']" @click="domToTop(item)">
+                <svg-icon :iconClass="item.icon" :iconName="item.icon"></svg-icon>
+                <span>{{ item.label}}</span>
+            </div>
+        </el-aside>
+        <el-container>
+            <el-main>
+                <div v-if="showFile" class="height_100">
+                    <div style="margin-bottom:10px"> 
+                        <el-button type="primary" size="mini" @click="showFile = false">返回</el-button>
+                    </div>
+                    <openFile ref="openFile" :file="file" style="height: calc(100% - 35px);" @submitResult="submitResult"></openFile>
+                </div>
+                <template >
+                    <div v-show="!showFile" v-for="item in menu" :key="item.value" :id="item.id" class="message">
+                        <span style="font-weight:bold;">{{ item.label }}</span>
+                        <div class="components">
+                            <component :ref="item.id" :is='item.id' :taskId="taskId" :taskMessage="taskMessage" :taskType="taskType" @openFile="openFile"></component>
+                        </div>
+                        
+                    </div>
+                </template>
+                
+            </el-main>
+            <el-footer  style="height:auto !important;margin-top:10px" v-show="userinfo.id == taskMessage.handler && taskMessage.status == 2">
+                <div style="padding:0 0 20px 0">
+                    <div style="display:flex;justify-content:flex-end;height:0px;">
+                        <el-button type="primary" size="mini" :loading="btnLoading" @click="submit" style="height: 28px;z-index:998">提交</el-button>
+                    </div>
+                    <el-form :model="form" label-position="right" label-width="130px">
+                        <el-form-item prop="result" label="审核结果:">
+                            <el-button :type="form.result == '通过'?'success':''" size="small" @click="$set(form,'result','通过')">通过<i class="el-icon-check"></i></el-button>
+                            <el-button :type="form.result == '不通过'?'danger':''" size="small" @click="$set(form,'result','不通过')">不通过<i class="el-icon-close"></i></el-button>
+                        </el-form-item>
+                        <el-form-item prop="description" label="审核说明:">
+                            <el-input type="textarea" v-model="form.description" placeholder="请输入审核说明"></el-input>
+                        </el-form-item>
+                        <!-- <div style="display:flex;justify-content:flex-end;margin-bottom:15px">
+                            <el-button type="primary" size="mini" @click="chooseNext">选择下一个审核人</el-button>
+                        </div> -->
+                        <template>
+                            <div style="width:100%" class="examine">
+                                <el-row :gutter="10" type="flex" align="middle">
+                                        <el-col :span="4"><div>下一个审核人:</div></el-col>
+                                        <el-col >
+                                            <div>
+                                                <el-select v-model="form.handler" placeholder="请选择负责人" style="width: 100%;" filterable remote
+                                                :remote-method="querySearchPersonnel" v-SelectLazyLoading="personnelLoad"
+                                                :loading="personnelList.loading">
+                                                    <el-option v-for="item in personnelList.data" :key="item.id" :label="item.name" :value="item.id"></el-option>
+                                                </el-select>
+                                                <!-- <el-autocomplete v-model="form.handlerName" value-key="name" v-SelectLazyLoading="personnelLoad"
+                                                    :fetch-suggestions="querySearchPersonnel" placeholder="请输入审核人" :trigger-on-focus="false"
+                                                    @select="handleSelectPersonnel" @blur="handleBlur(form.handlerName)" style="width: 100%;"></el-autocomplete> -->
+                                            </div>
+                                        </el-col>
+                                        <el-col :span="3"><div>截止日期:</div></el-col>
+                                        <el-col>
+                                            <div>
+                                                <el-date-picker style="width:100%" v-model="form.deadLineTime" value-format="yyyy-MM-dd HH:mm:ss" type="datetime" placeholder="选择日期"></el-date-picker>
+                                            </div>
+                                        </el-col>
+                                </el-row>
+                            </div>
+                        </template>
+                    </el-form>
+                </div>
+            </el-footer>
+        </el-container>
+    </el-container>
+  </div>
+</template>
+
+<script>
+import examineHistory from './examineHistory.vue';
+import examineMessage from './examineMessage.vue';
+import openFile from './openFile.vue';
+import projectMessage from './projectMessage.vue';
+import taskMessage from './taskMessage.vue';
+const defaultMenu = [
+    {
+        icon:'任务信息',
+        label:'任务信息',
+        value:1,
+        id:'taskMessage',
+        taskType:[1,5,7],
+    },
+    {
+        icon:'所属项目',
+        label:'所属任务信息',
+        value:2,
+        id:'projectMessage',
+        taskType:[5],
+    },
+    {
+        icon:'所属项目',
+        label:'所属项目信息',
+        value:2,
+        id:'projectMessage',
+        taskType:[7],
+    },
+    {
+        icon:'审核信息',
+        label:'待审核信息',
+        value:3,
+        id:'examineMessage',
+        taskType:[1,5,7],
+    },
+    {
+        icon:'审核历史',
+        label:'审核历史',
+        value:4,
+        id:'examineHistory',
+        taskType:[1,5,7],
+    },
+]
+export default {
+  components: {
+    taskMessage,
+    projectMessage,
+    examineMessage,
+    examineHistory,
+    openFile
+  },
+  props: {
+    taskType:{},
+    taskId:{},
+  },
+  mixins:[],
+  data() {
+    return {
+        file:null,
+        showFile:false,
+        menu:[],
+        taskMessage:{},
+        clickDom:null,
+        form:{},
+        btnLoading:false,
+        //人员列表懒加载
+        personnelList: {
+          queryParams: {
+            current: 1,
+            size: 10
+          },
+          loading: false,
+          name: '',
+          data: [],
+        },
+    };
+  },
+  watch: {},
+  computed: {
+    userinfo(){
+        return this.$s.getObj('userinfo') 
+    }
+  },
+  created() {},
+  mounted() {
+    this.init()
+  },
+  methods: {
+    //打开文件
+    openFile(file,model){
+        if(!model){
+            model = (this.userinfo.id == this.taskMessage.handler && this.taskMessage.status == 2)?'edit':'view'
+        }
+        this.file = {
+            projectId:this.taskMessage.projectId,
+            guid:file.fileGuid,
+            fileType:file.fileType,
+            title:file.originalName,
+            createTime:file.createTime,
+            model:model
+        }
+        this.showFile = true
+    },
+    async init(){
+        if(!this.taskType || !this.taskId){
+            return
+        }
+        this.getMenu()
+        await this.getTaskMessage()
+    },
+    //获取左侧菜单
+    getMenu(){
+        this.menu = defaultMenu.filter(item=>{
+            return item.taskType.indexOf(Number(this.taskType)) != -1
+        })
+    },
+    //获取任务信息
+    getTaskMessage(){
+        let params = {
+            current:1,
+            size:10,
+            searchQuery: `id=${this.taskId}`,//检索条件
+            orderDTOList:[],//排序信息
+        }
+        this.$api.queryProjectTask(params).then(response => {
+            if (response.code == 200) {
+                if(response.data.data && response.data.data.length>0){
+                    this.taskMessage =  response.data.data[0]
+                    if(this.userinfo.id == this.taskMessage.handler && this.taskMessage.status == 2){
+                        this.querySearchPersonnel()
+                    }
+                }
+            }
+        }).catch(error => {
+        })
+    },
+    //指定节点到最上方
+    domToTop(item){
+        var dom = item.id
+        this.clickDom = dom
+        let target = document.querySelector('#' + dom)
+        target.scrollIntoView({
+            block: 'start',
+            inline: 'nearest',
+            behavior: 'smooth'
+        })
+    },
+    //提交审核结果
+    submit(){
+        // if(!this.file){
+        //     this.submitResult()
+        //     return
+        // }
+        if(this.$refs.openFile){
+            this.$refs.openFile.requestSave('submitResult',1)
+        }else{
+            this.submitResult()
+        }
+        
+    },
+    submitResult(){
+        var params = {
+            taskId:this.taskId,
+            projectId:this.taskMessage.projectId,
+            ...this.form,
+            handlerType:0,
+            // files:this.$refs.examineMessage[0].getTableData()
+        }
+        this.btnLoading = true
+        // 提交审核结果
+        this.$api.submitResult(params).then(response=>{
+            if(response.code == 200){
+                this.$message.success('审核结果提交成功')
+                this.btnLoading = false
+                this.getTaskMessage()
+                this.$refs.examineHistory[0].getExamineHistory()
+            }
+        }).catch(error=>{
+            this.btnLoading = false
+        })
+    },
+     /**
+    * 人员
+    */
+    // 懒加载人员方法
+    personnelLoad() {
+      if (this.personnelList.queryParams.current * this.personnelList.queryParams.size >= this.personnelList.queryParams.total) {
+        return false
+      }
+      this.personnelList.queryParams.current++
+      this.questionPersonnel()
+    },
+    // 查询人员
+    async questionPersonnel() {
+      let params = {
+        ...this.personnelList.queryParams,
+        name:this.personnelList.name
+      }
+      await this.$api.getPermissionPersonnel(params).then(res => {
+        if (res.code == 200) {
+          this.personnelList.data.push(...res.data)
+          this.personnelList.queryParams.total = res.pageColumn.total
+        //   this.personnelList.cb(this.personnelList.data);
+        }
+      })
+    },
+    //获取下拉建议人员数据
+    async querySearchPersonnel(queryString, cb) {
+      this.personnelList.queryParams.current = 1
+      this.personnelList.name = queryString
+      this.personnelList.data = []
+      this.personnelList.cb = cb
+      await this.questionPersonnel()
+    },
+    // 人员输入框失焦
+    handleBlur(val) {
+      if (this.form.handlerName && this.form.handlerName.includes('@')) {
+        this.form.handler = val
+      }
+    },
+    // 人员输入框选择
+    handleSelectPersonnel(val) {
+      this.form.handler=val.id
+    },
+  },
+};
+</script>
+<style lang="scss">
+.message{
+    .el-row{
+        width: calc(100% - 20px);
+        margin: 15px 0;
+        display: flex;
+        align-items: stretch;
+    }
+    .el-col{
+        line-height: 30px;
+        border: 1px solid rgb(216, 216, 216);
+    }
+    .el-col:nth-child(odd){
+        max-width:150px;
+        min-width:150px;
+        width:150px;
+        background-color: var(--color1);
+        color: var(--color);
+        text-align: right;
+        border-radius: 5px 0 0 5px;
+        border-right: 0;
+        margin-left:20px;
+        display: flex;
+        justify-content: flex-end;
+        align-items: center;
+    }
+    .el-col:nth-child(even){
+        text-align: left;
+        border-radius: 0 5px 5px 0;
+        border-left: 0;
+        display: flex;
+        align-items: center;
+    }
+} 
+.examine{
+    font-size: 14px;
+    font-weight: bold;
+    .el-col:nth-child(odd){
+        text-align: right;
+    }
+}
+</style>
+<style lang="scss" scoped>
+.title{
+    width:100%;
+    line-height: 50px;
+    text-align: center;
+    background-color: var(--bg);
+    color: var(--color);
+    font-weight: bold;
+}
+.menuItem{
+    width:calc(100% - 16px);
+    line-height: 35px;
+    text-align: left;
+    padding: 8px;
+    cursor: pointer;
+    font-weight: bold;
+    font-size: 14px;
+    &:hover{
+        color: var(--color1);
+    }
+    &:active{
+        color: var(--bg);
+    }
+    span{
+        margin-left:10px;
+    }
+}
+.menuItem_active{
+    color: var(--bg);
+}
+.message{
+    min-height: 100px;
+    .components{
+        margin: 10px 0;
+    }
+}
+#taskMessage,#projectMessage{
+    .components{
+        border: 1px solid var(--color1);
+        border-radius:8px ;
+        padding: 5px 0;
+    }
+}
+</style>

+ 135 - 0
src/views/task/components/examine/components/examineHistory.vue

@@ -0,0 +1,135 @@
+<template>
+  <div>
+    <el-table :data="tableData" border style="width: 100%" header-row-class-name="custom-table-header">
+        <el-table-column label="序号" width="60" type="index" align="center">
+            <template slot-scope="scope">
+                <span>{{ (scope.$index + 1)}}</span>
+            </template>
+        </el-table-column>
+        <el-table-column label="审核人" width="120" align="center">
+            <template slot-scope="scope">
+                <div>
+                    {{scope.row.createName}}
+                </div>
+            </template>
+        </el-table-column>
+        <el-table-column label="审核状态" width="120" align="center">
+            <template slot-scope="scope">
+                <div>
+                    {{taskStatusList[scope.row.status]}}
+                </div>
+            </template>
+        </el-table-column>
+        <el-table-column label="审核时间" width="180" align="center">
+            <template slot-scope="scope">
+                <div >
+                    {{scope.row.createTime}}
+                </div>
+            </template>
+        </el-table-column>
+        <el-table-column label="审核结果" width="150" align="center">
+            <template slot-scope="scope">
+                <div >
+                    {{scope.row.handleResult}}
+                </div>
+            </template>
+        </el-table-column>
+        <el-table-column label="审核说明" align="center">
+            <template slot-scope="scope">
+                <div >
+                    {{scope.row.description}}
+                </div>
+            </template>
+        </el-table-column>
+        <el-table-column label="相关附件" width="400" align="center">
+            <template slot-scope="scope">
+                <div >
+                    <div v-for="(file,ind) in scope.row.files" :key="ind" class="cursor_pointer file">
+                        {{ file.originalName }} 
+                        <span class="btns"> 
+                          <el-button type="text" @click="review(file)">预览</el-button>
+                          <el-button type="text" @click="downLoad(file)">下载</el-button>
+                        </span>
+                      </div>
+                </div>
+            </template>
+        </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script>
+import mixins from './mixins/index'
+export default {
+  components: {},
+  mixins:[mixins],
+  props: {
+    fileGuid:{
+        type:String,
+        default:''
+    },
+    taskId:{
+        type:[String,Number],
+        default:''
+    }
+  },
+  data() {
+    return {
+        tableData:[]
+    };
+  },
+  watch: {
+    fileGuid(){
+        this.getExamineHistory()
+    },
+    taskId(){
+        this.getExamineHistory()
+    }
+  },
+  computed: {},
+  created() {},
+  mounted() {
+    this.getExamineHistory()
+  },
+  methods: {
+    //获取审核历史
+    getExamineHistory(){
+        if(!this.taskId && !this.fileGuid){
+            return
+        }
+        var params = {
+            taskId:this.taskId,
+            fileGuid:this.fileGuid
+        }
+        this.$api.getExamineHistory(params).then(response=>{
+            if(response.code == 200){
+                this.tableData = response.data
+            }
+        })
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+.cursor_pointer{
+    .btns{
+        opacity:0;
+        pointer-events: none;
+    }
+    &:hover{
+        color:#66b1ff;
+        .btns{
+            opacity:1;
+            pointer-events: all;
+        }
+    }
+  
+}
+.file{
+    line-height: 35px;
+    width: 100%;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+}
+</style>

+ 122 - 0
src/views/task/components/examine/components/examineMessage.vue

@@ -0,0 +1,122 @@
+<template>
+  <div>
+    <!-- 项目信息 -->
+    <template v-if="taskType == 1">
+        <div>
+            <projectMessage :allMessage="true" :taskId="taskId" :taskMessage="taskMessage" :taskType="taskType"></projectMessage>
+        </div>
+    </template>
+    <!-- 文件信息 -->
+    <template v-else>
+        <div>
+            <el-table :data="tableData" border style="width: 100%" header-row-class-name="custom-table-header">
+                <el-table-column label="序号" width="60" type="index" align="center">
+                    <template slot-scope="scope">
+                        <span>{{ (scope.$index + 1)}}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column label="文件名称" align="center">
+                    <template slot-scope="scope">
+                        <div>
+                            <span class="cursor_pointer color" @click="openFile(scope.row)">{{scope.row.originalName}}</span>
+                         </div>
+                    </template>
+                </el-table-column>
+                <el-table-column label="文件类型" width="150" align="center">
+                    <template slot-scope="scope">
+                        <div>
+                            {{scope.row.fileType}}
+                         </div>
+                    </template>
+                </el-table-column>
+                <el-table-column label="创建人" width="180" align="center">
+                    <template slot-scope="scope">
+                        <div>
+                            {{scope.row.createName}}
+                         </div>
+                    </template>
+                </el-table-column>
+                <el-table-column label="创建时间" width="250" align="center">
+                    <template slot-scope="scope">
+                        <div>
+                            {{scope.row.createTime}}
+                         </div>
+                    </template>
+                </el-table-column>
+                <el-table-column label="操作" width="200" align="center">
+                    <template slot-scope="scope">
+                        <div>
+                            <el-button type="text" @click="downLoad({guid:scope.row.fileGuid,originalName:scope.row.originalName})">下载</el-button>
+                         </div>
+                    </template>
+                </el-table-column>
+            </el-table>
+        </div>
+    </template>
+  </div>
+</template>
+
+<script>
+import mixins from './mixins/index'
+import projectMessage from './projectMessage.vue';
+export default {
+  components: {
+    projectMessage
+  },
+  mixins:[mixins],
+  props: {},
+  data() {
+    return {
+        tableData:[]
+    };
+  },
+  watch: {
+
+  },
+  computed: {},
+  created() {},
+  mounted() {
+    this.init()
+  },
+  methods: {
+    getTableData(){
+        return this.tableData
+    },
+    async init(){
+        if(this.taskType == 1){
+            return
+        }
+        this.getExamineMessage()
+    },
+     //获取待审核信息(任务关联的文件信息)
+     getExamineMessage(){
+        if(!this.taskId){
+            return
+        }
+        var params = {
+            taskId:this.taskId
+        }
+        this.$api.getExamineMessage(params).then(response=>{
+            if(response.code == 200){
+                this.tableData = response.data
+            }
+        })
+    },
+    //打开文件
+    openFile(item){
+        this.$emit('openFile',item)
+    },
+
+  },
+};
+</script>
+<style lang="scss" scoped>
+.cursor_pointer{
+    &:hover{
+    color:#66b1ff
+  }
+}
+.color{
+    color:#409EFF;
+}
+</style>

+ 64 - 0
src/views/task/components/examine/components/mixins/index.js

@@ -0,0 +1,64 @@
+import { downLoad2 } from "@/utils"
+
+export default{
+    props:{
+        taskMessage:{
+            type:Object,
+            default:()=>{
+                return {}
+            }
+        },
+        taskType:{
+
+        },
+        taskId:{}
+    },
+    data() {
+        return {
+             // 任务类型
+            taskTypeList: {
+                0: '标引任务',
+                1: '项目开卷审核任务',
+                2: '检索条件任务',
+                3: '对比任务',
+                4: '协同任务',
+                5: '任务审核任务',
+                6: '文件分配任务',
+                7: '文件审核任务',
+            },
+            // 任务状态
+            taskStatusList: {
+                1: '审核中',
+                2: '处理中',
+                3: '已完成',
+                // 4: '缺少资料',
+                4: '已完成',
+                5: '取消',
+                6: '确认结果中',
+            },
+        }
+    },
+    methods: {
+        getFileProperty(item,fieldIndex){
+            return (item-1)*this.col + fieldIndex - 1
+        },
+        // 预览
+        review(file){
+            // var data = {
+            //     originalName:file.originalName,
+            //     fileType:file.type,
+            //     fileGuid:file.guid
+            // }
+            // this.$emit('openFile',data,'view')
+            // return
+            var data = {
+                fileName:file.originalName
+            }
+            this.$commonJS.previewFile(data,file.guid,file.type)
+        },
+        //下载
+        downLoad(file){
+            downLoad2(file.guid,file.originalName)
+        }
+    },
+}

+ 136 - 0
src/views/task/components/examine/components/openFile.vue

@@ -0,0 +1,136 @@
+<template>
+    <div class='qualityManual-container'>
+        <div v-if='show' class='qualityManual-container-office'>
+            <vab-only-office :option='option'/>
+        </div>
+    </div>
+</template>
+<script>
+import vabOnlyOffice from '@/components/VabOnlyOffice/index.vue'
+import { formatDate } from "@/utils";
+import onlyOfficeMixins from '@/views/components/onlyOffice/index'
+export default {
+    components: {
+        vabOnlyOffice,
+    },
+    mixins:[onlyOfficeMixins],
+    props:{
+        file:{
+            type:Object,
+            default:()=>{
+                return {}
+            }
+        }
+    },
+    data() {
+        return {
+            //参考vabOnlyOffice组件参数配置
+            option: {
+                url: '',
+                isEdit: true,
+                fileType: '',
+                title: '',
+                lang: 'zh-CN',
+                isPrint: true,
+                user: {
+                    id: this.$s.getObj('userinfo').id,
+                    name: this.$s.getObj('userinfo').name
+                }
+            },
+            show: false,
+        }
+    },
+    computed:{
+       
+    },
+    watch:{
+        file(){
+            this.show = false
+            this.loadOnlyOffice()
+        }
+    },
+    created(){
+    },
+    mounted() {
+        this.loadOnlyOffice()
+    },
+    deactivated(){
+    },
+    methods:{
+        loadOnlyOffice(){
+            if(!this.file || !this.file.guid){
+                return
+            }
+            if(!this.file.fileType){
+                var fileIds = [this.file.guid]
+                this.$api.getFileData(fileIds).then(response=>{
+                    if(response && response.length>0){
+                        var data = response[0]
+                        this.file.fileType = data.type
+                        this.getOption()
+                    }
+                })
+            }else{
+                this.getOption()
+            }
+            // this.option.name = optionTemp.name
+            // this.option.id = optionTemp.id
+            // this.option.title = optionTemp.title
+            // this.option.url = optionTemp.url
+            // this.option.fileType = optionTemp.fileType
+            // this.option.token = optionTemp.token
+            // this.show = true
+        },
+        //刷新网页参数
+        reLoadQuery(data={}){
+            this.$router.replace({
+                path: '/onlyOffice',
+                query: {
+                    ...this.file,
+                    ...data
+                
+                }
+            })
+        },
+        getOption(){
+            this.option.name = this.file.title
+            this.option.id = this.file.guid
+            this.option.title = this.file.title
+            this.option.url = this.$c.url+ (this.$c.env=='production'?'/api':'')+'/fileManager/downloadFile?fileId=' + this.file.guid
+            this.option.fileType = this.file.fileType
+            this.option.key = this.file.guid
+            this.option.created = this.file.createTime || formatDate(new Date(),'YYYY-MM-DD HH:mm:ss')
+
+            this.option.model = this.file.model || 'edit'
+            this.$nextTick(()=>{
+                this.show = true
+            })
+            
+            // this.option.token = optionTemp.token
+        },
+        generateString(length) {
+            let result = '';
+            const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
+            const charactersLength = characters.length;
+            for (let i = 0; i < length; i++) {
+                result += characters.charAt(Math.floor(Math.random() * charactersLength));
+            }
+            return result;
+        }
+    }
+}
+</script>
+<style>
+  .qualityManual-container {
+    padding: 0 !important;
+    height: 100%;
+  }
+
+  .qualityManual-container-office {
+    width: 100%;
+    height: calc(100% - 0px);
+  }
+</style>
+<style lang="scss" scoped>
+
+</style>

+ 247 - 0
src/views/task/components/examine/components/projectMessage.vue

@@ -0,0 +1,247 @@
+<template>
+  <div>
+    <template v-if="taskType == 5">
+        <div>
+            <taskMessageVue :taskId="taskId" :taskMessage="belongingTask" :taskType="taskType"></taskMessageVue>
+        </div>
+    </template>
+    <template v-else>
+        <el-row :gutter="15" v-for="(item) in (columnList.length/col | 1)" :key="item+'q'">
+            <template v-for="fieldIndex in 3" v-if="columnList[getFileProperty(item,fieldIndex)]" >
+                <el-col :key="fieldIndex+'a'"><div>{{columnList[getFileProperty(item,fieldIndex)].name}}:</div></el-col>
+                <el-col :key="fieldIndex+'b'">
+                <div v-html="$commonJS.getColumnData(projectMessage,columnList[getFileProperty(item,fieldIndex)])"></div>
+                </el-col>
+            </template>
+        </el-row>
+        <el-row :gutter="15" v-if="projectMessage.systemFileList && projectMessage.systemFileList.length>0">
+            <el-col>附件:</el-col>
+            <el-col class="value">
+                <div v-for="file in projectMessage.systemFileList" :key="file.guid" class="cursor_pointer file">
+                    {{ file.originalName }} 
+                    <div class="btns"> 
+                        <el-button type="text" @click="review(file)">预览</el-button>
+                        <el-button type="text" @click="downLoad(file)">下载</el-button>
+                    </div>
+                </div>
+            </el-col>
+        </el-row>
+    </template>
+    
+  </div>
+</template>
+
+<script>
+const defaultColumnList = [
+    {
+        name:'项目名称',
+        field:'name',
+        projectType:[1,2,3]
+    },
+    {
+        name:'标的专利/产品',
+        field:'signPatentNo',
+        projectType:[2]
+    },
+    {
+        name:'报告类型',
+        field:'reportTypeName',
+        projectType:[2]
+    },
+    {
+        name:'报告状态',
+        field:'statusName',
+        projectType:[2]
+    },
+    {
+        name:'负责人',
+        field:'headName',
+        projectType:[1,2,3]
+    },
+    {
+        name:'负责部门',
+        field:'departmentName',
+        projectType:[1,2,3]
+    },
+    {
+        name:'发明点',
+        field:'inventionPoint',
+        projectType:[4]
+    },
+    {
+        name:'创建人',
+        field:'createName',
+        projectType:[1,2,3,4]
+    },
+    {
+        name:'创建时间',
+        field:'createTime',
+        projectType:[1,2,3,4]
+    },
+    {
+        name:'备注',
+        field:'description',
+        projectType:[1,2,3]
+    },
+    
+]
+import mixins from './mixins/index'
+import taskMessageVue from './taskMessage.vue';
+export default {
+  components: {
+    taskMessageVue
+  },
+  mixins:[mixins],
+  props: {
+    allMessage:{
+        type:Boolean,
+        default:false
+    }
+  },
+  data() {
+    return {
+        columnList:[],
+        col:3,
+        projectMessage:{},
+        belongingTask:{},
+    };
+  },
+  watch: {
+    taskMessage(val,oldVal){
+        if(!oldVal.projectType && val.projectType){
+            this.init()
+        }
+    }
+  },
+  computed: {},
+  created() {},
+  mounted() {
+    this.init()
+  },
+  methods: {
+    async init(){
+        if(this.taskType == 5){
+            this.getBelongingTask()
+            return
+        }
+        await this.getColumnData()
+        this.getProjectMessage()
+    },
+    //获取任务信息
+    getBelongingTask(){
+        if(!this.taskMessage.assoTaskId){
+            return
+        }
+        let params = {
+            current:1,
+            size:10,
+            searchQuery: `id=${this.taskMessage.assoTaskId}`,//检索条件
+            orderDTOList:[],//排序信息
+        }
+        this.$api.queryProjectTask(params).then(response => {
+            if (response.code == 200) {
+                if(response.data.data && response.data.data.length>0){
+                    this.belongingTask =  response.data.data[0]
+                }
+            }
+        }).catch(error => {
+        })
+    },
+    //获取栏位信息
+    async getColumnData(){
+        if(!this.taskMessage.projectType){
+            return
+        }
+        if(!this.allMessage || this.taskMessage.projectType == 4){
+            this.columnList = defaultColumnList.filter(item=>{
+                return item.projectType.indexOf(Number(this.taskMessage.projectType)) != -1
+            })
+            return
+        }
+        //projectType项目类型(1专题库 2报告 3专利挖掘项目 4查新检索)
+        var projectType = {
+            1:'patentProject',
+            2:'reportProject',
+            3:'patentDigProject'
+        }
+        this.columnList = await this.$commonJS.getCustomField(projectType[this.taskMessage.projectType])
+    },
+    //获取所属项目信息
+    getProjectMessage(){
+        if(!this.taskMessage.projectId){
+            return
+        }
+        var params = {
+            searchQuery: `id=${this.taskMessage.projectId}`,//检索条件
+            orderDTOList: [],//排序
+        }
+        switch(this.taskMessage.projectType){
+            case 1://查询专利数据库信息
+                this.$api.queryPatentProject(params).then(response=>{
+                    if(response.code == 200){
+                        if(response.data.data && response.data.data.length>0){
+                            this.projectMessage =  response.data.data[0]
+                        }
+                    }
+                })
+                break;
+            case 2://查询报告信息
+                this.$api.queryReportProject(params).then(response => {
+                    if (response.code == 200) {
+                        if(response.data.data && response.data.data.length>0){
+                            this.projectMessage =  response.data.data[0]
+                        }
+                    }
+                }).catch(error => {
+                })
+                break;
+            case 3://查询专利挖掘信息
+                this.$api.queryPatentDigProject(params).then(response => {
+                    if (response.code == 200) {
+                        if(response.data.data && response.data.data.length>0){
+                            this.projectMessage =  response.data.data[0]
+                        }
+                    }
+                }).catch(error => {
+                })
+                break;
+            case 4://查询查新检索项目信息
+                params.searchQuery = `projectId=${this.taskMessage.projectId}`
+                this.$api.queryNoveltyProject(params).then(response=>{
+                    if(response.code == 200){
+                        if(response.data.data && response.data.data.length>0){
+                            this.projectMessage =  response.data.data[0]
+                        }
+                    }
+                }).catch(error=>{
+                })
+                break;
+        }
+        
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+.cursor_pointer{
+    .btns{
+        opacity:0;
+        pointer-events: none;
+    }
+    &:hover{
+        color:#66b1ff;
+        .btns{
+            opacity:1;
+            pointer-events: all;
+        }
+    }
+  
+}
+.file{
+    line-height: 35px;
+    width: 100%;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+}
+</style>

+ 54 - 0
src/views/task/components/examine/components/taskMessage.vue

@@ -0,0 +1,54 @@
+<template>
+  <div>
+    <el-row :gutter="15" v-for="(item) in (columnList.length/col | 1)" :key="item+'q'">
+        <template v-for="fieldIndex in 3" v-if="columnList[getFileProperty(item,fieldIndex)]" >
+            <el-col :key="fieldIndex+'a'"><div>{{columnList[getFileProperty(item,fieldIndex)].name}}:</div></el-col>
+            <el-col :key="fieldIndex+'b'">
+                <div v-if="['type'].includes(columnList[getFileProperty(item,fieldIndex)].value)" v-html="$commonJS.getColumnData(taskMessage, columnList[getFileProperty(item,fieldIndex)], null, { data: taskTypeList })"></div>
+                <div v-else-if="['status'].includes(columnList[getFileProperty(item,fieldIndex)].value)" v-html="$commonJS.getColumnData(taskMessage, columnList[getFileProperty(item,fieldIndex)], null, { data: taskStatusList })"></div>
+                <div v-else-if="['projectName'].includes(columnList[getFileProperty(item,fieldIndex)].value)">
+                  <div v-if="taskMessage.projectType == 4">查新检索项目</div>
+                  <div v-else v-html="$commonJS.getColumnData(taskMessage, columnList[getFileProperty(item,fieldIndex)])"></div>
+                </div>
+                <div v-else v-html="$commonJS.getColumnData(taskMessage, columnList[getFileProperty(item,fieldIndex)])"></div>
+            </el-col>
+        </template>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import mixins from './mixins/index'
+export default {
+  components: {},
+  mixins:[mixins],
+  props: {},
+  data() {
+    return {
+        columnList:[],
+        col:3
+    };
+  },
+  watch: {},
+  computed: {},
+  created() {},
+  mounted() {
+    this.getColumn()
+  },
+  methods: {
+    async getColumn(){
+      var columnList = await this.$commonJS.getCustomField('projectTask')
+      if(this.taskType != 5){
+        this.columnList = columnList.filter(item=>{
+          return item.field != 'processName'
+        })
+      }else{
+        this.columnList = columnList
+      }
+      
+    }
+  },
+};
+</script>
+<style lang="scss" scoped>
+</style>

+ 33 - 0
src/views/task/components/examine/index.vue

@@ -0,0 +1,33 @@
+<template>
+  <div class="height_100">
+    <examine :taskId="taskId" :taskType="taskType"></examine>
+  </div>
+</template>
+
+<script>
+import examine from './components/examine.vue';
+export default {
+  components: {
+    examine
+  },
+  props: {},
+  data() {
+    return {
+    };
+  },
+  watch: {},
+  computed: {
+    taskId(){
+        return this.$route.query.taskId
+    },
+    taskType(){
+        return this.$route.query.taskType
+    },
+  },
+  created() {},
+  mounted() {},
+  methods: {},
+};
+</script>
+<style lang="scss" scoped>
+</style>

+ 21 - 5
src/views/task/components/index.vue

@@ -75,6 +75,9 @@
     <handleTask1 ref="handleTask1Dialog" @isSuccess="isSuccess"></handleTask1>
     <handleTask2 ref="handleTask2Dialog" @isSuccess="isSuccess"></handleTask2>
     <lookReport ref="lookReport" @isSuccess="isSuccess"></lookReport>
+
+    <!-- 审核历史 -->
+    <examineHistoryDialog ref="examineHistoryDialog"></examineHistoryDialog>
   </div>
 </template>
 
@@ -87,6 +90,8 @@ import createTask from '@/views/patentMining/components/dialog/createTask.vue'
 import handleTask1 from '@/views/patentMining/components/dialog/handleTask1.vue'
 import handleTask2 from '@/views/patentMining/components/dialog/handleTask2.vue'
 import lookReport from '@/views/report/components/dialog/lookReport.vue'
+
+import examineHistoryDialog from '@/views/report/components/reportFile/examineHistoryDialog.vue'
 export default {
   mixins: [column, optionsData, taskPatentMining],
   // type区分是从哪里进入
@@ -107,6 +112,7 @@ export default {
     handleTask1,
     handleTask2,
     lookReport,
+    examineHistoryDialog
   },
   data() {
     return {
@@ -253,7 +259,8 @@ export default {
     handleCommand(ev, row) {
       switch (ev) {
         case '1'://查看审核记录
-          this.$refs.auditRecords.open(row)
+          // this.$refs.auditRecords.open(row)
+          this.$refs.examineHistoryDialog.open(null,row.id)
           break;
         case '2'://取消任务//发起人和审核人可以取消任务,外部人员不能取消任务
           this.finishClose(row, 1)
@@ -376,7 +383,8 @@ export default {
           this.handleAllocation(row)
           break;
         case 1://项目开卷审核任务
-          this.handleProject(row, str)
+          // this.handleProject(row, str)
+          this.fileExamine(row,str)
           break;
         case 3://报告对比任务
           this.handleAllocation(row)
@@ -450,11 +458,19 @@ export default {
     },
     //文件及任务审核任务(专利挖掘)
     fileExamine(row,str) {
-      row.disabled = str 
+      // row.disabled = str 
+      // let router = this.$router.resolve({
+      //   path: '/handleExamine',
+      //   query: {
+      //     row: JSON.stringify(row)
+      //   }
+      // })
+      // window.open(router.href, '_blank')
       let router = this.$router.resolve({
-        path: '/handleExamine',
+        path: '/examine',
         query: {
-          row: JSON.stringify(row)
+          taskId:row.id,
+          taskType:row.type
         }
       })
       window.open(router.href, '_blank')

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 8652 - 8504
yarn.lock


BIN
小世系统(本地).zip


BIN
小世系统(生产).zip