Browse Source

无效应对

zhuhao 2 years ago
parent
commit
173cf2da15
36 changed files with 5574 additions and 114 deletions
  1. 58 9
      RMS-FrontEnd/src/App.vue
  2. 196 0
      RMS-FrontEnd/src/api/InvalidResponse.js
  3. 2 0
      RMS-FrontEnd/src/api/index.js
  4. 50 0
      RMS-FrontEnd/src/router/index.js
  5. 4 0
      RMS-FrontEnd/src/store/modules/report.js
  6. 39 3
      RMS-FrontEnd/src/views/components/articles/ContrastIndex.vue
  7. 2 2
      RMS-FrontEnd/src/views/components/articles/components/PatentRight.vue
  8. 39 2
      RMS-FrontEnd/src/views/components/articles/components/mixins.js
  9. 168 18
      RMS-FrontEnd/src/views/components/articles/index.vue
  10. 118 66
      RMS-FrontEnd/src/views/components/common/mixins.js
  11. 514 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/InvalidEvidence.vue
  12. 632 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/InvalidEvidence1.vue
  13. 86 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/InvalidFeatures.vue
  14. 750 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/InvalidIndex.vue
  15. 131 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/TableField.vue
  16. 433 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/addOpinion.vue
  17. 26 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/checkFile.vue
  18. 259 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/choseOpinion.vue
  19. 378 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/evidenceAndRequest.vue
  20. 36 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/evidenceAndRequestRouter.vue
  21. 148 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/flowPath.vue
  22. 39 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/invalidIdexRouter.vue
  23. 241 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/opinionPlan.vue
  24. 159 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/reasonAndEvidence.vue
  25. 234 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/responseDialog.vue
  26. 175 0
      RMS-FrontEnd/src/views/report/InvalidResponse/import/components/importPatent.vue
  27. 294 0
      RMS-FrontEnd/src/views/report/InvalidResponse/import/components/systemTask.vue
  28. 32 0
      RMS-FrontEnd/src/views/report/InvalidResponse/import/index.vue
  29. 86 0
      RMS-FrontEnd/src/views/report/InvalidResponse/index.vue
  30. 2 1
      RMS-FrontEnd/src/views/report/components/Card.vue
  31. 97 6
      RMS-FrontEnd/src/views/report/components/CreateReport.vue
  32. 2 0
      RMS-FrontEnd/src/views/report/components/Tabel.vue
  33. 1 1
      RMS-FrontEnd/src/views/report/components/matter/remarryMatter.vue
  34. 98 0
      RMS-FrontEnd/src/views/report/components/mixins.js
  35. 40 2
      RMS-FrontEnd/src/views/report/index.vue
  36. 5 4
      RMS-FrontEnd/src/views/task/MyHandle.vue

+ 58 - 9
RMS-FrontEnd/src/App.vue

@@ -14,11 +14,19 @@
                 </el-radio-group>
                 &NonBreakingSpace;&NonBreakingSpace;
                 <a onclick="pizhu()" style="font-size: 14px;font-weight: 500;"> 批注</a>
-                &NonBreakingSpace;&NonBreakingSpace;
-                <a onclick="addDuiBi()" v-if="!mark.id" style="font-size: 14px;font-weight: 500;">对比</a>
-              <!-- &NonBreakingSpace;&NonBreakingSpace; -->
-                <!-- <a @click="addOpinion" >陈述意见</a>
-              &NonBreakingSpace;&NonBreakingSpace; -->
+                
+                <template  v-if="[1,2,3].includes(Number(mark.reportType)) && mark.taskId">
+                  &NonBreakingSpace;&NonBreakingSpace;
+                  <a onclick="addDuiBi()" v-if="!mark.id" style="font-size: 14px;font-weight: 500;">对比</a>
+                </template>
+
+                <template v-if="mark.reportType==7">
+                  &NonBreakingSpace;&NonBreakingSpace;
+                  <a v-if="mark.scratchField && mark.scratchField.includes('权利要求') && (mark.signPatentNo == mark.patentNo)" @click="addStateOpinion()" style="font-size: 14px;font-weight: 500;" >添加特征</a>
+                  <a v-else-if="mark.signPatentNo != mark.patentNo" @click="addStateOpinion()" style="font-size: 14px;font-weight: 500;" >陈述意见</a>
+                 </template>
+
+             <!-- &NonBreakingSpace;&NonBreakingSpace; -->
                 <!-- <a onclick="hiddenPizhu()"></a> -->
                 &NonBreakingSpace;&NonBreakingSpace;
                 <a v-if="mark.id" @click="hiddenPiZhuDelete" style="font-size: 14px;font-weight: 500;">删除</a>
@@ -27,15 +35,18 @@
     </div>
     <!-- <div class="pizhu"></div> -->
     <piZhu :gaoLiangCaiDan="gaoLiangCaiDan" :piZhuDelete="piZhuDelete"></piZhu>
+    <addOpinion ref="addOpinion"></addOpinion>
   </div>
 </template>
 
 <script>
 import piZhu from '@/views/components/gaoliang/components/pizhu.vue'
+import addOpinion from '@/views/report/InvalidResponse/components/addOpinion.vue'
 export default {
   name: 'app',
   components: {
     piZhu,
+    addOpinion,
   },
   data() {
     return {
@@ -45,6 +56,7 @@ export default {
   },
   computed:{
     mark() {
+      console.log( this.$store.state.patent.index);
       return this.$store.state.patent.index || {
         rangeType:[]
       }
@@ -68,6 +80,45 @@ export default {
     })
   },
   methods: {
+    //添加陈述意见
+    addStateOpinion() {
+      console.log(this.mark)
+//       {
+//     "color": "#ff0000",
+//     "scratchType": 2,
+//     "permissionType": 1,
+//     "rangeType": true,
+//     "content": "",
+//     "remark": null,
+//     "Id": "fa59a921-5e1b-44b9-8ff0-42d40e1d4b93",
+//     "patentNo": "CN109924892B",
+//     "text": "承载部向上",
+//     "rangeId": 437,
+//     "scratchField": "摘要",
+//     "position": 31,
+//     "id": null,
+//     "createFrom": 2,
+//     "Type": 0
+// }
+
+      var form = {
+        color: this.mark.color,
+        scratchType: this.mark.scratchType,
+        patentNo: this.mark.patentNo,
+        content: this.mark.text,
+        reportId: this.mark.rangeId,
+        scratchField: this.mark.scratchField,
+        position: this.mark.position,
+        proofId: this.mark.evidenceFlieId,//证据文献Id
+        signPatentNo: this.mark.signPatentNo,
+        rightId:this.mark.rightSort,
+        // reportType:this.mark.reportType,
+        // taskId:this.mark.taskId,
+      }
+      this.$refs.addOpinion.open(form,form.patentNo==form.signPatentNo)
+    },
+
+
     changeColor(){},
     changeRadio(val) {
       this.mark.scratchType = val
@@ -109,9 +160,7 @@ export default {
     user-select:none;
     cursor: pointer;
   }
-  .el-radio__inner{
-    display: none;
-  }
+ 
 }
 .showPiZhu{
   position: absolute;
@@ -139,7 +188,7 @@ export default {
     padding: 0;
     p{
       margin: 0;
-      width: 50px;
+      min-width: 50px;
       line-height: 30px;
       height: 30px;
     }

+ 196 - 0
RMS-FrontEnd/src/api/InvalidResponse.js

@@ -0,0 +1,196 @@
+import axios from '@/utils/axios';
+
+export default {
+  /**
+ * 查询excel导入
+ */
+  importProjectPatent(params) {
+    return axios.post('/v2/project/import/patent', params)
+  },
+   /**
+   * 获取专题库文件夹列表
+   */
+   getProjectFolderList(params) {
+    return axios.get('/v2/project/folder/list', { params })
+  },
+   /**
+   * 获取自定义字段
+   */
+  getCustomField(params) {
+    return axios.get('/v2/field/custom', { params, loading: false })
+  },
+   /**
+   * 获取导入任务列表
+   */
+   getTaskList(params) {
+    return axios.get('/v2/task/list', { params })
+  },
+  /**
+   * 获取队列
+   */
+  getQueueList(params) {
+    return axios.get('/v2/task/queue', { params })
+  },
+  /**
+   * 删除导入成功的任务
+   */
+  deleteTask(params) {
+    return axios({
+      url: '/v2/task/delete',
+      method: 'post',
+      params: params
+    })
+  },
+  /**
+ * 查询无效证据和无效请求书
+ */
+  queryProof(params) {
+    return axios.post('/report/api/CompareFiles/queryProof', params)
+  },
+  /**
+ * 上传非专利文献
+ */
+  addProofByFile(params) {
+    return axios.post('/report/api/CompareFiles/addProofByFile', params)
+  },
+  /**
+ * 无效流程无效事务添加
+ */
+  addInvalidProcess(params) {
+    return axios.post('/report/api/invalidProcess/add', params)
+  },
+  /**
+ * 无效流程无效事务修改
+ */
+  updateInvalidProcess(params) {
+    return axios.post('/report/api/invalidProcess/update', params)
+  },
+  /**
+ * 无效流程无效事务查询
+ */
+  queryInvalidProcess(params) {
+    return axios.get('/report/api/invalidProcess/query', {params})
+  },
+  /**
+ * 无效流程无效事务删除
+ */
+  deleteInvalidProcess(params) {
+    return axios.get('/report/api/invalidProcess/delete', {params})
+  },
+  /**
+ * 无效理由和证据:添加无效理由和证据
+ */
+  addInvalidReason(params) {
+    return axios.post('/report/api/invalidReason/addInvalidReason', params)
+  },
+  /**
+ * 根据专利号查询专利
+ */
+  getFeatureRights(params) {
+    return axios.get('/report/api/feature/getRights', {params})
+  },
+  /**
+ * 添加证据
+ */
+  addSingleFeature(params) {
+    return axios.post('/report/api/feature/addSingleFeature', params)
+  },
+  /**
+ * 查询证据
+ */
+  getFeatureList(params) {
+    return axios.get('/report/api/feature/getFeatureList', {params})
+  },
+  /**
+ * 添加或更新
+ */
+  addOrUpdatePoofArguments(params) {
+    return axios.post('/report/api/arguments/addOrUpdatePoofArguments', params)
+  },
+  /**
+ * 查询陈述意见列表
+ */
+  queryPoofArguments(params) {
+    return axios.get('/report/api/arguments/queryPoofArguments', {params})
+  },
+  /**
+ * 查询无效理由和证据
+ */
+  queryInvalidReason(params) {
+    return axios.get('/report/api/invalidReason/queryInvalidReason', {params})
+  },
+  /**
+ * 更新无效理由和证据
+ */
+  updatelnvalidReason(params) {
+    return axios.post('/report/api/invalidReason/updateInvalidReason', params)
+  },
+  /**
+ * 删除无效理由和证据
+ */
+  deleteInvalidReason(params) {
+    return axios.post('/report/api/invalidReason/deleteInvalidReason', params)
+  },
+  /**
+ * 根据特征查询证据
+ */
+  queryProofStr(params) {
+    return axios.get('/report/api/arguments/queryProofStr', {params})
+  },
+  /**
+ * 添加陈述意见
+ */
+  addArguments(params) {
+    return axios.post('/report/api/arguments/addArguments', params)
+  },
+  /**
+ * 删除陈述意见
+ */
+  deletePoofArguments(params) {
+    return axios.post('/report/api/arguments/deleteArguments', params)
+  },
+  /**
+ * 划词查询陈述意见
+ */
+  queryScratchs(params) {
+    return axios.get('/report/api/arguments/queryScratchs', {params})
+  },
+  /**
+ * 划词编辑陈述意见
+ */
+  updateArguments(params) {
+    return axios.post('/report/api/arguments/updateArgument', params)
+  },
+  /**
+ * 生成陈述意见方案
+ */
+  addArgumentsScenario(params) {
+    return axios.post('/report/api/argumentsScenario/add', params)
+  },
+  /**
+ * 查询陈述意见方案
+ */
+  queryArgumentsScenario(params) {
+    return axios.get('/report/api/argumentsScenario/query', {params})
+  },
+  /**
+ * 删除陈述意见方案
+ */
+  deleteArgumentsScenario(params) {
+    return axios.post('/report/api/argumentsScenario/delete', params)
+  },
+  /**
+ * 更新陈述意见方案
+ */
+  updataArgumentsScenario(params) {
+    return axios.post('/report/api/argumentsScenario/updata', params)
+  },
+
+   /**
+ * 证据文献排序
+ */
+   addProodOrder(params) {
+    return axios.post('/report/api/CompareFiles/order/addProodOrder', params)
+  },
+  
+}

+ 2 - 0
RMS-FrontEnd/src/api/index.js

@@ -7,6 +7,7 @@ import product from './product';
 import matters from './matters';
 import task from './task';
 import highlight from './highlight';
+import InvalidResponse from './InvalidResponse';
 
 export default {
   ...report,
@@ -17,4 +18,5 @@ export default {
   ...matters,
   ...task,
   ...highlight,
+  ...InvalidResponse,
 }

+ 50 - 0
RMS-FrontEnd/src/router/index.js

@@ -242,6 +242,56 @@ const routes = [
         },
         component:() => import('@/views/report/components/addPatentList'),
       },
+      {
+        path:'/InvalidResponse',
+        name:'InvalidResponse',
+        meta:{
+          title:'无效应对',
+          aside:true,
+          showHeader:true,
+        },
+        component:() => import('@/views/report/InvalidResponse/index'),
+      },
+      {
+        path:'/evidenceAndRequest',
+        name:'evidenceAndRequest',
+        meta:{
+          title:'无效证据',
+          aside:true,
+          showHeader:true,
+        },
+        component:() => import('@/views/report/InvalidResponse/components/evidenceAndRequest'),
+      },
+      {
+        path:'/importPatent',
+        name:'importPatent',
+        meta:{
+          title:'Excel上传',
+          aside:true,
+          showHeader:true,
+        },
+        component:() => import('@/views/report/InvalidResponse/import/index.vue'),
+      },
+      {
+        path:'/invalidIdexRouter',
+        name:'invalidIdexRouter',
+        meta:{
+          title:'无效证据和理由',
+          aside:true,
+          showHeader:true,
+        },
+        component:() => import('@/views/report/InvalidResponse/components/invalidIdexRouter.vue'),
+      },
+      {
+        path:'/evidenceAndRequestIndex',
+        name:'evidenceAndRequestIndex',
+        meta:{
+          title:'证据详情',
+          aside:true,
+          showHeader:true,
+        },
+        component:() => import('@/views/report/InvalidResponse/components/evidenceAndRequestRouter.vue'),
+      },
       //产品管理
       {
         path: "/product",

+ 4 - 0
RMS-FrontEnd/src/store/modules/report.js

@@ -9,9 +9,13 @@ export default {
     patentList: [],
     contrastList:[],
     pizhucontrastList:[],
+    opinioncontrastList:[],
   },
 
   mutations: {
+    SET_PATENT_OPINION_CONTRAST:(state, opinioncontrastList)=>{
+      state.opinioncontrastList = opinioncontrastList
+    },
     SET_PATENT_PIZHU_CONTRAST:(state, pizhucontrastList)=>{
       state.pizhucontrastList = pizhucontrastList
     },

+ 39 - 3
RMS-FrontEnd/src/views/components/articles/ContrastIndex.vue

@@ -34,6 +34,9 @@
                 <span v-else>切换原文</span>
               </el-link>
             </div>
+              <div style="position: absolute;right: 0;top:0;">
+                <PatentMark :patentNo="patent.patentNo" @biaozhu="getBiaoZhu"></PatentMark>
+              </div>
             </div>
            
             <div  style="  position: relative;">
@@ -60,12 +63,12 @@
           <div class="patent-articles-content-left1" :style="{ width: showRight ? 'calc(100% - 321px)' : 'calc(100% - 21px)' }">
             <div class="dom1 box1" v-dragControllerDiv1 style="display:flex;width:100%">
               <div class="component left1" style="width:100%;overflow-y:auto;overflow-x: hidden;padding-bottom:10px" :style="{height:height}">
-                <component :is="componentName" :type1='type' :isTrue="isTrue" @openContrast='openContrast' :project-id="projectId" :patent="patent" :patent-id="patentId" :signPatentNo="signPatentNo" :patentNo="this.activeMenu == 'patentWorth'?[patentNo?patentNo:productPublicNo]:patentNo" :publicNo="publicNo" :domId="patentNo + '2'" :reportId="reportId" @refresh="getPatent(patent.patentNo)"></component>
+                <component :is="componentName" v-bind="$attrs" :type1='type' :isTrue="isTrue" @openContrast='openContrast'  :project-id="projectId" :patent="patent" :patent-id="patentId" :signPatentNo="signPatentNo" :patentNo="this.activeMenu == 'patentWorth'?[patentNo?patentNo:productPublicNo]:patentNo" :publicNo="publicNo" :domId="patentNo + '2'" :reportId="reportId" @refresh="getPatent(patent.patentNo)"></component>
               </div>
               <div class="resize2" title="收缩侧边栏" v-show="(radio == 2 || radio == 3) && activeMenu != activeMenu2"><p><span>˙</span><span>˙</span><span>˙</span></p></div>
               <div class="resize1" title="收缩侧边栏" v-show="(radio == 4 || radio == 5) && activeMenu != activeMenu2"><span>⋮</span></div>
             <div v-show="radio != 1 && activeMenu != activeMenu2" class="mid1" :style="{height:(radio == 4 || radio == 5)?height:'280px'}"  style="width:450px;height:280px;border:1px solid #E4E7ED;margin:10px;overflow-y:auto;overflow-x: hidden;">
-              <component :is="activeMenu2" :project-id="projectId" :patent="patent" :patent-id="patentId" :pdfType1="(patent.pdf && patent.pdf.length>0)?patent.pdf[0].type:2" :sign="true"></component>
+              <component :is="activeMenu2" v-bind="$attrs" :project-id="projectId" :patent="patent" :patent-id="patentId" :pdfType1="(patent.pdf && patent.pdf.length>0)?patent.pdf[0].type:2" :sign="true"></component>
             </div>
             </div>
           
@@ -122,6 +125,7 @@ import PatentWorth from './components/history/components/echarts/components/echa
 
 import { splitScreen1 } from '../common/SplitScreen'
 
+import PatentMark from './components/PatentMark.vue'
 export default {
   mixins: [patentKeywordsHighlight, changeTranslation,splitScreen1],
   components: {
@@ -144,7 +148,8 @@ export default {
     Other,
     Permit,
     ProductManage,
-    PatentWorth
+    PatentWorth,
+    PatentMark
   },
   props:['patentMessage','publicNo','signPatentNo','reportId','type','isTrue',"taskId","patentStatus2A"],
   // props: {
@@ -311,8 +316,39 @@ export default {
     //   console.log(this.signPatentNo)
     //   this.getContrastList()
     // }
+    
   },
   methods: {
+     //获取需要跳转的批注
+     getBiaoZhu(val) {
+      if (val.scratchField == '摘要') {
+        this.activeMenu = 'PatentBasic'
+      } else { 
+        this.activeMenu = this.menuList.find(item => {
+          return val.scratchField.indexOf(item.label)!=-1
+        }).value
+          if (val.scratchField.indexOf('译文') !=-1) {
+          this.activeName = '1'
+          } else {
+            this.activeName='0'
+          }
+      }
+      this.handleSelect(this.activeMenu)
+      
+        this.tiaozhuan(val.id,val)
+    },
+    tiaozhuan(id) {
+      const href = `#${id}`
+      const anchor = document.createElement('a');
+        anchor.href = href;
+        anchor.style.display = "none";
+        document.body.appendChild(anchor);
+        setTimeout(function () {
+          anchor.click();
+          document.body.removeChild(anchor);
+        }, 66);
+        return true;
+    },
     openContrast(val){
       this.$emit('openContrast',val)
     },

+ 2 - 2
RMS-FrontEnd/src/views/components/articles/components/PatentRight.vue

@@ -13,7 +13,7 @@
         </p> -->
         <div v-html="getViewDom1(patent.rights,'权利要求原文','contentOut')"  data-type="权利要求译文"></div>
       </el-tab-pane>
-      <el-tab-pane v-if="signPatentNo" label="权利特征" name="2" :style="{height: height + 'px',overflowY: 'auto'}">
+      <el-tab-pane v-if="signPatentNo && type1!=7" label="权利特征" name="2" :style="{height: height + 'px',overflowY: 'auto'}">
           <Features :patentNo="signPatentNo" :reportId="reportId"></Features>
       </el-tab-pane>
     </el-tabs>
@@ -30,7 +30,7 @@ export default {
   components:{
     Features
   },
-  props:['signPatentNo','reportId'],
+  props:['signPatentNo','reportId','parentNo','type1'],
   mixins: [commonMixins,addContrast,patentKeywordsHighlight],
   data() {
     return {

+ 39 - 2
RMS-FrontEnd/src/views/components/articles/components/mixins.js

@@ -703,7 +703,7 @@ export const addContrast1 = {
 }
 
 export const addContrast = {
-  props:['reportId','activeName'],
+  props:['reportId','activeName','evidenceFlieId','signPatentNo','reportType','taskId','type'],
   data() {
     return {
       mX: 0,
@@ -724,6 +724,9 @@ export const addContrast = {
     contrastList() {
       return this.$store.state.report.contrastList
     },
+    opinioncontrastList() {
+      return this.$store.state.report.opinioncontrastList
+    },
   },
   watch: {
     index(val) {
@@ -739,8 +742,18 @@ export const addContrast = {
     window.hiddenPizhu = this.hiddenPizhu
     window.selectMark = this.selectMark
     window.addDuiBi = this.addDuiBi
+    // window.addStateOpinion = this.addStateOpinion
+    console.log(this.reportType,this.taskId);
   },
   methods: {
+    // 划词点击添加陈述意见
+    // addStateOpinion() {
+    //   let dl = document.getElementsByClassName("opinion");
+    //   console.log(dl);
+    //   // let opinion = this.currentSelectObj
+    //   // opinion.isHuaCi=true
+    //   // this.$emit('openAddStateOpinion',opinion)
+    // },
     // 点击对比按钮
     addDuiBi() {
       this.duiBiCurrentSelectObj=this.$store.state.patent.index
@@ -770,6 +783,13 @@ export const addContrast = {
           return item.id==Id
         })
         this.$emit('openContrast', a)
+      } else if (selectType == 2) {
+        let a=this.opinioncontrastList.find(item => {
+          return item.id==Id
+        })
+        this.$emit('openOpinioncontrast', a)
+        // this.showPizhu()
+        // this.$store.commit('SET_PATENT_INDEX',a)
       }
       
     },
@@ -815,6 +835,12 @@ export const addContrast = {
           // a.color = this.currentSelectObj.color
           a.createFrom = 2
           a.Type = 0
+
+          a.rightSort=this.currentSelectObj.rightSort
+          a.evidenceFlieId = this.evidenceFlieId
+          a.signPatentNo = this.signPatentNo
+          a.reportType = this.reportType ?this.reportType:this.type
+          a.taskId = this.taskId
           this.$store.commit("SET_PATENT_INDEX", a)
           this.showPizhu()
         }
@@ -885,9 +911,20 @@ export const addContrast = {
           NotIncludeDataType(node.parentElement);
         }
       }
+      var rightSort = null
+      if (this.reportType == 7 && temNode.getAttribute("data-type").includes('权利要求')) {
+        getRightSort(a)
+        function getRightSort(node) {
+          if (node.getAttribute("right-sort") != null) {
+            rightSort = node.getAttribute("right-sort")
+          } else {
+            getAttribute(node.parentElement);
+          }
+        }
+      }
       this.getColumn(temNode, selectObj);
       this.isFirst = true
-      return { "Id": this.uuid(), "column": temNode.getAttribute("data-type"), "index": this.anchorOffset, "text": selectObj.toString(), 'temNode': temNode.innerHTML };
+      return { "Id": this.uuid(), "column": temNode.getAttribute("data-type"), "index": this.anchorOffset, "text": selectObj.toString(), 'temNode': temNode.innerHTML,'rightSort':rightSort };
     },
     getColumn(node, selectObj) {
       var baseNode = this.getColumnNode(node);

File diff suppressed because it is too large
+ 168 - 18
RMS-FrontEnd/src/views/components/articles/index.vue


File diff suppressed because it is too large
+ 118 - 66
RMS-FrontEnd/src/views/components/common/mixins.js


+ 514 - 0
RMS-FrontEnd/src/views/report/InvalidResponse/components/InvalidEvidence.vue

@@ -0,0 +1,514 @@
+<template>
+  <div>
+    <div class="demo-input-suffix">
+      标的专利:<el-link type="primary" @click="toPatentDetails(patentNo)">{{ patentNo }}</el-link>
+    </div>
+    <div style="margin-top: 20px; display: flex; justify-content: space-between">
+      <el-button-group>
+        <el-button @click="addFeature1" :disabled="row.length > 0 ? false : true">添加特征</el-button>
+        <!-- <el-button @click="addFeature">添加特征</el-button> -->
+        <el-button @click="addOpinion" :disabled="row.length > 0 ? false : true">添加陈述意见</el-button>
+      </el-button-group>
+      <div>
+        <el-button @click="keep" type="primary" :loading="btnLoading">保存</el-button>
+      </div>
+    </div>
+    <div>
+      <el-table v-if="refreshData" :data="tableData" ref="table" border height="300"
+        :span-method="objectSpanMethod" v-loading="loading" style="min-width: 100%; margin-top: 20px;overflow:auto">
+        <el-table-column prop="pRightName" label="权要" align="center" width="200px">
+          <template slot-scope="scope">
+            <el-checkbox-group v-model="checkList">
+              <el-checkbox :label="scope.row.pRightName" @change="getFunInfo(scope.row, scope, 1)">
+                <el-tooltip class="item" effect="dark" :content="scope.row.pContent" placement="top">
+                  <span>{{ scope.row.pRightName }}</span>
+                </el-tooltip>
+              </el-checkbox>
+            </el-checkbox-group>
+
+          </template>
+        </el-table-column>
+        <el-table-column prop="content" label="特征" align="center" width="300px">
+          <template slot-scope="scope">
+            <el-checkbox-group v-model="checkList" v-if="scope.row.hasOwnProperty('content')">
+            <!-- <el-checkbox-group v-model="checkList"> -->
+              <el-checkbox :label="scope.row.id" @change="getFunInfo(scope.row, scope, 0)"
+                style="display: flex; align-items: center;">
+                <div class="selectButton">
+                  <el-select v-model="scope.row.content" placeholder="请选择"  style="width:100%"  @change="featureChange">
+                    <el-option v-for="item in featureList" :key="item.featureId" :label="item.featureName" :value="item.featureId" :disabled="tableData1.findIndex(item1=>{return item1.content == item.featureId})!=-1">
+                    </el-option>
+                  </el-select>
+                <el-button @click.stop="addFeature(scope.row)" ><i class="el-icon-plus"></i></el-button>
+              </div>
+                 
+              </el-checkbox>
+            </el-checkbox-group>
+            <!-- <el-input type="textarea" autosize v-model="scope.row.content" v-if="scope.row.hasOwnProperty('content')"> {{scope.row.content}}</el-input> -->
+          </template>
+        </el-table-column>
+
+        <el-table-column prop="evidence" align="center" label="证据(无效请求人)">
+          <template slot-scope="scope">
+            <!-- <div v-if="scope.row.hasOwnProperty('content')" -->
+            <div
+              style="width:100%;outline: #dcdfe6;border:1px solid #DCDFE6;border-radius:5px" id="preview" class="preview"
+              contenteditable="true" v-html="scope.row.evidence"  @blur="saveValue(scope.row,'evidence',$event.target.innerHTML)" v-on:paste="handlePaste($event, scope.row, 'evidence')"
+              @input="getValue(scope.row,'evidence',$event.target.innerHTML)"
+              >
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="evidence2" align="center" label="证据(权利人)">
+          <template slot-scope="scope">
+            <div class="innerTable" style="width:calc(100% + 20px);margin-left:-10px;word-wrap:break-word;">
+              <div class="item" v-for="(item, index) in scope.row.evidence2">
+                <div style="width:100%;outline: #dcdfe6;border:1px solid #DCDFE6;border-radius:5px" id="preview"
+                  contenteditable="true" v-html="item.argumentStr"  @blur="saveValue(scope.row.evidence2[index],'argumentStr',$event.target.innerHTML)"  v-on:paste="handlePaste($event, scope.row.evidence2[index], 'argumentStr',null)"
+                  @input="getValue(scope.row.evidence2[index],'argumentStr',$event.target.innerHTML)"
+                 >
+                </div>
+              </div>
+            </div>
+
+          </template>
+        </el-table-column>
+        <el-table-column v-for="column in tableField.filter(item => !item.hidden)" :key="column.key" :prop="column.key"
+          align="center" :label="column.name">
+          <template slot-scope="scope">
+            <div v-if="scope.row.hasOwnProperty('content')">
+              <div style="width:100%;outline: #dcdfe6;border:1px solid #DCDFE6;border-radius:5px" id="preview"
+                contenteditable="true" v-html="scope.row[column.key]" @input="saveValue($event.target.innerHTML)"
+                @click="saveValue($event.target.innerHTML)">
+              </div>
+            </div>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <!-- <Table-Field ref="tableField" @update="getTableField"></Table-Field> -->
+    <el-dialog title="添加特征" :visible.sync="addFeatureVisibe" width="400px" :before-close="closeFeature" append-to-body>
+      <div style="display:flex;">
+        <el-input type=""  v-model="featureName" style="margin-right: 10px;"></el-input>
+        <el-button @click="submitFeature" type="primary">添加</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+<script>
+import { explain1 } from "../../components/mixins";
+import { PatentDetails } from "@/views/components/common/mixins";
+import TableField from './TableField.vue'
+export default {
+  mixins: [explain1, PatentDetails],
+  props: ['patentNo','reportId','isOpinion','sign','evidence'],
+  components: {
+    TableField
+  },
+  data() {
+    return {
+      features: [],//特征数组
+      refreshData: true,
+      tableData: [],
+      tableData1: [],
+      splitType1: "1",
+      splitBy1: "2",
+      Type: "0",
+      btnLoading: false,
+      tableHeight: null,
+      loading: false,
+      checkList: [],
+      typeArr: [],
+      mergeObj: {},
+      row: [],//选中特征push到row中
+      mergeArr: ['id', 'pRightName'],//解释
+      tableField: [
+        {
+          key: 'Review',
+          name: '审委意见',
+          hidden: true
+        },
+        {
+          key: 'court',
+          name: '法院意见',
+          hidden: true
+        },
+        {
+          key: 'association',
+          name: '关联案件的证据',
+          hidden: true
+        },
+      ],
+      featureList: [],//选择特征数组
+      featureName:'',
+      addFeatureVisibe:false,
+    };
+  },
+  watch: {
+    tableData() {
+      if (this.evidence) {
+        
+      } else {
+        this.$nextTick(() => {
+          this.setHeight()
+        })
+      }
+      
+    },
+    sign(val) {
+      if (val) {
+        this.$emit('evidence', this.tableData)
+      }
+    },
+  },
+  mounted() {
+    if (this.evidence) {
+      // console.log(this.evidence);
+      // this.$nextTick(() => {
+        this.getPoofArguments(this.evidence.row, this.evidence.right)
+        this.getFeature(this.evidence.row, this.evidence.right.sort)
+      // })
+    }
+    // this.getList();
+    // this.getRight()
+  },
+  methods: {
+    featureChange(val) {
+      console.log(val);
+    },
+    // 查询陈述意见
+    getPoofArguments(row, right) {
+      // console.log(row,right);
+      this.tableData1=[]
+      let params = {
+        reportId  : this.reportId,
+        rightSort: right.sort,
+        proofId : row.id,
+      }
+      this.$api.queryPoofArguments(params).then((res) => {
+        if (res.code == 200) {
+          if (res.data.length > 0) {
+            res.data.forEach(item => {
+              let a = {
+                pRightName: item.rightName,
+                pContent: item.rightContent,
+                content: item.featureId,
+                featureName: item.featureName,
+                evidence:item.proofStr,
+                evidence2: item.arguments,
+                rightSort: params.rightSort,
+                proofId:item.proofId,
+              }
+              this.tableData1.push(a)
+            })
+          } else {
+            this.tableData1 = [
+              {
+                pRightName: right.rightName,
+                id: right.sort,
+                pType: 0,
+                pContent: right.content,
+                // 文献ID
+                proofId: row.id,
+                rightSort: params.rightSort,
+              },
+            ]
+          }
+          this.TypeSelect(this.Type)
+          // console.log(this.tableData)
+        }
+          
+      })
+    },
+    // 查已添加的特征
+    getFeature(row,right) {
+      let params = {
+        reportId: this.reportId,
+        rightSort:right
+      }
+      this.$api.getFeatureList(params).then((res) => {
+        if (res.code==200) {
+          this.featureList=res.data
+          // this.tableData =res.data
+        }
+      })
+    },
+
+    open(row, right) {
+      // this.getList(row, right);
+      row.evidence = this.tableData1
+      this.getFeature(row, right.sort)
+      this.getPoofArguments(row, right)
+    },
+     //拆分权要
+     getList(row, right) {
+      // console.log(row,right);
+      // this.tableData1 = [
+      //   {
+      //     pRightName: right.rightName,
+      //     id: right.sort,
+      //     pType: 0,
+      //     pContent: right.content,
+      //     // 文献ID
+      //     proffId:row.id
+      //   },
+      // ]
+      // this.TypeSelect(this.Type)
+      // console.log(this.tableData1,right);
+      // this.tableData1 = localStorage.patent
+    },
+    setHeight() {
+      const offsetTop = window.innerHeight - this.$refs.table.$el.offsetTop - 40
+      this.height = offsetTop
+      const body = document.querySelector('.el-table__body')
+      if (!body) {
+        return false
+      }
+      const offsetBodyHeight = body.offsetHeight
+      //console.log( window.innerHeight,body,offsetBodyHeight,offsetTop)
+      if (this.tableData.length && offsetBodyHeight < offsetTop) {
+        this.tableHeight = offsetBodyHeight + 75
+      } else if (!this.tableData.length) {
+        this.tableHeight = null
+      } else {
+        this.tableHeight = offsetTop
+      }
+      this.tableHeight = this.tableHeight > 300 ? this.tableHeight : 300
+    },
+    //选中特征
+    getFunInfo(row, scope, type) {
+      let Index = this.row.findIndex(item => { return item.id == row.id })
+      if (Index < 0) {
+        row.$index = scope.$index
+        row.choseType = type
+        this.row.push(row)
+      } else {
+        this.row.splice(Index, 1)
+      }
+    },
+
+    //添加陈述意见
+    addOpinion() {
+      if (this.row.length > 1) {
+        this.$alert('不能同时给多条特征添加陈述意见', '提示', {
+          confirmButtonText: '确定',
+          type: 'warning',
+          callback: action => {
+          }
+        })
+        return false
+      }
+      if (this.row[0].choseType != 0) {
+        this.$alert('请选择特征添加陈述意见', '提示', {
+          confirmButtonText: '确定',
+          type: 'warning',
+          callback: action => {
+          }
+        })
+        return false
+      }
+      this.checkList = []
+      var Index = this.tableData1.findIndex(item => {
+        return item.id == this.row[0].id
+      })
+      if (Index != -1) {
+        if (this.tableData1[Index].hasOwnProperty('evidence2')) {
+          this.tableData1[Index].evidence2.push({
+            argumentStr: ''
+          })
+        } else {
+          this.tableData1[Index].evidence2 = [
+            {
+              argumentStr: ''
+            }
+          ]
+        }
+
+        this.TypeSelect(this.Type)//调用显示权要
+        this.row = []
+      }
+
+    },
+    //添加特征
+    addFeature() {
+      this.addFeatureVisibe=true
+    },
+    closeFeature() {
+      this.addFeatureVisibe = false
+      this.featureName=''
+      
+    },
+    submitFeature() {
+      let params = {
+        content:this.featureName,
+        rightId:this.tableData1[0].rightSort,//权要的id
+        reportId:this.reportId
+      }
+      this.$api.addSingleFeature(params).then((res) => {
+        if (res.code==200) {
+          this.getFeature('',params.rightId)
+          this.$message.success('添加特征成功')
+          this.closeFeature()
+        }
+      })
+    },
+    addFeature1() {
+      // console.log(this.tableData1,this.tableData);
+      if (this.row.length > 1) {
+        this.$alert('不能同时给多个权要添加特征', '提示', {
+          confirmButtonText: '确定',
+          type: 'warning',
+          callback: action => {
+          }
+        })
+        return false
+      }
+      if (this.row[0].choseType != 1) {
+        this.$alert('请选择权要添加特征', '提示', {
+          confirmButtonText: '确定',
+          type: 'warning',
+          callback: action => {
+          }
+        })
+        return false
+      }
+      this.checkList = []
+      var Index = this.tableData1.findLastIndex(item => {
+        return item.pRightName == this.row[0].pRightName
+      })
+      if (Index != -1) {
+        if (this.tableData1[Index].hasOwnProperty('content')) {
+          let arr = JSON.parse(JSON.stringify(this.tableData1[Index]))
+          arr.content = ''
+          arr.evidence = ''
+          arr.evidence2 = [
+            {
+              argumentStr: ''
+            }
+          ]
+          // arr.proofId=
+          this.tableData1.splice(Index + 1, 0, arr)
+        } else {
+          this.$set(this.tableData1[Index], 'content', '')
+          this.$set(this.tableData1[Index], 'evidence', '')
+          var evidence2 = [
+            {
+              argumentStr: ''
+            }
+          ]
+          this.$set(this.tableData1[Index], 'evidence2', evidence2)
+        }
+        this.TypeSelect(this.Type)//调用显示权要
+        this.row = []
+      }
+      // console.log(this.tableData1)
+    },
+    //获取每个元素所需合并的行数
+    getSpanArr(data) {
+      this.row = []
+      this.mergeArr.forEach((key, index1) => {
+        let count = 0;
+        this.mergeObj[key] = [];
+        data.forEach((item, index) => {
+          if (index === 0) {
+            this.mergeObj[key].push(1);
+          } else {
+            if (item[key] === data[index - 1][key] && item[key] !== 'evidence') {
+              this.mergeObj[key][count] += 1;
+              this.mergeObj[key].push(0);
+            } else {
+              count = index;
+              this.mergeObj[key].push(1);
+            }
+          }
+        })
+      })
+    },
+    //合并行
+    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
+      if (this.mergeArr.indexOf(column.property) !== -1) {
+        if (this.mergeObj[column.property][rowIndex]) {
+          return [this.mergeObj[column.property][rowIndex], 1]
+        } else {
+          return [0, 0];
+        }
+      }
+    },
+
+    refreshTable() {
+      this.refreshData = false
+      this.$nextTick(() => {
+        this.refreshData = true
+      })
+    },
+   
+    keep() {
+      // console.log(this.tableData,this.tableData1);
+      var params=[]
+      for (let i = 0; i < this.tableData.length; i++){
+        params[i] = {
+          reportId: this.reportId,
+          rightSort: this.tableData[i].rightSort,
+          featureId: this.tableData[i].content,
+          proofStr: this.tableData[i].evidence,
+          proofStrId: 0,
+          proofId: this.tableData[i].proofId,
+          arguments: this.tableData[i].evidence2,
+        }
+      }
+      // console.log(params);
+        this.$api.addOrUpdatePoofArguments(params).then((res) => {
+          if (res.code ==200) {
+            this.$message.success('添加成功')
+            this.getPoofArguments()
+          }
+        })
+        // localStorage.patent = JSON.stringify(this.tableData1)
+    },
+
+    TypeSelect(event) {//显示
+      // this.typeArr = [];
+      // if (event == 1) {
+      //   this.typeArr.push(1);
+      // } else {
+      //   this.typeArr.push(1, 0);
+      // }
+      // this.tableData = this.tableData1.filter(item => {
+      //   return this.typeArr.includes(item.pType)
+      // })
+      this.tableData = this.tableData1
+      this.getSpanArr(this.tableData)
+    },
+  },
+};
+</script>
+<style lang="scss">
+  @import '@/assets/css/selectButton.scss';
+</style>
+<style lang="scss" scoped>
+.innerTable .item {
+  /* min-width:200px; */
+  padding: 20px 0;
+  margin: 0;
+  display: flex;
+  justify-content: flex-start;
+  align-items: center;
+  // height: 130px;
+  line-break: normal;
+  overflow: auto;
+  border-bottom: 1px solid #EBEEF5;
+}
+
+.innerTable .item:last-child:first-child {
+  //item 即是最后一个元素 又是第一个元素
+  height: 100%;
+}
+
+.innerTable .item:nth-child(1) {
+  border-bottom: 1px solid #EBEEF5;
+}
+
+.innerTable .item:last-child {
+  border-bottom: none;
+}
+</style>

+ 632 - 0
RMS-FrontEnd/src/views/report/InvalidResponse/components/InvalidEvidence1.vue

@@ -0,0 +1,632 @@
+<template>
+  <div>
+    <div class="demo-input-suffix">
+      标的专利:<el-link type="primary" @click="toPatentDetails(patentNo)">{{ patentNo }}</el-link>
+    </div>
+    <div style="margin-top: 20px; display: flex; justify-content: space-between">
+      <el-button-group>
+        <!-- <el-button @click="addFeature" :disabled="row.length > 0 ? false : true">添加特征</el-button> -->
+        <el-button @click="addFeature">添加特征</el-button>
+        <el-button @click="addOpinion" :disabled="row.length > 0 ? false : true">添加陈述意见</el-button>
+      </el-button-group>
+      <div>
+        <el-button @click="keep" type="primary" :loading="btnLoading">保存</el-button>
+      </div>
+    </div>
+    <div>
+      <el-table v-if="refreshData" :data="tableData" ref="table" border :height="tableHeight"
+        :span-method="objectSpanMethod" v-loading="loading" style="min-width: 100%; margin-top: 20px;overflow:auto">
+        <el-table-column prop="pRightName" label="权要" align="center" width="200px">
+          <template slot-scope="scope">
+            <el-checkbox-group v-model="checkList">
+              <el-checkbox :label="scope.row.pRightName" @change="getFunInfo(scope.row, scope, 1)">
+                <el-tooltip class="item" effect="dark" :content="scope.row.pContent" placement="top">
+                  <span>{{ scope.row.pRightName }}</span>
+                </el-tooltip>
+              </el-checkbox>
+            </el-checkbox-group>
+
+          </template>
+        </el-table-column>
+        <el-table-column prop="content" label="特征" align="center" width="300px">
+          <template slot-scope="scope">
+            <!-- <el-checkbox-group v-model="checkList" v-if="scope.row.hasOwnProperty('content')"> -->
+            <el-checkbox-group v-model="checkList">
+              <el-checkbox :label="scope.row.id" @change="getFunInfo(scope.row, scope, 0)"
+                style="display: flex; align-items: center;">
+                <!-- <el-input type="textarea" style="width:250px" autosize v-model="scope.row.content"> {{scope.row.content}}</el-input> -->
+
+                <!-- <el-autocomplete class="inline-input" v-model="scope.row.content" :fetch-suggestions="querySearch"
+                  placeholder="请输入内容"></el-autocomplete> -->
+                  <el-select v-model="scope.row.content" placeholder="请选择" style="width:100%" >
+                    <el-option v-for="item in rightList" :key="item.featureId" :label="item.featureName" :value="item.featureId" :disabled="scope.row.content?true:false">
+                    </el-option>
+                  </el-select>
+              </el-checkbox>
+            </el-checkbox-group>
+            <!-- <el-input type="textarea" autosize v-model="scope.row.content" v-if="scope.row.hasOwnProperty('content')"> {{scope.row.content}}</el-input> -->
+          </template>
+        </el-table-column>
+
+        <el-table-column prop="evidence" align="center" label="证据(无效请求人)">
+          <template slot-scope="scope">
+            <!-- <div v-if="scope.row.hasOwnProperty('content')" -->
+            <div
+              style="width:100%;outline: #dcdfe6;border:1px solid #DCDFE6;border-radius:5px" id="preview" class="preview"
+              contenteditable="true" v-html="scope.row.evidence"  @blur="saveValue(scope.row,'evidence',$event.target.innerHTML)" v-on:paste="handlePaste($event, scope.row, 'evidence')"
+              @input="saveValue(scope.row,'evidence',$event.target.innerHTML)"
+              >
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="evidence2" align="center" label="证据(权利人)">
+          <template slot-scope="scope">
+            <div class="innerTable" style="width:calc(100% + 20px);margin-left:-10px;word-wrap:break-word;">
+              <div class="item" v-for="(item, index) in scope.row.evidence2">
+                <div style="width:100%;outline: #dcdfe6;border:1px solid #DCDFE6;border-radius:5px" id="preview"
+                  contenteditable="true" v-html="item.argumentStr"  @blur="saveValue(scope.row.evidence2[index],'argumentStr',$event.target.innerHTML)"  v-on:paste="handlePaste($event, scope.row.evidence2[index], 'argumentStr',null)"
+                  @input="saveValue(scope.row.evidence2[index],'argumentStr',$event.target.innerHTML)"
+                 >
+                </div>
+              </div>
+            </div>
+
+          </template>
+        </el-table-column>
+        <el-table-column v-for="column in tableField.filter(item => !item.hidden)" :key="column.key" :prop="column.key"
+          align="center" :label="column.name">
+          <template slot-scope="scope">
+            <div v-if="scope.row.hasOwnProperty('content')">
+              <div style="width:100%;outline: #dcdfe6;border:1px solid #DCDFE6;border-radius:5px" id="preview"
+                contenteditable="true" v-html="scope.row[column.key]" @input="saveValue($event.target.innerHTML)"
+                @click="saveValue($event.target.innerHTML)">
+              </div>
+            </div>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <!-- <Table-Field ref="tableField" @update="getTableField"></Table-Field> -->
+    <el-dialog title="添加特征" :visible.sync="addFeatureVisibe" width="400px" :before-close="closeFeature" append-to-body>
+      <div style="display:flex;">
+        <el-input type=""  v-model="rightName"></el-input>
+        <el-button @click="addRight">添加</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+<script>
+// import { explain1 } from "../../components/mixins";
+import { PatentDetails } from "@/views/components/common/mixins";
+import TableField from './TableField.vue'
+export default {
+  mixins: [ PatentDetails],
+  props: ['patentNo', 'reportId', 'isOpinion', 'sign', 'evidenceData',"showBtnRight",'proofGroups'],
+  components: {
+    TableField
+  },
+  data() {
+    return {
+      features: [],//特征数组
+      refreshData: true,
+      tableData: [],
+      tableData1: [],
+      splitType1: "1",
+      splitBy1: "2",
+      Type: "0",
+      btnLoading: false,
+      tableHeight: null,
+      loading: false,
+      checkList: [],
+      typeArr: [],
+      mergeObj: {},
+      row: [],//选中特征push到row中
+      mergeArr: ['id', 'pRightName'],//解释
+      tableField: [
+        {
+          key: 'Review',
+          name: '审委意见',
+          hidden: true
+        },
+        {
+          key: 'court',
+          name: '法院意见',
+          hidden: true
+        },
+        {
+          key: 'association',
+          name: '关联案件的证据',
+          hidden: true
+        },
+      ],
+      rightList: [],//选择特征数组
+      rightName:'',
+      addFeatureVisibe:false,
+    };
+  },
+  watch: {
+    tableData() {
+      this.$nextTick(() => {
+        this.setHeight()
+      })
+    },
+    sign(val) {
+      if (val) {
+        this.$emit('evidence', this.tableData)
+      }
+    },
+    evidenceData(val) {
+      if (val) {
+        console.log(val);
+        this.tableData1 = val
+        this.TypeSelect(this.Type)
+      }
+
+    },
+  },
+  mounted() {
+    if (this.evidenceData) {
+      this.tableData1 = this.evidenceData
+      console.log(this.evidenceData)
+      this.TypeSelect(this.Type)
+    }
+    if (this.showBtnRight) {
+      this.getList(this.proofGroups,this.showBtnRight);
+      this.proofGroups.evidence = this.tableData1
+    }
+    // this.getList();
+    // this.getRight()
+  },
+  methods: {
+    // 查询陈述意见
+    getPoofArguments() {
+      console.log(this.tableData1);
+      let params = {
+        reportId  : this.reportId,
+        rightSort:this.tableData1[0].id,
+        proofId : this.tableData1[0].proffId,
+      }
+      this.$api.queryPoofArguments(params).then((res) => {
+        if (res.code == 200) {
+          res.data.forEach(item => {
+            let a = {
+              pRightName: item.rightName,
+              pContent: item.rightContent,
+              content: item.featureId,
+              featureName: item.featureName,
+              evidence:item.proofStr,
+              evidence2:item.arguments,
+            }
+            let b = {
+              featureId: item.featureId,
+              featureName: item.featureName,
+            }
+            this.tableData
+            // let index=this.tableData.findIndex(item1 => {
+            //   return item1.id==item.featureId
+            // })
+            // if (index!=-1) {
+              // this.tableData.push(a)
+              // this.rightList.push(b)
+            // }else{
+            //   this.tableData.splice(index,1,a)
+            //   this.rightList.push(index,1,b)
+            // }
+            
+          })
+        }
+      })
+    },
+    // 查已添加的特征
+    getRight() {
+      let params = {
+        reportId: this.reportId,
+        rightSort:this.tableData1[0].id
+      }
+      this.$api.getFeatureList(params).then((res) => {
+        if (res.code==200) {
+          this.rightList=res.data
+        }
+      })
+    },
+    querySearch(queryString, cb) {
+      // var restaurants = this.restaurants;
+      // var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants;
+      // 调用 callback 返回建议列表的数据
+      cb(this.features);
+    },
+    open(row, right) {
+      this.getList(row, right);
+      row.evidence = this.tableData1
+      this.getRight()
+      this.getPoofArguments()
+    },
+    setHeight() {
+      const offsetTop = window.innerHeight - this.$refs.table.$el.offsetTop - 40
+      this.height = offsetTop
+      const body = document.querySelector('.el-table__body')
+      if (!body) {
+        return false
+      }
+      const offsetBodyHeight = body.offsetHeight
+      //console.log( window.innerHeight,body,offsetBodyHeight,offsetTop)
+      if (this.tableData.length && offsetBodyHeight < offsetTop) {
+        this.tableHeight = offsetBodyHeight + 75
+      } else if (!this.tableData.length) {
+        this.tableHeight = null
+      } else {
+        this.tableHeight = offsetTop
+      }
+      this.tableHeight = this.tableHeight > 300 ? this.tableHeight : 300
+    },
+    //选中特征
+    getFunInfo(row, scope, type) {
+      let Index = this.row.findIndex(item => { return item.id == row.id })
+      if (Index < 0) {
+        row.$index = scope.$index
+        row.choseType = type
+        this.row.push(row)
+      } else {
+        this.row.splice(Index, 1)
+      }
+    },
+    //合并
+    merge() {
+      //console.log(this.row)
+      var sign = this.row[0].rightId
+      var allow = true
+      this.row.forEach(item => {
+        if (item.rightId != sign) {
+          allow = false
+          return false
+        }
+      });
+      if (!allow) {
+        this.$alert('不能合并不同权要的特征', '提示', {
+          confirmButtonText: '确定',
+          type: 'warning',
+          callback: action => {
+          }
+        })
+        return false;
+      }
+
+      //   this.keepSure=false
+      var str = ''
+      var strText = ""
+      if (this.row != []) {
+        let row = this.row.sort((aId, bId) => {
+          return aId.$index - bId.$index;
+        })
+        row.sort((aId, bId) => {
+          if (aId.$index - bId.$index != 1) {
+            allow = false
+          }
+        })
+        if (!allow) {
+          this.$alert('只能合并相邻的特征', '提示', {
+            confirmButtonText: '确定',
+            type: 'warning',
+            callback: action => {
+            }
+          })
+          return false;
+        }
+        for (var i = 0; i < this.row.length; i++) {
+          if (i < row.length - 1) {
+            str = str + row[i].content
+            strText = strText + row[i].evidence
+            let Index = this.tableData1.findIndex(item => { return item.id == row[i].id })
+            this.tableData1.splice(Index, 1)
+          } else if (i == row.length - 1) {
+            str = str + row[i].content
+            strText = strText + row[i].evidence
+          }
+        }
+      }
+      var a = this.tableData1.findIndex(item => {
+        return item.id == this.row[this.row.length - 1].id
+      })
+      this.tableData1[a].content = str
+      this.tableData1[a].evidence = strText
+      this.TypeSelect(this.Type)//调用显示权要
+      this.row = []
+      this.checkList = []
+    },
+    //拆分
+    split() {
+      if (this.row.length > 1) {
+        this.$alert('不能同时拆分多条特征', '提示', {
+          confirmButtonText: '确定',
+          type: 'warning',
+          callback: action => {
+          }
+        })
+        return false
+      }
+      //只对勾选的进行拆分
+      //   this.keepSure=false
+      this.checkList = []
+      this.row.forEach(ele => {
+        var Index = this.tableData1.findIndex(item => {
+          return item.id == ele.id
+        })
+        var a = Math.floor((Math.random() * 9999) + 1000);
+        let tab = {
+          pSignPatentNo: ele.pSignPatentNo,
+          pPatentId: ele.pPatentId,
+          pContent: ele.pContent,
+          pRightName: ele.pRightName,
+          pType: ele.pType,
+          pSort: ele.pSort,
+          pReportId: ele.pReportId,
+          pContentOut: ele.pContentOut,
+
+          id: ele.id + "a" + ele.$index + a,
+          signPatentNo: ele.signPatentNo,
+          contentOut: "",
+          content: "",
+          rightId: ele.rightId,
+          isFinal: ele.isFinal,
+          reportId: ele.reportId,
+          evidence: "",
+          evidence2: '',
+          rightName: ele.rightName,
+          rightType: ele.rightType,
+          splitBy: ele.splitBy,
+        }
+        // //console.log(tab)
+        this.tableData1.splice(Index + 1, 0, tab)
+      })
+      this.TypeSelect(this.Type)//调用显示权要
+      this.row = []
+    },
+    //添加陈述意见
+    addOpinion() {
+      if (this.row.length > 1) {
+        this.$alert('不能同时给多条特征添加陈述意见', '提示', {
+          confirmButtonText: '确定',
+          type: 'warning',
+          callback: action => {
+          }
+        })
+        return false
+      }
+      if (this.row[0].choseType != 0) {
+        this.$alert('请选择特征添加陈述意见', '提示', {
+          confirmButtonText: '确定',
+          type: 'warning',
+          callback: action => {
+          }
+        })
+        return false
+      }
+      this.checkList = []
+      var Index = this.tableData1.findIndex(item => {
+        return item.id == this.row[0].id
+      })
+      if (Index != -1) {
+        if (this.tableData1[Index].hasOwnProperty('evidence2')) {
+          this.tableData1[Index].evidence2.push({
+            argumentStr: ''
+          })
+        } else {
+          this.tableData1[Index].evidence2 = [
+            {
+              argumentStr: ''
+            }
+          ]
+        }
+
+        this.TypeSelect(this.Type)//调用显示权要
+        this.row = []
+      }
+
+    },
+    //添加特征
+    addFeature() {
+      this.addFeatureVisibe=true
+    },
+    closeFeature() {
+      this.addFeatureVisibe = false
+      this.rightName=''
+      this.getRight()
+    },
+    addRight() {
+      // this.rightList.push(this.rightName)
+      let params = {
+        content:this.rightName,
+        rightId:this.tableData1[0].id,//权要的id
+        reportId:this.reportId
+      }
+      this.$api.addSingleFeature(params).then((res) => {
+        if (res.code==200) {
+          this.$message.success('添加特征成功')
+          this.closeFeature()
+        }
+      })
+    },
+    addFeature1() {
+      if (this.row.length > 1) {
+        this.$alert('不能同时给多个权要添加特征', '提示', {
+          confirmButtonText: '确定',
+          type: 'warning',
+          callback: action => {
+          }
+        })
+        return false
+      }
+      if (this.row[0].choseType != 1) {
+        this.$alert('请选择权要添加特征', '提示', {
+          confirmButtonText: '确定',
+          type: 'warning',
+          callback: action => {
+          }
+        })
+        return false
+      }
+      this.checkList = []
+      var Index = this.tableData1.findLastIndex(item => {
+        return item.pRightName == this.row[0].pRightName
+      })
+      if (Index != -1) {
+        if (this.tableData1[Index].hasOwnProperty('content')) {
+          let arr = JSON.parse(JSON.stringify(this.tableData1[Index]))
+          arr.content = ''
+          arr.evidence2 = [
+            {
+              content: ''
+            }
+          ]
+          this.tableData1.splice(Index + 1, 0, arr)
+        } else {
+          this.$set(this.tableData1[Index], 'content', '')
+          var evidence2 = [
+            {
+              content: ''
+            }
+          ]
+          this.$set(this.tableData1[Index], 'evidence2', evidence2)
+        }
+
+        this.TypeSelect(this.Type)//调用显示权要
+        this.row = []
+      }
+      console.log(this.tableData1)
+    },
+    //获取每个元素所需合并的行数
+    getSpanArr(data) {
+      this.row = []
+      this.mergeArr.forEach((key, index1) => {
+        let count = 0;
+        this.mergeObj[key] = [];
+        data.forEach((item, index) => {
+          if (index === 0) {
+            this.mergeObj[key].push(1);
+          } else {
+            if (item[key] === data[index - 1][key] && item[key] !== 'evidence') {
+              this.mergeObj[key][count] += 1;
+              this.mergeObj[key].push(0);
+            } else {
+              count = index;
+              this.mergeObj[key].push(1);
+            }
+          }
+        })
+      })
+    },
+    //合并行
+    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
+      if (this.mergeArr.indexOf(column.property) !== -1) {
+        if (this.mergeObj[column.property][rowIndex]) {
+          return [this.mergeObj[column.property][rowIndex], 1]
+        } else {
+          return [0, 0];
+        }
+      }
+    },
+    openField() {
+      this.$refs.tableField.open(this.tableField)
+    },
+    getTableField(val) {
+      this.tableField = val
+      this.refreshTable()
+    },
+    refreshTable() {
+      this.refreshData = false
+      this.$nextTick(() => {
+        this.refreshData = true
+      })
+    },
+    //拆分权要
+    getList(row, right) {
+      console.log(row,right);
+      this.tableData1 = [
+        {
+          pRightName: right.rightName,
+          id: right.sort,
+          pType: 0,
+          pContent: right.content,
+          // 文献ID
+          proffId:row.id
+        },
+      ]
+      this.TypeSelect(this.Type)
+      console.log(this.tableData1,right);
+      // this.tableData1 = localStorage.patent
+    },
+    keep() {
+      // console.log(this.tableData,this.tableData1);
+      var params=[]
+      for (let i = 0; i < this.tableData.length; i++){
+        params[i] = {
+          reportId: this.reportId,
+          rightSort: this.tableData[i].id,
+          featureId: this.tableData[i].content,
+          proofStr: this.tableData[i].evidence,
+          proofStrId: 0,
+          proofId: this.tableData[i].proffId,
+          arguments: this.tableData[i].evidence2,
+        }
+      }
+      // console.log(params);
+        this.$api.addOrUpdatePoofArguments(params).then((res) => {
+          if (res.code ==200) {
+            this.$message.success('添加成功')
+            this.getPoofArguments()
+          }
+        })
+        // localStorage.patent = JSON.stringify(this.tableData1)
+    },
+    // 条件选择下拉框
+    splitTypeSelect(event) {//拆主权要
+      this.splitType1 = event;
+      this.splitPatentRight()
+    },
+    splitBySelect(event) {//按符号拆分
+      //console.log(event);
+      this.splitBy1 = event;
+      this.splitPatentRight();
+    },
+    TypeSelect(event) {//显示
+      this.typeArr = [];
+      if (event == 1) {
+        this.typeArr.push(1);
+      } else {
+        this.typeArr.push(1, 0);
+      }
+      this.tableData = this.tableData1.filter(item => {
+        return this.typeArr.includes(item.pType)
+      })
+      this.getSpanArr(this.tableData)
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+.innerTable .item {
+  /* min-width:200px; */
+  padding: 20px 0;
+  margin: 0;
+  display: flex;
+  justify-content: flex-start;
+  align-items: center;
+  // height: 130px;
+  line-break: normal;
+  overflow: auto;
+  border-bottom: 1px solid #EBEEF5;
+}
+
+.innerTable .item:last-child:first-child {
+  //item 即是最后一个元素 又是第一个元素
+  height: 100%;
+}
+
+.innerTable .item:nth-child(1) {
+  border-bottom: 1px solid #EBEEF5;
+}
+
+.innerTable .item:last-child {
+  border-bottom: none;
+}
+</style>

+ 86 - 0
RMS-FrontEnd/src/views/report/InvalidResponse/components/InvalidFeatures.vue

@@ -0,0 +1,86 @@
+<template>
+  <div>
+    <el-table :data="featuresList" style="height: 200px;overflow: auto;">
+      <el-table-column prop="index" label="#" width="50px" align="center">
+        <template slot-scope="scope">
+          <div>
+            <el-checkbox :label="scope.row.label" @change="changeSelect(scope.row)"
+              :checked="selected.indexOf(scope.row.features) !== -1">
+              <span>{{ (scope.$index + 1) }}</span>
+            </el-checkbox>
+          </div>
+        </template>
+      </el-table-column>
+
+      <el-table-column prop="features" label="特征" align="center">
+        <template slot-scope="scope">
+          {{ scope.row.features }}
+        </template>
+      </el-table-column>
+    </el-table>
+    <div style="display:flex;justify-content: flex-end;margin-top:10px">
+      <el-button type="primary" size="small" @click="submit">确定</el-button>
+      <el-button type="primary" size="small" @click="cancel">取消</el-button>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  props:['patentNo','rightFeaturesList'],
+  data() {
+    return {
+      featuresList:this.rightFeaturesList,
+      selected:[],
+      proofGroups: [],
+    }
+  },
+  watch: {
+    rightFeaturesList(val) {
+      this.featuresList=val
+    }
+  },
+  computed: {},
+  mounted() {
+   
+  },
+  methods: {
+    
+    submit() {
+      if (this.proofGroups.length == 0) {
+        this.$message.error('请选择后再添加')
+        return false
+      }
+      
+      // console.log(this.form,this.proofGroups);
+      let a = {
+        proofGroups: this.proofGroups,
+        close:false,
+      }
+      this.$emit('checkFeatures',a)
+      this.cancel()
+    },
+    cancel() {
+      // this.proofGroups = []
+      this.featuresList=[]
+      this.selected = []
+      this.$emit('closeFeatures',false)
+    },
+    // change选中
+    changeSelect(row) {
+      console.log(row);
+      const index = this.selected.indexOf(row.features)
+      if (index === -1) {
+        this.selected.push(row.features)
+        this.proofGroups.push(row)
+      } else {
+        this.selected.splice(index, 1)
+        this.proofGroups.splice(index, 1)
+      }
+      console.log(this.proofGroups,this.selected);
+    },
+  },
+}
+</script>
+
+<style lang="scss" scoped></style>

+ 750 - 0
RMS-FrontEnd/src/views/report/InvalidResponse/components/InvalidIndex.vue

@@ -0,0 +1,750 @@
+<template>
+  <!-- 无效理由和证据 -->
+  <div @click="clickBody">
+    <div style="display:flex;justify-content: flex-end;margin-bottom:10px">
+      <el-button type="primary" size="small" @click="addInvalid">添加无效证据</el-button>
+      <el-button type="primary" size="small" @click="openField">显示栏位管理</el-button>
+    </div>
+    
+    <el-table border v-if="refreshData" :data="tableData" :span-method="objectSpanMethod" :height="tableHeight" >
+      <el-table-column prop="index" label="序号" align="center">
+        <template slot-scope="scope">
+          <div>
+            {{ scope.$index + 1 }}
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column v-for="item in tableField.filter(item => !item.hidden)"  :key="item.key" :label="item.name" :prop="item.key" align="center">
+        <template slot-scope="scope">
+            <!-- <el-input v-model='scope.row[item.key]' type="textarea" 
+               v-if='(scope.row.index == tabRowIndex && scope.column.index == tabColumnIndex) && ["proofStr","argumentStr","comOptions","courtOptions"].includes(scope.column.property)'
+               @blur='inputBlur(scope.row)' size="mini" ></el-input> -->
+            <div v-if="item.key == 'proofStr'">
+              <span v-if="scope.row.proofGroups.length > 0">
+                <p v-for="(i, index) in scope.row.proofGroups" :key="index">
+                  <span v-for="(y, index1) in i.proofs" :key="y.label">
+                    <el-popover placement="top-start" width="800" trigger="hover" :close-delay="100000" ref="popoverHover">
+                      <div>
+                        <p><span>描述:</span><span>{{ y.description }}</span></p>
+                        <div>
+                          <Invalid-Evidence ref="invalid" :sign="sign" @evidence="getEvidence" :evidence="showPopover(y,scope.row.content)" :reportId="reportId" :patentNo="signPatentNo"></Invalid-Evidence>
+                        </div>
+                      </div>
+                      <el-link @click="check(item, y)" slot="reference">D{{ y.sort }}</el-link>
+                      <!-- <i class="el-icon-arrow-down el-icon--right"></i> -->
+                      <!-- <i class="el-icon-edit"  @click.stop="visibleIcons"></i> -->
+                    </el-popover>
+                    <span v-if="index1 < i.proofs.length - 1"> + </span>
+                  </span>
+                  <el-popover placement="top-start" width="200" trigger="hover">
+                    <div>
+                      <p><span>描述:</span><span>{{ i.description }}</span></p>
+                      <p><span>陈述意见:</span><span>{{ i.argumentStr }}</span></p>
+                    </div>
+                    <span class="check" slot="reference">
+                      <i class="el-icon-view chakan"></i>
+                      <i class="el-icon-circle-close guanbi" @click="delCompose(scope.row.proofGroups, index,scope.row)"></i>
+                    </span>
+                  </el-popover>
+                </p>
+              </span>
+              <span>
+                {{ scope.row[item.key] }}
+              </span>
+            </div>
+            <div v-else>{{ getData(scope.row,item.key) }}</div>
+          <!-- invalidName -->
+          <!-- <div v-if="scope.row.invalidName == 1 || scope.row.invalidName == 2">
+            <span v-if="item.key == 'invalidName'">{{ invalidList.find(item => item.value == scope.row.invalidName).label }}</span>
+            <span v-else v-html="scope.row[item.key]"></span>
+          </div>
+          <div v-else>
+            <span v-if="item.key != 'proofStr' || scope.row.proofGroups.length == 0">
+              <span v-if="item.key == 'invalidName'">{{ invalidList.find(item => item.value == scope.row.invalidName).label }}</span>
+              <span v-else v-html="scope.row[item.key]"></span>
+            </span>
+            <span v-else-if="scope.row.proofGroups.length > 0">
+              <p v-for="(i, index) in scope.row.proofGroups" :key="index">
+                <span v-for="(y, index1) in i.proofGroups" :key="y.label">
+                  <el-popover placement="top-start" width="800" trigger="hover">
+                    <div>
+                      <p><span>描述:</span><span>{{ y.description }}</span></p>
+                      <div>
+                        <Invalid-Evidence ref="invalid" :sign="sign" @evidence="getEvidence"
+                          :evidenceData="y.evidence"></Invalid-Evidence>
+                      </div>
+                    </div>
+                    <el-link @click="check(item, y)" slot="reference">{{ y.label }}</el-link>
+                  </el-popover>
+                  <span v-if="index1 < i.proofGroups.length - 1"> + </span>
+                </span>
+                <el-popover placement="top-start" width="200" trigger="hover">
+                  <div>
+                    <p><span>描述:</span><span>{{ i.description }}</span></p>
+                    <p><span>陈述意见:</span><span>{{ i.argumentStr }}</span></p>
+                  </div>
+                  <span class="check" slot="reference">
+                    <i class="el-icon-view chakan"></i>
+                    <i class="el-icon-circle-close guanbi" @click="delCompose(scope.row.proofGroups, index)"></i>
+                  </span>
+                </el-popover>
+              </p>
+            </span>
+          </div> -->
+        </template>
+      </el-table-column>
+      <el-table-column  label="操作" align="center" width="180px">
+        <template slot-scope="scope">
+          <div>
+            <el-button @click.native.prevent="editRow(scope.row)" type="text" size="small"> 编辑 </el-button>
+            <el-button @click.native.prevent="deleteRow(scope.row)" type="text" size="small" style="color: red;"> 删除 </el-button>
+          </div>
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- <div style="text-align: center;margin-top: 10px;">
+      <el-pagination background layout="total, prev, pager, next, jumper" :current-page.sync="queryParams.current"
+        :page-size.sync="queryParams.size" @current-change="handleCurrentChange" :total="queryParams.total">
+      </el-pagination>
+    </div> -->
+    <Table-Field ref="tableField" :reportId="reportId" @update="getTableField"></Table-Field>
+
+    <el-dialog :title="title" :visible.sync="visible" width="800px" :before-close="close">
+      <div>
+        <el-form :model="form" ref="form" :rules='rules' label-width="100px" label-position="left">
+          <el-form-item label="无效理由:" prop="invalidName">
+            <el-select v-model="form.invalidName" placeholder="请选择" style="width:100%">
+              <el-option v-for="item in invalidList" :key="item.value" :label="item.label" :value="item.value">
+              </el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="涉及内容:" prop="content">
+            <!-- 说明书为0,权要为权要id,字段coutent -->
+            <span v-if="form.invalidName == 1">说明书</span>
+            <el-select v-else v-model="form.content" placeholder="请选择" style="width:100%" @change="contentChange">
+              <el-option v-for="item in rightList" :key="item.sort" :label="item.rightName" :value="item.sort">
+              </el-option>
+            </el-select>
+          </el-form-item>
+          <template v-if="form.invalidName == 0 && (form.content == 0 || form.content) ">
+            <!-- features -->
+            <el-form-item label="选择特征:">
+              <span v-for="item in form.features" :key="item.id" style="margin-right:10px">{{ item.features }}</span>
+              <span  v-if="rightFeaturesList && rightFeaturesList.length > 0"><el-link type="primary" @click="showFeatures = true">添加</el-link></span>
+              <div v-else>
+                <span >{{ rightList.find(item => item.sort == this.form.content).content }}</span>
+              </div>
+              <div v-if="showFeatures">
+                <InvalidFeatures :patentNo="signPatentNo" :rightFeaturesList="rightFeaturesList" @checkFeatures="checkFeatures" @closeFeatures="closeFeatures"></InvalidFeatures>
+              </div>
+            </el-form-item>
+          </template>
+          <el-form-item label="相关证据:" v-if="form.content == 0 || form.content || form.invalidName">
+            <span v-if="form.invalidName == 0 || form.invalidName == 1">
+              <el-input type="text" v-model="form.proofStr" placeholder="请输入相关证据" style="width:100%"></el-input>
+            </span>
+            <div v-else>
+              <span v-for="(item, index) in form.proofGroups" :key="index" style="margin-right:10px">
+                <span v-for="(i, index1) in (item.proofs)" :key="i.label">
+                  <!-- {{ i }} -->
+                  <el-popover placement="top-start" width="800" trigger="hover" :close-delay="100000" ref="popoverHover">
+                    <div>
+                      <p><span>描述:</span><span>{{ i.description }}</span></p>
+                      <div>
+                        <!--  -->
+                        <Invalid-Evidence ref="invalid" :patentNo="signPatentNo"  :evidence="showPopover(i)" :reportId="reportId" :sign="sign" @evidence="getEvidence"></Invalid-Evidence>
+                      </div>
+                    </div>
+                    <el-link v-if="i.sort" slot="reference">D{{ i.sort }}</el-link>
+                    <el-link v-else slot="reference">{{ i.sortStr }}</el-link>
+                  </el-popover>
+                  <span v-if="index1 < item.proofs.length - 1">+</span>
+                </span>
+                <el-popover placement="top-start" width="200" trigger="hover">
+                  <div>
+                    <p><span>描述:</span><span>{{ item.description }}</span></p>
+                    <p><span>陈述意见:</span><span>{{ item.argumentStr }}</span></p>
+                  </div>
+                  <span class="check" slot="reference">
+                    <i class="el-icon-view chakan"></i>
+                    <i class="el-icon-circle-close guanbi" @click="delCompose(form.proofGroups, index)"></i>
+                  </span>
+                </el-popover>
+
+              </span><span><el-link type="primary" @click="showBtn()">添加</el-link></span>
+              <template v-if="show" >
+                <div>
+                  <el-table :data="EvidenceList" style="overflow: auto;" height='300'>
+                    <el-table-column prop="index" label="#" width="50px" align="center">
+                      <template slot-scope="scope">
+                        <div>
+                          <el-checkbox :label="scope.row.id" @change="changeSelect(scope.row)"
+                            :checked="selected.indexOf(scope.row.id) !== -1">
+                            <span>{{ (scope.$index + 1) }}</span>
+                          </el-checkbox>
+                        </div>
+                      </template>
+                    </el-table-column>
+                    <el-table-column prop="sortStr" label="证据" align="center">
+                      <template slot-scope="scope">
+                        <!-- 打开证据弹窗,添加证据文献中的证据 -->
+                        <div>
+                          {{ scope.row.sortStr }} <span style="float:right" @click="openEvidence(scope.row)"><el-link
+                              type="primary">详情</el-link></span>
+                        </div>
+                      </template>
+                    </el-table-column>
+                    <el-table-column prop="description" label="描述" align="center">
+                      <template slot-scope="scope">
+                        <div>
+                          <el-input type="textarea" :rows="1" v-model="scope.row.description"></el-input>
+                        </div>
+                      </template>
+                    </el-table-column>
+                  </el-table>
+                  <div style="display:flex;align-items:center">
+                    <p style="margin:0">描述:</p>
+                    <div style="flex:1">
+                      <el-input type="textarea" :rows="1" v-model="description"></el-input>
+                    </div>
+                  </div>
+                  <div style="display:flex;align-items:center">
+                    <p style="margin:0">陈述意见:</p>
+                    <div style="flex:1">
+                      <el-input type="textarea" :rows="1" v-model="argumentStr"></el-input>
+                    </div>
+                  </div>
+                  <div style="display:flex;justify-content: flex-end;margin-top:10px">
+                    <el-button type="primary" size="small" @click="submit">确定</el-button>
+                    <el-button type="primary" size="small" @click="cancel">取消</el-button>
+                  </div>
+                </div>
+              </template>
+            </div>
+          </el-form-item>
+          <el-form-item label="陈述意见:">
+            <el-input type="textarea" :rows="1" v-model="form.argumentStr"></el-input>
+            <!-- <div style="width:100%;outline: #dcdfe6;border:1px solid #DCDFE6;border-radius:5px;min-height:50px;background:white" id="preview" contenteditable="true" 
+                            v-html="form.argumentStr"  @input="saveValue($event.target.innerHTML)"  @click="saveValue($event.target.innerHTML)"> 
+                        </div> -->
+          </el-form-item>
+          <el-form-item label="复审委意见:">
+            <el-input type="textarea" :rows="1" v-model="form.comOptions"></el-input>
+            <!-- <div style="width:100%;outline: #dcdfe6;border:1px solid #DCDFE6;border-radius:5px;min-height:50px;background:white" id="preview" contenteditable="true" 
+                            v-html="form.comOptions"  @input="saveValue($event.target.innerHTML)"  @click="saveValue($event.target.innerHTML)"> 
+                        </div> -->
+          </el-form-item>
+          <el-form-item label="法院意见:">
+            <el-input type="textarea" :rows="1" v-model="form.courtOptions"></el-input>
+            <!-- <div style="width:100%;outline: #dcdfe6;border:1px solid #DCDFE6;border-radius:5px;min-height:50px;background:white" id="preview" contenteditable="true" 
+                            v-html="form.courtOptions"  @input="saveValue($event.target.innerHTML)"  @click="saveValue($event.target.innerHTML)"> 
+                        </div> -->
+          </el-form-item>
+        </el-form>
+      </div>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="close">取 消</el-button>
+        <el-button type="primary" @click="sure">确 定</el-button>
+      </div>
+    </el-dialog>
+    <el-dialog title="添加证据" :visible.sync="EvidenceVisible" width="1000px" :before-close="closeEvidence" append-to-body>
+      <Invalid-Evidence ref="invalid" :reportId="reportId" :patentNo="signPatentNo" :sign="sign" @evidence="getEvidence"></Invalid-Evidence>
+    </el-dialog>
+  </div>
+</template>
+<script>
+import TableField from './TableField.vue'
+import InvalidEvidence from './InvalidEvidence.vue'
+import InvalidFeatures from './InvalidFeatures.vue'
+export default {
+  props: ['reportId','signPatentNo','reportType'],
+  components: {
+    TableField,
+    InvalidEvidence,
+    InvalidFeatures,
+  },
+  data() {
+    const contentRule = (rule, value, callback) => {
+      if (this.form.invalidName == 1) {
+        callback()
+      } else {
+        if (value === '') {
+          callback(new Error('请选择涉及内容'))
+        } else {
+          callback()
+        }
+      }
+      
+    }
+    return {
+      sign: false,
+      description: '',
+      argumentStr: '',
+      show: false,
+      showFeatures: false,
+      selected: [],
+      form: {
+        proofGroups: []
+      },
+      visible: false,
+      title:'',
+      EvidenceVisible: false,
+      refreshData: true,
+      tableData: [],
+      tableField: [
+        {
+          key: 'invalidName',
+          name: '无效理由',
+          hidden: false
+        },
+        {
+          key: 'court',
+          name: '涉及内容',
+          hidden: false
+        },
+        {
+          key: 'proofStr',
+          name: '相关证据',
+          hidden: false
+        },
+        {
+          key: 'argumentStr',
+          name: '陈述意见',
+          hidden: false
+        },
+        {
+          key: 'comOptions',
+          name: '复审委意见',
+          hidden: true
+        },
+        {
+          key: 'courtOptions',
+          name: '法院意见',
+          hidden: true
+        },
+      ],//显示栏位管理
+      invalidList: [
+        {
+          id: 0,
+          label: '权利要求不清楚',
+          value: 0
+        },
+        {
+          id: 1,
+          label: '说明书公开不充分',
+          value: 1
+        },
+        {
+          id: 2,
+          label: '不具备创造性',
+          value: 2
+        },
+        {
+          id: 3,
+          label: '不具备新颖性',
+          value: 3
+        },
+      ],//无效理由数组
+      rightList: [],//权要数组
+      proofGroups: [],//子组件新增的数据
+      EvidenceList: [],//新增证据数组
+      rules: {
+        invalidName:[ { required: true, message: '请选择无效理由', trigger: 'change' }],
+        content:[{ required: true,validator:contentRule, trigger: 'change' }],
+      },
+      showBtnRight: {},
+      rightFeaturesList: [],
+      mergeObj: {},
+      mergeArr: ['invalidName'],//解释
+      tableHeight: '',
+      // tabRowIndex:null,//行角标
+      // tabColumnIndex:null,//列角标
+    }
+  },
+  watch: {
+    
+  },
+  async mounted() {
+    // 请求专利权要
+    await this.getPatentByPatentNo()
+    // 请求证据文献
+    this.getQueryProofList()
+    // 请求无效理由和证据
+    await this.getInvalidReason()
+    // 请求划词特征
+    // this.getFeaturesList()
+    this.getHeight()
+  },
+  methods: {
+    clickBody(event) {
+      if (event.target === document.body || document.body.contains(event.target)) {
+        for (let i = 0; i < this.$refs.popoverHover.length; i++){
+          this.$refs.popoverHover[i].doClose()
+        }
+      }
+    },
+      // 获取点击的单元格位置
+    // getCell(row, column, cell, event) {
+    //   this.tabRowIndex = row.index
+    //   this.tabColumnIndex = column.index
+    // },
+    // 把角标赋值给行和列,赋值后可以直接拿到点击位置的坐标
+    // getRowColumn({ row, column, rowIndex, columnIndex }) {
+    //   row.index = rowIndex
+    //   column.index = columnIndex
+    // },
+    // inputBlur(val) {
+    //   // 把输入框隐藏
+    //   this.tabRowIndex = null
+    //   this.tabColumnIndex = null
+    //   val.reportId=this.reportId
+    //   this.$api.updatelnvalidReason(val).then((res) => {
+    //     if (res.code == 200) {
+    //       this.$message.success('更新成功')
+    //       this.getInvalidReason()
+    //     }
+    //   })
+    //   // 发请求把修改的数据发送给后台
+    //   // this.subForm()
+    // },
+    // table高度
+    getHeight() {
+      let a = document.body.clientHeight
+      this.tableHeight=a-300
+    },
+    // 回显
+    getData(row,key) {
+      if (key == 'invalidName') {
+        return this.invalidList.find(item => item.value ==row.invalidName).label
+      }else if (key == 'court') {
+        if (row.content == -1) {
+          return '说明书'
+        } else if (row.content != 0 && !row.content) {
+          return '说明书'
+        } else {
+          return '权要'+(row.content + 1)
+        }
+      } else {
+        return row[key]
+      }
+    },
+   async getInvalidReason() {
+      await this.$api.queryInvalidReason({reportId:this.reportId}).then((res) => {
+        if (res.code == 200) {
+          var a = [...new Set(res.data.map(item => item.invalidName))]
+         this.tableData=res.data.sort((x,y)=>{
+            return a.indexOf(x.invalidName) - a.indexOf(y.invalidName)
+        })
+          // this.tableData=res.data
+          this.getSpanArr(this.tableData) 
+        }
+      })
+    },
+    //获取每个元素所需合并的行数
+    getSpanArr(data) {
+      this.mergeArr.forEach((key, index1) => {
+        let count = 0;
+        this.mergeObj[key] = [];
+        data.forEach((item, index) => {
+          if (index === 0) {
+            this.mergeObj[key].push(1);
+          } else {
+            if (item[key] === data[index - 1][key] && item[key] !== 'evidence') {
+              this.mergeObj[key][count] += 1;
+              this.mergeObj[key].push(0);
+            } else {
+              count = index;
+              this.mergeObj[key].push(1);
+            }
+          }
+        })
+      })
+    },
+     //合并行
+     objectSpanMethod({ row, column, rowIndex, columnIndex }) {
+      if (this.mergeArr.indexOf(column.property) !== -1) {
+        if (this.mergeObj[column.property][rowIndex]) {
+          return [this.mergeObj[column.property][rowIndex], 1]
+        } else {
+          return [0, 0];
+        }
+      }
+    },
+    // 划词特征
+    getFeaturesList() {
+      this.rightFeaturesList = [
+        // {features:'特征1',id:0},
+        // {features:'特征2',id:1},
+        // {features:'特征3',id:2},
+      ]
+    },
+    checkFeatures({proofGroups,close}) {
+      this.form.features = proofGroups
+      this.showFeatures=close
+      console.log(proofGroups,close);
+    },
+    closeFeatures(val) {
+      this.showFeatures=val
+    },
+    // 证据组合hover
+    showBtn() {
+      this.getQueryProofList()
+      this.show=true
+    },
+    // 查询专利权要
+   async getPatentByPatentNo() {
+      let params = {patentNo: this.signPatentNo,}
+     await this.$api.getFeatureRights(params).then((res) => {
+        if (res.code==200) {
+          this.rightList=res.data
+        }
+      })
+    },
+    getQueryProofList() {
+      let params = {
+        reportId:this.reportId,
+        signPatentNo:this.signPatentNo,
+        size: 99,
+        current: 1,
+      }
+      this.$api.queryProof(params).then((res) => {
+        if (res.code==200) {
+          this.EvidenceList=res.data
+        }
+      }).catch((error) => {
+        
+      })
+    },
+    //删除证据组合
+    delCompose(data, index,row) {
+      if (row && row.id) {
+        row.proofGroups.splice(index, 1)
+        this.form = row
+        this.form.isEdit=true
+        this.sure()
+      } else {
+         data.splice(index, 1)
+      }
+      
+    },
+    //打开添加证据弹窗
+    openEvidence(row) {
+      // console.log(row, rightList, contentSort);
+      let right = this.rightList.find(item => { return item.sort == this.form.content })
+      this.EvidenceVisible = true
+      this.$nextTick(() => {
+        this.$refs.invalid.open(row,right)
+      })
+    },
+    //关闭添加证据弹窗
+    closeEvidence() {
+      this.EvidenceVisible = false
+      // console.log(this.form,this.proofGroups);
+    },
+    //获取子组件传回来的证据、
+    getEvidence(val) {
+      // console.log(val);
+      // this.proofGroups
+    },
+    //添加证据组合
+    submit() {
+      if (this.proofGroups.length == 0) {
+        this.$message.error('请选择后再添加')
+        return false
+      }
+      this.sign = true
+      var a = {
+        description: this.description,
+        argumentStr: this.argumentStr,
+        proofs: this.proofGroups,
+        proofIds: this.selected,
+      }
+      console.log(this.form,this.proofGroups);
+      
+      this.form.proofGroups.push(a)
+      this.cancel()
+    },
+    //取消
+    cancel() {
+      this.EvidenceList = [],
+      this.selected = []
+      this.proofGroups = []
+      this.description = ''
+      this.argumentStr = ''
+      this.show = false
+    },
+    // 涉及内容的change
+    contentChange() {
+      this.cancel()
+      this.form.proofGroups = []
+      localStorage.removeItem('patent')
+    },
+    //选择证据
+    changeSelect(row) {
+      // this.showBtnRight = this.rightList.find(item => { return item.sort == this.form.content })
+      const index = this.selected.indexOf(row.id)
+      if (index === -1) {
+        this.selected.push(row.id)
+        this.proofGroups.push(row)
+      } else {
+        this.selected.splice(index, 1)
+        this.proofGroups.splice(index, 1)
+      }
+    },
+    // popover
+    showPopover(val,id) {
+      // console.log(val,this.rightList,id);
+      
+      return {
+        row: val,
+        right:this.rightList.find(item => { return item.sort == id })  || this.rightList.find(item => { return item.sort == this.form.content }) 
+      }
+    },
+    //下拉框隐藏时获取证据
+    getEvidence(val) {
+      if (!val) {
+        this.form.proofStr = this.form.proofGroups.join('+')
+      }
+    },
+    //查看证据文献
+    check(item,val) {
+      // console.log('11', item, val);
+      var router = this.$router.resolve({
+        path: '/ContrastIndex/' + val.id,
+        // query: {
+        //   patentNo: val.patentNo,
+          
+        // }
+      })
+      let params = this.$s.getSession('params')
+      params.type=7
+      params.reportType=7
+      params.aid=val.id
+      params.signPatentNo=this.signPatentNo
+      params.reportId=this.reportId
+      this.$s.setSession('params', params)
+      window.open(router.href, '_blank');
+    },
+    //打开显示栏位管理弹窗
+    openField() {
+      this.$refs.tableField.open(this.tableField)
+    },
+    //获取表格最新显示栏位
+    getTableField(val) {
+      this.tableField = val
+      this.refreshTable()
+    },
+    //重置表格
+    refreshTable() {
+      this.refreshData = false
+      this.$nextTick(() => {
+        this.refreshData = true
+      })
+    },
+    //打开添加无效理由和证据弹窗
+    addInvalid() {
+      this.title='添加无效理由和证据'
+      this.visible = true
+    },
+    //关闭添加无效理由和证据弹窗
+    close() {
+      this.form =  {
+        proofGroups: []
+      },
+      this.cancel()
+      this.$refs.form.resetFields()
+      this.visible = false
+    },
+    //确认添加无效理由和证据
+    sure() {
+      // this.form.features = this.rightList.find(item => { return item.id == this.form.content }).content
+      // console.log(this.form);
+      // 为说明书时content为-1
+      if (this.form.invalidName == 1) {
+        this.form.content == -1
+      }
+      this.form.reportId = this.reportId
+      if (this.form.isEdit) {
+        this.sureEdit()
+      } else {
+        this.$refs.form.validate((valid) => {
+          if (valid) {
+            // this.tableData.push(this.form)
+            // this.tableData[0].reportId=this.reportId
+            // console.log(this.form);
+            if (!this.form.id) {
+              this.$api.addInvalidReason(this.form).then((res) => {
+                if (res.code == 200) {
+                  // console.log(this.tableData,this.form);
+                  this.getInvalidReason()
+                  this.refreshTable()
+                  this.close()
+                }
+              })
+            } else {
+             this.sureEdit()
+            }
+          } else {
+            this.$message.error('请填写信息')
+            return false;
+          }
+        });
+      }
+    },
+    sureEdit() {
+      console.log(this.form);
+      this.$api.updatelnvalidReason(this.form).then((res) => {
+        if (res.code == 200) {
+          this.$message.success('更新成功')
+          this.getInvalidReason()
+          this.refreshTable()
+          this.close()
+        }
+      })
+    },
+    deleteRow(row) {
+      let id = [
+        row.id,
+      ]
+      this.$api.deleteInvalidReason(id).then((res) => {
+        if (res.code == 200) {
+          this.$message.success('删除成功')
+          this.getInvalidReason()
+        }
+      })
+    },
+    editRow(row) {
+      this.title="编辑无效理由和证据"
+      this.form=row
+      this.visible = true
+      console.log(row);
+    },
+    handleCurrentChange(val) {
+      this.queryParams.current = val
+      this.getInvalidReason()
+    }
+  },
+}
+</script>
+<style lang="scss" scoped>
+// .check:hover::after{
+//     content:'X'
+// }
+.check:hover {
+  .chakan {
+    display: none;
+  }
+
+  .guanbi {
+    display: inline-block;
+  }
+}
+
+.check {
+  margin-left: 5px;
+
+  .guanbi {
+    display: none;
+  }
+}
+</style>

+ 131 - 0
RMS-FrontEnd/src/views/report/InvalidResponse/components/TableField.vue

@@ -0,0 +1,131 @@
+<template>
+  <div class="">
+    <el-dialog title="显示栏位管理" :visible.sync="visible" width="650px" append-to-body destroy-on-close :before-close="close" top="10vh">
+      <div class="project-table-field">
+        <el-transfer
+            class="transfer"
+            v-model="selected"
+            filterable
+            :filter-method="filterMethod"
+            :titles="['未选择', '已选择']"
+            :button-texts="['', '']"
+            :format="{ noChecked: '${total}', hasChecked: '${checked}/${total}' }"
+            @right-check-change="rightCheckChange"
+            @change="handleChange2"
+            :data="dataList">
+          <span slot-scope="{ option }">{{ option.name }}</span>
+          <div slot="left-footer"></div>
+          <div class="transfer-footer" slot="right-footer">
+            <el-button @click="handleQueryOrder(-1)" type="primary" size="small" icon="el-icon-top" circle></el-button>
+            <el-button @click="handleQueryOrder(1)" size="small" icon="el-icon-bottom" circle></el-button>
+          </div>
+        </el-transfer>
+      </div>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="close">取 消</el-button>
+        <el-button type="primary" @click="submit" :loading="btnLoading">确 定</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+
+export default {
+  props:['reportId'],
+  data() {
+    return {
+      visible: false,
+      dataList: [],
+      btnLoading: false,
+      selected: [],
+      rightSelect: [],
+    }
+  },
+  mounted() {
+  },
+  methods: {
+    handleQueryOrder(order) {
+      this.rightSelect.map(item => {
+        const index = this.selected.indexOf(item)
+        const cIndex = index + order
+        if (cIndex < 0 || cIndex >= this.selected.length) {
+          return false
+        }
+        let current = this.dataList.find(item => item.key === this.selected[index])
+        let exchange = this.dataList.find(item => item.key === this.selected[cIndex])
+        current.order = current.order + order
+        exchange.order = exchange.order + (order === -1 ? 1 : -1)
+        this.dataList.sort((a, b) => {
+          return a.order - b.order
+        })
+        const temp = this.selected[index]
+        this.selected[index] = this.selected[cIndex] 
+        this.selected[cIndex] = temp
+      })
+    },
+    handleChange2() {
+      let order = 1
+      for (let i = 0; i < this.selected.length; i++) {
+        const index = this.dataList.map(item => item.key).indexOf(this.selected[i])
+        this.dataList[index].order = order++
+      }
+    },
+    filterMethod(query, item) {
+      return item.name.indexOf(query) !== -1
+    },
+    rightCheckChange(data) {
+      this.rightSelect = data
+    },
+    open(dataList) {
+      console.log(dataList)
+      this.dataList = JSON.parse(JSON.stringify(dataList))
+      this.selected = this.dataList.filter(item => !item.hidden).map(item => item.key)
+      this.visible = true
+    },
+    close() {
+      this.visible = false
+      this.$emit('close')
+    },
+    submit() {
+      this.dataList.map(item => item.hidden = this.selected.indexOf(item.key) === -1)
+      this.$emit('update', this.dataList)
+      this.visible = false
+        this.btnLoading = false
+      // let data = {
+      //   data: this.dataList,
+      //   projectId: 0,
+      //   type: 'project',
+      // }
+      // this.btnLoading = true
+      // this.$api.updateUserSettingField(data).then(response => {
+      //   this.$emit('update', response.data)
+      //   this.visible = false
+      //   this.btnLoading = false
+      //   this.$message.success('操作成功')
+      // }).catch(error => {
+      //   this.btnLoading = false
+      // })
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+.project-table-field {
+  text-align: center;
+  .transfer {
+    text-align: left;
+    display: inline-block;
+  }
+  .el-transfer-panel__body {
+    height: 400px;
+  }
+  .el-transfer-panel__list.is-filterable {
+    height: 350px;
+  }
+  .transfer-footer {
+    margin: 5px;
+  }
+}
+</style>

+ 433 - 0
RMS-FrontEnd/src/views/report/InvalidResponse/components/addOpinion.vue

@@ -0,0 +1,433 @@
+<template>
+  <div>
+    <el-dialog  :title="title"  :visible.sync="dialogVisible" :before-close="closeDialog">
+          <div class="opinion" id="opinion">
+            <el-form :model="form" label-width="100px" label-position="left">
+              <template v-if="form.content">
+                <el-form-item label="颜色:">
+                  <el-input type="color" size="small" class="changeColor"  v-model="form.color" style="user-select:none;width:100px"> </el-input>
+                </el-form-item>
+                <el-form-item label="类型:">
+                  <el-radio-group v-model.number="form.scratchType" @change="changeRadioType">
+                    <el-radio :label="2">波浪线</el-radio>
+                    <el-radio :label="0">下划线</el-radio>
+                    <el-radio :label="1">高亮</el-radio>
+                  </el-radio-group>
+                </el-form-item>
+                <el-form-item label="当前文献:">
+                  <span>{{ form.sortStr }}</span>
+                </el-form-item>
+                <el-form-item label="选中文本:">
+                  <span> {{ form.content }}</span>
+                </el-form-item>
+              </template>
+              <el-form-item v-if="!form.content" label="对比文献:">
+                <el-select v-model="form.proofId" placeholder="请选择" style="width:100%">
+                <el-option
+                  v-for="item in files"
+                  :key="item.id"
+                  :label="item.sortStr"
+                  :value="item.id">
+                </el-option>
+              </el-select>
+
+                  <!-- <span>{{ form.file }}</span> -->
+              </el-form-item>
+              <el-form-item label="位置/附图号" class="item">
+                <el-input v-model="form.position" placeholder="请输入备注" show-word-limit></el-input>
+              </el-form-item>
+            </el-form>
+            <div>
+              <p style="margin-bottom:0">相关权要/特征:</p>
+              <!-- <div>
+                <el-tree 
+                  :data="tableData1"
+                  :props="{children:'features',label:'content'}"
+                  :show-checkbox="true" 
+                  :check-on-click-node="false"
+                  :check-strictly="true" 
+                  node-key="id" 
+                  @check="treeCheck"
+                  ref="treeForm">
+                    <span slot-scope="{ node, data }">
+                      <span>{{ data.features?data.RightName:data.content }}</span><span v-if="data.evidence">————{{ data.evidence }}</span>
+                    </span>
+                  </el-tree>
+              </div> -->
+              <el-collapse v-model="witchRight" accordion  @change="handleChange" style="height: 300px;overflow:auto;">
+                <el-collapse-item v-for="item in tableData1" :key="item.sort" :name="item.sort">
+                  <template slot="title">
+                    <div style="width:100%;display:flex;justify-content: space-between;">
+                     <p>{{ item.rightName }} </p> <p class="addFeature" @click.stop="addFeature(item)"> <el-link style="color: blue;">+ 添加</el-link> </p>
+                    </div>
+                    
+                  </template>
+                  <div>
+                    <el-divider></el-divider>
+                    <div v-for="feature in tableData1.featureList" :key="feature.featureId" style="padding:10px">
+                      <!-- <el-divider></el-divider> -->
+                      <el-tooltip :content="feature.content" placement="top">
+                        <el-radio-group v-model="form.featureId" @change="changeRadio(feature)">
+                          <el-radio :label="feature.featureId">{{feature.featureName}}</el-radio>
+                        </el-radio-group>
+                      </el-tooltip>
+                      <!-- <p>{{feature.content}}</p> -->
+                      </div>
+                  </div>
+                  
+                </el-collapse-item>
+              </el-collapse>
+            </div>
+            <div v-if="dialogVisible">
+              <p style="margin-bottom:0">无效证据:</p>
+              <span>
+                <div style="width:100%;outline: #dcdfe6;border:1px solid #DCDFE6;border-radius:5px;min-height:50px;" id="preview" 
+                  contenteditable="true" v-html="form.proofStr"
+                  @blur="saveValue(form,'proofStr',$event.target.innerHTML)" v-on:paste="handlePaste($event, form, 'proofStr')">
+                </div>
+                <!-- <div style="width:100%;outline: #dcdfe6;border:1px solid #DCDFE6;border-radius:5px;background:white" id="preview" contenteditable="true" 
+                    v-html="form.content2"  @input="saveValue($event.target.innerHTML)"  @click="saveValue($event.target.innerHTML)"> 
+                </div> -->
+              </span>
+            </div>
+            <div  v-if="dialogVisible">
+              <p style="margin-bottom:0">陈述意见:</p>
+              <span>
+                <div style="width:100%;outline: #dcdfe6;border:1px solid #DCDFE6;border-radius:5px;min-height:50px;" id="preview"
+                  contenteditable="true" v-html="form.argumentStr" 
+                  @blur="saveValue(form,'argumentStr',$event.target.innerHTML)" v-on:paste="handlePaste($event, form, 'argumentStr')">
+                </div>
+                <!-- <div style="width:100%;outline: #dcdfe6;border:1px solid #DCDFE6;border-radius:5px;min-height:50px;background:white" id="preview" contenteditable="true" 
+                    v-html="form.content1"  @input="saveValue($event.target.innerHTML)"  @click="saveValue($event.target.innerHTML)"> 
+                </div> -->
+              </span>
+            </div>
+          </div>
+          <div slot="footer" class="dialog-footer">
+              <el-button @click="closeDialog">取 消</el-button>
+              <el-button type="primary" @click="AddOpinion">确 定</el-button>
+            </div>
+        </el-dialog>
+
+        <el-dialog title="添加特征" style="user-select:none;" :visible.sync="featureVisible" :before-close="closeFeature" append-to-body>
+          <div>
+            <el-form :model="featureForm" label-width="100px" label-position="left">
+              <el-form-item v-if="featureForm.rightSort || featureForm.rightName" label="所属权要:">
+                <span v-if="featureForm.rightSort">权要{{ Number(featureForm.rightSort)+1  }}</span>
+                <span v-else>{{ featureForm.rightName }}</span>
+              </el-form-item>
+              <el-form-item v-else label="所属权要:">
+                <span>{{ featureForm.scratchField }}</span>
+              </el-form-item>
+              <el-form-item label="特征内容:">
+                <span v-if="show">{{ featureForm.content }}</span>
+                <el-input v-else type="textarea" v-model="featureForm.content"></el-input>
+              </el-form-item>
+              <el-form-item label="对比文献:" v-if="show">
+                <el-select v-model="featureForm.proofId" placeholder="请选择" style="width:100%">
+                <el-option
+                  v-for="item in files"
+                  :key="item.id"
+                  :label="item.sortStr"
+                  :value="item.id">
+                </el-option>
+              </el-select>
+              </el-form-item>
+            </el-form>
+            <div v-if="featureVisible && show" style="user-select:none;">
+              <p style="margin-bottom:0">无效证据:</p>
+              <span>
+                <div style="width:100%;outline: #dcdfe6;border:1px solid #DCDFE6;border-radius:5px;min-height:50px;" id="preview" 
+                  contenteditable="true" v-html="form.proofStr" @input="saveValue($event.target.innerHTML)"
+                  @click="saveValue($event.target.innerHTML)">
+                </div>
+                <!-- <div style="width:100%;outline: #dcdfe6;border:1px solid #DCDFE6;border-radius:5px;min-height:50px;background:white;user-select:none;" id="preview" contenteditable="true" 
+                    v-html="featureForm.content2"  @input="saveValue($event.target.innerHTML)"  @click="saveValue($event.target.innerHTML)"> 
+                </div> -->
+              </span>
+            </div>
+            <div  v-if="featureVisible && show" style="user-select:none;">
+              <p style="margin-bottom:0">陈述意见:</p>
+              <span>
+                <div style="width:100%;outline: #dcdfe6;border:1px solid #DCDFE6;border-radius:5px;min-height:50px;" id="preview"
+                  contenteditable="true" v-html="form.argumentStr" @input="saveValue($event.target.innerHTML)"
+                  @click="saveValue($event.target.innerHTML)">
+                </div>
+                <!-- <div style="width:100%;outline: #dcdfe6;border:1px solid #DCDFE6;border-radius:5px;min-height:50px;background:white;user-select:none;" id="preview" contenteditable="true" 
+                    v-html="featureForm.content1"  @input="saveValue($event.target.innerHTML)"  @click="saveValue($event.target.innerHTML)"> 
+                </div> -->
+              </span>
+            </div>
+          </div>
+          <div slot="footer" class="dialog-footer">
+              <el-button @click="closeFeature">取 消</el-button>
+              <el-button type="primary" @click="submitFeature">确 定</el-button>
+            </div>
+        </el-dialog>
+  </div>
+</template>
+<script>
+import { explain1 } from "@/views/report/components/mixins";
+export default {
+  mixins:[explain1],
+  data() {
+    return {
+      form: {},
+      featureForm: {},
+      tableData1: [],
+      dialogVisible: false,
+      featureVisible: false,
+      witchRight: null,
+      show: false,
+      files: [],//所有的文献
+      reportId: '',
+      title:'',
+    }
+  },
+  mounted() {
+
+  },
+  methods: {
+    closeDialog() {
+      this.form = {}
+      this.dialogVisible = false
+    },
+    // 添加陈述意见确认按钮
+    AddOpinion() {
+      console.log(this.form);
+      if (!this.form.featureId) {
+        this.$message.error('请选择特征')
+        return false
+      }
+      if (!this.form.id) {
+        this.$api.addArguments(this.form).then((res) => {
+          if (res.code == 200) {
+            this.$message.success('添加陈述意见成功')
+            this.queryScratchs()
+            this.closeDialog()
+          }
+        })
+      } else {
+        this.$api.updateArguments(this.form).then((res) => {
+          if (res.code == 200) {
+            this.$message.success('修改陈述意见成功')
+            this.queryScratchs()
+            this.closeDialog()
+          }
+        })
+      }
+    },
+    // 查询划词陈述意见
+    queryScratchs() {
+      this.$api.queryScratchs({proofId:this.form.proofId}).then((res) => {
+        if (res.code == 200) {
+          this.$store.commit('SET_PATENT_OPINION_CONTRAST', res.data)
+        }
+      })
+    },
+    // 特征选择
+    changeRadio(feature) {
+      console.log(feature)
+      this.getFeatureZheng(feature)
+    },
+    treeCheck(node, list) {
+      if (list.checkedKeys.length == 2) {
+        this.$refs.treeForm.setCheckedKeys([node.id]);
+      }
+    },
+    // 打开
+    async open(form, data) {
+      console.log(form);
+      if (form.scratchType) {
+        form.scratchType=Number(form.scratchType)
+      }
+      this.form = form
+     
+      if (!data) {
+        await this.getQueryProofList(this.form)
+        await this.getFeatureRights(form.patentNo)
+        if (this.form.id) {
+          this.witchRight = this.form.rightId
+          await this.getFeature()
+          this.getFeatureZheng(form)
+          this.title='编辑陈述意见'
+        } else {
+          this.title='添加陈述意见'
+        }
+        
+        this.dialogVisible = true
+      } else {
+        this.featureForm=form
+        this.featureVisible = true
+        this.show = true
+      }
+    },
+    //查询证据文献列表
+    async getQueryProofList(form) {
+      let params = {
+        reportId:form.reportId,
+        signPatentNo:form.signPatentNo,
+        size: 99,
+        current: 1,
+      }
+      await this.$api.queryProof(params).then((res) => {
+        if (res.code == 200) {
+          this.files = res.data
+          let a =this.files.find(item => {
+           return item.id==this.form.proofId
+          })
+          this.form.sortStr = a.sortStr
+          // this.featureForm.rightSort =a.sortStr
+        }
+      }).catch((error) => {
+        
+      })
+    },
+
+
+    addFeature(val) {
+      console.log(val);
+      this.featureForm.rightName = val.rightName
+      this.featureForm.rightId = val.sort
+      this.featureForm.reportId = this.form.reportId
+      this.featureVisible = true
+    },
+    closeFeature() {
+      this.featureVisible = false
+      this.show = false
+      this.featureForm = {}
+    },
+    submitFeature() {
+      if (!this.featureForm.rightSort) {
+        // 第二种方式弹窗中添加特征
+        this.$api.addSingleFeature(this.featureForm).then((res) => {
+          if (res.code== 200) {
+            this.getFeature()
+            this.closeFeature()
+          }
+        })
+      } else {
+        
+      }
+    },
+    // 请求权要特征
+    async getFeatureRights(val) {
+      // this.loading=true
+      // let PatentRight = {
+      //     patentNo: val,
+      //     splitType: "1",
+      //     splitBy: "2",
+      //     ReportId: id
+      //     }
+      let params = { patentNo: val}
+      await this.$api.getFeatureRights(params).then((res) => {
+        if (res.code == 200) {
+          this.tableData1 = res.data
+        }
+      })
+      // this.$api.splitPatentRight(PatentRight).then(res => {
+      //     if (res.code == 200) {
+      //     res.data.patentRightVos.forEach(item=>{
+      //         item.id = item.RightName
+      //         item.features[0].evidence = '证据'
+      //     })
+      //     this.tableData1 = res.data.patentRightVos;
+
+      //     }
+      // })
+    },
+    // 折叠面板
+    handleChange(val) {
+      console.log(val);
+      this.form.rightId=val
+      this.getFeature()
+    },
+    // 查询已添加的特征
+    async getFeature() {
+      console.log(this.form,this.witchRight);
+      let params = {
+        reportId: this.form.reportId,
+        rightSort:this.witchRight
+      }
+      await this.$api.getFeatureList(params).then((res) => {
+        if (res.code == 200) {
+          this.$set(this.tableData1,'featureList',res.data)
+        }
+      })
+    },
+    // 根据特征查询证据
+    getFeatureZheng(val) {
+      console.log(val);
+      let params = {
+        proofId: this.form.proofId,
+        featureId:val.featureId,
+      }
+      this.$api.queryProofStr(params).then((res) => {
+        if (res.code == 200) {
+          if (res.data.proofStr) {
+            this.form.proofStr = res.data.proofStr
+          }
+        }
+      })
+    },
+    //划词类型
+    changeRadioType() {
+      
+    },
+  },
+}
+</script>
+<style lang="scss" scoped>
+ .avatar-uploader-icon {
+    background-color: #fbfdff;
+    border: 1px dashed #c0ccda;
+    font-size: 28px;
+    color: #8c939d;
+    width: 148px;
+    height: 148px;
+    line-height: 148px;
+    text-align: center;
+  }
+ .avatar {
+  
+  position: relative;
+    width: 148px;
+    height: 148px;
+    display: block;
+  }
+  .avatar:hover .deleteImg {
+    display: block;
+}
+.deleteImg {
+  display: none;
+  font-size: 30px;
+  width: 148px;
+  height: 148px;
+  background-color:black;
+	opacity: 0.6; 
+  position: absolute;
+  top: 0;
+  right: 0;
+  left: 0;
+  bottom: 0;
+  margin: auto;
+  z-index: 999;
+}
+.deleteImg span i{
+  margin-left: 10px;
+  color: #fff;
+}
+.deleteImg span{
+  display: flex;
+  align-items:center;/*垂直居中*/
+  justify-content: center;/*水平居中*/
+  width:100%;
+  height:100%;
+}
+
+.addFeature{
+  margin-right:30px;
+  
+}
+
+</style>

+ 26 - 0
RMS-FrontEnd/src/views/report/InvalidResponse/components/checkFile.vue

@@ -0,0 +1,26 @@
+<template>
+    <div>
+        
+        <iframe :src="FileUrl" frameborder="0" width="100%" :height="fullHeight"></iframe>
+    </div>
+</template>
+<script>
+export default {
+    data() {
+        return {
+          FileUrl: '',
+          fullHeight: document.documentElement.clientHeight - 250,
+        }
+    },
+    mounted() {
+        
+    },
+  methods: {
+      open(val) {
+        if (val) {
+          this.FileUrl=  val
+        }
+      },
+    },
+}
+</script>

+ 259 - 0
RMS-FrontEnd/src/views/report/InvalidResponse/components/choseOpinion.vue

@@ -0,0 +1,259 @@
+<template>
+  <!-- 生成陈述意见方案 -->
+  <div>
+    <span>证据文献:</span>
+    <el-select v-model="proofId" placeholder="请选择证据文献" @change="changeEvidence" style="padding:20px 0 0 0;margin-right: 20px;">
+      <el-option v-for="item in EvidenceList" :key="item.sortStr" :value="item.id"
+        :label="item.sortStr"></el-option>
+    </el-select>
+    <span>权要:</span>
+    <el-select v-model="right" placeholder="请选择权要" @change="changeRight" style="padding:20px 0 0 0">
+      <el-option v-for="item in rightList" :key="item.rightName" :value="item.sort"
+        :label="item.rightName"></el-option>
+    </el-select>
+    <el-table :data="tableData" ref="table" border :height="tableHeight" v-loading="loading"
+      style="min-width: 100%; margin-top: 20px;overflow:auto">
+      <el-table-column prop="featureName" label="特征" align="center">
+        <template slot-scope="scope">
+          <div>
+              <el-tooltip class="item" effect="dark" :content="scope.row.featureContent" placement="top">
+               <span>{{ scope.row.featureName }}</span> 
+              </el-tooltip>
+          </div>
+        </template>
+      </el-table-column>
+
+      <el-table-column prop="proofStr" align="center" label="证据(无效请求人)">
+        <template slot-scope="scope">
+          <div v-html="scope.row.proofStr"> </div>
+        </template>
+      </el-table-column>
+      <el-table-column prop="arguments" align="center" label="证据(权利人)">
+        <template slot-scope="scope">
+          <div class="innerTable" style="width:calc(100% + 20px);margin-left:-10px;word-wrap:break-word;">
+            <div class="item" v-for="(item, index) in scope.row.arguments">
+              <el-checkbox-group v-model="checkList">
+                <el-checkbox :label="item.id" style="display: flex; align-items: center;">
+                  <div v-html="item.argumentStr"> </div>
+                </el-checkbox>
+              </el-checkbox-group>
+              <el-button @click.native.prevent="deleteRow(item.id)" type="text" size="small" style="margin-left: 10px;color: red;"> 删除 </el-button>
+            </div>
+          </div>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <div style="display:flex; justify-content: space-between;align-items:center;padding-top:20px" v-if="show">
+      <p>修改方案/理由:</p>
+      <div style="width:calc(100% - 200px);">
+        <div style="width:100%;outline: #dcdfe6;border:1px solid #DCDFE6;border-radius:5px;min-height:50px;" id="preview"
+                  contenteditable="true" v-html="ruleForm.result" 
+                  @blur="saveValue(ruleForm,'result',$event.target.innerHTML)" v-on:paste="handlePaste($event, ruleForm, 'result')">
+                </div>
+        <!-- <el-input type="textarea" v-model="ruleForm.result" placeholder="请输入结论"></el-input> -->
+      </div>
+      <div>
+        <el-button type="primary" @click="save">保存</el-button>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+import { explain1 } from "@/views/report/components/mixins";
+export default {
+  mixins: [explain1],
+  props:['reportId','signPatentNo'],
+  data() {
+    return {
+      ruleForm:{},
+      tableData: [],
+      tableData1: [],
+      rightList: [],
+      right: '',//当前权要
+      tableHeight: null,
+      loading: false,
+      checkList: [],
+      result: '',
+      show: true,
+      EvidenceList: [],//证据文献List
+      proofId:'',
+    }
+  },
+  watch: {
+    tableData() {
+      this.$nextTick(() => {
+        this.setHeight()
+      })
+    },
+  },
+  async mounted() {
+    await this.getPatentByPatentNo()
+    await this.getQueryProofList()
+    this.getList()
+  },
+  methods: {
+    setHeight() {
+      const offsetTop = window.innerHeight - this.$refs.table.$el.offsetTop - 140
+      const body = document.querySelector('.el-table__body')
+      if (!body) {
+        return false
+      }
+      const offsetBodyHeight = body.offsetHeight
+      //console.log( window.innerHeight,body,offsetBodyHeight,offsetTop)
+      if (this.tableData.length && offsetBodyHeight < offsetTop) {
+        this.tableHeight = offsetBodyHeight + 75
+      } else if (!this.tableData.length) {
+        this.tableHeight = null
+      } else {
+        this.tableHeight = offsetTop
+      }
+      this.tableHeight = this.tableHeight > 300 ? this.tableHeight : 300
+    },
+    // 查询专利权要
+   async getPatentByPatentNo() {
+      let params = {patentNo: this.signPatentNo,}
+      await this.$api.getFeatureRights(params).then((res) => {
+        if (res.code==200) {
+          this.rightList = res.data
+          this.right = res.data[0].sort
+        }
+      })
+    },
+    // 查询证据文献
+    async getQueryProofList() {
+      let params = {
+        reportId:this.reportId,
+        signPatentNo:this.signPatentNo,
+        size: 99,
+        current: 1,
+      }
+      await this.$api.queryProof(params).then((res) => {
+        if (res.code==200) {
+          this.EvidenceList = res.data
+          this.proofId=res.data[0].id
+        }
+      }).catch((error) => {
+        
+      })
+    },
+    // 请求陈述意见列表
+    getList() {
+      let params = {
+        proofId:this.proofId,
+        rightSort:this.right,
+        reportId:this.reportId,
+      }
+      this.$api.queryPoofArguments(params).then((res) => {
+        if (res.code == 200) { 
+          this.tableData=res.data
+        }
+      })
+      // let PatentRight = {
+      //   "patentNo": "CN102727071A",
+      //   "splitType": "1",
+      //   "splitBy": "2",
+      //   "ReportId": 368
+      // }
+      // this.rightList = []
+      // this.$api.splitPatentRight(PatentRight).then(res => {
+      //   if (res.code == 200) {
+      //     res.data.patentRightVos.forEach(item => {
+      //       this.rightList.push({
+      //         type: item.type,
+      //         rightName: item.RightName
+      //       })
+      //       item.id = item.RightName
+      //       item.features[0].evidence = '证据' //证据(无效请求人)
+      //       item.features[0].evidence2 = [] //证据(权利人)
+      //     })
+      //     this.right = this.rightList[0].rightName
+      //     this.tableData1 = res.data.patentRightVos;
+      //     this.getTableData()
+      //   }
+      // })
+    },
+    getTableData() {
+      // this.tableData = this.tableData1.find(item => {
+      //   return item.RightName == this.right
+      // }).features
+    },
+    changeRight(val) {
+      console.log(val);
+      // this.getTableData()
+      this.clearChose()
+      this.right=val
+      this.getList()
+    },
+    changeEvidence(val) {
+      this.clearChose()
+      this.proofId=val
+      this.getList()
+    },
+    //保存方案
+    save() {
+      console.log(this.result,this.checkList,this.right,this.ruleForm);
+      let params = {
+        reportId: this.reportId,
+        rightSort: this.right,
+        modifyReason: this.ruleForm.result,
+        argumentIds: this.checkList
+      }
+      this.$api.addArgumentsScenario(params).then((res) => {
+        if (res.code == 200) { 
+          this.$message.success('保存成功')
+          this.clearChose()
+        }
+      })
+    },
+    //清空信息
+    clearChose() {
+      this.checkList = []
+      this.result = ''
+      this.show = false
+      this.$nextTick(() => {
+        this.show = true
+      })
+    },
+    deleteRow(val) {
+      console.log(val);
+      let params = [
+        val
+      ]
+      this.$api.deletePoofArguments(params).then((res) => {
+        if (res.code == 200) {
+          this.getList()
+          this.$message.success('删除成功')
+        }
+      })
+    },
+  },
+}
+</script>
+<style lang="scss" scoped>
+.innerTable .item {
+  /* min-width:200px; */
+  padding: 20px 10px;
+  margin: 0;
+  display: flex;
+  justify-content: flex-start;
+  align-items: center;
+  // height: 130px;
+  line-break: normal;
+  overflow: auto;
+  border-bottom: 1px solid #EBEEF5;
+}
+
+.innerTable .item:last-child:first-child {
+  //item 即是最后一个元素 又是第一个元素
+  height: 100%;
+}
+
+.innerTable .item:nth-child(1) {
+  border-bottom: 1px solid #EBEEF5;
+}
+
+.innerTable .item:last-child {
+  border-bottom: none;
+}
+</style>

+ 378 - 0
RMS-FrontEnd/src/views/report/InvalidResponse/components/evidenceAndRequest.vue

@@ -0,0 +1,378 @@
+<template>
+  <div>
+    <div style="margin-bottom: 10px;float: right;">
+      <el-button type="primary" size="small" v-if="examine" @click="andClick(1)">上传无效请求书</el-button>
+      <el-button type="primary" size="small"  @click="andClick()">上传专利文件</el-button>
+      <el-button type="primary" size="small"  @click="andClick(5)">上传非专利文件</el-button>
+      <el-button type="primary" size="small" v-if="examine"  @click="isExamine">报告审核</el-button>
+    </div>
+   <div>
+    <el-table :data="tableData"  border style="width: 100%" v-if="show">
+      <el-table-column prop="sortStr" align="center" label="排序" min-width="180">
+        <template slot-scope="scope">
+          <div>
+              <el-link type="primary" @click="check(scope.row)">{{ scope.row.sortStr }}</el-link>
+              <el-popover
+                        placement="bottom"
+                        width="200"
+                        trigger="click"
+                        v-if="$reportPermission(reportId,[0,1])"
+                        >
+                        <p>将本文件(<span style="color:red">{{ scope.row.sortStr }}</span>)作为:</p>
+                        <el-tree
+                          ref="tree"
+                          :data="tableAll"
+                          :props="{label:'sortStr',value:'id'}"
+                          @node-drop="handleDrop"
+                          :allow-drop="allowDrop"
+                          draggable
+                          @check-change="handleCheckChange"
+                          style="height: 300px;overflow: auto;">
+                          <span class="custom-tree-node" slot-scope="{ node, data }"><el-radio v-model="val" @input="changeRadio(scope.row,data)" :label="data.id">{{ data.sortStr }}</el-radio></span>
+                        </el-tree>
+                        <p style="color:red">备注:选择其中一个文件与其交换位置</p>
+                        <i class="el-icon-arrow-down el-icon--right" @click="getVal(scope.row)" slot="reference"></i>
+                      </el-popover>
+          </div>
+        </template>
+      
+      </el-table-column>
+      <el-table-column prop="proofName" align="center" label="名称" min-width="180"> 
+        <!-- <template slot-scope="scope">
+          <div>
+            {{ scope.row.proofName }}
+          </div>
+        </template> -->
+      </el-table-column>
+      <el-table-column prop="proofType" align="center" label="文件类型" min-width="180"> </el-table-column>
+    </el-table>
+    <div style="text-align: center;margin-top: 10px;">
+      <el-pagination background layout="total, prev, pager, next, jumper" :current-page.sync="queryParams.current"
+        :page-size.sync="queryParams.size" @current-change="handleCurrentChange" :total="queryParams.total">
+      </el-pagination>
+    </div>
+   </div>
+
+   <responseDialog ref="responseDialog" :reportId='reportId' @isFinish="handleFinish"></responseDialog>
+
+   <el-dialog title="添加审核任务" :visible.sync="showTask" width="500px"  @close="handleCloseTask" append-to-body :close-on-click-modal="false">
+      <el-form :model="task" :rules="TaskRules" ref="TaskForm" label-width="120px">
+        <el-form-item label="任务名称 :" prop="taskName">
+            <el-input v-model="task.taskName" type="text" placeholder="输入主题" />
+          </el-form-item>
+          <el-form-item label="审核人 :" prop="personnelId">
+          <el-select style="width:100%;" ref="select1" v-model="task.personnelId" clearable filterable >
+               <el-option v-for="item in personnelList" :key="item.id" :label="item.personnelName" :value="item.id"></el-option>
+            </el-select>
+            </el-form-item>
+          <el-form-item label="完成日期 :" prop="endTime">
+            <el-date-picker style="width:100%" v-model="task.endTime" value-format="yyyy-MM-dd HH:mm:ss" type="datetime"  placeholder="选择日期">
+            </el-date-picker>
+          </el-form-item>
+          <el-form-item label="备注 :" prop="remark">
+            <el-input v-model="task.remark" type="textarea" placeholder="输入备注" />
+          </el-form-item>
+      </el-form>
+     <span slot="footer" class="dialog-footer">
+              <el-button @click="handleCloseTask">取 消</el-button>
+              <el-button type="primary" @click="submitTask" >确 定</el-button>
+        </span>
+    </el-dialog>
+
+
+    <el-dialog title="上传专利文件" :visible.sync="showFile" width="1200px"  @close="handleFile" append-to-body  :close-on-click-modal="false">
+      <importPatent :reportId="this.queryParams.reportId || this.reportId"></importPatent>
+        <span slot="footer" class="dialog-footer">
+          <el-button type="primary" @click="submitFile" >确 定</el-button>
+        </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import responseDialog from "./responseDialog.vue"
+import importPatent from "../import/components/importPatent.vue"
+
+export default {
+  props:['reportId','signPatentNo','examine'],
+  components: {
+    responseDialog,
+    importPatent,
+  },
+  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 {
+      tableData: [],
+      tableAll: [],//排序所用,全部的证据文献
+      queryParams: {
+        reportId:this.reportId,
+        signPatentNo:this.signPatentNo,
+        size: 10,
+        current: 1,
+        orderType: '',//asc,desc
+        total: 0,
+      },
+      form: {},
+      showTask: false,
+      showFile: false,
+      task: {},
+      TaskRules:{
+        taskName:[{ required: true, message: '请输入任务名称', trigger: 'blur' },],
+        personnelId: [{ required: true, message: '请选择审核人', trigger: 'change' },],
+        endTime: [{  required: true, validator:isTime, trigger: 'change' } ],
+      },
+      personnelList: [],//全部人员
+      val: null,
+      show: true,
+      reportForm:{}
+    }
+  },
+  computed: {
+    reportID() {
+      return this.$route.query.reportId
+    },
+  },
+  watch: {
+    showFile(val) {
+      if (!val) {
+        this.getList()
+        this.getListTable()
+      }
+    }
+  },
+  mounted() {
+    this.getList()
+    this.getListTable()
+    console.log(this.reportId,this.queryParams.reportId);
+  },
+  methods: {
+     //查看证据文献
+     check(val) {
+      console.log('11', val);
+      var router = this.$router.resolve({
+        path: '/ContrastIndex/' + val.id,
+        // query: {
+        //   patentNo: val.patentNo,
+          
+        // }
+      })
+      let params = this.$s.getSession('params')
+      console.log(params);
+      params.type=7
+      params.reportType=7
+      params.aid=val.id
+      params.signPatentNo=this.signPatentNo || val.proofConditions
+      params.reportId=this.reportId ||this.queryParams.reportId
+      this.$s.setSession('params', params)
+      window.open(router.href, '_blank');
+    },
+    handleCheckChange(val1,val2,val3){
+      // var getCheck = this.$refs.tree.getCheckedNodes()
+      // //console.log(getCheck)
+      //console.log(val1,val2,val3)
+      // if(val2){
+      //   if(this.checked.length>1){
+      //     this.$alert('只能对2条特征进行交换','提示',{
+      //       confirmButtonText: '确定',
+      //       type:'warning',
+      //       callback: action => {
+      //       }
+      //     })
+      //     return false
+      //   }
+      //   this.checked.push(val1)
+      // }else{
+      //   var a = this.checked.findIndex(item=>{
+      //     return item.id == val1.id
+      //   })
+      //   if(a!=-1){
+      //     this.checked.splice(a,1)
+      //   }
+      // }
+      
+      //console.log(this.checked)
+    },
+    getVal(val){
+      this.val = val.id
+    },
+    handleDrop(before, after, inner, ev) { },
+    allowDrop(draggingNode, dropNode, type){
+      if(draggingNode.level == dropNode.level){
+        return type === 'next' || type === 'prev'
+      }else{
+        return type === 'prev'
+      }
+    },
+    changeRadio(val1, node) {
+      console.log(val1,node,this.tableAll)
+      var index1 = this.tableAll.findIndex(item=>{//获取当前专利位置
+        return item.id == val1.id
+      })
+      var index2 = this.tableAll.findIndex(item=>{//获取选中专利位置
+        return item.id == node.id
+      })
+      this.tableAll[index1] = this.tableAll.splice(index2,1,this.tableAll[index1])[0]
+      // this.recordData[index1] = this.recordData.splice(index2,1,this.recordData[index1])[0]
+      this.addOrder()
+      
+    },
+    addOrder() {
+      var params ={
+        "report": this.reportId || this.queryParams.reportId,
+        "orders": this.tableAll.map((item,index) => {
+          return {
+            id: item.id,
+            order:index+1
+          }
+        })
+      }
+      this.$api.addProodOrder(params).then(response => {
+        if (response.code == 200) {
+          this.show = false
+          this.getList()
+          this.$nextTick(() => {
+            this.show = true
+          })
+        }
+      }).catch(error => {
+        
+      })
+    },
+
+    open(val,id) {
+      console.log(val.id);
+      this.getAllPersonnelList()
+      this.queryParams.reportId = id
+      this.reportForm=val
+    },
+    // 报告审核按钮
+    isExamine() {
+      this.showTask=true
+     
+    },
+    // 审核确认
+    submitTask() { 
+      this.$refs.TaskForm.validate((valid) => {
+        if (valid) { 
+          let formData = new FormData()
+          let a = this.task
+          a.report=this.reportForm,
+          a.reportId = this.queryParams.reportId || this.reportId
+          a.personIds = [this.task.personnelId]
+          a.type = 0
+          formData.append('taskVO',JSON.stringify(a))
+          this.$api.AddTask(formData).then(response=>{
+              if (response.code == 200) {
+              this.$message.success('报告创建成功并发送审核')
+              // this.$emit('getList', true)
+              this.handleCloseTask()
+            }
+          }).catch(error => {
+            this.$message.error('报告创建失败')
+            // this.handleCloseTask()
+          })
+        }
+      })
+    },
+    // 审核取消
+    handleCloseTask() { 
+      this.$refs.TaskForm.resetFields()
+      this.task = {}
+      this.showTask = false
+      this.$emit('show',false)
+    },
+    //获取全部人员
+    getAllPersonnelList(){
+      this.$api.getTenantPersonnel().then(response=>{
+        // console.log(response)
+        this.personnelList = response.data
+      })
+    },
+    // 子组件上传成功弹窗关闭
+    handleFinish(val) {
+      this.getList();
+    },
+    getList() {
+      this.$api.queryProof(this.queryParams).then((res) => {
+        if (res.code==200) {
+          this.tableData=res.data
+          this.queryParams.size=res.pageColumn.size
+          this.queryParams.current=res.pageColumn.current
+          this.queryParams.total=res.pageColumn.total
+        }
+      }).catch((error) => {
+        
+      })
+    },
+    getListTable() {
+      // this.queryParams.size=999
+      var params = {
+        size: 999,
+        current: 1,
+        reportId:this.reportId ||this.queryParams.reportId
+      }
+      this.$api.queryProof(params).then((res) => {
+        if (res.code==200) {
+          this.tableAll = res.data
+        }
+      }).catch((error) => {
+        
+      })
+    },
+    andClick(val) {
+      if (val) {
+        this.form.reportId=this.reportId?this.reportId:this.reportID
+        this.form.processType=val
+        this.$refs.responseDialog.open(this.form)
+      } else {
+        // 上传专利文件
+        // this.toImport()
+        this.showFile=true
+      }
+    },
+    // 上传文件弹窗关闭
+    handleFile() {
+      this.showFile=false
+    },
+    // 上传文件弹窗确认按钮
+    submitFile() {
+      this.getList()
+      this.handleFile()
+    },
+    // toImport() {
+    //   let router=this.$router.push({
+    //     path: '/importPatent',
+    //     query: {
+    //       // patentNo:this.signPatentNo,
+    //       id: this.reportId?this.reportId:this.reportID,
+    //     }
+    //   })
+    //   window.open(router.href,'_blank')
+    // },
+    // 分页
+    handleCurrentChange(val) {
+      this.queryParams.current = val;
+      this.getList();
+    },
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 36 - 0
RMS-FrontEnd/src/views/report/InvalidResponse/components/evidenceAndRequestRouter.vue

@@ -0,0 +1,36 @@
+<template>
+  <div>
+    <evidenceAndRequest :reportId="reportId" :signPatentNo="signPatentNo" ></evidenceAndRequest>
+  </div>
+</template>
+
+<script>
+import evidenceAndRequest from "./evidenceAndRequest.vue"
+export default {
+  components: {
+    evidenceAndRequest
+  },
+  data() {
+    return {
+    }
+  },
+  computed: {
+    reportId() {
+      return this.$route.query.reportId
+    },
+    signPatentNo() {
+      return  this.$route.query.patentNo
+    },
+  },
+  watch: {},
+  mounted() {
+    
+  },
+  methods: {
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 148 - 0
RMS-FrontEnd/src/views/report/InvalidResponse/components/flowPath.vue

@@ -0,0 +1,148 @@
+<template>
+  <div>
+    <!-- 无效流程 -->
+    <div style="display: flex;justify-content: end;margin-bottom: 10px;">
+      <el-dropdown @command="handleCommand">
+        <el-button type="primary" size="small">
+          添加无效请求书<i class="el-icon-arrow-down el-icon--right"></i>
+        </el-button>
+        <el-dropdown-menu slot="dropdown" >
+          <el-dropdown-item command="1">添加无效请求书</el-dropdown-item>
+          <el-dropdown-item command="2">添加陈述意见书</el-dropdown-item>
+          <el-dropdown-item command="0">添加口审记录</el-dropdown-item>
+          <el-dropdown-item command="3">添加无效决定书</el-dropdown-item>
+          <el-dropdown-item command="4">添加行政诉讼书</el-dropdown-item>
+        </el-dropdown-menu>
+      </el-dropdown>
+    </div>
+    <div :style="{height:tableHeight+'px'}">
+      <el-timeline>
+        <el-timeline-item v-for="item in timelineList" :timestamp="item.date" placement="top">
+          <el-card>
+            <div>
+              <span>{{ timeType[item.processType] }}:</span><span>{{ item.occuredTime.slice(0,10) }}</span>
+              <div style="float: right;">
+                  <span style="margin-right: 10px;"  @click="edit(item)"><el-link>编辑</el-link></span>
+                  <span  @click="dele(item)"><el-link>删除</el-link></span>
+              </div>
+            </div>
+            <div v-if="item.processType==0">
+              <p><span>地点:</span><span>{{ item.oralExam.address }}</span></p>
+              <p><span>参与人:</span><span>{{ item.oralExam.participants }}</span></p>
+            </div>
+            <div v-if="item.processType!=0" style="margin-top: 35px;">
+              <div v-if="item.reportFile" class="upload-file">
+                <div  style="margin:0;display:flex;justify-content:space-around;">
+                  <p style="margin:0;width:calc(100% - 40px);overflow: hidden;white-space: nowrap;text-overflow:ellipsis;cursor: pointer;">{{item.reportFile.name?item.reportFile.name+'.'+item.reportFile.suffix:item.reportFile.fileName}}</p> 
+                  <Menu :data="item.reportFile" @delFile="delFile(item)" :isDelete="true"></Menu>
+                </div>
+              </div>
+            </div>
+          </el-card>
+        </el-timeline-item>
+      </el-timeline>
+    </div>
+
+    <responseDialog ref="responseDialog" :reportId="reportId" @isFinish="handleFinish" :deleFile="deleFile"></responseDialog>
+  </div>
+</template>
+
+<script>
+import Menu from '@/views/components/common/menu/index.vue'
+import responseDialog from './responseDialog.vue'
+
+export default {
+  props:['reportId'],
+  components: {
+    Menu,
+    responseDialog,
+  },
+  data() {
+    return {
+      timelineList:[],
+      isOpen: false,
+      isOpenNum: null,
+      form: {},
+      queryParams: {},
+      timeType: {
+        '1': '提出无效时间',
+        '2': '陈述答复时间',
+        '0': '口审时间',
+        '3': '无效决定时间',
+        '4': '发起诉讼时间',
+      },
+      deleFile: false,
+      tableHeight:0,
+    }
+  },
+  computed: {},
+  watch: {},
+  mounted() {
+    this.getLise()
+    this.getHeight()
+  },
+  methods: {
+    getHeight() {
+      let a = document.body.clientHeight
+      this.tableHeight=a-300
+    },
+    getLise() {
+      this.queryParams.reportId = this.reportId
+      // 1正序
+      this.queryParams.orderBy = 1
+      this.$api.queryInvalidProcess(this.queryParams).then((res) => {
+        if (res.code==200) {
+          this.timelineList = res.data
+        }
+      }).catch((error) => {
+        
+      })
+    },
+    handleFinish() {
+      this.getLise()
+    },
+    // 删除文件
+    delFile(item) {
+      console.log(item);
+      // var index = this.form.files.findIndex(item => {
+      //   return item.id == id
+      // })
+      // if (index != -1) {
+      item.reportFile = {}
+      this.form=item
+      this.deleFile=!this.deleFile
+      //   this.submit()
+      // }
+    },
+    // 编辑
+    edit(item) {
+      this.form = JSON.parse(JSON.stringify(item))
+      this.$refs.responseDialog.open(this.form)
+    },
+    // 删除
+    dele(item) {
+      let a = {
+        id:item.id
+      }
+      this.$api.deleteInvalidProcess(a).then((res) => {
+        if (res.code==200) {
+          this.$message.success('删除成功')
+          this.getLise()
+        }
+      })
+    },
+    // 添加
+    handleCommand(ev) {
+      this.form.processType = ev
+      this.$refs.responseDialog.open(this.form)
+    },
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+.edit{
+  float: right;
+  margin-right: 10px;
+}
+</style>

+ 39 - 0
RMS-FrontEnd/src/views/report/InvalidResponse/components/invalidIdexRouter.vue

@@ -0,0 +1,39 @@
+<template>
+  <div>
+    <InvalidIndex :reportId="reportId" :signPatentNo="signPatentNo" :reportType="reportType"></InvalidIndex>
+  </div>
+</template>
+
+<script>
+import InvalidIndex from "./InvalidIndex.vue"
+export default {
+  components: {
+    InvalidIndex
+  },
+  data() {
+    return {
+    }
+  },
+  computed: {
+    reportId() {
+      return this.$route.query.reportId
+    },
+    signPatentNo() {
+      return  this.$route.query.patentNo
+    },
+    reportType() {
+      return  this.$route.query.reportType
+    },
+  },
+  watch: {},
+  mounted() {
+    
+  },
+  methods: {
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 241 - 0
RMS-FrontEnd/src/views/report/InvalidResponse/components/opinionPlan.vue

@@ -0,0 +1,241 @@
+<template>
+  <!-- 导出陈述意见方案 -->
+  <div>
+    <div style="display:flex;justify-content:flex-end">
+      <el-button type="primary" size="small" style="width:100px">导出</el-button>
+    </div>
+    <el-table :data="tableData" ref="table" border :height="tableHeight"  :span-method="objectSpanMethod"
+      v-loading="loading" style="min-width: 100%; margin-top: 20px;overflow:auto">
+      <el-table-column prop="proofName" label="证据" align="center" width="200px">
+        <template slot-scope="scope">
+          <!-- <div v-for="item in scope.row.argumentsVOList"> -->
+            <!-- <el-tooltip class="item" effect="dark" :content="scope.row.rightContent" placement="top"> -->
+              <span>{{ scope.row.proofName }}</span>
+            <!-- </el-tooltip> -->
+          <!-- </div> -->
+        </template>
+      </el-table-column>
+      <el-table-column prop="argumentsVOList.rightName" label="权要" align="center" width="200px">
+        <template slot-scope="scope">
+          <div v-for="item in scope.row.argumentsVOList">
+            <el-tooltip class="item" effect="dark" :content="scope.row.rightContent" placement="top">
+              <span>{{ item.rightName }}</span>
+            </el-tooltip>
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column prop="argumentsVOList.featureName" label="特征" align="center" width="200px">
+        <template slot-scope="scope">
+          <div v-for="item in scope.row.argumentsVOList">
+            <el-tooltip class="item" effect="dark" :content="item.featureContent" placement="top">
+             <span>{{ item.featureName }}</span> 
+            </el-tooltip>
+          </div>
+        </template>
+      </el-table-column>
+
+      <el-table-column prop="argumentsVOList.proofStr" align="center" label="证据(无效请求人)"  width="300px">
+        <template slot-scope="scope">
+          <div v-for="item in scope.row.argumentsVOList">
+            <div v-html="item.proofStr"> </div>
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column prop="argumentsVOList.arguments" align="center" label="证据(权利人)"  min-width="100px">
+        <template slot-scope="scope">
+          <div v-for="item in scope.row.argumentsVOList">
+            <div class="innerTable" style="width:calc(100% + 20px);margin-left:-10px;word-wrap:break-word;">
+              <div class="item" v-for="(item1, index) in item.arguments">
+                <div v-html="item1.argumentStr"> </div>
+              </div>
+            </div>
+          </div>
+
+        </template>
+      </el-table-column>
+      <el-table-column prop="modifyReason" align="center" label="修改方案/理由">
+        <template slot-scope="scope">
+          <div v-html="scope.row.modifyReason"> </div>
+        </template>
+      </el-table-column>
+      <el-table-column  label="操作" align="center" width="180px">
+        <template slot-scope="scope">
+          <div>
+            <!-- <el-button @click.native.prevent="editRow(scope.row)" type="text" size="small" style="color: red;"> 编辑 </el-button> -->
+            <el-button @click.native.prevent="deleteRow(scope.row)" type="text" size="small" style="color: red;"> 删除 </el-button>
+          </div>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+<script>
+export default {
+  props:['reportId'],
+  data() {
+    return {
+      tableData: [],
+      loading: false,
+      checkList: [],
+      tableHeight: null,
+      mergeObj: {},
+      row: [],//选中特征push到row中
+      mergeArr: ['proofId', 'proofName','rightSort','rightName'],//解释
+    }
+  },
+  watch: {
+    tableData() {
+      this.$nextTick(() => {
+        this.setHeight()
+      })
+    },
+  },
+  mounted() {
+    this.getList()
+  },
+  methods: {
+    setHeight() {
+      const offsetTop = window.innerHeight - this.$refs.table.$el.offsetTop - 140
+      const body = document.querySelector('.el-table__body')
+      if (!body) {
+        return false
+      }
+      const offsetBodyHeight = body.offsetHeight
+      //console.log( window.innerHeight,body,offsetBodyHeight,offsetTop)
+      if (this.tableData.length && offsetBodyHeight < offsetTop) {
+        this.tableHeight = offsetBodyHeight + 75
+      } else if (!this.tableData.length) {
+        this.tableHeight = null
+      } else {
+        this.tableHeight = offsetTop
+      }
+      this.tableHeight = this.tableHeight > 300 ? this.tableHeight : 300
+    },
+    getFunInfo() {
+
+    },
+    getList() {
+      let params = {
+        reportId:this.reportId,
+      }
+      this.$api.queryArgumentsScenario(params).then((res) => {
+        if (res.code == 200) { 
+          var sort = [...new Set(res.data.map(item => { return item.sortStr }))]
+          sort=sort.sort((a, b) => {
+              return Number(a.splice(1,a.length)) - Number(b.splice(1,b.length))
+            })
+          var a = []
+          sort.forEach((item1, index) => {
+            console.log()
+            a[index]=res.data.filter(item => {
+              return item.sortStr == item1
+            })
+            
+            // var right = [...new Set(a[index].map(i => { return i.rightSort }))]
+            // right=right.sort((a, b) => {
+            //   return Number(a) - Number(b)
+            // })
+            // var rightList = []
+            // right.forEach((y, index2) => {
+
+            //   feature[index2] = a[index].argumentsVOList.filter(y1 => { return y1.rightSort == y })
+            //   feature[index2] = feature[index2].sort((a, b) => {
+            //     return Number(a.featureName.splice(2,a.featureName.length)) - Number(b.featureName.splice(2,b.featureName.length))
+            //   })
+            // })
+            // feature = [].concat(...feature)
+            // console.log(feature)
+          })
+          this.tableData = [].concat(...a)
+          // console.log(a)
+          // this.tableData = res.data
+          
+          
+          this.getSpanArr(this.tableData)
+        }
+      })
+    },
+    // // 更新
+    // editRow(val) {
+    //   let params = {
+
+    //   }
+    //   this.$api.updataArgumentsScenario(params).then((res) => {
+    //     if (res.code == 200) { 
+    //       this.getList()
+    //     }
+    //   })
+    // },
+    // 删除
+    deleteRow(val) {
+      let params = [
+        val.id
+      ]
+      this.$api.deleteArgumentsScenario(params).then((res) => {
+        if (res.code == 200) { 
+          this.getList()
+        }
+      })
+    },
+    //获取每个元素所需合并的行数
+    getSpanArr(data) {
+      this.row = []
+      this.mergeArr.forEach((key, index1) => {
+        let count = 0;
+        this.mergeObj[key] = [];
+        data.forEach((item, index) => {
+          if (index === 0) {
+            this.mergeObj[key].push(1);
+          } else {
+            if (item[key] === data[index - 1][key] && item[key] !== 'evidence') {
+              this.mergeObj[key][count] += 1;
+              this.mergeObj[key].push(0);
+            } else {
+              count = index;
+              this.mergeObj[key].push(1);
+            }
+          }
+        })
+      })
+      //   this.mergeObj.result = JSON.parse(JSON.stringify(this.mergeObj.pRightName))
+    },
+    //合并行
+    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
+      if (this.mergeArr.indexOf(column.property) !== -1) {
+        if (this.mergeObj[column.property][rowIndex]) {
+          return [this.mergeObj[column.property][rowIndex], 1]
+        } else {
+          return [0, 0];
+        }
+      }
+    },
+  },
+}
+</script>
+<style lang="scss" scoped>
+.innerTable .item {
+  /* min-width:200px; */
+  padding: 20px 10px;
+  margin: 0;
+  display: flex;
+  justify-content: flex-start;
+  align-items: center;
+  // height: 130px;
+  line-break: normal;
+  overflow: auto;
+  border-bottom: 1px solid #EBEEF5;
+}
+
+.innerTable .item:last-child:first-child {
+  //item 即是最后一个元素 又是第一个元素
+  height: 100%;
+}
+
+.innerTable .item:nth-child(1) {
+  border-bottom: 1px solid #EBEEF5;
+}
+
+.innerTable .item:last-child {
+  border-bottom: none;
+}
+</style>

+ 159 - 0
RMS-FrontEnd/src/views/report/InvalidResponse/components/reasonAndEvidence.vue

@@ -0,0 +1,159 @@
+<template>
+  <div>
+    <!-- 添加无效理由和证据 -->
+    <div style="margin-bottom: 10px;float: right;">
+      <el-button type="primary" size="small" @click="andClick(0)">添加无效证据</el-button>
+      <el-button type="primary" size="small"  @click="andClick(1)">显示栏位管理</el-button>
+    </div>
+    <div>
+      <el-table :data="tableData"  border style="width: 100%">
+        <el-table-column prop="sortStr" align="center" label="序号" min-width="180"> </el-table-column>
+        <el-table-column prop="proofType" align="center" label="无效理由" min-width="180"> </el-table-column>
+        <el-table-column prop="proofName" align="center" label="涉及内容" min-width="180"> </el-table-column>
+        <el-table-column prop="proofType" align="center" label="相关证据" min-width="180"> </el-table-column>
+        <el-table-column prop="proofType" align="center" label="陈述意见" min-width="180"> </el-table-column>
+      </el-table>
+    </div>
+
+
+    <el-dialog title="添加无效证据和理由" :visible.sync="showDialog" width="500px" :close-on-click-modal="false"  @close="handleClose" >
+      <el-form  :model="form" :rules="rules" ref="form" label-width="120px" label-position="left">
+        <el-form-item  label="无效理由:">
+          <el-select style="width: 100%;" v-model="form.invalidity" placeholder="请选择无效理由" filterable  :popper-append-to-body="false">
+            <el-option v-for="item in invalidityList" :key="item.value" :label="item.lable" :value="item.value"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item  label="涉及内容:">
+          <p v-if="form.invalidity==1">说明书</p>
+          <!-- 是说明书显示说明书,是权利要求选择涉及内容 -->
+          <el-select v-if="form.invalidity==0" style="width: 100%;" v-model="form.content" placeholder="请选择涉及内容" filterable  :popper-append-to-body="false">
+            <el-option v-for="item in invalidityList" :key="item.id" :label="item.invalidity" :value="item.id"></el-option>
+          </el-select>
+        </el-form-item>
+        <!-- 只有权利要求才出现 -->
+        <el-form-item v-if="form.invalidity==0"  label="选择特证:">
+          <p>{{  }}</p>
+        </el-form-item>
+        <el-form-item  label="相关证据:">
+          <el-input v-if="form.invalidity!=2" v-model="form.evidence" autocomplete="off" placeholder="请输入相关证据"></el-input>
+          <!-- 不具备创造型时相关证据需要自己添加 -->
+          <el-button v-else type="text" @click="addEvidence">添加</el-button>
+          <div v-show="showAddTable">
+            <el-table :data="addTableData" style="width: 100%">
+              <el-table-column slot-scope="scope" prop="date" label="序号" width="180" > 
+                <el-checkbox v-for="source in sourceData[item.id]" :label="source.value">
+                  <span>{{(scope.$index + 1) + ((queryParams.current - 1) * queryParams.size)}}</span>
+                </el-checkbox>
+              </el-table-column>
+              <el-table-column prop="zhnegju" label="证据" width="180"> </el-table-column>
+              <el-table-column prop="miaoshu" label="描述" width="180">
+                <el-button type="text">详情</el-button> 
+                <el-input type='textarea' v-model="form.miaoshu" autocomplete="off"></el-input>
+              </el-table-column>
+            </el-table>
+            <span>总描述: <el-input type='textarea' v-model="form.miaoshu" autocomplete="off"></el-input></span>
+            <span>总陈述意见: <el-input type='textarea' v-model="form.chenshu" autocomplete="off"></el-input></span>
+          </div>
+          <div>
+            <el-button type="primary" size="small" @click="addTableSure">确认</el-button>
+            <el-button type="primary" size="small"  @click="addTableClose">取消</el-button>
+          </div>
+        </el-form-item>
+        <el-form-item  label="陈述意见:">
+          <el-input type='textarea' v-model="form.opinions" autocomplete="off" placeholder="请输入陈述意见"></el-input>
+        </el-form-item>
+        <el-form-item  label="复审委意见:">
+          <el-input type='textarea' v-model="form.reviewCommittee" autocomplete="off" placeholder="请输入复审委意见"></el-input>
+        </el-form-item>
+        <el-form-item  label="法院意见:">
+          <el-input type='textarea' v-model="form.court" autocomplete="off" placeholder="请输入法院意见"></el-input>
+        </el-form-item>
+     
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="handleClose">取 消</el-button>
+        <el-button type="primary" @click="finish" >确 定</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      tableData: [],
+      showDialog: false,
+      form: {},
+      rules: {},
+      invalidityList: [
+        {
+          lable: '权利要求不清楚',
+          value:0,
+        },
+        {
+          lable: '说明书公开不充分',
+          value:1,
+        },
+        {
+          lable: '不具备创造性',
+          value:2,
+        },
+        {
+          lable: '不具备新颖性',
+          value:3,
+        },
+      ],//无效理由List
+      addTableData: [],//相关证据table数据
+      showAddTable:false,//控制相关证据table显示
+    }
+  },
+  computed: {},
+  watch: {},
+  mounted() {
+
+  },
+  methods: {
+    // 添加相关证据table
+    addEvidence() {
+    },
+    // 添加相关证据table确认按钮
+    addTableSure() { },
+    // 添加相关证据table取消按钮
+    addTableClose(){},
+    // 添加无效证据和显示栏位管理按钮
+    andClick(val) {
+      switch (val) {
+        case 0:
+          
+          break;
+        case 1:
+          
+          break;
+      
+        default:
+          break;
+      }
+    },
+    // 添加无效证据弹窗确认按钮
+    finish() {
+      // this.$api.addProofByFile(this.form).then(response => {
+      //   if (response.code==200) {
+      //       this.handleClose()
+      //     }
+      //   }).catch(error => {
+
+      // })
+    },
+    // 关闭弹窗
+    handleClose() {
+      this.form={}
+      this.showDialog=false
+    },
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 234 - 0
RMS-FrontEnd/src/views/report/InvalidResponse/components/responseDialog.vue

@@ -0,0 +1,234 @@
+<template>
+  <div class="responseDialog">
+    <el-dialog  :title="form.id?'编辑' +title[form.processType]:'添加' +title[form.processType]" :visible.sync="showDialog" width="500px" :close-on-click-modal="false"  @close="handleClose" append-to-body>
+      <el-form  :model="form" :rules="rules" ref="reportForm" label-width="120px" label-position="left" v-loading="loading">
+        <el-form-item v-if="form.processType!=5" :label="timeType[form.processType]">
+          <el-date-picker v-model="form.occuredTime" value-format="yyyy-MM-dd" type="date"  placeholder="请选择时间" style="width: 100%;"></el-date-picker>
+        </el-form-item>
+        <el-form-item v-else label="文献名称:">
+          <el-input  v-model="form.fileName" autocomplete="off" placeholder="请输入文献名称"></el-input>
+        </el-form-item>
+        <template v-if="form.processType==0">
+          <el-form-item  label="地点">
+            <el-input  v-model="form.oralExam.address" autocomplete="off" placeholder="请输入地点"></el-input>
+          </el-form-item>
+          <el-form-item  label="参与人">
+            <el-input  v-model="form.oralExam.participants" autocomplete="off" placeholder="请输入参与人"></el-input>
+          </el-form-item>
+        </template>
+        <el-form-item v-if="form.processType!=0" label="附件:">
+              <el-upload  ref="upload" class="upload-file" drag action="#" :auto-upload="false" :show-file-list="true" :on-change="onChange" :limit="1"  :on-remove="handleRemove" :on-exceed="handleExceed">
+                <i :class="!file ? 'el-icon-upload' : 'el-icon-refresh'"></i>
+                <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
+                <div class="el-upload__tip" slot="tip"></div>
+              </el-upload>
+        </el-form-item>
+        <el-form-item v-if="form.processType==5" label="备注内容:">
+          <el-input type='textarea' v-model="form.remark" autocomplete="off" placeholder="请输入备注"></el-input>
+        </el-form-item>
+      </el-form>
+
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="handleClose">取 消</el-button>
+        <el-button type="primary" @click="finish" >确 定</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  props:['reportId'],
+  data() {
+    return {
+      showDialog: false,
+      loading: false,
+      form: {},
+      rules: {},
+      Already: [],
+      file: [],
+      isFinish: false,
+      timeType: {
+        '1': '提出无效时间',
+        '2': '陈述答复时间',
+        '0': '口审时间',
+        '3': '无效决定时间',
+        '4': '发起诉讼时间',
+      },
+      title: {
+        // type为5是非专利文献,后台未定义
+        '1': '无效请求书',
+        '2': '陈述意见书',
+        '0': '口审记录',
+        '3': '无效决定书',
+        '4': '行政诉讼书',
+        '5': '非专利文献',
+      }
+    }
+  },
+  watch: {
+  },
+  mounted() {
+
+  },
+  methods: {
+    open(form) {
+      this.form = JSON.parse(JSON.stringify(form))
+      this.showDialog=true
+    },
+    // 弹窗确定
+    finish() {
+      if (this.form.processType ==0 ||(this.file && this.file.length > 0)) {
+        var formData = new FormData()
+        this.form.reportId=this.reportId
+        if (this.form.processType != 5) {
+          if (this.file && this.form.processType!=0) {
+            for (var i = 0; i < this.file.length; i++) {
+              formData.append("file", this.file[i]);
+            }
+          }
+          formData.append('invalidProcessStr', JSON.stringify(this.form))
+        } else {
+          if (this.file) {
+            for (var i = 0; i < this.file.length; i++) {
+              formData.append("files", this.file[i]);
+            }
+          }
+          formData.append('proofAddNewDTOStr', JSON.stringify(this.form))
+        }
+        if (this.form.processType != 5) {
+          // 上传无效请求书、口审记录等(无效流程的上传接口)
+          this.addInvalidProcess(formData)
+        } else {
+          // 上传非专利文献
+          this.ProofByFile(formData)
+        }
+      } else {
+        this.$message.error('请上传文件')
+        return false
+      }
+     
+    },
+    // 上传无效请求书
+    addInvalidProcess(formData) {
+      if (!this.form.id) {
+        this.$api.addInvalidProcess(formData).then(response => {
+          if (response.code == 200) {
+            this.isFinish = !this.isFinish
+            this.handleClose()
+            this.$emit('isFinish', this.isFinish)
+            this.$message.success('上传成功')
+          }
+        })
+      } else {
+        this.$api.updateInvalidProcess(formData).then(response => {
+          if (response.code == 200) {
+            this.isFinish = !this.isFinish
+            this.handleClose()
+            this.$emit('isFinish', this.isFinish)
+            this.$message.success('编辑成功')
+          }
+        })
+      }
+    },
+    // 上传非专利文件
+    ProofByFile(formData) {
+      if (!this.form.id) {
+        this.$api.addProofByFile(formData).then(response => {
+          if (response.code == 200) {
+            this.isFinish = !this.isFinish
+            this.handleClose()
+            this.$emit('isFinish', this.isFinish)
+            this.$message.success('上传成功')
+          }
+        }).catch(error => {
+
+        })
+      } 
+      
+    },
+    // 关闭弹窗
+    handleClose() {
+      if (this.form.processType!=0) {
+        this.$refs.upload.clearFiles()
+      }
+      this.showDialog = false
+      this.file = []
+      this.form = {}
+    },
+    onChange(file, fileList) {
+      if (file && file.length>0) {
+        this.$message.error("请选择文件");
+        return false
+      }
+      if (this.form.reportFiles) {
+        var index3 = this.form.reportFiles.findIndex(item => {
+          return item.name + '.' + item.suffix == file.raw.name
+        })
+        if (index3 != -1) {
+
+          this.Already.push(this.form.reportFiles[index3].name)
+          var index2 = fileList.reverse().findIndex(item => {
+            return item.raw.name == file.raw.name
+          })
+          fileList.splice(index2, 1)
+        } else {
+          this.inFile(file, fileList)
+        }
+      } else {
+        this.inFile(file, fileList)
+      }
+      this.$nextTick(() => {
+        var b = ''
+        if (this.Already.length > 0) {
+          this.Already.forEach(item => {
+            b = b + item + ','
+          })
+          this.$alert('文件' + b + '已存在', '提示', {
+            confirmButtonText: '确定',
+            type: 'warning',
+            callback: action => {
+              this.Already = []
+            }
+          });
+
+        }
+      })
+    },
+    inFile(file, fileList) {
+      var index = this.file.findIndex(item => {
+        return item.name == file.raw.name
+      })
+      if (index != -1) {
+        this.Already.push(this.file[index].name)
+        var index2 = fileList.reverse().findIndex(item => {
+          return item.raw.name == file.raw.name
+        })
+        fileList.splice(index2, 1)
+      } else {
+        this.file.push(file.raw)
+      }
+    },
+    handleRemove(file, fileList) {
+      var index = this.file.findIndex(item => {
+        return item.uid == file.raw.uid
+      })
+      if (index != -1) {
+        this.file.splice(index, 1)
+      }
+      // console.log(this.file, fileList);
+    },
+    handleExceed(file, fileList) {
+      this.$message.error('禁止一次上传多个文件')
+    },
+  },
+}
+</script>
+
+<style lang="scss">
+.responseDialog{
+  .el-dialog__body{
+    padding-bottom: 0px;
+  }
+}
+</style>

+ 175 - 0
RMS-FrontEnd/src/views/report/InvalidResponse/import/components/importPatent.vue

@@ -0,0 +1,175 @@
+<template>
+    <div class="import-patent">
+    <el-container class="import-patent">
+      <el-main class="import-patent-main">
+        <el-container class="import-patent-action">
+          <el-main class="import-patent-action-main" v-loading="loading">
+            <el-form :model="form"> 
+              <el-form-item label="数据来源:">
+                <select style="width:390px;border:0;outline:none" name="" id="" v-model="sourceId">
+                  <option value="">请选择数据来源</option>
+                  <option v-for="item in customField.dataType" :value="item.id">{{item.name}}</option>
+                </select>
+                <el-divider ></el-divider>
+              </el-form-item>
+              
+              <el-form-item label="选择需要上传的专利信息导入文件">
+                <el-upload class="upload-file" drag action="#" :auto-upload="false" :show-file-list="false" :on-change="onChange">
+                  <i :class="!form.file ? 'el-icon-upload' : 'el-icon-refresh'"></i>
+                  <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
+                  <div class="el-upload__tip" slot="tip"></div>
+                </el-upload>
+              </el-form-item>
+            </el-form>
+          </el-main>
+        </el-container>
+
+        <systemTask ref="systemTask" :form="1" :reportId="reportId"></systemTask>
+      </el-main>
+    </el-container>
+  </div>
+</template>
+
+<script>
+import systemTask from './systemTask.vue'
+export default {
+  props:['reportId'],
+  components: {
+    systemTask
+  },
+  data() {
+    return {
+      form: {},
+      sourceId: '',
+      customField: [],
+      loading:false,
+    }
+  },
+  computed: {},
+  mounted() {
+    this.getCustomField()
+console.log(this.reportId);
+  },
+  methods: {
+    getCustomField() {
+      this.$api.getCustomField({ projectId: 0, patentTotal: false }).then(response => {
+        this.customField = response.data
+      })
+    },
+    getQueueList() {
+      this.$refs.systemTask.getQueueList()
+    },
+    onChange(file, fileList) {
+      this.form.file = file.raw
+      this.handleConfirm()
+    },
+    handleConfirm() {
+      const json = JSON.parse(JSON.stringify(this.form))
+      const refs = this.$refs
+     
+      let data = {
+        reportId: this.reportId,
+        sourceId:this.sourceId,
+        fieldList: [],
+        folderIds: refs.folderTree ? refs.folderTree.getCheckedKeys() : []
+      }
+      for (let uid in json.field) {
+        const field = json.field[uid]
+        if (!field) {
+          continue;
+        }
+        const type = field.type
+        const value = field.value
+        if (value) {
+          if (type === 5) {
+            value.map(option => {
+              data.fieldList.push({
+                fieldId: parseInt(id),
+                type: type,
+                optionId: option
+              })
+            })
+          } else if (type === 6) {
+            const tree = refs[id]
+            if (tree) {
+              const treeNode = tree[0].getCheckedKeys()
+              treeNode.map(node => {
+                data.fieldList.push({
+                  fieldId: parseInt(id),
+                  type: type,
+                  optionId: node
+                })
+              })
+            }
+          } else {
+            data.fieldList.push({
+              fieldId: parseInt(id),
+              type: type,
+              optionId: [0, 1, 2].indexOf(type) === -1 ? value : 0,
+              text: value
+            })
+          }
+        }
+      }
+      if (!this.form.file) {
+        this.$message.error('请选择文件')
+        return false
+      }
+      if (!this.sourceId) {
+        this.$message.error('请选择数据类型')
+        return false
+      }
+      let formData = new FormData()
+      formData.append('file', this.form.file)
+      formData.append('json', JSON.stringify(data))
+      this.btnLoading = true
+      this.loading = true
+      // console.log(formData)
+      this.$api.importProjectPatent(formData).then(response => {
+        this.$message.success('任务创建成功')
+        this.form.file = null
+        this.btnLoading = false
+        this.loading = false
+        // this.handleClose()
+        this.getQueueList()
+      }).catch(error => {
+        this.btnLoading = false
+        this.loading = false
+      })
+    }
+  },
+}
+</script>
+
+<style lang="scss">
+.el-divider--horizontal{
+  margin:0
+}
+.import-patent {
+  height: 100%;
+  .import-patent-main {
+    padding: 0;
+    height: 100%;
+    background: #fff;
+  }
+  .import-patent-action {
+    width: 450px;
+    height: 100%;
+    border-right: 1px solid #d2d2d2;
+    float: left;
+    .custom-field-form .el-form-item__label {
+      font-weight: bold !important;
+    }
+    .import-patent-action-form {
+      margin-left: 20px;
+    }
+    .import-patent-action-main {
+      padding: 10px;
+    }
+  }
+  .import-patent-button {
+    height: 70px !important;
+    text-align: right;
+  }
+}
+</style>

+ 294 - 0
RMS-FrontEnd/src/views/report/InvalidResponse/import/components/systemTask.vue

@@ -0,0 +1,294 @@
+<template>
+  <div>
+    <el-container>
+      <el-header class="position_relative">
+        <div class="header-tabs">
+          <el-tabs v-model="activeName" type="card">
+            <el-tab-pane label="实时进度" name="0"></el-tab-pane>
+            <el-tab-pane label="任务列表" name="1"></el-tab-pane>
+          </el-tabs>
+        </div>
+      </el-header>
+      <el-main class="system-task-main">
+        <div v-if="activeName === '0'" key="task1">
+            <el-table :data="taskData" border header-row-class-name="custom-table-header" v-loading="loadingCancel" element-loading-text = "请耐心等待,数据正在加载中...">
+              <el-table-column v-if="form === 1" label="文件名称" prop="oldName" align="center" show-overflow-tooltip></el-table-column>
+              <el-table-column label="任务数量" prop="total" align="center" show-overflow-tooltip>
+                <template slot-scope="scope">
+                  <div>
+                    <span>{{ scope.row.total?scope.row.total:scope.row.allNum }}</span>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="当前下标" prop="index" align="center" show-overflow-tooltip>
+                <template slot-scope="scope">
+                  <div>
+                    <span>{{ scope.row.index?scope.row.index:scope.row.successNum }}</span>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="实时进度" align="center" min-width="200px" show-overflow-tooltip>
+                <template slot-scope="scope">
+                  <el-progress :text-inside="true" :stroke-width="20" :percentage="scope.row.percentage?scope.row.percentage:scope.row.taskProcess" :color="customColors"></el-progress>
+                </template>
+              </el-table-column>
+              <el-table-column label="当前状态" align="center" v-if="form == 8" min-width="100px" show-overflow-tooltip>
+                <template slot-scope="scope">
+                  <span>{{ statusObj[scope.row.taskDetailState] }}</span>
+                <!-- <span v-if="scope.row.taskDetailState!=5">{{ scope.row.taskType?'进行中':'等待中' }}</span>
+                <span v-else>已取消</span> -->
+                </template>
+              </el-table-column>
+              <el-table-column v-if="form === 2" label="操作" align="center" width="120" show-overflow-tooltip>
+                <template slot-scope="scope">
+                  <span v-if="!scope.row.url">等待中</span>
+                  <el-link v-else type="primary" @click.native="handleDownload(scope.row)">下载文件</el-link>
+                </template>
+              </el-table-column>
+            </el-table>
+        </div>
+        <div v-else key="task2">
+          <el-table v-loading="loading" :data="tableData" border header-row-class-name="custom-table-header" @sort-change="sortChange">
+            <el-table-column label="文件名称" prop="oldName" align="center" show-overflow-tooltip></el-table-column>
+           
+            <el-table-column  label="开始时间" align="center" show-overflow-tooltip>
+              <template slot-scope="scope">
+                <span >{{ $d(scope.row.startTime) }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column  label="结束时间" align="center" show-overflow-tooltip>
+              <template slot-scope="scope">
+                <span>{{ $d(scope.row.endTime) }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="任务状态" align="center" show-overflow-tooltip>
+              <template slot-scope="scope">
+                <span >{{ statusObj[scope.row.status] }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column prop="createName" label="创建人" align="center" width="120" show-overflow-tooltip></el-table-column>
+            <el-table-column label="操作" align="center" width="120" show-overflow-tooltip>
+              <template slot-scope="scope" v-if="scope.row.status !== 0">
+                <el-link type="primary" @click.native="handleDownload(scope.row)">下载</el-link>
+                <el-link class="margin-left_10" type="danger" @click.native="handleDelete(scope.row)" >删除</el-link>
+              </template>
+            </el-table-column>
+          </el-table>
+          <div class="pagination">
+            <el-pagination :current-page.sync="queryParams.current" :page-size="queryParams.size" :total="total" @current-change="handleCurrentChange" layout="total, prev, pager, next, jumper" background></el-pagination>
+          </div>
+        </div>
+      </el-main>
+    </el-container>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from "vuex";
+import { downLoad2, getFileName } from "@/utils";
+export default {
+  props:['form','reportId'],
+  data() {
+    return {
+      activeName: '0',
+      taskData: [],
+      loading: false,
+      loadingCancel:false,
+      total: 0,
+      tableData: [],
+      queryParams: {
+        state:0,
+        size: 10,
+        current: 1,
+        reportId: 0
+      },
+      statusObj: {
+        0: '队列中',
+        1: '进行中',
+        2: '成功',
+        3: '失败',
+      },
+      customColors: [
+        {color: '#f56c6c', percentage: 20},
+        {color: '#e6a23c', percentage: 40},
+        {color: '#5cb87a', percentage: 60},
+        {color: '#1989fa', percentage: 80},
+        {color: '#6f7ad3', percentage: 100}
+      ],
+      taskType: {
+        1: '专利导入',
+        2: '专利导出',
+        3: '说明书导入',
+      },
+      webSocket1:null,
+    }
+  },
+  computed: {
+    // ...mapGetters(['webSocket', 'userinfo'])
+    userinfo() {
+        return this.$store.state.admin.userinfo
+    }
+  },
+  watch: {
+    activeName(val){
+      if(val==1){
+        this.getList()
+      }else{
+        this.getQueueList()
+      }
+    },
+    'userinfo.id'() {
+      this.connectWebSocket(this.userinfo.id)
+    }
+  },
+  mounted() {
+    console.log(this.reportId);
+    this.getQueueList()
+    // this.initTask()
+    if (this.userinfo.id) {
+      this.connectWebSocket(this.userinfo.id)
+    }
+  },
+  methods: {
+    connectWebSocket(userId) {
+      this.webSocket1 = new WebSocket(`ws://${this.$c.hostname}:8877/api/v2/ws/` + userId)
+      // this.webSocket1 = new WebSocket(`ws://192.168.1.24:8877/api/v2/ws/` + userId)
+
+      // Store.commit('SET_WEB_SOCKET', webSocket)
+      this.webSocket1.onopen = () => {
+        console.log('WebSocket连接成功')
+        this.initTask()
+        return true
+      }
+      // webSocket.onmessage = async (e) => {
+      //   console.log(e)
+      // }
+      this.webSocket1.onerror = () => {
+        console.log('WebSocket连接失败')
+      }
+      this.webSocket1.onclose = () => {
+        console.log('WebSocket连接关闭')
+      }
+    },
+    initTask() {
+      if(this.webSocket1){
+      this.webSocket1.onmessage = (e) => {
+        const { code, data, message } = JSON.parse(e.data)
+        if (code === 903 || code === 904) {
+          const index = this.taskData.map(item => item.taskId).indexOf(data.taskId)
+          if (index === -1) {
+          } else {
+            this.$set(this.taskData, index, data)
+          }
+          if (data.complete) {
+            if(this.form==1){
+              this.$message.success(`导入任务完成`)
+               for(var i = 0;i<this.taskData.length;i++){
+              if(this.taskData[i].complete==true){
+                this.taskData.splice(i,1)
+              }
+            }
+            }else{
+              this.$message.success(`导出任务完成`)
+            }
+            this.getList()
+          }
+        } else if (code === 803 || code === 804) {
+          this.$message.error(message)
+          this.getList()
+        }
+      }
+    }
+    },
+    getQueueList() {
+      this.taskData = []
+      this.queryParams.reportId = this.reportId
+      this.queryParams.state=0
+      this.$api.getQueueList(this.queryParams).then(response => {
+        console.log(response);
+        response.data.map(item => {
+          this.taskData.push({
+            reportId: item.reportId,
+            total: item.importCount,
+            index: 0,
+            taskId: item.id,
+            oldName: item.taskName,
+            complete: false,
+            url: '',
+            fileName: '',
+            taskType: item.type,
+            percentage: 0
+          })
+        })
+      })
+    },
+    getList() {
+      this.loading = true
+      this.queryParams.state = 2
+      this.queryParams.reportId = this.reportId
+      this.$api.getTaskList(this.queryParams).then(response => {
+        this.tableData = response.data.records
+        this.total = response.data.total
+        this.loading = false
+      }).catch(error => {
+        this.loading = false
+      })
+    },
+    handleDownload(row) {
+      downLoad2(row.filePath)
+    },
+    handleDelete(row) {
+      this.$confirm('确认删除本条数据吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.loading = true
+        this.$api.deleteTask({ id: row.id }).then(response => {
+          this.$message.success('删除成功')
+          this.loading = false
+          this.getList()
+        }).catch(error => {
+          this.loading = false
+        })
+      })
+    },
+    // 排序
+    sortChange() { },
+    handleCurrentChange(val) {
+      this.queryParams.current = val;
+      this.getList();
+    },
+  },
+}
+</script>
+
+<style lang="scss">
+.system-task {
+  // height: 100%;
+  height: 500px;
+  overflow: auto;
+  .system-task-main {
+    background: #fff;
+    padding: 5px 20px;
+    margin-top: 20px;
+  }
+  .header-tabs {
+    position: absolute;
+    bottom: 0;
+    height: 100%;
+    padding-right: 9px;
+    left: 12px;
+    .el-tabs {
+      margin-top: 19px;
+    }
+    .el-tabs__header {
+      margin-bottom: 0 !important;
+    }
+  }
+  .pagination {
+    text-align: center;
+    margin: 20px 0;
+  }
+}
+</style>

+ 32 - 0
RMS-FrontEnd/src/views/report/InvalidResponse/import/index.vue

@@ -0,0 +1,32 @@
+<template>
+  <div>
+    <importPatent :reportId="id"></importPatent>
+  </div>
+</template>
+
+<script>
+import importPatent from './components/importPatent.vue'
+export default {
+  components: {
+    importPatent
+  },
+  data() {
+    return {
+
+    }
+  },
+  computed: {
+    id() {
+      return this.$route.query.id
+    }
+  },
+  mounted() {
+
+  },
+  methods: {},
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 86 - 0
RMS-FrontEnd/src/views/report/InvalidResponse/index.vue

@@ -0,0 +1,86 @@
+<template>
+  <div>
+    <el-container>
+        <el-aside width="210px" style="overflow:hidden" class="patent-articles-menu">
+          <el-menu class="theme-dark" :default-active="activeMenu" @select="handleSelect">
+            <el-menu-item v-for="item in menuList" :index="item.path" v-if="!item.show">
+              <i class="el-icon-film"></i>
+              <span slot="title">{{item.title}}</span>
+            </el-menu-item>
+          </el-menu>
+        </el-aside>
+        <el-container>
+          <el-main class="admin-main-box">
+            <component :is="activeMenu" :reportId="reportId" :signPatentNo="signPatentNo" :reportType="reportType"></component>
+          </el-main>
+        </el-container>
+      </el-container>
+  </div>
+</template>
+
+<script>
+import BasicInformation from '@/views/report/reportDetails/components/basicMessage.vue';
+import InvalidIndex from "./components/InvalidIndex.vue"
+import EvidenceAndRequest from "./components/evidenceAndRequest.vue"
+import ChoseOpinion from "./components/choseOpinion.vue"
+import OpinionPlan from "./components/opinionPlan.vue"
+import FlowPath from "./components/flowPath.vue"
+import RemarryMatter from '@/views/report/components/matter/remarryMatter.vue';
+import TaskDetails from '@/views/report/reportDetails/components/taskDetails.vue';
+export default {
+  components: {
+    BasicInformation,
+    InvalidIndex,
+    EvidenceAndRequest,
+    ChoseOpinion,
+    OpinionPlan,
+    FlowPath,
+    RemarryMatter,
+    TaskDetails,
+
+  },
+  data() {
+    return {
+      activeMenu:'BasicInformation',
+      menuList: [
+        {title: '基本信息', path:"BasicInformation"},
+        {title: '无效理由和证据', path:"InvalidIndex"},
+        {title: '证据文献', path:"EvidenceAndRequest"},
+        {title: '生成陈述意见方案', path:"ChoseOpinion"},
+        {title: '导出陈述意见方案', path:"OpinionPlan"},
+        {title: '无效应对流程', path:"FlowPath"},
+        {title: '后续跟进事项', path:"RemarryMatter",show:(this.row && this.row.status==3 && this.$permission('/rms/matter'))?true:false},
+        // {title: '后续跟进事项', path:"RemarryMatter",},
+        {title: '任务清单', path:"TaskDetails"},
+      ],
+    }
+  },
+  computed: {
+    reportId() {
+      return this.$s.getSession('params').id
+    },
+    signPatentNo() {
+      return this.$s.getSession('params').signPatentNo
+    },
+    reportType() {
+      return this.$s.getSession('params').type
+    },
+    row() {
+      return this.$s.getSession('params')
+    },
+  },
+  watch: {},
+  mounted() {
+    console.log(this.row);
+  },
+  methods: {
+    handleSelect(index, path) {
+      this.activeMenu = index
+    },
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 2 - 1
RMS-FrontEnd/src/views/report/components/Card.vue

@@ -23,7 +23,8 @@
                         <el-dropdown-item command="10" v-if="[0,1,2,3].includes(item.type)&&[2].includes(item.status) && $reportPermission(item.id,[0,1])"> 添加对比文件</el-dropdown-item>
                         <el-dropdown-item command="11" v-if="[1,2].includes(item.status) && $reportPermission(item.id,[0,1])"> 完成报告</el-dropdown-item>
                         <el-dropdown-item command="12"  v-if="[3].includes(item.status) && $reportPermission(item.id,[0,1])">添加追踪报告</el-dropdown-item>
-
+                        <el-dropdown-item command="13" v-if="(item.type == 7 && [2,3].includes(item.status)) && $reportPermission(item.id,[0,1])">添加无效理由和证据</el-dropdown-item>
+                        <el-dropdown-item command="14" v-if="(item.type == 7 && [2,3].includes(item.status)) && $reportPermission(item.id,[0,1])">导入无效证据</el-dropdown-item>
                         <!-- <el-dropdown-item command="6" v-if="[2,3].includes(item.status)&& item.type != 4">导入 </el-dropdown-item> -->
                         <el-dropdown-item command="7" divided style="color: red; " v-if="$reportPermission(item.id,[0,1])">删除 </el-dropdown-item>
                         <!-- <el-dropdown-item command="0">分享</el-dropdown-item> -->

+ 97 - 6
RMS-FrontEnd/src/views/report/components/CreateReport.vue

@@ -85,6 +85,21 @@
                 <el-option v-for="item in copyList" :key="item.dictChildValue" :label="item.dictChildLabel" :value="item.dictChildValue"></el-option>
               </el-select>
             </el-form-item>
+            <el-form-item label="案件编号" v-if="form.type==7">
+              <el-input v-model="form.caseNumber" autocomplete="off" placeholder="请输入案件编号"></el-input>
+            </el-form-item>
+            <el-form-item label="发文序号"  v-if="form.type==7">
+              <el-input v-model="form.issueNumber" autocomplete="off" placeholder="请输入发文序号"></el-input>
+            </el-form-item>
+            <el-form-item label="发明创造名称"  v-if="form.type==7">
+              <el-input v-model="form.inventionName" autocomplete="off" placeholder="请输入发明创造名称"></el-input>
+            </el-form-item>
+            <el-form-item label="专利权人"  v-if="form.type==7">
+              <el-input v-model="form.currentApplication" autocomplete="off" placeholder="请输入专利权人"></el-input>
+            </el-form-item>
+            <el-form-item label="无效宣告请求人"  v-if="form.type==7">
+              <el-input v-model="form.invalidApplication" autocomplete="off" placeholder="请输入无效宣告请求人"></el-input>
+            </el-form-item>
             <el-form-item label="卷号" prop="volumeNumber" >
               <el-input v-model="form.volumeNumber" autocomplete="off" placeholder="请输入卷号"></el-input>
             </el-form-item>
@@ -109,7 +124,8 @@
         </el-form>
         <span slot="footer" class="dialog-footer" v-if="$reportPermission(form.id,[0,1])">
               <el-button @click="handleClose">取 消</el-button>
-              <el-button type="primary" @click="ifDialog" >确 定</el-button>
+              <el-button type="primary" @click="ifNext " v-if="form.type==7 && !form.id">下一步</el-button>
+              <el-button type="primary" @click="ifDialog "  v-else>确 定</el-button>
         </span>
     </el-dialog>
     <el-dialog title="添加审核任务" :visible.sync="showTask" width="500px"  @close="handleCloseTask">
@@ -147,6 +163,10 @@
       
       <!-- <div v-html="imageUrl"></div> -->
     </el-dialog>
+
+    <el-dialog :visible.sync="showEvidenceAndRequest" width="1000px" :close-on-click-modal="false">
+      <evidenceAndRequest ref="evidence" :examine="true" @show="showEvidenceAndRequest = false"></evidenceAndRequest>
+    </el-dialog>
   </div>
 </template>
 
@@ -157,6 +177,7 @@ import { PatentDetails } from "@/views/components/common/mixins";
 import PersonnelList from './personnelList.vue'
 import Menu from '@/views/components/common/menu/index.vue'
 import addMatter from "./matter/addMatter.vue";
+import evidenceAndRequest from "@/views/report/InvalidResponse/components/evidenceAndRequest.vue";
 
 export default {
   props: ['isTrue'],
@@ -165,7 +186,8 @@ export default {
     SelectTree,
     PersonnelList,
     addMatter,
-    Menu
+    Menu,
+    evidenceAndRequest,
   },
   data() {
     //校验部门是否为空
@@ -302,7 +324,10 @@ export default {
       Already:[],
       load_text: '',
       isEndTime:true,
-      isEndTimes:null,
+      isEndTimes: null,
+      newReportId: null,
+      formCopy: {},
+      showEvidenceAndRequest:false,
     };
   },
   computed: {
@@ -320,6 +345,7 @@ export default {
     this.getAllClientList()
     this.getAllDepartmentList()
     this.getDictsFromPAS()
+    console.log(this.$refs.evidence);
   },
   methods: {
     //隐藏popover
@@ -633,7 +659,7 @@ export default {
         // }
     },
     //接收创建报告类型
-    open(row,dictMessage) {
+    open(row, dictMessage) {
       this.tenantType = this.userinfo.tenantType
       this.verify=true
       var a = ''
@@ -758,7 +784,7 @@ export default {
                             this.file = []
                             // this.$refs.upload.clearFiles()
                             this.$message.success('报告创建成功')
-                            this.$emit('getList',true)
+                            this.$emit('getList', true)
                             this.handleClose()
                           }
                         })
@@ -796,7 +822,14 @@ export default {
                           this.file = []
                           // this.$refs.upload.clearFiles()
                           this.$message.success('报告创建成功')
-                          this.$emit('getList',true)
+                          this.$emit('getList', true)
+                          // if (this.form.type == 7) {
+                          //   this.formCopy=JSON.parse(JSON.stringify(this.form))
+                          //   this.getQueryReport()
+                          //   setTimeout(() => {
+                          //     this.toInvalidResponset()
+                          //   },1000)
+                          // }
                           this.handleClose()
                         }
                       })  
@@ -843,6 +876,64 @@ export default {
         }
       });
     },
+    // 无效应对报告下一步
+    ifNext() {
+      this.$refs.reportForm.validate((valid) => {
+        if (valid) {
+          let formData = new FormData()
+          if (this.file) {
+            for (var i = 0; i < this.file.length; i++) {
+              formData.append("files", this.file[i]);
+            }
+          }
+          formData.append('report', JSON.stringify(this.form))
+           this.$api.AddReport(formData).then(response => {
+            if (response.code == 200) {
+              this.file = []
+              this.formCopy = JSON.parse(JSON.stringify(this.form))
+              // this.$refs.upload.clearFiles()
+              // this.$message.success('报告创建成功')
+              this.$emit('getList', true)
+              this.handleClose()
+              this.openDialog(response.data)
+            }
+          })
+        }
+      })
+      
+      // this.ifDialog()
+    },
+   async openDialog(id) {
+      await  this.getQueryReport()
+        this.showEvidenceAndRequest = true
+        console.log(this.$refs.evidence);
+        this.$nextTick(() => {
+          // this.$refs.evidence.open(id)
+          this.$s.setSession('params', this.newReportId)
+          this.$refs.evidence.open(this.newReportId,id)
+        })
+    },
+    async getQueryReport() {
+      let a = {
+        current:1,
+        size:10
+      }
+      await this.$api.QueryReport(a).then(response=>{
+        if (response.code == 200) {
+          this.newReportId=response.data[0]
+        }
+      }).catch(error=>{
+      })
+    },
+    // toInvalidResponset() {
+    //   this.$router.push({
+    //     path: '/evidenceAndRequest',
+    //     query: {
+    //       patentNo: this.form.patentNo,
+    //       reportId: this.newReportId.id,
+    //     }
+    //   })
+    // },
     // 弹出框关闭
     handleClose() {
       if (!this.form.id) {

+ 2 - 0
RMS-FrontEnd/src/views/report/components/Tabel.vue

@@ -57,6 +57,8 @@
               <el-dropdown-item command="10" v-if="[0,1,2,3].includes(scope.row.type)&&[2].includes(scope.row.status) && $reportPermission(scope.row.id,[0,1])"> 添加对比文件</el-dropdown-item>
               <el-dropdown-item command="11" v-if="[1,2].includes(scope.row.status) && $reportPermission(scope.row.id,[0,1])"> 完成报告</el-dropdown-item>
               <el-dropdown-item command="12" v-if="[3].includes(scope.row.status) && $reportPermission(scope.row.id,[0,1])">添加追踪报告</el-dropdown-item>
+              <el-dropdown-item command="13" v-if="(scope.row.type == 7 && [1,2,3].includes(scope.row.status)) && $reportPermission(scope.row.id,[0,1])">添加无效理由和证据</el-dropdown-item>
+              <el-dropdown-item command="14" v-if="(scope.row.type == 7 && [1,2,3].includes(scope.row.status)) && $reportPermission(scope.row.id,[0,1])">导入无效证据</el-dropdown-item>
               <!-- <el-dropdown-item command="6" v-if="[2,3].includes(scope.row.status)&& scope.row.type != 4">导入 </el-dropdown-item> -->
               <el-dropdown-item command="7" divided style="color: red;" v-if=" $reportPermission(scope.row.id,[0,1])">删除 </el-dropdown-item>
             </el-dropdown-menu>

+ 1 - 1
RMS-FrontEnd/src/views/report/components/matter/remarryMatter.vue

@@ -2,7 +2,7 @@
     <div>
         <div style="display: flex;justify-content: flex-end; margin-bottom: 20px;" v-if="$reportPermission(reportId,[0,1])">
             <el-dropdown trigger="click" split-button type="primary" size="small" @command="handleCommand($event)" >
-               <span @click="handleClick(1)">添加后续事项</span>
+               <P @click="handleClick(1)" >添加后续事项</P>
                 <el-dropdown-menu slot="dropdown" class="text-align_center">
                     <el-dropdown-item command="1">添加后续事项</el-dropdown-item>
                     <el-dropdown-item command="2">批量添加后续事项</el-dropdown-item>

+ 98 - 0
RMS-FrontEnd/src/views/report/components/mixins.js

@@ -167,6 +167,104 @@ export const explain = {
   },
 }
 
+export const explain1 = {
+  data() {
+    return {
+      innerHTML:''
+    }
+  },
+  methods: {
+    // getValue(row, name, innerHtml) {
+    //   // this.innerHTML = innerHtml
+    //   // console.log(row,innerHtml,this.innerHTML);
+    //   // row[name] = this.innerHTML
+    // },
+    saveValue(row, name, innerHtml) {
+      // console.log(row,this.innerHTML,innerHtml);
+      console.log(row, name, innerHtml);
+      row[name] = innerHtml
+
+    },
+    //粘贴图片
+    handlePaste(event, row, name,index) {
+      var e = event || window.event
+        e.preventDefault();
+        const items = (event.clipboardData || window.clipboardData).items;
+        // console.log(items)
+        let file = null;
+        if (!items || items.length === 0) {//?
+          this.$message.error("当前浏览器不支持本地");
+          return;
+        }
+        for (let i = 0; i < items.length; i++) {
+          if (items[i].type.indexOf("text") !== -1) {
+            var text =  (e.originalEvent || e).clipboardData.getData('text/plain') || prompt('在这里输入文本');
+            //清除回车
+            text = text.replace(/\[\d+\]|\n|\r/ig,"")
+            if (index == 0 || index) {
+              var str = row[name][index] ? row[name][index] : ''
+              this.$set(row[name][index],'content' , e.target.innerHTML + text)
+              this.setValue(row,name,e.target.innerHTML + text,index)
+            } else {
+              var str = row[name] ? row[name] : ''
+              this.$set(row, name, e.target.innerHTML + text)
+              this.setValue(row,name, e.target.innerHTML + text)
+            }
+            break;
+          }
+          if (items[i].type.indexOf("image") !== -1) {
+            file = items[i].getAsFile();
+            break;
+          }
+        }
+        if (!file) {
+          this.$message.error("粘贴内容非图片");
+          return;
+        }
+        const reader = new FileReader();
+        reader.onload = (event) => {
+          var blobUrl = event.target.result
+          // console.log(blobUrl,event)
+          var new_img = '<img src="' + blobUrl + '" style="width:80px;height: 80px;border: 1px solid #f9f6f675;vertical-align:middle"/>';
+          
+         
+          if (index == 0 || index) {
+            var str = row[name][index]?row[name][index]:''
+            // this.$set(row, name[index], str + new_img)
+            row[name][index].content = e.target.innerHTML + new_img
+            e.target.innerHTML = row[name][index].content
+            console.log(row,name[index],name,str+new_img,);
+          } else {
+            var str = row[name]?row[name]:''
+            this.$set(row, name, e.target.innerHTML + new_img)
+            e.target.innerHTML=row[name]
+          }
+          this.refreshData = false
+          this.$nextTick(() => {
+         this.refreshData = true
+            e.target.onfocus = function(){}
+         })
+          // if(this.tableHeight){
+          //   this.setHeight()
+          // }
+         
+         
+        };
+        reader.readAsDataURL(file);
+        this.pasteFile = file;
+    },
+    setValue( row, name, innerHtml) {
+      this.$set(row, name, innerHtml)
+        // this.refreshData = false
+        // this.$nextTick(() => {
+        //   this.refreshData = true
+        //   event.target.click()
+        //   console.log(event.target, event.target.style)
+        // })
+    },
+  },
+}
+
 export const editContrast = {
   methods: {
     editContrast(patentNo){

+ 40 - 2
RMS-FrontEnd/src/views/report/index.vue

@@ -130,6 +130,8 @@ import shareReport from './components/share/shareReport.vue';
 import ReportVisual from './components/visual/reportVisual.vue';
 
 import CronConclusion from './components/cronConclusion.vue';
+
+import InvalidIndex from "@/views/report/InvalidResponse/components/InvalidIndex.vue"
 export default {
   components: {
     ReportTabel,
@@ -140,7 +142,8 @@ export default {
     ProjectFileDrawer,
     shareReport,
     ReportVisual,
-    CronConclusion
+    CronConclusion,
+    InvalidIndex,
   },
   data() {
     return {
@@ -183,8 +186,8 @@ export default {
   },
   computed: {
     dictMessage() {
-      // console.log(111,this.$store.state.dictMessage.dictMessage);
       var a = this.$store.state.dictMessage.dictMessage
+      console.log(111,this.$store.state.dictMessage.dictMessage);
       if(a.REPORT_TYPE){
         a.REPORT_TYPE.forEach(item=>{
           if(['0','1','2'].includes(item.dictChildValue)){
@@ -195,6 +198,8 @@ export default {
             item.permission = 'tort'
           }else if(item.dictChildValue == 5){
             item.permission = 'avoidDesign'
+          }else if (item.dictChildValue == 7) {
+            item.permission = 'InvalidResponse'
           }
         })
       }
@@ -317,6 +322,13 @@ export default {
             window.open(router.href, '_blank');
           break;
         case 6:
+          break;
+        case 7:
+            var router = this.$router.resolve({
+              name: 'InvalidResponse',
+            })
+            window.open(router.href, '_blank');
+          break;
       }
       
 
@@ -392,11 +404,37 @@ export default {
         // associateReportName:this.row.volumeNumber?this.row.volumeNumber:this.row.name,
         //         associateReportId:this.reportId
             break
+        case '13'://添加无效理由和证据
+          this.toInvalidIndex(row)
+            break;
+        case '14'://导入无效证据
+          this.toInvalidResponset(row)
+            break;
         case 'e':
           this.handleEdit(row)
           break
       }
     },
+    // 导入无效证据
+    toInvalidResponset(row) {
+      this.$router.push({
+        path: '/evidenceAndRequestIndex',
+        query: {
+          patentNo: row.signPatentNo,
+          reportId: row.id,
+        }
+      })
+    },
+    toInvalidIndex(row) {
+      this.$router.push({
+        path: '/invalidIdexRouter',
+        query: {
+          patentNo: row.signPatentNo,
+          reportId: row.id,
+          reportType: row.reportType || row.type,
+        }
+      })
+    },
     //追踪报告
     trackReport(row){
       var form = JSON.parse(JSON.stringify(row))

+ 5 - 4
RMS-FrontEnd/src/views/task/MyHandle.vue

@@ -174,10 +174,10 @@
 			<el-descriptions-item label="备注">{{form.remark}}</el-descriptions-item>
   		</el-descriptions> -->
         <span slot="footer" class="dialog-footer">
-              <el-button @click="handleClose">取 消</el-button>
-			  <el-dropdown split-button type="primary" @click="submit">
-				{{btn.label}}
-				<el-dropdown-menu slot="dropdown">
+              <el-button @click="handleClose" size="small">取 消</el-button>
+			  <el-dropdown split-button type="primary" @click="submit" size="small">
+				<p>{{btn.label}}</p>
+				<el-dropdown-menu slot="dropdown" class="text-align_center">
 					<el-dropdown-item v-for="item in btnObj" :key="item.label" @click.native="onChangeFamily(item)">{{ item.label }}</el-dropdown-item>
 				</el-dropdown-menu>
 			  </el-dropdown>
@@ -360,6 +360,7 @@ import Menu from '@/views/components/common/menu/index.vue'
 	  },
 	  //完成任务
     handleEdit(row) {
+      console.log(row);
       switch (row.type) {
         case 0://开卷
           this.bookReviewTask(row)