Explorar o código

Merge branch 'respond' into dev

zhuliu %!s(int64=2) %!d(string=hai) anos
pai
achega
eb4a6a593c
Modificáronse 100 ficheiros con 15637 adicións e 628 borrados
  1. 54 21
      RMS-FrontEnd/package-lock.json
  2. 3 2
      RMS-FrontEnd/package.json
  3. 177 0
      RMS-FrontEnd/src/App.vue
  4. 273 0
      RMS-FrontEnd/src/api/InvalidResponse.js
  5. 28 0
      RMS-FrontEnd/src/api/highlight.js
  6. 8 2
      RMS-FrontEnd/src/api/index.js
  7. 97 0
      RMS-FrontEnd/src/api/quartz.js
  8. 4 4
      RMS-FrontEnd/src/assets/css/activeDiv.scss
  9. 2 1
      RMS-FrontEnd/src/config/index.js
  10. 539 0
      RMS-FrontEnd/src/icons/icon/demo.css
  11. 37 0
      RMS-FrontEnd/src/icons/icon/iconfont.css
  12. 1 0
      RMS-FrontEnd/src/icons/icon/iconfont.js
  13. 44 0
      RMS-FrontEnd/src/icons/icon/iconfont.json
  14. BIN=BIN
      RMS-FrontEnd/src/icons/icon/iconfont.ttf
  15. BIN=BIN
      RMS-FrontEnd/src/icons/icon/iconfont.woff
  16. BIN=BIN
      RMS-FrontEnd/src/icons/icon/iconfont.woff2
  17. 539 0
      RMS-FrontEnd/src/icons/icon2/demo.css
  18. 131 0
      RMS-FrontEnd/src/icons/icon2/iconfont.css
  19. 1 0
      RMS-FrontEnd/src/icons/icon2/iconfont.js
  20. 212 0
      RMS-FrontEnd/src/icons/icon2/iconfont.json
  21. BIN=BIN
      RMS-FrontEnd/src/icons/icon2/iconfont.ttf
  22. BIN=BIN
      RMS-FrontEnd/src/icons/icon2/iconfont.woff
  23. BIN=BIN
      RMS-FrontEnd/src/icons/icon2/iconfont.woff2
  24. 13 1
      RMS-FrontEnd/src/main.js
  25. 51 0
      RMS-FrontEnd/src/router/index.js
  26. 12 1
      RMS-FrontEnd/src/store/modules/patent.js
  27. 8 0
      RMS-FrontEnd/src/store/modules/report.js
  28. 151 0
      RMS-FrontEnd/src/utils/constants.js
  29. 2 2
      RMS-FrontEnd/src/utils/directives.js
  30. 7 2
      RMS-FrontEnd/src/utils/index.js
  31. 45 7
      RMS-FrontEnd/src/views/components/articles/ContrastIndex.vue
  32. 15 15
      RMS-FrontEnd/src/views/components/articles/components/PatentBasic.vue
  33. 1 1
      RMS-FrontEnd/src/views/components/articles/components/PatentInstruction.vue
  34. 123 0
      RMS-FrontEnd/src/views/components/articles/components/PatentMark.vue
  35. 9 7
      RMS-FrontEnd/src/views/components/articles/components/PatentRight.vue
  36. 310 2
      RMS-FrontEnd/src/views/components/articles/components/mixins.js
  37. 270 29
      RMS-FrontEnd/src/views/components/articles/index.vue
  38. 8 0
      RMS-FrontEnd/src/views/components/common/RichText/index.js
  39. 207 0
      RMS-FrontEnd/src/views/components/common/RichText/index.vue
  40. 6 0
      RMS-FrontEnd/src/views/components/common/RichText/mixins.js
  41. 40 0
      RMS-FrontEnd/src/views/components/common/RichText/reviewClass.js
  42. 5 5
      RMS-FrontEnd/src/views/components/common/SplitScreen.js
  43. 196 0
      RMS-FrontEnd/src/views/components/common/components/editDiv.js
  44. 357 0
      RMS-FrontEnd/src/views/components/common/components/mixins.js
  45. 421 0
      RMS-FrontEnd/src/views/components/common/components/search.vue
  46. 74 0
      RMS-FrontEnd/src/views/components/common/components/searchIndex.vue
  47. 149 0
      RMS-FrontEnd/src/views/components/common/components/timeChoose.vue
  48. 19 0
      RMS-FrontEnd/src/views/components/common/components/timeIndex.vue
  49. 409 295
      RMS-FrontEnd/src/views/components/common/mixins.js
  50. 31 0
      RMS-FrontEnd/src/views/components/gaoliang/components/mixins.js
  51. 269 0
      RMS-FrontEnd/src/views/components/gaoliang/components/pizhu.vue
  52. 25 0
      RMS-FrontEnd/src/views/components/gaoliang/index.vue
  53. 309 0
      RMS-FrontEnd/src/views/components/import/PatentNoImport/download.vue
  54. 34 0
      RMS-FrontEnd/src/views/components/import/PatentNoImport/index.vue
  55. 96 0
      RMS-FrontEnd/src/views/components/import/conditionImport/AdvancedSearch.vue
  56. 513 0
      RMS-FrontEnd/src/views/components/import/conditionImport/FormSearch.vue
  57. 406 0
      RMS-FrontEnd/src/views/components/import/conditionImport/components/projectListDialog.vue
  58. 271 0
      RMS-FrontEnd/src/views/components/import/conditionImport/components/search_history.vue
  59. 138 0
      RMS-FrontEnd/src/views/components/import/conditionImport/customSearch.vue
  60. 30 0
      RMS-FrontEnd/src/views/components/import/conditionImport/index.vue
  61. 159 0
      RMS-FrontEnd/src/views/components/import/conditionImport/patentDetails/PatentList.vue
  62. 276 0
      RMS-FrontEnd/src/views/components/import/conditionImport/patentDetails/patentDetail.vue
  63. 140 0
      RMS-FrontEnd/src/views/components/import/conditionImport/patentDetails/patentIndex.vue
  64. 145 0
      RMS-FrontEnd/src/views/components/import/conditionImport/search.vue
  65. 504 0
      RMS-FrontEnd/src/views/components/import/conditionImport/searchResult.vue
  66. 41 0
      RMS-FrontEnd/src/views/components/import/conditionImport/searchResultIndex.vue
  67. 178 0
      RMS-FrontEnd/src/views/components/import/excelImport/importPatent.vue
  68. 32 0
      RMS-FrontEnd/src/views/components/import/excelImport/index.vue
  69. BIN=BIN
      RMS-FrontEnd/src/views/components/task/components/img/loading.gif
  70. 90 0
      RMS-FrontEnd/src/views/components/task/components/mixins.js
  71. 227 0
      RMS-FrontEnd/src/views/components/task/components/realTime.vue
  72. 366 0
      RMS-FrontEnd/src/views/components/task/components/todoList.vue
  73. 133 0
      RMS-FrontEnd/src/views/components/task/components/updateLog.vue
  74. 67 231
      RMS-FrontEnd/src/views/components/task/index.vue
  75. 775 0
      RMS-FrontEnd/src/views/components/task/index1.vue
  76. 30 0
      RMS-FrontEnd/src/views/components/task/taskIndex.vue
  77. 318 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/FileDetails/addOpinions.vue
  78. 120 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/FileDetails/fileDetails.vue
  79. 258 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/FileDetails/index.vue
  80. 276 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/FileDetails/patentDetail.vue
  81. 102 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/InvalidDetails/InvalidDetails.vue
  82. 105 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/InvalidDetails/addInvalidDialog.vue
  83. 318 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/InvalidDetails/table.vue
  84. 361 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/InvalidEvidence.vue
  85. 86 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/InvalidFeatures.vue
  86. 849 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/InvalidIndex.vue
  87. 262 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/TableField.vue
  88. 122 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/addFeatures/rightContent.vue
  89. 503 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/addOpinion.vue
  90. 131 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/addOrEditField.vue
  91. 25 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/checkFile.vue
  92. 259 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/choseOpinion.vue
  93. 355 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/evidenceAndRequest.vue
  94. 37 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/evidenceAndRequestRouter.vue
  95. 177 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/flowPath.vue
  96. 39 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/invalidIdexRouter.vue
  97. 241 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/opinionPlan.vue
  98. 234 0
      RMS-FrontEnd/src/views/report/InvalidResponse/components/responseDialog.vue
  99. 116 0
      RMS-FrontEnd/src/views/report/InvalidResponse/index.vue
  100. 0 0
      RMS-FrontEnd/src/views/report/components/Card.vue

+ 54 - 21
RMS-FrontEnd/package-lock.json

@@ -2963,7 +2963,6 @@
       "version": "1.0.2",
       "resolved": "https://registry.nlark.com/call-bind/download/call-bind-1.0.2.tgz",
       "integrity": "sha1-sdTonmiBGcPJqQOtMKuy9qkZvjw=",
-      "dev": true,
       "requires": {
         "function-bind": "^1.1.1",
         "get-intrinsic": "^1.0.2"
@@ -4241,7 +4240,6 @@
       "version": "1.1.1",
       "resolved": "https://registry.nlark.com/deep-equal/download/deep-equal-1.1.1.tgz",
       "integrity": "sha1-tcmMlCzv+vfLBR4k4UNKJaLmB2o=",
-      "dev": true,
       "requires": {
         "is-arguments": "^1.0.4",
         "is-date-object": "^1.0.1",
@@ -4383,7 +4381,6 @@
       "version": "1.1.3",
       "resolved": "https://registry.nlark.com/define-properties/download/define-properties-1.1.3.tgz",
       "integrity": "sha1-z4jabL7ib+bbcJT2HYcMvYTO6fE=",
-      "dev": true,
       "requires": {
         "object-keys": "^1.0.12"
       }
@@ -5338,8 +5335,7 @@
     "extend": {
       "version": "3.0.2",
       "resolved": "https://registry.nlark.com/extend/download/extend-3.0.2.tgz",
-      "integrity": "sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo=",
-      "dev": true
+      "integrity": "sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo="
     },
     "extend-shallow": {
       "version": "3.0.2",
@@ -5415,6 +5411,11 @@
       "resolved": "https://registry.nlark.com/fast-deep-equal/download/fast-deep-equal-3.1.3.tgz",
       "integrity": "sha1-On1WtVnWy8PrUSMlJE5hmmXGxSU="
     },
+    "fast-diff": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/fast-diff/-/fast-diff-1.1.2.tgz",
+      "integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig=="
+    },
     "fast-glob": {
       "version": "2.2.7",
       "resolved": "https://registry.nlark.com/fast-glob/download/fast-glob-2.2.7.tgz",
@@ -5743,8 +5744,7 @@
     "function-bind": {
       "version": "1.1.1",
       "resolved": "https://registry.nlark.com/function-bind/download/function-bind-1.1.1.tgz",
-      "integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0=",
-      "dev": true
+      "integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0="
     },
     "functional-red-black-tree": {
       "version": "1.0.1",
@@ -5773,7 +5773,6 @@
       "version": "1.1.1",
       "resolved": "https://registry.nlark.com/get-intrinsic/download/get-intrinsic-1.1.1.tgz",
       "integrity": "sha1-FfWfN2+FXERpY5SPDSTNNje0q8Y=",
-      "dev": true,
       "requires": {
         "function-bind": "^1.1.1",
         "has": "^1.0.3",
@@ -5918,7 +5917,6 @@
       "version": "1.0.3",
       "resolved": "https://registry.nlark.com/has/download/has-1.0.3.tgz",
       "integrity": "sha1-ci18v8H2qoJB8W3YFOAR4fQeh5Y=",
-      "dev": true,
       "requires": {
         "function-bind": "^1.1.1"
       }
@@ -5955,14 +5953,12 @@
     "has-symbols": {
       "version": "1.0.2",
       "resolved": "https://registry.nlark.com/has-symbols/download/has-symbols-1.0.2.tgz",
-      "integrity": "sha1-Fl0wcMADCXUqEjakeTMeOsVvFCM=",
-      "dev": true
+      "integrity": "sha1-Fl0wcMADCXUqEjakeTMeOsVvFCM="
     },
     "has-tostringtag": {
       "version": "1.0.0",
       "resolved": "https://registry.nlark.com/has-tostringtag/download/has-tostringtag-1.0.0.tgz?cache=0&sync_timestamp=1628199163867&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fhas-tostringtag%2Fdownload%2Fhas-tostringtag-1.0.0.tgz",
       "integrity": "sha1-fhM4GKfTlHNPlB5zw9P5KR5liyU=",
-      "dev": true,
       "requires": {
         "has-symbols": "^1.0.2"
       }
@@ -6701,7 +6697,6 @@
       "version": "1.1.1",
       "resolved": "https://registry.nlark.com/is-arguments/download/is-arguments-1.1.1.tgz",
       "integrity": "sha1-FbP4j9oB8ql/7ITKdhpWDxI++ps=",
-      "dev": true,
       "requires": {
         "call-bind": "^1.0.2",
         "has-tostringtag": "^1.0.0"
@@ -6797,7 +6792,6 @@
       "version": "1.0.5",
       "resolved": "https://registry.nlark.com/is-date-object/download/is-date-object-1.0.5.tgz",
       "integrity": "sha1-CEHVU25yTCVZe/bqYuG9OCmN8x8=",
-      "dev": true,
       "requires": {
         "has-tostringtag": "^1.0.0"
       }
@@ -6948,7 +6942,6 @@
       "version": "1.1.4",
       "resolved": "https://registry.nlark.com/is-regex/download/is-regex-1.1.4.tgz",
       "integrity": "sha1-7vVmPNWfpMCuM5UFMj32hUuxWVg=",
-      "dev": true,
       "requires": {
         "call-bind": "^1.0.2",
         "has-tostringtag": "^1.0.0"
@@ -8141,8 +8134,7 @@
     "object-assign": {
       "version": "4.1.1",
       "resolved": "https://registry.nlark.com/object-assign/download/object-assign-4.1.1.tgz",
-      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
-      "dev": true
+      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
     },
     "object-copy": {
       "version": "0.1.0",
@@ -8234,7 +8226,6 @@
       "version": "1.1.5",
       "resolved": "https://registry.nlark.com/object-is/download/object-is-1.1.5.tgz",
       "integrity": "sha1-ud7qpfx/GEag+uzc7sE45XePU6w=",
-      "dev": true,
       "requires": {
         "call-bind": "^1.0.2",
         "define-properties": "^1.1.3"
@@ -8243,8 +8234,7 @@
     "object-keys": {
       "version": "1.1.1",
       "resolved": "https://registry.nlark.com/object-keys/download/object-keys-1.1.1.tgz",
-      "integrity": "sha1-HEfyct8nfzsdrwYWd9nILiMixg4=",
-      "dev": true
+      "integrity": "sha1-HEfyct8nfzsdrwYWd9nILiMixg4="
     },
     "object-visit": {
       "version": "1.0.1",
@@ -8540,6 +8530,11 @@
         "no-case": "^2.2.0"
       }
     },
+    "parchment": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/parchment/-/parchment-1.1.4.tgz",
+      "integrity": "sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg=="
+    },
     "parent-module": {
       "version": "1.0.1",
       "resolved": "https://registry.npmmirror.com/parent-module/download/parent-module-1.0.1.tgz?cache=0&sync_timestamp=1633338007897&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fparent-module%2Fdownload%2Fparent-module-1.0.1.tgz",
@@ -9696,6 +9691,36 @@
       "integrity": "sha1-M0WUG0FTy50ILY7uTNogFqmu9/Y=",
       "dev": true
     },
+    "quill": {
+      "version": "1.3.7",
+      "resolved": "https://registry.npmmirror.com/quill/-/quill-1.3.7.tgz",
+      "integrity": "sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==",
+      "requires": {
+        "clone": "^2.1.1",
+        "deep-equal": "^1.0.1",
+        "eventemitter3": "^2.0.3",
+        "extend": "^3.0.2",
+        "parchment": "^1.1.4",
+        "quill-delta": "^3.6.2"
+      },
+      "dependencies": {
+        "eventemitter3": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-2.0.3.tgz",
+          "integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg=="
+        }
+      }
+    },
+    "quill-delta": {
+      "version": "3.6.3",
+      "resolved": "https://registry.npmmirror.com/quill-delta/-/quill-delta-3.6.3.tgz",
+      "integrity": "sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==",
+      "requires": {
+        "deep-equal": "^1.0.1",
+        "extend": "^3.0.2",
+        "fast-diff": "1.1.2"
+      }
+    },
     "randombytes": {
       "version": "2.1.0",
       "resolved": "https://registry.nlark.com/randombytes/download/randombytes-2.1.0.tgz",
@@ -9874,7 +9899,6 @@
       "version": "1.3.1",
       "resolved": "https://registry.nlark.com/regexp.prototype.flags/download/regexp.prototype.flags-1.3.1.tgz",
       "integrity": "sha1-fvNSro0VnnWMDq3Kb4/LTu8HviY=",
-      "dev": true,
       "requires": {
         "call-bind": "^1.0.2",
         "define-properties": "^1.1.3"
@@ -12518,6 +12542,15 @@
         }
       }
     },
+    "vue-quill-editor": {
+      "version": "3.0.6",
+      "resolved": "https://registry.npmmirror.com/vue-quill-editor/-/vue-quill-editor-3.0.6.tgz",
+      "integrity": "sha512-g20oSZNWg8Hbu41Kinjd55e235qVWPLfg4NvsLW6d+DhgBTFbEuMpcWlUdrD6qT3+Noim6DRu18VLM9lVShXOQ==",
+      "requires": {
+        "object-assign": "^4.1.1",
+        "quill": "^1.3.4"
+      }
+    },
     "vue-resize-sensor": {
       "version": "2.0.0",
       "resolved": "https://registry.npmmirror.com/vue-resize-sensor/-/vue-resize-sensor-2.0.0.tgz",

+ 3 - 2
RMS-FrontEnd/package.json

@@ -4,8 +4,8 @@
   "private": true,
   "scripts": {
     "build": "vue-cli-service build",
-    "build1":"vue-cli-service build --mode test",
-    "build2":"vue-cli-service build --mode production",
+    "build1": "vue-cli-service build --mode test",
+    "build2": "vue-cli-service build --mode production",
     "lint": "vue-cli-service lint",
     "dev": "vue-cli-service serve"
   },
@@ -25,6 +25,7 @@
     "sass-loader": "^9.0.3",
     "sortablejs": "^1.14.0",
     "vue": "^2.6.11",
+    "vue-quill-editor": "^3.0.6",
     "vue-router": "^3.2.0",
     "vuex": "^3.4.0"
   },

+ 177 - 0
RMS-FrontEnd/src/App.vue

@@ -1,23 +1,200 @@
 <template>
   <div id="app">
     <router-view />
+    <div class="caidan" style ="display:none;"  v-if="$permission('/workspace/scratchWords')">
+          <div style="display: flex;align-items: center;">
+                <div class="dropbtn" :style='{"background-color":mark.color,"border-radius":"50%","width":"12px","height":"12px","margin-top":"1px"}'>
+                  <el-input type="color" v-model="mark.color"  style="opacity: 0;user-select:none;" @input="changeColor()"/>
+                </div>
+                &NonBreakingSpace;&NonBreakingSpace;&NonBreakingSpace;
+                <el-radio-group v-model="mark.scratchType">
+                  <el-radio :label="2" style="margin:0 10px;" @click.native.prevent="handleRadioClick(2)">波浪线</el-radio>
+                  <el-radio :label="0" style="margin-right: 10px;" @click.native.prevent="handleRadioClick(0)">下划线</el-radio>
+                  <el-radio :label="1" style="margin-right: 10px;font-size: 18px;" @click.native.prevent="handleRadioClick(1)">高亮</el-radio>
+                </el-radio-group>
+                &NonBreakingSpace;&NonBreakingSpace;
+                <a onclick="pizhu()" style="font-size: 14px;font-weight: 500;"> 批注</a>
+                
+                <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>
+                &NonBreakingSpace;&NonBreakingSpace;
+          </div>
+    </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 {
+      gaoLiangCaiDan:false,
+      piZhuDelete:false,
+    }
+  },
+  computed:{
+    mark() {
+      return this.$store.state.patent.index || {
+        rangeType:[]
+      }
+    },
+    contrastList() {
+      return this.$store.state.report.contrastList
+    },
   },
   created() {
 
   },
+  mounted() {
+    document.addEventListener('mousedown',function(e){
+      let btn = document.getElementsByClassName("caidan");
+      // let box = document.getElementsByClassName('pizhu')
+      if(btn[0].style.display!='none'){
+        if ( !btn[0].contains(e.target)) {
+          btn[0].setAttribute("style", "display:none;");
+        }
+      }
+    })
+  },
   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,
+        rightPosition: this.mark.rightPosition,
+        proofId: this.mark.evidenceFlieId,//证据文献Id
+        signPatentNo: this.mark.signPatentNo,
+        rightId:this.mark.rightSort,
+        rightSort:this.mark.rightSort,
+        // reportType:this.mark.reportType,
+        // taskId:this.mark.taskId,
+      }
+      this.$refs.addOpinion.open(form,form.patentNo==form.signPatentNo,true)
+    },
+
 
+    changeColor(){},
+    changeRadio(val) {
+      this.mark.scratchType = val
+      // 仅自己可见仅本专题或本报告可见
+      this.mark.permissionType=0
+      this.mark.rangeType = true
+      this.gaoLiangCaiDan = !this.gaoLiangCaiDan
+      this.handleCaiDan()
+    },
+    // 在el-radio-group无法对默认项点击
+    handleRadioClick(val) {
+      this.changeRadio(val)
+    },
+    handleCaiDan() {
+      let btn = document.getElementsByClassName("caidan");
+      if(btn[0].style.display!='none'){
+        btn[0].setAttribute("style", "display:none;");
+      }
+    },
+    hiddenPiZhuDelete() {
+      this.piZhuDelete = !this.piZhuDelete
+      this.handleCaiDan()
+    },
   }
 }
 </script>
 
+<style lang="scss">
+.opinion .el-form-item{
+  margin-bottom: 10px;
+  .el-form-item__content,.el-form-item__label{
+    line-height: normal;
+    min-height: 30px;
+  }
+}
+.caidan{
+  user-select:none;
+  a{
+    user-select:none;
+    cursor: pointer;
+  }
+ 
+}
+.showPiZhu{
+  position: absolute;
+  background: rgb(255 249 199);
+  left:0;
+  width:200px;
+  box-shadow: 5px 5px 5px rgb(227, 227, 75);
+  padding: 5px;
+  border-radius: 5px;
+}
+.pizhuLightHeigh{
+  position: relative;
+  background: #409EFF !important;
+}
+
+.greenColor{
+  background: #409EFF !important;
+}
+
+   .jinzhi{
+    cursor: not-allowed;
+    pointer-events:none;
+  }
+  .el-dropdown .el-button-group .el-button--primary:first-child{
+    padding: 0;
+    p{
+      margin: 0;
+      min-width: 50px;
+      line-height: 30px;
+      height: 30px;
+    }
+  }
+</style>
 <style lang="less">
 // .el-main > *{
 //   height: 100%;

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

@@ -0,0 +1,273 @@
+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)
+  },
+  /**
+ * 删除单个特征
+ */
+  deleteSingleFeature(params) {
+    return axios.get('/report/api/feature/deleteSingleFeature', {params})
+  },
+  /**
+ * 查询特征
+ */
+  getFeatureList(params) {
+    return axios.get('/report/api/feature/getFeatureList', {params})
+  },
+   /**
+ * 查询证据组合详情
+ */
+   queryDetailByInvalidId(params) {
+    return axios.get('/report/api/proofGroup/queryDetailByInvalidId', {params})
+  },
+    /**
+ * 修改证据组合详情
+ */
+    updateProofGroup(params) {
+      return axios.post('/report/api/proofGroup/update', params)
+    },
+  /**
+ * 添加或更新无效证据
+ */
+  addOrUpdatePoofArguments(params) {
+    return axios.post('/report/api/arguments/addOrUpdatePoofArguments', params)
+  },
+  
+   /**
+ * 添加更新无效证据
+ */
+   addOrUpdateProofStr(params) {
+    return axios.post('/report/api/proof/addOrUpdateProofStr', params)
+  },
+   /**
+ * 删除无效证据
+ */
+   deleteProofStr(params) {
+    return axios.post('/report/api/proof/deleteProofStr', params)
+  },
+  /**
+ * 查询陈述意见列表
+ */
+  queryPoofArguments(params) {
+    return axios.get('/report/api/arguments/queryPoofArguments', {params})
+  },
+  /**
+ * 查询无效理由和证据
+ */
+  queryInvalidReason(params) {
+    return axios.get('/report/api/invalidReason/queryInvalidReason', {params})
+  },
+  /**
+ * 更新无效理由和证据
+ */
+  updateInvalidReason(params) {
+    return axios.post('/report/api/invalidReason/updateInvalidReason', params)
+  },
+   /**
+ * 更新无效理由和证据的陈述意见
+ */
+   updateArgumentStr(params) {
+    return axios.post('/report/api/invalidReason/updateArgumentStr', 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)
+  },
+  
+
+
+/**
+ * 添加自定义栏位
+ */
+addOrUpdateInvalidFields(params) {
+  return axios.post('/report/api/invalidReasonField/addOrUpdateFields', params)
+},
+/**
+ *  查询自定义栏位
+ */
+queryInvalidFields(params) {
+  return axios.get('/report/api/invalidReasonField/queryFields', {params})
+},
+
+/**
+ * 删除自定义栏位
+ */
+deleteInvalidFields(params) {
+  return axios.post('/report/api/invalidReasonField/deleteFields', params)
+},
+/**
+ * 更新自定义栏位排序和显示
+ */
+updateSort(params) {
+  return axios.post('/report/api/invalidReasonField/updateSort', params)
+},
+
+/**
+ * 添加或更新无效理由自定义字段值
+ */
+addOrUpdateValue(params) {
+  return axios.post('/report/api/invalidReason/addOrUpdateValue', params)
+},
+/**
+ * 导出无效理由列表
+ */
+exportInvalid(params) {
+  return axios.post('/report/api/invalidReason/exportInvalid', params)
+},
+}

+ 28 - 0
RMS-FrontEnd/src/api/highlight.js

@@ -0,0 +1,28 @@
+import axios from '@/utils/axios'
+
+export default {
+  /**
+   * 新增标注
+   */
+  scratchWordsAdd(params) {
+    return axios.post('/v2/scratchWords/add', params)
+  },
+  /**
+   * 查询标注
+   */
+  scratchWordsQuery(params) {
+    return axios.post('/v2/scratchWords/query', params)
+  },
+  /**
+   * 更新标注
+   */
+  scratchWordsUpdate(params) {
+    return axios.post('/v2/scratchWords/update', params)
+  },
+  /**
+   * 删除标注
+   */
+  scratchWordsDelete(params) {
+    return axios.post('/v2/scratchWords/delete', params)
+  },
+}

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

@@ -5,7 +5,10 @@ import patent from './patent';
 import permission from './permission';
 import product from './product';
 import matters from './matters';
-import task from './task'
+import task from './task';
+import highlight from './highlight';
+import InvalidResponse from './InvalidResponse';
+import quartz from "./quartz";
 
 export default {
   ...report,
@@ -14,5 +17,8 @@ export default {
   ...permission,
   ...product,
   ...matters,
-  ...task
+  ...task,
+  ...highlight,
+  ...InvalidResponse,
+  ...quartz
 }

+ 97 - 0
RMS-FrontEnd/src/api/quartz.js

@@ -0,0 +1,97 @@
+import axios from '@/utils/axios'
+export default{
+/**
+   * 获取下载接口所有配置
+   */
+ getAllConfig(params) {
+    return axios.get('/v2/config/getAllConfig', { params })
+  },
+  /**
+   * 根据配置类型获取配置元素
+   */
+  getConfigCell(params) {
+    return axios.get('/v2/config/getConfigCell', { params })
+  },
+  /**
+   * 添加导入任务
+   */
+  addTask(data) {
+    return axios.post('/v2/task/addTask', data)
+  },
+  /**
+   * 继续导入任务
+   */
+  resumeJobTask(params) {
+    return axios.get('/v2/task/continue', {params})
+  },
+  /**
+   * 暂停导入任务
+   */
+  pauseJobTask(params) {
+    return axios.get('/v2/task/pause', {params})
+  },
+   /**
+   * 取消导入任务
+   */
+   cancelTask(params) {
+    return axios.get('/v2/task/cancelTask', {params})
+  },
+  /**
+   * 删除任务
+   */
+  // deleteTasks(data) {
+  //   return axios.post('/v2/task/deleteTasks', data)
+  // },
+  deleteTask(data) {
+    return axios.get('/v2/task/deleteTask', {data})
+  },
+  /**
+   * 更新定时任务
+   */
+  updateTasks(data) {
+    return axios.post('/v2/task/update', data)
+  },
+  /**
+   * 查询导入任务
+   */
+  // getTasks(data) {
+  //   return axios.post('/v2/task/getTasks', data)
+  // },
+  getTasks(data) {
+    return axios.post('/v2/task/queryTasks', data)
+  },
+  /**
+   * 查询实时进度或当前行数据的更新日志
+   */
+  // getTaskDetails(data) {
+  //   return axios.post('/v2/task/getTaskDetails', data)
+  // },
+  queryQrtzTaskLogs(data) {
+    return axios.post('/v2/task/queryQrtzTaskLogs', data)
+  },
+  /**
+   * 更改任务状态
+   */
+  setDetailState(params) {
+    return axios.get('/v2/task/setDetailState', {params})
+  },
+
+  //添加网站账号配置
+  addLoginConfig(params){
+    return axios.post('/v2/config/addLoginConfig',params)
+  },
+
+  //查询网站账号配置
+  queryLoginConfig(params){
+    return axios.post('/v2/config/queryLoginConfig',params)
+  },
+
+  //删除网站账号配置
+  deleteConfig(params){
+    return axios.post('/v2/config/deleteConfig',params)
+  },
+  //专利号导入
+  importByNos(params){
+    return axios.post('/v2/project/import/importByNos',params)
+  }
+}

+ 4 - 4
RMS-FrontEnd/src/assets/css/activeDiv.scss

@@ -4,8 +4,8 @@
         display: flex;
         justify-content: space-around;
         width: 100%;
-        height: 100%;
-        margin: 10px 0px;
+        // height: 100%;
+        // margin: 10px 0px;
         overflow: auto;
         box-shadow: -1px 9px 10px 3px rgba(0, 0, 0, 0.11);
     }
@@ -45,13 +45,13 @@
     .mid {
         // float: left;
         // width: 68%;   
-        height: 100%;
+        // height: 100%;
         background: #fff;
         box-shadow: -1px 4px 5px 3px rgba(0, 0, 0, 0.11);
     }
     .box1{
         width: 100%;
-        height: 100%;
+        // height: 100%;
         
     }
     /*拖拽区div样式*/

+ 2 - 1
RMS-FrontEnd/src/config/index.js

@@ -1,8 +1,9 @@
+const doname = /^([\w-]+\.)+((com)|(net)|(org)|(gov\.cn)|(info)|(cc)|(com\.cn)|(net\.cn)|(org\.cn)|(name)|(biz)|(tv)|(cn)|(mobi)|(name)|(sh)|(ac)|(io)|(tw)|(com\.tw)|(hk)|(com\.hk)|(ws)|(travel)|(us)|(tm)|(la)|(me\.uk)|(org\.uk)|(ltd\.uk)|(plc\.uk)|(in)|(eu)|(it)|(jp))$/;
 export default {
     baseURL: "/api",
     host: window.location.host,
     hostname: window.location.hostname,
     staticURL: process.env.NODE_ENV === 'production' ? window.location.protocol+'//'+window.location.hostname+':8084' : (process.env.NODE_ENV === 'test'?'http://139.224.24.90:8083':'http://192.168.1.24:8084'),
     staticURL2: process.env.NODE_ENV === 'production' ? window.location.protocol+'//'+window.location.hostname+':8081' : (process.env.NODE_ENV === 'test'?'http://139.224.24.90:8083':'http://192.168.1.24:8081'),
-    pasURL:process.env.NODE_ENV === 'production' ? window.location.protocol+'//'+window.location.hostname+':80' :(process.env.NODE_ENV === 'test'?window.location.protocol+'//'+window.location.hostname+':8080':window.location.protocol+'//'+window.location.hostname+':8085') ,
+    pasURL:process.env.NODE_ENV === 'production' ? (!doname.test(document.domain)?(window.location.protocol+'//'+window.location.hostname+':80'):'http://www.xsip.cn')  :(process.env.NODE_ENV === 'test'?window.location.protocol+'//'+window.location.hostname+':8080':window.location.protocol+'//'+window.location.hostname+':8085') ,
 }

+ 539 - 0
RMS-FrontEnd/src/icons/icon/demo.css

@@ -0,0 +1,539 @@
+/* Logo 字体 */
+@font-face {
+  font-family: "iconfont logo";
+  src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
+  src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
+}
+
+.logo {
+  font-family: "iconfont logo";
+  font-size: 160px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+/* tabs */
+.nav-tabs {
+  position: relative;
+}
+
+.nav-tabs .nav-more {
+  position: absolute;
+  right: 0;
+  bottom: 0;
+  height: 42px;
+  line-height: 42px;
+  color: #666;
+}
+
+#tabs {
+  border-bottom: 1px solid #eee;
+}
+
+#tabs li {
+  cursor: pointer;
+  width: 100px;
+  height: 40px;
+  line-height: 40px;
+  text-align: center;
+  font-size: 16px;
+  border-bottom: 2px solid transparent;
+  position: relative;
+  z-index: 1;
+  margin-bottom: -1px;
+  color: #666;
+}
+
+
+#tabs .active {
+  border-bottom-color: #f00;
+  color: #222;
+}
+
+.tab-container .content {
+  display: none;
+}
+
+/* 页面布局 */
+.main {
+  padding: 30px 100px;
+  width: 960px;
+  margin: 0 auto;
+}
+
+.main .logo {
+  color: #333;
+  text-align: left;
+  margin-bottom: 30px;
+  line-height: 1;
+  height: 110px;
+  margin-top: -50px;
+  overflow: hidden;
+  *zoom: 1;
+}
+
+.main .logo a {
+  font-size: 160px;
+  color: #333;
+}
+
+.helps {
+  margin-top: 40px;
+}
+
+.helps pre {
+  padding: 20px;
+  margin: 10px 0;
+  border: solid 1px #e7e1cd;
+  background-color: #fffdef;
+  overflow: auto;
+}
+
+.icon_lists {
+  width: 100% !important;
+  overflow: hidden;
+  *zoom: 1;
+}
+
+.icon_lists li {
+  width: 100px;
+  margin-bottom: 10px;
+  margin-right: 20px;
+  text-align: center;
+  list-style: none !important;
+  cursor: default;
+}
+
+.icon_lists li .code-name {
+  line-height: 1.2;
+}
+
+.icon_lists .icon {
+  display: block;
+  height: 100px;
+  line-height: 100px;
+  font-size: 42px;
+  margin: 10px auto;
+  color: #333;
+  -webkit-transition: font-size 0.25s linear, width 0.25s linear;
+  -moz-transition: font-size 0.25s linear, width 0.25s linear;
+  transition: font-size 0.25s linear, width 0.25s linear;
+}
+
+.icon_lists .icon:hover {
+  font-size: 100px;
+}
+
+.icon_lists .svg-icon {
+  /* 通过设置 font-size 来改变图标大小 */
+  width: 1em;
+  /* 图标和文字相邻时,垂直对齐 */
+  vertical-align: -0.15em;
+  /* 通过设置 color 来改变 SVG 的颜色/fill */
+  fill: currentColor;
+  /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
+      normalize.css 中也包含这行 */
+  overflow: hidden;
+}
+
+.icon_lists li .name,
+.icon_lists li .code-name {
+  color: #666;
+}
+
+/* markdown 样式 */
+.markdown {
+  color: #666;
+  font-size: 14px;
+  line-height: 1.8;
+}
+
+.highlight {
+  line-height: 1.5;
+}
+
+.markdown img {
+  vertical-align: middle;
+  max-width: 100%;
+}
+
+.markdown h1 {
+  color: #404040;
+  font-weight: 500;
+  line-height: 40px;
+  margin-bottom: 24px;
+}
+
+.markdown h2,
+.markdown h3,
+.markdown h4,
+.markdown h5,
+.markdown h6 {
+  color: #404040;
+  margin: 1.6em 0 0.6em 0;
+  font-weight: 500;
+  clear: both;
+}
+
+.markdown h1 {
+  font-size: 28px;
+}
+
+.markdown h2 {
+  font-size: 22px;
+}
+
+.markdown h3 {
+  font-size: 16px;
+}
+
+.markdown h4 {
+  font-size: 14px;
+}
+
+.markdown h5 {
+  font-size: 12px;
+}
+
+.markdown h6 {
+  font-size: 12px;
+}
+
+.markdown hr {
+  height: 1px;
+  border: 0;
+  background: #e9e9e9;
+  margin: 16px 0;
+  clear: both;
+}
+
+.markdown p {
+  margin: 1em 0;
+}
+
+.markdown>p,
+.markdown>blockquote,
+.markdown>.highlight,
+.markdown>ol,
+.markdown>ul {
+  width: 80%;
+}
+
+.markdown ul>li {
+  list-style: circle;
+}
+
+.markdown>ul li,
+.markdown blockquote ul>li {
+  margin-left: 20px;
+  padding-left: 4px;
+}
+
+.markdown>ul li p,
+.markdown>ol li p {
+  margin: 0.6em 0;
+}
+
+.markdown ol>li {
+  list-style: decimal;
+}
+
+.markdown>ol li,
+.markdown blockquote ol>li {
+  margin-left: 20px;
+  padding-left: 4px;
+}
+
+.markdown code {
+  margin: 0 3px;
+  padding: 0 5px;
+  background: #eee;
+  border-radius: 3px;
+}
+
+.markdown strong,
+.markdown b {
+  font-weight: 600;
+}
+
+.markdown>table {
+  border-collapse: collapse;
+  border-spacing: 0px;
+  empty-cells: show;
+  border: 1px solid #e9e9e9;
+  width: 95%;
+  margin-bottom: 24px;
+}
+
+.markdown>table th {
+  white-space: nowrap;
+  color: #333;
+  font-weight: 600;
+}
+
+.markdown>table th,
+.markdown>table td {
+  border: 1px solid #e9e9e9;
+  padding: 8px 16px;
+  text-align: left;
+}
+
+.markdown>table th {
+  background: #F7F7F7;
+}
+
+.markdown blockquote {
+  font-size: 90%;
+  color: #999;
+  border-left: 4px solid #e9e9e9;
+  padding-left: 0.8em;
+  margin: 1em 0;
+}
+
+.markdown blockquote p {
+  margin: 0;
+}
+
+.markdown .anchor {
+  opacity: 0;
+  transition: opacity 0.3s ease;
+  margin-left: 8px;
+}
+
+.markdown .waiting {
+  color: #ccc;
+}
+
+.markdown h1:hover .anchor,
+.markdown h2:hover .anchor,
+.markdown h3:hover .anchor,
+.markdown h4:hover .anchor,
+.markdown h5:hover .anchor,
+.markdown h6:hover .anchor {
+  opacity: 1;
+  display: inline-block;
+}
+
+.markdown>br,
+.markdown>p>br {
+  clear: both;
+}
+
+
+.hljs {
+  display: block;
+  background: white;
+  padding: 0.5em;
+  color: #333333;
+  overflow-x: auto;
+}
+
+.hljs-comment,
+.hljs-meta {
+  color: #969896;
+}
+
+.hljs-string,
+.hljs-variable,
+.hljs-template-variable,
+.hljs-strong,
+.hljs-emphasis,
+.hljs-quote {
+  color: #df5000;
+}
+
+.hljs-keyword,
+.hljs-selector-tag,
+.hljs-type {
+  color: #a71d5d;
+}
+
+.hljs-literal,
+.hljs-symbol,
+.hljs-bullet,
+.hljs-attribute {
+  color: #0086b3;
+}
+
+.hljs-section,
+.hljs-name {
+  color: #63a35c;
+}
+
+.hljs-tag {
+  color: #333333;
+}
+
+.hljs-title,
+.hljs-attr,
+.hljs-selector-id,
+.hljs-selector-class,
+.hljs-selector-attr,
+.hljs-selector-pseudo {
+  color: #795da3;
+}
+
+.hljs-addition {
+  color: #55a532;
+  background-color: #eaffea;
+}
+
+.hljs-deletion {
+  color: #bd2c00;
+  background-color: #ffecec;
+}
+
+.hljs-link {
+  text-decoration: underline;
+}
+
+/* 代码高亮 */
+/* PrismJS 1.15.0
+https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
+/**
+ * prism.js default theme for JavaScript, CSS and HTML
+ * Based on dabblet (http://dabblet.com)
+ * @author Lea Verou
+ */
+code[class*="language-"],
+pre[class*="language-"] {
+  color: black;
+  background: none;
+  text-shadow: 0 1px white;
+  font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
+  text-align: left;
+  white-space: pre;
+  word-spacing: normal;
+  word-break: normal;
+  word-wrap: normal;
+  line-height: 1.5;
+
+  -moz-tab-size: 4;
+  -o-tab-size: 4;
+  tab-size: 4;
+
+  -webkit-hyphens: none;
+  -moz-hyphens: none;
+  -ms-hyphens: none;
+  hyphens: none;
+}
+
+pre[class*="language-"]::-moz-selection,
+pre[class*="language-"] ::-moz-selection,
+code[class*="language-"]::-moz-selection,
+code[class*="language-"] ::-moz-selection {
+  text-shadow: none;
+  background: #b3d4fc;
+}
+
+pre[class*="language-"]::selection,
+pre[class*="language-"] ::selection,
+code[class*="language-"]::selection,
+code[class*="language-"] ::selection {
+  text-shadow: none;
+  background: #b3d4fc;
+}
+
+@media print {
+
+  code[class*="language-"],
+  pre[class*="language-"] {
+    text-shadow: none;
+  }
+}
+
+/* Code blocks */
+pre[class*="language-"] {
+  padding: 1em;
+  margin: .5em 0;
+  overflow: auto;
+}
+
+:not(pre)>code[class*="language-"],
+pre[class*="language-"] {
+  background: #f5f2f0;
+}
+
+/* Inline code */
+:not(pre)>code[class*="language-"] {
+  padding: .1em;
+  border-radius: .3em;
+  white-space: normal;
+}
+
+.token.comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+  color: slategray;
+}
+
+.token.punctuation {
+  color: #999;
+}
+
+.namespace {
+  opacity: .7;
+}
+
+.token.property,
+.token.tag,
+.token.boolean,
+.token.number,
+.token.constant,
+.token.symbol,
+.token.deleted {
+  color: #905;
+}
+
+.token.selector,
+.token.attr-name,
+.token.string,
+.token.char,
+.token.builtin,
+.token.inserted {
+  color: #690;
+}
+
+.token.operator,
+.token.entity,
+.token.url,
+.language-css .token.string,
+.style .token.string {
+  color: #9a6e3a;
+  background: hsla(0, 0%, 100%, .5);
+}
+
+.token.atrule,
+.token.attr-value,
+.token.keyword {
+  color: #07a;
+}
+
+.token.function,
+.token.class-name {
+  color: #DD4A68;
+}
+
+.token.regex,
+.token.important,
+.token.variable {
+  color: #e90;
+}
+
+.token.important,
+.token.bold {
+  font-weight: bold;
+}
+
+.token.italic {
+  font-style: italic;
+}
+
+.token.entity {
+  cursor: help;
+}

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 37 - 0
RMS-FrontEnd/src/icons/icon/iconfont.css


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
RMS-FrontEnd/src/icons/icon/iconfont.js


+ 44 - 0
RMS-FrontEnd/src/icons/icon/iconfont.json

@@ -0,0 +1,44 @@
+{
+  "id": "4145129",
+  "name": "icon1",
+  "font_family": "iconfont",
+  "css_prefix_text": "icon-",
+  "description": "",
+  "glyphs": [
+    {
+      "icon_id": "383629",
+      "name": "信息",
+      "font_class": "xinxi4",
+      "unicode": "e623",
+      "unicode_decimal": 58915
+    },
+    {
+      "icon_id": "7872852",
+      "name": "信息",
+      "font_class": "xinxi1",
+      "unicode": "e644",
+      "unicode_decimal": 58948
+    },
+    {
+      "icon_id": "8289020",
+      "name": "信息",
+      "font_class": "xinxi2",
+      "unicode": "e86f",
+      "unicode_decimal": 59503
+    },
+    {
+      "icon_id": "12685022",
+      "name": "标记",
+      "font_class": "icon_huabanfuben",
+      "unicode": "e62f",
+      "unicode_decimal": 58927
+    },
+    {
+      "icon_id": "23949533",
+      "name": "信息",
+      "font_class": "xinxi3",
+      "unicode": "ec68",
+      "unicode_decimal": 60520
+    }
+  ]
+}

BIN=BIN
RMS-FrontEnd/src/icons/icon/iconfont.ttf


BIN=BIN
RMS-FrontEnd/src/icons/icon/iconfont.woff


BIN=BIN
RMS-FrontEnd/src/icons/icon/iconfont.woff2


+ 539 - 0
RMS-FrontEnd/src/icons/icon2/demo.css

@@ -0,0 +1,539 @@
+/* Logo 字体 */
+@font-face {
+  font-family: "iconfont logo";
+  src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
+  src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
+}
+
+.logo {
+  font-family: "iconfont logo";
+  font-size: 160px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+/* tabs */
+.nav-tabs {
+  position: relative;
+}
+
+.nav-tabs .nav-more {
+  position: absolute;
+  right: 0;
+  bottom: 0;
+  height: 42px;
+  line-height: 42px;
+  color: #666;
+}
+
+#tabs {
+  border-bottom: 1px solid #eee;
+}
+
+#tabs li {
+  cursor: pointer;
+  width: 100px;
+  height: 40px;
+  line-height: 40px;
+  text-align: center;
+  font-size: 16px;
+  border-bottom: 2px solid transparent;
+  position: relative;
+  z-index: 1;
+  margin-bottom: -1px;
+  color: #666;
+}
+
+
+#tabs .active {
+  border-bottom-color: #f00;
+  color: #222;
+}
+
+.tab-container .content {
+  display: none;
+}
+
+/* 页面布局 */
+.main {
+  padding: 30px 100px;
+  width: 960px;
+  margin: 0 auto;
+}
+
+.main .logo {
+  color: #333;
+  text-align: left;
+  margin-bottom: 30px;
+  line-height: 1;
+  height: 110px;
+  margin-top: -50px;
+  overflow: hidden;
+  *zoom: 1;
+}
+
+.main .logo a {
+  font-size: 160px;
+  color: #333;
+}
+
+.helps {
+  margin-top: 40px;
+}
+
+.helps pre {
+  padding: 20px;
+  margin: 10px 0;
+  border: solid 1px #e7e1cd;
+  background-color: #fffdef;
+  overflow: auto;
+}
+
+.icon_lists {
+  width: 100% !important;
+  overflow: hidden;
+  *zoom: 1;
+}
+
+.icon_lists li {
+  width: 100px;
+  margin-bottom: 10px;
+  margin-right: 20px;
+  text-align: center;
+  list-style: none !important;
+  cursor: default;
+}
+
+.icon_lists li .code-name {
+  line-height: 1.2;
+}
+
+.icon_lists .icon {
+  display: block;
+  height: 100px;
+  line-height: 100px;
+  font-size: 42px;
+  margin: 10px auto;
+  color: #333;
+  -webkit-transition: font-size 0.25s linear, width 0.25s linear;
+  -moz-transition: font-size 0.25s linear, width 0.25s linear;
+  transition: font-size 0.25s linear, width 0.25s linear;
+}
+
+.icon_lists .icon:hover {
+  font-size: 100px;
+}
+
+.icon_lists .svg-icon {
+  /* 通过设置 font-size 来改变图标大小 */
+  width: 1em;
+  /* 图标和文字相邻时,垂直对齐 */
+  vertical-align: -0.15em;
+  /* 通过设置 color 来改变 SVG 的颜色/fill */
+  fill: currentColor;
+  /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
+      normalize.css 中也包含这行 */
+  overflow: hidden;
+}
+
+.icon_lists li .name,
+.icon_lists li .code-name {
+  color: #666;
+}
+
+/* markdown 样式 */
+.markdown {
+  color: #666;
+  font-size: 14px;
+  line-height: 1.8;
+}
+
+.highlight {
+  line-height: 1.5;
+}
+
+.markdown img {
+  vertical-align: middle;
+  max-width: 100%;
+}
+
+.markdown h1 {
+  color: #404040;
+  font-weight: 500;
+  line-height: 40px;
+  margin-bottom: 24px;
+}
+
+.markdown h2,
+.markdown h3,
+.markdown h4,
+.markdown h5,
+.markdown h6 {
+  color: #404040;
+  margin: 1.6em 0 0.6em 0;
+  font-weight: 500;
+  clear: both;
+}
+
+.markdown h1 {
+  font-size: 28px;
+}
+
+.markdown h2 {
+  font-size: 22px;
+}
+
+.markdown h3 {
+  font-size: 16px;
+}
+
+.markdown h4 {
+  font-size: 14px;
+}
+
+.markdown h5 {
+  font-size: 12px;
+}
+
+.markdown h6 {
+  font-size: 12px;
+}
+
+.markdown hr {
+  height: 1px;
+  border: 0;
+  background: #e9e9e9;
+  margin: 16px 0;
+  clear: both;
+}
+
+.markdown p {
+  margin: 1em 0;
+}
+
+.markdown>p,
+.markdown>blockquote,
+.markdown>.highlight,
+.markdown>ol,
+.markdown>ul {
+  width: 80%;
+}
+
+.markdown ul>li {
+  list-style: circle;
+}
+
+.markdown>ul li,
+.markdown blockquote ul>li {
+  margin-left: 20px;
+  padding-left: 4px;
+}
+
+.markdown>ul li p,
+.markdown>ol li p {
+  margin: 0.6em 0;
+}
+
+.markdown ol>li {
+  list-style: decimal;
+}
+
+.markdown>ol li,
+.markdown blockquote ol>li {
+  margin-left: 20px;
+  padding-left: 4px;
+}
+
+.markdown code {
+  margin: 0 3px;
+  padding: 0 5px;
+  background: #eee;
+  border-radius: 3px;
+}
+
+.markdown strong,
+.markdown b {
+  font-weight: 600;
+}
+
+.markdown>table {
+  border-collapse: collapse;
+  border-spacing: 0px;
+  empty-cells: show;
+  border: 1px solid #e9e9e9;
+  width: 95%;
+  margin-bottom: 24px;
+}
+
+.markdown>table th {
+  white-space: nowrap;
+  color: #333;
+  font-weight: 600;
+}
+
+.markdown>table th,
+.markdown>table td {
+  border: 1px solid #e9e9e9;
+  padding: 8px 16px;
+  text-align: left;
+}
+
+.markdown>table th {
+  background: #F7F7F7;
+}
+
+.markdown blockquote {
+  font-size: 90%;
+  color: #999;
+  border-left: 4px solid #e9e9e9;
+  padding-left: 0.8em;
+  margin: 1em 0;
+}
+
+.markdown blockquote p {
+  margin: 0;
+}
+
+.markdown .anchor {
+  opacity: 0;
+  transition: opacity 0.3s ease;
+  margin-left: 8px;
+}
+
+.markdown .waiting {
+  color: #ccc;
+}
+
+.markdown h1:hover .anchor,
+.markdown h2:hover .anchor,
+.markdown h3:hover .anchor,
+.markdown h4:hover .anchor,
+.markdown h5:hover .anchor,
+.markdown h6:hover .anchor {
+  opacity: 1;
+  display: inline-block;
+}
+
+.markdown>br,
+.markdown>p>br {
+  clear: both;
+}
+
+
+.hljs {
+  display: block;
+  background: white;
+  padding: 0.5em;
+  color: #333333;
+  overflow-x: auto;
+}
+
+.hljs-comment,
+.hljs-meta {
+  color: #969896;
+}
+
+.hljs-string,
+.hljs-variable,
+.hljs-template-variable,
+.hljs-strong,
+.hljs-emphasis,
+.hljs-quote {
+  color: #df5000;
+}
+
+.hljs-keyword,
+.hljs-selector-tag,
+.hljs-type {
+  color: #a71d5d;
+}
+
+.hljs-literal,
+.hljs-symbol,
+.hljs-bullet,
+.hljs-attribute {
+  color: #0086b3;
+}
+
+.hljs-section,
+.hljs-name {
+  color: #63a35c;
+}
+
+.hljs-tag {
+  color: #333333;
+}
+
+.hljs-title,
+.hljs-attr,
+.hljs-selector-id,
+.hljs-selector-class,
+.hljs-selector-attr,
+.hljs-selector-pseudo {
+  color: #795da3;
+}
+
+.hljs-addition {
+  color: #55a532;
+  background-color: #eaffea;
+}
+
+.hljs-deletion {
+  color: #bd2c00;
+  background-color: #ffecec;
+}
+
+.hljs-link {
+  text-decoration: underline;
+}
+
+/* 代码高亮 */
+/* PrismJS 1.15.0
+https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
+/**
+ * prism.js default theme for JavaScript, CSS and HTML
+ * Based on dabblet (http://dabblet.com)
+ * @author Lea Verou
+ */
+code[class*="language-"],
+pre[class*="language-"] {
+  color: black;
+  background: none;
+  text-shadow: 0 1px white;
+  font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
+  text-align: left;
+  white-space: pre;
+  word-spacing: normal;
+  word-break: normal;
+  word-wrap: normal;
+  line-height: 1.5;
+
+  -moz-tab-size: 4;
+  -o-tab-size: 4;
+  tab-size: 4;
+
+  -webkit-hyphens: none;
+  -moz-hyphens: none;
+  -ms-hyphens: none;
+  hyphens: none;
+}
+
+pre[class*="language-"]::-moz-selection,
+pre[class*="language-"] ::-moz-selection,
+code[class*="language-"]::-moz-selection,
+code[class*="language-"] ::-moz-selection {
+  text-shadow: none;
+  background: #b3d4fc;
+}
+
+pre[class*="language-"]::selection,
+pre[class*="language-"] ::selection,
+code[class*="language-"]::selection,
+code[class*="language-"] ::selection {
+  text-shadow: none;
+  background: #b3d4fc;
+}
+
+@media print {
+
+  code[class*="language-"],
+  pre[class*="language-"] {
+    text-shadow: none;
+  }
+}
+
+/* Code blocks */
+pre[class*="language-"] {
+  padding: 1em;
+  margin: .5em 0;
+  overflow: auto;
+}
+
+:not(pre)>code[class*="language-"],
+pre[class*="language-"] {
+  background: #f5f2f0;
+}
+
+/* Inline code */
+:not(pre)>code[class*="language-"] {
+  padding: .1em;
+  border-radius: .3em;
+  white-space: normal;
+}
+
+.token.comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+  color: slategray;
+}
+
+.token.punctuation {
+  color: #999;
+}
+
+.namespace {
+  opacity: .7;
+}
+
+.token.property,
+.token.tag,
+.token.boolean,
+.token.number,
+.token.constant,
+.token.symbol,
+.token.deleted {
+  color: #905;
+}
+
+.token.selector,
+.token.attr-name,
+.token.string,
+.token.char,
+.token.builtin,
+.token.inserted {
+  color: #690;
+}
+
+.token.operator,
+.token.entity,
+.token.url,
+.language-css .token.string,
+.style .token.string {
+  color: #9a6e3a;
+  background: hsla(0, 0%, 100%, .5);
+}
+
+.token.atrule,
+.token.attr-value,
+.token.keyword {
+  color: #07a;
+}
+
+.token.function,
+.token.class-name {
+  color: #DD4A68;
+}
+
+.token.regex,
+.token.important,
+.token.variable {
+  color: #e90;
+}
+
+.token.important,
+.token.bold {
+  font-weight: bold;
+}
+
+.token.italic {
+  font-style: italic;
+}
+
+.token.entity {
+  cursor: help;
+}

+ 131 - 0
RMS-FrontEnd/src/icons/icon2/iconfont.css

@@ -0,0 +1,131 @@
+@font-face {
+  font-family: "iconfont"; /* Project id 4121381 */
+  src: url('iconfont.woff2?t=1690508543387') format('woff2'),
+       url('iconfont.woff?t=1690508543387') format('woff'),
+       url('iconfont.ttf?t=1690508543387') format('truetype');
+}
+
+.iconfont {
+  font-family: "iconfont" !important;
+  font-size: 16px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+.icon-yanjing_yincang:before {
+  content: "\eb45";
+}
+
+.icon-yanjing_xianshi:before {
+  content: "\eb46";
+}
+
+.icon-quxiaorenwu1:before {
+  content: "\100aa";
+}
+
+.icon-banbengengxinjilu:before {
+  content: "\e6a2";
+}
+
+.icon-xiazai:before {
+  content: "\e6b7";
+}
+
+.icon-zanting:before {
+  content: "\e656";
+}
+
+.icon-zanting1:before {
+  content: "\e629";
+}
+
+.icon-quxiaorenwu:before {
+  content: "\e61d";
+}
+
+.icon-bianji:before {
+  content: "\e622";
+}
+
+.icon-zidongzhihang:before {
+  content: "\e6e3";
+}
+
+.icon-baocun:before {
+  content: "\e65c";
+}
+
+.icon-shanchu:before {
+  content: "\e670";
+}
+
+.icon-shouye:before {
+  content: "\e621";
+}
+
+.icon-renwujincheng:before {
+  content: "\ec35";
+}
+
+.icon-fanhui:before {
+  content: "\e6ff";
+}
+
+.icon-guding:before {
+  content: "\e626";
+}
+
+.icon-xiahuaxian:before {
+  content: "\e701";
+}
+
+.icon-arrow121112:before {
+  content: "\e90b";
+}
+
+.icon-guanbi-:before {
+  content: "\e60b";
+}
+
+.icon-fujian1:before {
+  content: "\e85a";
+}
+
+.icon-zhixiang:before {
+  content: "\e601";
+}
+
+.icon-wodegaoliang:before {
+  content: "\e6e5";
+}
+
+.icon-zhixiang1:before {
+  content: "\e602";
+}
+
+.icon-fix:before {
+  content: "\e9b9";
+}
+
+.icon-tianjialiebiao:before {
+  content: "\e625";
+}
+
+.icon-bumen:before {
+  content: "\e686";
+}
+
+.icon-sousuo1:before {
+  content: "\e609";
+}
+
+.icon-a-24_nor:before {
+  content: "\e611";
+}
+
+.icon-caozuo:before {
+  content: "\e605";
+}
+

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
RMS-FrontEnd/src/icons/icon2/iconfont.js


+ 212 - 0
RMS-FrontEnd/src/icons/icon2/iconfont.json

@@ -0,0 +1,212 @@
+{
+  "id": "4121381",
+  "name": "xiaoshi",
+  "font_family": "iconfont",
+  "css_prefix_text": "icon-",
+  "description": "",
+  "glyphs": [
+    {
+      "icon_id": "5387735",
+      "name": "眼睛_隐藏",
+      "font_class": "yanjing_yincang",
+      "unicode": "eb45",
+      "unicode_decimal": 60229
+    },
+    {
+      "icon_id": "5387736",
+      "name": "眼睛_显示",
+      "font_class": "yanjing_xianshi",
+      "unicode": "eb46",
+      "unicode_decimal": 60230
+    },
+    {
+      "icon_id": "27804747",
+      "name": "取消任务",
+      "font_class": "quxiaorenwu1",
+      "unicode": "100aa",
+      "unicode_decimal": 65706
+    },
+    {
+      "icon_id": "707805",
+      "name": "版本更新记录",
+      "font_class": "banbengengxinjilu",
+      "unicode": "e6a2",
+      "unicode_decimal": 59042
+    },
+    {
+      "icon_id": "1057009",
+      "name": "下载",
+      "font_class": "xiazai",
+      "unicode": "e6b7",
+      "unicode_decimal": 59063
+    },
+    {
+      "icon_id": "1111470",
+      "name": "暂停",
+      "font_class": "zanting",
+      "unicode": "e656",
+      "unicode_decimal": 58966
+    },
+    {
+      "icon_id": "8353894",
+      "name": "暂停",
+      "font_class": "zanting1",
+      "unicode": "e629",
+      "unicode_decimal": 58921
+    },
+    {
+      "icon_id": "33846828",
+      "name": "取消任务",
+      "font_class": "quxiaorenwu",
+      "unicode": "e61d",
+      "unicode_decimal": 58909
+    },
+    {
+      "icon_id": "33987167",
+      "name": "编辑",
+      "font_class": "bianji",
+      "unicode": "e622",
+      "unicode_decimal": 58914
+    },
+    {
+      "icon_id": "1790443",
+      "name": "自动执行",
+      "font_class": "zidongzhihang",
+      "unicode": "e6e3",
+      "unicode_decimal": 59107
+    },
+    {
+      "icon_id": "3978372",
+      "name": "保存",
+      "font_class": "baocun",
+      "unicode": "e65c",
+      "unicode_decimal": 58972
+    },
+    {
+      "icon_id": "6056159",
+      "name": "删除",
+      "font_class": "shanchu",
+      "unicode": "e670",
+      "unicode_decimal": 58992
+    },
+    {
+      "icon_id": "765433",
+      "name": "历史记录",
+      "font_class": "shouye",
+      "unicode": "e621",
+      "unicode_decimal": 58913
+    },
+    {
+      "icon_id": "5767874",
+      "name": "任务进程",
+      "font_class": "renwujincheng",
+      "unicode": "ec35",
+      "unicode_decimal": 60469
+    },
+    {
+      "icon_id": "687392",
+      "name": "返回",
+      "font_class": "fanhui",
+      "unicode": "e6ff",
+      "unicode_decimal": 59135
+    },
+    {
+      "icon_id": "755543",
+      "name": "固定",
+      "font_class": "guding",
+      "unicode": "e626",
+      "unicode_decimal": 58918
+    },
+    {
+      "icon_id": "1790513",
+      "name": "下划线",
+      "font_class": "xiahuaxian",
+      "unicode": "e701",
+      "unicode_decimal": 59137
+    },
+    {
+      "icon_id": "2387391",
+      "name": "上传",
+      "font_class": "arrow121112",
+      "unicode": "e90b",
+      "unicode_decimal": 59659
+    },
+    {
+      "icon_id": "7312822",
+      "name": "关闭",
+      "font_class": "guanbi-",
+      "unicode": "e60b",
+      "unicode_decimal": 58891
+    },
+    {
+      "icon_id": "8288905",
+      "name": "附件",
+      "font_class": "fujian1",
+      "unicode": "e85a",
+      "unicode_decimal": 59482
+    },
+    {
+      "icon_id": "8352735",
+      "name": "指向",
+      "font_class": "zhixiang",
+      "unicode": "e601",
+      "unicode_decimal": 58881
+    },
+    {
+      "icon_id": "13102581",
+      "name": "我的高亮",
+      "font_class": "wodegaoliang",
+      "unicode": "e6e5",
+      "unicode_decimal": 59109
+    },
+    {
+      "icon_id": "15855674",
+      "name": "指向",
+      "font_class": "zhixiang1",
+      "unicode": "e602",
+      "unicode_decimal": 58882
+    },
+    {
+      "icon_id": "18170419",
+      "name": "解除固定,图钉",
+      "font_class": "fix",
+      "unicode": "e9b9",
+      "unicode_decimal": 59833
+    },
+    {
+      "icon_id": "19378122",
+      "name": "添加列表",
+      "font_class": "tianjialiebiao",
+      "unicode": "e625",
+      "unicode_decimal": 58917
+    },
+    {
+      "icon_id": "21053809",
+      "name": "部门",
+      "font_class": "bumen",
+      "unicode": "e686",
+      "unicode_decimal": 59014
+    },
+    {
+      "icon_id": "21303015",
+      "name": "搜索",
+      "font_class": "sousuo1",
+      "unicode": "e609",
+      "unicode_decimal": 58889
+    },
+    {
+      "icon_id": "23008574",
+      "name": "批注",
+      "font_class": "a-24_nor",
+      "unicode": "e611",
+      "unicode_decimal": 58897
+    },
+    {
+      "icon_id": "13030066",
+      "name": "操作",
+      "font_class": "caozuo",
+      "unicode": "e605",
+      "unicode_decimal": 58885
+    }
+  ]
+}

BIN=BIN
RMS-FrontEnd/src/icons/icon2/iconfont.ttf


BIN=BIN
RMS-FrontEnd/src/icons/icon2/iconfont.woff


BIN=BIN
RMS-FrontEnd/src/icons/icon2/iconfont.woff2


+ 13 - 1
RMS-FrontEnd/src/main.js

@@ -18,13 +18,25 @@ require('./assets/css/fix.scss')
 require('./assets/css/layout.less')
 import './icons'
 import lodash from 'lodash'
-
+import "@/icons/icon/iconfont.css"
+import "@/icons/icon2/iconfont.css"
 import {hasPermission} from './directives/permission';
 Vue.prototype.$permission = hasPermission
 
 import directive from './utils/directives'
 Vue.use(directive)
 
+import myRichText from '@/views/components/common/RichText/index'
+Vue.use(myRichText);
+
+
+import VueQuillEditor from 'vue-quill-editor'
+import 'quill/dist/quill.core.css'
+import 'quill/dist/quill.snow.css'
+import 'quill/dist/quill.bubble.css'
+Vue.use(VueQuillEditor);
+
+
 import {reportPermission} from '@/utils/reportPermission'
 // import Directives from './directives/index'
 // Vue.use(Directives)

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

@@ -242,6 +242,57 @@ 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:'/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:'/fileDetails/:id',
+        name:'fileDetails/:id',
+        meta:{
+          title:'证据文献详情',
+          aside:true,
+          showHeader:true,
+        },
+        component:() => import('@/views/report/InvalidResponse/components/FileDetails/index.vue'),
+      },
+      {
+        path:'/RichText',
+        name:'RichText',
+        meta:{
+          title:'富文本',
+          aside:true,
+          showHeader:true,
+        },
+        component:() => import('@/views/components/common/RichText'),
+      },
       //产品管理
       {
         path: "/product",

+ 12 - 1
RMS-FrontEnd/src/store/modules/patent.js

@@ -6,7 +6,15 @@ export default {
     records: [],
     menuLoading: false,
     highlight: {},
-    queryData: []
+    queryData: [],
+    index:{
+      color:'#ff0000',
+      scratchType:2,
+      permissionType:1,
+      rangeType:true,
+      content:'',
+      remark:'',//标注文本
+    },
   },
 
   mutations: {
@@ -30,6 +38,9 @@ export default {
     },
     SET_PATENT_QUERY_DATA(state, queryData) {
       state.queryData = queryData
+    },
+    SET_PATENT_INDEX(state, index){
+      state.index = index
     }
   },
 

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

@@ -8,9 +8,17 @@ export default {
     form: {},
     patentList: [],
     contrastList:[],
+    piZhuContrastList:[],
+    opinionContrastList:[],
   },
 
   mutations: {
+    SET_PATENT_OPINION_CONTRAST:(state, opinionContrastList)=>{
+      state.opinionContrastList = opinionContrastList
+    },
+    SET_PATENT_PIZHU_CONTRAST:(state, piZhuContrastList)=>{
+      state.piZhuContrastList = piZhuContrastList
+    },
     SET_PATENT_CONTRAST:(state, contrastList)=>{
       state.contrastList = contrastList
     },

+ 151 - 0
RMS-FrontEnd/src/utils/constants.js

@@ -73,4 +73,155 @@ export default {
     { label: 'Courier New', value: 'Courier New' },
     { label: 'Microsoft YaHei', value: 'Microsoft YaHei' },
   ],
+
+    /**
+   * 检索栏位type为1表示中国仅有,2表示世界仅有,3表示两者都包含
+   * dataType为数据格式:1为字符串,2为日期,3为数组
+   */
+    searchField:[
+      {
+        label:'文本',
+        value:'text',
+        children:[
+          {label: '发明名称/标题', value: 'TI',type:3,dataType:1,placeholder:'请输入发明名称/标题,例:计算机 OR "computer and phone"'},
+          {label: '主权利要求', value: 'CL',type:1,dataType:1,placeholder:'请输入主权利要求,例:加煤系统 OR "computer and phone"'},
+          {label: '关键词', value: 'TX',type:3,dataType:1,placeholder:'请输入关键词,例:石墨烯 OR "computer and phone"'},
+          {label: '摘要', value: 'AB',type:3,dataType:1,placeholder:'请输入摘要或简要说明,例:外喷放热气 OR "computer and phone"'},
+        ]
+      },
+      {
+        label:'号码',
+        value:'number',
+        children:[
+          {label: '申请号', value: 'AN',type:3,dataType:1,placeholder:'请输入申请号,例:CN202330275114.7 OR CN202330275114.7'},
+          {label: '原始申请号', value: 'ANO',type:3,dataType:1,placeholder:'请输入原始申请号,例:CN202330275109.6 OR CN202330275109.6'},
+          {label: '公告号', value: 'GN',type:1,dataType:1,placeholder:'请输入公告号,例:CN102860161 OR CN1526554846'},
+          {label: '公开号', value: 'PN',type:3,dataType:1,placeholder:'请输入公开号,例:CN102860161 OR CN1526554846'},
+          {label: '原始公开号', value: 'PNO',type:2,dataType:1,placeholder:'请输入原始公开号,例:CN102860161 OR CN1526554846'},
+        ]
+      },
+      {
+        label:'类型及状态',
+        value:'typeAndStatus',
+        children:[
+          {label: '专利类型', value: 'PT',type:1,dataType:3},
+          {label: '法律状态', value: 'LG',type:1,dataType:3},
+        ]
+      },
+      {
+        label:'分类',
+        value:'typeNumber',
+        children:[
+          {label: '分类号', value: 'IC',type:3,dataType:1,placeholder:'请输入分类号,例:21-01 OR B61D47/00'},
+          {label: '主分类号', value: 'MC',type:3,dataType:1,placeholder:'请输入分类号,例:21-01 OR B61D47/00'},
+          {label: '优先权号', value: 'PR',type:3,dataType:1,placeholder:'请输入优先权号,例:DEP3833692.8'},
+          {label: '范畴分类', value: 'CT',type:1,dataType:1,placeholder:'请输入范畴分类,例:32D OR 40B'},
+          {label: '欧洲分类', value: 'EC',type:2,dataType:1,placeholder:'请输入欧洲分类号'},
+        ]
+      },
+      {
+        label:'日期',
+        value:'date',
+        children:[
+          {label: '申请日', value: 'AD',type:3,dataType:2},
+          {label: '公告日', value: 'GD',type:1,dataType:2},
+          {label: '公开日', value: 'PD',type:3,dataType:2},
+        ]
+      },
+      {
+        label:'公司/人',
+        value:'person',
+        children:[
+          {label: '发明人', value: 'IN',type:3,dataType:1,placeholder:'请输入发明人,例:钟丽红'},
+          {label: '第一发明人', value: 'FI',type:3,dataType:1,placeholder:'请输入第一发明人,例:钟丽红'},
+          {label: '申请人', value: 'PA',type:3,dataType:1,placeholder:'请输入申请人,例:钟丽红'},
+          {label: '第一申请人', value: 'FP',type:3,dataType:1,placeholder:'请输入第一申请人,例:钟丽红'},
+          {label: '当前权利人', value: 'PE',type:1,dataType:1,placeholder:'请输入当前权利人,例:钟丽红'},
+          {label: '代理机构代码', value: 'AG',type:1,dataType:1,placeholder:'请输入代理机构代码,例:11223'},
+          {label: '代理人', value: 'AT',type:1,dataType:1,placeholder:'请输入代理人,例:张三'},
+          {label: '代理机构名称', value: 'AGN',type:1,dataType:1,placeholder:'请输入代理机构名称,例:威士博'},
+        ]
+      },
+      {
+        label:'地址',
+        value:'date',
+        children:[
+          {label: '国省代码', value: 'CO',type:3,dataType:1,placeholder:'请输入国省代码,例:94 OR CN'},
+          {label: '发明人国家', value: 'ICO',type:2,dataType:1,placeholder:'请输入发明人国家,例:94 OR CN'},
+          {label: '国家', value: 'GJ',type:3,dataType:3,placeholder:'请输入国家,例:CN'},
+          {label: '申请人地址', value: 'DZ',type:1,dataType:1,placeholder:'请输入申请人地址,例:深圳市南山区'},
+        ]
+      },
+      {
+        label:'引用',
+        value:'excerpt',
+        children:[
+          {label: '引用专利', value: 'CC',type:3,dataType:1,placeholder:'请输入引用专利,例:US1743377A,1930.01.14'},
+          {label: '引用非专利', value: 'UCC',type:1,dataType:1,placeholder:'请输入引用非专利'},
+        ]
+      },
+    ],
+    // searchField:[
+    //   {label: '申请号', value: 'AN',type:3,dataType:1},
+    //   {label: '原始申请号', value: 'ANO',type:3,dataType:1},
+    //   {label: '公告号', value: 'GN',type:1,dataType:1},
+    //   {label: '公开号', value: 'PN',type:3,dataType:1},
+    //   {label: '原始公开号', value: 'PNO',type:2,dataType:1},
+    //   {label: '分类号', value: 'IC',type:3,dataType:1},
+    //   {label: '主分类号', value: 'MC',type:3,dataType:1},
+    //   {label: '优先权号', value: 'PR',type:3,dataType:1},
+    //   {label: '发明人', value: 'IN',type:3,dataType:1},
+    //   {label: '第一发明人', value: 'FI',type:3,dataType:1},
+    //   {label: '申请人', value: 'PA',type:3,dataType:1},
+    //   {label: '第一申请人', value: 'FP',type:3,dataType:1},
+    //   {label: '当前权利人', value: 'PE',type:1,dataType:1},
+    //   {label: '代理机构代码', value: 'AG',type:1,dataType:1},
+    //   {label: '代理人', value: 'AT',type:1,dataType:1},
+    //   {label: '发明名称/标题', value: 'TI',type:3,dataType:1},
+    //   {label: '主权利要求', value: 'CL',type:1,dataType:1},
+    //   {label: '申请日', value: 'AD',type:3,dataType:2},
+    //   {label: '公告日', value: 'GD',type:1,dataType:2},
+    //   {label: '公开日', value: 'PD',type:3,dataType:2},
+    //   {label: '范畴分类', value: 'CT',type:1,dataType:1},
+    //   {label: '国省代码', value: 'CO',type:3,dataType:1},
+    //   {label: '发明人国家', value: 'ICO',type:2,dataType:1},
+    //   {label: '国家', value: 'GJ',type:3,dataType:3},
+    //   {label: '申请人地址', value: 'DZ',type:1,dataType:1},
+    //   {label: '关键词', value: 'TX',type:3,dataType:1},
+    //   {label: '摘要', value: 'AB',type:3,dataType:1},
+    //   {label: '专利类型', value: 'PT',type:1,dataType:3},
+    //   {label: '法律状态', value: 'LG',type:1,dataType:3},
+    //   {label: '引用专利', value: 'CC',type:3,dataType:1},
+    //   {label: '引用非专利', value: 'UCC',type:1,dataType:1},
+    //   {label: '代理机构名称', value: 'AGN',type:1,dataType:1},
+    //   {label: '欧洲分类', value: 'EC',type:2,dataType:1},
+    // ],
+    LG:[//法律状态
+      {
+        label:'有效',
+        value:1
+      },
+      {
+        label:'无效',
+        value:2
+      },
+      {
+        label:'审中',
+        value:3
+      },
+    ],
+    PT:[//专利类型
+      {
+        label:'发明',
+        value:1
+      },
+      {
+        label:'新型',
+        value:2
+      },
+      {
+        label:'外观',
+        value:3
+      },
+    ],
 }

+ 2 - 2
RMS-FrontEnd/src/utils/directives.js

@@ -11,7 +11,7 @@ const draggable = (el, binding) => {
     // 绑定拖拽事件 [绑定拖拽触发元素为弹框头部、拖拽移动元素为整个弹框]
     startDrag(el.querySelector('.el-dialog__header'), el.querySelector('.el-dialog'), binding.value);
 };
- 
+//左右拖动改变宽度大小
 const dragControllerDiv=(el, binding)=>{
   var resize = el.children[1];
   var left =el.children[0];
@@ -135,6 +135,7 @@ const dragControllerDiv1=(el,binding)=>{
           return false;
         }
 };
+//上下拖动改变高度大小
 const dragControllerDiv2=(el,binding)=> {
   var resize1 = el.children[1];
   // var resize2 = el.children[1];
@@ -169,7 +170,6 @@ const dragControllerDiv2=(el,binding)=> {
           // resize1[i].top = resize1[i].offsetTop;
           // 鼠标拖动事件
           document.onmousemove = function (e) {
-              
               var endX = e.clientY;
               var moveLen = resize1.top + (endX - startX); // (endx-startx)=移动的距离。resize[i].left+移动的距离=左边区域最后的宽度
               var maxT = boxClientHeight- resize1.offsetHeight; // 容器宽度 - 左边区域的宽度 = 右边区域的宽度

+ 7 - 2
RMS-FrontEnd/src/utils/index.js

@@ -51,8 +51,13 @@ export const downLoadBase64 = (content, fileName) => {
   aLink.click();
 }
 
-export const downLoad2 = (url) => {
-  const href = `/api/report/api/download/downloadFile?url=${encodeURIComponent(url)}`
+export const downLoad2 = (url,id) => {
+  if(id){
+    var a = `taskId=${id}&url=${encodeURIComponent(url)}`
+  }else{
+    var a = `url=${encodeURIComponent(url)}`
+  }
+  const href = `/api/report/api/download/downloadFile?${a}`
   const anchor = document.createElement('a');
   const fileName = 'download';
   if ('download' in anchor) {

+ 45 - 7
RMS-FrontEnd/src/views/components/articles/ContrastIndex.vue

@@ -17,8 +17,8 @@
         <el-header class="patent-articles-title">
           <div class="patent-articles-title-box">
             <div style="position:relative">
-              <img src="@/assets/visual/fixed.png" width="20px" height="20px" v-if="fix===true" @click="qx" style="position:absolute;top:5px;left:5px"/>
-              <img src="@/assets/visual/unfixed.png" width="20px" height="20px" v-if="fix===false"  @click="gd" style="position:absolute;top:5px;left:5px"/>
+              <img src="@/assets/visual/fixed.png" width="20px" height="20px" v-if="fix===true && !showEvidence" @click="qx" style="position:absolute;top:5px;left:5px"/>
+              <img src="@/assets/visual/unfixed.png" width="20px" height="20px" v-if="fix===false && !showEvidence"  @click="gd" style="position:absolute;top:5px;left:5px"/>
               <!-- <div>
                  <patent-list :patent-id="patentId" :project-id="projectId" @on-change="onChange" />
               </div> -->
@@ -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,9 +148,10 @@ export default {
     Other,
     Permit,
     ProductManage,
-    PatentWorth
+    PatentWorth,
+    PatentMark
   },
-  props:['patentMessage','publicNo','signPatentNo','reportId','type','isTrue',"taskId","patentStatus2A"],
+  props:['patentMessage','publicNo','signPatentNo','reportId','type','isTrue',"taskId","patentStatus2A",'showEvidence'],
   // props: {
   //   'patentMessage':String,
   //   'publicNo':String,
@@ -261,7 +266,9 @@ export default {
    
     publicNo(val) {
       // console.log(val);
-      this.getPatent(val)
+      if (this.fix != true) {
+          this.getPatent(val)
+        }
     },
     patentMessage(val, oldval) {
       if (val) {
@@ -311,8 +318,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)
     },

+ 15 - 15
RMS-FrontEnd/src/views/components/articles/components/PatentBasic.vue

@@ -80,14 +80,14 @@
             <el-tabs value="0">
               <el-tab-pane label="著录项目" name="0">
                 <el-descriptions :column=2>
-                <el-descriptions-item label="申请号"><div class="patent-basic-value" data-type="申请号" v-html="getViewDom(patent.applicationNo,'申请号')"></div></el-descriptions-item>
-                <el-descriptions-item label="申请日"><div class="patent-basic-value" data-type="申请日" v-html="getViewDom(patent.applicationDate,'申请日')"></div></el-descriptions-item>
-                <el-descriptions-item label="公开号"><div class="patent-basic-value" data-type="公开号" v-html="getViewDom(patent.publicNo,'公开号')"></div></el-descriptions-item>
-               <el-descriptions-item label="公开日"><div class="patent-basic-value" data-type="公开日" v-html="getViewDom(patent.publicDate,'公开日')"></div></el-descriptions-item>
+                <el-descriptions-item label="申请号"><div class="patent-basic-value"  v-html="getViewDom(patent.applicationNo,'申请号')"></div></el-descriptions-item>
+                <el-descriptions-item label="申请日"><div class="patent-basic-value"  v-html="getViewDom(patent.applicationDate,'申请日')"></div></el-descriptions-item>
+                <el-descriptions-item label="公开号"><div class="patent-basic-value"  v-html="getViewDom(patent.publicNo,'公开号')"></div></el-descriptions-item>
+               <el-descriptions-item label="公开日"><div class="patent-basic-value"  v-html="getViewDom(patent.publicDate,'公开日')"></div></el-descriptions-item>
              
-                <el-descriptions-item label="授权号" v-if="patent.publicAccreditNo"><div class="patent-basic-value" data-type="授权号" v-html="getViewDom(patent.publicAccreditNo,'授权号')"></div></el-descriptions-item>
-                <el-descriptions-item label="授权日" v-if="patent.publicAccreditDate"><div class="patent-basic-value" data-type="授权日" v-html="getViewDom(patent.publicAccreditDate,'授权日')"></div></el-descriptions-item>
-                <el-descriptions-item label="优先权" v-if="patent.priorityNo"><div class="patent-basic-value" data-type="优先权" v-html="getViewDom(patent.priorityNo,'优先权')+ '&nbsp;&nbsp;&nbsp;&nbsp;' +getViewDom(patent.priorityDate,'优先权')"></div></el-descriptions-item>
+                <el-descriptions-item label="授权号" v-if="patent.publicAccreditNo"><div class="patent-basic-value"  v-html="getViewDom(patent.publicAccreditNo,'授权号')"></div></el-descriptions-item>
+                <el-descriptions-item label="授权日" v-if="patent.publicAccreditDate"><div class="patent-basic-value"  v-html="getViewDom(patent.publicAccreditDate,'授权日')"></div></el-descriptions-item>
+                <el-descriptions-item label="优先权" v-if="patent.priorityNo"><div class="patent-basic-value"  v-html="getViewDom(patent.priorityNo,'优先权')+ '&nbsp;&nbsp;&nbsp;&nbsp;' +getViewDom(patent.priorityDate,'优先权')"></div></el-descriptions-item>
             </el-descriptions>
               </el-tab-pane>
             </el-tabs>
@@ -105,26 +105,26 @@
               <el-tab-pane label="相关人" name="0">
                 <el-descriptions :column="1">
                 <el-descriptions-item label="申请人" labelStyle="width:90px" v-if="patent.applicant" contentStyle="display:flex;flex-direction: row;flex-wrap: wrap;justify-content: flex-start;">
-                   <div class="patent-basic-value" v-for="item in patent.applicant.filter(a => a.dataType === 2)"  data-type="申请人" v-html="getViewDom(item.name,'申请人')+'(标:'+getViewDom(item.shortName,'申请人')+')&nbsp;&nbsp;&nbsp;&nbsp;'"></div>
+                   <div class="patent-basic-value" v-for="item in patent.applicant.filter(a => a.dataType === 2)"   v-html="getViewDom(item.name,'申请人')+'(标:'+getViewDom(item.shortName,'申请人')+')&nbsp;&nbsp;&nbsp;&nbsp;'"></div>
                 </el-descriptions-item>
                 <el-descriptions-item label="申请人地址" labelStyle="width:90px" v-if="patent.applicant">
-                   <div class="patent-basic-value" v-for="(item,index) in patent.applicant.filter(a => a.dataType === 2)"  v-if="index==0" data-type="申请人地址" v-html="getViewDom(item.addressStr,'申请人地址')"></div>
+                   <div class="patent-basic-value" v-for="(item,index) in patent.applicant.filter(a => a.dataType === 2)"  v-if="index==0"  v-html="getViewDom(item.addressStr,'申请人地址')"></div>
                 </el-descriptions-item>
                <el-descriptions-item label="权利人" labelStyle="width:90px" v-if="patent.applicant" contentStyle="display:flex;flex-direction: row;flex-wrap: wrap;justify-content: flex-start;">
-                 <div class="patent-basic-value" v-for="item in patent.applicant.filter(a => a.dataType === 1)" data-type="权利人" v-html="getViewDom(item.name,'权利人')+'(标:'+getViewDom(item.shortName,'权利人')+')&nbsp;&nbsp;&nbsp;&nbsp;'"></div>
+                 <div class="patent-basic-value" v-for="item in patent.applicant.filter(a => a.dataType === 1)"  v-html="getViewDom(item.name,'权利人')+'(标:'+getViewDom(item.shortName,'权利人')+')&nbsp;&nbsp;&nbsp;&nbsp;'"></div>
                </el-descriptions-item>
                 <el-descriptions-item label="权利人地址" labelStyle="width:90px" v-if="patent.applicant">
-                  <div class="patent-basic-value" v-for="(item,key) in patent.applicant.filter(a => a.dataType === 1)" v-if="key==0" data-type="权利人地址" v-html="getViewDom(item.addressStr,'权利人地址')"></div>
+                  <div class="patent-basic-value" v-for="(item,key) in patent.applicant.filter(a => a.dataType === 1)" v-if="key==0"  v-html="getViewDom(item.addressStr,'权利人地址')"></div>
                 </el-descriptions-item>
                
                 <el-descriptions-item label="发明人" labelStyle="width:90px" contentStyle="display:flex;flex-direction: row;flex-wrap: wrap;justify-content: flex-start;">
-                  <div class="patent-basic-value" v-for="item in patent.inventor" data-type="发明人" v-html="getViewDom(item.name,'发明人')+ '&nbsp;&nbsp;&nbsp;&nbsp;'"></div>
+                  <div class="patent-basic-value" v-for="item in patent.inventor"  v-html="getViewDom(item.name,'发明人')+ '&nbsp;&nbsp;&nbsp;&nbsp;'"></div>
                 </el-descriptions-item>
                 <el-descriptions-item label="代理人" labelStyle="width:90px" v-if="patent.agent">
-                  <div class="patent-basic-value" v-for="item in patent.agent" data-type="代理人" v-html="getViewDom(item.name,'代理人')+ '&nbsp;&nbsp;&nbsp;&nbsp;'"></div>
+                  <div class="patent-basic-value" v-for="item in patent.agent"  v-html="getViewDom(item.name,'代理人')+ '&nbsp;&nbsp;&nbsp;&nbsp;'"></div>
                 </el-descriptions-item>
                 <el-descriptions-item label="代理机构" labelStyle="width:90px" v-if="patent.agency">
-                   <div v-if="patent.agency" class="patent-basic-value" data-type="代理机构" v-html="getViewDom(patent.agency.name,'代理机构')+ '&nbsp;&nbsp;&nbsp;&nbsp;'"></div>
+                   <div v-if="patent.agency" class="patent-basic-value"  v-html="getViewDom(patent.agency.name,'代理机构')+ '&nbsp;&nbsp;&nbsp;&nbsp;'"></div>
                 </el-descriptions-item>
             </el-descriptions>
               </el-tab-pane>
@@ -143,7 +143,7 @@
               <el-tab-pane label="分类号" name="0"  v-if="patent.ipcList">
                 <el-descriptions :column=1>
                 <el-descriptions-item label="IPC分类号" contentStyle="display:flex;flex-direction: row;flex-wrap: wrap;justify-content: flex-start;">
-                  <div class="patent-basic-value" v-for="item in patent.ipcList" data-type="IPC分类号" v-html="getViewDom(item,'IPC分类号')+ '&nbsp;&nbsp;&nbsp;&nbsp;'"></div>
+                  <div class="patent-basic-value" v-for="item in patent.ipcList"  v-html="getViewDom(item,'IPC分类号')+ '&nbsp;&nbsp;&nbsp;&nbsp;'"></div>
                 </el-descriptions-item>
             </el-descriptions>
               </el-tab-pane>

+ 1 - 1
RMS-FrontEnd/src/views/components/articles/components/PatentInstruction.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="patent-instruction" @mouseup="mouseup" @mousemove="mousemove">
-    <el-tabs value="0">
+    <el-tabs v-model="name">
       <el-tab-pane label="原文" name="0" :style="{height: height + 'px',overflowY: 'auto'}">
         <p class="common" v-if="patent.instruction" data-type="说明书文本原文" v-html="getViewDom(patent.instruction.manual,'说明书文本原文')"></p>
       </el-tab-pane>

+ 123 - 0
RMS-FrontEnd/src/views/components/articles/components/PatentMark.vue

@@ -0,0 +1,123 @@
+<template>
+  <div class="content">
+    <div class="item" v-for="item in patentMark" :key="item.id" :style="{'background':item.color}">
+      <el-popover
+        placement="bottom"
+        width="200"
+        trigger="hover">
+      <div>
+        <p><span style="color: #409EFF;">栏位:</span><span>{{ item.scratchField }}</span></p>
+        <!-- <p>栏位:{{ item.scratchField }}</p> -->
+        <p><span style="color: #409EFF;">选中文本:</span>{{ item.text }}</p>
+        <p v-if="item.remark"><span style="color: #409EFF;">标注:</span>{{ item.remark }}</p>
+      </div>
+      <div slot="reference" style="height:100%;width:100%" @click.prevent.stop="runTo(item)"></div>
+      </el-popover>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  props:['patentNo'],
+  data() {
+    return {
+      patentMark:[]
+    }
+  },
+  computed: {
+    // contrastList() {
+    //   return this.$store.state.report.contrastList
+    // },
+    piZhuContrastList() {
+      return this.$store.state.report.piZhuContrastList
+    }
+  },
+  watch: {
+    // 'contrastList'(val) {
+    //   this.getPatentMark()
+    // },
+    'piZhuContrastList'(val) {
+      this.getPatentMark()
+    },
+    patentNo(val) {
+      this.getPatentMark()
+    },
+  },
+  mounted() {
+    this.getPatentMark()
+  },
+  methods: {
+    getPatentMark() {
+      this.$nextTick(() => {
+        this.patentMark=[]
+        var a = ['摘要', '权利要求', '说明书']
+        var b = this.piZhuContrastList.filter(item => {
+          return item.patentNo == this.patentNo
+        })
+        /**方案一 */
+        // a.forEach(item => {
+        //   b.forEach((item2, index) => {
+        //     if (item2.scratchField.indexOf(item) != -1) {
+        //       this.patentMark.push(item2)
+        //       // 每次都需要重新遍历全部,优化
+        //     }
+        //   })
+        // })
+        /**方案二 */
+        // var c = []
+        // a.forEach((item,index) => {
+        //   c[index] = []
+        // })
+        // b.forEach((item2) => {
+        //   var index = a.findIndex(item => { return item2.scratchField.indexOf(item) != -1 })
+        //   c[index].push(item2)
+        // })
+        // a.forEach((item,index) => {
+        //   c[index].sort((a, b) => {
+        //     return (a.position + a.text.length) - (b.position + b.text.length)
+        //   })
+        // })
+        // this.patentMark = [].concat(...c)
+        /**方案三 */
+        // this.patentMark=b.sort((x,y)=>{
+        //     return a.findIndex(item=>{return x.scratchField.indexOf(item)!=-1}) - a.findIndex(item=>{return y.scratchField.indexOf(item)!=-1})
+        // })
+        /**方案四 */
+        var c = []
+        a.forEach((item,index) => {
+          c[index] = b.filter(item2 => {
+            return item2.scratchField.indexOf(item) != -1  
+          })
+          c[index].sort((a, b) => {
+            return a.position - b.position
+          })
+        })
+        this.patentMark = [].concat(...c)
+      })
+    },
+    runTo(val) {
+      var a = JSON.parse(JSON.stringify(val))
+      a.id = 'p'+a.id
+      this.$emit('biaozhu',a)
+
+    }
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+.item{
+  width: 8px;
+  height: 8px;
+  border: 1px solid black;
+  margin:2px 2px;
+}
+.content{
+  max-width: 300px;
+  max-height: 50px;
+  overflow: auto;
+  display: flex;
+  flex-wrap: wrap;
+}
+</style>

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

@@ -1,17 +1,19 @@
 <template>
   <div class="patent-articles-patent-right" @mouseup="mouseup" @mousemove="mousemove">
-    <el-tabs value="0">
+    <el-tabs v-model="name">
       <el-tab-pane label="原文" name="0" :style="{height: height + 'px',overflowY: 'auto'}">
-        <p class="common" v-for="(item, index) in records.original">
+        <!-- <p class="common" v-for="(item, index) in records.original">
           <span v-if="item" :data-type="'权利要求原文'+(index+1)"  v-html="getViewDom(item,'权利要求原文'+(index+1))"></span>
-        </p>
+        </p> -->
+        <div v-html="getViewDom1(patent.rights,'权利要求原文','content')"  data-type="权利要求原文"></div>
       </el-tab-pane>
       <el-tab-pane label="译文" name="1" :style="{height: height + 'px',overflowY: 'auto'}">
-        <p class="common" v-for="(item, index) in records.translation">
+        <!-- <p class="common" v-for="(item, index) in records.translation">
           <span v-if="item"  :data-type="'权利要求译文'+(index+1)"  v-html="getViewDom(item,'权利要求译文'+(index+1))"></span>
-        </p>
+        </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>
@@ -28,7 +30,7 @@ export default {
   components:{
     Features
   },
-  props:['signPatentNo','reportId'],
+  props:['signPatentNo','reportId','parentNo','type1'],
   mixins: [commonMixins,addContrast,patentKeywordsHighlight],
   data() {
     return {

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

@@ -66,7 +66,7 @@ export const commonMixins = {
   }
 }
 
-export const addContrast = {
+export const addContrast1 = {
     props:['isTrue','type1','reportType'],
   data() {
     return {
@@ -88,7 +88,7 @@ export const addContrast = {
   mounted() {
     document.onselectionchange = () => {
       this.isSelecting=true;
-   };
+    };
   },
   watch:{
     isTrue(val){
@@ -700,4 +700,312 @@ export const addContrast = {
 
    
   }
+}
+
+export const addContrast = {
+  props:['reportId','activeName','evidenceFlieId','signPatentNo','reportType','taskId','type'],
+  data() {
+    return {
+      mX: 0,
+      mY: 0,
+      isSelecting: false,
+      anchorOffset: 0,
+      currentSelectObj:{},
+      contrast: {},
+      currentColor:null,
+      duiBiCurrentSelectObj: {},
+      name:this.activeName,
+    }
+  },
+  computed: {
+    index() {
+      return JSON.stringify(this.$store.state.patent.index)
+    },
+    contrastList() {
+      return this.$store.state.report.contrastList
+    },
+    opinionContrastList() {
+      return this.$store.state.report.opinionContrastList
+    },
+  },
+  watch: {
+    index(val) {
+      var index1 = JSON.parse(val)
+      this.currentColor = index1.color
+    },
+    activeName(val) {
+      this.name = val
+    },
+  },
+  mounted() {
+    window.pizhu = this.pizhu
+    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
+      // open打开弹窗
+      if (this.duiBiCurrentSelectObj.Id) {
+        this.$emit('openContrast',this.duiBiCurrentSelectObj)
+      }
+    },
+    //点击图标回显数据
+    selectMark(id, selectType) {
+      var Id = id.substring(1,id.length)
+      if (selectType=='p') {
+        var index = this.piZhuContrastList.findIndex(item => {
+        if (item.id == Id) {
+          // 清空currentSelectObj,否则Id与id同时存在
+          this.currentSelectObj = {}
+          this.$store.commit("SET_PATENT_INDEX", this.currentSelectObj)
+          this.contrast = item
+          this.$store.commit('SET_PATENT_INDEX', this.contrast)
+        }
+        return item.id == Id
+        })
+        if (index != -1) {
+          this.showPizhu()
+        }
+      } else if (selectType == 'c') {
+        let a=this.contrastList.find(item => {
+          return item.id==Id
+        })
+        this.$emit('openContrast', a)
+      } else if (selectType == 'o') {
+        let a=this.opinionContrastList.find(item => {
+          return item.id==Id
+        })
+        this.$emit('openOpinioncontrast', a)
+        // this.showPizhu()
+        // this.$store.commit('SET_PATENT_INDEX',a)
+      }
+      
+    },
+    mousemove(e) {
+      this.mX = e.pageX;
+      this.mY = e.pageY;
+    },
+    mouseup(e) {
+      sessionStorage.mY = this.mY
+      sessionStorage.mX = this.mX
+      this.isSelecting = true;
+      if (this.isSelecting) {
+        this.isSelecting = false;
+        let selectObj = document.getSelection();
+        this.anchorOffset = 0;
+        let temSelectObj = this.getSelectobj(selectObj);
+        var tempdt = this.getColumnName(selectObj.anchorNode);
+        if (tempdt != undefined && selectObj.toString() != '') {
+          this.currentSelectObj = temSelectObj;
+          this.currentSelectObj.color = this.currentColor;
+          this.currentSelectObj.Type = 0;
+          this.currentSelectObj.patentNo = this.patent.publicNo
+          // rangeId(专题库id/报告id)
+          this.currentSelectObj.rangeId = this.reportId
+          // 创建来源(默认0/专题库1/报告2)
+          this.currentSelectObj.createFrom = 2
+          // this.showPizhu();
+          this.currentSelectObj.remark = ''
+        }
+        else {
+          this.currentSelectObj = {};
+        }
+        if (this.currentSelectObj.Id) {
+          var a = JSON.parse(this.index)
+          a.Id = this.currentSelectObj.Id
+          a.patentNo = this.currentSelectObj.patentNo
+          a.text = this.currentSelectObj.text
+          a.rangeId = this.reportId
+          a.scratchField = this.currentSelectObj.column
+          a.position = this.currentSelectObj.index
+          a.id = null
+          a.remark = null
+          // 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
+          a.rightPosition = this.currentSelectObj.rightPosition
+          this.$store.commit("SET_PATENT_INDEX", a)
+          this.showPizhu()
+        }
+      }
+    },
+    // 打开批注框
+    pizhu() {
+      if (this.contrast.id == undefined) {
+        this.currentSelectObj = JSON.parse(this.index)
+      }
+      if (this.currentSelectObj.Id != undefined || this.contrast.id != undefined) {
+        // 划词进入
+        // if (this.currentSelectObj.Id != undefined) {
+        //   console.log(2,this.currentSelectObj);
+        //   this.$store.commit('SET_PATENT_INDEX', this.currentSelectObj)
+        // }
+        this.currentSelectObj.Type = 2;
+        this.hiddenPizhu();
+        this.showPizhu2()
+        this.contrast = {}
+      }
+    },
+    showPizhu2() {//展示批注
+      let dl = document.getElementsByClassName("pizhu");
+      let mX = sessionStorage.mX
+      let mY = sessionStorage.mY
+      console.log(document.body.clientHeight , mY);
+      if ((document.body.clientWidth - mX - 380) < 0) {
+        mX = document.body.clientWidth - 390;
+      }
+      if ((document.body.clientHeight - mY - 40) < 0) {
+        mY = document.body.clientHeight - 40;
+      }
+      if ((document.body.clientHeight - mY) < 420) {
+        mY = mY - 410
+      }
+      if ((document.body.clientWidth - mX) < 330) {
+        mX = mX - 330
+      }
+      dl[0].setAttribute("style", "user-select:none;box-shadow: 10px 10px 5px #888888;display:block;position:absolute;left:" + mX.toString() + "px;top:" + mY.toString() + "px;background-color: #F7EED6;border-radius: 15px 15px;padding: 10px;width:380px;z-index: 2;");
+    },
+    showPizhu() {//展示菜单
+      // this.AddClass1(this.currentSelectObj)
+      let mX = sessionStorage.mX
+      let mY = sessionStorage.mY
+      let dl = document.getElementsByClassName("caidan");
+      if ((document.body.clientWidth - mX - 420) < 0) {
+        mX = document.body.clientWidth - 420;
+      }
+      if ((document.body.clientHeight - mY - 40) < 0) {
+        mY = document.body.clientHeight - 40;
+      }
+      dl[0].setAttribute("style", "opacity:0.95;box-shadow: 10px 10px 5px #888888;display:block;position:absolute;left:" + mX.toString() + "px;top:" + mY.toString() + "px;background-color: white;border-radius: 15px 15px;height:30px;display: flex;align-items: center;padding: 10px;user-select:none");
+    },
+    // 关闭菜单
+    hiddenPizhu() {
+      let dl = document.getElementsByClassName("caidan");
+      dl[0].setAttribute("style", "display:none;");
+    },
+    getSelectobj(selectObj) {
+      var temNode = selectObj.anchorNode;
+      var a = temNode.parentElement
+      NotIncludeDataType(a)
+      function NotIncludeDataType(node) {
+        if (node.getAttribute("data-type") != null) {
+          temNode = node
+        } else {
+          NotIncludeDataType(node.parentElement);
+        }
+      }
+      var rightSort = null
+      if (this.reportType == 7 && temNode.getAttribute("data-type").includes('权利要求')) {
+        var node1 = null
+        getRightSort(a)
+        function getRightSort(node) {
+          if (node.getAttribute("right-sort") != null) {
+            rightSort = node.getAttribute("right-sort")
+            node1 = node
+          } else {
+            getAttribute(node.parentElement);
+          }
+        }
+        var rightPosition = this.getColumn(node1, selectObj)
+      }
+      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,'rightSort':rightSort,'rightPosition':rightPosition };
+    },
+    getColumn(node, selectObj) {
+      var baseNode = this.getColumnNode(node);
+      var anchorNodePosition = this.getPosition(baseNode, selectObj.anchorNode, selectObj.anchorOffset);
+      var focusNodePosition = this.getPosition(baseNode, selectObj.focusNode, selectObj.focusOffset);
+      var num = Math.min(anchorNodePosition, focusNodePosition)
+      this.anchorOffset = num
+      return num;
+    },
+    getColumnNode(node) {
+      //获取节点所在的栏位节点
+      if (node != null) {
+        if (node.nodeType != 3 && node.getAttribute("data-type") != null) {
+          return node;
+        } else {
+          if (node == document.root) {
+            return node;
+          } else {
+            return this.getColumnNode(node.parentNode);
+          }
+        }
+      }
+    },
+    getNodes(baseNode, path) {
+      // 拿到所有类型的节点
+      var temPath = path;
+      if (baseNode != null) {
+        temPath.push(baseNode);
+        if (baseNode.childNodes.length > 0) {
+          for (let i = 0; i < baseNode.childNodes.length; i++) {
+            this.getNodes(baseNode.childNodes[i], temPath);
+          }
+        }
+      }
+    },
+    getPosition(baseNode, node, offset) {
+      //根据节点获取给定node中offset位置在栏位中的实际位置
+      let path = [];
+      this.getNodes(baseNode, path);
+      let retIdx = 0;
+      for (let i = 0; i < path.length; i++) {
+        if (path[i] == node) {
+          retIdx += offset;
+          return retIdx;
+        } else {
+          if (path[i].nodeType == 3) {
+            retIdx += path[i].nodeValue.length;
+          }
+        }
+      }
+    },
+    uuid() {
+      var s = [];
+      var hexDigits = "0123456789abcdef";
+      for (var i = 0; i < 36; i++) {
+        s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
+      }
+      s[14] = "4";  // bits 12-15 of the time_hi_and_version field to 0010
+      s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);  // bits 6-7 of the clock_seq_hi_and_reserved to 01
+      s[8] = s[13] = s[18] = s[23] = "-";
+      var uuid = s.join("");
+      return uuid;
+    },
+    getColumnName(el) {
+      let root = el;
+      if (el == undefined) {
+        return undefined;
+      }
+      if (!(el instanceof HTMLElement)) {
+        root = el.parentElement;
+      }
+      let dt = root.getAttribute("data-Type");
+      if (dt != undefined) {
+        return root;
+      }
+      return dt = this.getColumnName(root.parentElement);
+    },
+  },
 }

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 270 - 29
RMS-FrontEnd/src/views/components/articles/index.vue


+ 8 - 0
RMS-FrontEnd/src/views/components/common/RichText/index.js

@@ -0,0 +1,8 @@
+import RichText from './index.vue'
+const myRichText = {
+    install: function(Vue) {
+        // 注册并获取组件,然后在main.js中引用,在Vue.use()就可以了
+        Vue.component('myRichText', RichText)
+    }
+}
+export default myRichText

+ 207 - 0
RMS-FrontEnd/src/views/components/common/RichText/index.vue

@@ -0,0 +1,207 @@
+<template>
+    <div class="boxs">
+      <!-- <el-upload
+        class="avatar-uploader"
+        name="file"
+        action=""
+        :show-file-list="false"
+        :data="uploadData"
+        :http-request="uploadHttpRequest"
+      >
+      </el-upload> -->
+      <quill-editor v-model="content" ref="myQuillEditor" :options="editorOption" @blur="saveHtml" @change="saveHtml1" @focus="getFocus"></quill-editor>
+      <!-- 富文本内容 -->
+    </div>
+</template> 
+<script>
+  import { quillEditor } from "vue-quill-editor";
+  import ImageBlot from './reviewClass'
+  // 工具栏配置
+//   const toolbarOptions = [
+//     ["bold", "italic", "underline", "strike"], // 加粗 斜体 下划线 删除线
+//     ["blockquote", "code-block"], // 引用  代码块
+//     [{ header: 1 }, { header: 2 }], // 1、2 级标题
+//     [{ list: "ordered" }, { list: "bullet" }], // 有序、无序列表
+//     [{ script: "sub" }, { script: "super" }], // 上标/下标
+//     [{ indent: "-1" }, { indent: "+1" }], // 缩进
+//     // [{'direction': 'rtl'}],                         // 文本方向
+//     [{ size: ["small", false, "large", "huge"] }], // 字体大小
+//     [{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题
+//     [{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色
+//     [{ font: [] }], // 字体种类
+//     [{ align: [] }], // 对齐方式
+//     ["clean"], // 清除文本格式
+//     ["link", "image", "video"], // 链接、图片、视频
+//   ];
+  export default {
+    props:{
+        value:{
+            type:String,
+            default:(value)=>{
+                if(!value){
+                  return ""
+                }
+                
+            }
+        },
+        placeholder:{
+            type:String,
+            default:()=>{
+                return "请输入"
+            }
+        },
+        filed:{
+            type:String,
+            default:()=>{
+                return ''
+            }
+        },
+        keys:{
+          type:String,
+          default:()=>{
+            const len = 6
+            const codeList = []
+            const chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz0123456789'
+            const charsLen = chars.length
+            for (let i = 0; i < len; i++) {
+              codeList.push(chars.charAt(Math.floor(Math.random() * charsLen)))
+            }
+            return  codeList.join('')
+          }
+        }
+    },
+    data() {
+      return {
+        uploadData: {}, // 图片文件
+        content: this.value||"", // 内容
+        // content: null,
+        editorOption: {
+          placeholder: this.placeholder,
+          key:this.keys,
+        //   modules: {
+        //     toolbar: {
+        //       container: toolbarOptions,
+        //       handlers: {
+        //         image: function (value) {
+        //           if (value) {
+        //             // 触发input框选择图片文件
+        //             document.querySelector(".avatar-uploader input").click();
+        //           } else {
+        //             this.quill.format("image", false);
+        //           }
+        //         },
+        //       },
+        //     },
+        //   },
+        },
+      };
+    },
+    watch:{
+        value(val){
+          var a = this.content.replace(/<p>|<\/p>/g,'')
+            if(a!=val){
+              this.content = val
+            }
+        },
+    },
+    computed:{
+      quill(){
+        return this.$refs.myQuillEditor.quill
+      }
+    },
+    mounted() {
+      // let quill = this.$refs.myQuillEditor.quill
+      // this.quill.enable(false)
+      //     this.$nextTick(()=>{
+            this.quill.enable(true)
+          // })
+      this.$forceUpdate()
+      this.quill.root.addEventListener('paste', evt => {
+        if (evt.clipboardData && evt.clipboardData.files && evt.clipboardData.files.length) {
+          evt.preventDefault();
+          [].forEach.call(evt.clipboardData.files,async file => {
+            if (!file.type.match(/^image\/(gif|jpe?g|a?png|bmp)/i)) {
+              return
+            }
+          // 获取光标所在位置
+          let length = this.quill.selection.savedRange.index
+          var str = await this.fileToBase64(file)
+          this.quill.insertEmbed(length, 'image',{
+            url:str,
+            width:'',
+            height:'',
+            style:'width:80px;height: 80px;border: 1px solid #f9f6f675;vertical-align:middle'
+          })
+          this.quill.setSelection(length + 2)
+          })
+        }
+      }, false)
+    },
+    methods: {
+      // 将file文件上传转化为base64进行显示
+        fileToBase64(file) {
+            return new Promise((resolve, reject) => {
+                ///FileReader类就是专门用来读文件的
+                const reader = new FileReader()
+                //开始读文件
+                reader.readAsDataURL(file)
+                reader.onload = () => resolve(reader.result)
+                // 失败返回失败的信息
+                reader.onerror = error => reject(error)
+            })
+        },
+      //失去焦点
+      saveHtml(event) {
+        // this.quill.enable(false)
+        // console.log("this.content", this.content);
+        // this.content = this.content.replace(/<p>|<\/p>/g,'')
+        //   this.$emit('input',this.content)
+        //   this.$nextTick(()=>{
+        //     this.quill.enable(true)
+        //   })
+          
+        // this.$emit('value',{
+        //     filed:this.filed,
+        //     content:this.content
+        // })
+      },
+      //值变化
+      saveHtml1(event) {
+        var a = this.content.replace(/<p>|<\/p>/g,'')
+          this.$emit('input',a)
+      },
+      getFocus(){
+            this.quill.enable(true)
+      },
+    },
+  };
+</script> 
+<style lang="scss">
+  .boxs {
+    /* line-height: normal !important;
+    height: 500px;
+    width: 700px;
+    margin: 20px auto; */
+    .ql-toolbar{
+        display: none;
+    }
+    .quill-editor{
+        border:1px solid #dcdfe6;
+        border-radius: 5px;
+       .ql-container
+       {
+        border:0;
+        .ql-editor{
+          display: flex;
+          align-items: end;
+        }
+       }
+    }
+    .ql-editor.ql-blank::before {
+        font-style: normal;
+      }
+
+  }
+</style>   
+  
+  

+ 6 - 0
RMS-FrontEnd/src/views/components/common/RichText/mixins.js

@@ -0,0 +1,6 @@
+import RichText from './index.vue'
+export const RichText1 ={
+    components:{
+        RichText
+    }
+}

+ 40 - 0
RMS-FrontEnd/src/views/components/common/RichText/reviewClass.js

@@ -0,0 +1,40 @@
+
+import {Quill} from 'vue-quill-editor'
+const BlockEmbed = Quill.import('blots/block/embed')
+// 添加插入图片
+class ImageBlot extends BlockEmbed {
+  static create(value) {
+    const node = super.create(value)
+    node.setAttribute('src', value.url)
+    // node.setAttribute('title', value.name)
+    // node.setAttribute('controls', value.controls)
+    // node.setAttribute('controlslist', value.controlslist)
+    node.setAttribute('width', value.width)
+    node.setAttribute('height', value.height)
+    node.setAttribute('webkit-playsinline', true)
+    node.setAttribute('playsinline', true)
+    node.setAttribute('x5-playsinline', true)
+    node.setAttribute('style', value.style)
+    // if (value.autoplay) {
+    //   node.setAttribute('autoplay', value.autoplay)
+    // }
+    return node
+  }
+ 
+  static value(node) {
+    return {
+      url: node.getAttribute('src'), // 注意这里和上面的属性和值反过来相对
+    //   name: node.getAttribute('title'),
+    //   autoplay: node.getAttribute('autoplay'),
+    //   controls: node.getAttribute('controls'),
+    //   controlslist: node.getAttribute('controlslist'),
+      width: node.getAttribute('width'),
+      height: node.getAttribute('height'),
+      style: node.getAttribute('style')
+    }
+  }
+}
+ 
+ImageBlot.blotName = 'image' //quill使用时的名称
+ImageBlot.tagName = 'img' //定义的html标签名
+Quill.register(ImageBlot) // 注册

+ 5 - 5
RMS-FrontEnd/src/views/components/common/SplitScreen.js

@@ -37,7 +37,7 @@ export const splitScreen = {
     },
     mounted() {
         this.$nextTick(()=>{
-            this.$set(this,'height',document.getElementsByClassName('patent-articles-content-left')[0].offsetHeight +20 + 'px')
+            this.$set(this,'height',document.getElementsByClassName('el-main')[0].offsetHeight-200 + 'px')
             this.height2 = this.height
          })
     },
@@ -56,7 +56,7 @@ export const splitScreen = {
         switch(val){
           case 1://tab展示
             dom[0].style.flexDirection = ''
-            this.height = (height) + 'px'
+            this.height = document.getElementsByClassName('el-main')[0].offsetHeight-200 + 'px'
             this.$nextTick(()=>{
               left1[0].style.width = '100%'
             })
@@ -129,10 +129,10 @@ export const splitScreen1 = {
     mounted() {
       this.$nextTick(() => {
           if (document.getElementsByClassName('patent-articles-content-left').length>0) {
-             this.$set(this,'height',document.getElementsByClassName('patent-articles-content-left')[0].offsetHeight+20  + 'px')
+             this.$set(this,'height',document.getElementsByClassName('el-main')[0].offsetHeight-200 + 'px')
           }
             if(this.height == '20px'){
-                this.$set(this,'height',document.getElementsByClassName('patent-articles-content-left1')[0].offsetHeight+20  + 'px')
+                this.$set(this,'height',document.getElementsByClassName('el-main')[0].offsetHeight-200 + 'px')
                 this.height2 = this.height
             }
          })
@@ -152,7 +152,7 @@ export const splitScreen1 = {
             switch(val){
               case 1://tab展示
                 dom[0].style.flexDirection = ''
-                this.height = (height) + 'px'
+                this.height = document.getElementsByClassName('el-main')[0].offsetHeight-200 + 'px'
                 // this.$nextTick(()=>{
                 //   left1[0].style.width = '100%'
                 // })

+ 196 - 0
RMS-FrontEnd/src/views/components/common/components/editDiv.js

@@ -0,0 +1,196 @@
+export const changeWidth={
+    mounted() {
+        // this.dragControllerDiv()
+    },
+    methods: {
+        dragControllerDiv:function() {
+            var resize = document.getElementsByClassName('resize');
+            var left = document.getElementsByClassName('left');
+            var mid = document.getElementsByClassName('mid');
+            var box = document.getElementsByClassName('box');
+            for (let i = 0; i < resize.length; i++) {
+                // 鼠标按下事件
+                resize[i].onmousedown = function (e) {
+                    //颜色改变提醒
+                    resize[i].style.background = '#818181';
+                    var startX = e.clientX;
+                    resize[i].left = resize[i].offsetLeft;
+                    // 鼠标拖动事件
+                    document.onmousemove = function (e) {
+                        var endX = e.clientX;
+                        var moveLen = resize[i].left + (endX - startX); // (endx-startx)=移动的距离。resize[i].left+移动的距离=左边区域最后的宽度
+                        var maxT = box[i].clientWidth - resize[i].offsetWidth; // 容器宽度 - 左边区域的宽度 = 右边区域的宽度
+
+                        if (moveLen < 32) moveLen = 32; // 左边区域的最小宽度为32px
+                        if (moveLen > maxT - 150) moveLen = maxT - 150; //右边区域最小宽度为150px
+
+                        resize[i].style.left = moveLen; // 设置左侧区域的宽度
+
+                        for (let j = 0; j < left.length; j++) {
+                            left[j].style.width = moveLen + 'px';
+                           if(mid[j]){
+                            mid[j].style.width = (box[i].clientWidth - moveLen - 10) + 'px';
+                           }
+                            
+                        }
+                    };
+                    // 鼠标松开事件
+                    document.onmouseup = function (evt) {
+                        //颜色恢复
+                        resize[i].style.background = '#d6d6d6';
+                        document.onmousemove = null;
+                        document.onmouseup = null;
+                        resize[i].releaseCapture && resize[i].releaseCapture(); //当你不在需要继续获得鼠标消息就要应该调用ReleaseCapture()释放掉
+                    };
+                    resize[i].setCapture && resize[i].setCapture(); //该函数在属于当前线程的指定窗口里设置鼠标捕获
+                    return false;
+                };
+            }
+        },
+        dragControllerDiv1:function() {
+            var resize1 = document.getElementsByClassName('resize1');
+            var left = document.getElementsByClassName('left1');
+            var mid = document.getElementsByClassName('mid1');
+            var box = document.getElementsByClassName('box1');
+            
+            for (let i = 0; i < resize1.length; i++) {
+                // 鼠标按下事件
+                resize1[i].onmousedown = function (e) {
+                    //颜色改变提醒
+                    resize1[i].style.background = '#818181';
+                    var startX = e.clientX;
+                    resize1[i].left = resize1[i].offsetLeft-50;
+                    // 鼠标拖动事件
+                    document.onmousemove = function (e) {
+                        var flex = box[i].style.flexDirection
+                        var endX = e.clientX;
+                        var moveLen = resize1[i].left + (endX - startX); // (endx-startx)=移动的距离。resize[i].left+移动的距离=左边区域最后的宽度
+                        var maxT = box[i].clientWidth - resize1[i].offsetWidth; // 容器宽度 - 左边区域的宽度 = 右边区域的宽度
+
+                        if (moveLen < 32) moveLen = 32; // 左边区域的最小宽度为32px
+                        if (moveLen > maxT - 150) moveLen = maxT - 150; //右边区域最小宽度为150px
+
+                        resize1[i].style.left = moveLen; // 设置左侧区域的宽度
+
+                        for (let j = 0; j < left.length; j++) {
+                            switch (flex) {
+                                case 'row-reverse':
+                                    mid[j].style.width = moveLen + 'px';
+                                    if(left[j]){
+                                     left[j].style.width = (box[i].clientWidth - moveLen - 10) + 'px';
+                                    }
+                                    break;
+                                case 'row':
+                                    left[j].style.width = moveLen + 'px';
+                                    if(mid[j]){
+                                        mid[j].style.width = (box[i].clientWidth - moveLen - 10) + 'px';
+                                    }
+                                    break;
+                                case 'column-reverse':
+                                    
+                                    break;
+                                case 'column':
+                                    
+                                    break;
+                                default:
+                                    break;
+                            }
+                       
+                          
+                        }
+                    };
+                    // 鼠标松开事件
+                    document.onmouseup = function (evt) {
+                        //颜色恢复
+                        resize1[i].style.background = '#d6d6d6';
+                        document.onmousemove = null;
+                        document.onmouseup = null;
+                        resize1[i].releaseCapture && resize1[i].releaseCapture(); //当你不在需要继续获得鼠标消息就要应该调用ReleaseCapture()释放掉
+                    };
+                    resize1[i].setCapture && resize1[i].setCapture(); //该函数在属于当前线程的指定窗口里设置鼠标捕获
+                    return false;
+                };
+            }
+        },
+        dragControllerDiv2:function() {
+            var resize1 = document.getElementsByClassName('resize2');
+            var left = document.getElementsByClassName('left1');
+            var mid = document.getElementsByClassName('mid1');
+            var box = document.getElementsByClassName('box1');
+            
+            for (let i = 0; i < resize1.length; i++) {
+                // 鼠标按下事件
+                resize1[i].onmousedown = function (e) {
+                    var flex = box[i].style.flexDirection
+                    switch (flex) {
+                        case 'row-reverse':
+                           
+                            break;
+                        case 'row':
+                            
+                            break;
+                        case 'column-reverse':
+                            resize1[i].top = mid[i].offsetHeight;
+                            break;
+                        case 'column':
+                            resize1[i].top = left[i].offsetHeight;
+                            break;
+                        default:
+                            break;
+                    }
+                    //颜色改变提醒
+                    resize1[i].style.background = '#818181';
+                    var startX = e.clientY;
+                    // resize1[i].top = resize1[i].offsetTop;
+                    // 鼠标拖动事件
+                    document.onmousemove = function (e) {
+                        
+                        var endX = e.clientY;
+                        var moveLen = resize1[i].top + (endX - startX); // (endx-startx)=移动的距离。resize[i].left+移动的距离=左边区域最后的宽度
+                        var maxT = box[i].clientHeight - resize1[i].offsetHeight; // 容器宽度 - 左边区域的宽度 = 右边区域的宽度
+                        if (moveLen < 150) moveLen = 150; // 左边区域的最小宽度为32px
+                        if (moveLen > maxT - 150) moveLen = maxT - 150; //右边区域最小宽度为150px
+
+                        resize1[i].style.top = moveLen; // 设置左侧区域的宽度
+                        for (let j = 0; j < left.length; j++) {
+                            switch (flex) {
+                                case 'row-reverse':
+                                   
+                                    break;
+                                case 'row':
+                                    
+                                    break;
+                                case 'column-reverse':
+                                    mid[j].style.height = moveLen + 10 + 'px';
+                                    if(left[j]){
+                                        left[j].style.height = (box[i].clientHeight - moveLen ) + 'px';
+                                    }
+                                    break;
+                                case 'column':
+                                    left[j].style.height = moveLen + 10 + 'px';
+                                    if(mid[j]){
+                                        mid[j].style.height = (box[i].clientHeight - moveLen ) + 'px';
+                                    }
+                                    break;
+                                default:
+                                    break;
+                            }
+                       
+                          
+                        }
+                    };
+                    // 鼠标松开事件
+                    document.onmouseup = function (evt) {
+                        //颜色恢复
+                        resize1[i].style.background = '#d6d6d6';
+                        document.onmousemove = null;
+                        document.onmouseup = null;
+                        resize1[i].releaseCapture && resize1[i].releaseCapture(); //当你不在需要继续获得鼠标消息就要应该调用ReleaseCapture()释放掉
+                    };
+                    resize1[i].setCapture && resize1[i].setCapture(); //该函数在属于当前线程的指定窗口里设置鼠标捕获
+                    return false;
+                };
+            }
+        },
+    },
+}

+ 357 - 0
RMS-FrontEnd/src/views/components/common/components/mixins.js

@@ -0,0 +1,357 @@
+export const cron = {
+    methods: {
+        //生成cron表达式
+    getCron(type) {
+      if(type){
+        var cron = ''
+        if(type == "day"){
+            let m = "";
+            let s = "";
+            let h = "";
+            let date = new Date();
+            if (date) {
+              h = date.getHours();
+              m = date.getMinutes();
+              s = date.getSeconds();
+          }
+          this.$set(this,'value',h+':'+m+':'+s)
+            cron = s + " " + m + " " + h + " * * ? *";
+        }else if (type == "week") { //星期
+          let m = "";
+          let s = "";
+          let h = "";
+          var value1 = ''
+          var week = new Date().getDay()
+          // 编辑回显后再次转义
+          switch (week) {
+            case 0:
+              value1 = "1";
+              break;
+            case 1:
+              value1 = "2";
+              break;
+            case 2:
+              value1 = "3";
+              break;
+            case 3:
+              value1 = "4";
+              break;
+            case 4:
+              value1 = "5";
+              break;
+            case 5:
+              value1 = "6";
+              break;
+            case 6:
+              value1 = "7";
+              break;
+          }
+          var en2cnMap = {
+            1: "周日",
+            2: "周一",
+            3: "周二",
+            4: "周三",
+            5: "周四",
+            6: "周五",
+            7: "周六",
+          };
+          this.$set(this,'day',en2cnMap[value1])
+          let date = new Date();
+          if (date) {
+            h = date.getHours();
+            m = date.getMinutes();
+            s = date.getSeconds();
+          }
+          this.$set(this, 'time', (h < 10 ? ("0" + h) : h )+ ':' + (m < 10 ? ("0" + m) : m) + ':' + (s < 10 ? ("0" + s) : s))
+          this.$set(this, 'value', this.day + " " + this.time)
+          cron = s + " " + m + " " + h + " ? * " + value1 + " *";
+          //周cron表达式
+        } else if (type == "month") {//每月的几号
+          let m = "";
+          let s = "";
+          let h = "";
+          let mo =  "";
+          var date = new Date();
+          if (date) {
+            mo = date.getDate() 
+            h = date.getHours();
+            m = date.getMinutes();
+            s = date.getSeconds();
+          }
+          this.$set(this,'day',mo+'日')
+          this.$set(this, 'time', (h < 10 ? ("0" + h) : h )+ ':' + (m < 10 ? ("0" + m) : m) + ':' + (s < 10 ? ("0" + s) : s))
+          this.$set(this,'value',this.day+" "+this.time)
+          cron = s + " " + m + " " + h + " " + mo + " * ? *"
+        } else if (type == "year") {//指定年月日
+          let m = "";
+          let s = "";
+          let h = "";
+          let year = "";
+          let month = "";
+          let day = "";
+          //指定时间
+
+          var date = new Date();
+          if (date) {
+            h = date.getHours();
+            m = date.getMinutes();
+            s = date.getSeconds();
+            year = date.getFullYear();
+            month =date.getMonth() + 1 
+            day = date.getDate() 
+          }
+          this.$set(this,'value',date)
+          cron =
+            s +
+            " " +
+            m +
+            " " +
+            h +
+            " " +
+            day +
+            " " +
+            month +
+            " " +
+            "?" +
+            " " +
+            "*";
+        }
+        return cron
+      }
+            var cron = ''
+            if(this.type == "day"){//天
+                let m = "";
+                let s = "";
+                let h = "";
+                let date = this.value;
+                date= date.split(':')
+                if (date) {
+                  h = date[0];
+                  m = date[1];
+                  s = date[2];
+                }
+                cron = s + " " + m + " " + h + " * * ? *";
+            }else if (this.type == "week") { //星期
+                let m = "";
+                let s = "";
+                let h = "";
+                var day = this.day || "";
+                switch (day) {
+                  case "周日":
+                    day = "1";
+                    break;
+                  case "周一":
+                    day = "2";
+                    break;
+                  case "周二":
+                    day = "3";
+                    break;
+                  case "周三":
+                    day = "4";
+                    break;
+                  case "周四":
+                    day = "5";
+                    break;
+                  case "周五":
+                    day = "6";
+                    break;
+                  case "周六":
+                    day = "7";
+                    break;
+                }
+                let date = this.time;
+                date= date.split(':')
+                if (date) {
+                  h = date[0];
+                  m = date[1];
+                  s = date[2];
+                }
+                
+                cron = s + " " + m + " " + h + " ? * " + day + " *";
+                //周cron表达式
+              } else if (this.type == "month") {//每月的几号
+                let m = "";
+                let s = "";
+                let h = "";
+                let mo = this.day.match(/\d+/) || "";
+                let date = this.time;
+                date= date.split(':')
+                if (date) {
+                  h = date[0];
+                  m = date[1];
+                  s = date[2];
+                }
+                cron = s + " " + m + " " + h + " " + mo + " * ? *";
+              } else if (this.type == "year") {//指定年月日
+                let m = "";
+                let s = "";
+                let h = "";
+                let year = "";
+                let month = "";
+                let day = "";
+                //指定时间
+                var date = this.value;
+                date = new Date(date);
+                if (date) {
+                  h = date.getHours();
+                  m = date.getMinutes();
+                  s = date.getSeconds();
+                  year = date.getFullYear();
+                  month = date.getMonth() + 1 
+                  day = date.getDate()
+                }
+                cron =
+                  s +
+                  " " +
+                  m +
+                  " " +
+                  h +
+                  " " +
+                  day +
+                  " " +
+                  month +
+                  " " +
+                  "?" +
+                  " " +
+                  "*";
+              }
+              return cron
+        },
+        //反编译cron
+    cronChangeDate(str) {
+        var toDate = {};
+        if (!str) {
+          return;
+        } else {
+          var result = str.split(" ").join("");
+          var nArr = str.split(" ");
+          var countData = this.getPlaceholderCount(result);
+          var str1 = "";
+          str1 = result.split("").reverse().join("").substring(3, 4);
+          if (countData.count1 && str1 == "?") {
+            toDate.loopType = "周循环";
+            var keys = nArr[5];
+            var en2cnMap = {
+              1: "周日",
+              2: "周一",
+              3: "周二",
+              4: "周三",
+              5: "周四",
+              6: "周五",
+              7: "周六",
+            };
+            var cnKeys = keys.split(",").map(function (key, idx) {
+              return en2cnMap[key];
+            });
+            toDate.loopValue = cnKeys.join(",");
+          } else if (countData.count1 + countData.count2 === 3) {
+            toDate.loopType = "月循环";
+            var mot = [];
+            var mkeys = nArr[3].split(",");
+            for (var i = 0; i < mkeys.length; i++) {
+              let mo = mkeys[i];
+              mot.push(mo);
+            }
+            toDate.loopValue = mot.join(",");
+          } else {
+          }
+          if (this.type == "year") {
+            toDate.loopTime =
+              nArr[6] +
+              "-" +
+              nArr[4] +
+              "-" +
+              nArr[3] +
+              " " +
+              nArr[2] +
+              ":" +
+              nArr[1] +
+              ":" +
+              nArr[0];
+          } else {
+            toDate.loopTime =
+              2020 +
+              "-" +
+              10 +
+              "-" +
+              10 +
+              " " +
+              nArr[2] +
+              ":" +
+              nArr[1] +
+              ":" +
+              nArr[0];
+          }
+  
+          var date = toDate.loopTime;
+          date = date.substring(0, 19);
+          date = date.replace(/-/g, "/");
+          var timestamp = new Date(date);
+          if (toDate.loopType == "周循环") {
+            // this.time = date;
+            // this.day = toDate.loopValue;
+            date = date.split(' ')[1].split(":")
+            var h = date[0];
+             var m = date[1];
+             var s = date[2];
+            this.$set(this, 'time', (h < 10 ? ("0" + h) : h )+ ':' + (m < 10 ? ("0" + m) : m) + ':' + (s < 10 ? ("0" + s) : s))
+            this.$set(this, 'day', toDate.loopValue)
+            this.$set(this,'value',this.day+" "+this.time)
+          } else if (toDate.loopType == "月循环") {
+            date = date.split(' ')[1].split(":")
+              var h = date[0];
+             var m = date[1];
+             var s = date[2];
+            this.$set(this, 'time', (h < 10 ? ("0" + h) : h )+ ':' + (m < 10 ? ("0" + m) : m) + ':' + (s < 10 ? ("0" + s) : s))
+            // this.time = date;
+            // this.day = toDate.loopValue + '日';
+            // this.$set(this,'time',date)
+            this.$set(this, 'day', toDate.loopValue + '日')
+            this.$set(this,'value',this.day+" "+this.time)
+          } else {
+            // this.value = date;
+            this.$set(this,'value',date)
+          }
+        }
+        return toDate;
+    },
+    // 根据cron表达式获取更新周期
+    getType(str){
+      if(!str){
+        return "";
+      }
+      var type = ''
+      var result = str.split(" ").join("");
+      var countData = this.getPlaceholderCount(result);
+      var str1 = "";
+      str1 = result.split("").reverse().join("").substring(3, 4);
+      if (countData.count1 && str1 == "?") {
+        type = 'week'
+      } else if (countData.count1 + countData.count2 === 3) {
+        type = 'month'
+      } else if(countData.count1 && str1 == "*") {
+        type = 'day'
+      }else{
+        type = 'year'
+      }
+      return type
+    },
+      // 统计字符串中包含某个字符的个数
+      getPlaceholderCount(strSource) {
+        var count1 = 0; 
+        var count2 = 0; 
+        strSource.replace(/\*|\?/g, function (m, i) {
+          if (m === "?") {
+            count1++;
+          } else if (m === "*") {
+            count2++;
+          }
+        });
+  
+        var obj = {};
+        obj.count1 = count1;
+        obj.count2 = count2;
+        return obj; 
+      },
+    },
+}

+ 421 - 0
RMS-FrontEnd/src/views/components/common/components/search.vue

@@ -0,0 +1,421 @@
+<template>
+    <div style="padding:10px">
+        <!-- 表单检索 -->
+        <div>
+            <div class="content_border">
+                <div v-for="(items,i) in list" :key="i" class="content"> 
+                    <!-- <el-row :gutter="24"> -->
+                        <!-- 逻辑符 -->
+                        <!-- <el-col :span="5"> -->
+                            <span style="width:150px">
+                                <span v-if="i==0" style="opacity: 0;"> 内容 </span>
+                                <el-select v-else v-model="list[i].logical" size='small' width='100%' >
+                                    <el-option
+                                        v-for="item in logical"
+                                        :key="item[logicalProps.value]"
+                                        :label="item[logicalProps.value]"
+                                        :value="item[logicalProps.value]">
+                                    </el-option>
+                                </el-select>
+                            </span>
+                        <!-- </el-col> -->
+                        <!-- 搜索条件 -->
+                        <!-- <el-col :span="7"> -->
+                            <!-- <el-select v-model="list[i].field" @change="change(list[i])" filterable size='small' style="width:250px" :title="getTitle(list[i].field)">
+                                <el-option
+                                    v-for="item in field"
+                                    :key="item[fieldProps.value]"
+                                    :label="item[fieldProps.label]+'('+item[fieldProps.value]+')'"
+                                    :value="item[fieldProps.value]">
+                                </el-option>
+                            </el-select> -->
+                            <el-cascader :options="field" v-model="list[i].field" :props="deftProps" filterable size='small' @change="change(list[i])" style="width:250px" :title="getTitle(list[i].field)" :show-all-levels="false"></el-cascader>
+                        <!-- </el-col> -->
+                        <!-- 运算符 -->
+                        <!-- <el-col :span="3" style="padding:0"> -->
+                            <el-select v-model="list[i].operator" size='small' style="width:150px">
+                                <el-option
+                                    v-for="item in operator"
+                                    :key="item[operatorProps.value]"
+                                    :label="item[operatorProps.label]"
+                                    :value="item[operatorProps.value]">
+                                </el-option>
+                            </el-select>
+                        <!-- </el-col> -->
+                        <!-- 搜索值 -->
+                        <!-- <el-col :span="9"> -->
+                            <div style="width:100%">
+                                <div v-if="list[i].dataType==2" style="display:flex;width:100%">
+                                    <el-date-picker
+                                        v-model="list[i].value[0]"
+                                        style="width:50%"
+                                        type="date"
+                                        size='small'
+                                        value-format="yyyyMMdd"
+                                        placeholder="开始,例:20000101">
+                                    </el-date-picker>
+                                    <el-date-picker
+                                        style="width:50%"
+                                        v-model="list[i].value[1]"
+                                        type="date"
+                                        size='small'
+                                        value-format="yyyyMMdd"
+                                        placeholder="结束,例:20001231">
+                                    </el-date-picker>
+                                </div>
+                                <div v-else-if="list[i].dataType==3" style="width:100%">
+                                    <el-select v-model="list[i].value" size="small" multiple filterable collapse-tags placeholder="请选择,可多选" style="width:100%">
+                                        <el-option
+                                            v-for="item in constants[list[i].field]"
+                                            :key="item.value"
+                                            :label="item.label"
+                                            :value="item.value">
+                                        </el-option>
+                                    </el-select>
+                                </div>
+                                <div v-else style="width:100%"><el-input size='small' style="width:100%" v-model="list[i].value" :placeholder="list[i].placeholder"></el-input> </div>
+                               
+                            </div>
+                            
+                        <!-- </el-col> -->
+                    <!-- </el-row> -->
+                    <div style="width:50px">
+                        <span v-if="list.length==1" style="opacity: 0;"> 内容 </span>
+                        <el-button v-else size="small" @click="deleteList(i)"><i class="el-icon-delete"></i></el-button>
+                    </div>
+                </div>
+
+            </div>
+            <div class="button_group">
+                <el-button size="small" type="primary" @click="add">增加</el-button>
+                <el-button size="small" type="primary" @click="search2">检索</el-button>
+                <el-button size="small" @click="reset">重置</el-button>
+                <!-- <el-button size="small" @click="createSearch" v-if="searchValue">生成检索式</el-button> -->
+            </div>
+        </div>
+        <!-- 检索式检索 -->
+        <div v-if="searchValue">
+            <p><b>检索式检索</b><span style="margin-left:10px">[例: TI=(计算机) ]</span></p>
+            <div>
+                <el-input type="textarea" :rows="4" v-model="searchStr"></el-input>
+            </div>
+            <!-- <div class="button_group">
+                <el-button size="small" type="primary" @click="search2">检索</el-button>
+            </div> -->
+        </div>
+    </div>
+</template>
+<script>
+export default {
+    props:{
+        //逻辑符
+        logical:{
+            type:Array,
+            default: ()=>{ return [
+                {
+                    label:'并且',
+                    value:'&&'
+                },
+                {
+                    label:'或者',
+                    value:'||'
+                },
+            ] }
+        },
+        //逻辑符配置
+        logicalProps:{
+            type:Object,
+            default:()=>{
+                return {
+                    label:'label',
+                    value:'value',
+                }
+            }
+        },
+        //运算符
+        operator:{
+            type:Array,
+            default: ()=>{ return [
+                {
+                    label:'=',
+                    value:'='
+                },
+                {
+                    label:'>',
+                    value:'>'
+                },
+                {
+                    label:'<',
+                    value:'<'
+                },
+            ] }
+        },
+        //运算符配置
+        operatorProps:{
+            type:Object,
+            default:()=>{
+                return {
+                    label:'label',
+                    value:'value',
+                }
+            }
+        },
+        //搜索值
+        field:{
+            type:Array,
+            default: ()=>{ return [] }
+        },
+        //搜索值配置
+        fieldProps:{
+            type:Object,
+            default:()=>{
+                return {
+                    label:'label',
+                    value:'value',
+                }
+            }
+        },
+        //是否展示检索式
+        searchValue:{
+            type:Boolean,
+            default:()=>{
+                return true
+            }
+        },
+        //默认值
+        list:{
+            type:Array,
+            default:()=>{
+                return []
+            }
+        }
+    },
+    data() {
+        return {
+            // list:[],
+            searchStr:'',
+            constants:this.$constants,
+            deftProps:{
+                emitPath:false
+            },
+            filedList:[]
+        }
+    },
+    watch:{
+        // 'list'(){
+        //     this.createSearch()
+        // }
+        list: {
+            handler(val) {
+                this.createSearch()
+            },
+            deep: true,// 深度监听
+        }
+    },
+    mounted() {
+        this.filedList =[].concat(...this.field.map(item=>{return item.children}))
+        this.rule()
+    },
+    methods: {
+        change(list){
+            var a = this.filedList.find(item=>{
+                return item.value == list.field
+            })
+            list.dataType = a.dataType
+            list.placeholder = a.placeholder
+            if(list.dataType==2 || list.dataType==3){
+                this.$set(list,'value', [])
+            }else{
+                this.$set(list,'value', '')
+            }
+        },
+        //校验
+        rule(){
+            if(this.list.length>=2 && this.list.length % 2 == 0){
+                return false
+            }else{
+                this.list.push({
+                    logical:this.logical.length>0?this.logical[0][this.logicalProps.value]:'',
+                    // field:this.field.length>0?this.field[0][this.fieldProps.value]:'',
+                    field:'PN',
+                    placeholder:'请输入公开号,例:CN102860161 OR CN1526554846',
+                    operator:this.operator.length>0?this.operator[0][this.operatorProps.value]:'',
+                })
+                // this.rule()
+            }
+        },
+        //增加
+        add(){
+            this.list.push({
+                logical:this.logical.length>0?this.logical[0][this.logicalProps.value]:'',
+                // field:this.field.length>0?this.field[0][this.fieldProps.value]:'',
+                field:'PN',
+                placeholder:'请输入公开号,例:CN102860161 OR CN1526554846',
+                operator:this.operator.length>0?this.operator[0][this.operatorProps.value]:'',
+            },
+            // {
+            //     logical:this.logical.length>0?this.logical[0][this.logicalProps.value]:'',
+            //     field:this.field.length>0?this.field[0][this.fieldProps.value]:'',
+            //     operator:this.operator.length>0?this.operator[0][this.operatorProps.value]:''
+            // }
+            )
+        },
+        //鼠标悬浮文字提示
+        getTitle(val){
+            if(val){
+                return this.filedList.filter(item=>{
+                    return item.value == val
+                })[0].label + '('+ val + ')'
+            }
+        },
+        //删除
+        deleteList(index){
+            this.list.splice(index,1)
+        },
+        //重置
+        reset(){
+            this.list = [
+                {
+                    logical:this.logical.length>0?this.logical[0][this.logicalProps.value]:'',
+                    // field:this.field.length>0?this.field[0][this.fieldProps.value]:'',
+                    field:'PN',
+                    placeholder:'请输入公开号,例:CN102860161 OR CN1526554846',
+                    operator:this.operator.length>0?this.operator[0][this.operatorProps.value]:''
+                },
+                // {
+                //     logical:this.logical.length>0?this.logical[0][this.logicalProps.value]:'',
+                //     field:this.field.length>0?this.field[0][this.fieldProps.value]:'',
+                //     operator:this.operator.length>0?this.operator[0][this.operatorProps.value]:''
+                // }
+            ]
+        },
+        //生成检索式
+        createSearch(){
+            var str = ''
+            if(!this.list[0].field || !this.list[0].operator){
+                return false
+            }
+            var a = false
+            this.list.forEach((item,index) => {
+                if(item.dataType == 3){
+                    if(item.value.length>0){
+                        a = true
+                        if(index == 0){
+                            if(item.value.length == 1){
+                                str = str +' '+ item.field + item.operator  + item.value[0]
+                            }else{
+                                str = str +' '+ item.field + item.operator +'(' + item.value.join(' OR ')+')'
+                            }
+                           
+                        }else{
+                            if(item.value.length == 1){
+                                str = str + " "+ item.logical + ' '+ item.field + item.operator + item.value[0]
+                            }else{
+                                str = str + " "+ item.logical + ' '+ item.field + item.operator + '(' + item.value.join(" OR ")+')'
+                            }
+                            
+                        }
+                    }
+                }else if(item.dataType == 2){
+                    if(item.value.length>0){
+                        if(!item.value[0] && !item.value[1]){
+
+                        }else{
+                            if( item.value[0] && item.value[1] ){
+                                str = str + " "+ item.logical + ' '+ item.field + item.operator + '(' + item.value[0] +'~'+item.value[1]+')'
+                            }else if(!item.value[0] || !item.value[1]){
+                                str = str + " "+ item.logical + ' '+ item.field + item.operator + (item.value[0] || item.value[1])
+                            }
+                        }    
+                    }
+                }else{
+                    if(item.value){
+                        a = true
+                        var a = item.value.replace(/("[^"]*"|'[^']*')/g,'')
+                        var arr = a.match(/\s{1}and|AND|OR|or|NOT|not\s{1}/g)
+                        if(arr&&arr.length>0){
+                            if(index == 0){
+                                str = str +' '+ item.field + item.operator +'(' + item.value+')'
+                            }else{
+                                str = str + " "+ item.logical + ' '+ item.field + item.operator +'(' + item.value+')'
+                            }
+                        }else{
+                            if(index == 0){
+                                str = str +' '+ item.field + item.operator  + item.value
+                            }else{
+                                str = str + " "+ item.logical + ' '+ item.field + item.operator  + item.value
+                            }
+                        }
+                    }
+                        
+                }
+                
+            });
+            // if(!a){
+            //     this.$message.info('请输入要检索的内容')
+            //     return false
+            // }
+            this.searchStr = str
+        },
+        //表单检索
+        search1(){
+            var str = ''
+            if(!this.list[0].field || !this.list[0].operator){
+                return false
+            }
+            var a = false
+            this.list.forEach((item,index) => {
+                if(item.value){
+                    a = true
+                    if(index == 0){
+                        str = str +'('+ item.field + item.operator + item.value+')'
+                    }else{
+                        str = str + item.logical + '('+ item.field + item.operator + item.value+')'
+                    }
+                }
+            });
+            if(!a){
+                this.$message.info('请输入要检索的内容')
+                return false
+            }
+            this.$emit('search',str)
+        },
+        //检索式检索
+        search2(){
+            this.$emit('search',this.searchStr.trim())
+        }
+    },
+}
+</script>
+<style lang="scss" scoped>
+    .content_border{
+        width:100%;
+        // min-width: 1500px;
+       display: flex;
+       align-items: center; 
+       justify-content: flex-start;
+       flex-wrap:wrap;
+    }
+    .content_border .content{
+        display: flex;
+        // justify-content: space-between;
+        position: relative;
+        width: 100%;
+        margin-bottom: 10px;
+        padding-right:20px;
+        
+    }
+    .content_border .content>*{
+        padding:10px
+    }
+    .button_group{
+        margin-top:20px;
+        margin-right:20px;
+        display: flex;
+        justify-content: flex-end;
+    }
+    .button_group .el-button{
+        width:92px
+    }
+    
+</style>

+ 74 - 0
RMS-FrontEnd/src/views/components/common/components/searchIndex.vue

@@ -0,0 +1,74 @@
+<template>
+    <div>
+        <search :logical="logical" :logicalProps="logicalProps" :operator="operator" :field="field" :searchValue="true" :list="list"></search>
+    </div>
+</template>
+<script>
+import search from './search.vue'
+export default {
+    components:{
+        search
+    },
+    data() {
+        return {
+        //逻辑符
+        logical:[
+            {
+                name:'并且',
+                value:'&&'
+            },
+            {
+                name:'或者',
+                value:'||'
+            },
+        ],
+        logicalProps:{
+            label:'name',
+            value:'value'
+        },
+        //运算符
+        operator:[
+            {
+                label:'=',
+                value:'='
+            },
+            {
+                label:'>',
+                value:'>'
+            },
+            {
+                label:'<',
+                value:'<'
+            },
+            {
+                label:'<=',
+                value:'<='
+            },
+        ],
+        //搜索值
+        field:[
+            {
+                label:'专利号',
+                value:'patentNo'
+            },
+            {
+                label:'标题',
+                value:'title'
+            },
+            {
+                label:'公开日',
+                value:'publicDate'
+            },
+        ],
+        list:[
+            {
+                logical:'and',
+                field:'patentNo',
+                operator:'=',
+                value:'123'
+            }
+        ],
+        }
+    },
+}
+</script>

+ 149 - 0
RMS-FrontEnd/src/views/components/common/components/timeChoose.vue

@@ -0,0 +1,149 @@
+<template>
+    <div>
+        <div style="width:100%">
+            <el-popover
+                v-if="!showTime && !showDate"
+                ref="popover"
+                placement="bottom"
+                width="400"
+                trigger="click">
+            <div style="display:flex;width:100%" >
+                <el-input  v-model="day" placeholder="选择时间" style="margin-right:10px;width:100%"></el-input>
+                <el-time-picker
+                    @change="changeTime"
+                    @blur="changeTime"
+                    v-model="time"
+                    value-format="HH:mm:ss"
+                    placeholder="选择时间">
+                </el-time-picker>
+            </div>
+            <div style="display:flex;flex-wrap:wrap;width:100% " >
+                <p style="min-width:50px;width:calc(100% / 7);text-align:center;cursor:pointer" v-for="(item,index) in list[type]" :key="index" @click="check(item)">{{ item }}</p>
+            </div>
+            <el-input slot="reference" v-model="value" placeholder="选择时间"  style="width:100%"></el-input>
+            </el-popover>
+            <el-time-picker
+                v-if="showTime"
+                @change="changeTime"
+                v-model="value"
+                style="width:100%"
+                value-format="HH:mm:ss"
+                placeholder="选择时间">
+            </el-time-picker>
+            <el-date-picker
+                popper-class="picker-date"
+                format="MM-dd HH:mm:ss"
+                v-if="showDate"
+                @change="changeTime"
+                v-model="value"
+                type="datetime"
+                placeholder="选择日期时间">
+            </el-date-picker>
+        </div>
+       
+    </div>
+</template>
+<script>
+import { cron } from "./mixins";
+export default {
+  mixins:[cron],
+    props:{
+        type:{
+            default:'day'
+      },
+        cron:{}
+        
+    },
+    data() {
+        return {
+            value:'',
+            day:'',
+            time:'',
+            list:{
+                week:['周一','周二','周三','周四','周五','周六','周日'],
+                month:[]
+            },
+            showDate:false,
+            showTime:false,
+            
+        }
+  },
+  watch: {
+    type(val) {
+      this.init()
+     }, 
+    },
+  mounted() {
+        this.init()
+    },
+  methods: {
+    init() {
+      this.value = ''
+      this.day = ''
+      this.time = ''
+      this.showTime =this.type=='day'? true:false
+      this.showDate = this.type == 'year' ? true : false
+      
+      switch (this.type) {
+            case 'day':
+                break;
+            case 'week':
+                break;
+            case 'month':
+                for(let i = 1;i < 32;i++){
+                    this.list.month.push(i+'日')
+                }
+                break;
+        case 'year':
+                break;
+      }
+      if (!this.cron && this.type) {
+        let cron = this.getCron(this.type)
+        this.$emit('value', cron)
+      } else if(this.cron && this.type){
+         this.cronChangeDate(this.cron)
+      }
+      },
+        check(item){
+            this.$set(this,'day',item)
+            if(!this.time){
+               this.$set(this,'time','18:30:00') 
+            }
+            
+            this.changeTime()
+        },
+        changeTime(){
+            if(!this.showDate && !this.showTime){
+                this.$set(this,'value',this.day+" "+this.time)
+            }
+          // console.log(this.value)
+            let cron=this.getCron()
+          this.$emit('value', cron)
+        }
+    },
+}
+</script>
+
+<style lang="scss">
+.el-time-panel{
+    margin-top:20px;
+    z-index: 9999 !important;
+}
+.el-picker-panel{
+    z-index: 9999 !important;
+}
+
+.picker-date {
+  .el-date-picker__header {
+    span:nth-child(3) {      
+      display: none;
+    }
+    button:nth-child(1) {
+      display: none;
+    }
+    button:nth-child(5) {
+      display: none;
+    }
+  }
+}
+</style>

+ 19 - 0
RMS-FrontEnd/src/views/components/common/components/timeIndex.vue

@@ -0,0 +1,19 @@
+<template>
+    <div>
+        <timeChoose :type="type" style="width:200px"></timeChoose>
+    </div>
+</template>
+<script>
+import timeChoose from './timeChoose.vue'
+export default {
+    components:{
+        timeChoose
+    },
+    data() {
+        return {
+            width:'300px',
+            type:'week'
+        }
+    },
+}
+</script>

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 409 - 295
RMS-FrontEnd/src/views/components/common/mixins.js


+ 31 - 0
RMS-FrontEnd/src/views/components/gaoliang/components/mixins.js

@@ -0,0 +1,31 @@
+export const explain = {
+  data() {
+    return {
+      innerHtml:''
+    }
+  },
+  mounted() {
+  },
+  methods: {
+     // 解释所需方法
+    saveValue(val) {//点击输入触发,第一次为空不打印
+      if (this.keepSure) {
+        this.keepSure = false;
+      }
+      // 解决鼠标错位问题
+      // this.$refs["preview"].focus();
+      // document.execCommand("selectAll", false, null);
+      // document.getSelection().collapseToEnd();
+      this.innerhtml = val
+      // this.mark.remark=val
+      this.$forceUpdate()
+          if(this.tableHeight){
+            this.setHeight()
+          }
+    },
+    getValue(row,name) {//失去焦点触发,row本行数据,name是传过来的row里面每一个属性
+        row[name] = this.innerhtml
+        this.innerhtml = ''
+    },
+  }
+}

+ 269 - 0
RMS-FrontEnd/src/views/components/gaoliang/components/pizhu.vue

@@ -0,0 +1,269 @@
+<template>
+  <div>
+    <div class="pizhu" style="display:none;">
+          <div style="display:flex;justify-content: space-between;font-size:14px;border-bottom: 1px white solid;padding-bottom: 5px;">
+            <p style="font-weight:800;margin:0">{{ userinfo.name }}</p>
+            <p style="margin:0">{{ getDate() }}</p>
+          </div>
+          <div>
+            <p style="display: flex;align-items: center;"><span style="width: 60px;">内容:</span><span style="width: 100%;"><el-input type="textarea" v-model="mark.text" readonly rows="2"></el-input></span></p>
+          </div>
+          <div>
+            <p><span>颜色:</span>
+              <span>
+                <el-input type="color" size="small" class="changeColor"  v-model="mark.color" style="user-select:none;width:100px" @input="changeColor()"> </el-input>
+              </span></p>
+            <p><span>类型:</span>
+              <span>
+                <el-radio-group v-model="mark.scratchType" @change="changeRadio">
+                  <el-radio :label="2">波浪线</el-radio>
+                  <el-radio :label="0">下划线</el-radio>
+                  <el-radio :label="1">高亮</el-radio>
+                </el-radio-group>
+              </span></p>
+          </div>
+          <div>
+            <p>
+              <span>使用权限:</span>
+              <span>
+                <el-radio-group v-model="mark.permissionType" @change="changePower()">
+                  <el-radio :label="1">所有人可见</el-radio>
+                  <el-radio :label="0">本人可见</el-radio>
+                </el-radio-group>
+              </span>
+            </p>
+          </div>
+          <div>
+            <p style="display:flex">
+              <span>可见范围:</span>
+              <span>
+                <el-switch
+                  v-model="mark.rangeType"
+                  active-color="#13ce66"
+                  inactive-color="#ff4949"
+                  active-text="本报告可见">
+                </el-switch>
+              </span>
+            </p>
+          </div>
+          <div style="user-select: none;">
+            <!-- <el-input type="textarea"></el-input> -->
+            <p style="margin-bottom:5px">标注:</p>
+            <el-input v-model="mark.remark" type="textarea" class="my-input-preview"></el-input>
+            <!-- <div ref="preview" style="width:100%;outline: #dcdfe6;border:1px solid #DCDFE6;border-radius:5px;min-height:50px;background:white;" id="preview" class="my-input-preview" contenteditable="true" 
+               v-html="mark.remark"  @input="saveValue($event.target.innerHTML)"  @click="saveValue($event.target.innerHTML)"
+               @blur="getValue(mark,'remark')">
+            </div> -->
+          </div>
+          <div style="display:flex;justify-content: flex-end;">
+            <span style="cursor: pointer;" @click="cancelPizhu" >取消</span>
+            <span style="margin-left:15px;cursor: pointer;" v-if="mark.id" @click="deletePizhu">删除</span>
+            <span style="margin-left:15px;cursor: pointer;" @click="submitPizhu">确定</span>
+          </div>
+    </div>
+  </div>
+</template>
+
+<script>
+// 阿里巴巴icon
+// import "@/assets/iconfont/iconfont.css"
+// import { explain } from "./mixins";
+export default {
+  name:'pizhu',
+  // mixins: [explain],
+  props: ['gaoLiangCaiDan','piZhuDelete'],
+  components: {
+  },
+  
+  data() {
+    return {
+      color:'#dff209',
+      scratchType:2,
+      permissionType:2,
+      rangeType:[],
+      remark:'',
+      currentIndex:{},
+      dialogVisible:false,
+      featureVisible:false,
+      featureForm:{},
+      tableData1:[],
+      witchRight: "权要1",
+    }
+  },
+  computed:{
+    mark() {
+      let a = this.$store.state.patent.index
+      if (a.rangeType == 'true' || a.rangeType==true) {
+        a.rangeType=true
+      } else {
+        a.rangeType=false
+      }
+      return a || { rangeType:[] }
+    },
+    userinfo() {
+      return this.$store.state.admin.userinfo
+    },
+    piZhuContrastList() {
+      return this.$store.state.report.piZhuContrastList
+    }
+  },
+  watch: {
+    gaoLiangCaiDan(val) {
+      this.submitPizhu()
+    },
+    piZhuDelete(val) {
+      this.deletePizhu()
+    },
+  },
+  created() {
+
+  },
+  mounted() {
+
+  },
+  methods: {
+    // 显示时间
+    getDate() {
+      let date = new Date()
+      var Y = date.getFullYear().toString()
+      var m = (date.getMonth() + 1) > 9 ? (date.getMonth() + 1).toString() : "0" + (date.getMonth() + 1)
+      var d = date.getDate() > 9 ? date.getDate().toString() : "0" + date.getDate()
+      var H = date.getHours() > 9 ? date.getHours().toString() : "0" + date.getHours()
+      var M = date.getMinutes() > 9 ? date.getMinutes().toString() : "0" + date.getMinutes()
+      var S = date.getSeconds() > 9 ? date.getSeconds().toString() : "0" + date.getSeconds()
+      return Y + '-' + m + '-' + d + ' ' + H + ':' + M + ':' + S
+    },
+    // 确定增加批注
+    submitPizhu() {
+      this.mark.rangeType=false
+      if (this.mark.id) {
+        this.$api.scratchWordsUpdate(this.mark).then(response => {
+          if (response.code == 200) {
+            this.getContrastList('update')
+            this.$message.success('更新成功')
+            this.cancelPizhu()
+          }
+        }).catch(error => {
+
+        })
+      } else {
+        this.$api.scratchWordsAdd(this.mark).then(response => {
+          if (response.code == 200) {
+            this.getContrastList('add')
+            this.$message.success('添加成功')
+            this.cancelPizhu()
+          }
+        }).catch(error => {
+
+        })
+      }
+
+    },
+    // 关闭批注
+    cancelPizhu() {
+      if (this.mark.id|| this.mark.Id) {
+        let index={
+          color:this.mark.color,
+          scratchType:this.mark.scratchType,
+          permissionType:this.mark.permissionType,
+          rangeType:this.mark.rangeType,
+          content:'',
+          remark:'',//标注文本
+        }
+      this.$store.commit('SET_PATENT_INDEX', index)
+      }
+       
+      // }
+      let dl = document.getElementsByClassName("pizhu");
+      dl[0].setAttribute("style", "display:none;");
+    },
+    // 删除批注
+    deletePizhu() {
+      let ids = [
+        this.mark.id
+      ]
+      this.$api.scratchWordsDelete(ids).then(response => {
+        if (response.code == 200) {
+          this.getContrastList('delete')
+          this.$message.success('删除成功')
+          this.cancelPizhu()
+        }
+      }).catch(error => {
+
+      })
+    },
+    // 查询批注
+    getContrastList(type) {
+      if (type != 'add') {
+        var index = this.piZhuContrastList.findIndex(item => {
+          return item.id == this.mark.id
+        })
+      }
+      switch (type) {
+        case 'add':
+          let params = {
+            patentNo:this.mark.patentNo,
+            id: this.mark.rangeId,
+            createFrom:1
+          }
+          this.$api.scratchWordsQuery(params).then(res => {
+            if (res.code == 200) {
+              if (this.piZhuContrastList.length > 0) {
+                var a = this.piZhuContrastList.filter(item => {
+                  return  item.patentNo != params.patentNo
+                }).concat(res.data)
+              } else {
+                var a = res.data
+              }
+              this.$store.commit('SET_PATENT_PIZHU_CONTRAST', a)
+            }
+          })
+          break;
+        case 'update':
+          this.piZhuContrastList.splice(index,1,this.mark)
+          break;
+        case "delete":
+          this.piZhuContrastList.splice(index,1)
+          break;
+      }
+    },
+    // 颜色
+    changeColor(val) {
+      // var a = JSON.parse(this.index)
+      // // a.color = this.color
+      // a.color = this.mark.color
+      // this.$store.commit('SET_PATENT_INDEX',a)
+    },
+    // 类型:下划线,高亮
+    changeRadio(val) {
+      // var a = JSON.parse(this.index)
+      // a.radio = this.radio
+      // console.log(a);
+      // this.$store.commit('SET_PATENT_INDEX',a)
+    },
+    // 使用权限
+    changePower(val) {
+      // var a = JSON.parse(this.index)
+      // a.power = this.power
+      // this.$store.commit('SET_PATENT_INDEX',a)
+    },
+    // 使用范围
+    changeRange(val) {
+      // var a = JSON.parse(this.index)
+      // a.range = this.range
+      // console.log(a);
+      // this.$store.commit('SET_PATENT_INDEX',a)
+    },
+  }
+}
+</script>
+<style lang="less">
+.opinion .el-form-item{
+  margin-bottom: 10px;
+  .el-form-item__content,.el-form-item__label{
+    line-height: normal;
+    min-height: 30px;
+  }
+}
+
+</style>

+ 25 - 0
RMS-FrontEnd/src/views/components/gaoliang/index.vue

@@ -0,0 +1,25 @@
+<template>
+  <div>
+
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+
+    }
+  },
+  mounted() {
+
+  },
+  methods: {
+
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 309 - 0
RMS-FrontEnd/src/views/components/import/PatentNoImport/download.vue

@@ -0,0 +1,309 @@
+<template>
+    <div style="background: white;padding: 20px;height: 100%;">
+      <div style="float:right" v-if="downloadId==9">
+        <el-button type="primary" @click="settingUser">账号配置</el-button>
+      </div>
+      <div style="width: 800px;margin: 0 auto;">
+        <div v-if="downloadId==9" >
+          <el-form :inline="true" :model="queryParams" :rules="rules" ref="from" class="demo-form-inline" style="display: flex;justify-content: space-between;">
+            <el-form-item label="来源网站" prop="configId">
+              <el-select v-model="queryParams.configId" placeholder="请选择网站" >
+                  <el-option v-for="item in website"
+                    :key="item.id"
+                    :label="item.webName"
+                    :value="item.id">
+                  </el-option>
+              </el-select>
+            </el-form-item>
+            <el-form-item label="下载内容" prop="configCells">
+              <el-select v-model="queryParams.configCells"  multiple collapse-tags placeholder="请选择下载内容" style="width: 100%;">
+                  <el-option v-for="item in download"
+                    :key="Number(item.cellValue)"
+                    :label="item.cellName"
+                    :value="Number(item.cellValue)">
+                  </el-option>
+              </el-select>
+            </el-form-item>
+            <el-form-item label="是否更新" prop="taskType">
+              <el-switch v-model="queryParams.taskType" :active-value="1" :inactive-value="0" active-color="#13ce66" inactive-color="#ff4949" @change="change3">  </el-switch>
+            </el-form-item>
+          </el-form>
+          <div v-show="queryParams.taskType"  >
+            <el-form :inline="true" ref="from" :model="queryParams" :rules="rules" class="demo-form-inline" style="display: flex;justify-content: space-between;">
+              <el-form-item label="更新间隔" prop="dateType">
+                <el-select v-model="queryParams.dateType" @change="getDateType" clearable placeholder="请选择更新时间间隔" style="margin-right: 20px;">
+                  <el-option v-for="item in options"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value">
+                  </el-option>
+                </el-select>
+              </el-form-item>
+              <el-form-item label="选择更新具体时间" v-if="queryParams.dateType" >
+                <timeChoose :type="queryParams.dateType" @value="handleData" :cron="queryParams.crons" style="width:300px"></timeChoose>
+              </el-form-item>
+            </el-form>
+          </div>
+          </div>
+          <!-- <div style="display: flex;margin-bottom: 10px;" v-if="queryParams.configType==2">
+            <p style="width:150px;margin-right:10px;margin-bottom: 10px;">数据库:</p>
+            <div>
+              <el-checkbox-group v-model="queryParams.database">
+                <el-checkbox v-for="item in database" :key="item.value" :label="item.value" style="margin:5px">{{ item.label }}</el-checkbox>
+              </el-checkbox-group>
+            </div>
+          </div> -->
+          <!-- 搜索 -->
+          <div style="display: flex;justify-content: center;width: 100%;align-items:center">
+            <span style="width: 100%;">
+               <el-input v-model="queryParams.conditions" :placeholder="downloadId==9?'请输入检索信息':'请输入专利号(多个专利号同时添加中间请用符号“|”隔开)'" ></el-input>
+            </span>
+            <span style="margin-left:8px" v-if="queryParams.configType==2">
+              <el-tooltip class="item" effect="dark" content="检索说明" placement="top">
+                <i class="el-icon-question" style="font-size:28px" @click="checkConceal(3)" ></i>
+              </el-tooltip>
+            </span>
+              <el-button @click="imports" type="primary" icon="el-icon-upload el-icon--right" style="margin-left:20px"> 导入 </el-button>
+          </div>  
+      </div>
+      
+      <div>
+         <SystemTask :form="9" :reportId="reportId" ></SystemTask> 
+      </div>
+    </div>
+</template>
+
+<script>
+import SystemTask from "@/views/components/task/index.vue";
+import { cron } from "@/views/components/common/components/mixins";
+import timeChoose from "@/views/components/common/components/timeChoose.vue";
+
+export default {
+  mixins:[cron],
+  props:['reportId','downloadId'],
+  components: {
+    SystemTask,
+    timeChoose,
+  },
+  data() {
+    const dateTypeRule = (rule, value, callback) => {
+      // console.log(value)
+      if (this.queryParams.taskType == 1) {
+        if (value) {
+          callback()
+        } else {
+          callback(new Error('请选择更新周期'))
+        }
+      } else {
+        callback()
+      }
+    }
+    return {
+      database:[
+        {
+          label:'中国发明专利',
+          value:'FMZL'
+        },
+        {
+          label:'中国发明授权',
+          value:'FMSQ'
+        },
+        {
+          label:'中国实用新型',
+          value:'SYXX'
+        },
+        {
+          label:'中国外观专利',
+          value:'WGZL'
+        },
+        {
+          label:'美国',
+          value:'USPATENT'
+        },
+        {
+          label:'英国',
+          value:'GBPATENT'
+        },
+        {
+          label:'法国',
+          value:'FRPATENT'
+        },
+        {
+          label:'德国',
+          value:'DEPATENT'
+        },
+        {
+          label:'瑞士',
+          value:'CHPATENT'
+        },
+        {
+          label:'日本',
+          value:'JPPATENT'
+        },
+        {
+          label:'俄罗斯',
+          value:'RUPATENT'
+        },
+        {
+          label:'韩国',
+          value:'KRPATENT'
+        },
+        {
+          label:'欧洲专利局',
+          value:'EPPATENT'
+        },
+        {
+          label:'世界知识产权组织',
+          value:'WOPATENT'
+        },
+
+      ],
+      website:[],//选择网站
+      download: [],//选择下载内容
+      options: [
+        {label:'每天',value:'day'},
+        {label:'每周',value:'week'},
+        {label:'每月',value:'month'},
+        {label:'每年',value:'year'},
+      ],
+      queryParams: {
+        database:[],
+        reportId: this.reportId,
+        crons:'',
+        conditions:'',//搜索条件
+        configId: '',//网站
+        configType:'',
+        configCells: [],//下载内容
+        dateType:'',
+        dates: '',
+        taskType:0,//0普通任务1定时任务
+        taskState:0,//任务状态 0等待1进行2成功3失败
+      },
+      isGetList:false,
+      rules: {
+        configId: [{ required: true, message: '请选择来源网站', trigger: 'change' },],
+        configCells: [{ required: true, message: '请选择下载内容', trigger: 'change' },],
+        taskType: [{ required: true, message: '请选择', trigger: 'change' },],
+        dateType: [{ required: true,  validator:dateTypeRule, trigger: 'change' },],
+      },
+    }
+  },
+  created() {
+
+  },
+  watch: {
+    'queryParams.configId'(val) {//更换网站
+      let a= this.website.filter(item => {
+        return item.id==val
+      })
+      this.queryParams.configType = a[0].webType
+      this.downloads()
+    },
+
+  },
+  mounted() {
+    // this.getList()
+  },
+  methods: {
+    checkConceal(id) {
+      const router = this.$router.resolve({
+        path: '/agreeConceal',
+        query: {
+          id:id
+        }
+      })
+      window.open(router.href, '_blank')
+      // const router1 = this.$router.resolve({
+      //   path: '/downPatentList',
+        
+      // })
+      // window.open(router1.href, '_blank')
+    },
+    //打开账号配置
+    settingUser(){
+      this.$refs.settingUser.open(this.website)
+    },
+    change3(val) {
+      // console.log(val);
+    },
+    getDateType(val) {
+      // console.log(val)
+      this.queryParams.crons = ''
+    },
+    // 获取时间
+    handleData(val) {
+      if (this.queryParams.dateType=='') {
+        this.$message.error('请先选择更新周期')
+        return false
+      }
+      this.queryParams.crons=val
+    },
+    // 请求全部网站
+    getList() {
+      this.$api.getAllConfig({}).then(res => {
+        if (res.code==200) {
+          this.website = res.data
+        }
+      })
+    },
+    // 请求当前网站可下载项
+    async downloads() {
+      await this.$api.getConfigCell({type:this.queryParams.configType}).then(res => {
+        if (res.code==200) {
+          this.download = res.data
+          this.queryParams.configCells=this.download.map(item=>{ return Number(item.cellValue) })
+        }
+      })
+    },
+    // 导入
+    imports() {
+      if (this.queryParams.conditions == '') {
+        if (this.downloadId == 9) {
+          this.$message.error('请输入检索信息')
+        } else {
+          this.$message.error('请输入专利号')
+        }
+        return false
+      }
+      if (this.downloadId == 8) {
+        this.queryParams.patentNo = this.queryParams.conditions
+        this.queryParams.conditions = ''
+        this.$api.importByNos(this.queryParams).then(res => {
+          // console.log(res.code);
+          if (res.code == 200) {
+            if (res.data && res.data.length > 0) {
+              // if (!res.data.includes('')) {
+              // this.alterMessage(res.data)
+              // }
+            } else {
+              this.$message.success('创建任务完成,正在导入!')
+            }
+           
+            this.queryParams.patentNo = ''
+            // this.getList()
+          }
+        }).catch(error => {
+        })
+        return false
+      }
+      this.$refs.from.validate((valid) => {
+        if (valid) {
+          this.$api.addTask(this.queryParams).then(res => {
+            if (res.code==200) {
+              this.$message.success('创建任务完成,正在导入!')
+              this.queryParams.conditions = ''
+              this.isGetList=!this.isGetList
+            }
+          })
+        }
+        
+      })
+     
+    },
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 34 - 0
RMS-FrontEnd/src/views/components/import/PatentNoImport/index.vue

@@ -0,0 +1,34 @@
+<template>
+  <div>
+    <download :projectId="id" :downloadId="option"></download>
+  </div>
+</template>
+
+<script>
+import download from "./download.vue";
+export default {
+  components: {
+    download
+  },
+  data() {
+    return {
+
+    }
+  },
+  computed: {
+    id() {
+      return this.$route.query.id
+    },
+    option() {
+      return this.$route.query.option
+    },
+  },
+  methods: {
+
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 96 - 0
RMS-FrontEnd/src/views/components/import/conditionImport/AdvancedSearch.vue

@@ -0,0 +1,96 @@
+<template>
+  <div class="advancedSearch">
+    <div>
+        <el-input type="textarea" v-model="condition" :rows="3" placeholder='高级检索语句,例:TI=(石墨烯 NOT 石墨烯薄膜 OR "graphene film") AND AD=2018 AND GD=20180205~20190101'></el-input>
+        <div style="display:flex;justify-content: flex-end;margin-top:20px">
+            <el-button type="danger" plain size="small" style="width:100px" @click="cancel">清空</el-button>
+            <el-button type="primary" size="small" style="width:100px" @click="search">检索</el-button>
+        </div>
+    </div>
+    <div>
+        <div>
+            <div><b>表达式与语法:</b></div>
+            检索条件表达式,可支持AND、OR、NOT等逻辑运算符号(不区分大小写)和等于(=)比较符号,其中:<br>
+            1、日期栏位的值支持yyyy. yyyyMM、 yyyyMMdd等格式;已知时间的连续范围为“2006-02-02”到“2009-01-01”,应输入:<span class="red">AD=20060202~20090101</span>;注意:日期的范围检索必须精确到日。<br>
+            2、专利类型(PT)栏位的值包括:1、8 为发明 检索发明,2、9 为新型,3 为外观(注意:仅中国专利);例:<span class="red">PT=1</span><br>
+            3、法律状态(LG)栏位的值包括:1:有效、2:失效、3:审中(注意:仅中国专利);例:<span class="red">LG=1</span><br>
+            4、国家〔地区)相关栏位的值为国家地区代码,需要大写,例如:CN代表中国、US代表美国、JP代表日本等;<br>
+            5、搜索条件中有空格把整个搜索条件前后加上英文双引号,例如:<span class="red">TI=(石墨烯 NOT 石墨烯薄膜 OR "graphene film") AND AD=2018 AND GD=20180205~20190101</span>;<br>
+        </div>
+        <div>
+            <div><b>检索栏位包括:</b></div>
+            <div class="field">
+                <p v-for="item in field.filter(item=>{return item.type != (this.DBType=='WD'?1:2)})" :key="item.label"><span style="color:red">{{ item.value }}</span>:{{ item.label }}</p>
+            </div>
+            <div><b>省市代码(仅中国专利):</b></div>
+            <div v-html="changeRed('province')">
+               
+            </div>
+            <div><b>国别代码:</b></div>
+            <div>
+                <span v-for="(item) in countryList" :key="item.value"><span class="red">{{ item.value }}</span>&nbsp;{{ item.label }}&nbsp;&nbsp;</span>
+            </div>
+        </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  components: {},
+  props:['countryList','DBType'],
+  data() {
+    return {
+        condition:'',
+        field:this.$constants.searchField,
+    };
+  },
+  watch: {
+  },
+  computed: {},
+  
+  created() {},
+  mounted() {
+    this.field = [].concat(...this.field.map(item=>{return item.children}))
+  },
+  methods: {
+    changeRed(val){
+        if(val == 'province'){
+            var str = ' 北京 12 天津 13 河北 14 山西 15 内蒙 21 辽宁 22 吉林 23 黑龙江 31 上海 32 江苏 33'
+                    +'浙江 34 安徽 35 福建 36 江西 37 山东 41 河南 42 湖北 43 湖南 44 广东 45 广西 51 四' 
+                    +'川 52 贵州 53 云南 54 西藏 61 陕西 62 甘肃 63 青海 64 宁夏 65 新疆 66 海南 71 台'
+                    +'湾 81 广州 83 武汉 85 重庆 87 西安 89 沈阳 91 大连 93 哈尔滨 94 深圳 95 青岛 97 宁'
+                    +'波 HK 香港'
+            var regx = new RegExp("[0-9A-Z]+", "g")
+        }
+        return "<span style='color:red'>11 </span>"+str.replace(regx,"<span style='color:red'>&nbsp;&nbsp; $& </span>")
+    },
+    cancel(){
+        this.condition = ''
+    },
+    search(){
+        var a = this.condition
+        // if(a.trim().indexOf('(')!=0){
+        //     a = `${a}`
+        // }
+        this.$emit('search',a.trim())
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+.advancedSearch{
+    padding: 10px;
+}
+.field{
+    display: flex;
+    flex-wrap:wrap;
+    p{
+        width:200px;
+        margin:5px;
+    }
+}
+.red{
+    color:red
+}
+</style>

+ 513 - 0
RMS-FrontEnd/src/views/components/import/conditionImport/FormSearch.vue

@@ -0,0 +1,513 @@
+<template>
+    <div class="formSearch">
+        <el-form :model="form" label-width="120px" size="small" label-position="right">
+            <template  v-for="item in constants.searchField" >
+                <div :key="item.label" v-if="(dbType ==2 && item.value!='typeAndStatus')||dbType !=2 ">
+                    <div>
+                        <span>{{item.label}}</span>
+                        <el-divider></el-divider>
+                    </div>
+                    <div>
+                        <el-row>
+                            <el-col :span="24">
+                                <div v-for="(i,index) in item.children" :key="i.value">
+                                    <div v-if="index%2==0">
+                                        <el-col :span="12" v-if="(item.children[index].type == dbType || item.children[index].type == 3)">
+                                            <el-form-item :label="item.children[index].label+':'">
+                                                <!-- <el-select v-model="form[item.children[index].value]" multiple filterable collapse-tags placeholder="请选择,可多选" style="width:100%">
+                                                    <el-option
+                                                    v-for="item in constants[item.children[index].value]"
+                                                    :key="item.value"
+                                                    :label="item.label"
+                                                    :value="item.value">
+                                                    </el-option>
+                                                </el-select> -->
+                                                <div v-if="item.children[index].dataType==2" style="display:flex;width:100%">
+                                                    <el-date-picker
+                                                        v-model="form[item.children[index].value][0]"
+                                                        style="width:50%"
+                                                        type="date"
+                                                        size='small'
+                                                        value-format="yyyyMMdd"
+                                                        placeholder="开始,例:20000101">
+                                                    </el-date-picker>
+                                                    <el-date-picker
+                                                        style="width:50%"
+                                                        v-model="form[item.children[index].value][1]"
+                                                        type="date"
+                                                        size='small'
+                                                        value-format="yyyyMMdd"
+                                                        placeholder="结束,例:20001231">
+                                                    </el-date-picker>
+                                                </div>
+                                                <div v-else-if="item.children[index].dataType==3" style="width:100%">
+                                                    <el-select v-model="form[item.children[index].value]" size="small" multiple filterable collapse-tags placeholder="请选择,可多选" style="width:100%">
+                                                        <el-option
+                                                            v-for="item in item.children[index].value=='GJ'?countryList:constants[item.children[index].value]"
+                                                            :key="item.value"
+                                                            :label="item.label"
+                                                            :value="item.value">
+                                                        </el-option>
+                                                    </el-select>
+                                                </div>
+                                                <div v-else style="width:100%"><el-input size='small' style="width:100%" v-model="form[item.children[index].value]" :placeholder="item.children[index].placeholder"></el-input> </div>
+                                            </el-form-item>
+                                        </el-col>
+                                        <el-col :span="12" v-if="(item.children[index+1]) && (item.children[index+1].type == dbType || item.children[index+1].type == 3)" >
+                                            <el-form-item :label="item.children[index+1].label+':'">
+                                                <!-- <el-select v-model="form[item.children[index+1]?.value]" multiple filterable collapse-tags placeholder="请选择,可多选" style="width:100%">
+                                                    <el-option
+                                                    v-for="item in constants[item.children[index+1]?.value]"
+                                                    :key="item.value"
+                                                    :label="item.label"
+                                                    :value="item.value">
+                                                    </el-option>
+                                                </el-select> -->
+                                                <div v-if="item.children[index+1].dataType==2" style="display:flex;width:100%">
+                                                    <el-date-picker
+                                                        v-model="form[item.children[index+1].value][0]"
+                                                        style="width:50%"
+                                                        type="date"
+                                                        size='small'
+                                                        value-format="yyyyMMdd"
+                                                        placeholder="开始,例:20000101">
+                                                    </el-date-picker>
+                                                    <el-date-picker
+                                                        style="width:50%"
+                                                        v-model="form[item.children[index+1].value][1]"
+                                                        type="date"
+                                                        size='small'
+                                                        value-format="yyyyMMdd"
+                                                        placeholder="结束,例:20001231">
+                                                    </el-date-picker>
+                                                </div>
+                                                <div v-else-if="item.children[index+1].dataType==3" style="width:100%">
+                                                    <el-select v-model="form[item.children[index+1].value]" size="small" multiple filterable collapse-tags placeholder="请选择,可多选" style="width:100%">
+                                                        <el-option
+                                                            v-for="item in item.children[index+1].value=='GJ'?countryList:constants[item.children[index+1].value]"
+                                                            :key="item.value"
+                                                            :label="item.label"
+                                                            :value="item.value">
+                                                        </el-option>
+                                                    </el-select>
+                                                </div>
+                                                <div v-else style="width:100%"><el-input size='small' style="width:100%" v-model="form[item.children[index+1].value]" :placeholder="item.children[index+1].placeholder"></el-input> </div>
+
+                                            </el-form-item>
+                                        </el-col>
+                                    </div>
+                                    
+                                </div>
+                                
+                            </el-col>
+                        </el-row>
+                    </div>
+                </div>
+            </template>
+
+
+<!-- 
+            <template>
+                <div>
+                    <span>类型及状态</span>
+                    <el-divider></el-divider>
+                </div>
+            </template>
+            <template>
+                <div>
+                    <el-row>
+                        <el-col :span="12" style="padding-right:20px" v-if="DBType != 'WD'">
+                            <el-form-item label="专利类型:">
+                                <el-select v-model="form.PT" multiple filterable collapse-tags placeholder="请选择,可多选" style="width:100%">
+                                    <el-option
+                                    v-for="item in option2"
+                                    :key="item.value"
+                                    :label="item.label"
+                                    :value="item.value">
+                                    </el-option>
+                                </el-select>
+                            </el-form-item>
+                        </el-col>
+                        <el-col :span="12">
+                            <el-form-item label="法律状态:" v-if="DBType != 'WD'">
+                                <el-select v-model="form.LG" multiple filterable collapse-tags placeholder="请选择,可多选" style="width:100%">
+                                    <el-option
+                                    v-for="item in option1"
+                                    :key="item.value"
+                                    :label="item.label"
+                                    :value="item.value">
+                                    </el-option>
+                                </el-select>
+                            </el-form-item>
+                        </el-col>
+                    </el-row>
+                    <el-row>
+                        <el-col :span="12" style="padding-right:20px" >
+                            <el-form-item label="IPC分类号:">
+                                <el-input v-model="form.IC" placeholder="IPC分类号,例:A018 OR A024"></el-input>
+                            </el-form-item>
+                            
+                        </el-col>
+                        <el-col :span="12">
+                            <el-form-item label="国家地区:" v-if="DBType != 'CN'">
+                                <el-select v-model="form.GJ" multiple filterable collapse-tags placeholder="请选择,可多选" style="width:100%">
+                                    <el-option
+                                        :label="(form.GJ && form.GJ.length == countryList.length)?'全部取消':'全部选择'"
+                                        value="-1"
+                                        @click.native="selectAll"
+                                    >
+                                    </el-option>
+                                    <el-option
+                                    v-for="item in countryList"
+                                    :key="item.value"
+                                    :label="item.label"
+                                    :value="item.value">
+                                    </el-option>
+                                </el-select>
+                            
+                            </el-form-item>
+                        </el-col>
+                    </el-row>
+                </div>
+            </template>
+            
+            <template>
+                <div>
+                    <span>申请信息</span>
+                    <el-divider></el-divider>
+                </div>
+            </template>
+            <template>
+                <div>
+                    <el-row>
+                        <el-col :span="12" style="padding-right:20px">
+                            <el-form-item label="申请号:">
+                                <el-input v-model="form.AN" placeholder="申请号,例:CN20120304957.6 OR CN20120305264.1"></el-input>
+                            </el-form-item>
+                        </el-col>
+                        <el-col :span="12">
+                            <el-form-item label="申请日:">
+                                <el-date-picker
+                                v-model="form.AD[0]"
+                                style="width:50%"
+                                type="date"
+                                value-format="yyyyMMdd"
+                                placeholder="开始,例:20000101">
+                                </el-date-picker>
+                                <el-date-picker
+                                style="width:50%"
+                                v-model="form.AD[1]"
+                                type="date"
+                                value-format="yyyyMMdd"
+                                placeholder="结束,例:20001231">
+                                </el-date-picker>
+                            </el-form-item>
+                        </el-col>
+                    </el-row>
+                    <el-row>
+                        <el-col :span="12" style="padding-right:20px">
+                            <el-form-item label="发明/设计人:">
+                                <el-input v-model="form.IN" placeholder="发明人,例:张三 OR 李四"></el-input>
+                            </el-form-item>
+                        </el-col>
+                        <el-col :span="12" >
+                            <el-form-item label="申请人:">
+                                <el-input v-model="form.PA" placeholder="申请人,例:清华大学 OR 北京大学"></el-input>
+                            </el-form-item>
+                        </el-col>
+                    </el-row>
+                    <el-row>
+                        <el-col :span="12" style="padding-right:20px" v-if="DBType != 'WD'">
+                            <el-form-item label="地址:">
+                                <el-input v-model="form.DZ" placeholder="申请人地址,例:北京 OR 上海"></el-input>
+                            </el-form-item>
+                        </el-col>
+                    </el-row>
+                </div>
+            </template>
+           
+            <template>
+                <div>
+                    <span>公开公告</span>
+                    <el-divider></el-divider>
+                </div>
+            </template>
+            <template>
+                <div>
+                    <el-row>
+                        <el-col :span="12">
+                            <el-form-item label="公开号:" style="padding-right:20px">
+                                <el-input v-model="form.PN" placeholder="公开号,例:CN102860161 OR CN1526554846"></el-input>
+                            </el-form-item>
+                        </el-col>
+                        <el-col :span="12">
+                            <el-form-item label="公开日:" >
+                                <el-date-picker
+                                v-model="form.PD[0]"
+                                style="width:50%"
+                                type="date"
+                                value-format="yyyyMMdd"
+                                placeholder="开始,例:20000101">
+                                </el-date-picker>
+                                <el-date-picker
+                                style="width:50%"
+                                v-model="form.PD[1]"
+                                type="date"
+                                value-format="yyyyMMdd"
+                                placeholder="结束,例:20001231">
+                                </el-date-picker>
+                            </el-form-item>
+                            
+                        </el-col>
+                    </el-row>
+                    <el-row>
+                        <el-col :span="12" style="padding-right:20px">
+                            <el-form-item label="公告号:"  v-if="DBType != 'WD'">
+                                <el-input v-model="form.GN" placeholder="公告号,例:CN102860161"></el-input>
+                            </el-form-item>
+                        </el-col>
+                        <el-col :span="12">
+                            <el-form-item label="公告日:" v-if="DBType != 'WD'">
+                                <el-date-picker
+                                v-model="form.GD[0]"
+                                style="width:50%"
+                                type="date"
+                                value-format="yyyyMMdd"
+                                placeholder="开始,例:20000101">
+                                </el-date-picker>
+                                <el-date-picker
+                                style="width:50%"
+                                v-model="form.GD[1]"
+                                type="date"
+                                value-format="yyyyMMdd"
+                                placeholder="结束,例:20001231">
+                                </el-date-picker>
+                            </el-form-item>
+                        </el-col>
+                    </el-row>
+                </div>
+            </template>
+            
+            <template>
+                <div>
+                    <span>文本</span>
+                    <el-divider></el-divider>
+                </div>
+            </template>
+            <template>
+                <div>
+                    <el-row>
+                        <el-col :span="12" style="padding-right:20px">
+                            <el-form-item label="名称:">
+                                <el-input v-model="form.TI" placeholder="专利名称,例:计算机 OR 手机"></el-input>
+                            </el-form-item>
+                        </el-col>
+                        <el-col :span="12">
+                            <el-form-item label="摘要:">
+                                <el-input v-model="form.AB" placeholder="文摘或简要说明,例:外喷放热气 OR 手机壳"></el-input>
+                            </el-form-item>
+                        </el-col>
+                    </el-row>
+                    <el-row>
+                        <el-col :span="12" style="padding-right:20px">
+                            <el-form-item label="关键词:">
+                                <el-input v-model="form.TX" placeholder="关键词,例:石墨烯 OR 壳"></el-input>
+                            </el-form-item>
+                        </el-col>
+                        <el-col :span="12"  v-if="DBType != 'WD'">
+                            <el-form-item label="权利要求:">
+                                <el-input v-model="form.CL" placeholder="主权利要求,例:加煤系统 OR 手机是由壳和屏幕构成"></el-input>
+                            </el-form-item>
+                            
+                        </el-col>
+                    </el-row>
+                </div>
+            </template>
+
+            <template v-if="DBType != 'WD'">
+                <div>
+                    <span>专利代理</span>
+                    <el-divider></el-divider>
+                </div>
+            </template>
+            <template v-if="DBType != 'WD'">
+                <div>
+                    <el-row>
+                        <el-col :span="12" style="padding-right:20px">
+                            <el-form-item label="代理机构:">
+                                <el-input v-model="form.AGN" placeholder="代理机构,例:威世博"></el-input>
+                            </el-form-item>
+                        </el-col>
+                        <el-col :span="12">
+                            <el-form-item label="代理人:">
+                                <el-input v-model="form.AT" placeholder="代理人,例:王五"></el-input>
+                            </el-form-item>
+                        </el-col>
+                    </el-row>
+                </div>
+            </template> -->
+        </el-form>
+        <div style="display:flex;justify-content: center;">
+            <el-button type="danger" plain size="small" style="width:100px" @click="cancel">清空</el-button>
+            <el-button type="primary" size="small" style="width:100px" @click="search">检索</el-button>
+        </div>
+    </div>
+</template>
+<script>
+export default {
+    props:['countryList','DBType'],
+    data() {
+        return {
+            form:{
+                AD:[],
+                PD:[],
+                GD:[]
+            },
+            dbType:this.DBType=='WD'?'2':'1',
+            constants:this.$constants,
+            option1:[//法律状态
+                {
+                    label:'有效',
+                    value:1
+                },
+                {
+                    label:'无效',
+                    value:2
+                },
+                {
+                    label:'审中',
+                    value:3
+                },
+            ],
+            option2:[//专利类型
+                {
+                    label:'发明',
+                    value:1
+                },
+                {
+                    label:'新型',
+                    value:2
+                },
+                {
+                    label:'外观',
+                    value:3
+                },
+            ],
+        }
+    },
+    watch:{
+        DBType(val){
+            this.dbType = val == 'WD'?'2':'1'
+        }
+    },
+    mounted() {
+        
+    },
+    methods: {
+        selectAll () {
+            if (this.form.GJ.length < this.countryList.length) { // 非全选时,点击选择全部
+                this.form.GJ = this.countryList.map((item) => {
+                    return item.value
+                })
+                // this.form.GJ.unshift('-1')
+            } else { // 全选时,点击置空
+                this.form.GJ = []
+            }
+        },
+        cancel(){
+            this.form = {
+                AD:[],
+                PD:[],
+                GD:[]
+            }
+        },
+        search(){
+            var str = ''
+            var keys = Object.keys(this.form)
+            for(let i = 0;i<keys.length;i++){
+                var str1 = ''
+                if(typeof this.form[keys[i]] == 'object'){
+                    if(this.form[keys[i]].length>0){
+                        if(keys[i]=='PD' || keys[i]=='GD' || keys[i]=='AD'){
+                            if(this.form[keys[i]].length>0){
+                                // if(this.form[keys[i]][0]){
+                                //     str1 = str1 + keys[i] + '>=' + this.form[keys[i]][0]  
+                                // }
+                                // console.log(this.form[keys[i]])
+                                if(!this.form[keys[i]][0] && !this.form[keys[i]][1]){
+
+                                }else{
+                                    if( this.form[keys[i]][0] && this.form[keys[i]][1] ){
+                                        // str1 = str1 + ' AND ' + keys[i] + '<=' + this.form[keys[i]][1] 
+                                        str1 = str1 + keys[i] + '=' + this.form[keys[i]][0] +'~'+this.form[keys[i]][1]
+                                    }else if(!this.form[keys[i]][0] || !this.form[keys[i]][1]){
+                                        // str1 = str1 + keys[i] + '<=' + this.form[keys[i]][1] 
+                                        str1 = str1 + keys[i] + '=' + (this.form[keys[i]][0] || this.form[keys[i]][1])
+                                    }
+                                }
+                                
+                            }
+                        }else{
+                            // this.form[keys[i]].forEach((item,index)=>{
+                            //     if(index<this.form[keys[i]].length-1){
+                            //         str1 = str1 + keys[i] + '=' + item + ' AND '
+                            //     }else{
+                            //         str1 = str1 + keys[i] + '=' + item
+                            //     }
+                            // })
+                            // if(keys[i] == 'GJ'){
+                            //     var index = this.form.GJ.findIndex(item=>{return item == '-1'})
+                            //     if(index!=-1){
+                            //         this.form.GJ.splice(index,1)
+                            //     }
+                            // }
+                            if(this.form[keys[i]].length>1){
+                                str1 = str1 + keys[i] + '=(' + this.form[keys[i]].join(" OR ") +')'
+                            }else{
+                                str1 = str1 + keys[i] + '=' + this.form[keys[i]][0]
+                            }
+                            
+                        }
+                    }
+                }else{
+                    if(this.form[keys[i]]){
+                        var a = this.form[keys[i]].replace(/("[^"]*"|'[^']*')/g,'')
+                        var arr = a.match(/\s{1}and|AND|OR|or|NOT|not\s{1}/g)
+                        if(arr&&arr.length>0){
+                            str1 = str1 + keys[i] + '=(' + this.form[keys[i]]+')'  
+                        }else{
+                            str1 = str1 + keys[i] + '=' + this.form[keys[i]] 
+                        }
+                        
+                    }
+                    
+                }
+                if(str1!=''){
+                    if(i<keys.length-1){
+                        str = str + str1 + ' AND ' 
+                    }else{
+                        str = str +  str1 
+                    }
+                }
+                
+            }
+            if(str.charAt(str.length-1)==' '){
+                str=str.slice(0,str.length-5);
+            }
+            this.$emit('search',str)
+        },
+    },
+}
+</script>
+<style lang="scss">
+.formSearch .el-divider{
+    margin-top:5px;
+    margin-bottom:24px;
+}
+
+</style>
+<style lang="scss" scoped>
+    .formSearch{
+        padding:10px;
+    }
+</style>

+ 406 - 0
RMS-FrontEnd/src/views/components/import/conditionImport/components/projectListDialog.vue

@@ -0,0 +1,406 @@
+<template>
+  <div>
+    <el-dialog title="导入到专题库" :visible.sync="dialogVisible" width="500px" :before-close="handleClose">
+        <div>
+            <el-form ref="form" :model="form" :rules="rules" label-width="100px">
+              <!-- <el-form-item label="任务名称">
+                <div>
+                  <el-input v-model="form.taskName" placeholder="请输入任务名称"></el-input>
+                </div>
+              </el-form-item> -->
+                <el-form-item label="选择报告" prop="projectId">
+                    <div class="selectButton">
+                        <el-select v-model="form.projectId" filterable clearable @change="changeProjectId" placeholder="请选择专题库" >
+                            <el-option
+                            v-for="item in projectList"
+                            :key="item.id"
+                            :label="item.name"
+                            :value="item.id"
+                            >
+                            </el-option>
+                        </el-select>
+                        <el-button @click="addProject"><i class="el-icon-plus"></i></el-button>
+                    </div>
+                </el-form-item>
+                <template v-if="form.projectId" >
+                    <div style="margin:10px 0;">
+                        <p>选择需要关联的标引与分类</p>
+                        <!-- <el-form-item label="选择需要关联的标引与分类"> -->
+                            <el-table :data="tableData" :show-header="false">
+                                <el-table-column type="expand">
+                                    <template slot-scope="props">
+                                        <el-form label-position="top" class="custom-field-form">
+                                            <template v-if="props.row.field === 'folder'">
+                                                <el-tree
+                                                    ref="folderTree"
+                                                    :data="customField.folder"
+                                                    check-strictly
+                                                    :default-checked-keys="form.json.field.folder"
+                                                    show-checkbox
+                                                    node-key="id"
+                                                    :props="defaultProps"
+                                                    @check-change="changeFolder"
+                                                ></el-tree>
+                                            </template>
+                                            <template v-else v-for="(item, index) in customField[props.row.field]">
+                                                <el-form-item :label="`${index + 1}. ${item.name}`">
+                                                    <template v-if="item.type === 0 || item.type === 2">
+                                                    <el-input v-model="form.json.field[item.id].value" placeholder="请输入内容" size="small"></el-input>
+                                                    </template>
+                                                    <template v-if="item.type === 1">
+                                                    <el-date-picker v-model="form.json.field[item.id].value" value-format="yyyy-MM-dd" type="date" size="small" placeholder="选择日期" style="width: 100%;"></el-date-picker>
+                                                    </template>
+                                                    <template v-if="item.type === 3">
+                                                    <el-select v-model="form.json.field[item.id].value" size="small" placeholder="请选择" class="width_100">
+                                                        <el-option v-for="option in item.option" :value="option.id" :label="option.name"></el-option>
+                                                    </el-select>
+                                                    </template>
+                                                    <template v-if="item.type === 4">
+                                                    <el-radio-group v-model="form.json.field[item.id].value">
+                                                        <el-radio v-for="option in item.option" :label="option.id">{{ option.name }}</el-radio>
+                                                    </el-radio-group>
+                                                    </template>
+                                                    <template v-if="item.type === 5">
+                                                    <el-checkbox-group v-model="form.json.field[item.id].value">
+                                                        <el-checkbox v-for="option in item.option" :label="option.id">{{ option.name }}</el-checkbox>
+                                                    </el-checkbox-group>
+                                                    </template>
+                                                    <template v-if="item.type === 6">
+                                                    <el-tree
+                                                        :ref="item.id"
+                                                        :data="item.option"
+                                                        check-strictly
+                                                        :default-checked-keys="form.json.field[item.id].value"
+                                                        show-checkbox
+                                                        node-key="id"
+                                                        :props="defaultProps"
+                                                        @check-change="changeField(item.id)"
+                                                    ></el-tree>
+                                                    </template>
+                                                </el-form-item>
+                                            </template>
+                                        </el-form>
+                                    </template>
+                                </el-table-column>
+                                <el-table-column prop="name" show-overflow-tooltip>
+                                    <template slot-scope="scope">
+                                        <div style="display:flex;justify-content: space-between;align-items:center">
+                                            <span>{{ scope.row.name }}</span>
+                                            <span v-if="scope.row.field === 'folder'"><el-button type="primary" size="small" @click="handleFolder(form.projectId)" :disabled="!($permission('/workspace/common/folder_manage') && $r(form.projectId,[1,2]))">文件夹管理</el-button></span>
+                                            <span v-else><el-button type="primary" size="small" @click="handleManage(form.projectId)" :disabled="!($permission('/workspace/common/customField') && $r(form.projectId,[1,2]))">自定义栏位管理</el-button></span>
+                                        </div>
+                                    </template>
+                                </el-table-column>
+                            </el-table>
+                        <!-- </el-form-item>  -->
+                    </div>
+                </template>
+                <el-form-item label="下载内容">
+                    <el-select v-model="form.configCells" multiple collapse-tags style="width:100%">
+                        <el-option v-for="item in patentField"
+                            :key="item.value"
+                            :label="item.label"
+                            :value="item.value">
+                        </el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="定期更新" prop="taskType">
+                    <el-switch v-model="form.taskType" :active-value="1" :inactive-value="0" active-color="#13ce66" inactive-color="#ff4949" @change="changeTaskType"></el-switch>
+                </el-form-item>
+                <template>
+                    <div v-show="form.taskType">
+                    <el-form-item label="更新间隔" prop="dateType">
+                        <el-select v-model="form.dateType" @change="getDateType" clearable placeholder="请选择更新时间间隔"  style="width:100%">
+                        <el-option v-for="item in options"
+                            :key="item.value"
+                            :label="item.label"
+                            :value="item.value">
+                        </el-option>
+                        </el-select>
+                    </el-form-item>
+                    <el-form-item label="具体更新时间" v-if="form.dateType"  style="width:100%">
+                        <timeChoose :type="form.dateType" @value="handleData" :cron="form.crons"></timeChoose>
+                    </el-form-item>
+                </div>
+                </template>
+            </el-form>
+            <div class="button">
+                <el-button type="primary" size="small" @click="onSubmit">导入</el-button>
+                <el-button size="small" @click="handleClose">取消</el-button>
+            </div>
+        </div>
+    </el-dialog>
+   
+
+    <project-form-drawer @submit="submitProjectForm" :common-data="commonData" ref="projectFormDrawer"/>
+
+    <project-field-drawer @close="handleClose2" ref="projectFieldDrawer" />
+
+    <project-folder-dialog @close="updateFolder" ref="projectFolderDialog" />
+  </div>
+</template>
+
+<script>
+import ProjectFormDrawer from "@/views/workspace/components/drawer/Form.vue";
+import timeChoose from "@/views/workspace/components/common/timeChoose.vue";
+
+import ProjectFieldDrawer from "@/views/workspace/components/drawer/Field";
+import ProjectFolderDialog from "@/views/workspace/components/dialog/Folder";
+export default {
+  components: {
+    ProjectFormDrawer,
+    timeChoose,
+    ProjectFieldDrawer,
+    ProjectFolderDialog
+  },
+  props: [],
+  data() {
+    return {
+      customField:{},
+      tableData:[
+        {
+            name: '标引',
+            field: 'index'
+        }, 
+        {
+            name: '分类',
+            field: 'classify'
+        }, 
+        {
+            name: '文件夹',
+            field: 'folder'
+        }
+      ],
+      defaultProps: {
+        children: 'children',
+        label: 'name'
+      },
+      dialogVisible:false,
+      form: {},
+      projectList: [],
+      commonData:{},
+      options: [
+        {label:'每天',value:'day'},
+        {label:'每周',value:'week'},
+        {label:'每月',value:'month'},
+        {label:'每年',value:'year'},
+      ],
+    //   /1.著录项目 2.权要 3.说明书文本 4.说明书pdf 6.摘要附图
+      patentField:[
+        {
+            value:'1',
+            label:'著录项目'
+        },
+        {
+            value:'2',
+            label:'权利要求'
+        },
+        {
+            value:'3',
+            label:'说明书文本'
+        },
+        {
+            value:'4',
+            label:'说明书pdf'
+        },
+        {
+            value:'6',
+            label:'摘要附图'
+        },
+      ],
+      rules: {
+          projectId: [
+            { required: true, message: '请选择专题库', trigger: 'change' }
+          ],
+      }
+    };
+  },
+  watch: {},
+  computed: {},
+  created() {},
+  mounted() {
+    this.$api.getCommonData({ keys: 'QUERY_GROUP,ENTERPRISE_APPLICATION_SCENARIO,INVESTIGATION_TYPE' }).then(response => {
+      this.commonData = response.data
+    })
+    this.getProjectList();
+  },
+  methods: {
+    open(form){
+        this.form = { 
+            ...form,
+            configCells:['1','2','3','4','6'],
+            taskType2:4,
+            taskType:0,
+            configId:2,
+            json: {
+                projectId: 0,
+                field: [],
+                folder: {}
+            }
+        }
+       if(this.form.projectId){
+        this.$set(this.form,'projectId',Number(this.form.projectId))
+       } 
+        this.dialogVisible=true
+    },
+    //关闭弹窗
+    handleClose(){
+      this.$refs.form.resetFields()
+      this.dialogVisible=false
+    },
+    //导入
+    onSubmit(){
+      this.$refs.form.validate((valid) => {
+        if (valid) {
+          
+          this.form.fieldList = []
+          this.form.folderIds = this.form.json.field.folder
+          for (let id in this.form.json.field) {
+              const field = this.form.json.field[id]
+              if (!field) {
+                  continue;
+              }
+              const type = field.type
+              const value = field.value
+              if (value) {
+              if (type === 5 || type === 6) {
+                  value.map(option => {
+                      this.form.fieldList.push({
+                      fieldId: parseInt(id),
+                      type: type,
+                      optionId: option
+                  })
+                  })
+              } else {
+                  this.form.fieldList.push({
+                  fieldId: parseInt(id),
+                  type: type,
+                  optionId: [0, 1, 2].indexOf(type) === -1 ? value : 0,
+                  text: value
+                  })
+              }
+              }
+          }
+          this.$api.addTask(this.form).then(response=>{
+            if(response.code == 200){
+              this.$message.success(response.data)
+              this.handleClose()
+            }
+          }).catch(error=>{
+          })
+        }
+      })
+    },
+    //切换专题库
+    changeProjectId(val){
+        if(val){
+           this.getCustomField(val) 
+        }
+        
+    },
+    //获取标引类型
+    getCustomField(projectId) {
+      this.$api.getCustomField({ projectId: projectId }).then(response => {
+        this.customField = response.data;
+        ['index', 'classify'].map(key => {
+          this.customField[key].map(item => {
+            let value = null
+            if (item.type === 5 || item.type === 6) {
+              value = []
+            }
+            this.$set(this.form.json.field, item.id, { type: item.type, value })
+          })
+        })
+      })
+    },
+    //打开自定义栏位弹窗
+    handleManage(projectId) {
+      this.$refs.projectFieldDrawer.open(projectId)
+    },
+    //关闭自定义栏位弹窗并更新自定义栏位数据
+    handleClose2(projectId) {
+      this.getCustomField(projectId)
+    },
+    //获取选中的分类节点
+    changeField(id){
+        this.form.json.field[id].value = this.$refs[id][0].getCheckedKeys()
+    },
+    //打开文件夹管理弹窗
+    handleFolder(projectId) {
+      this.$refs.projectFolderDialog.open(projectId)
+    },
+    //关闭文件夹弹窗并更新数据
+    updateFolder(projectId) {
+      this.$api.getProjectFolderList({ projectId: projectId, patentTotal: false }).then(response => {
+        this.customField.folder = response.data
+      })
+    },
+    //获取选中的文件夹
+    changeFolder(data, checked, indeterminate){
+        this.form.json.field.folder = this.$refs.folderTree.getCheckedKeys()
+    },
+    //获取更新周期
+    getDateType(val) {
+      this.form.crons = ''
+    },
+    //是否定期更新
+    changeTaskType(val){
+        if(!val){
+            this.form.dateType = ''
+            this.form.crons = ''
+        }
+    },
+     // 获取时间
+     handleData(val) {
+      if (this.form.dateType=='') {
+        this.$message.error('请先选择更新周期')
+        return false
+      }
+      this.form.crons=val
+    },
+    //查询专题库列表
+    getProjectList() {
+      let params = {
+        current: 1,
+        size: 9999,
+        myself: true,
+        name: "",
+        sort: {
+          order: "desc",
+          prop: "create_time",
+        },
+      };
+      this.$api.getProjectListV2(params).then((response) => {
+        this.projectList = response.data.records;
+      });
+    },
+    //打开新增专题库弹窗
+    addProject() {
+      this.$refs.projectFormDrawer.open(
+        {
+          update: 0,
+          updateTime: "一天",
+          status: "0",
+          sort: 1,
+          typeList: [],
+          scenarioList: [],
+        },
+        "新增专题库"
+      );
+    },
+    //更新列表
+    submitProjectForm(type) {
+      this.getProjectList()
+    },
+  },
+};
+</script>
+<style lang="scss">
+@import "@/assets/css/selectButton.scss";
+</style>
+<style lang="scss" scoped>
+.button{
+    display: flex;
+    justify-content: center;
+}
+</style>

+ 271 - 0
RMS-FrontEnd/src/views/components/import/conditionImport/components/search_history.vue

@@ -0,0 +1,271 @@
+<template>
+  <div style="background:white;padding:20px 20px 0;">
+    <el-button @click="deletes()"><i class="iconfont icon-shanchu"></i> 删除<span v-if="multipleSelection.length>0">{{ multipleSelection.length }}条</span><span v-else>所有</span>检索记录</el-button>
+    <el-divider></el-divider>
+    <el-table
+      ref="table"
+      :data="tableData"
+      style="width: 100%"
+      :maxHeight="height - 230"
+      v-loading="loading"
+      :row-key="getRowKeys"
+      @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" :reserve-selection="true">
+
+      </el-table-column>
+      <el-table-column prop="conditions" label="检索式"></el-table-column>
+      <el-table-column prop="dbType" label="检索范围" width="140">
+        <template slot-scope="scope">
+          <div>
+            {{ dbType[scope.row.dbType] }}
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column prop="time" label="创建/更新时间" width="240">
+        <template slot-scope="scope">
+          <div class="time">
+            <p>创建:{{ scope.row.retrieveTime }}</p>
+            <p>更新:{{ scope.row.updateTime }}</p>
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column prop="totalNum" label="检索结果" width="120">
+        <template slot-scope="scope">
+          <div>
+            {{ scope.row.totalNum }}件
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" width="140">
+        <template slot-scope="scope">
+            <div class="icon">
+                <span @click="editSearch(scope.row)" class="margin-left_10">
+                  <el-tooltip class="item" effect="dark" content="编辑" placement="top">
+                    <i class="iconfont icon-bianji"></i>
+                  </el-tooltip>
+                </span>
+                <span @click="executeSearch(scope.row)" class="margin-left_10">
+                  <el-tooltip class="item" effect="dark" content="再次执行" placement="top">
+                    <i class="iconfont icon-zidongzhihang"></i>
+                  </el-tooltip>
+                </span>
+                <span @click="delSearch(scope.row)" class="margin-left_10">
+                  <el-tooltip class="item" effect="dark" content="删除" placement="top">
+                    <i class="iconfont icon-shanchu"></i>
+                  </el-tooltip>
+                </span>
+            </div>
+        </template>
+      </el-table-column>
+    </el-table>
+<div class="foot">
+  <el-pagination
+          background
+          layout="total, prev, pager, next, jumper"
+          :current-page.sync="queryParams.current"
+          :page-size.sync="queryParams.size"
+          @current-change="handleCurrentChange"
+          @size-change="getList"
+          :total="queryParams.total"
+        >
+        </el-pagination>
+</div>
+    <el-dialog title="编辑检索式" :visible.sync="dialogVisible" width="800px" :before-close="handleClose" :close-on-click-modal="false" append-to-body>
+      <div>
+        <el-form :model="form" label-width="120px" size="small" label-position="right">
+          <el-form-item label="检索范围:">
+            <el-radio-group v-model="form.dbType">
+              <el-radio label="CN">中国专利检索</el-radio>
+              <el-radio label="WD">世界专利检索</el-radio>
+            </el-radio-group>
+          </el-form-item>
+          <el-form-item label="检索式:">
+            <el-input type="textarea" v-model="form.conditions"></el-input>
+          </el-form-item>
+        </el-form>
+      </div>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="handleClose">取 消</el-button>
+        <el-button type="primary" @click="submit" :loading="btnLoading">检 索</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  components: {},
+  props:['reportId'],
+  data() {
+    return {
+      height:document.documentElement.clientHeight,
+        tableData:[],
+        multipleSelection:[],
+        loading:false,
+        dialogVisible:false,
+        btnLoading:false,
+        queryParams:{
+          size:10,
+          current:1,
+          total:0
+        },
+        dbType:{
+          'CN':'中国专利检索',
+          'WD':'世界专利检索'
+        },
+        form:{},
+    };
+  },
+  watch: {},
+  computed: {},
+  created() {},
+  mounted() {
+    this.getList()
+  },
+  methods: {
+    getRowKeys(row) {
+      return row.id
+    },
+    open(){
+      this.getList()
+    },
+    handleSelectionChange(val){
+        this.multipleSelection = val
+    },
+    //切换页数
+    async handleCurrentChange(val) {
+      this.queryParams.current = val;
+      await this.getList();
+    },
+    //查询检索历史
+    getList(){
+      this.loading = true
+      this.$api.queryRetrieveRecord(this.queryParams).then(response=>{
+        if(response.code == 200){
+          this.tableData = response.data.records
+          this.queryParams.total = response.data.total
+          this.loading = false
+        }
+      }).catch(error=>{
+        this.tableData = []
+        this.loading = false
+      })
+    },
+    //打开编辑检索历史弹窗
+    editSearch(row){
+      this.form = {
+        dbType:row.dbType,
+        id:row.id,
+        conditions:row.conditions,
+      }
+      this.dialogVisible = true
+    },
+    //关闭编辑检索历史弹窗
+    handleClose(){
+      this.form = {}
+      this.dialogVisible = false
+    },
+    //提交编辑内容
+    submit(){
+      // this.btnLoading = true
+      // this.$api.updateRetrieveRecord(this.form).then(response=>{
+      //   if(response.code == 200){
+      //     this.$message.success('编辑成功')
+      //     this.btnLoading = false
+      //     this.handleClose()
+      //     this.getList()
+      //   }
+      // }).catch(error=>{
+
+      // })
+      const router = this.$router.resolve({
+                path: '/searchResult',
+                query: {
+                    condition:this.form.conditions,
+                    DBType:this.form.dbType,
+                    reportId:this.reportId?this.reportId:null,
+                    retrieveRecordId:null
+                }
+            })
+            // this.$s.setSession('retrieveRecordId',0)
+            this.handleClose()
+            this.getList()
+            window.open(router.href, '_blank');
+    },
+    //执行检索历史
+    executeSearch(row){
+      const router = this.$router.resolve({
+                path: '/searchResult',
+                query: {
+                    condition:row.conditions,
+                    DBType:row.dbType,
+                    reportId:this.reportId?this.reportId:null,
+                    retrieveRecordId:null
+                }
+            })
+            // this.$s.setSession('retrieveRecordId',row.id)
+            window.open(router.href, '_blank');
+    },
+    //检索历史id加入到数组
+    delSearch(row){
+      var a = [row.id]
+      this.deletes(a)
+    },
+    //删除检索历史
+    deletes(val){
+      var arr = {
+        isAll:false
+      }
+      if(val){
+        arr.ids = val
+      }else{
+        if(this.multipleSelection.length>0){
+          arr.ids = this.multipleSelection.map(item=>{return item.id})
+        }else{
+          arr.isAll = true
+          arr.ids = []
+        }
+      }
+      this.$confirm('确认删除吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.loading = true
+        this.$api.deleteRetrieveRecord(arr).then(response=>{
+          if(response.code == 200){
+            this.$message.success('删除成功')
+            if(this.multipleSelection.length>0){
+              this.multipleSelection = []
+              this.$refs.table.clearSelection();
+            }
+            
+            this.loading = false
+            this.getList()
+          }
+        }).catch(error=>{
+
+        })
+      })
+        
+    }
+  },
+};
+</script>
+<style lang="scss" scoped>
+.time{
+  p{
+    margin:0;
+  }
+}
+.icon{
+  i{
+    font-size:20px;
+  }
+}
+.foot{
+  margin-top:10px;
+  display: flex;
+  justify-content: center;
+}
+</style>

+ 138 - 0
RMS-FrontEnd/src/views/components/import/conditionImport/customSearch.vue

@@ -0,0 +1,138 @@
+<template>
+  <div class="customSearch">
+    <el-container style=" border: 1px solid #eee" :style="{height:height-70+'px'}">
+        <el-aside v-if="DBType == 'WD'">
+             <div>
+                <div class="clearfix">
+                    <span><el-checkbox v-model="checked" @change="change">全部国家地区</el-checkbox></span>
+                    <span style="float: right; padding: 3px 0" type="text">{{ checkList.length }}/{{countryList.length}}</span>
+                </div>
+                    <div style="overflow-y:auto;overflow-x:hidden;" :style="{height:height-120+'px'}">
+                       <el-checkbox-group v-model="checkList">
+                        <div v-for="item in countryList" :key="item.value" class="item">
+                            <el-checkbox :label="item.value">{{ item.label }}({{ item.value }})</el-checkbox>
+                        </div>
+                            
+                        </el-checkbox-group> 
+                    </div>
+                     
+             </div>
+        </el-aside>
+        <el-main>
+            <div>
+                <search :logical="logical" :logicalProps="logicalProps" :operator="operator" :field="field" :searchValue="true" @search="search"></search>
+            </div>
+        </el-main>
+    </el-container>
+  </div>
+</template>
+
+<script>
+import search from '@/views/components/common/components/search.vue'
+export default {
+  components: {
+    search
+  },
+  props: ['countryList','DBType'],
+  data() {
+    return {
+        height:document.getElementsByClassName('el-main')[0].clientHeight,
+        checkList:[],
+        checked:false,
+        //逻辑符
+        logical:[
+                {
+                    name:'并且',
+                    value:'AND'
+                },
+                {
+                    name:'或者',
+                    value:'OR'
+                },
+                {
+                    name:'非',
+                    value:'NOT'
+                },
+            ],
+            logicalProps:{
+                label:'name',
+                value:'value'
+            },
+            //运算符
+            operator:[
+                {
+                    label:'=',
+                    value:'='
+                },
+                // {
+                //     label:'>',
+                //     value:'>'
+                // },
+                // {
+                //     label:'<',
+                //     value:'<'
+                // },
+                // {
+                //     label:'<=',
+                //     value:'<='
+                // },
+            ],
+            //搜索值
+            field:JSON.parse(JSON.stringify(this.$constants.searchField)),
+    };
+  },
+  watch: {
+    'checkList'(val){
+      if(val.length == this.countryList.length){
+        this.checked = true
+      }else{
+        this.checked = false
+      }
+    },
+    DBType(){
+      this.getField()
+    },
+  },
+  computed: {},
+  created() {},
+  mounted() {
+    this.getField()
+  },
+  methods: {
+    getField(){
+      var a = JSON.parse(JSON.stringify(this.$constants.searchField))
+      this.field = a.map(item=>{ 
+        item.children = item.children.filter(item1 =>{return item1.value!='GJ' && item1.type != (this.DBType != 'WD'?'2':'1')}) 
+        return item
+      })
+    },
+    search(val){
+      if(this.DBType == 'WD' && this.checkList.length>0){
+        var str = `${val} AND (GJ=${this.checkList})`
+        this.$emit('search',str)
+      }else{
+        this.$emit('search',`${val}`)
+      }
+      
+    },
+    change(val){
+      if(val){
+        this.checkList = this.countryList.map(item=>item.value)
+      }else{
+        this.checkList = []
+      }
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+
+  .clearfix {
+    // padding-left:20px ;
+    padding:10px 20px ;
+    border-bottom: 1px solid #eeeeee;
+  }
+  .item{
+    padding:10px 20px;
+  }
+</style>

+ 30 - 0
RMS-FrontEnd/src/views/components/import/conditionImport/index.vue

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

+ 159 - 0
RMS-FrontEnd/src/views/components/import/conditionImport/patentDetails/PatentList.vue

@@ -0,0 +1,159 @@
+<template>
+    <div class="change-patent" style="background:white;display:flex; justify-content:flex-end" key="1"> 
+      <el-button type="" size="small" :disabled="prev==0||ban==1" @click="handleLink(records[index-1],'prev')" >
+        <span class="p"><i class="el-icon-arrow-up"></i>
+          <span>上一篇</span>
+        </span>
+        <span class="n" v-if="prev">
+          <span>{{ records[index-1].patentNo }}</span>
+        </span>
+        <span class="n" v-else>无数据</span>
+      </el-button>
+      <div style="width:120px;height:50px;border-radius:5px ;border:1px solid #DCDCDC;display:flex; justify-content:flex-start;margin:0 10px">
+        <div class="t" style="min-width:50px;text-align:center;line-height:50px;border-right:1px solid #DCDCDC;" v-if="prev>0">{{ prev }}</div>
+        <div class="t" style="min-width:50px;text-align:center;line-height:50px" v-if="next">{{ next }}</div>
+        </div>
+      <el-button type="" size="small" :disabled="next==0||ban==1" @click="handleLink(records[index+1],'next')" >
+        <span class="p">
+          <i class="el-icon-arrow-down"></i>
+          <span>下一篇</span>
+        </span>
+        <span class="n" v-if="next">
+          <span>{{ records[index+1].patentNo }}</span>
+        </span>
+        <span class="n" v-else>无数据</span>
+      </el-button>
+    </div>
+</template>
+  
+  <script>
+  
+  export default {
+    mixins: [],
+    props: ['ban'],
+    data() {
+      return {
+        queryParams: {},
+        records: [],
+        total: 0,
+        loading: false,
+        index:0,
+        prev:0,
+        next:0,
+      }
+    },
+    watch: {
+    },
+    async mounted() {
+      // console.log(this.$s.getSession('params'))
+        var index = this.$s.getSession('params').index
+        this.index = index%10
+        this.queryParams = this.$s.getSession('params').params
+        this.queryParams.PageNum = Math.floor(index/10)+1
+        this.queryParams.RowCount = 10
+        if(this.index == 9){
+          this.queryParams.RowCount = 20
+        }
+       await this.getPatentList()
+    },
+    methods: {
+     async getPatentList(val) {
+        // this.loading = true
+       await this.$api.patentSelectImport(this.queryParams).then(response=>{
+          if(response.code == 200){
+            var params = this.$s.getSession('params')
+            if(this.index == 9){
+              this.queryParams.RowCount = 10
+            }
+            this.total =response.data.total
+            this.$set(this,'prev',(this.queryParams.PageNum-1)*this.queryParams.RowCount + this.index)
+            this.$set(this,'next',this.total>2?((this.total - this.prev - 1)<0?0:(this.total - this.prev - 1)):0)
+            // this.prev = (this.queryParams.PageNum-1)*this.queryParams.RowCount + this.index
+            // this.next = this.total>2?((this.total - this.prev - 1)<0?0:(this.total - this.prev - 1)):0
+            if(val){
+              this.$set(this,'records',response.data.records.concat(this.records))
+            }else{
+              this.$set(this,'records',this.records.concat(response.data.records))
+            }
+            // this.records = this.records.concat(response.data.records)
+            params.index = this.prev
+            this.$s.setSession('params',params)
+            // this.loading = false
+            
+          }
+        }).catch(error=>{
+          this.loading = false
+        })
+      },
+    handleLink(item,type) {
+        this.$emit('on-change', item)
+        if(type == 'prev'){
+            this.index =this.index - 1
+            this.prev -=1
+            this.next +=1
+            if(this.index <= 1){
+                if(this.queryParams.PageNum>1){
+                    this.index += 10
+                    this.queryParams.PageNum -= 1
+                    this.getPatentList(type)
+                    this.$nextTick(()=>{
+                        this.records.splice(10,10)
+                    })
+                }
+            }
+        }else{
+          if(this.prev>=9999){
+            this.$message.warning('系统不能查看10000条以后的数据!!!')
+            return false
+          }
+            this.index =this.index + 1
+            this.prev +=1
+            this.next-=1
+            if(this.records.length==20 && this.index == 18){
+                this.index -= 10
+                this.queryParams.PageNum += 1
+                this.getPatentList()
+                this.$nextTick(this.records.splice(0,10))
+            }else if(this.records.length<=10 && this.index == 8){
+                this.getPatentList()
+            }
+        }
+        
+      },
+    }
+  }
+</script>
+  
+  <style lang="scss">
+  .change-patent {
+    padding: 10px;
+    .el-button {
+      height: 50px;
+      width: 100%;
+      margin-left: 0 !important;
+    
+      // margin-top: 10px;
+      text-align: left;
+      font-size: 12px;
+      .p {
+        display: block;
+        margin-bottom: 5px;
+        color: black;
+        .t {
+          height: 50px;
+          width: 100px;
+          border: 1px solid #797979;
+          padding-left: 10px;
+          color: #1e9fff;
+          font-size: 14px;
+          font-weight: bold;
+        }
+      }
+      .n {
+        margin-left: 18px;
+        font-size: 12px;
+        color: #797979;
+      }
+    }
+  }
+  </style>

+ 276 - 0
RMS-FrontEnd/src/views/components/import/conditionImport/patentDetails/patentDetail.vue

@@ -0,0 +1,276 @@
+<template>
+    <div>
+        <div class="patent-articles" >
+            <el-container v-loading="loading">
+                <el-container >
+                    <el-header class="patent-articles-title">
+                        <div class="patent-articles-title-box">
+                            <div style="position:relative">
+                                <img src="@/assets/visual/fixed.png" width="20px" height="20px" v-if="fix===true" @click="qx" style="position:absolute;top:5px;left:5px"/>
+                                <img src="@/assets/visual/unfixed.png" width="20px" height="20px" v-if="fix===false"  @click="gd" style="position:absolute;top:5px;left:5px"/>
+                                <div>
+                                    <span v-html="getViewDom(patent.publicNo)"></span>
+                                    <el-tag type="primary" effect="dark" size="mini" class="margin-left_10">{{ patent.simpleStatus }}</el-tag>
+                                </div>
+                                <div style="color: #6b6868; font-size: 15px;border-bottom: 1px solid #e6e6e6;padding-bottom: 5px;">
+                                    <span v-html="getViewDom2(patent, 'name')"></span>
+                                    <el-link v-if="projectId" type="primary" @click.native="handleChange(patent, 'name')" style="margin-left: 10px;margin-top: -3px;">
+                                        <span v-if="!patent.change">切换译文</span>
+                                        <span v-else>切换原文</span>
+                                    </el-link>
+                                </div>
+                            </div>
+                            <div  style="  position: relative;">
+                                <el-link v-for="item in menuList" :type="activeMenu === item.value ? 'primary' : undefined" v-if="!item.show" @click.native="handleSelect(item.value)">
+                                {{ item.label }}
+                                <!-- <span v-if="item.value == 'PatentImage'|| item.value=='PatentPDF'" @click.stop="ending(item.value)">
+                                    <el-popover
+                                        placement="right"
+                                        width="400"
+                                        trigger="click">
+                                        <el-radio v-for="(item, index) in positionList" :key="index" v-model="radio" @input="changePosition"  :label="item.value">{{item.label}}</el-radio>
+                                        <i class="el-icon-setting" slot="reference"></i>
+                                    </el-popover>
+                                    </span> -->
+                                </el-link>
+                            </div>
+                        </div>
+                    </el-header>
+                    <el-main class="patent-articles-content" style="padding-left:30px">
+                        <div class="patent-articles-content-left">
+                            <!-- <div class="dom1 box1" v-dragControllerDiv1 style="display:flex;width:100%">
+                                <div class="component left1" style="width:100%;overflow-y:auto;overflow-x: hidden;" :style="{height:height}"> -->
+                                    <component style="width:100%;height:100%" :is="componentName" :patent="patent" :patentNo="[patent.patentNo]" :domId="patent.patentNo + '1'"  :pdfType1="(patent.pdf && patent.pdf.length>0)?patent.pdf[0].type:2" @refresh="getPatent(applicationNo)"></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;overflow-y:auto;overflow-x: hidden;">
+                                    <component :is="activeMenu2" :patent="patent" :patent-id="patentId" :pdfType1="(patent.pdf && patent.pdf.length>0)?patent.pdf[0].type:2" :sign="true"></component>
+                                </div> -->
+                            <!-- </div> -->
+                        </div>
+                    </el-main>
+                </el-container>
+            </el-container>
+            <div class="content-main" style="padding-left:40px"></div>
+        </div>
+    </div>
+</template>
+
+<script>
+import { changeTranslation, patentKeywordsHighlight } from '@/views/workspace/folder/components/mixins'
+
+import PatentField from '@/views/workspace/folder/articles/components/PatentField'
+import PatentAnnotation from '@/views/workspace/folder/articles/components/PatentAnnotation'
+import PatentBasic from "@/views/workspace/folder/articles/components/PatentBasic"
+import PatentPDF from "@/views/workspace/folder/articles/components/PatentPDF"
+import PatentImage from "@/views/workspace/folder/articles/components/PatentImage"
+import PatentRight from "@/views/workspace/folder/articles/components/PatentRight"
+import PatentInstruction from "@/views/workspace/folder/articles/components/PatentInstruction"
+import PatentFamily from "@/views/workspace/folder/articles/components/PatentFamily"
+import PatentStatus from "@/views/workspace/folder/articles/components/PatentStatus"
+
+export default {
+  components: {
+    PatentField,
+    PatentAnnotation,
+    PatentBasic,
+    PatentPDF,
+    PatentImage,
+    PatentRight,
+    PatentFamily,
+    PatentStatus,
+    PatentInstruction,
+  },
+  props: ['applicationNo','projectId'],
+  mixins: [patentKeywordsHighlight, changeTranslation],
+  data() {
+    return {
+        radio:1,
+        height:null,
+        loading:false,
+        fix:false,
+        activeMenu: 'PatentBasic',
+        activeMenu2:'',
+        componentName: 'PatentBasic',
+        menuList: [
+            {
+                value: 'PatentBasic',
+                label: '基础信息'
+            },
+            {
+                value: 'PatentRight',
+                label: '权利要求'
+            },
+            {
+                value: 'PatentImage' ,
+                label:'附图'
+            },
+            {
+                value: 'PatentInstruction',
+                label: '说明书文本'
+            },
+            {
+                value: 'PatentFamily',
+                label: '同族专利'
+            },
+            {
+                value: 'PatentStatus',
+                label: '事务数据'
+            },
+            {
+                value: 'PatentPDF',
+                label: '说明书'
+            },
+        ],
+        positionList:[
+            {
+                label:'tab展示',
+                value:1
+            },
+            {
+                label:'上边展示',
+                value:2
+            },
+            {
+                label:'下边展示',
+                value:3
+            },
+            {
+                label:'左边展示',
+                value:4
+            },
+            {
+                label:'右边展示',
+                value:5
+            },
+        ],
+        patent:{},
+    };
+  },
+  watch: {
+    applicationNo(val){
+        if(this.fix!=true){
+          this.getPatent(val)
+        }
+    },
+    fix(val){
+        this.$emit('on-change',val)
+    },
+  },
+  computed: {},
+  created() {},
+  async mounted() {
+   await this.getPatent(this.applicationNo)
+   this.changePageTitle()
+  },
+  methods: {
+     //修改title
+     changePageTitle() {
+      document.title = `${this.patent.publicNo} ${this.patent.name || ''}`
+    },
+    //解除定住,可以切换
+    qx(){
+      this.fix=false
+    },
+    //定住不能切换
+    gd(){
+      this.fix=true
+    },
+    //切换显示内容
+    handleSelect(index) {
+    //   if(index == this.activeMenu2){
+    //     this.activeMenu2 = ''
+    //     this.radio = 1
+    //     this.changePosition(this.radio)
+    //   }
+      this.activeMenu = index
+      this.componentName = index
+    },
+    //获取专利信息
+    async getPatent(applicationNo){
+        var params =this.$s.getSession('params').params
+        params.CurrentQuery = "(AN="+ applicationNo +")"
+        params.PageNum = 1
+        // params.retrieveRecordId = null
+        this.loading = true
+       await this.$api.patentSelectImport(params).then(response=>{
+          if(response.code == 200){
+            this.patent = response.data.records[0]
+            this.loading = false
+          }
+        }).catch(error=>{
+          this.loading = false
+        })
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+.patent-articles {
+  width: 100%;
+  height: 100% !important;
+  padding: 0 !important;
+  .patent-articles-menu {
+
+  }
+  .el-menu-item.is-active {
+    background: #ecf5ff !important;
+    color: #409EFF!important;
+  }
+  .patent-articles-title {
+    padding: 0 !important;
+    height: 100px !important;
+    .el-link {
+      margin-right: 20px;
+    }
+    .patent-articles-title-box {
+      font-size: 20px;
+      width: 100%;
+      text-align: center;
+    }
+  }
+  .patent-articles-content {
+    background: #fff;
+    padding: 0;
+    height: 100%;
+    overflow: hidden;
+    .patent-articles-content-left {
+        width:100%;
+      float: left;
+      height: 100%;
+      overflow-y: auto;
+      overflow-x: hidden;
+      padding: 10px;
+    }
+    .patent-articles-content-right {
+      width: 300px;
+      border-left: 1px solid #e6e6e6;
+      float: right;
+      height: 100%;
+      .el-header {
+        height: 50px !important;
+        position: relative !important;
+      }
+      .el-main {
+        padding: 0 12px !important;
+      }
+      .el-container, .el-main {
+        height: 100%;
+      }
+      .patent-articles-option {
+        position: absolute;
+        bottom: 0;
+        height: 100%;
+        left: 50px;
+        .el-tabs {
+          margin-top: 9px;
+        }
+        .el-tabs__header {
+          margin-bottom: 0 !important;
+        }
+      }
+    }
+  }
+}
+</style>

+ 140 - 0
RMS-FrontEnd/src/views/components/import/conditionImport/patentDetails/patentIndex.vue

@@ -0,0 +1,140 @@
+<template>
+    <div style="height:calc(100% - 50px)">
+        <div style="background:white;display:flex; justify-content:flex-end;align-items: center;">
+            <el-button type="primary" class="margin-right_10" @click="importToProject">导入到专题库</el-button>
+            <el-switch
+                v-model="value"
+                :disabled="!$permission('/workspace/details/comparison')"
+                inactive-text="对比"
+                active-color="#00BFFF"
+                inactive-color="#D3D3D3">
+            </el-switch>
+            <PatentList @on-change="onChange" :ban='ban'/>
+        </div> 
+        <div class="box" ref="box" v-dragControllerDiv>
+            <div class="left" :style="{width:width}"><!--左侧div内容-->
+                <PatentDetail :applicationNo="applicationNo" @on-change='changefix' />
+            </div>
+            <div class="resize" title="收缩侧边栏"   v-show="width!='100%'">⋮</div>
+            <div class="mid" v-show="width!='100%'" :style="{width:width}"><!--右侧div内容-->
+                <PatentDetail :applicationNo="applicationNo" @on-change='changefix' />
+            </div>
+        </div> 
+
+        <Project-List-Dialog ref="projectListDialog"></Project-List-Dialog>
+  </div>
+</template>
+
+<script>
+import PatentDetail from './patentDetail.vue';
+import PatentList from './PatentList.vue'
+import ProjectListDialog from '../components/projectListDialog.vue'
+export default {
+  components: {
+    PatentDetail,
+    PatentList,
+    ProjectListDialog
+  },
+  props: {},
+  data() {
+    return {
+        ban:0,
+        value: false,
+        width:'100%',
+        applicationNo:this.$route.query.applicationNo || null,
+        patentNo:this.$route.query.patentNo || null,
+    };
+  },
+  watch: {
+    value(val){
+      if(val==true){
+        this.width='50%'
+      }else{
+        this.width='100%'
+      }
+    },
+  },
+  computed: {
+    contrastList() {
+      return this.$store.state.report.contrastList
+    }
+  },
+  created() {},
+  mounted() {
+    this.getContrastList(this.patentNo)
+  },
+  methods: {
+    //导入到专题库
+    importToProject(){
+      var params =this.$s.getSession('params').params
+      var form = {
+        conditions:"(AN="+ this.applicationNo +")",
+        DBType:params.DBType,
+        orderBy:params.OrderBy,
+        orderByType:params.OrderByType,
+        startNumber:1,
+        endNumber:0,
+        isAddPatentNos:[this.applicationNo],
+        isDeletePatentNos:[],
+        projectId:this.$s.getSession('params').projectId
+      }
+      this.$refs.projectListDialog.open(form)
+    },
+    //修改定住
+    changefix(){
+
+    },
+    //切换专利
+    async onChange(val){
+        this.applicationNo = val.applicationNo
+        this.patentNo = val.patentNo
+       
+        this.changePageTitle(val.publicNo,val.name)
+        this.getContrastList(val.patentNo)
+        await this.$router.push({
+          path: '/search/patentDetail',
+          query: {
+            applicationNo: val.applicationNo,
+            patentNo: val.patentNo,
+          }
+        })
+    },
+    // 查询批注
+    getContrastList(val) {
+      if (val) {
+        var index = this.contrastList.findIndex(item => {
+          item.patentNo == val
+        })
+        if (index != -1) {
+          return false;
+        }
+      }
+      let params = {
+        patentNo: val?val:this.patentNo,
+        id: this.projectId,
+        createFrom:this.projectId?1:0
+      }
+      this.$api.scratchWordsQuery(params).then(response => {
+        if (response.code==200) {
+          if (this.contrastList.length > 0) {
+             var a = this.contrastList.filter(item => {
+              return item.patentNo != params.patentNo
+             }).concat(response.data)
+          } else {
+             var a = response.data
+          }
+           this.$store.commit('SET_PATENT_CONTRAST', a)
+        }
+      })
+    },
+    //修改title
+    changePageTitle(publicNo,name) {
+      document.title = `${publicNo} ${name || ''}`
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+@import '@/assets/css/activeDiv.scss';
+
+</style>

+ 145 - 0
RMS-FrontEnd/src/views/components/import/conditionImport/search.vue

@@ -0,0 +1,145 @@
+<template>
+    <div style="background:white">
+        <div class="head">
+            <div class="menu">
+                <span class="type">
+                    <el-radio-group v-model="DBType">
+                        <el-radio label="CN">中国专利检索</el-radio>
+                        <el-radio label="WD">世界专利检索</el-radio>
+                    </el-radio-group>
+                </span>
+                  <el-link :type="isComponent === 'FormSearch' ? 'primary' : undefined" @click="changeComponent('FormSearch')" >表格检索</el-link>
+                  <el-link :type="isComponent === 'customSearch' ? 'primary' : undefined" @click="changeComponent('customSearch')">高级检索</el-link>
+                  <el-link :type="isComponent === 'AdvancedSearch' ? 'primary' : undefined" @click="changeComponent('AdvancedSearch')">专家检索</el-link>  
+                <span class="icon">
+                    <i class="iconfont icon-shouye" @click="openHistory"></i>
+                </span>
+            </div> 
+        </div>
+        
+        <div style="width:70%;margin:0 auto;">
+            <component :is='isComponent' @search="search" :countryList="countryList" :DBType="DBType"></component>
+        </div>
+
+        <el-dialog title="检索历史" :visible.sync="dialogVisible" width="1200px" :close-on-click-modal="false">
+            <div>
+                <searchHistory ref="searchHistory" :reportId="reportId"></searchHistory> 
+            </div>
+        </el-dialog>
+        
+    </div>
+</template>
+<script>
+import FormSearch from './FormSearch.vue';
+import AdvancedSearch from './AdvancedSearch.vue';
+import customSearch from './customSearch.vue'
+
+import searchHistory from './components/search_history.vue';
+export default {
+    components:{
+        FormSearch,
+        AdvancedSearch,
+        customSearch,
+        searchHistory
+    },
+    props:['reportId'],
+    data() {
+        return {
+            isComponent:'FormSearch',
+            countryList:[],
+            DBType:"CN",
+            dialogVisible:false,
+        }
+    },
+    mounted() {
+        this.getCountry()
+    },
+    methods: {
+        //获取国家
+        getCountry(){
+            var str = 'AD 安道尔 AE 阿拉伯联合酋长国 AF 阿富汗 AG 安提瓜和巴布达 AI 安圭拉岛 AL 阿尔巴尼亚 AM 亚'
+                    +'美尼亚 AN 荷属安的列斯群岛 AO 安哥拉 AP 非洲地区工业产权组织(ARIPO) AR 阿根廷 AT 奥地'
+                    +'利 AU 澳大利亚 AW 阿鲁巴岛(荷) BA 波斯尼亚和黑塞哥维那(波黑) BB 巴巴多斯 BD 孟加拉 AZ'
+                    +'阿塞拜疆 BE 比利时 BF 布基纳法索 BG 保加利亚 BH 巴林 BI 布隆迪 BJ 贝宁 BM 百慕大 BN 文'
+                    +'莱 BO 玻利维亚 BR 巴西 BS 巴哈马 BT 不丹 BV 布韦岛 BW 博茨瓦那 BX 比、荷、卢经济联盟商'
+                    +'标局及外观设计局 BY 白俄罗斯 BZ 伯利兹 CA 加拿大 CD 刚果民主共和国 CF 中非共和国 CG 刚'
+                    +'果 CH 瑞士 CI 科特迪瓦 CK 库克群岛 CL 智利 CM 喀麦隆 CN 中国 CO 哥伦比亚 CR 哥斯达黎'
+                    +'加 CU 古巴 CV 佛得角 CY 塞浦路斯 CZ 捷克共和国 DE 德国 DJ 吉布提 DK 丹麦 DM 多米尼克'
+                    +'DO 多米尼加共和国 DZ 阿尔及利亚 EA 欧亚专利组织(EAPO) EC 厄瓜多尔 EE 爱沙尼亚 EG 埃'
+                    +'及 EH 西撒哈拉 EM 内部市场协调局(OHIM) EP 欧洲专利局(EPO) ER 厄立特里亚 ES 西班牙 ET 埃'
+                    +'塞俄比亚 FI 芬兰 FJ 斐济 FK 福克兰群岛(马尔维纳斯群岛) FO 法罗群岛 FR 法国 GA 加蓬 GB 英'
+                    +'国 GD 格林纳达 GH 加纳 GC 海湾地区阿拉伯国家合作委员会专利局(GCC) GE 格鲁吉亚 GI 直布罗'
+                    +'陀 GL 格陵兰 GM 冈比亚 GN 几内亚 GQ 赤道几内亚 GR 希腊 GS 南乔治亚和南三维治群岛 GT'
+                    +'危地马拉 GW 几内亚比绍 GY 圭亚那 HK 中华人民共和国香港特别行政区 HN 洪都拉斯 HR 克罗地'
+                    +'亚 HT 海地 HU 匈牙利  WO 世界知识产权组织国际局(WIPO) ID 印度尼西亚 IE 爱尔兰 IL 以色'
+                    +'列 IN 印度 IQ 伊拉克 IR 伊朗,伊斯兰共和国'
+                var regx = new RegExp("[A-Z]{2} ", "g")
+                var a = str.split(regx)
+                a.splice(0,1)
+                var b = str.match(regx)
+                b.forEach((item,index)=>{
+                    this.countryList.push({
+                        label:a[index],
+                        value:item
+                    })
+                })
+        },
+        changeComponent(val){
+            this.isComponent = val
+        },
+        search(val){
+            this.$router.push({
+                path: '/searchResult',
+                query: {
+                    condition:val,
+                    DBType:this.DBType,
+                    reportId:this.reportId?this.reportId:null,
+                    retrieveRecordId:null
+                }
+            })
+            // this.$s.setSession('retrieveRecordId',0)
+            // window.open(router.href, '_blank');
+        },
+        openHistory(){
+            // this.dialogVisible = true
+            // this.$nextTick(()=>{
+            //     this.$refs.searchHistory.open()
+            // })
+            const router = this.$router.resolve({
+                path: '/searchHistory',
+            })
+            window.open(router.href, '_blank');
+        },
+
+    },
+}
+</script>
+<style lang="scss" scoped>
+.head{
+    background: rgb(223 223 223);
+    line-height: 50px;
+    text-align: center;
+}
+.menu{
+    width:70%;
+    margin:0 auto;
+    position: relative;
+    .el-link{
+        margin-right: 20px; 
+    } 
+    .type{
+        position: absolute;
+        left:0;
+        top:0;
+    }
+    .icon{
+        
+        position: absolute;
+        right:0;
+        top:0;
+        i{
+            font-size:24px;
+        }
+    }
+}
+</style>

+ 504 - 0
RMS-FrontEnd/src/views/components/import/conditionImport/searchResult.vue

@@ -0,0 +1,504 @@
+<template>
+  <div style="background: white; height: 100%">
+    <el-container style="padding: 0 20px">
+      <el-header
+        class="workspace-content-container-header"
+        style="display: flex; justify-content: space-between"
+      >
+        <div>
+          <el-button-group class="margin-left_10">
+            <el-tooltip v-for="item in viewList" class="item" effect="dark" :content="item.title" placement="top">
+              <el-button @click="handleChangeView(item)" size="small" :type="viewSelected === item.value ? 'primary' : ''" :icon="item.btn"></el-button>
+            </el-tooltip>
+          </el-button-group>
+          <span v-if="selectedTotal>0" >
+            已勾选 <b>{{ selectedTotal }}</b> 条
+          </span>
+        </div>
+        
+        <div style="max-width:calc(100% - 620px)">
+          <p><span>条件:</span>{{ condition }}</p>
+        </div>
+        <div>
+          <el-button type="primary" size="small" @click="importToProject">导入到专题库</el-button>
+          <el-button size="small" type="warning" @click="handleFieldManage">显示栏位管理</el-button>
+          <el-popover placement="bottom" title="" width="220" trigger="click">
+            <el-main class="patent-fast-edit-popover" v-loading="selectNumberLoading">
+              <div class="btn" @click="handleSelectNumber(0)">本页选择</div>
+              <div class="btn" @click="handleSelectNumber(1)">全部选择</div>
+              <el-divider></el-divider>
+              <div class="select-number">
+                <span>从</span>
+                <el-input size="mini" v-model="queryParams.startNumber" @change="change1"></el-input>
+                <span>到</span>
+                <el-input size="mini" v-model="queryParams.endNumber" @change="change2"></el-input>
+                <el-button type="text" size="" @click="handleSelectNumber(2)">确定</el-button>
+              </div>
+            </el-main>
+            <el-button type="info" size="small" class="margin-left_10" slot="reference"> 选择专利<i class="el-icon-arrow-down el-icon--right"></i></el-button>
+          </el-popover>
+          <el-button type="text" size="small" class="margin-left_10" @click="handleCancelSelectNumber">取消选择</el-button>
+        </div>
+      </el-header>
+      <el-main id="patent-list-container" v-loading="loading">
+        <div>
+          <component
+            ref="patentViewList"
+            :is="viewSelected"
+            @select-change="handleSelect"
+            :selected.sync="queryParams.selected"
+            :patentNoList.sync="patentNoList"
+            :view-field="patentViewField"
+            @on-sort="handleSort"
+            @addSelect="getChoosePatentNo"
+          ></component>
+        </div>
+      </el-main>
+      <el-footer class="workspace-content-patent-page foot-total">
+        <span class="total">共{{ total }}条</span>
+        <el-pagination
+          background
+          layout="total, sizes, prev, pager, next, jumper"
+          :current-page.sync="queryParams.current"
+          :page-size.sync="queryParams.size"
+          :page-sizes="pageSizes"
+          :page-count="getPageCount()"
+          @current-change="handleCurrentChange"
+          @size-change="getList"
+        >
+        </el-pagination>
+      </el-footer>
+    </el-container>
+
+    <patent-view-field @reset="getPatentViewField(true)" @update="updatePatentViewField" ref="patentViewField"/>
+    <Project-List-Dialog ref="projectListDialog"></Project-List-Dialog>
+  </div>
+</template>
+
+<script>
+import PatentViewField from "../dialog/PatentViewField.vue";
+import PatentTableListView from "../view/Table";
+import PatentAbstractListView from "../view/Abstract";
+import PatentPictureListView from "../view/Picture";
+import ProjectListDialog from "./components/projectListDialog.vue";
+export default {
+  components: {
+    PatentViewField,
+    PatentTableListView,
+    PatentAbstractListView,
+    PatentPictureListView,
+    ProjectListDialog,
+  },
+  props: ["condition", "DBType",'reportId','retrieveRecordId'],
+  data() {
+    return {
+      pageSizes:[10, 20, 30, 40, 50],
+      viewSelected: "patent-table-list-view",
+      viewList: [
+        {
+          value: "patent-table-list-view",
+          title: "表格视图",
+          btn: "el-icon-tickets",
+        },
+        {
+          value: "patent-abstract-list-view",
+          title: "摘要视图",
+          btn: "el-icon-news",
+        },
+        {
+          value: "patent-picture-list-view",
+          title: "图片视图",
+          btn: "el-icon-picture-outline",
+        },
+      ],
+      patentNoList: [],
+      queryParams: {
+        selected: [],
+        current: 1,
+        size: 10,
+        isAdd: [],
+        isDelete: [],
+        OrderBy:"AD",
+        OrderByType:"DESC",
+        retrieveRecordId:this.retrieveRecordId
+      },
+      patentViewField: [],
+      tableData:[],
+      total: 0,
+      selectNumberLoading: false,
+      loading: false,
+      selectedTotal:0,
+      startNumber: 1,
+      endNumber: 0,
+      quickSelect: false,
+      quickSelectArr:[],
+    };
+  },
+  watch: {},
+  computed: {
+    records() {
+      return this.$store.state.patent.records;
+    },
+  },
+  created() {},
+  async mounted() {
+    // console.log(this.$s.getSession('queryParams'),this.queryParams)
+    if(this.$s.getSession('queryParams')&&this.$s.getSession('queryParams').params.retrieveRecordId){
+        this.queryParams.retrieveRecordId = this.$s.getSession('queryParams').params.retrieveRecordId
+      }
+    
+  await  this.getList();
+    this.getPatentViewField();
+  },
+  methods: {
+    //导入到专题库
+    importToProject() {
+      var form = {
+        conditions:this.condition,
+        DBType:this.DBType,
+        orderBy:this.queryParams.OrderBy,
+        orderByType:this.queryParams.OrderByType,
+        startNumber:this.selectedTotal>0?this.startNumber:1,
+        endNumber:this.selectedTotal>0?this.endNumber:this.total,
+        isAddPatentNos:this.queryParams.isAdd,
+        isDeletePatentNos:this.queryParams.isDelete,
+        reportId:this.reportId
+      }
+      this.$refs.projectListDialog.open(form);
+    },
+    //切换页数
+    async handleCurrentChange(val) {
+      this.queryParams.current = val;
+      this.patentNoList = []
+      await this.getList();
+      this.$nextTick(()=>{
+        if(this.quickSelect){
+          this.commonSwitch()
+        }else{
+          if(this.queryParams.isAdd.length>0){
+            this.getHaveChoose([])
+          }
+        }
+      })
+    },
+    //获取最大页数
+    getPageCount(){
+      var a = Math.ceil(Number(this.total)/Number(this.queryParams.size))
+      return a>200?200:a
+    },
+    //开始条数校验
+    change1(val) {
+      if (!isNaN(val)) {
+         if (!val || val <= 0) {
+          this.queryParams.startNumber=1
+        } else {
+          if (this.queryParams.startNumber>this.total) {
+            this.queryParams.startNumber=this.total
+          }
+        }
+      } else {
+        this.queryParams.startNumber=1
+      }
+    },
+     //结束条数校验
+    change2(val) {
+      if (!isNaN(val)) {
+        if (!val || val <= 0) {
+          this.queryParams.endNumber = this.total
+        } else {
+          if (this.queryParams.endNumber > this.total) {
+            this.queryParams.endNumber = this.total
+          }
+        }
+      }else {
+        this.queryParams.endNumber=this.total
+      }
+    },
+    //查询专利
+    async getList() {
+      let queryParams = JSON.parse(JSON.stringify(this.queryParams));
+
+      var params = {
+        CurrentQuery: this.condition, //检索式
+        DBType: this.DBType, //”CN”或”WD”,表示检索中文库或世界库
+        PageNum: this.queryParams.current, //页码(最多 200 页)
+        RowCount: this.queryParams.size, //每页返回条数(最多 50 条)
+        OrderBy: this.queryParams.OrderBy, //排序字段:“AD”,“PD”,“GD”, “ID”(检索引擎自生成字段,排序顺序固定)
+        OrderByType: this.queryParams.OrderByType, //排序方式:“ASC”,“DESC” 即正序倒序
+        retrieveRecordId:this.queryParams.retrieveRecordId
+      };
+      // console.log(this.$s.getSession('retrieveRecordId'),)
+      
+      queryParams.params = params;
+      queryParams.reportId = this.reportId
+      this.$store.commit("SET_PATENT_PARAMS", queryParams);
+      this.$store.commit("SET_PATENT_RECORDS", []);
+      this.loading = true;
+      await this.$api.patentSelectImport(params).then((response) => {
+          if (response.code == 200) {
+            this.total = response.data.total;
+            this.$set(this.queryParams,'startNumber',this.endNumber > 0 ? this.startNumber : 1)
+              this.$set(this.queryParams,'endNumber',this.endNumber > 0 ? this.endNumber : this.total)
+            let records = response.data.records;
+            this.tableData = records
+            params.retrieveRecordId = response.data.retrieveRecordId
+            this.queryParams.retrieveRecordId = response.data.retrieveRecordId
+            this.$store.commit("SET_PATENT_PARAMS", queryParams);
+            this.$s.setSession('queryParams',queryParams)
+            this.$store.commit("SET_PATENT_RECORDS", records);
+            this.loading = false;
+          }
+        })
+        .catch((error) => {
+          this.loading = false;
+        });
+        
+    },
+    handleSelect(data) {
+      // this.queryParams.selected = data
+    },
+    async handleChangeView(item) {
+      // console.log(item)
+      if(this.viewSelected==item.value){
+        return false
+      }
+      if(this.viewSelected!="patent-picture-list-view" && item.value!="patent-picture-list-view"){
+        this.queryParams.size = 10;
+        this.viewSelected = item.value;
+      }else if(this.viewSelected=="patent-picture-list-view" || item.value=="patent-picture-list-view"){
+        if (item.value === "patent-picture-list-view") {
+          this.$set(this.queryParams, "size", 20);
+        } else {
+          this.queryParams.size = 10;
+        }
+        this.viewSelected = item.value;
+        this.getList();
+      }
+return 
+
+      this.viewSelected = item.value;
+      if (this.viewSelected === "patent-picture-list-view") {
+        this.$set(this.queryParams, "size", 20);
+      } else {
+        this.queryParams.size = 10;
+      }
+      // await this.getPatentViewField();
+      this.getList();
+    },
+    async handleFieldManage() {
+      // await this.getPatentViewField()
+      this.$refs.patentViewField.open(
+        this.patentViewField,
+        this.queryParams.retrieveRecordId,
+        this.viewSelected
+      );
+    },
+    async getPatentViewField(refresh) {
+      var arr = ['标签','简单同族','Inpadoc同族','扩展同族','[标]权利人','[标]申请人','引用专利数量','被引用数量','权利要求数']
+      let params = {
+        project:this.queryParams.retrieveRecordId,
+        type: "list",
+        view: this.viewSelected,
+        refresh: refresh,
+      };
+      const { data } = await this.$api.getUserSettingField(params);
+      this.patentViewField = data.filter(item=>{ return arr.indexOf(item.name) == -1});
+    },
+    updatePatentViewField(data) {
+      this.patentViewField = data;
+    },
+    //快速选择
+    handleSelectNumber(type) {
+      switch (type) {
+        case 0: //本页选择
+          this.patentNoList = [...new Set(this.patentNoList.concat(this.$store.state.patent.records.map((item) => item.applicationNo))),];
+          this.queryParams.isAdd = [...new Set(this.queryParams.isAdd.concat(this.$store.state.patent.records.map((item) => item.applicationNo))),];
+          break;
+        case 1: //全部选择
+          this.startNumber = 1;
+          this.endNumber = this.total;
+          this.$set(this.queryParams,'startNumber',1)
+          this.$set(this.queryParams,'endNumber',this.total)
+        case 2: //范围选择
+          this.queryParams.isDelete = [];
+          this.queryParams.isAdd = [];
+          this.patentNoList = [];
+          this.quickSelect = true;
+          if (type == 2) {
+            if (!Number(this.queryParams.startNumber) ||!Number(this.queryParams.endNumber)) {
+              this.$set(this.queryParams,'startNumber',this.endNumber > 0 ? this.startNumber : 1)
+              this.$set(this.queryParams,'endNumber',this.endNumber > 0 ? this.endNumber : this.total)
+              break;
+            }
+            this.startNumber = this.queryParams.startNumber;
+            this.endNumber = this.queryParams.endNumber;
+          }
+          this.commonSwitch();
+          break;
+      }
+      this.getSelectedTotal()
+    },
+    //每页全部选择或范围选择的专利
+    commonSwitch() {
+      var arr = []
+      if (this.queryParams.size * this.queryParams.current >= this.startNumber) {
+        if (this.queryParams.size * this.queryParams.current >=this.endNumber) {
+          if (this.queryParams.size * (this.queryParams.current - 1) + 1 <=this.startNumber) {
+            var a =this.startNumber -(this.queryParams.size * (this.queryParams.current - 1) + 1);
+            var b =this.endNumber -(this.queryParams.size * (this.queryParams.current - 1) + 1);
+            for (var y = a; y <= b; y++) {
+              arr.push(this.tableData[y].applicationNo)
+            }
+          } else {
+            var a =this.queryParams.size * (this.queryParams.current - 1) +1 -(this.queryParams.size * (this.queryParams.current - 1) + 1);
+            var b = this.endNumber -(this.queryParams.size * (this.queryParams.current - 1) + 1);
+            for (var y = a; y <= b; y++) {
+              arr.push(this.tableData[y].applicationNo)
+            }
+          }
+        } else {
+          if (this.queryParams.size * (this.queryParams.current - 1) + 1 <=this.startNumber) {
+            var a =this.startNumber -(this.queryParams.size * (this.queryParams.current - 1) + 1);
+            var b =this.queryParams.size * this.queryParams.current -(this.queryParams.size * (this.queryParams.current - 1) + 1);
+            for (var y = a; y <= b; y++) {
+              arr.push(this.tableData[y].applicationNo)
+            }
+          } else {
+            var a =this.queryParams.size * (this.queryParams.current - 1) +1 -(this.queryParams.size * (this.queryParams.current - 1) + 1);
+            var b =this.queryParams.size * this.queryParams.current -(this.queryParams.size * (this.queryParams.current - 1) + 1);
+            for (var y = a; y <= b; y++) {
+              arr.push(this.tableData[y].applicationNo)
+            }
+          }
+        }
+      }
+      // this.patentNoList = JSON.parse(JSON.stringify(arr))
+      this.quickSelectArr = JSON.parse(JSON.stringify(arr))
+      this.getHaveChoose(arr)
+    },
+    //获取已选择的专利
+    getHaveChoose(arr){
+      var arr1 = [...new Set(arr.concat(this.queryParams.isAdd))]
+      this.patentNoList = arr1.filter((x) => this.queryParams.isDelete.indexOf(x)==-1)
+    },
+    //获取已选择的总条数
+    getSelectedTotal(){
+      this.selectedTotal = Number(this.endNumber) - Number(this.startNumber) + 1 + Number(this.queryParams.isAdd.length) - Number(this.queryParams.isDelete.length)
+    },
+    //获取手动选择的专利
+    getChoosePatentNo(patentNo){
+      if(this.quickSelect){
+        var index = this.queryParams.isDelete.findIndex(item=>{
+          return item == patentNo
+        })
+        if(index == -1){
+          var index2 = this.quickSelectArr.findIndex(item=>{
+            return item == patentNo
+          })
+          if(index2==-1){
+            this.setIsAdd(patentNo)
+          }else{
+            this.queryParams.isDelete.push(patentNo)
+          }
+        }else{
+          this.queryParams.isDelete.splice(index,1)
+        }
+      }else{
+        this.setIsAdd(patentNo)
+      }
+      this.getSelectedTotal()
+    },
+    //是否加入isAdd里面
+    setIsAdd(patentNo){
+      var index = this.queryParams.isAdd.findIndex(item=>{
+          return item == patentNo
+        })
+      if(index!=-1){
+        this.queryParams.isAdd.splice(index,1)
+      }else{
+        this.queryParams.isAdd.push(patentNo)
+      }
+    },
+    //取消选择
+    handleCancelSelectNumber() {
+        this.patentNoList = [];
+        this.queryParams.isAdd = []
+        this.queryParams.isDelete = []
+        this.startNumber = 1
+        this.queryParams.startNumber = 1
+        this.queryParams.endNumber = this.total
+        this.endNumber = 0
+        this.quickSelect = false
+        this.selectedTotal = 0
+      // this.getList()
+    },
+    //排序
+    handleSort(data) {
+      console.log(data);
+      const o = {
+        publicAccreditDate: "GD",
+        publicDate: "PD",
+        applicationDate: "AD",
+      };
+      this.queryParams.OrderBy = o[data.prop];
+      this.queryParams.OrderByType = data.order.toUpperCase();
+      this.getList();
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+.total{
+  margin-right: 10px;
+    font-weight: 400;
+    color: #606266;
+    display: inline-block;
+    font-size: 13px;
+    min-width: 35.5px;
+    height: 28px;
+    line-height: 28px;
+    vertical-align: top;
+    box-sizing: border-box;
+}
+.foot-total{
+  display: flex;
+  align-items: center;
+}
+.patent-fast-edit-popover {
+  padding: 0 !important;
+  .btn {
+    color: #000;
+    line-height: 40px;
+    border-radius: 5px;
+    padding-left: 10px;
+    text-align: left;
+    font-size: 14px;
+    cursor: pointer;
+    &:hover {
+      background: #adadad;
+      color: #fff;
+    }
+  }
+  .disabled {
+    cursor: not-allowed !important;
+  }
+  .bottom {
+    text-align: right;
+    color: #1e9fff;
+    line-height: 40px;
+    padding-left: 10px;
+    font-size: 18px;
+  }
+  .el-divider--horizontal {
+    margin: 10px 0 !important;
+  }
+  .select-number {
+    .el-input {
+      width: 70px;
+    }
+    span {
+      padding: 0 3px;
+    }
+  }
+}
+</style>

+ 41 - 0
RMS-FrontEnd/src/views/components/import/conditionImport/searchResultIndex.vue

@@ -0,0 +1,41 @@
+<template>
+  <div>
+    <search-Result :condition="condition"  :DBType="DBType" :reportId="reportId" :retrieveRecordId="retrieveRecordId"></search-Result>
+  </div>
+</template>
+
+<script>
+import searchResult from './searchResult.vue';
+export default {
+  components: {
+    searchResult
+  },
+  props: {},
+  data() {
+    return {
+    };
+  },
+  watch: {},
+  computed: {
+    condition(){
+        return this.$route.query.condition
+    },
+    DBType(){
+        return this.$route.query.DBType
+    },
+    reportId(){
+        return this.$route.query.reportId
+    },
+    retrieveRecordId(){
+      return this.$route.query.retrieveRecordId
+    }
+  },
+  methods: {},
+  created() {},
+  mounted() {
+    
+  }
+};
+</script>
+<style lang="scss" scoped>
+</style>

+ 178 - 0
RMS-FrontEnd/src/views/components/import/excelImport/importPatent.vue

@@ -0,0 +1,178 @@
+<template>
+    <div class="import-patent">
+    <el-container class="import-patent">
+      <el-aside class="import-patent-main" style="width:450px">
+        <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:300px;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>
+
+        
+      </el-aside>
+      <el-main>
+        <systemTask ref="systemTask" :form="1" :reportId="reportId"></systemTask>
+      </el-main>
+    </el-container>
+  </div>
+</template>
+
+<script>
+// import systemTask from './systemTask.vue'
+import systemTask from '@/views/components/task/index.vue'
+export default {
+  props:['reportId'],
+  components: {
+    systemTask
+  },
+  data() {
+    return {
+      form: {},
+      sourceId: '',
+      customField: [],
+      loading:false,
+    }
+  },
+  computed: {},
+  mounted() {
+    this.getCustomField()
+  },
+  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 {
+    overflow-x: hidden;
+    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>

+ 32 - 0
RMS-FrontEnd/src/views/components/import/excelImport/index.vue

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

BIN=BIN
RMS-FrontEnd/src/views/components/task/components/img/loading.gif


+ 90 - 0
RMS-FrontEnd/src/views/components/task/components/mixins.js

@@ -0,0 +1,90 @@
+import { downLoad2, getFileName } from "@/utils";
+import { cron } from "@/views/components/common/components/mixins";
+export const common = {
+    mixins:[cron],
+    props: ['form','reportId','tableHeight','review','webSocket'],
+    data() {
+        return {
+            // statusObj: {
+            //     0: '等待中',
+            //     1: '进行中',
+            //     2: '成功',
+            //     3: '失败',
+            //     4: '等待下一次执行',
+            //     5: '已取消',
+            //     6: '暂停',
+            //     7: '待取消',
+            //     8: '待暂停'
+            //   },
+            statusObj: {
+                0: '等待中',
+                1: '进行中',
+                2: '已完成',
+                4: '已暂停',
+                5: '已取消',
+            },
+            taskType:{
+                0: '普通任务',
+                1: '定时任务',
+            },
+            taskType2:{
+                1: 'Excel导入',
+                2: '导出',
+                3: '欧专局导入',
+                4: '专利之星导入',
+            },
+        }
+    },
+    computed: {
+        userinfo() {
+            return this.$store.state.admin.userinfo
+        }
+      },
+    watch:{
+        reportId(val){
+            this.queryParams.reportId = val
+            this.getList()
+        },
+        review(val){
+            if(val){
+                this.getList()
+            }
+        }
+    },
+    mounted() {
+        if(this.form == 1){
+            this.queryParams.taskType2 = '1'
+        }else if(this.form == 2){
+            this.queryParams.taskType2 = '2'
+        }
+    },
+    methods: {
+        handleDownload(row) {
+            downLoad2(row.url,row.id)
+        },
+         // 实时进度取消
+        cancel(row) {
+            let task = {
+                taskId: row.id,
+            // state:7,//7为待取消
+            }
+            this.$api.cancelTask(task).then(res => {
+            if (res.code==200) {
+                this.$message.success('任务已取消')
+                if(this.taskData){
+                    var index = this.taskData.findIndex(item=>{return item.id == row.id})
+                    if(index!=-1){
+                        this.taskData.splice(i,1)
+                    }
+                }else{
+                    row.status = 5
+                }
+                // this.getList()
+            }
+            }).catch(error => {
+            // this.$message.error(error.message)
+            this.loadingCancel=false
+            })
+        },
+    },
+}

+ 227 - 0
RMS-FrontEnd/src/views/components/task/components/realTime.vue

@@ -0,0 +1,227 @@
+<template>
+  <div style="padding:5px 10px;">
+    <el-table :data="taskData" border header-row-class-name="custom-table-header" :maxHeight="tableHeight - 150" v-loading="loadingCancel" element-loading-text = "请耐心等待,数据正在加载中...">
+            <el-table-column label="任务名称" prop="taskName" 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">
+                <div style="display:flex">
+                  <span style="width:100%"><el-progress :text-inside="true" :stroke-width="20" :percentage="scope.row.percentage?scope.row.percentage:Math.floor(Number(scope.row.successNum)/Number(scope.row.total)*100)" :color="customColors"></el-progress></span>
+                  <span ><span >{{ scope.row.successNum }}/</span><span>{{ scope.row.total }}</span></span>
+                </div>
+                
+              </template>
+            </el-table-column>
+            <el-table-column label="当前状态" align="center" min-width="100px" show-overflow-tooltip>
+              <template slot-scope="scope">
+                <span>{{ statusObj[scope.row.status] }}</span>
+              </template>
+            </el-table-column>
+       
+            <el-table-column label="操作" align="center" width="120" show-overflow-tooltip v-if="form === 2">
+                        <template slot-scope="scope">
+                          <div class="operate">
+                            <span v-if="!scope.row.url">等待中</span>
+                            <el-link v-else type="primary" @click.native="handleDownload(scope.row)">
+                              <el-tooltip class="item" effect="dark" content="下载" placement="top">
+                                <i class="iconfont icon-xiazai"></i>
+                              </el-tooltip>
+                            </el-link>
+                            <el-link class="margin-left_10" type="primary" @click="handleCancelZan(scope.row)" v-if="scope.row.status==4">
+                              <el-tooltip class="item" effect="dark" content="继续" placement="top">
+                                <i class="iconfont icon-zanting"></i> 
+                              </el-tooltip>
+                            </el-link>
+                            <el-link class="margin-left_10" type="primary" @click="handleCancelZan(scope.row)" v-if="scope.row.status==1">
+                              <el-tooltip class="item" effect="dark" content="暂停" placement="top">
+                                <i class="iconfont icon-zanting1"></i>
+                              </el-tooltip>
+                            </el-link>
+                          </div>
+                            
+                        </template>
+              </el-table-column> 
+          
+         
+                <el-table-column label="操作" align="center" width="150" show-overflow-tooltip v-else>
+                    <template slot-scope="scope">
+                      <div class="operate">
+                         <!-- <p v-if="scope.row.status!=5"> -->
+                        
+                        <el-link class="margin-left_10" type="primary"  @click="handleCancelZan(scope.row)" v-if="scope.row.status==4">
+                          <el-tooltip class="item" effect="dark" content="继续" placement="top">
+                            <i class="iconfont icon-zanting"></i> 
+                          </el-tooltip>
+                        </el-link>
+                        <!-- <span class="loadCss" type="danger" @click="handleCancelZan(scope.row)" v-else-if="scope.row.taskDetailState==8" >暂停中</span> -->
+                        <el-link class="margin-left_10" type="primary" @click="handleCancelZan(scope.row)" v-if="scope.row.status==1">
+                          <el-tooltip class="item" effect="dark" content="暂停" placement="top">
+                            <i class="iconfont icon-zanting1"></i>
+                          </el-tooltip>
+                        </el-link>
+                        <el-link class="margin-left_10" type="danger"  @click="cancel(scope.row)" v-if="scope.row.status!=2">
+                          <el-tooltip class="item" effect="dark" content="取消" placement="top">
+                            <i class="iconfont icon-quxiaorenwu1"></i> 
+                          </el-tooltip>
+                        </el-link>
+                        <!-- </p> -->
+                        <!-- <p class="margin-left_10" type="danger" v-else>已取消</p> -->
+                      </div>
+                       
+                    </template>
+                </el-table-column>
+          </el-table>
+  </div>
+</template>
+
+<script>
+import { common } from './mixins';
+export default {
+  components: {},
+  props: [],
+  mixins:[common],
+  data() {
+    return {
+      taskData:[],
+      loadingCancel:false,
+      customColors: [
+        {color: '#f56c6c', percentage: 20},
+        {color: '#e6a23c', percentage: 40},
+        {color: '#5cb87a', percentage: 60},
+        {color: '#1989fa', percentage: 80},
+        {color: '#6f7ad3', percentage: 100}
+      ],
+      queryParams:{
+        taskStatus:[0,1,4],
+        reportId:this.reportId?this.reportId:null
+      }
+    };
+  },
+  watch: {
+  },
+  computed: {
+    webSocket1(){
+      return this.webSocket
+    }
+  },
+  created() {},
+  mounted() {
+    this.initTask()
+    this.getList()
+  },
+  methods: {
+    initTask() {
+      var webSocket = this.webSocket1
+      webSocket.onmessage = (e) => {
+        const { code, data, message } = JSON.parse(e.data)
+        console.log({ code, data, message });
+        if (code === 903 || code === 904) {
+          const index = this.taskData.findIndex(item=>{return item.id == data.taskId})
+          // const index = this.taskData.findIndex(item=>{return item.id == data.id})
+          if (index === -1) {
+            if(data.reportId == this.reportId){
+              this.getList()
+            }
+            
+            // this.taskData.unshift(data)
+          } else {
+            var arr = this.taskData[index]
+            arr.index = data.index
+            arr.percentage = data.percentage
+            arr.successNum =  data.index
+            arr.status =  data.taskStatus
+            this.$set(this.taskData, index, arr)
+          }
+          if (data.complete) {
+            if(data.taskType!=2){
+              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(`导出任务完成`)
+            }
+            
+            // console.log(this.form)
+           
+            this.getList()
+          }
+        } else if (code === 803 || code === 804) {
+          this.$message.error(message)
+          this.getList()
+        }
+      }
+    },
+    getList(){
+      this.loadingCancel = true
+      this.$api.getTasks(this.queryParams).then(response=>{
+        if(response.code == 200){
+          this.taskData = response.data.records
+          this.loadingCancel = false
+        }
+      }).catch(error=>{
+        this.loadingCancel = false
+      })
+    },
+   
+    // 实时进度暂停继续
+    handleCancelZan(row) {
+      let task = {
+        taskId: row.id,
+        // state:0
+      }
+      if (row.status==4) {
+        //  task.state = 0
+         this.$api.resumeJobTask(task).then(res => {
+          if (res.code==200) {
+            this.$message.success('继续执行')
+              // this.getList()
+              row.status = res.data
+            }
+         }).catch(error => {
+            this.$message.error(error.message)
+            this.loadingCancel=false
+         })
+      } else if (row.status==1) {
+        // task.state = 8
+        this.$api.pauseJobTask(task).then(res => {
+          if (res.code==200) {
+            this.$message.success('已暂停')
+            // this.getList()
+            row.status = 4
+            }
+        }).catch(error => {
+          this.$message.error(error.message)
+          this.loadingCancel=false
+        })
+      }
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+.operate{
+  i{
+    font-size: 24px;
+  }
+}
+.pagination {
+    text-align: center;
+    margin: 20px 0;
+  }
+</style>

+ 366 - 0
RMS-FrontEnd/src/views/components/task/components/todoList.vue

@@ -0,0 +1,366 @@
+<template>
+  <div style="padding:5px 10px;">
+        <el-form inline>
+            <el-form-item  label="创建人">
+              <el-input v-model="queryParams.createName" size="small" placeholder="请输入创建人名称"></el-input>
+            </el-form-item>
+            <el-form-item  label="任务类型" v-if="form != 1 && form != 2">
+                <!-- <el-input v-model.trim="queryParams.taskType" size="small" placeholder="请输入任务类型"></el-input> -->
+                <el-select v-model="queryParams.taskType" size="small" clearable placeholder="请选择任务类型">
+                  <el-option
+                    v-for="item in Object.entries(taskType)"
+                    :key="item[0]"
+                    :label="item[1]"
+                    :value="item[0]">
+                  </el-option>
+                </el-select>
+            </el-form-item>
+            <el-form-item  label="导入类型" v-if="form != 1 && form != 2">
+                <!-- <el-input v-model.trim="queryParams.taskType" size="small" placeholder="请输入任务类型"></el-input> -->
+                <el-select v-model="queryParams.taskType2" size="small" clearable placeholder="请选择任务类型">
+                  <el-option
+                    v-for="item in Object.entries(taskType2)"
+                    :key="item[0]"
+                    :label="item[1]"
+                    :value="item[0]">
+                  </el-option>
+                </el-select>
+            </el-form-item>
+            <el-form-item>
+              <el-button  size="small" type="" @click="getList2">搜索</el-button>
+            </el-form-item>
+          </el-form>
+          <el-table v-loading="loading" :data="tableData" border header-row-class-name="custom-table-header" @sort-change="sortChange" :maxHeight="tableHeight - 220">
+            <el-table-column label="#" type="index" align="center" width="55">
+              <template slot-scope="scope">
+                <span>{{ (scope.$index + 1) + ((queryParams.current - 1) * queryParams.size) }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="任务名称" prop="taskName" align="center" show-overflow-tooltip></el-table-column>
+            <el-table-column  label="创建时间" prop="createTime" align="center" sortable="custom" show-overflow-tooltip>
+              <template slot-scope="scope">
+                <span>{{ scope.row.createTime }}</span>
+              </template>
+            </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>{{taskType2[ scope.row.type] }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column  label="任务类型" v-if="form !==1 && form !==2" align="center" show-overflow-tooltip>
+              <template slot-scope="scope">
+                <span v-if="scope.row.taskType">{{ taskType[ scope.row.taskType] }}</span>
+                <span v-else>普通任务</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="任务状态" align="center" show-overflow-tooltip>
+              <template slot-scope="scope">
+                <span v-if="scope.row.taskType == 1 && scope.row.status==2">等待下一次执行</span>
+                <span v-else>{{ statusObj[scope.row.status] }}</span>
+                <!-- <span v-else>{{ statusObj[scope.row.taskState] }}</span> -->
+              </template>
+            </el-table-column>
+            <el-table-column prop="createName" label="创建人" align="center" width="120" show-overflow-tooltip></el-table-column>
+            <el-table-column v-if="form !=1 && form !=2" label="定时周期" prop="dateType" align="center" show-overflow-tooltip>
+              <template slot-scope="scope">
+                <div>
+                <span v-if="scope.row.taskType == 1">{{dateType.find(item=> item.value == getType(scope.row.crons)).label }}</span> 
+                <span v-else></span> 
+                </div>
+              </template>
+            </el-table-column>
+            <!-- <el-table-column v-if="form==9 || form==8" label="定时时间" prop="dates" align="center" show-overflow-tooltip></el-table-column> -->
+            <el-table-column v-if="form!=1 && form!=2" label="最近更新时间" prop="modifiedTime" align="center" sortable="custom" show-overflow-tooltip>
+              <template slot-scope="scope">
+                <span>{{ $d(scope.row.modifiedTime) }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="导入情况" align="center"  show-overflow-tooltip>
+              <template slot-scope="scope">
+                <div class="log">
+                  <p>成功{{ scope.row.trueSuccessNum }}条</p>
+                  <p>失败{{ scope.row.defaultNum }}条</p>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column label="操作" align="center" width="150" show-overflow-tooltip>
+              <template slot-scope="scope" >
+                <div  class="operate">
+                  <el-link type="primary" @click.native="handleDownload(scope.row)" v-if="$permission('/workspace/common/taskDownload') && ((scope.row.type == 1 || scope.row.type == 2) && (scope.row.status !== 0 || scope.row.status !== 1))">
+                    <el-tooltip class="item" effect="dark" content="下载" placement="top">
+                      <i class="iconfont icon-xiazai"></i>
+                    </el-tooltip>  
+                  </el-link>
+                 
+                  <el-link class="margin-left_10" type="primary"  @click="handleSuspend(scope.row)" v-if="scope.row.status==1 || scope.row.status==4">
+                    <el-tooltip class="item" effect="dark" content="暂停" placement="top">
+                      <i class="iconfont icon-zanting1" v-if="scope.row.status==1"></i>
+                    </el-tooltip>
+                    <el-tooltip class="item" type="primary" effect="dark" content="继续" placement="top">
+                      <i class="iconfont icon-zanting" v-if="scope.row.status==4"></i> 
+                    </el-tooltip>
+                  </el-link>
+                  
+                  <el-link class="margin-left_10" type="primary"  v-if="scope.row.taskType == 1" @click="updateLog(scope.row)">
+                      <el-tooltip class="item" effect="dark" content="更新记录" placement="top">
+                        <i class="iconfont icon-banbengengxinjilu" style="font-size:18px"></i>
+                      </el-tooltip>
+                    </el-link>
+                    <el-link class="margin-left_10" type="danger" @click.native="cancel(scope.row)" v-if="(scope.row.status!=2 && scope.row.status!=5) || scope.row.taskType == 1" >
+                    <el-tooltip class="item" effect="dark" content="取消" placement="top">
+                      <i class="iconfont icon-quxiaorenwu1"></i>
+                    </el-tooltip> 
+                  </el-link>
+                </div>
+                <!-- <div v-else class="operate">
+                  <el-link class="margin-left_10"  type="danger" @click.native="handleDelete(scope.row)">
+                    <el-tooltip class="item" effect="dark" content="删除" placement="top">
+                      <i class="iconfont icon-shanchu"></i>
+                    </el-tooltip>
+                  </el-link>
+                  
+                  <el-link class="margin-left_10" type="primary"  @click="handleSuspend(scope.row)" v-if="scope.row.status==1 || scope.row.status==4">
+                    <el-tooltip class="item" effect="dark" content="暂停" placement="top">
+                      <i class="iconfont icon-zanting1" v-if="scope.row.status==1"></i>
+                    </el-tooltip>
+                    <el-tooltip class="item" effect="dark" content="继续" placement="top">
+                      <i class="iconfont icon-zanting" v-if="scope.row.status==4"></i> 
+                    </el-tooltip>
+                  </el-link>
+                  
+                    <el-link class="margin-left_10" type="primary"  v-if="scope.row.taskType == 1" @click="updateLog(scope.row)">
+                      <el-tooltip class="item" effect="dark" content="更新记录" placement="top">
+                        <i class="iconfont icon-banbengengxinjilu"></i>
+                      </el-tooltip>
+                    </el-link>
+                </div> -->
+              </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>
+
+          <updateLog ref="updateLog"></updateLog>
+        </div>
+</template>
+
+<script>
+import { common } from './mixins';
+import updateLog from "./updateLog.vue";
+export default {
+  components: {
+    updateLog
+  },
+
+  mixins:[common],
+  data() {
+    return {
+        loading:false,
+        tableData:[],
+        queryParams:{
+            current:1,
+            size:10,
+            createName:'',
+            taskStatus:[0,1,2,4,5],
+            reportId:this.reportId?this.reportId:null,
+            orderBy:'createTime',
+            orderType:'desc',
+        },
+        total:0,
+        options: [
+          {label:'普通任务',value:0},
+          {label:'定时任务',value:1},
+        ],
+        dateType: [
+          {label:'每天',value:'day'},
+          {label:'每周',value:'week'},
+          {label:'每月',value:'month'},
+          {label:'每年',value:'year'},
+        ],
+    };
+  },
+  watch: {},
+  created() {},
+  mounted() {
+    this.getList()
+  },
+  methods: {
+    getList2(){
+      this.queryParams.current = 1
+      this.getList()
+    },
+    getList(){
+      this.loading = true
+      this.$api.getTasks(this.queryParams).then(response=>{
+        if(response.code == 200){
+          this.tableData = response.data.records
+          this.total = response.data.total
+          this.loading = false
+        }
+      }).catch(error=>{
+        this.loading = false
+      })
+    },
+    handleCurrentChange(val) {
+      this.queryParams.current = val;
+      this.getList();
+    },
+    //排序
+    sortChange({ column, prop, order }) {
+      if (!order) {
+        return false
+      }
+      const o = {
+        'descending': 'desc',
+        'ascending': 'asc',
+      }
+      this.queryParams.orderBy = prop
+      this.queryParams.orderType = o[order]
+      this.getList()
+    },
+    //删除
+    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
+        })
+      })
+    },
+    // 网站导入表格操作按钮组
+    handleCommand(command,row) {
+      switch (command) {
+        case '1'://暂停/继续
+          this.handleSuspend(row)
+          break;
+        case '2'://删除
+          this.handleDelete(row)
+          break;
+        case '3'://取消定时
+          // this.handleTime(row)
+          break;
+        case '4'://更新日志
+          this.updateLog(row)
+          break;
+        default:
+          break;
+      }
+    },
+    handleClick(row){
+      this.handleDelete(row)
+    },
+    //更新日志
+    updateLog(row){
+      this.$refs.updateLog.open(row,this.webSocket)
+    },
+    // 网站导入暂停,继续任务操作
+    async handleSuspend(row) {
+      // console.log(this.pause);
+      if (row.status==1) {//暂停pauseJobTask
+       await this.$api.pauseJobTask({taskId: row.id}).then(res => {
+          if (res.code == 200) {
+            row.status==4
+            this.$message.success('已成功暂停该任务')
+            // console.log(this.pause);
+          }
+        })
+      } else if (row.status==4) {//继续
+       await this.$api.resumeJobTask({taskId: row.id}).then(res => {
+          if (res.code == 200) {
+            row.status==res.data
+            this.$message.success('继续执行该任务')
+          }
+        })
+      }
+      // this.$nextTick(() => {
+      //   this.getList()
+      // })
+    },
+    deletes(row) {
+      this.$confirm('确认删除本条数据吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+         this.$api.deleteTasks([row.id]).then(res => {
+          if (res.code == 200) {
+            if(res.data.length>0){
+              this.$message.error(`${res.data.length}条任务删除失败`)
+            }else{
+              this.$message.success('成功删除该任务')
+            }
+            
+            this.getList()
+          }
+        })
+      }).catch(err => {
+        this.$message.info('取消删除该任务')
+      })
+     
+    },
+
+  },
+};
+</script>
+<style lang="scss" scoped>
+.operate{
+  i{
+    font-size: 24px;
+  }
+}
+.log{
+  p{
+    margin-bottom: 0;
+  }
+}
+.loadCss::after{
+  content:'暂停中';
+  color: #F56C6C;
+  position: absolute;
+  left: 0;
+  top: 0;
+  overflow: hidden;
+  animation: loadName 1s linear infinite;
+}
+// .loadCss::before{
+//   content: '   ';
+//   position: absolute;
+//   left: 0;
+//   top: 0;
+//   overflow: hidden;
+// }
+.loadCss{
+  color: #ebeef5;
+  margin-left: 10px;
+  position: relative;
+}
+@keyframes loadName {
+  0%{
+    width: 0;
+  };
+  100%{
+    width: 100%;
+  }
+}
+</style>

+ 133 - 0
RMS-FrontEnd/src/views/components/task/components/updateLog.vue

@@ -0,0 +1,133 @@
+<template>
+  <div>
+    <el-dialog title="更新日志"
+      :visible.sync="visible"
+      width="1000px"
+      append-to-body
+      :before-close="close"
+      :close-on-click-modal="false">
+      <div style="height: 800px;overflow: auto;" infinite-scroll-immediate="false" v-infinite-scroll="load">
+         <el-timeline>
+          <el-timeline-item v-for="item in tableData" :timestamp="item.createTime" placement="top">
+            <el-card>
+              <p>状态:{{ statusObj[item.status] }}</p>
+              <p>总条数:{{ item.total  }} </p>
+              <p>成功数量:{{ item.trueSuccessNum }}</p>
+              <p>失败条数:{{ item.defaultNum }}</p>
+              <p>完成时间:{{ $d(item.endTime) }}</p>
+            </el-card>
+          </el-timeline-item>
+        </el-timeline>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { cron } from "@/views/components/common/components/mixins";
+export default {
+  mixins:[cron],
+  data() {
+    return {
+      tableData:[],
+      visible:false,
+      statusObj: {
+        0: '等待中',
+        1: '进行中',
+        2: '已完成',
+        4: '已暂停',
+        5: '已取消',
+      },
+      queryParams: {
+        taskId: '',
+        size: 10,
+        current: 0,
+        orderBy:'createTime',
+        orderType:'desc'
+      },
+      total: 1,
+    }
+  },
+  watch: {
+
+  },
+  mounted() {
+
+  },
+  methods: {
+    initTask(webSocket1) {
+      webSocket1.onmessage = (e) => {
+        const { code, data, message } = JSON.parse(e.data)
+        if (code === 903 || code === 904) {
+          if (this.tableData[0].id==data.id) {
+            var index=this.tableData[0]
+            if (index === -1) {
+              // this.taskData.push(data)
+            } else {
+              this.tableData[index].status = data.taskStatus
+              // this.$set(this.tableData, index, data)
+            }
+          }
+          // const index = this.taskData.findIndex(item=>{return item.id == data.id || item.taskId==data.taskId})
+          // const index = this.taskData.findIndex(item=>{return item.id == data.id})
+          // if (index === -1) {
+          //   // this.taskData.push(data)
+          // } else {
+          //   this.tableData[index].status = data.taskStatus
+          //   // this.$set(this.tableData, index, data)
+          // }
+          if (data.complete) {
+            this.tableData[0].status = 2
+            
+            // console.log(this.form)
+           
+            // this.getList()
+          }
+        } else if (code === 803 || code === 804) {
+          this.$message.error(message)
+          this.getList()
+        }
+      }
+    },
+    getList() {
+      this.$api.queryQrtzTaskLogs(this.queryParams).then(res => {
+        if (res.code == 200) {
+          this.total = res.data.total
+          if (res.data.records.length > 0) {
+            this.tableData= this.tableData.concat(res.data.records)
+          }
+        } 
+      })
+    },
+    open(row, webSocket1) {
+      this.queryParams.taskId = row.id
+      this.initTask(webSocket1)
+      this.load()
+      this.visible = true
+    },
+    // 懒加载
+    load() {
+      if (this.total > this.queryParams.current * this.queryParams.size) {
+        this.queryParams.current += 1
+        this.getList();
+      }
+      
+    },
+    close() {
+      this.total = 1
+      this.tableData = []
+      this.queryParams.current = 0
+      this.visible = false
+    }
+
+  },
+  
+}
+</script>
+
+<style lang="scss" scoped>
+.pagination {
+    text-align: center;
+    margin: 20px 0;
+  }
+</style>

+ 67 - 231
RMS-FrontEnd/src/views/components/task/index.vue

@@ -1,266 +1,102 @@
 <template>
-  <div class="system-task">
-    <el-container>
-      <el-header class="position_relative">
+   <div class="system-task">
         <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 v-model="activeName" type="card" @tab-click="handleClick">
+            <el-tab-pane label="实时进度" name="0"> 
+              <component :is='components' v-bind="$attrs" v-if="activeName == 0" :review="review" :tableHeight="height" :webSocket="webSocket"></component>
+            </el-tab-pane>
+            <el-tab-pane label="任务列表" name="1">
+              <component :is='components' v-bind="$attrs" v-if="activeName == 1" :review="review" :tableHeight="height" :webSocket="webSocket"></component>
+            </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">
-            <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></el-table-column>
-            <el-table-column label="当前条数" prop="index" align="center" show-overflow-tooltip></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" :color="customColors"></el-progress>
-              </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-form inline>
-            <el-form-item label="创建人">
-              <el-input v-model="queryParams.createUserName" size="small" placeholder="请输入创建人名称"></el-input>
-            </el-form-item>
-            <el-form-item>
-              <el-button size="small" type="" @click="getList">搜索</el-button>
-            </el-form-item>
-          </el-form>
-          <el-table v-loading="loading" :data="tableData" border header-row-class-name="custom-table-header">
-            <el-table-column v-if="form === 1" label="文件名称" prop="taskName" align="center" show-overflow-tooltip></el-table-column>
-            <el-table-column v-else label="#" type="index" align="center" width="55"></el-table-column>
-            <el-table-column label="开始时间" align="center" show-overflow-tooltip>
-              <template slot-scope="scope">
-                <span>{{ scope.row.createDate }}</span>
-              </template>
-            </el-table-column>
-            <el-table-column label="结束时间" align="center" show-overflow-tooltip>
-              <template slot-scope="scope">
-                <span>{{ scope.row.finishTime }}</span>
-              </template>
-            </el-table-column>
-            <el-table-column label="任务状态" align="center" show-overflow-tooltip>
-              <template slot-scope="scope">
-                <span>{{ statusObj[scope.row.state] }}</span>
-              </template>
-            </el-table-column>
-            <el-table-column prop="createUserName" 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";
-
+import realTime from './components/realTime.vue';
+import taskList from './components/todoList.vue';
 export default {
-  // props: {
-  //   form: Number,
-  // },
-  props:['form','reportId'],
+  components: {
+    realTime,
+    taskList
+  },
+  props: {},
   data() {
     return {
-      activeName: '0',
-      taskData: [],
-      loading: false,
-      total: 0,
-      tableData: [],
-      queryParams: {
-        // status: null,
-        state:0,
-        size: 10,
-        current: 1,
-        // projectName: '',
-        // type: 0,
-        // order: 'desc',
-        // createName: '',
-        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: '说明书导入',
-      }
-    }
+        activeName:0,
+        components:'realTime',
+        height:null,
+        review:false,
+        webSocket:''
+    };
   },
+  watch: {},
   computed: {
-    ...mapGetters(['webSocket', 'userinfo'])
-
-  },
-  watch:{
-    activeName(val){
-      if(val==1){
-        this.getList()
-      }else{
-        this.getQueueList()
-      }
-    },
+    userinfo() {
+        return this.$store.state.admin.userinfo
+    }
   },
+  created() {},
   mounted() {
-    // this.queryParams.type = this.form
-    // this.queryParams.reportId = this.reportId
-   this.getQueueList()
-    this.initTask()
-    
+    this.getHeight()
+    this.connectWebSocket()
   },
   methods: {
-    initTask() {
-      if(this.webSocket){
-      this.webSocket.onmessage = (e) => {
-        // console.log(e)
-        const { code, data, message } = JSON.parse(e.data)
-        // console.log(JSON.parse(e.data))
-        if (code === 903 || code === 904) {
-          const index = this.taskData.map(item => item.taskId).indexOf(data.taskId)
-          if (index === -1) {
-            // this.taskData.push(data)
-          } 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(`导出任务完成`)
-            }
-            
-            // console.log(this.form)
-           
-            this.getList()
-          }
-        } else if (code === 803 || code === 804) {
-          this.$message.error(message)
-          this.getList()
-        }
+    connectWebSocket() {
+      let webSocket = new WebSocket(`ws://${this.$c.hostname}:8877/api/report/api/ws/`+this.userinfo.id)
+      this.webSocket = webSocket
+      webSocket.onopen = () => {
+        console.log('WebSocket连接成功')
+      }
+      webSocket.onerror = () => {
+        console.log('WebSocket连接失败')
+      }
+      webSocket.onclose = () => {
+        console.log('WebSocket连接关闭')
       }
-    }
-    },
-    getQueueList() {
-      
-      this.taskData = []
-      this.queryParams.reportId = this.reportId
-      this.queryParams.state=0
-      this.$api.reImportTask(this.queryParams).then(response => {
-        response.data.records.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
-          })
-        })
-      })
-    },
-    handleDownload(row) {
-      downLoad2(row.filePath)
     },
-    handleDelete(row) {
-      this.$confirm('确认删除本条数据吗?', '提示', {
-        confirmButtonText: '确定',
-        cancelButtonText: '取消',
-        type: 'warning'
-      }).then(() => {
-        this.loading = true
-        this.$api.deleteImportTask({ id: row.id }).then(response => {
-          this.$message.success('删除成功')
-          this.loading = false
-          this.getList()
-        }).catch(error => {
-          this.loading = false
-        })
+    getQueueList(){
+      this.review = true
+      this.$nextTick(()=>{
+        this.review = false
       })
     },
-    handleCurrentChange(val) {
-      this.queryParams.current = val;
-      this.getList();
+    getHeight(){
+      this.height = document.getElementsByClassName('el-main')[0].clientHeight
     },
-    getList() {
-      this.loading = true
-      this.queryParams.state = 2
-      this.queryParams.reportId = this.reportId
-      this.$api.reImportTask(this.queryParams).then(response => {
-        this.tableData = response.data.records
-        this.total = response.data.total
-        this.loading = false
-      }).catch(error => {
-        this.loading = false
-      })
+    handleClick(){
+      var components= {
+        0:'realTime',
+        1:'taskList'
+      }
+      this.components = components[this.activeName]
+      // console.log(this.activeName)
     },
-  }
-}
+  },
+};
 </script>
-
-<style lang="scss">
+<style lang="scss" scoped>
 .system-task {
   height: 100%;
-  .system-task-main {
-    background: #fff;
-    padding: 5px 20px;
-    margin-top: 20px;
-  }
+  background: #fff;
+  padding: 10px;
   .header-tabs {
-    position: absolute;
-    bottom: 0;
+    // position: absolute;
+    // bottom: 0;
     height: 100%;
     padding-right: 9px;
-    left: 12px;
-    .el-tabs {
-      margin-top: 19px;
-    }
+    // left: 12px;
+    // .el-tabs {
+    //   margin-top: 19px;
+    // }
     .el-tabs__header {
       margin-bottom: 0 !important;
     }
   }
-  .pagination {
-    text-align: center;
-    margin: 20px 0;
-  }
+ 
 }
+
 </style>

+ 775 - 0
RMS-FrontEnd/src/views/components/task/index1.vue

@@ -0,0 +1,775 @@
+<template>
+  <div class="system-task">
+    <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-column v-if="form === 9 || form === 8" label="操作" align="center" width="150" show-overflow-tooltip>
+              <template slot-scope="scope">
+                <p v-if="scope.row.taskDetailState!=5">
+                  <el-link class="margin-left_10" type="danger"  @click="cancel(scope.row)">取消</el-link>
+                  <el-link class="margin-left_10" type="danger" @click="handleCancelZan(scope.row)" v-if="scope.row.taskDetailState==6">继续</el-link>
+                  <span class="loadCss" type="danger" @click="handleCancelZan(scope.row)" v-else-if="scope.row.taskDetailState==8" >暂停中</span>
+                  <el-link class="margin-left_10" type="danger" @click="handleCancelZan(scope.row)" v-else>暂停</el-link>
+                </p>
+                <p class="margin-left_10" type="danger" v-else>已取消</p>
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+        <div v-else key="task2">
+          <el-form inline v-if="form!=9">
+            <el-form-item  label="创建人">
+              <el-input v-model="queryParams.createName" size="small" placeholder="请输入创建人名称"></el-input>
+            </el-form-item>
+            <!-- <el-form-item v-else label="任务类型">
+                <el-input v-model.trim="queryParams.taskType" size="small" placeholder="请输入任务类型"></el-input>
+                <el-select v-model="queryParams.taskType" size="small" clearable placeholder="请选择任务类型">
+                  <el-option
+                    v-for="item in options"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value">
+                  </el-option>
+                </el-select>
+            </el-form-item> -->
+            <el-form-item>
+              <el-button  size="small" type="" @click="getList2">搜索</el-button>
+            </el-form-item>
+          </el-form>
+          <el-table v-loading="loading" :data="tableData" border header-row-class-name="custom-table-header" @sort-change="sortChange">
+            <el-table-column v-if="form === 1" label="文件名称" prop="oldName" align="center" show-overflow-tooltip></el-table-column>
+            <el-table-column v-else label="#" type="index" align="center" width="55">
+              <template slot-scope="scope">
+                <span>{{ (scope.$index + 1) + ((queryParams.current - 1) * queryParams.size) }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column v-if="form!=9 && form!=8" label="开始时间" align="center" show-overflow-tooltip>
+              <template slot-scope="scope">
+                <span >{{ $d(scope.row.startTime) }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column v-if="form!=9 && form!=8" label="结束时间" align="center" show-overflow-tooltip>
+              <template slot-scope="scope">
+                <span>{{ $d(scope.row.endTime) }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column v-else label="创建时间" prop="createTime" align="center" sortable="custom" show-overflow-tooltip>
+              <template slot-scope="scope">
+                <span>{{ scope.row.createTime }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column v-if="form==9 || form==8" label="任务类型" align="center" show-overflow-tooltip>
+              <template slot-scope="scope">
+                <span>{{ scope.row.taskType==1?'定时任务':'普通任务' }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="任务状态" align="center" show-overflow-tooltip>
+              <template slot-scope="scope">
+                <span v-if="form!=9 && form!=8">{{ statusObj[scope.row.status] }}</span>
+                <span v-else>{{ statusObj[scope.row.taskState] }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column prop="createName" label="创建人" align="center" width="120" show-overflow-tooltip></el-table-column>
+            <el-table-column v-if="form==9 || form==8" label="定时周期" prop="dateType" align="center" show-overflow-tooltip>
+            <template slot-scope="scope">
+              <div>
+               <span v-if="scope.row.taskType == 1">{{dateType.find(item=> item.value == getType(scope.row.crons)).label }}</span> 
+               <span v-else></span> 
+              </div>
+            </template>
+            </el-table-column>
+            <!-- <el-table-column v-if="form==9 || form==8" label="定时时间" prop="dates" align="center" show-overflow-tooltip></el-table-column> -->
+            <el-table-column v-if="form==9 || form==8" label="最近更新时间" prop="modifiedTime" align="center" sortable="custom" show-overflow-tooltip></el-table-column>
+            <el-table-column v-if="form!=9 && form!=8" 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)" v-if="$permission('/workspace/common/taskDownload')">下载</el-link>
+                <el-link class="margin-left_10" type="danger" @click.native="handleDelete(scope.row)" v-if="$permission('/workspace/common/delete')">删除</el-link>
+              </template>
+            </el-table-column>
+            <el-table-column v-else label="操作" align="center" width="150" show-overflow-tooltip>
+              <template slot-scope="scope">
+                <div>
+                  <el-dropdown v-if="scope.row.taskType == 1" split-button type="primary" size="small" @command="handleCommand($event,scope.row)" @click="handleClick(scope.row)">
+                    <p>编辑</p>
+                    <el-dropdown-menu slot="dropdown">
+                      <el-dropdown-item command="1">{{ pause==0?'暂停任务':'继续任务' }} </el-dropdown-item>
+                      <!-- <el-dropdown-item command="1">暂停任务 </el-dropdown-item> -->
+                      <el-dropdown-item command="2">删除任务</el-dropdown-item>
+                      <!-- <el-dropdown-item command="3">取消</el-dropdown-item> -->
+                      <el-dropdown-item command="4">更新记录</el-dropdown-item>
+                    </el-dropdown-menu>
+                  </el-dropdown>
+                  <el-dropdown v-else split-button type="primary" size="small" @command="handleCommand($event,scope.row)" @click="deletes(scope.row)">
+                    <p>删除</p>
+                    <el-dropdown-menu slot="dropdown">
+                      <el-dropdown-item command="4">更新记录</el-dropdown-item>
+                    </el-dropdown-menu>
+                  </el-dropdown>
+                  <!-- <el-link class="margin-left_10" type="danger" @click="deletes(scope.row)" v-if="scope.row.taskType!=1">删除</el-link> -->
+                </div>
+              </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>
+    <el-dialog title="编辑"
+      :visible.sync="visible"
+      width="600px"
+      :before-close="close"
+      append-to-body
+      :close-on-click-modal="false">
+        <el-form :model="forms" :rules="rules" ref="forms" label-width="100px">
+          <el-form-item label="来源网站" prop="configId">
+              <el-select v-model="forms.configId" placeholder="请选择网站" style="width: 100%;">
+                  <el-option v-for="item in website"
+                    :key="item.id"
+                    :label="item.webName"
+                    :value="item.id">
+                  </el-option>
+              </el-select>
+            </el-form-item>
+            <el-form-item label="下载内容" prop="configCells">
+              <el-select v-model="forms.configCells"  multiple collapse-tags placeholder="请选择下载内容" style="width: 100%;">
+                  <el-option v-for="item in download"
+                    :key="item.id"
+                    :label="item.cellName"
+                    :value="item.id">
+                  </el-option>
+              </el-select>
+            </el-form-item>
+            <el-form-item label="是否更新" prop="taskType">
+              <el-switch v-model="forms.taskType" @change="changeTaskType" :active-value="1" :inactive-value="0" active-color="#13ce66" inactive-color="#ff4949">  </el-switch>
+            </el-form-item>
+            <el-form-item label="更新间隔" v-if="forms.taskType==1" prop="dateType">
+                <el-select v-model="forms.dateType" @change="getDateType" clearable placeholder="请选择更新时间间隔" style="margin-right: 20px;width: 100%;">
+                  <el-option v-for="item in dateType"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value">
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            <el-form-item label="选择更新时间" v-show="forms.dateType">
+                <timeChoose :type="forms.dateType" @value="handleData" :cron="forms.crons" style="width:100%"></timeChoose>
+            </el-form-item>
+            <el-form-item label="检索信息">
+              <el-input v-model="forms.conditions" placeholder="请输入检索信息" type="textarea"></el-input>
+            </el-form-item>
+        </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="close">取 消</el-button>
+        <el-button type="primary" @click="sure">确 定</el-button>
+      </span>
+    </el-dialog>
+
+    <updateLog ref="updateLog"></updateLog>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from "vuex";
+import { downLoad2, getFileName } from "@/utils";
+import { cron } from "@/views/components/common/components/mixins";
+import timeChoose from "@/views/components/common/components/timeChoose.vue";
+import updateLog from "./components/updateLog.vue";
+
+export default {
+  mixins:[cron],
+  props: {
+    form: Number,
+    downloadId:String,
+    isGetList:Boolean,
+  },
+  components: {
+    timeChoose,
+    updateLog,
+  },
+  data() {
+    const dateTypeRule = (rule, value, callback) => {
+      if (this.forms.taskType == 1) {
+        if (value) {
+          callback()
+        } else {
+          callback(new Error('请选择更新周期'))
+        }
+      } else {
+        callback()
+      }
+    }
+    return {
+      activeName: '0',
+      taskData: [],
+      loading: false,
+      total: 0,
+      tableData: [],
+      queryParams: {
+        status: null,
+        size: 10,
+        current: 1,
+        projectName: '',
+        type: 0,
+        order: 'desc',
+        createName: '',
+        projectId: 0
+      },
+      statusObj: {
+        0: '等待中',
+        1: '进行中',
+        2: '成功',
+        3: '失败',
+        4: '等待下一次执行',
+        5: '已取消',
+        6: '暂停',
+        7: '待取消',
+        8: '待暂停'
+      },
+      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: '说明书导入',
+      },
+      visible:false,
+      loadingCancel:false,
+      options: [
+        {label:'普通任务',value:0},
+        {label:'定时任务',value:1},
+      ],
+      dateType: [
+        {label:'每天',value:'day'},
+        {label:'每周',value:'week'},
+        {label:'每月',value:'month'},
+        {label:'每年',value:'year'},
+      ],
+      website:[],
+      download:[],
+      forms:{},
+      pause:0,
+      rules: {
+        configId: [{ required: true, message: '请选择来源网站', trigger: 'change' },],
+        configCells: [{ required: true, message: '请选择下载内容', trigger: 'change' },],
+        taskType: [{ required: true, message: '请选择', trigger: 'change' },],
+        dateType: [{ required: true,  validator:dateTypeRule, trigger: 'change' },],
+      },
+      webSocket1: '',
+    }
+  },
+  computed: {
+    ...mapGetters(['webSocket', 'userinfo'])
+  },
+  watch: {
+    isGetList(val) {
+      this.getList2()
+    },
+  },
+  mounted() {
+    this.queryParams.type = this.form
+    this.queryParams.projectId = this.$route.query.id
+    // this.getList()
+    // console.log(this.downloadId);
+    
+   
+    if (this.form != 9) {
+      this.initTask()
+      this.getList()
+      this.getQueueList()
+    } else {
+      this.connectWebSocket(this.userinfo.id)
+      this.getTasks()//网站导入查询
+      this.getTaskDetails()//传入状态查询实时进度
+      this.getAllConfig()//请求全部网站
+    }
+    
+    
+  },
+  methods: {
+    connectWebSocket(userId) {
+      this.webSocket1 = new WebSocket(`ws://${this.$c.hostname}:8111/api/quartz/ws/` + userId)
+      // this.webSocket1 = new WebSocket(`ws://192.168.1.24:8111/api/quartz/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连接失败')
+        // var timer = setTimeout(() => {
+        //   for (var i = 0; i < 3; i++){
+        //     var state = this.connectWebSocket(this.userinfo.id)
+        //     if (state) {
+        //       clearTimeout(timer)
+        //     }
+        //     if (i == 2) {
+        //       clearTimeout(timer)
+        //     }
+        //   }
+        // },1000)
+      }
+      this.webSocket1.onclose = () => {
+        console.log('WebSocket连接关闭')
+        // var timer = setTimeout(() => {
+        //   for (var i = 0; i < 3; i++){
+        //     var state = this.connectWebSocket(this.userinfo.id)
+        //     if (state) {
+        //       clearTimeout(timer)
+        //     }
+        //     if (i == 2) {
+        //       clearTimeout(timer)
+        //     }
+        //   }
+        // },1000)
+      }
+    },
+    initTask(webSocket1) {
+      var webSocket = this.webSocket1?this.webSocket1:this.webSocket
+      webSocket.onmessage = (e) => {
+        const { code, data, message } = JSON.parse(e.data)
+        // console.log({ code, data, message });
+        if (code === 903 || code === 904) {
+          const index = this.taskData.findIndex(item=>{return item.id == data.id || item.taskId==data.taskId})
+          // const index = this.taskData.findIndex(item=>{return item.id == data.id})
+          if (index === -1) {
+            // this.taskData.push(data)
+          } 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 if (this.form==9) {
+             switch (data.taskDetailState) {
+              case '3':
+                this.$message.error(`导入任务失败`)
+                break;
+              case '2':
+                this.$message.success(`导入任务完成`)
+                break;
+              default:
+                break;
+             }
+            }else{
+              this.$message.success(`导出任务完成`)
+            }
+            
+            // console.log(this.form)
+           
+            this.getList2()
+          }
+        } else if (code === 803 || code === 804) {
+          this.$message.error(message)
+          this.getList2()
+        }
+      }
+    },
+    getQueueList() {
+      this.taskData = []
+      this.$api.getQueueList({ type: this.form, projectId: this.queryParams.projectId }).then(response => {
+        // console.log(response.data)
+        response.data.map(item => {
+          this.taskData.push({
+            projectId: item.projectId,
+            total: item.total,
+            index: 0,
+            taskId: item.id,
+            oldName: item.oldName,
+            complete: false,
+            url: '',
+            fileName: '',
+            taskType: item.type,
+            percentage: 0
+          })
+        })
+      })
+    },
+    handleDownload(row) {
+      downLoad2(row.url)
+    },
+    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
+        })
+      })
+    },
+    handleCurrentChange(val) {
+      this.queryParams.current = val;
+      this.getList2();
+    },
+    getList() {
+      this.loading = true
+      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
+      })
+    },
+    getList2() {
+      if (this.form!=9) {
+        this.getList()
+      } else {
+        // 网站导入查询按钮(当form为9网站导入,8为专利号导入)
+        this.getTasks()
+        this.getTaskDetails()//传入状态查询实时进度
+      }
+    },
+    // 网站导入暂停,继续任务操作
+    async handleSuspend(row) {
+      // console.log(this.pause);
+      if (this.pause==0) {//暂停pauseJobTask
+       await this.$api.pauseJobTask({taskId: row.id}).then(res => {
+          if (res.code == 200) {
+            this.pause=1
+            this.$message.success('已成功暂停该任务')
+            // console.log(this.pause);
+          }
+        })
+      } else {//继续
+       await this.$api.resumeJobTask({taskId: row.id}).then(res => {
+          if (res.code == 200) {
+            this.pause=0
+            this.$message.success('继续执行该任务')
+          }
+        })
+      }
+      this.$nextTick(() => {
+        this.getList2()
+      })
+      
+    },
+    // 网站导入表格操作编辑按钮
+    handleClick(row) {
+      this.forms = JSON.parse(JSON.stringify(row))
+      this.forms.dateType = this.getType(JSON.parse(JSON.stringify(row.crons)))
+      this.forms.configCells=this.forms.configCells.split(',').map(Number)
+      // console.log(this.forms);
+      this.downloads()
+      this.visible=true
+    },
+    // 网站导入表格操作按钮组
+    handleCommand(command,row) {
+      switch (command) {
+        case '1'://暂停/继续
+          this.handleSuspend(row)
+          break;
+        case '2'://删除
+          this.deletes(row)
+          break;
+        case '3'://取消定时
+          // this.handleTime(row)
+          break;
+        case '4'://更新日志
+          this.$refs.updateLog.open(row,this.userinfo.id,this.webSocket1)
+          break;
+        default:
+          break;
+      }
+    },
+    deletes(row) {
+      this.$confirm('确认删除本条数据吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+         this.$api.deleteTasks([row.id]).then(res => {
+          if (res.code == 200) {
+            if(res.data.length>0){
+              this.$message.error(`${res.data.length}条任务删除失败`)
+            }else{
+              this.$message.success('成功删除该任务')
+            }
+            
+            this.getList2()
+          }
+        })
+      }).catch(err => {
+        this.$message.info('取消删除该任务')
+      })
+     
+    },
+     // 请求全部网站
+     getAllConfig() {
+      this.$api.getAllConfig({}).then(res => {
+        if (res.code==200) {
+          this.website = res.data
+        }
+      })
+    },
+    // 请求当前网站可下载项
+    async downloads() {
+      let a= this.website.filter(item => {
+        return item.id==this.forms.configId
+      })
+      this.forms.configType = a[0].webType
+      await this.$api.getConfigCell({type:this.forms.configType}).then(res => {
+        if (res.code==200) {
+          this.download = res.data
+          this.forms.configCells=this.download.map(item=>{ return item.id })
+        }
+      })
+    },
+    // 实时进度取消
+    cancel(row) {
+      // console.log(row);
+      let task = {
+        taskId: row.id,
+        state:7,//7为待取消
+      }
+      // this.loadingCancel=true
+      this.$api.setDetailState(task).then(res => {
+        if (res.code==200) {
+          this.$message.success('任务已取消')
+          this.getList2()
+        }
+      }).catch(error => {
+        this.$message.error(error.message)
+        this.loadingCancel=false
+      })
+    },
+    // 实时进度暂停继续
+    handleCancelZan(row) {
+      // console.log(row);
+      // this.loadingCancel=true
+      let task = {
+        taskId: row.id,
+        // state:0
+      }
+      if (row.taskDetailState==6) {
+         task.state = 0
+         this.$api.setDetailState(task).then(res => {
+          if (res.code==200) {
+            this.$message.success('继续执行')
+              this.getList2()
+            }
+         }).catch(error => {
+            this.$message.error(error.message)
+            this.loadingCancel=false
+         })
+      } else {
+        task.state = 8
+        this.$api.setDetailState(task).then(res => {
+          if (res.code==200) {
+            this.$message.success('已暂停')
+            this.getList2()
+            }
+        }).catch(error => {
+          this.$message.error(error.message)
+          this.loadingCancel=false
+        })
+      }
+      // this.$nextTick(() => {
+      //   this.getList2()
+      // })
+    },
+    changeTaskType(val) {
+        this.forms.dateType=''
+        this.forms.conditions=''
+    },
+    //网站下载任务查询
+    getTasks() {
+      // this.tableData = []
+      this.loading=true
+      this.$api.getTasks(this.queryParams).then(response => {
+        // console.log(response.data)
+        this.tableData = response.data.records
+        this.total = response.data.total
+        this.loading=false
+      }).catch(error => {
+        this.loading = false
+      })
+    },
+    getTaskDetails() {
+      let queryParams = {
+        current: 1,
+        size: 10,
+        taskDetailStates: [0,1,6,8]//等待,进行,取消,暂停
+      }
+      this.$api.getTaskDetails(queryParams).then(res => { 
+        if (res.code==200) {
+          this.taskData=res.data.records
+          // this.total=res.data.total
+        }
+      })
+    },
+   
+    // 获取时间
+    handleData(val) {
+      if (this.forms.dateType=='') {
+        this.$message.error('请先选择更新周期')
+        return false
+      }
+      this.forms.crons=val
+    },
+    // 排序
+    sortChange({ column, prop, order }) {
+      if (!order) {
+        return false
+      }
+      const o = {
+        'descending': 'desc',
+        'ascending': 'asc',
+      }
+      this.queryParams.orderBy = prop
+      this.queryParams.orderType = o[order]
+      this.getList2()
+    },
+    sure() {
+      this.$refs.forms.validate((valid) => { 
+        let a= this.website.filter(item => {
+            return item.webType==this.forms.configType
+        })
+        this.forms.configId = a[0].id
+        if (valid) {
+          this.$api.updateTasks(this.forms).then(response => { 
+            if (response.code==200) {
+              this.$message.success('已成功编辑该任务')
+              this.getList2()
+              this.close()
+            }
+          })
+        }
+      })
+      
+     
+    },
+    close() {
+      this.visible=false
+    },
+    getDateType(val) {
+      // console.log(val)
+      this.forms.crons = ''
+    },
+  }
+}
+</script>
+
+<style lang="scss">
+.loadCss::after{
+  content:'暂停中';
+  color: #F56C6C;
+  position: absolute;
+  left: 0;
+  top: 0;
+  overflow: hidden;
+  animation: loadName 1s linear infinite;
+}
+// .loadCss::before{
+//   content: '   ';
+//   position: absolute;
+//   left: 0;
+//   top: 0;
+//   overflow: hidden;
+// }
+.loadCss{
+  color: #ebeef5;
+  margin-left: 10px;
+  position: relative;
+}
+@keyframes loadName {
+  0%{
+    width: 0;
+  };
+  100%{
+    width: 100%;
+  }
+}
+.system-task {
+  height: 100%;
+  .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>

+ 30 - 0
RMS-FrontEnd/src/views/components/task/taskIndex.vue

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

+ 318 - 0
RMS-FrontEnd/src/views/report/InvalidResponse/components/FileDetails/addOpinions.vue

@@ -0,0 +1,318 @@
+<template>
+  <div class="addOpinion">
+    <div >
+        <el-form ref="form" :model="form" inline label-width="100px">
+          <el-form-item label="无效理由:">
+            <el-select v-model="form.invalidName" placeholder="请选择" @change="changeInvalid" >
+              <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="form.invalidName==1?'说明书:':'权要:'" v-if="form.invalidName+''">
+            <div v-if="form.invalidName == 1">说明书</div>
+            <div v-else>
+              <el-select v-model="form.content" placeholder="请选择" @change="changeContent" >
+                <el-option
+                  v-for="item in rightList"
+                  :key="item.id"
+                  :label="'权要'+(item.content+1)"
+                  :value="item.id">
+                </el-option>
+              </el-select>
+              <span class="margin-left_10"><el-link type="primary" @click="show = !show">{{ show?'收起':'展开' }}</el-link></span>
+            </div>
+            
+          </el-form-item>
+          <!-- <el-form-item label="证据组合:" v-if="form.content+''">
+            <el-select v-model="form.proofGroups" placeholder="请选择" @change="changeProofGroups">
+              <el-option
+                v-for="item in proofGroups"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value">
+              </el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="证据:" v-if="form.proofGroups+''">
+            <el-select v-model="form.proofs" placeholder="请选择" @change="changeProofs">
+              <el-option
+                v-for="item in proofs"
+                :key="item.value"
+                :label="'D' + item.sort"
+                :value="item.id">
+              </el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="特征:" v-if="form.proofs+''">
+            <el-select v-model="form.features" placeholder="请选择">
+              <el-option
+                v-for="item in features"
+                :key="item.featureId"
+                :label="item.featureName"
+                :value="item.featureId">
+              </el-option>
+            </el-select>
+          </el-form-item> -->
+          <el-form-item >
+            <el-button type="primary" @click="addInvalid">无效理由和证据</el-button>
+          </el-form-item>
+        </el-form>
+    </div>
+    <div v-if="show">
+      <InvalidDetails :invalidReasonId="form.content" :reportId="reportId" :rightSort="rightSort"></InvalidDetails>
+    </div>
+    <div style="margin-left:20px">
+      <div style="display:flex;justify-content:space-between;align-items:center">
+        <p style="margin-top:0">陈述意见:</p>
+        <el-button type="primary" size="small" @click="submit">保存</el-button>
+      </div>
+      <myRich-Text placeholder="请输入陈述意见" v-model="argumentStr"></myRich-Text>
+    </div>
+
+    <el-dialog title="无效理由和证据" :visible.sync="visible" width="1200px" :before-close="close"> 
+      <div>
+        <InvalidIndex :reportId="reportId" :signPatentNo="signPatentNo"></InvalidIndex>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import InvalidIndex from '../InvalidIndex.vue'
+import InvalidDetails from '../InvalidDetails/InvalidDetails.vue';
+export default {
+  components: {
+    InvalidIndex,
+    InvalidDetails
+  },
+  mixins:[],
+  props: ['reportId','signPatentNo'],
+  data() {
+    return {
+      show:false,
+      rightSort:null,
+      visible:false,
+        form:{
+          invalidName:'',
+          content:'',
+          proofGroups:'',
+          proofs:'',
+          features:''
+        },
+        options:[],
+        argumentStr:'',
+        invalidList:[
+        {
+          id: 0,
+          label: '权利要求不清楚',
+          value: 0
+        },
+        {
+          id: 1,
+          label: '说明书公开不充分',
+          value: 1
+        },
+        {
+          id: 2,
+          label: '不具备创造性',
+          value: 2
+        },
+        {
+          id: 3,
+          label: '不具备新颖性',
+          value: 3
+        },
+      ],
+      rightList:[],
+      proofGroups:[],
+      proofs:[],
+      features:[]
+    };
+  },
+  watch: {
+    reportId(){
+        this.getInvalidReason()  
+    },
+  },
+  computed: {},
+  created() {},
+  mounted() {
+    if(this.reportId){
+       this.getInvalidReason() 
+    }
+    
+  },
+  methods: {
+    //更新陈述意见
+    submit(){
+      var params={
+        id:this.form.content,
+        argumentStr:this.argumentStr
+      }
+      this.$api.updateArgumentStr(params).then(response=>{
+        if(response.code == 200){
+          this.$message.success('陈述意见添加成功')
+        }
+      }).catch(error=>{
+        this.$message.error('陈述意见添加失败')
+      })
+    },
+    //打开无效理由和证据弹窗
+    addInvalid(){
+      this.visible = true
+    },
+    //关闭无效理由和证据弹窗
+    close(){
+      this.visible = false
+      this.getInvalidReason() 
+    },
+    //修改无效理由选项
+    changeInvalid(val){
+      this.form.content = ''
+      this.form.proofGroups = ''
+      this.form.proofs = ''
+      this.form.features = ''
+      this.argumentStr = ''
+      if(val==1){
+        return false
+      }
+        var rightList = this.options.filter(item=>{return item.invalidName == val})
+        this.rightList = rightList
+        this.rightSort = rightList[0].content
+        this.form.content = rightList[0].id
+        this.argumentStr = rightList[0].argumentStr || ''
+        // if(rightList.length>0){
+        //   this.rightList = [...new Set(rightList.map(item1=>item1.content))].map(item1=>{
+        //     return {
+        //       label : item1!=-1?('权要'+(item1+1)):'说明书',
+        //       value :item1
+        //     }
+        //     item1.
+        //     item1.value = item1
+        //     return item1
+        //   })
+        // }
+    },
+    //修改权要选项
+    changeContent(val){
+      var a = this.rightList.find(item=>{return item.id == val})
+      this.rightSort = a.content
+      this.argumentStr = a.argumentStr || ''
+      // this.form.proofGroups = ''
+      // this.form.proofs = ''
+      // this.form.features = ''
+      //   if(val == -1 ){
+      //     return false
+      //   }
+      //   this.proofGroups = []
+      // var proofGroups = this.options.filter(item=>{return item.invalidName = this.form.invalidName && item.content == val})
+      // if(proofGroups.length>0){
+      //   proofGroups.forEach(item=>{
+      //     item.proofGroups.forEach(item1=>{
+      //       item1.label = item1.proofs.map(i=>'D'+i.sort).join('+')
+      //       item1.value = item1.proofs.map(i=>'D'+i.sort).join('+')
+      //       this.proofGroups.push(item1)
+      //     })
+      //   })
+      // }
+    },
+    //修改证据组合选项
+    changeProofGroups(val){
+      this.form.proofs = ''
+      this.form.features = ''
+      this.proofs = this.proofGroups.find(item=>{return item.value == val}).proofs
+
+    },
+    //修改证据选项
+    changeProofs(val){
+      this.form.features = ''
+      let params = {
+        reportId: this.reportId,
+        rightSort:this.form.content
+      }
+       this.$api.getFeatureList(params).then((res) => {
+        if (res.code == 200) {
+          this.$set(this,'features',res.data)
+        }
+      })
+    },
+    //获取无效理由和证据
+    async getInvalidReason() {
+      await this.$api.queryInvalidReason({reportId:this.reportId}).then((res) => {
+        if (res.code == 200) {
+          if(res.data){
+            this.options = res.data
+            // this.arrangeData(res.data)
+            // 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)
+            // })
+          }else{
+            this.options = []
+          }
+        }
+      })
+    },
+    //整理无效理由和证据数据
+    arrangeData(data){
+        var invalidList=[
+        {
+          id: 0,
+          label: '权利要求不清楚',
+          value: 0
+        },
+        {
+          id: 1,
+          label: '说明书公开不充分',
+          value: 1
+        },
+        {
+          id: 2,
+          label: '不具备创造性',
+          value: 2
+        },
+        {
+          id: 3,
+          label: '不具备新颖性',
+          value: 3
+        },
+      ]
+      invalidList.forEach(item=>{
+        var rightList = data.filter(item1=>{return item1.invalidName == item.value})
+        if(rightList.length>0){
+         
+          item.children = [...new Set(rightList.map(item1=>item1.content))].map(item1=>{
+            return {
+              label:item1 != -1?'权要'+item1:'说明书',
+              value:item1
+            }
+          })
+          if(item.children.length>0){
+            item.children.forEach(item1=>{
+              item1.children = rightList.filter(item2=>{return item2.content == item1.value}).map(item2=>{
+                if(item2.proofGroups>0){
+                  item2.proofGroups.forEach(i=>{
+                    
+                  })
+                }
+              })
+            })
+          }
+        }else{
+          item.children = []
+        }
+        
+      })
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+.addOpinion{
+    // display: flex;
+}
+</style>

+ 120 - 0
RMS-FrontEnd/src/views/report/InvalidResponse/components/FileDetails/fileDetails.vue

@@ -0,0 +1,120 @@
+<template>
+  <div >
+    <div v-if="!showEvidence">
+      <div>
+        <img src="@/assets/visual/fixed.png" width="20px" height="20px" @click="qx" v-if="fix===true" />
+          <img src="@/assets/visual/unfixed.png" width="20px" height="20px" @click="gd" v-if="fix===false"  />
+      </div>
+        <el-tabs v-model="activeName" @tab-click="handleClick">
+            <el-tab-pane label="标的专利" name="patent">
+                <ContrastIndex v-bind="$attrs" v-on="$listeners" :reportId="reportId" :evidenceFlieId="evidence.id" :evidence="evidence" @on-change='changefix' :publicNo="signPatentNo"  :signPatentNo="signPatentNo" :reportType="reportType" :showEvidence="!showEvidence"></ContrastIndex>
+            </el-tab-pane>
+            <el-tab-pane label="无效请求书" name="InvalidRequest">
+                <check-File ref="checkFile"></check-File>
+            </el-tab-pane>
+        </el-tabs>
+    </div>
+    <div v-else>
+       <ContrastIndex v-if="type == 1" v-bind="$attrs" v-on="$listeners" :reportId="reportId" :evidenceFlieId="evidence.id" :evidence="evidence" @on-change='changefix' :publicNo="evidence.proofConditions" :signPatentNo="signPatentNo" :reportType="reportType"></ContrastIndex> 
+       <check-File v-else ref="checkFile1"></check-File>
+    </div>
+    
+  </div>
+</template>
+
+<script>
+import ContrastIndex from '@/views/components/articles/ContrastIndex.vue';
+import checkFile from '@/views/report/InvalidResponse/components/checkFile.vue'
+export default {
+  components: {
+    ContrastIndex,
+    checkFile
+  },
+  props: ['isEvidence','evidence','reportId','signPatentNo','reportType'],
+  data() {
+    return {
+        activeName:'patent',
+        fix:false,
+        showEvidence:this.isEvidence,
+        type:1,
+        url:'',
+    };
+  },
+  watch: {
+    isEvidence(val){
+        if(!this.fix){
+            this.showEvidence = val
+        }
+    },
+    'evidence'(val){
+        if(!this.fix){
+            this.type = val.type
+            this.showEvidence = true
+            this.getDetails(val)
+        }
+    },
+  },
+  computed: {},
+  created() {
+    
+  },
+  mounted() {
+    // this.$nextTick(()=>{
+    //     if(this.evidence.id){
+    //         this.getDetails(this.evidence)
+    //     }
+    // })
+  },
+  methods: {
+    qx() {
+      this.fix = false
+
+    },
+    gd() {
+      this.fix = true
+    },  
+    //获取证据详情
+    getDetails(val){
+        // 1是文献2是非文献
+        if (val.type == 1) {
+            // this.getPatent(val.proofConditions)
+            // this.getPiZhuContrastList(val.proofConditions)
+        } else if (val.type == 2){
+            let url = `http://${this.$c.hostname}:8012/onlinePreview?url=` + btoa(encodeURIComponent(this.$p + val.proofConditions))
+            this.$nextTick(() => {
+                this.$refs.checkFile1.open(url)
+            })
+        }
+    },
+    //切换tab栏
+    handleClick(){
+        if(this.activeName == 'InvalidRequest'){
+            if (this.url) {
+            let url = `http://${this.$c.hostname}:8012/onlinePreview?url=` + btoa(encodeURIComponent(this.url))
+            this.$refs.checkFile.open(url)
+          } else {
+            var params = {
+              reportId: this.reportId,
+              type:1,
+            }
+            this.$api.queryInvalidProcess(params).then((res) => {
+              if (res.code==200) {
+                this.url = this.$p + res.data[0].reportFile.url
+                let url = `http://${this.$c.hostname}:8012/onlinePreview?url=` + btoa(encodeURIComponent(this.url))
+                this.$refs.checkFile.open(url)
+              }
+            }).catch((error) => {
+              
+            })
+          }
+        }
+    },
+    //是否定住
+    changefix(val){
+        this.fix = val
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+</style>

+ 258 - 0
RMS-FrontEnd/src/views/report/InvalidResponse/components/FileDetails/index.vue

@@ -0,0 +1,258 @@
+<template>
+    <div style="height:calc(100% - 50px)">
+        
+        <div style="background:white;display:flex; justify-content:flex-end;align-items: center;">
+            <!-- <el-button type="primary" size="small" @click="checkInvalid" style="margin-right:10px;height:32px;"> 查看无效请求书/标的专利 </el-button> -->
+            <el-button type="primary" size="small" @click="addOpinion" style="margin-right:10px;height:32px;"> 添加陈述意见 </el-button>
+            <el-switch
+                v-model="value"
+                :disabled="!$permission('/workspace/details/comparison')"
+                inactive-text="对比"
+                active-color="#00BFFF"
+                inactive-color="#D3D3D3">
+            </el-switch>
+            <div class="evidence" style="max-width: 300px;height: 50px;;overflow: auto;margin-left:10px">
+                <span style="margin-right:5px">
+                  <el-tooltip class="item" effect="dark" content="无效请求书/标的专利" placement="top">
+                    <el-link @click="checkInvalid" :type="evidence.id === -1 ? 'primary' : undefined">T</el-link>
+                  </el-tooltip>
+                </span>
+                <span v-for="item in EvidenceList" :key="item.sortStr" style="margin-right:5px">
+                  <el-tooltip class="item" effect="dark" :content="item.proofName" placement="top">
+                    <el-link @click="evidenceBtn(item)" :type="item.id === evidence.id ? 'primary' : undefined">{{ item.sortStr }}</el-link>
+                  </el-tooltip>
+                  
+                </span>
+            </div>
+        </div> 
+        <div class="box1" v-dragControllerDiv1 style="display:flex;flex-direction:column;width:100%;">
+          <div class="left1 fileDetails" style="width:100%;padding-bottom:10px" :style="{height:height}">
+            <div class="box" ref="box" v-dragControllerDiv :style="{height:'100%'}">
+              <div class="left" :style="{width:width}" v-loading="loading" style="height:100%"><!--左侧div内容-->
+                <FileDetails :isEvidence="isEvidence" style="overflow-y:auto;overflow-x: hidden;" :style="{height:'100%'}" :evidence="evidence" :reportId="params.reportId" :height="height" :signPatentNo="params.signPatentNo" :reportType="params.reportType" :type="params.reportType"></FileDetails>
+              </div>
+              <div class="resize" title="收缩侧边栏"   v-show="width!='100%'" style="height:100%">⋮</div>
+              <div class="mid" v-show="width!='100%'" :style="{width:width}" style="height:100%"><!--右侧div内容-->
+                <FileDetails :isEvidence="isEvidence" style="overflow-y:auto;overflow-x: hidden;" :style="{height:'100%'}" :evidence="evidence" :reportId="params.reportId" :height="height" :signPatentNo="params.signPatentNo" :reportType="params.reportType" :type="params.reportType"></FileDetails>
+              </div>
+            </div> 
+          </div>
+          <div class="resize2" title="收缩侧边栏" v-show="showPosition"><p><span>˙</span><span>˙</span><span>˙</span></p></div>
+          <div class="resize1" title="收缩侧边栏" v-show="false"><span>⋮</span></div>
+          <div class="mid1" v-show="showPosition" style="height:280px;border:1px solid #E4E7ED;margin:10px;overflow-y:auto;overflow-x: hidden;">
+            <addOpinion :reportId="params.reportId" :signPatentNo="params.signPatentNo"></addOpinion>
+          </div>
+          
+
+        </div>
+        
+
+  </div>
+</template>
+
+<script>
+import PatentDetail from './patentDetail.vue';
+import FileDetails from './fileDetails.vue';
+import addOpinion from './addOpinions.vue'
+export default {
+  components: {
+    PatentDetail,
+    FileDetails,
+    addOpinion
+  },
+  props: {},
+  data() {
+    return {
+        ban:0,
+        value: false,
+        width:'100%',
+        height:null,
+        applicationNo:this.$route.query.applicationNo || null,
+        patentNo:this.$route.query.patentNo || null,
+        FileVisible: false,
+        EvidenceList:[],
+        params:{},
+        evidence:{},//证据文献
+        // literatureType:1,//文献类型1是专利文献
+        loading:false,
+        isEvidence:true,
+        showPosition:false,
+    };
+  },
+  watch: {
+    value(val){
+      if(val==true){
+        this.width='50%'
+      }else{
+        this.width='100%'
+      }
+    },
+  },
+  computed: {
+    piZhuContrastList() {
+      return this.$store.state.report.piZhuContrastList
+    }
+  },
+  created() {
+    // var that = this
+    //监听指定DOM变化
+    // this.resizeObserver = new ResizeObserver(function( entries ) { 
+    //       entries.forEach((item, index) =>{ 
+    //         that.$set(that,'height',item.target.clientHeight)
+    //         // item.target.childNodes[0].style.height= item.target.clientHeight + 'px'
+    //         // console.log(item.target.childNodes)
+    //       }) 
+    //     })
+  },
+  mounted() {
+    this.params = this.$s.getSession('params')
+    
+    this.evidence.id = this.params.aid
+    
+    if(!this.evidence.id ||this.evidence.id == -1){
+        this.isEvidence = false
+    }else{
+      this.loading = true
+        this.queryScratchs()//获取陈述意见列表
+    }
+    this.getQueryProofList()//获取证据列表
+    this.$nextTick(()=>{
+        this.$set(this,'height',document.getElementsByClassName('el-main')[0].offsetHeight-60  + 'px')
+        this.addOpinion()
+     })
+  },
+  methods: {
+    //打开无效请求书/标的专利
+    async checkInvalid(){
+        this.isEvidence = false
+        this.evidence.id = -1
+        this.params.aid = -1
+        this.$s.setSession('params',this.params)
+        this.getPiZhuContrastList(this.params.signPatentNo)
+        await this.$router.push({
+        path: '/fileDetails/' + -1,
+      })
+    },
+    //打开陈述意见
+    addOpinion(){
+      this.showPosition = !this.showPosition 
+      if(this.showPosition){
+        // 监听dom
+        // this.resizeObserver.observe(document.getElementsByClassName('fileDetails')[0])
+        this.$set(this,'height',document.getElementsByClassName('el-main')[0].offsetHeight-260 + 'px')
+      }else{
+        // resizeObserver.disconnect()  
+        this.$set(this,'height',document.getElementsByClassName('el-main')[0].offsetHeight-60 + 'px')
+      }
+    },
+    // 查询划词陈述意见
+    queryScratchs() {
+      this.$api.queryScratchs({proofId:this.evidence.id}).then((res) => {
+        if (res.code == 200) {
+          this.$store.commit('SET_PATENT_OPINION_CONTRAST', res.data)
+        }
+      })
+    },
+     // 文献点击事件
+   async evidenceBtn(val) {
+    this.isEvidence = true
+      this.evidence = val
+    //   this.literatureType = val.type
+    //  this.evidenceFlieId = val.id
+     this.params.aid = val.id
+     this.$s.setSession('params',this.params)
+      this.loading = false
+      // 1是文献2是非文献
+     if (val.type == 1) {
+        // this.getPatent(val.proofConditions)
+        this.getPiZhuContrastList(val.proofConditions)
+      } else {
+        // let url = `http://${this.$c.hostname}:8012/onlinePreview?url=` + btoa(encodeURIComponent(this.$p + val.proofConditions))
+        // this.$nextTick(() => {
+        //   this.$refs.checkFile1.open(url)
+        // })
+     }
+      await this.$router.push({
+        path: '/fileDetails/' + val.id,
+      })
+    },
+    //查询证据文献
+    getQueryProofList() {
+      let params = {
+        reportId:this.params.reportId,
+        signPatentNo:this.params.signPatentNo,
+        size: 99,
+        current: 1,
+      }
+      this.$api.queryProof(params).then((res) => {
+        if (res.code==200) {
+          this.EvidenceList = res.data
+          var index = this.EvidenceList.findIndex(item => {
+            return item.id == this.evidence.id
+          })
+          if (index != -1) {
+            this.evidenceBtn(this.EvidenceList[index])
+          }
+        }
+      }).catch((error) => {
+        
+      })
+    },
+    //修改定住
+    changefix(){
+
+    },
+    //切换专利
+    async onChange(val){
+        this.applicationNo = val.applicationNo
+        this.patentNo = val.patentNo
+       
+        this.changePageTitle(val.publicNo,val.name)
+        this.getContrastList(val.patentNo)
+        await this.$router.push({
+          path: '/search/patentDetail',
+          query: {
+            applicationNo: val.applicationNo,
+            patentNo: val.patentNo,
+          }
+        })
+    },
+    // 查询批注
+    getPiZhuContrastList(val) {
+      if (val) {
+        var index = this.piZhuContrastList.findIndex(item => {
+          item.patentNo == val
+        })
+        if (index != -1) {
+          return false;
+        }
+      }
+      let params = {
+        patentNo: val,
+        id: this.params.reportId,
+        createFrom:2
+      }
+      this.$api.scratchWordsQuery(params).then(response => {
+        if (response.code==200) {
+          if (this.piZhuContrastList.length > 0) {
+             var a = this.piZhuContrastList.filter(item => {
+              return item.patentNo != params.patentNo
+             }).concat(response.data)
+          } else {
+             var a = response.data
+          }
+           this.$store.commit('SET_PATENT_PIZHU_CONTRAST', a)
+        }
+      })
+    },
+    //修改title
+    changePageTitle(publicNo,name) {
+      document.title = `${publicNo} ${name || ''}`
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+@import '@/assets/css/activeDiv.scss';
+
+</style>

+ 276 - 0
RMS-FrontEnd/src/views/report/InvalidResponse/components/FileDetails/patentDetail.vue

@@ -0,0 +1,276 @@
+<template>
+    <div>
+        <div class="patent-articles" >
+            <el-container v-loading="loading">
+                <el-container >
+                    <el-header class="patent-articles-title">
+                        <div class="patent-articles-title-box">
+                            <div style="position:relative">
+                                <img src="@/assets/visual/fixed.png" width="20px" height="20px" v-if="fix===true" @click="qx" style="position:absolute;top:5px;left:5px"/>
+                                <img src="@/assets/visual/unfixed.png" width="20px" height="20px" v-if="fix===false"  @click="gd" style="position:absolute;top:5px;left:5px"/>
+                                <div>
+                                    <span v-html="getViewDom(patent.publicNo)"></span>
+                                    <el-tag type="primary" effect="dark" size="mini" class="margin-left_10">{{ patent.simpleStatus }}</el-tag>
+                                </div>
+                                <div style="color: #6b6868; font-size: 15px;border-bottom: 1px solid #e6e6e6;padding-bottom: 5px;">
+                                    <span v-html="getViewDom2(patent, 'name')"></span>
+                                    <el-link v-if="projectId" type="primary" @click.native="handleChange(patent, 'name')" style="margin-left: 10px;margin-top: -3px;">
+                                        <span v-if="!patent.change">切换译文</span>
+                                        <span v-else>切换原文</span>
+                                    </el-link>
+                                </div>
+                            </div>
+                            <div  style="  position: relative;">
+                                <el-link v-for="item in menuList" :type="activeMenu === item.value ? 'primary' : undefined" v-if="!item.show" @click.native="handleSelect(item.value)">
+                                {{ item.label }}
+                                <!-- <span v-if="item.value == 'PatentImage'|| item.value=='PatentPDF'" @click.stop="ending(item.value)">
+                                    <el-popover
+                                        placement="right"
+                                        width="400"
+                                        trigger="click">
+                                        <el-radio v-for="(item, index) in positionList" :key="index" v-model="radio" @input="changePosition"  :label="item.value">{{item.label}}</el-radio>
+                                        <i class="el-icon-setting" slot="reference"></i>
+                                    </el-popover>
+                                    </span> -->
+                                </el-link>
+                            </div>
+                        </div>
+                    </el-header>
+                    <el-main class="patent-articles-content" style="padding-left:30px">
+                        <div class="patent-articles-content-left">
+                            <!-- <div class="dom1 box1" v-dragControllerDiv1 style="display:flex;width:100%">
+                                <div class="component left1" style="width:100%;overflow-y:auto;overflow-x: hidden;" :style="{height:height}"> -->
+                                    <component style="width:100%;height:100%" :is="componentName" :patent="patent" :patentNo="[patent.patentNo]" :domId="patent.patentNo + '1'"  :pdfType1="(patent.pdf && patent.pdf.length>0)?patent.pdf[0].type:2" @refresh="getPatent(applicationNo)"></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;overflow-y:auto;overflow-x: hidden;">
+                                    <component :is="activeMenu2" :patent="patent" :patent-id="patentId" :pdfType1="(patent.pdf && patent.pdf.length>0)?patent.pdf[0].type:2" :sign="true"></component>
+                                </div> -->
+                            <!-- </div> -->
+                        </div>
+                    </el-main>
+                </el-container>
+            </el-container>
+            <div class="content-main" style="padding-left:40px"></div>
+        </div>
+    </div>
+</template>
+
+<script>
+import { changeTranslation, patentKeywordsHighlight } from '@/views/components/common/mixins'
+
+import PatentField from '@/views/components/articles/components/PatentField'
+import PatentAnnotation from '@/views/components/articles/components/PatentAnnotation'
+import PatentBasic from "@/views/components/articles/components/PatentBasic"
+import PatentPDF from "@/views/components/articles/components/PatentPDF"
+import PatentImage from "@/views/components/articles/components/PatentImage"
+import PatentRight from "@/views/components/articles/components/PatentRight"
+import PatentInstruction from "@/views/components/articles/components/PatentInstruction"
+import PatentFamily from "@/views/components/articles/components/PatentFamily"
+import PatentStatus from "@/views/components/articles/components/PatentStatus"
+
+export default {
+  components: {
+    PatentField,
+    PatentAnnotation,
+    PatentBasic,
+    PatentPDF,
+    PatentImage,
+    PatentRight,
+    PatentFamily,
+    PatentStatus,
+    PatentInstruction,
+  },
+  props: ['applicationNo','projectId'],
+  mixins: [patentKeywordsHighlight, changeTranslation],
+  data() {
+    return {
+        radio:1,
+        height:null,
+        loading:false,
+        fix:false,
+        activeMenu: 'PatentBasic',
+        activeMenu2:'',
+        componentName: 'PatentBasic',
+        menuList: [
+            {
+                value: 'PatentBasic',
+                label: '基础信息'
+            },
+            {
+                value: 'PatentRight',
+                label: '权利要求'
+            },
+            {
+                value: 'PatentImage' ,
+                label:'附图'
+            },
+            {
+                value: 'PatentInstruction',
+                label: '说明书文本'
+            },
+            {
+                value: 'PatentFamily',
+                label: '同族专利'
+            },
+            {
+                value: 'PatentStatus',
+                label: '事务数据'
+            },
+            {
+                value: 'PatentPDF',
+                label: '说明书'
+            },
+        ],
+        positionList:[
+            {
+                label:'tab展示',
+                value:1
+            },
+            {
+                label:'上边展示',
+                value:2
+            },
+            {
+                label:'下边展示',
+                value:3
+            },
+            {
+                label:'左边展示',
+                value:4
+            },
+            {
+                label:'右边展示',
+                value:5
+            },
+        ],
+        patent:{},
+    };
+  },
+  watch: {
+    applicationNo(val){
+        if(this.fix!=true){
+          this.getPatent(val)
+        }
+    },
+    fix(val){
+        this.$emit('on-change',val)
+    },
+  },
+  computed: {},
+  created() {},
+  async mounted() {
+   await this.getPatent(this.applicationNo)
+   this.changePageTitle()
+  },
+  methods: {
+     //修改title
+     changePageTitle() {
+      document.title = `${this.patent.publicNo} ${this.patent.name || ''}`
+    },
+    //解除定住,可以切换
+    qx(){
+      this.fix=false
+    },
+    //定住不能切换
+    gd(){
+      this.fix=true
+    },
+    //切换显示内容
+    handleSelect(index) {
+    //   if(index == this.activeMenu2){
+    //     this.activeMenu2 = ''
+    //     this.radio = 1
+    //     this.changePosition(this.radio)
+    //   }
+      this.activeMenu = index
+      this.componentName = index
+    },
+    //获取专利信息
+    async getPatent(applicationNo){
+        var params =this.$s.getSession('params').params
+        params.CurrentQuery = "(AN="+ applicationNo +")"
+        params.PageNum = 1
+        // params.retrieveRecordId = null
+        this.loading = true
+       await this.$api.patentSelectImport(params).then(response=>{
+          if(response.code == 200){
+            this.patent = response.data.records[0]
+            this.loading = false
+          }
+        }).catch(error=>{
+          this.loading = false
+        })
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+.patent-articles {
+  width: 100%;
+  height: 100% !important;
+  padding: 0 !important;
+  .patent-articles-menu {
+
+  }
+  .el-menu-item.is-active {
+    background: #ecf5ff !important;
+    color: #409EFF!important;
+  }
+  .patent-articles-title {
+    padding: 0 !important;
+    height: 100px !important;
+    .el-link {
+      margin-right: 20px;
+    }
+    .patent-articles-title-box {
+      font-size: 20px;
+      width: 100%;
+      text-align: center;
+    }
+  }
+  .patent-articles-content {
+    background: #fff;
+    padding: 0;
+    height: 100%;
+    overflow: hidden;
+    .patent-articles-content-left {
+        width:100%;
+      float: left;
+      height: 100%;
+      overflow-y: auto;
+      overflow-x: hidden;
+      padding: 10px;
+    }
+    .patent-articles-content-right {
+      width: 300px;
+      border-left: 1px solid #e6e6e6;
+      float: right;
+      height: 100%;
+      .el-header {
+        height: 50px !important;
+        position: relative !important;
+      }
+      .el-main {
+        padding: 0 12px !important;
+      }
+      .el-container, .el-main {
+        height: 100%;
+      }
+      .patent-articles-option {
+        position: absolute;
+        bottom: 0;
+        height: 100%;
+        left: 50px;
+        .el-tabs {
+          margin-top: 9px;
+        }
+        .el-tabs__header {
+          margin-bottom: 0 !important;
+        }
+      }
+    }
+  }
+}
+</style>

+ 102 - 0
RMS-FrontEnd/src/views/report/InvalidResponse/components/InvalidDetails/InvalidDetails.vue

@@ -0,0 +1,102 @@
+<template>
+  <div style="padding:10px">
+    <div v-for="(item,index2) in InvalidDetails" :key="item.id">
+        <div>
+            <p>
+              <span>证据组合{{ index2+1 }}:</span><span v-for="(i,index) in item.proofs" :key="i.id">D{{ i.sort }} <span v-if="index<item.proofs.length-1">+</span> </span>
+              <span >
+                <i v-if="!item.show" class="iconfont icon-yanjing_xianshi" @click="changeShow(item)" style="font-size:20px"></i>
+                <i class="iconfont icon-yanjing_yincang" v-else @click="changeShow(item)" style="font-size:20px"></i>
+              </span>
+            </p>
+            <div style="display:flex;align-items:center" v-if="!item.show">
+              <p style="width:80px">陈述意见:</p>
+                <div  v-if="!item.editArgumentStr" >
+                  <span v-html="item.argumentStr"></span><span @click="editArgumentStr(item)"><el-link type="primary"><i class="iconfont icon-bianji" style="font-size:28px"></i></el-link></span>
+                </div>
+                <div v-else style="width:100%;display:flex;align-items:center">
+                  <myRich-Text style="width:100%" v-model="item.argumentStr" placeholder="请输入陈述意见"></myRich-Text>
+                  <el-button type="primary" class="margin-left_10" icon="el-icon-check" circle style="font-size:15px" @click="saveArgumentStr(item)"></el-button>
+                  <el-button type="primary" class="margin-left_10" icon="iconfont icon-fanhui" circle style="font-size:15px" @click="cancelArgumentStr(item)"></el-button>
+                  <!-- <span class="margin-left_10" @click="saveArgumentStr(item)"><el-link type="primary"><i class="el-icon-check" style="font-size:28px"></i></el-link></span> -->
+                </div>
+            </div>
+        </div>
+        <div v-if="!item.show">
+          <Table :tableData="item.proofDetails" @submit="submitInvalid"  v-bind="$attrs" v-on="$listeners" :proofs="item.proofs" :proofGroup="item"></Table>
+        </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import Table from './table.vue';
+export default {
+  components: {
+    Table
+  },
+  props: ['invalidReasonId'],
+  data() {
+    return {
+      InvalidDetails:[],
+    };
+  },
+  watch: {
+    invalidReasonId(){
+      this.queryDetailByInvalidId()
+    }
+  },
+  computed: {},
+  created() {},
+  mounted() {
+    this.queryDetailByInvalidId()
+    
+  },
+  methods: {
+    
+    //根据无效理由Id查询证据组合详情
+    queryDetailByInvalidId(){
+        this.$api.queryDetailByInvalidId({invalidReasonId:this.invalidReasonId}).then(response=>{
+            if(response.code == 200){
+                this.InvalidDetails = response.data
+            }
+        })
+    },
+   //修改是否展示详情
+   changeShow(row){
+    this.$set(row,'show',!row.show)
+   },
+   //编辑组合陈述意见
+   editArgumentStr(row){
+    this.$set(row,'editArgumentStr',!row.editArgumentStr)
+    this.$set(row,'argumentStr1',row.argumentStr)
+   },
+   //保存证据组合陈述意见
+   saveArgumentStr(row){
+    var params = {
+      ...row,
+    }
+    this.$api.updateProofGroup(params).then(response=>{
+      if(response.code == 200){
+        this.$message.success('陈述意见更新成功')
+        this.editArgumentStr(row)
+      }
+    }).catch(error=>{
+      this.$message.error('陈述意见更新失败')
+    })
+   },
+   //取消证据组合陈述意见
+   cancelArgumentStr(row){
+    this.$set(row,'editArgumentStr',!row.editArgumentStr)
+    this.$set(row,'argumentStr',row.argumentStr1)
+   },
+  //修改证据组合的无效证据
+    submitInvalid(){
+      this.queryDetailByInvalidId()
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+
+</style>

+ 105 - 0
RMS-FrontEnd/src/views/report/InvalidResponse/components/InvalidDetails/addInvalidDialog.vue

@@ -0,0 +1,105 @@
+<template>
+  <div>
+    <el-dialog title="添加特征" :visible.sync="visible" width="800px" :before-close="close" append-to-body>
+        <div>
+            <el-form :model="form" label-position="right" label-width="140px" >
+                <el-form-item label="所属权要:">
+                    <span>权要{{ form.rightId+1 }}</span>
+                </el-form-item>
+                <el-form-item label="证据文献:">
+                    <span>{{ form.proofSortStr }}</span>
+                </el-form-item>
+                <el-form-item label="所属特征:">
+                    <div class="selectButton">
+                        <el-select v-model="form.featureId" placeholder="请选择"  style="width:100%" :popperAppendToBody="false" >
+                            <el-option v-for="item in featureList" :key="item.featureId" :label="item.featureName" :value="item.featureId">
+                                <el-tooltip class="item" effect="dark" :content="item.content" placement="top">
+                                    <span>{{ item.featureName }}</span>
+                                </el-tooltip>
+                            </el-option>
+                        </el-select>
+                        <el-button @click.stop="addFeature( )" ><i class="el-icon-plus"></i></el-button>
+                    </div>
+                </el-form-item>
+                <el-form-item label="无效请求书理由:">
+                    <myRich-Text placeholder="请输入无效请求书理由" v-model="form.proofStr"></myRich-Text>
+                </el-form-item>
+                <el-form-item label="答辩意见:">
+                    <myRich-Text placeholder="请输入答辩意见" v-model="form.argumentStr"></myRich-Text>
+                </el-form-item>
+            </el-form>
+        </div>
+        <div slot="footer" class="dialog-footer">
+            <el-button @click="close">取 消</el-button>
+            <el-button type="primary" @click="submit">确 定</el-button>
+        </div>
+    </el-dialog>
+    <el-dialog title="添加特征" :visible.sync="addFeatureVisible" width="800px" :before-close="closeFeature" append-to-body>
+      <div>
+        <rightContent :reportId="form.reportId" ref="rightContent"></rightContent>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+// import { RichText1 } from '@/views/components/common/RichText/mixins';
+import rightContent from '../addFeatures/rightContent.vue'
+export default {
+  components: {
+    rightContent
+  },
+//   mixins:[RichText1],
+  props: ['featureList'],
+  data() {
+    return {
+        visible:false,
+        addFeatureVisible:false,
+        form:{},
+        rightDetails:{}
+    };
+  },
+  watch: {},
+  computed: {},
+  created() {},
+  mounted() {},
+  methods: {
+    open(form,right){
+        this.form = {...form,
+            proofStr:"",
+            argumentStr:"",
+         }
+        this.rightDetails = right
+        this.visible = true
+    },
+    closeFeature() {
+      this.addFeatureVisible = false
+      this.$emit('addFeature')
+    },
+    close(){
+        this.visible = false
+    },
+    submit(){
+        this.$api.addArguments(this.form).then(response=>{
+            if(response.code == 200){
+                this.$message.success('添加成功')
+                this.close()
+                this.$emit('submit',true)
+            }
+        })
+    },
+     //添加特征
+     addFeature() {
+      this.addFeatureVisible=true
+      this.$nextTick(()=>{
+        this.$refs.rightContent.open(this.rightDetails)
+    })
+    },
+  },
+};
+</script>
+<style lang="scss">
+  @import '@/assets/css/selectButton.scss';
+</style>
+<style lang="scss" scoped>
+</style>

+ 318 - 0
RMS-FrontEnd/src/views/report/InvalidResponse/components/InvalidDetails/table.vue

@@ -0,0 +1,318 @@
+<template>
+  <div>
+    <div style="margin-top: 20px; display: flex; justify-content: space-between">
+            <!-- <el-button @click="addInvalid" type="primary" size="small">添加/更新无效证据</el-button> -->
+            <el-dropdown @command="getProof">
+                <span class="el-dropdown-link">
+                    <el-button type="primary" size="small">
+                        添加/更新无效证据<i class="el-icon-arrow-down el-icon--right"></i>
+                    </el-button>
+                </span>
+                <el-dropdown-menu slot="dropdown">
+                    <el-dropdown-item v-for="item in proofs" :key="item.id" :command="item.id" >添加/更新<span style="color:#66b1ff">D{{item.sort}}</span>的无效证据</el-dropdown-item>
+                </el-dropdown-menu>
+            </el-dropdown>
+        </div>
+            <div>
+                <el-table v-if="refreshData" :data="tableData" ref="table" border maxHeight="400" v-loading="loading" style="min-width: 100%; margin-top: 20px;overflow:auto">
+                    <el-table-column prop="featureId" label="特征" align="center" width="300px">
+                        <template slot-scope="scope">
+                            <!-- <div class="selectButton" v-if="scope.row.edit">
+                                <el-select v-model="scope.row.featureId" placeholder="请选择"  style="width:100%">
+                                    <el-option v-for="feature in featureList" :key="feature.featureId" :label="feature.featureName" :value="feature.featureId" :disabled="tableData.findIndex(item1=>{return item1.featureId == feature.featureId})!=-1">
+                                    </el-option>
+                                </el-select>
+                                <el-button @click.stop="addFeature(scope.row)" ><i class="el-icon-plus"></i></el-button>
+                            </div> -->
+                            <div >
+                                <el-tooltip class="item" effect="dark" :content="scope.row.featureContent" placement="top">
+                                    <span>特征{{ scope.row.featuresOrder }}</span>
+                                </el-tooltip>
+                            </div>
+                        </template>
+                    </el-table-column>
+                    <el-table-column prop="sort" align="center" label="证据文献">
+                        <template slot-scope="scope">
+                            D{{ scope.row.sort }}
+                        </template>
+                    </el-table-column>
+                    <el-table-column prop="proofStr" align="center" label="无效请求书理由">
+                        <template slot-scope="scope">
+                            <!-- <myRich-Text placeholder="请输入无效请求书理由" v-model="scope.row.proofStr" v-if="scope.row.edit"></myRich-Text> -->
+                            <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="(item1, index) in scope.row.arguments" :key="index+'p'">
+                                    <myRich-Text placeholder="请输入答辩意见" v-model="item1.argumentStr" style="width:100%" v-if="scope.row.edit"></myRich-Text>
+                                    <div v-else v-html="item1.argumentStr"></div>
+                                </div>
+                            </div>
+
+                        </template>
+                    </el-table-column>
+                    <el-table-column align="center" label="操作">
+                        <template slot-scope="scope">
+                            <div v-if="!scope.row.edit">
+                                <span class="margin-left_10"><el-link type="primary" @click="editInvalid(scope.row,scope.$index)">编辑</el-link></span>
+                                <span class="margin-left_10"><el-link type="danger" @click="getProofId(scope.row)">删除</el-link></span>
+                            </div>
+                            <div v-else>
+                                <span class="margin-left_10"><el-link type="primary" @click="updateInvalid(scope.row,scope.$index)">保存</el-link></span>
+                                <span class="margin-left_10"><el-link type="danger" @click="cancelEdit(scope.row,scope.$index)">取消</el-link></span>
+                            </div>
+                        </template>
+                    </el-table-column>
+                </el-table>
+            </div>
+            <!-- <el-dialog title="选择证据文献" :visible.sync="visible" width="800px" append-to-body>
+                <div>
+                    <el-radio-group v-model="proofId" @input="getProof">
+                        <el-radio v-for="item in proofs" :key="item.id" :label="item.id">
+                            D{{item.sort}}
+                        </el-radio>
+                    </el-radio-group>
+                </div>
+            </el-dialog> -->
+            <!-- <addInvalidDialog ref="addInvalidDialog" :featureList="featureList" v-bind="$attrs" v-on="$listeners"></addInvalidDialog> -->
+            <el-dialog title="添加证据" :visible.sync="EvidenceVisible" width="1000px" :before-close="closeEvidence" custom-class="addInvalid" append-to-body>
+                <Invalid-Evidence ref="invalid" :reportId="reportId" :patentNo="patentNo" ></Invalid-Evidence>
+                <div slot="footer" class="dialog-footer">
+                    <el-button @click="closeEvidence">取 消</el-button>
+                    <el-button type="primary" @click="submitEvidence">确 定</el-button>
+                </div>
+            </el-dialog>
+  </div>
+</template>
+
+<script>
+import addInvalidDialog from "../InvalidDetails/addInvalidDialog.vue";
+import InvalidEvidence from '../InvalidEvidence.vue'
+export default {
+  components: {
+    addInvalidDialog,
+    InvalidEvidence
+  },
+  props: ['reportId','rightSort','tableData','proofs','patentNo','proofGroup','right'],
+  data() {
+    return {
+        loading:false,
+        row:[],
+        refreshData:true,
+        checkList:[],
+        featureList: [],//选择特征数组
+        proofId:'',//证据id
+        visible:false,
+        EvidenceVisible:false,
+        evidence:null,
+    };
+  },
+  watch: {
+    rightSort(){
+        this.getFeature()
+    }
+  },
+  computed: {},
+  created() {},
+  mounted() {
+    this.getFeature()
+  },
+  methods: {
+    //编辑无效证据
+    editInvalid(row,index){
+      if(row.arguments && row.arguments.length==0){
+        row.arguments.push({
+          argumentStr:''
+        })
+      }
+      this.tableData[index].oldData = JSON.parse(JSON.stringify(row))
+      this.$set(row,'edit',true)
+      this.refreshData = false
+      this.$nextTick(()=>{
+        this.refreshData = true
+      })
+      // row.edit = true
+    },
+    //取消编辑
+    cancelEdit(row,index){
+      this.tableData[index] = JSON.parse(JSON.stringify(row.oldData))
+      // this.$set(row,'edit',false)
+      this.refreshData = false
+      this.$nextTick(()=>{
+        this.refreshData = true
+      })
+    },
+    //更新无效证据
+    updateInvalid(row,index){
+      var params = {
+        reportId:this.reportId,
+        rightId:this.rightSort,
+        featureId:row.featureId,
+        proofId:row.proofId,
+        proofStrId:row.proofStrId,
+        proofStr:row.proofStr
+      }
+      if(row.arguments.length>0){
+        params.argumentId = row.arguments[0].id
+        params.argumentStr = row.arguments[0].argumentStr
+      }
+      this.$api.addArguments(params).then(response=>{
+        if(response.code == 200){
+          this.$message.success('更新成功')
+          row.oldData = null
+          this.$set(row,'edit',false)
+          this.tableData[index] = JSON.parse(JSON.stringify(row))
+          
+          this.refreshData = false
+          this.$nextTick(()=>{
+            this.refreshData = true
+          })
+        }
+      })
+    },
+    //获取需要删除的无效证据Id
+    getProofId(row){
+      this.$confirm('是否删除', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+            var proofStrIds = this.tableData.map(item=>{
+                if(item.sort == row.sort){
+                    return item.proofStrId
+                }
+            }).filter(item=>{
+                return item != row.proofStrId
+            })
+            var params = {
+                ...this.proofGroup,
+                compareFileId:row.proofId,
+                proofStrIds:proofStrIds
+            }
+            this.$api.updateProofGroup(params).then(response=>{
+                if(response.code == 200){
+                    this.$message.success('删除成功')
+                    var index = this.tableData.findIndex(item=>{
+                        return item.proofStrId == row.proofStrId
+                    })
+                    if(index!=-1){
+                        this.tableData.splice(index,1)
+                    }
+                }
+            }).catch(error=>{
+                this.$message.error('删除失败')
+            })
+        //   this.deletes([id])
+        }).catch(() => {          
+        });
+      
+    },
+    //删除无效证据
+    deletes(ids){
+      this.$api.deleteProofStr(ids).then(response=>{
+        if(response.code == 200){
+          this.$message.success('删除成功')
+          this.$emit('submit',true)
+        }
+      })
+    },
+
+    //关闭添加证据弹窗
+    closeEvidence() {
+      this.evidence.proofStrIds = []
+      this.EvidenceVisible = false
+    },
+    submitEvidence(){
+        var params = {
+            ...this.proofGroup,
+            compareFileId:this.evidence.id,
+            proofStrIds:this.evidence.proofStrIds
+        }
+        this.$api.updateProofGroup(params).then(response=>{
+            if(response.code == 200){
+                this.$message.success('更新成功')
+                this.EvidenceVisible = false
+                this.$emit('submit',true)
+            }
+        }).catch(error=>{
+            this.$message.error('更新失败')
+        })
+      
+    },
+    //获取证据详情并打开无效证据弹窗
+    getProof(val){
+        this.evidence = this.proofs.find(item=>{return item.id == val})
+        this.evidence.sortStr = 'D'+this.evidence.sort
+        this.$set(this.evidence,'proofStrIds',this.tableData.map(item=>{
+            if(item.sort == this.evidence.sort){
+                return item.proofStrId
+            }
+        }))
+        this.EvidenceVisible = true
+        this.$nextTick(() => {
+            this.$refs.invalid.open(this.evidence,this.right)
+        })
+    },
+    // 查已添加的特征
+    getFeature() {
+      let params = {
+        reportId: this.reportId,
+        rightSort:this.rightSort
+      }
+      this.$api.getFeatureList(params).then((res) => {
+        if (res.code==200) {
+          this.featureList=res.data
+        }
+      })
+    },
+    //打开添加新特征弹框
+    addFeature() {
+    //   this.addFeatureVisibe=true
+    },
+    //添加无效证据
+    addInvalid(){
+        this.proofId = ''
+        this.visible = true
+    //   var form = {
+    //     rightId:this.rightSort,
+    //     reportId:this.reportId
+    //   }
+    //   this.$refs.addInvalidDialog.open(form)
+    },
+  },
+};
+</script>
+<style lang="scss">
+.addInvalid .el-dialog__body{
+  padding-top:5px
+}
+</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>

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

@@ -0,0 +1,361 @@
+<template>
+  <div>
+    <div class="demo-input-suffix">
+     <!-- <p>标的专利:<el-link type="primary" @click="toPatentDetails(patentNo)">{{ patentNo }}</el-link></p>  -->
+     <p>所属证据:{{ evidence.sortStr }}</p>
+     <p>所属权要:权要{{ right+1 }}</p>
+    </div>
+    <div style="margin-top: 20px; display: flex; justify-content: space-between">
+        <el-button @click="addInvalid" type="primary" size="small">添加无效证据</el-button>
+    </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="proofStrId" label="#" align="center" width="200px">
+          <template slot-scope="scope">
+            <el-checkbox-group v-model="evidence.proofStrIds">
+              <el-checkbox :label="scope.row.proofStrId">
+                {{ scope.$index+1 }}
+                <!-- <el-tooltip class="item" effect="dark" :content="scope.row.rightContent" placement="top">
+                  <span>{{ scope.row.rightName }}</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">
+            <div v-if="scope.row.edit">
+                    <div class="selectButton">
+                      <el-select v-model="scope.row.featureId" placeholder="请选择"  style="width:100%" :popperAppendToBody="false" >
+                        <el-option v-for="item in featureList" :key="item.featureId" :label="item.featureName" :value="item.featureId" :disabled="tableData.findIndex(item1=>{return item1.featureId == item.featureId})!=-1">
+                          <el-tooltip class="item" effect="dark" :content="item.content" placement="top">
+                                    <span>{{ item.featureName }}</span>
+                                </el-tooltip>
+                        </el-option>
+                      </el-select>
+                      <el-button @click.stop="addFeature(scope.row)" ><i class="el-icon-plus"></i></el-button>
+                    </div>
+            </div>
+            <div v-else>
+              <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">
+            <myRich-Text placeholder="请输入无效请求书理由" v-model="scope.row.proofStr" v-if="scope.row.edit"></myRich-Text>
+            <div v-html="scope.row.proofStr" v-else></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">
+                <myRich-Text placeholder="请输入答辩意见" v-model="item.argumentStr" style="width:100%" v-if="scope.row.edit"></myRich-Text>
+                <div v-else v-html="item.argumentStr"></div>
+              </div>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column align="center" label="操作">
+          <template slot-scope="scope">
+            <div v-if="!scope.row.edit">
+              <span class="margin-left_10"><el-link type="primary" @click="editInvalid(scope.row,scope.$index)">编辑</el-link></span>
+              <span class="margin-left_10"><el-link type="danger" @click="getProofId(scope.row.proofStrId)">删除</el-link></span>
+            </div>
+            <div v-else>
+                <span class="margin-left_10"><el-link type="primary" @click="updateInvalid(scope.row,scope.$index)">保存</el-link></span>
+                <span class="margin-left_10"><el-link type="danger" @click="cancelEdit(scope.row,scope.$index)">取消</el-link></span>
+            </div>
+            
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <el-dialog title="添加特征" :visible.sync="addFeatureVisible" width="800px" :before-close="closeFeature" append-to-body>
+      <div>
+        <rightContent :reportId="reportId" ref="rightContent"></rightContent>
+      </div>
+    </el-dialog>
+    <addInvalidDialog ref="addInvalidDialog" @submit="submitInvalid" :featureList="featureList" @addFeature="getFeature(right)"></addInvalidDialog>
+  </div>
+</template>
+<script>
+import { explain1 } from "../../components/mixins";
+import { PatentDetails } from "@/views/components/common/mixins";
+import addInvalidDialog from "./InvalidDetails/addInvalidDialog.vue";
+import rightContent from './addFeatures/rightContent.vue'
+export default {
+  mixins: [explain1, PatentDetails],
+  props: ['patentNo','reportId'],
+  components: {
+    addInvalidDialog,
+    rightContent
+  },
+  data() {
+    return {
+      refreshData: true,
+      tableData: [],
+      btnLoading: false,
+      loading: false,
+      checkList: [],
+      mergeObj: {},
+      mergeArr: ['id', 'rightName'],//解释
+      featureList: [],//选择特征数组
+      featureName:'',
+      addFeatureVisible:false,
+      evidence:'',
+      right:null,
+      rightDetails:{}
+    };
+  },
+  watch: {
+  },
+  mounted() {
+  },
+  methods: {
+    //添加无效证据
+    addInvalid(){
+      var form = {
+        rightId:this.right,
+        proofId:this.evidence.id,
+        proofSortStr:this.evidence.sortStr,
+        reportId:this.reportId
+      }
+      this.$refs.addInvalidDialog.open(form,this.rightDetails)
+    },
+    submitInvalid(){
+      this.getPoofArguments(this.evidence,this.right)
+    },
+    //编辑无效证据
+    editInvalid(row,index){
+      if(row.arguments && row.arguments.length==0){
+        row.arguments.push({
+          argumentStr:''
+        })
+      }
+      this.tableData[index].oldData = JSON.parse(JSON.stringify(row))
+      this.$set(row,'edit',true)
+      this.refreshData = false
+      this.$nextTick(()=>{
+        this.refreshData = true
+      })
+      // row.edit = true
+    },
+    //取消编辑
+    cancelEdit(row,index){
+      this.tableData[index] = JSON.parse(JSON.stringify(row.oldData))
+      // this.$set(row,'edit',false)
+      this.refreshData = false
+      this.$nextTick(()=>{
+        this.refreshData = true
+      })
+    },
+    //更新无效证据
+    updateInvalid(row,index){
+      var params = {
+        reportId:this.reportId,
+        rightId:this.right,
+        featureId:row.featureId,
+        proofId:row.proofId,
+        proofStrId:row.proofStrId,
+        proofStr:row.proofStr
+      }
+      if(row.arguments.length>0){
+        params.argumentId = row.arguments[0].id
+        params.argumentStr = row.arguments[0].argumentStr
+      }
+      this.$api.addArguments(params).then(response=>{
+        if(response.code == 200){
+          this.$message.success('更新成功')
+          row.oldData = null
+          this.$set(row,'edit',false)
+          this.tableData[index] = JSON.parse(JSON.stringify(row))
+          
+          this.refreshData = false
+          this.$nextTick(()=>{
+            this.refreshData = true
+          })
+        }
+      })
+    },
+    //获取需要删除的无效证据Id
+    getProofId(id){
+      this.$confirm('是否删除', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          this.deletes([id])
+        }).catch(() => {          
+        });
+      
+    },
+    //删除无效证据
+    deletes(ids){
+      this.$api.deleteProofStr(ids).then(response=>{
+        if(response.code == 200){
+          this.$message.success('删除成功')
+          this.getPoofArguments(this.evidence,this.right)
+        }
+      })
+    },
+    // 查询陈述意见
+    getPoofArguments(row, right) {
+      this.tableData=[]
+      let params = {
+        reportId  : this.reportId,
+        rightSort: right,
+        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.tableData.push(a)
+            // })
+            this.tableData = res.data
+          } 
+          this.TypeSelect()
+        }
+          
+      }).catch(error=>{
+      })
+    },
+    // 查已添加的特征
+    getFeature(right) {
+      let params = {
+        reportId: this.reportId,
+        rightSort:right
+      }
+      this.$api.getFeatureList(params).then((res) => {
+        if (res.code==200) {
+          this.featureList=res.data
+        }
+      })
+    },
+
+    open(row, right) {
+      this.evidence = row
+      this.right=right.sort
+      this.rightDetails = right
+      // row.evidence = this.tableData
+      this.getFeature(this.right)
+      this.getPoofArguments(row, this.right)
+    },
+    //添加特征
+    addFeature() {
+      this.addFeatureVisible=true
+      this.$nextTick(()=>{
+        this.$refs.rightContent.open(this.rightDetails)
+    })
+    },
+    closeFeature() {
+      this.addFeatureVisible = false
+      this.featureName=''
+      this.getFeature(this.right)
+    },
+    submitFeature() {
+      let params = {
+        content:this.featureName,
+        rightId:this.tableData[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()
+        }
+      })
+    },
+    //获取每个元素所需合并的行数
+    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];
+        }
+      }
+    },
+
+    refreshTable() {
+      this.refreshData = false
+      this.$nextTick(() => {
+        this.refreshData = true
+      })
+    },
+
+    TypeSelect(event) {//显示
+      this.tableData = this.tableData
+      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>

+ 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>

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

@@ -0,0 +1,849 @@
+<template>
+  <!-- 无效理由和证据 -->
+  <div>
+    <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="addCourtOpinion">添加法院意见</el-button>
+      <el-button type="primary" size="small" @click="openField">显示栏位管理</el-button>
+      <el-button type="primary" size="small" @click="exportInvalid" :loading="btnLoading">导出无效理由</el-button>
+    </div>
+    
+    <el-table border ref="table" v-if="refreshData" :data="tableData" row-key="id" :expand-row-keys="expands" :span-method="objectSpanMethod" :maxHeight="tableHeight">
+      <el-table-column prop="index" label="序号" align="center" width="80px">
+        <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" type>
+        <template slot-scope="scope">
+            <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" 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,index)" :reportId="reportId" :patentNo="signPatentNo"></Invalid-Evidence>
+                        </div>
+                      </div>
+                      <el-link @click="check(item, y)" slot="reference">D{{ y.sort }}</el-link>
+                    </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 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-link @click="check(item, y)">D{{ y.sort }}</el-link>
+                    <span v-if="index1 < i.proofs.length - 1"> + </span>
+                  </span>
+                </p>
+              </span>
+              <span>
+                {{ scope.row[item.key] }}
+              </span>
+            </div>
+            <div v-else-if="item.key == 'court'">{{ getData(scope.row,item.key) }} <span style="margin-left:20px;float:right" v-if="scope.row.invalidName == 3 || scope.row.invalidName == 2"> <el-link type="primary" @click="toogleExpand(scope.row,scope.$index)">详情</el-link> </span></div>
+            <div v-else v-html="getData(scope.row,item.key)"></div>
+        </template>
+      </el-table-column>
+      <el-table-column v-for="item in tableField2.filter(item => item.fieldState)"  :key="item.fieldKey" :label="item.fieldName" :prop="item.fieldKey" align="center" type>
+        <template slot="header">
+          <div>
+            <span>{{ item.fieldName }}</span>
+            <span class="margin-left_10">
+              <el-link type="primary" v-if="!item[('edit'+item.fieldKey)]" @click="edit('edit'+item.fieldKey,item)">
+                <el-tooltip class="item" effect="dark" content="编辑" placement="top">
+                  <i class="iconfont icon-bianji"></i>
+                </el-tooltip>
+              </el-link>
+              <span v-else>
+                <el-link type="primary"  @click="save('edit'+item.fieldKey,item)">
+                  <el-tooltip class="item" effect="dark" content="保存" placement="top">
+                    <i class="iconfont icon-baocun"></i>
+                  </el-tooltip>
+                </el-link>
+                <el-link class="margin-left_10" type="primary"  @click="cancelEdit('edit'+item.fieldKey,item)">
+                  <el-tooltip class="item" effect="dark" content="取消编辑" placement="top">
+                    <i class="iconfont icon-fanhui"></i>
+                  </el-tooltip>
+                </el-link>
+              </span>
+              
+              
+            </span>
+          </div>
+        </template>
+        <template slot-scope="scope">
+          <div v-if="item[('edit'+item.fieldKey)]">
+            <myRich-Text v-model="scope.row[item.fieldKey]" :placeholder="'请输入'+item.fieldName"></myRich-Text>
+          </div>
+          <div v-else v-html="getData1(scope.row,item.fieldKey)"></div>
+        </template>
+      </el-table-column>
+      <el-table-column  label="操作" align="center" width="180px" type>
+        <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-column type="expand" width="1">
+      <template slot-scope="scope">
+        <InvalidDetails :invalidReasonId="scope.row.id" :reportId="reportId" :patentNo="signPatentNo" :rightSort="scope.row.content" :right="rightList.find(item => item.sort == scope.row.content)"></InvalidDetails>
+      </template>
+    </el-table-column>
+    </el-table>
+    <Table-Field ref="tableField" :reportId="reportId" @update="getTableField"></Table-Field>
+
+    <el-dialog :title="title" :visible.sync="visible" width="800px" :before-close="close" :append-to-body="true">
+      <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="选择特征:">
+              <rightContent :right="rightList.find(item => item.sort == this.form.content)" :reportId="reportId"></rightContent>
+                <!-- <span >{{ rightList.find(item => item.sort == this.form.content).content }}</span> -->
+            </el-form-item>
+          </template>
+          <el-form-item label="相关证据:" v-if="form.content == 0 || form.content">
+            <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">
+                  <el-popover placement="top-start" width="800" trigger="hover" ref="popoverHover" >
+                    <div>
+                      <p><span>描述:</span><span>{{ i.description }}</span></p>
+                      <div>
+                        <Invalid-Evidence ref="invalid" :patentNo="signPatentNo"  :evidence="showPopover(i,null,index)" :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 v-for="(item, index) in form.proofGroups" :key="index" style="margin-right:10px">
+                <span v-for="(i, index1) in (item.proofs)" :key="i.label">
+                    <el-link v-if="i.sort">D{{ i.sort }}</el-link>
+                    <el-link v-else>{{ i.sortStr }}</el-link>
+                  <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 v-if="!show"><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="陈述意见:">
+            <myRich-Text v-model="form.argumentStr" placeholder="请输入陈述意见"></myRich-Text>
+          </el-form-item>
+          <el-form-item v-for="item in tableField2"  :key="item.fieldKey" :label="item.fieldName+':'">
+            <myRich-Text v-model="form[item.fieldKey]" :placeholder="'请输入'+item.fieldName"></myRich-Text>
+          </el-form-item>
+          <!-- <el-form-item label="复审委意见:">
+            <el-input type="textarea" :rows="1" v-model="form.comOptions"></el-input>
+          </el-form-item>
+          <el-form-item label="法院意见:">
+            <el-input type="textarea" :rows="1" v-model="form.courtOptions"></el-input>
+          </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" custom-class="addInvalid" append-to-body>
+      <Invalid-Evidence ref="invalid" :reportId="reportId" :patentNo="signPatentNo" ></Invalid-Evidence>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="closeEvidence">取 消</el-button>
+        <el-button type="primary" @click="submitEvidence">确 定</el-button>
+      </div>
+    </el-dialog>
+    <AddOrEditField ref="addOrEditField" :reportId="reportId" :tableFields="tableField2" @submit="queryInvalidFields()"></AddOrEditField>
+  </div>
+</template>
+<script>
+import TableField from './TableField.vue'
+import InvalidEvidence from './InvalidEvidence.vue'
+import InvalidFeatures from './InvalidFeatures.vue'
+
+import InvalidDetails from './InvalidDetails/InvalidDetails.vue'
+import rightContent from './addFeatures/rightContent.vue'
+import AddOrEditField from './addOrEditField.vue'
+import { downLoad2 } from "@/utils";
+export default {
+  props: ['reportId','signPatentNo','reportType'],
+  components: {
+    TableField,
+    InvalidEvidence,
+    InvalidFeatures,
+    InvalidDetails,
+    rightContent,
+    AddOrEditField
+},
+  data() {
+    const contentRule = (rule, value, callback) => {
+      if (this.form.invalidName == 1) {
+        callback()
+      } else {
+        if (value === '') {
+          callback(new Error('请选择涉及内容'))
+        } else {
+          callback()
+        }
+      }
+      
+    }
+    return {
+      btnLoading:false,
+      expands:[],
+      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
+        // },
+      ],//显示栏位管理
+      tableField2:[],
+      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: document.getElementsByClassName('el-main')[0].clientHeight - 100,
+      // tabRowIndex:null,//行角标
+      // tabColumnIndex:null,//列角标
+      rowData:'',
+    }
+  },
+  watch: {
+    
+  },
+  async mounted() {
+    this.getHeight()
+    //获取自定义栏位
+    this.queryInvalidFields()
+    // 请求专利权要
+    await this.getPatentByPatentNo()
+    // 请求证据文献
+    this.getQueryProofList()
+    // 请求无效理由和证据
+    await this.getInvalidReason()
+    
+  },
+  methods: {
+    //导出无效理由和证据
+    exportInvalid(){
+      this.btnLoading = true
+      this.$api.exportInvalid({reportId:this.reportId}).then(response=>{
+        if(response.code == 200){
+          this.$message.success('导出成功')
+          downLoad2(response.data)
+          this.btnLoading = false
+        }
+      }).catch(error => {
+        this.$message.error('导出失败,请重试')
+        this.btnLoading = false
+      })
+    },
+    //编辑列数据
+    edit(key,row){
+      this.$set(row,key,true)
+      this.tableData.forEach(item=>{
+        item[row.fieldKey] = this.getData1(item,row.fieldKey)
+      })
+      this.refreshTable()
+    },
+    //保存列数据
+    save(key,row){
+      var params = []
+      this.tableData.forEach(item=>{
+        params.push(
+          {
+            "invalidReasonId": item.id,
+            "fieldId": row.id,
+            "fieldValue": item[row.fieldKey],
+            "fieldKey": row.fieldKey
+          }
+        )
+      })
+      this.$api.addOrUpdateValue(params).then(response=>{
+        if(response.code == 200){
+          this.$message.success('编辑成功')
+          this.$set(row,key,false)
+          this.getInvalidReason()
+          this.refreshTable()
+        }
+      })
+    },
+    //取消编辑列数据
+    cancelEdit(key,row){
+      this.$set(row,key,false)
+      this.tableData.forEach(item=>{
+        item[row.fieldKey] =''
+      })
+      this.refreshTable()
+    },
+    //添加法院意见
+    addCourtOpinion(){
+      var form = {}
+      this.$refs.addOrEditField.open(form)
+    },
+    //获取自定义栏位
+    queryInvalidFields(){
+      this.$api.queryInvalidFields({reportId:this.reportId}).then(response=>{
+        if(response.code == 200){
+          this.tableField2 = response.data
+        }
+      })
+    },
+    // table高度
+    getHeight() {
+      this.tableHeight = document.getElementsByClassName('el-main')[0].clientHeight - 100
+    },
+    //展开行
+    toogleExpand(row,index) {
+        var index1 = this.expands.findIndex(item=>{
+            return item == row.id
+          })
+        if(index1 == -1){
+          var a = []
+          a[0] = this.tableData.slice(0,index+1)
+          a[1]= this.tableData.slice(index+1,this.tableData.length)
+          var invalidName = []
+          a.forEach(item=>{
+            invalidName = invalidName.concat(this.getSpanArr(item))
+          })
+          this.mergeObj.invalidName = invalidName
+        }else{
+          this.getSpanArr(this.tableData)
+        }
+        this.refreshData = false
+        this.$nextTick(()=>{
+          this.refreshData = true
+          if(index1!=-1){
+            this.expands = []
+          }else{
+            this.expands = [row.id]
+          }
+          this.getHeight()
+        })
+      },
+    // 回显
+    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]
+      }
+    },
+    getData1(row,key){
+      var index = row.fields.findIndex(item=>item.fieldKey == key)
+      if(index!=-1){
+        return row.fields[index].fieldValue
+      }else{
+        return ''
+      }
+      
+    },
+    // 请求无效理由和证据
+   async getInvalidReason() {
+      await this.$api.queryInvalidReason({reportId:this.reportId}).then((res) => {
+        if (res.code == 200) {
+          if(res.data){
+            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)
+            })
+          }else{
+            this.tableData = []
+          }
+          this.expands = []
+          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);
+            }
+          }
+        })
+      })
+      return this.mergeObj.invalidName
+    },
+     //合并行
+     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];
+        }
+      }
+    },
+    // 证据组合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.map(item=>{
+            item.proofStrIds = []
+            return item
+          })
+        }
+      }).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) {
+      this.rowData = row
+      this.EvidenceVisible = true
+      this.$nextTick(() => {
+        this.$refs.invalid.open(row,this.rightList.find(item => item.sort == this.form.content))
+      })
+    },
+    //关闭添加证据弹窗
+    closeEvidence() {
+      this.rowData.proofStrIds = []
+      this.EvidenceVisible = false
+    },
+    submitEvidence(){
+      this.EvidenceVisible = false
+    },
+    //添加证据组合
+    submit() {
+      if (this.proofGroups.length == 0) {
+        this.$message.error('请选择后再添加')
+        return false
+      }
+      var a = {
+        description: this.description,
+        argumentStr: this.argumentStr,
+        proofs: this.proofGroups.sort((a,b)=>{
+          return Number(a.sortStr.substring(1,a.sortStr.length))  - Number(b.sortStr.substring(1,b.sortStr.length)) 
+        }),
+        proofIds: this.selected,
+        groupDetails:this.proofGroups.map(item=>{
+          return {
+            compareFileId:item.id,
+            proofStrIds:item.proofStrIds
+          }
+        })
+      }
+      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)
+      }
+    },
+    //查看证据文献
+    check(item,val) {
+      var router = this.$router.resolve({
+        path: '/fileDetails/' + val.id,
+      })
+      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.tableField2)
+    },
+    //获取表格最新显示栏位
+    getTableField({val,update}) {
+      if(val){
+        this.tableField2 = val
+      }
+      if(update){
+        this.getInvalidReason()
+      }
+      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() {
+      // 为说明书时content为-1
+      if (this.form.invalidName == 1) {
+        this.form.content == -1
+      }
+      this.form.reportId = this.reportId
+      this.form.fields = []
+      for(let key in this.form){
+        var index = this.tableField2.findIndex(item=>{
+          return item.fieldKey == key
+        })
+        if(index!=-1){
+          this.form.fields.push(
+            {
+              "invalidReasonId":this.form.id|| 0,
+              "fieldId": this.tableField2[index].id,
+              "fieldValue": this.form[key]
+            }
+          )
+        }
+      }
+      if (this.form.isEdit) {
+        this.sureEdit()
+      } else {
+        this.$refs.form.validate((valid) => {
+          if (valid) {
+            if (!this.form.id) {
+              this.$api.addInvalidReason(this.form).then((res) => {
+                if (res.code == 200) {
+                  this.getInvalidReason()
+                  this.refreshTable()
+                  this.close()
+                }
+              })
+            } else {
+             this.sureEdit()
+            }
+          } else {
+            this.$message.error('请填写信息')
+            return false;
+          }
+        });
+      }
+    },
+    sureEdit() {
+      this.$api.updateInvalidReason(this.form).then((res) => {
+        if (res.code == 200) {
+          this.$message.success('更新成功')
+          this.getInvalidReason()
+          this.refreshTable()
+          this.close()
+        }
+      })
+    },
+    deleteRow(row) {
+      let id = [
+        row.id,
+      ]
+      this.$confirm('是否确定删除?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          this.$api.deleteInvalidReason(id).then((res) => {
+            if (res.code == 200) {
+              this.$message.success('删除成功')
+              this.getInvalidReason()
+            }
+          })
+        }).catch(() => {
+          this.$message({
+            type: 'info',
+            message: '已取消删除'
+          });          
+        });
+      
+    },
+    editRow(row) {
+      this.title="编辑无效理由和证据"
+      this.form=JSON.parse(JSON.stringify(row))
+      this.form.fields.forEach(item=>{
+        this.form[item.fieldKey] = item.fieldValue
+      })
+      this.visible = true
+    },
+  },
+}
+</script>
+<style lang="scss">
+.addInvalid .el-dialog__body{
+  padding-top:5px
+}
+</style>
+<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>

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

@@ -0,0 +1,262 @@
+<template>
+  <div class="">
+    <el-dialog title="显示栏位管理" :visible.sync="visible" width="300px" append-to-body destroy-on-close :before-close="close" top="10vh">
+      <!-- <div class="project-table-field">
+        <el-transfer
+            class="transfer"
+            v-model="selected"
+            :props="{
+              key: 'fieldKey',
+              label: 'fieldName'
+            }"
+            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 }">
+            <span>{{ option.fieldName }}</span>
+            <span style="float:right">
+              <i class="el-icon-delete" @click.stop.prevent="delField(option)"></i>
+              <i class="iconfont icon-bianji margin-left_10" @click.stop.prevent="editField(option)"></i>
+            </span>
+            </span>
+          <div class="transfer-footer" slot="left-footer">
+            <el-button @click="addField(0)" size="small" icon="el-icon-plus" circle></el-button>
+          </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>
+            <el-button @click="addField(1)" size="small" icon="el-icon-plus" circle></el-button>
+          </div>
+        </el-transfer>
+      </div> -->
+      <div>
+        <el-checkbox-group v-model="selected">
+          <p v-for="option in dataList" :key="option.fieldKey" style="margin:10px 0;">
+            <el-checkbox :label="option.fieldKey">
+              <span>{{ option.fieldName }}</span>
+            </el-checkbox>
+            <span style="float:right">
+              <i class="el-icon-delete" @click.prevent="delField(option)" style="font-size:16px"></i>
+              <i class="iconfont icon-bianji margin-left_10" @click.prevent="editField(option)"></i>
+            </span>
+          </p>
+        </el-checkbox-group>
+      </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>
+
+    <el-dialog :title="title" :visible.sync="addVisible" width="650px" append-to-body :before-close="cancel">
+      <div>
+        <el-form ref="form" :model="form" label-width="80px">
+          <el-form-item label="栏位名称">
+            <el-input v-model="form.fieldName" placeholder="请输入栏位名称"></el-input>
+          </el-form-item>
+          <el-form-item label="栏位字段">
+            <el-input v-model="form.fieldKey" placeholder="请输入栏位字段"></el-input>
+          </el-form-item>
+        </el-form>
+      </div>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="cancel">取 消</el-button>
+        <el-button type="primary" @click="submitField" :loading="btnLoading2">确 定</el-button>
+      </div>
+    </el-dialog>
+    <AddOrEditField ref="addOrEditField" :reportId="reportId" :tableFields="dataList" @submit="queryInvalidFields(1)"></AddOrEditField>
+  </div>
+</template>
+
+<script>
+import AddOrEditField from './addOrEditField.vue'
+export default {
+  components:{
+    AddOrEditField
+  },
+  props:['reportId'],
+  data() {
+    return {
+      visible: false,
+      dataList: [],
+      btnLoading: false,
+      selected: [],
+      rightSelect: [],
+      form:{},
+      addVisible:false,
+      btnLoading2: false,
+      title:''
+    }
+  },
+  mounted() {
+  },
+  methods: {
+    //打开编辑显示栏位弹窗
+    editField(option){
+      this.title = '编辑显示栏位管理'
+      this.form = JSON.parse(JSON.stringify(option))
+      this.$refs.addOrEditField.open(this.form)
+      // this.addVisible = true
+    },
+    //删除显示栏位
+    delField(option){
+      this.deletes([option.id])
+    },
+    deletes(ids){
+      this.$confirm('是否确定删除?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          this.$api.deleteInvalidFields(ids).then(response=>{
+            if(response.code == 200){
+              this.$message.success('删除成功')
+              this.queryInvalidFields()
+            }
+          })
+        }).catch(() => {
+          this.$message({
+            type: 'info',
+            message: '已取消删除'
+          });          
+        });
+      
+    },
+    //打开添加显示栏位弹窗
+    addField(val){
+      this.title = '添加显示栏位管理'
+      this.form.fieldState=val
+      this.addVisible = true
+    },
+    //关闭添加显示栏位弹窗
+    cancel(){
+      this.form = {}
+      this.addVisible = false
+    },
+    //确认添加显示栏位
+    submitField(){
+      this.btnLoading2 = true
+      this.form.reportId = this.reportId
+      this.$api.addOrUpdateInvalidFields(this.form).then(response=>{
+        if(response.code == 200){
+          this.btnLoading2 = false
+          if(this.form.id){
+            this.$message.success('更新成功')
+          }else{
+            this.$message.success('添加成功')
+          }
+          this.cancel()
+          this.queryInvalidFields()
+        }
+      }).catch(error=>{
+        this.btnLoading2 = false
+      })
+    },
+    //获取自定义栏位
+    queryInvalidFields(val){
+      this.$api.queryInvalidFields({reportId:this.reportId}).then(response=>{
+            if(response.code == 200){
+              
+              if(!val){
+                this.$emit('update',{val:response.data})
+              }else{
+                this.$emit('update',{val:response.data,update:true})
+              }
+              this.dataList = response.data
+              this.selected = this.dataList.filter(item => item.fieldState).map(item => item.fieldKey)
+            }
+      })
+    },
+    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.fieldKey === this.selected[index])
+        let exchange = this.dataList.find(item => item.fieldKey === this.selected[cIndex])
+        current.fieldSort = current.fieldSort + order
+        exchange.fieldSort = exchange.fieldSort + (order === -1 ? 1 : -1)
+        this.dataList.sort((a, b) => {
+          return a.fieldSort - b.fieldSort
+        })
+        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.fieldKey).indexOf(this.selected[i])
+        this.dataList[index].fieldSort = order++
+      }
+    },
+    filterMethod(query, item) {
+      return item.fieldName.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.fieldState).map(item => item.fieldKey)
+      this.visible = true
+    },
+    close() {
+      this.visible = false
+      this.$emit('close')
+    },
+    submit() {
+      // this.dataList.map(item => item.fieldState != this.selected.indexOf(item.fieldKey) === -1)
+      // this.$emit('update', this.dataList)
+      this.dataList.forEach(item => {
+        item.fieldState = 0
+        var index = this.selected.indexOf(item.fieldKey)
+        if(index!=-1){
+          item.fieldState = 1
+        }
+      })
+      
+      this.btnLoading = true
+      this.$api.updateSort(this.dataList).then(response => {
+        this.visible = false
+        this.btnLoading = false
+        this.$message.success('操作成功')
+        this.queryInvalidFields(1)
+      }).catch(error => {
+        this.btnLoading = false
+      })
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+.project-table-field {
+  text-align: center;
+  .transfer {
+    .el-transfer-panel__item{
+      margin-right:0
+    }
+    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>

+ 122 - 0
RMS-FrontEnd/src/views/report/InvalidResponse/components/addFeatures/rightContent.vue

@@ -0,0 +1,122 @@
+<template>
+  <div  @mouseup="mouseup1" @mousemove="mousemove">
+    <div v-if="rightDetails" v-html="getDOMContent(rightDetails.content)" id="rightContent" data-type="权要"></div>
+    <addOpinion ref="addOpinion" @submit="submitFeature"></addOpinion>
+  </div>
+</template>
+
+<script>
+import {patentKeywordsHighlight} from '@/views/components/common/mixins'
+import {addContrast} from '@/views/components/articles/components/mixins'
+import addOpinion from '@/views/report/InvalidResponse/components/addOpinion.vue'
+export default {
+  components: {
+    addOpinion
+  },
+  props: ['right','reportId'],
+  mixins:[patentKeywordsHighlight,addContrast],
+  data() {
+    return {
+        rightDetails:this.right||null,
+        featureList:[],
+        rightContent:''
+    };
+  },
+  watch: {
+    right(val){
+        this.rightDetails = val
+        this.getFeature()
+    }
+  },
+  computed: {
+    showFeatures(){
+        return this.featureList
+    }
+  },
+  created() {},
+  mounted() {
+    if(this.rightDetails){
+        this.getFeature()
+    }
+    window.deleteFeature = this.deleteFeature
+  },
+  methods: {
+    deleteFeature(id,selectType){
+        this.$confirm('是否删除该特征?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+            var Id = id.substring(1,id.length)
+            this.$api.deleteSingleFeature({featureId:Id}).then(response=>{
+                if(response.code == 200){
+                    this.$message.success('删除成功')
+                    this.getFeature()
+                }
+            })
+        }).catch(() => {         
+        });
+    },
+    open(right){
+        this.rightDetails = right
+        this.getFeature()
+    },
+    getFeature() {
+      let params = {
+        reportId: this.reportId,
+        rightSort:this.rightDetails.sort
+      }
+      this.$api.getFeatureList(params).then((res) => {
+        if (res.code==200) {
+          this.featureList=res.data
+        }
+      })
+    },
+    getDOMContent(text){
+        this.showFeatures.forEach(item=>{
+            var a = {
+                color: item.color || 'yellow',
+                Type: 1,//1是默认高亮
+                Id: item.featureId,
+                column:'',
+                index: Number(item.position),
+                text:item.content,
+                temNode: text,
+                selectType:'r',
+              }
+              text = this.AddClass1(a);
+        })
+        this.rightContent = text
+        return text
+    },
+    mouseup1(){
+        let selectObj = document.getSelection();
+        if(selectObj.toString().length==0){
+            return false
+        }
+        var node = document.getElementById('rightContent')
+        if(selectObj.focusOffset - selectObj.anchorOffset != selectObj.toString().length){
+            this.$message.error('特征不能存在交叉部分')
+            return false
+        }
+        this.getColumn(node, selectObj);
+        var form = {
+            content: selectObj.toString(),
+            reportId: this.reportId,
+            position: this.anchorOffset,
+            rightId:this.rightDetails.sort,
+            rightSort:this.rightDetails.sort + '',
+      }
+      this.$refs.addOpinion.open(form,true)
+    },
+    submitFeature(){
+        this.getFeature()
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+#rightContent{
+    font-size:18px;
+}
+</style>

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

@@ -0,0 +1,503 @@
+<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-tooltip class="item" effect="dark" :content="item.proofName" placement="top">
+                      <span>{{ item.sortStr }}</span>
+                    </el-tooltip>
+                </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> -->
+                <myRich-Text v-model="form.proofStr" placeholder="请输入无效请求书理由"></myRich-Text>
+                <!-- <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> -->
+                <myRich-Text v-model="form.argumentStr" placeholder="请输入陈述意见"></myRich-Text>
+                <!-- <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>{{ 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-tooltip class="item" effect="dark" :content="item.proofName" placement="top">
+                      <span>{{ item.sortStr }}</span>
+                    </el-tooltip>
+                </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> -->
+                <myRich-Text v-model="form.proofStr" placeholder="请输入无效请求书理由"></myRich-Text>
+                <!-- <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> -->
+                <myRich-Text v-model="form.argumentStr" placeholder="请输入陈述意见"></myRich-Text>
+              </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>
+
+        <el-dialog title="添加特征" :visible.sync="addFeatureVisible" width="800px" :before-close="closeFeature2" append-to-body>
+        <div>
+          <rightContent :reportId="form.reportId" ref="rightContent"></rightContent>
+        </div>
+      </el-dialog>
+  </div>
+</template>
+<script>
+import { explain1 } from "@/views/report/components/mixins";
+export default {
+  name:'addOpinion',
+  components: {
+    rightContent: () => import('./addFeatures/rightContent.vue')
+  },
+
+  mixins:[explain1],
+  data() {
+    return {
+      addFeatureVisible:false,
+      rightContent:false,
+      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
+      }
+      this.form.rightSort = this.form.rightId
+      // 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) {
+      this.getFeatureZheng(feature)
+    },
+    treeCheck(node, list) {
+      if (list.checkedKeys.length == 2) {
+        this.$refs.treeForm.setCheckedKeys([node.id]);
+      }
+    },
+    // 打开
+    async open(form, data,show) {
+      if (form.scratchType) {
+        form.scratchType=Number(form.scratchType)
+      }
+      // if(form.proofId == -1){
+      //   form.proofId = null
+      // }
+      this.form = JSON.parse(JSON.stringify(form))
+      if(this.form.proofId == -1){
+        this.form.proofId = null
+      }
+      if (!data) {
+        await this.getQueryProofList(this.form)
+        await this.getFeatureRights(form.signPatentNo)
+        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=this.form
+        this.featureVisible = true
+        this.show = show
+        if(this.show){
+          this.getQueryProofList(form) 
+        }
+      }
+    },
+    //查询证据文献列表
+    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
+      this.addFeatureVisible=true
+      this.$nextTick(()=>{
+        this.$refs.rightContent.open(val)
+      })
+    },
+    closeFeature() {
+      this.featureVisible = false
+      this.show = false
+      this.featureForm = {}
+    },
+    closeFeature2(){
+      this.addFeatureVisible=false
+      this.getFeature()
+
+    },
+    submitFeature() {
+      if (!this.show) {
+        // 第二种方式弹窗中添加特征
+        this.$api.addSingleFeature(this.featureForm).then((res) => {
+          if (res.code== 200) {
+            // this.getFeature()
+            this.closeFeature()
+            this.$emit('submit',true)
+          }
+        })
+      } else {
+        var params = {
+          reportId:this.featureForm.reportId,
+          rightId:this.featureForm.rightId,
+          proofId:this.featureForm.proofId,
+          proofStr:this.featureForm.proofStr,
+          argumentStr:this.featureForm.argumentStr,
+          featureContent:this.featureForm.content,
+          // position:this.featureContent.rightPosition
+
+        }
+      this.$api.addArguments(params).then(response=>{
+        if(response.code == 200){
+          this.$message.success('添加成功')
+          this.closeFeature()
+        }
+      })
+      }
+    },
+    // 请求权要特征
+    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);
+      if(!(val+'')){
+        return false
+      }
+      this.form.rightId=val
+      this.getFeature()
+    },
+    // 查询已添加的特征
+    async getFeature() {
+      // console.log(this.form,this.witchRight);
+      if(this.witchRight == null){
+        return false
+      }
+      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) {
+      let params = {
+        proofId: this.form.proofId,
+        featureId:val.featureId,
+      }
+      this.$api.queryProofStr(params).then((res) => {
+        if (res.code == 200) {
+          if (res.data.proofStr) {
+            this.$set(this.form,'proofStr',res.data.proofStr)
+            this.$set(this.form,'proofStrId',res.data.proofStrId)
+            if(res.data.arguments && res.data.arguments.length>0){
+              this.$set(this.form,'argumentStr',res.data.arguments[0].argumentStr)
+              this.$set(this.form,'argumentId',res.data.arguments[0].id)
+            }
+            
+            // this.form.proofStr = res.data.proofStr
+          }
+        }
+      })
+    },
+    //划词类型
+    changeRadioType() {
+      
+    },
+  },
+}
+</script>
+<style lang="scss">
+.el-divider--horizontal{
+  margin:5px 0 !important;
+}
+  
+</style>
+<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>

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

@@ -0,0 +1,131 @@
+<template>
+  <div>
+    <el-dialog :title="title" :visible.sync="addVisible" width="650px" append-to-body :before-close="cancel">
+      <div>
+        <el-form ref="form" :model="form" label-width="80px">
+          <el-form-item label="栏位名称">
+            <el-select v-model="form.fieldName" placeholder="请选择栏位名称" style="width:100%" @change="changeFieldName">
+                <el-option
+                    v-for="item in tableField"
+                    :disabled="tableField2.findIndex(item1=>{return item1.fieldName == item.label})!=-1"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.label">
+                </el-option>
+            </el-select>
+          </el-form-item>
+        </el-form>
+      </div>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="cancel">取 消</el-button>
+        <el-button type="primary" @click="submitField" :loading="btnLoading2">确 定</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  components: {},
+  props: ['reportId','tableFields'],
+  data() {
+    return {
+        title:'',
+        addVisible:false,
+        btnLoading2:false,
+        form:{},
+        tableField:[
+            {
+                value:'2',
+                label:'法院二审',
+            },
+            {
+                value:'3',
+                label:'法院三审',
+            },
+            {
+                value:'4',
+                label:'法院四审',
+            },
+            {
+                value:'5',
+                label:'法院五审',
+            },
+            {
+                value:'6',
+                label:'法院六审',
+            },
+            {
+                value:'7',
+                label:'法院七审',
+            },
+            {
+                value:'8',
+                label:'法院八审',
+            },
+            {
+                value:'9',
+                label:'法院九审',
+            },
+        ],
+        tableField2:this.tableFields||[]
+    };
+  },
+  watch: {
+    tableFields(val){
+        this.tableField2 = val
+    }
+  },
+  computed: {},
+  created() {},
+  mounted() {},
+  methods: {
+    open(form){
+        this.form = JSON.parse(JSON.stringify(form))
+        if(form.id){
+            this.title = '编辑显示栏位'
+        }else{
+            this.title = '添加显示栏位'
+            var a = this.tableField.filter(item=>{
+                return this.tableField2.findIndex(item1=>{item1.fieldName == item.label})==-1
+            })
+            this.$set(this.form,'fieldName',a[0].label)
+            this.$set(this.form,'fieldKey','courtOptions'+a[0].value)
+        }
+        this.addVisible = true
+    },
+    changeFieldName(val){
+        var i = this.tableField.find(item=>{
+            return item.label == val
+        }).value
+        this.form.fieldKey = 'courtOptions'+i
+    },
+    //关闭添加显示栏位弹窗
+    cancel(){
+      this.form = {}
+      this.addVisible = false
+    },
+    //确认添加显示栏位
+    submitField(){
+      this.btnLoading2 = true
+      this.form.reportId = this.reportId
+      this.$api.addOrUpdateInvalidFields(this.form).then(response=>{
+        if(response.code == 200){
+          this.btnLoading2 = false
+          if(this.form.id){
+            this.$message.success('更新成功')
+          }else{
+            this.$message.success('添加成功')
+          }
+          this.cancel()
+          this.$emit('submit')
+        }
+      }).catch(error=>{
+        this.btnLoading2 = false
+      })
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+</style>

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

@@ -0,0 +1,25 @@
+<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>

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

@@ -0,0 +1,355 @@
+<template>
+  <div>
+    <div style="margin-bottom: 10px;float: right;">
+      <el-dropdown trigger="click" @command="andClick($event)" :hide-on-click="false" type="primary" size="small">
+      <el-button type="primary" size="small">
+        上传文件<i class="el-icon-arrow-down el-icon--right"></i>
+      </el-button>
+      <el-dropdown-menu slot="dropdown" class="text-align_center">
+        <el-dropdown-item>
+            <el-dropdown @command="andClick($event)" placement="right-start">
+              <span class="el-dropdown-link"> 上传专利文件 </span>
+                <el-dropdown-menu  class="children_item">
+                  <el-dropdown-item command="3">专利号导入</el-dropdown-item>
+                  <el-dropdown-item command="2">Excel导入</el-dropdown-item>
+                </el-dropdown-menu>
+            </el-dropdown>
+          </el-dropdown-item>
+          <el-dropdown-item command="5">上传非专利文件</el-dropdown-item>
+          <el-dropdown-item command="1" v-if="examine">上传无效请求书</el-dropdown-item>
+      </el-dropdown-menu>
+    </el-dropdown>
+
+
+
+      <!-- <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 class="margin-left_10" 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'}"
+                          :allow-drop="allowDrop"
+                          draggable
+                          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="title" :visible.sync="showFile" width="1200px"  @close="handleFile" append-to-body  :close-on-click-modal="false">
+      <!-- <importPatent :reportId="this.queryParams.reportId"></importPatent> -->
+      <component :is='isComponent' :reportId="this.queryParams.reportId"></component>
+        <!-- <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 ExcelImport from "@/views/components/import/excelImport/importPatent.vue"
+import PatentNoImport from "@/views/components/import/PatentNoImport/download.vue"
+
+export default {
+  props:['reportId','signPatentNo','examine'],
+  components: {
+    responseDialog,
+    ExcelImport,
+    PatentNoImport
+  },
+  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,
+      title:'',
+      isComponent:'',
+      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,
+    }
+  },
+  computed: {
+  },
+  watch: {
+  },
+  mounted() {
+    this.getList()
+    this.getListTable()
+    //创建报告时打开
+    if(this.examine){
+      this.getAllPersonnelList()
+    }
+  },
+  methods: {
+     //查看证据文献
+     check(val) {
+      // var router = this.$router.resolve({
+      //   path: '/ContrastIndex/' + val.id,
+      // })
+      var router = this.$router.resolve({
+        path: '/fileDetails/' + val.id,
+      })
+      let params = this.$s.getSession('params')
+      params.type=7
+      params.reportType=7
+      params.aid=val.id
+      params.signPatentNo=this.signPatentNo || val.proofConditions
+      params.reportId=this.queryParams.reportId
+      this.$s.setSession('params', params)
+      window.open(router.href, '_blank');
+    },
+    //获取当前文献id
+    getVal(val){
+      this.val = val.id
+    },
+    //上下拖动
+    allowDrop(draggingNode, dropNode, type){
+      if(draggingNode.level == dropNode.level){
+        return type === 'next' || type === 'prev'
+      }else{
+        return type === 'prev'
+      }
+    },
+    //交换文献
+    changeRadio(val1, node) {
+      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.addOrder()
+    },
+    //证据文献排序
+    addOrder() {
+      var params ={
+        "report": 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.getListTable()
+          this.$nextTick(() => {
+            this.show = true
+          })
+        }
+      }).catch(error => {
+        
+      })
+    },
+
+    // 报告审核按钮,打开审核弹窗
+    isExamine() {
+      this.showTask=true
+    },
+    // 审核确认
+    submitTask() { 
+      this.$refs.TaskForm.validate((valid) => {
+        if (valid) { 
+          let formData = new FormData()
+          let a = this.task
+          a.reportId = this.queryParams.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.handleCloseTask()
+              this.$emit('show',false)
+            }
+          }).catch(error => {
+            this.$message.error('报告创建失败')
+          })
+        }
+      })
+    },
+    // 审核取消,关闭审核弹窗
+    handleCloseTask() { 
+      this.$refs.TaskForm.resetFields()
+      this.task = {}
+      this.showTask = false
+    },
+    //获取全部人员
+    getAllPersonnelList(){
+      this.$api.getTenantPersonnel().then(response=>{
+        this.personnelList = response.data
+      })
+    },
+    // 上传证据文献成功弹窗关闭
+    handleFinish(val) {
+      this.getList();
+      this.getListTable()
+    },
+    //分页查询证据文献
+    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() {
+      var params = {
+        size: 999,
+        current: 1,
+        reportId:this.queryParams.reportId
+      }
+      this.$api.queryProof(params).then((res) => {
+        if (res.code==200) {
+          this.tableAll = res.data
+        }
+      }).catch((error) => {
+        
+      })
+    },
+    //打开上传文件弹窗
+    andClick(val) {
+      switch(val){
+        case '1':
+        case '5':
+          this.form.reportId=this.queryParams.reportId
+          this.form.processType=val
+          this.$refs.responseDialog.open(this.form)
+          break;
+        case '2':
+          this.title='Excel导入'
+          this.isComponent = 'ExcelImport'
+          this.showFile=true
+          break;
+        case '3':
+          this.title='专利号导入'
+          this.isComponent = 'PatentNoImport'
+          this.showFile=true
+          break;
+      }
+    },
+    // 上传文件弹窗关闭
+    handleFile() {
+      this.getList()
+      this.getListTable()
+      this.showFile=false
+    },
+    // 分页
+    handleCurrentChange(val) {
+      this.queryParams.current = val;
+      this.getList();
+    },
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

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

@@ -0,0 +1,37 @@
+<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>

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

@@ -0,0 +1,177 @@
+<template>
+  <div>
+    <!-- 无效流程 -->
+    <div style="display: flex;justify-content: end;margin-bottom: 10px;">
+      <el-button type="primary" size="small" @click="addOption">添加陈述意见</el-button>
+      <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 >
+      <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','signPatentNo'],
+  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.getList()
+    // this.getHeight()
+  },
+  methods: {
+    //添加陈述意见
+    addOption(){
+      var queryParams = {
+        reportId:this.reportId,
+        signPatentNo:this.signPatentNo,
+        size: 1,
+        current: 1,
+      }
+      this.$api.queryProof(queryParams).then((res) => {
+        if (res.code==200) {
+          // this.tableData=res.data[0].id
+          var router = this.$router.resolve({
+            path: '/fileDetails/' +res.data[0].id,
+          })
+          let params = this.$s.getSession('params')
+          params.type=7
+          params.reportType=7
+          params.aid=res.data[0].id
+          params.signPatentNo=this.signPatentNo
+          params.reportId=this.reportId
+          this.$s.setSession('params', params)
+          window.open(router.href, '_blank');
+            }
+      }).catch((error) => {
+        
+      })
+      
+    },
+    // getHeight() {
+    //   let a = document.body.clientHeight
+    //   this.tableHeight=a
+    // },
+    getList() {
+      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.getList()
+    },
+    // 删除文件
+    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.getList()
+        }
+      })
+    },
+    // 添加
+    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>

+ 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>

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

@@ -0,0 +1,116 @@
+<template>
+  <div>
+    <el-container>
+        <el-aside width="210px" style="overflow:hidden" class="patent-articles-menu" :style="{height:height}">
+          <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" :style="{height:height}">
+            <component :is="activeMenu" :reportId="reportId" :signPatentNo="signPatentNo" :reportType="reportType" :patent="{publicNo:signPatentNo}"></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';
+import Invalid from '@/views/components/articles/components/history/invalid.vue'
+export default {
+  components: {
+    BasicInformation,
+    InvalidIndex,
+    EvidenceAndRequest,
+    ChoseOpinion,
+    OpinionPlan,
+    FlowPath,
+    RemarryMatter,
+    TaskDetails,
+    Invalid
+  },
+  data() {
+    return {
+      activeMenu:'BasicInformation',
+      menuList: [
+        {title: '基本信息', path:"BasicInformation"},
+        {title: '标的专利无效历史', path:"Invalid"},
+        // {title: '无效应对流程', path:"FlowPath"},
+        {title: '无效理由和证据', path:"InvalidIndex"},
+        {title: '证据文献', path:"EvidenceAndRequest"},
+        // {title: '生成陈述意见方案', path:"ChoseOpinion"},
+        // {title: '导出陈述意见方案', path:"OpinionPlan"},
+        
+        {title: '后续跟进事项', path:"RemarryMatter",show:(this.row && this.row.status==3 && this.$permission('/rms/matter'))?true:false},
+        // {title: '后续跟进事项', path:"RemarryMatter",},
+        {title: '任务清单', path:"TaskDetails"},
+      ],
+      height:null,
+    }
+  },
+  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: {},
+  created(){
+    this.setData()
+  },
+  mounted() {
+    this.changePageTitle()
+    this.getHeight()
+  },
+
+  methods: {
+    getHeight(){
+      this.height = document.getElementsByClassName('el-main')[0].clientHeight - 20 + 'px'
+    },
+    setData(){
+            this.menuList =[
+              {title: '基本信息', path:"BasicInformation"},
+              {title: '标的专利无效历史', path:"Invalid"},
+              // {title: '无效应对流程', path:"FlowPath"},
+              {title: '无效理由和证据', path:"InvalidIndex"},
+              {title: '证据文献', path:"EvidenceAndRequest"},
+              // {title: '生成陈述意见方案', path:"ChoseOpinion"},
+              // {title: '导出陈述意见方案', path:"OpinionPlan"},
+              
+              {title: '后续跟进事项', path:"RemarryMatter",show:(this.row && this.row.status==3 && this.$permission('/rms/matter'))?true:false},
+              // {title: '后续跟进事项', path:"RemarryMatter",},
+              {title: '任务清单', path:"TaskDetails"},
+            ]
+        },
+    changePageTitle() {
+      document.title = `${this.row.name} ${'报告详情'}`
+    },
+    handleSelect(index, path) {
+      this.activeMenu = index
+    },
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

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


Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio