浏览代码

批量标引,合并发明人

zhuhao 1 年之前
父节点
当前提交
4fcfacc4c4

+ 40 - 0
src/api/newApi/patent.js

@@ -39,4 +39,44 @@ export default {
     queryPatentByNoFromWeb(params) {
         return axios.get("/xiaoshi/patent/queryPatentByNoFromWeb", {params});
     },
+    /**
+     * 合并发明人、申请人、权利人添加
+     * @param {*} data 
+     * @returns 
+     */
+    mergePerson(data) {
+        return axios.post("/xiaoshi/patent/mergePerson", data);
+    },
+    /**
+     * 合并发明人、申请人、权利人编辑
+     * @param {*} data 
+     * @returns 
+     */
+    updateMergePerson(data) {
+        return axios.post("/xiaoshi/patent/updateMergePerson", data);
+    },
+    /**
+     * 合并发明人、申请人、权利人查询列表
+     * @param {*} data 
+     * @returns 
+     */
+    selectMergePerson(data) {
+        return axios.post("/xiaoshi/patent/selectMergePerson", data);
+    },
+    /**
+     * 获取当前专题库所有的发明人、申请人、权利人
+     * @param {*} data 
+     * @returns 
+     */
+    getMergePerson(data) {
+        return axios.post("/xiaoshi/patent/getMergePerson", data);
+    },
+    /**
+     * 合并发明人、申请人、权利人列表的删除
+     * @param {*} data 
+     * @returns 
+     */
+    delMergePerson(data) {
+        return axios.post("/xiaoshi/patent/delMergePerson", data);
+    },
 }

+ 9 - 9
src/router/index.js

@@ -591,15 +591,15 @@ const routes = [
         },
         component: () => import('@/views/components/import/task/index.vue'),
       },
-      // //标注库
-      // {
-      //   path: "/indicia",
-      //   meta: {
-      //     title: '标注库',
-      //     button: [],
-      //   },
-      //   component: () => import('@/views/indicia'),
-      // },
+      //标注库
+      {
+        path: "/indicia",
+        meta: {
+          title: '标注库',
+          sign: 'indicia',
+        },
+        component: () => import('@/views/components/indicia/index.vue'),
+      },
 
 
     ]

+ 171 - 0
src/views/components/indicia/components/card.vue

@@ -0,0 +1,171 @@
+<template>
+  <div class="indiciaCard" v-loading="loading">
+    <!-- <el-row :gutter="24">
+      <el-col :span="6" v-for="(item, index) in cardData" :key="item.index"> -->
+      <template v-if="cardData && cardData.length > 0"  >
+        <el-card class="box-card" v-for="(item, index) in cardData" :key="index">
+          <div slot="header" class="clearfix">
+            <!-- <el-checkbox @change="changeRemark(item)" :value="remarkList.indexOf(item.id) !== -1"> -->
+              <span v-if="componentType == 'indiciaCard'" style="font-weight: 700;"> 序号:{{ (index + 1) + (queryParams.current - 1) * queryParams.size }}</span>
+              <span v-else style="font-weight: 700; "> 序号:{{ index + 1 }}</span>
+            <!-- </el-checkbox> -->
+          </div>
+          <div class="card-context text">
+            <div style="display: flex;" class="text textPRight context-marginTop">
+              <span style="font-weight: 700;">标注:</span>
+              <el-tooltip placement="top">
+                <template slot="content">
+                  <div style="max-width:500px;">{{ item.remark }}</div>
+                </template>
+                <span class="textPRight">{{ item.remark }}</span>
+              </el-tooltip>
+            </div>
+            <div class="text context-marginTop">
+              <span style="font-weight: 700;">标注人/时间:</span>
+              <span>{{ item.name }}</span> <span>{{ item.date }}</span>
+            </div>
+            <div style="display: flex;align-items: center;">
+              <!-- 文字前方颜色方块 -->
+              <!-- <div :style="{ 'background': item.color }"
+                style="width: 5px;height: 20px;border-radius: 5px;margin-right: 5px;margin-top: 18px;">
+              </div> -->
+              <p style="font-weight: 700;min-width: 75px;">标注位置:</p>
+              <el-tooltip placement="top">
+                <template slot="content">
+                  <div style="max-width:500px;">{{ '[' + item.scratchField + ']' + item.text }}</div>
+                </template>
+                <!-- 下划线 -->
+                <p v-if="item.scratchType == 0" :style="{ 'border-bottom': `2px solid ${item.color}` }"
+                  class="textPRight textP">{{ '[' + item.scratchField + ']' + item.text }}</p>
+                <!-- 高亮 -->
+                <p v-if="item.scratchType == 1"  :style="{ 'background': item.color }" style="color: aliceblue;"
+                  class="textPRight textP">{{ '[' + item.scratchField + ']' + item.text }}</p>
+                <!-- 波浪线 -->
+                <p v-if="item.scratchType == 2"
+                  :style="{ 'text-decoration-line': 'underline', 'text-decoration-style': 'wavy', 'text-decoration-color': item.color }"
+                  class="textPRight textP">{{ '[' + item.scratchField + ']' + item.text }}</p>
+              </el-tooltip>
+            </div>    
+            
+            <div class="text">
+              <span style="font-weight: 700;">专利号:</span>
+              <el-link @click.native="handleLink(item)">
+                <span style="color: #409EFF;">{{ item.patentNo }}</span>
+              </el-link>
+            </div>
+            <div class="text textPRight context-marginTop">
+              <span style="font-weight: 700;">专利标题:</span>
+              <el-tooltip placement="top">
+                <template slot="content">
+                  <div style="max-width:500px;">{{ item.patentTitle }}</div>
+                </template>
+                <span>{{ item.patentTitle }}</span>
+              </el-tooltip>
+            </div>
+            <div class="text context-marginTop">
+              <!-- <span style="font-weight: 700;">标注人:</span>
+              <span>{{ item.name }}</span> -->
+            </div>
+           
+          </div>
+
+        </el-card>
+      </template>
+      <template v-else>
+        <el-card class="box-card" >
+          <p style="margin-left: 10px;"> 暂 无 数 据 </p>
+        </el-card>
+      </template>
+      <!-- </el-col>
+    </el-row> -->
+  </div>
+</template>
+
+<script>
+export default {
+  props: ['dataArr','queryParams','loading','componentType'],
+  data() {
+    return {
+      remarkList: [],
+    }
+  },
+  computed: {
+    cardData() {
+      return this.dataArr
+    },
+  },
+  watch: {
+  },
+  mounted() {
+
+  },
+  methods: {
+    // 跳转专利详情
+    handleLink(row, index) {
+      var router = this.$router.resolve({
+        path: 'patentDetails',
+          query:{
+            patentId:row.patentId,
+            patentNo:row.patentNo,
+            id:row.patentId?true:null
+          }
+      })
+      // this.$s.setSession('params', this.params)
+      window.open(router.href, '_blank');
+    },
+    // 选中标注
+    changeRemark(row) {
+      const index1 = this.remarkList.indexOf(row.id)
+      if (index1 === -1) {
+        this.remarkList.push(row.id)
+      } else {
+        this.remarkList.splice(index1, 1)
+      }
+    },
+  },
+}
+</script>
+<style lang="scss">
+.indiciaCard {
+  .el-card__header {
+    padding: 10px 20px 0px 20px !important;
+  }
+
+  .box-card {
+    cursor: default;
+  }
+}
+</style>
+<style lang="scss" scoped>
+.card-context {
+  padding: 0 20px 20px 20px;
+}
+
+.text {
+  font-size: 14px;
+}
+
+.textP {
+  line-height: 25px;
+  // margin-bottom: 0px;
+  margin: 0px;
+}
+
+// .textLineRow {
+//   overflow-y: hidden; //多出的隐藏
+//   text-overflow: ellipsis; //多出部分用...代替
+//   display: -webkit-box; //定义为盒子模型显示
+//   -webkit-line-clamp: 1; //用来限制在一个块元素显示的文本的行数
+//   -webkit-box-orient: vertical; //从上到下垂直排列子元素(设置伸缩盒子的子元素排列方式)
+// }
+
+.textPRight {
+  word-break: keep-all;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+.context-marginTop{
+  margin-top: 10px;
+}
+</style>

+ 75 - 0
src/views/components/indicia/components/collapse.vue

@@ -0,0 +1,75 @@
+<template>
+  <div>
+    <el-collapse v-model="activeName" accordion @change="handleChange" v-loading="loading">
+      <!-- //collapse测试数据 -->
+      <template v-if="collapseList.length>0">
+        <!-- :key及:name要改成id -->
+        <el-collapse-item  v-for="(item,index) in collapseList" :key="index+1" :title="item[queryParams.grouping]" :name="item[queryParams.grouping]">
+          <div :style="{'height':sonHeight-(collapseList.length>1?'150':'100') +'px'}" style="padding: 10px;overflow-y: auto;">
+            <indiciaCard :dataArr="dataArr" :queryParams="params" ></indiciaCard>
+          </div>
+        </el-collapse-item>
+      </template>
+      <template v-else>
+        <el-collapse-item title="暂无数据" name="0">
+          <indiciaCard></indiciaCard>
+        </el-collapse-item>
+      </template>
+
+    </el-collapse>
+  </div>
+</template>
+
+<script>
+import indiciaCard from './card.vue'
+export default {
+  components: {
+    indiciaCard
+  },
+  //collapse测试数据
+  props: ['dataArr','collapseList','queryParams','sonHeight','loading'],
+  data() {
+    return {
+      activeName: '',
+      params: {
+        current: this.queryParams.current,
+        size:this.queryParams.size
+      }
+    }
+  },
+  computed: {
+    // activeName() {
+    //   let activeName = this.active
+    //   return activeName
+    // },
+  },
+  watch: {
+    'collapseList'(val) {
+      if (val) {
+        this.params={
+        current: this.queryParams.current,
+        size:this.queryParams.size
+      }
+        let data = val[0][this.queryParams.grouping]
+        this.activeName=data
+      } else {
+        this.activeName=''
+      }
+    },
+  },
+  mounted() { 
+
+  },
+  methods: {
+    handleChange(val) {
+      if (val) {
+        this.$emit('collapseVal',val)
+      }
+    },
+  },
+}
+</script>
+
+<style lang="scss">
+
+</style>

+ 286 - 0
src/views/components/indicia/components/indicia.vue

@@ -0,0 +1,286 @@
+<template>
+  <div class="indicia">
+    <div style="padding: 20px;">
+      <div class="indicia-top-components">
+        <div>
+          <el-select v-model="screenValue" size="small" class="indicia-top-select">
+            <el-option v-for="item in screenOptions" :key="item.value" :label="item.label" :value="item.value">
+            </el-option>
+          </el-select>
+          <template v-if="screenValue != 'date'">
+            <el-input v-model="screenInputValue" :placeholder="getPlaceholder()" size="small"
+              style="margin-left: 10px;width: 200px;"></el-input>
+          </template>
+          <template v-else>
+              <el-date-picker v-model="screenInputValue" value-format="yyyy-MM-dd" size="small" type="date" :placeholder="getPlaceholder()" style="margin-left: 10px;width: 200px;"></el-date-picker>
+              <!-- <el-date-picker v-model="screenInputValue.end" value-format="yyyy-MM-dd" size="small" type="date" :placeholder="getPlaceholder()" style="margin-left: 10px;width: 200px;"></el-date-picker> -->
+          </template>
+          <el-button size="small" type="primary" @click="screenBtn" class="indicia-top-button">搜 索</el-button>
+          <template v-if="searchOptions.length>0">
+          <el-popover placement="bottom" title="" width="200" trigger="hover" class="margin-left_10">
+                <div v-for="(item, index) in searchOptions" :key="index" class="workspace-content-header-query-box">
+                  <el-tag closable type="success" @close="handleDelete(item,index)" style="margin-bottom: 5px;">
+                    {{ item.label +':'+ item.content}}
+                  </el-tag>
+                </div>
+              <!-- <el-button  style="" >
+                检索条件<i class="el-icon-arrow-down el-icon--right"></i>
+              </el-button> -->
+              <span slot="reference" size="small" type="primary" style="font-size: 14px;"> 检索信息:({{ searchOptions[0].label +':'+searchOptions[0].content }}<i class="el-icon-arrow-down el-icon--right"></i>)</span>
+            </el-popover>
+          </template>
+        </div>
+        <div>
+          <span>分组查询:</span>
+          <el-select v-model="groupingValue" size="small" @change="changeGrouping" class="indicia-top-select">
+            <el-option v-for="item in groupingOption" :key="item.value" :label="item.label" :value="item.value">
+            </el-option>
+          </el-select>
+          <!-- <el-button size="small" type="primary" @click="importBtn" class="indicia-top-button">导 出</el-button> -->
+        </div>
+      </div>
+
+      <!-- table及collapse组件 -->
+      <div class="indicia-components" :style="{'height': sonHeight + 'px'}">
+        <component :dataArr="tableCollapseList" :collapseList="collapseList" :queryParams="queryParams" :sonHeight="sonHeight"
+          @collapseVal="collapseVal" :is="componentType" :loading="loading" :componentType="componentType">
+        </component>
+      </div>
+      <!-- collapse分页 -->
+      <div style="text-align: center;">
+        <el-pagination background layout="total, prev, pager, next, jumper" :current-page.sync="queryParams.current"
+          :page-size.sync="queryParams.size" @current-change="handleCurrentChange" :total="total" >
+        </el-pagination>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import indiciaCard from './card.vue'
+import indiciaCollapse from './collapse.vue'
+import { importExcel } from './mixins'
+// import { downLoad2 } from "@/utils";
+export default {
+  components: {
+    indiciaCollapse,
+    indiciaCard,
+  },
+  mixins:[importExcel,],
+  data() {
+    return {
+      componentType: 'indiciaCard',//切换组件,默认card组件
+      screenOptions: [
+        {
+          label: '标注',
+          value: 'remark',
+          placeholder: '请输入标注',
+        },
+        {
+          label: '专利号',
+          value: 'patentNo',
+          placeholder: '请输入专利号',
+        },
+        // {
+        //   label: '标注的位置',
+        //   value: 'address',
+        //   placeholder: '请输入标注的位置'
+        // },
+        {
+          label: '标注人',
+          value: 'name',
+          placeholder: '请输入标注人',
+        },
+        {
+          label: '标注时间',
+          value: 'date',
+          placeholder: '请选择标注时间',
+        },
+      ],//筛选
+      groupingOption: [
+        {
+          label: '不分组',
+          value: 'noGrouping',
+        },
+        {
+          label: '专利号',
+          value: 'patentNo',
+        },
+        {
+          label: '标注人',
+          value: 'name',
+        },
+        {
+          label: '标注时间',
+          value: 'date',
+        },
+      ],//分组
+      screenValue: 'remark',//筛选的值
+      screenInputValue: '',//筛选输入的值
+      groupingValue: 'noGrouping',//分组的值
+      queryParams: {
+        current: 1,
+        size: 10,
+      },
+      total: 0,
+      tableCollapseList: [],//获取的数据
+      collapseList: [],//collapse数据
+      sonHeight: document.documentElement.clientHeight -230,//页面高度
+      loading: false,
+      searchOptions:[],//检索条件
+    }
+  },
+  watch: {
+   
+  },
+  mounted() {
+    this.getList()
+  },
+  methods: {
+    // 请求card数据
+    getList(val) {
+      this.loading = true
+      if (val) {
+        let a=this.searchOptions.filter(item => {
+          return item.value!=this.queryParams.grouping
+        })
+        a.push({ value: this.queryParams.grouping, content: val })
+        var params = {
+          search:a
+        }
+      } else {
+        var params = {
+          //...扩展、展开
+          ...this.queryParams,
+          search:this.searchOptions,
+        }
+      }
+      this.$api.queryScratchS(params).then((res) => {
+        if (res.code == 200) {
+          this.tableCollapseList = res.data.records
+          if (!val) {
+            this.total=res.data.total
+          }
+          this.loading=false
+        }
+      }).catch(error => {
+        this.tableCollapseList = []
+        if (!val) {
+          this.total=0
+         }
+        this.loading=false
+      })
+    },
+    // 查询分组
+    getCollapse() {
+      this.loading = true
+      let params = {
+        //...扩展、展开
+        search:this.searchOptions,
+        ...this.queryParams,
+      }
+      this.$api.queryGroupScratchS(params).then((res) => { 
+        if (res.code == 200) {
+          this.collapseList = res.data.records
+          this.total=res.data.total
+          this.loading = false
+          if (this.collapseList.length > 0) {
+            this.getList(this.collapseList[0][this.queryParams.grouping])
+          }
+        }
+      }).catch(error => {
+        this.collapseList = []
+        this.total=0
+        this.loading=false
+      })
+    },
+    // 判断是查询分组还是只检索
+    isCollapse() {
+      if (this.componentType == 'indiciaCard') {
+        this.getList()
+      } else {
+        this.getCollapse()
+      }
+    },
+    // 搜索事件
+    screenBtn() { 
+      this.editSearchOptions()
+      this.isCollapse()
+      this.screenInputValue=''
+    },
+    // 修改检索数组
+    editSearchOptions() {
+      this.searchOptions.push(
+        {
+          value: this.screenValue,
+          label: this.screenOptions.find(item => { return item.value == this.screenValue }).label,
+          content: this.screenInputValue,
+        }
+      )
+    },
+    // 分组监听事件
+    changeGrouping(val) { 
+      this.queryParams.current = 1
+      if (val == 'noGrouping') {//不分组
+        this.componentType='indiciaCard'
+      } else {
+        this.componentType = 'indiciaCollapse'
+        this.queryParams.grouping = val
+      }
+      this.isCollapse()
+    },
+    // 分页
+    handleCurrentChange(val) {
+      this.queryParams.current = val
+      this.isCollapse()
+    },
+    // 获取输入框提示信息
+    getPlaceholder() {
+      let a = this.screenOptions.filter(item => {
+        return item.value == this.screenValue
+      })
+      return a[0].placeholder
+    },
+    // 删除检索条件
+    handleDelete(val,index) {
+      this.searchOptions.splice(index, 1)
+      this.isCollapse()
+    },
+    // 子组件
+    collapseVal(val) {
+      this.getList(val)
+    },
+  },
+}
+</script>
+<style lang="scss" scoped>
+.indicia {
+  width: 100%;
+  height: 100%;
+  min-width: 950px;
+  background: white;
+
+  .indicia-top-components {
+    margin-bottom: 20px;
+    // padding-right: 40px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+  }
+
+  .indicia-top-select {
+    width: 150px;
+  }
+
+  .indicia-top-button {
+    margin-left: 10px;
+  }
+
+  .indicia-components {
+    margin-bottom: 20px;
+    overflow: auto;
+    // padding-right: 40px;
+  }
+  
+}
+</style>

+ 98 - 0
src/views/components/indicia/components/mixins.js

@@ -0,0 +1,98 @@
+export const importExcel = {
+  data() {
+    return {
+      res:'',//存储excel导出的tr、td
+    }
+  },
+  methods: {
+    importBtn() {
+      if (this.selected && this.selected.length>0) {//部分导出
+        
+      } else {//全部导出
+        
+      }
+      if (this.selected.length > 0) {
+        // 点击导出时获取勾选中标注的信息,放在selectedExportExcel数组中
+        this.selected.forEach(item => {
+          if (this.componentType == 'indiciaCard') {
+            var a = tableCollapseList.find(item1 => {
+              return item == item1.id
+            })
+            this.selectedExportExcel.push(a)
+            
+          }
+          // else {
+          //   this.collapseList.forEach(itemForEach => {
+          //     var a= itemForEach.data.find(item1 => {
+          //       return item == item1.scratchId
+          //     })
+          //     this.selectedExportExcel.push(a)
+          //   })
+          // }
+        })
+        // const fields = ['专利号','专利标题','标注','标注的位置','标注人','标注时间']
+        // this.importExcel(fields, this.selectedExportExcel)
+        const fields = {
+          remark: '标注',
+          nameAndDate: '标注人/时间',
+          // date: '标注时间',
+          address: '标注的位置',
+          patentNo: '专利号',
+          pName: '专利标题',
+        }
+        let title = '标注库'
+        this.exportExcel(fields, this.selectedExportExcel, title)
+        this.isExcel = !this.isExcel
+        this.selectedExportExcel = []
+        this.selected = []
+      } else {
+        this.$message.error('请先勾选标注再进行导出')
+        return false
+      }
+    },
+      // 导出excel方法
+      exportExcel(filesValue,dataExcel,title) {
+        // 拼接标题行
+        const head = Object.values(filesValue).map(item => {
+          return `<td style='background:#FFC000;font-weight: bold;'>${item}</td>`
+        }).join('')
+        // 拼接数据行
+        dataExcel.map(item => {
+          this.getStr(item, filesValue)
+        }).join()
+        const body = this.res
+        this.res=''
+        const worksheet = title
+        const url = 'data:application/vnd.ms-excel;base64,'
+  
+        // 下载的表格模板数据
+        const template = `<html xmlns:o="urn:schemas-microsoft-com:office:office"
+                        xmlns:x="urn:schemas-microsoft-com:office:excel"
+                        xmlns="http://www.w3.org/TR/REC-html40">
+                        <head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet>
+                        <x:Name>${worksheet}</x:Name>
+                        <x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet>
+                        </x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]-->
+                      </head><body><table><tr style="mso-number-format:'\@';height:45px;line-height:45px;text-align:center;width:150px;">${head}</tr>${body}</table></body></html>`
+        // 下载模板
+        let link = document.createElement('a')
+        link.setAttribute('href', url + window.btoa(unescape(encodeURIComponent(template))))
+        link.setAttribute('download', title + '.xls')
+        link.click()
+        
+      },
+      getStr(item, filesValue) {
+        this.res += `<tr style="mso-number-format:'\@';height:80px;line-height:80px;text-align:center;" >`
+        for (const key in filesValue) {
+          if (key == 'address') {
+            this.res += `<td style='width:150px'>${'[' + item.scratchField + ']' + item.text}</td>`
+          } else if (key == 'nameAndDate') {
+            this.res += `<td style='width:150px'>${ item.name + '&nbsp;' + item.date}</td>`
+          } else {
+            this.res += `<td style='width:150px'>${item[key]}</td>`
+          }
+        }
+        this.res += '</tr>'
+      },
+  },
+}

+ 30 - 0
src/views/components/indicia/index.vue

@@ -0,0 +1,30 @@
+<template>
+  <div>
+    <indicia></indicia>
+  </div>
+</template>
+
+<script>
+import indicia from './components/indicia.vue'
+export default {
+  components: {
+    indicia,
+  },
+  data() {
+    return {
+
+    }
+  },
+  computed: {
+    
+  },
+  mounted() {
+
+  },
+  methods: {
+
+  },
+}
+</script>
+
+<style lang="scss" scoped></style>

+ 105 - 0
src/views/project/patentCollection/components/dialog/MergeApplicantExist.vue

@@ -0,0 +1,105 @@
+<template>
+  <div>
+    <el-dialog title="合并数据" :visible.sync="visible" width="900px" top="3vh" append-to-body destroy-on-close :before-close="close">
+      <el-form :inline="true">
+        <el-form-item label="当前名称">
+          <el-input v-model="queryParams.name" size="small" placeholder="请输入当前名称"></el-input>
+        </el-form-item>
+        <el-form-item label="标准名称">
+          <el-input v-model="queryParams.shortName" size="small" placeholder="请输入标准名称"></el-input>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="" size="small" @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 prop="name" label="当前名称" align="center" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="shortName" label="标准名称" align="center" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="countryName" label="国家" align="center" width="150" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="addressStr" label="地址" align="center" show-overflow-tooltip></el-table-column>
+        <el-table-column label="操作" width="80" align="center">
+          <template slot-scope="scope">
+            <el-link type="danger" @click="handleDelete(scope.row)" v-if="$permission('/workspace/folder/merge/applicationMerge/merged/remove')">移除</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 slot="footer" class="dialog-footer">
+        <el-button @click="visible = false">关 闭</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      visible: false,
+      loading: false,
+      tableData: [],
+      total: 0,
+      queryParams: {
+        name: '',
+        country: '',
+        address: '',
+        size: 10,
+        current: 1,
+        projectId: 0,
+        order: 'desc',
+        prop: 'update_time',
+        from: 'exist',
+        mergeId: 0
+      },
+    }
+  },
+  methods: {
+    open(row) {
+      this.visible = true
+      this.queryParams.projectId = row.projectId
+      this.queryParams.mergeId = row.id
+      this.getList()
+    },
+    close() {
+      this.visible = false
+      this.$emit('close')
+    },
+    getList() {
+      this.loading = true
+      this.$api.getPatentApplicantList(this.queryParams).then(response => {
+        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();
+    },
+    handleDelete(row) {
+      this.$confirm('确认删除本条数据吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.loading = true
+        this.$api.deletePatentMergeApplicant({ id: row.id, mergeId: this.queryParams.mergeId }).then(response => {
+          this.$message.success('删除成功')
+          this.loading = false
+          this.getList()
+        }).catch(error => {
+          this.loading = false
+        })
+      })
+    },
+  }
+}
+</script>
+
+<style lang="less">
+
+</style>

+ 125 - 0
src/views/project/patentCollection/components/dialog/MergeApplicantForm.vue

@@ -0,0 +1,125 @@
+<template>
+  <div>
+    <el-dialog :title="title" :visible.sync="visible" width="500px"  append-to-body destroy-on-close :before-close="close" top="10vh">
+      <div class="patent-applicant-merge-form">
+        <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="80px">
+          <el-form-item label="名称" prop="name">
+            <el-input v-model="ruleForm.name" placeholder="请输入名称"></el-input>
+          </el-form-item>
+          <el-form-item label="简称" prop="abbreviation">
+            <el-input v-model="ruleForm.abbreviation" placeholder="请输入名称"></el-input>
+          </el-form-item>
+          <el-form-item label="国家" prop="country">
+            <el-select v-model="ruleForm.country" placeholder="请选择" filterable class="width_100">
+              <el-option v-for="(item, index) in commonData.COUNTRIES" :label="item.label" :value="item.value"></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="地址" prop="addressIds">
+            <el-cascader @change="onChange" v-model="addressIds" :options="areaOptions" :props="props" class="width_100"></el-cascader>
+          </el-form-item>
+          <el-form-item label="详细地址" prop="address">
+            <el-input v-model="ruleForm.address" placeholder="请输入地址"></el-input>
+          </el-form-item>
+          <el-form-item label="备注" prop="remark">
+            <el-input v-model="ruleForm.remark" placeholder="请输入备注" type="textarea"></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="submit" :loading="btnLoading">下一步</el-button>
+      </div>
+    </el-dialog>
+
+    <MergeApplicantSelectDialog ref="MergeApplicantSelectDialog" @selectClose="selectClose"></MergeApplicantSelectDialog>
+  </div>
+</template>
+
+<script>
+import MergeApplicantSelectDialog from "../dialog/MergeApplicantSelect";
+export default {
+  components: {
+    MergeApplicantSelectDialog,
+  },
+  data() {
+    return {
+      commonData: {},
+      addressIds: [],
+      areaOptions: [],
+      visible: false,
+      loading: false,
+      title: '',
+      btnLoading: false,
+      props: {
+        value: 'id',
+        label: 'name'
+      },
+      ruleForm: {},
+      rules: {
+        name: [{ required: true, message: '请输入名称', trigger: 'blur' },],
+      },
+    }
+  },
+  mounted() {
+  },
+  methods: {
+    // 添加成功返回的消息
+    selectClose() {
+      this.close()
+    },
+    // 打开弹窗
+    open(form, title, commonData, areaOptions) {
+      this.ruleForm = { ...form }
+      this.commonData = commonData
+      this.areaOptions = areaOptions
+      this.visible = true
+      this.title = title
+    },
+    // 关闭弹窗
+    close() {
+      this.visible = false
+      this.$emit('close')
+    },
+    submit() {
+      this.$refs.ruleForm.validate((valid) => {
+        if (valid) {
+          this.$refs.MergeApplicantSelectDialog.open(this.ruleForm)
+          // this.btnLoading = true
+          // this.ruleForm.merge = true
+          // if (this.ruleForm.id) {
+          //   this.$api.updateMergePerson(this.ruleForm).then(response => {
+          //     this.$message.success('编辑成功')
+          //     this.btnLoading = false
+          //     this.close()
+          //   }).catch(error => {
+          //     this.btnLoading = false
+          //   })
+          // } else {
+          //   this.$api.mergePerson(this.ruleForm).then(response => {
+          //     this.$message.success('新增成功')
+          //     this.btnLoading = false
+          //     this.close()
+          //   }).catch(error => {
+          //     this.btnLoading = false
+          //   })
+          // }
+        } else {
+          // console.log('error submit!!');
+          return false;
+        }
+      });
+    },
+    onChange() {
+      this.ruleForm.provinceId = this.addressIds[0]
+      this.ruleForm.cityId = this.addressIds[1]
+      this.ruleForm.areaId = this.addressIds[2]
+    },
+  }
+}
+</script>
+
+<style lang="scss">
+.patent-applicant-merge-form {
+
+}
+</style>

+ 231 - 0
src/views/project/patentCollection/components/dialog/MergeApplicantSelect.vue

@@ -0,0 +1,231 @@
+<template>
+  <div>
+    <el-dialog title="选择申请人/权利人" :visible.sync="visible" width="900px" append-to-body destroy-on-close
+      :before-close="close" top="3vh">
+      <div class="patent-applicant-merge-select">
+        <el-form :inline="true">
+          <el-form-item label="当前名称">
+            <el-input v-model="queryParams.name" size="small" placeholder="请输入当前名称"></el-input>
+          </el-form-item>
+          <!-- <el-form-item label="标准名称">
+            <el-input v-model="queryParams.shortName" size="small" placeholder="请输入标准名称"></el-input>
+          </el-form-item> -->
+          <el-form-item>
+            <el-button type="primary" size="small" @click="getList">查询</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 align="center" width="55">
+            <!-- <template slot="header">
+              <el-checkbox :checked="selectAll" @change="onChange3"></el-checkbox>
+            </template> -->
+            <template slot-scope="scope">
+              <el-checkbox :label="scope.row.name" @change="onChange(scope.row)" v-if="!loading"
+                :checked="ruleForm.mergedName.indexOf(scope.row.name) !== -1"></el-checkbox>
+            </template>
+          </el-table-column>
+          <el-table-column sortable="custom" prop="name" label="当前名称" align="center"
+            show-overflow-tooltip></el-table-column>
+          <!-- <el-table-column sortable="custom" prop="shortName" label="标准名称" align="center" show-overflow-tooltip></el-table-column>
+          <el-table-column sortable="custom" prop="merge" label="是否合并" align="center" show-overflow-tooltip>
+            <template slot-scope="scope">
+              <span v-if="scope.row.merge">是</span>
+              <span v-else>否</span>
+            </template>
+          </el-table-column> -->
+          <el-table-column sortable="custom" prop="countryName" label="国家" align="center" width="150"
+            show-overflow-tooltip></el-table-column>
+          <el-table-column prop="addressStr" label="地址" align="center" show-overflow-tooltip></el-table-column>
+        </el-table>
+        <div class="pagination">
+          <el-pagination :current-page.sync="queryParams.pageNum" :page-size="queryParams.pageSize" :total="total"
+            @current-change="handleCurrentChange" layout="total, prev, pager, next, jumper" background></el-pagination>
+        </div>
+      </div>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="close">关 闭</el-button>
+        <el-button type="primary" @click="submit" :loading="btnLoading">确 定</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      selectAll: false,
+      visible: false,
+      loading: false,
+      btnLoading: false,
+      total: 0,
+      tableData: [],
+      queryParams: {
+        name: '',
+        // shortName: '',
+        pageSize: 10,
+        pageNum: 1,
+        projectId: 0,
+        // prop: 'id',
+        // order: 'desc',
+        // from: 'select',
+        // mergeId: 0
+      },
+    }
+  },
+  mounted() {
+  },
+  methods: {
+    open(row) {
+      
+      this.ruleForm = { ...row }
+      if (row.id) {
+        
+      } else {
+        this.$set(this.ruleForm, 'mergedName', [])
+      }
+      this.visible = true
+      this.selectAll = false
+      this.queryParams.projectId = row.projectId
+      this.queryParams.pageNum = 1
+      // this.queryParams.mergeId = row.id
+      this.getList()
+    },
+    close() {
+      this.visible = false
+    },
+    sortChange({ column, prop, order }) {
+      if (!order) {
+        this.queryParams.prop = 'id'
+        this.queryParams.order = 'desc'
+        this.getList()
+        return false
+      }
+      const o = {
+        'descending': 'desc',
+        'ascending': 'asc',
+      }
+      switch (prop) {
+        case 'shortName':
+          this.queryParams.prop = 'bname'
+          break
+        case 'countryName':
+          this.queryParams.prop = 'country'
+          break
+        default:
+          this.queryParams.prop = prop
+      }
+      this.queryParams.order = o[order]
+      this.getList()
+    },
+    onChange(row) {
+      const index = this.ruleForm.mergedName.indexOf(row.name)
+      if (index === -1) {
+        this.ruleForm.mergedName.push(row.name)
+      } else {
+        this.ruleForm.mergedName.splice(index, 1)
+      }
+    },
+    onChange3() {
+      this.selectAll = !this.selectAll
+      if (this.selectAll) {
+        let params = {
+          ...this.queryParams,
+          type: 0,
+        }
+        params.pageSize = 9999999
+        this.loading = true
+        this.$api.getMergePerson(params).then(response => {
+          this.ruleForm.mergedName = response.data.data.map(item => item.name)
+          this.loading = false
+        }).catch(error => {
+          this.loading = false
+        })
+      } else {
+        this.loading = true
+        this.ruleForm.mergedName = []
+        this.$nextTick(() => {
+          this.loading = false
+        })
+      }
+    },
+    // 获取人员信息
+    getList() {
+      this.loading = true
+      let params = {
+        type: 0,
+        ...this.queryParams
+      }
+      this.$api.getMergePerson(params).then(response => {
+        this.tableData = response.data.data
+        this.total = response.data.total
+        this.loading = false
+      }).catch(error => {
+        this.loading = false
+      })
+    },
+    handleCurrentChange(val) {
+      this.queryParams.pageNum = val;
+      this.getList();
+    },
+    // 确认按钮
+    submit() {
+      if (this.ruleForm.mergedName.length === 0) {
+        this.$message.error('请选择申请人')
+        return false
+      }
+      this.btnLoading = true
+      let params = {
+        type: 0,
+        ...this.ruleForm,
+      }
+      if (this.ruleForm.id) {
+        this.$api.updateMergePerson(params).then(response => {
+          if (response.code == 200) {
+            this.$message.success('编辑成功')
+            this.btnLoading = false
+            this.$emit('selectClose')
+            this.close()
+          }
+        }).catch(error => {
+          this.btnLoading = false
+        })
+      } else {
+        this.$api.mergePerson(params).then(response => {
+          if (response.code == 200) {
+            this.$message.success('新增成功')
+            this.btnLoading = false
+            this.$emit('selectClose')
+            this.close()
+          }
+        }).catch(error => {
+          this.btnLoading = false
+        })
+      }
+
+
+      // this.$api.editPatentApplicant(this.ruleForm).then(response => {
+      //   this.$message.success('编辑成功')
+      //   this.btnLoading = false
+      //   this.close()
+      // }).catch(error => {
+      //   this.btnLoading = false
+      // })
+    },
+  }
+}
+</script>
+
+<style lang="scss">
+.patent-applicant-merge-select {
+  .pagination {
+    text-align: center;
+    margin: 20px 0;
+  }
+
+  .el-checkbox__label {
+    display: none !important;
+  }
+}
+</style>

+ 218 - 0
src/views/project/patentCollection/components/drawer/MergeApplicant.vue

@@ -0,0 +1,218 @@
+<template>
+  <!-- 合并申请人、权利人 -->
+  <div class="">
+    <el-drawer class="custom-drawer-form" title="合并申请人/权利人" size="1000px" :visible.sync="drawer" direction="rtl"
+      :before-close="close" destroy-on-close>
+      <el-container class="patent-applicant-merge">
+        <el-header style="display:flex;align-items:center;justify-content: space-between;">
+          <div>
+            <el-form :inline="true" class="margin-left_20">
+              <el-form-item label="名称">
+                <el-input v-model="queryParams.name" size="small" placeholder="请输入名称"></el-input>
+              </el-form-item>
+              <el-form-item label="国家">
+                <el-select v-model="queryParams.country" size="small" placeholder="请选择" clearable filterable>
+                  <el-option v-for="(item, index) in commonData.COUNTRIES" :label="item.label"
+                    :value="item.value"></el-option>
+                </el-select>
+              </el-form-item>
+              <el-form-item>
+                <el-button type="primary" size="small" @click="getList">查询</el-button>
+                <!-- <el-button type="primary" size="small" @click="handleAdd()" :disabled="!$permission('/workspace/folder/merge/applicationMerge/add')">新增</el-button> -->
+              </el-form-item>
+            </el-form>
+          </div>
+          <div style="padding-right: 10px;">
+            <el-button type="primary" size="small" @click="handleAdd()">新增</el-button>
+          </div>
+        </el-header>
+        <el-main class="container-common-main">
+          <el-table v-loading="loading" :data="tableData" border header-row-class-name="custom-table-header">
+            <el-table-column type="index" label="#" width="55" align="center"></el-table-column>
+            <el-table-column prop="name" label="名称" align="center" show-overflow-tooltip></el-table-column>
+            <el-table-column prop="countryName" label="国家" align="center" show-overflow-tooltip></el-table-column>
+            <el-table-column prop="addressStr" label="地址" align="center" show-overflow-tooltip></el-table-column>
+            <el-table-column prop="createTime" label="更新时间" align="center" show-overflow-tooltip>
+            </el-table-column>
+            <el-table-column prop="remark" label="备注" align="center" show-overflow-tooltip></el-table-column>
+            <el-table-column label="操作" align="center" width="150">
+              <template slot-scope="scope">
+                <el-dropdown split-button type="primary" size="small">
+                  <span @click="handleEdit(scope.row)" v-if="$permission('/workspace/folder/merge/applicationMerge/modify')">
+                    编辑</span>
+                  <span v-else :disabled="true">编辑</span>
+                  <el-dropdown-menu slot="dropdown" class="text-align_center">
+                    <!-- <el-dropdown-item @click.native="handleSelect(scope.row)" :disabled="!$permission('/workspace/folder/merge/applicationMerge/addApplication')">添加申请人</el-dropdown-item> -->
+                    <el-dropdown-item @click.native="handleExist(scope.row)"
+                      :disabled="!$permission('/workspace/folder/merge/applicationMerge/merged')">已合并</el-dropdown-item>
+                    <el-dropdown-item divided class="color-red" @click.native="handleDelete(scope.row)"
+                      :disabled="!$permission('/workspace/folder/merge/applicationMerge/delete')">删除</el-dropdown-item>
+                  </el-dropdown-menu>
+                </el-dropdown>
+              </template>
+            </el-table-column>
+          </el-table>
+          <div class="pagination">
+            <el-pagination :current-page.sync="queryParams.pageNum" :page-size="queryParams.pageSize" :total="total"
+              @current-change="handleCurrentChange" layout="total, prev, pager, next, jumper" background></el-pagination>
+          </div>
+        </el-main>
+        <el-footer class="footer-common">
+          <el-button @click="close">关 闭</el-button>
+        </el-footer>
+      </el-container>
+    </el-drawer>
+
+    <merge-applicant-exist-dialog ref="mergeApplicantExistDialog" @close="close2" />
+
+    <!-- <merge-applicant-select-dialog ref="mergeApplicantSelectDialog" @close="close2" /> -->
+
+    <merge-applicant-form-dialog ref="mergeApplicantFormDialog" @close="close2" />
+  </div>
+</template>
+
+<script>
+import MergeApplicantExistDialog from "../dialog/MergeApplicantExist";
+import MergeApplicantFormDialog from "../dialog/MergeApplicantForm";
+
+export default {
+  components: {
+    // MergeApplicantSelectDialog,
+    MergeApplicantFormDialog,
+    MergeApplicantExistDialog
+  },
+  data() {
+    return {
+      drawer: false,
+      loading: false,
+      total: 0,
+      tableData: [],
+      projectId: 0,
+      commonData: {},
+      queryParams: {
+        name: '',
+        country: '',
+        address: '',
+        pageSize: 10,
+        pageNum: 1,
+        projectId: 0,
+        // order: 'desc',
+        prop: 'id',
+        from: 'merge'
+      },
+      addressIds: [],
+      areaTree: []
+    }
+  },
+  mounted() {
+  },
+  methods: {
+    // 打开抽屉弹窗
+    open(projectId) {
+      this.projectId = projectId
+      this.queryParams.projectId = projectId
+      this.drawer = true
+      this.getList()
+      // this.getCommonData()
+      // this.getAreaList()
+    },
+    // 关闭抽屉弹窗
+    close() {
+      this.drawer = false
+      this.$emit('mergeClose')
+    },
+    // 获取表格数据
+    getList() {
+      this.loading = true
+      let params = {
+        type: 0,
+        ...this.queryParams,
+      }
+      this.$api.selectMergePerson(params).then(response => {
+        if (response.code == 200) {
+          this.tableData = response.data.data
+          this.total = response.data.total
+          this.loading = false
+        }
+
+      }).catch(error => {
+        this.loading = false
+      })
+    },
+    // 表格分页
+    handleCurrentChange(val) {
+      this.queryParams.pageNum = val;
+      this.getList();
+    },
+    close2() {
+      this.getList()
+    },
+    // 获取国家和地区
+    getCommonData() {
+      this.$api.getCommonData({ keys: 'COUNTRIES' }).then(response => {
+        this.commonData = response.data
+      })
+    },
+    // 获取中国所有地区(省、自治区、特别行政区)
+    getAreaList() {
+      this.$api.getArea().then(response => {
+        this.areaTree = response.data
+      })
+    },
+    // 打开新增合并人弹窗
+    handleAdd() {
+      this.$refs.mergeApplicantFormDialog.open({
+        projectId: this.queryParams.projectId,
+        applicantIds: [],
+        name: '',
+        remark: '',
+        shortName: '',
+        country: '',
+        address: '',
+        addressIds: []
+      }, '新增合并申请人', this.commonData, this.areaTree)
+    },
+    // 打开添加申请人弹窗
+    // handleSelect(row) {
+    //   this.$refs.mergeApplicantSelectDialog.open(row)
+    // },
+    // 打开已合并申请人弹窗
+    handleExist(row) {
+      this.$refs.mergeApplicantExistDialog.open(row)
+    },
+    // 打开编辑合并申请人弹窗
+    handleEdit(row) {
+      row.projectId = this.projectId
+      this.$refs.mergeApplicantFormDialog.open(row, '编辑合并申请人', this.commonData, this.areaTree)
+    },
+    // 删除表格数据
+    handleDelete(row) {
+      this.$confirm('确认删除本条数据吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.loading = true
+        this.$api.delMergePerson({ id: row.id }).then(response => {
+          if (response.code == 200) {
+            this.$message.success('删除成功')
+            this.loading = false
+            this.getList()
+          }
+        }).catch(error => {
+          this.loading = false
+        })
+      })
+    },
+  }
+}
+</script>
+
+<style lang="scss">
+.patent-applicant-merge {
+  .pagination {
+    text-align: center;
+    margin: 20px 0;
+  }
+}
+</style>

+ 173 - 0
src/views/project/patentCollection/components/drawer/MergeInventor.vue

@@ -0,0 +1,173 @@
+<template>
+  <!-- 合并发明人 -->
+  <div class="">
+    <el-drawer class="custom-drawer-form" title="合并发明人" size="1000px" :visible.sync="drawer" direction="rtl"
+      :before-close="close" destroy-on-close>
+      <el-container class="patent-inventor-merge">
+        <el-header style="display:flex;align-items:center;justify-content: space-between;">
+          <div>
+            <el-form :inline="true" class="margin-left_20">
+              <el-form-item label="名称">
+                <el-input v-model="queryParams.name" size="small" placeholder="请输入名称"></el-input>
+              </el-form-item>
+              <el-form-item>
+                <el-button type="primary" size="small" @click="getList">查询</el-button>
+                <!-- <el-button type="primary" size="small" @click="handleAdd()" :disabled="!$permission('/workspace/folder/merge/inventorMerge/add')">新增</el-button> -->
+              </el-form-item>
+            </el-form>
+          </div>
+          <div>
+            <el-button type="primary" size="small" @click="handleAdd()">新增</el-button>
+          </div>
+        </el-header>
+        <el-main class="container-common-main">
+          <el-table v-loading="loading" :data="tableData" border header-row-class-name="custom-table-header">
+            <el-table-column type="index" label="#" width="55" align="center"></el-table-column>
+            <el-table-column prop="name" label="名称" align="center" show-overflow-tooltip></el-table-column>
+            <el-table-column prop="createTime" label="更新时间" align="center" show-overflow-tooltip>
+              <!-- <template slot-scope="scope">
+                <span>{{ $d(scope.row.updateTime) }}</span>
+              </template> -->
+            </el-table-column>
+            <el-table-column prop="remark" label="备注" align="center" show-overflow-tooltip></el-table-column>
+            <el-table-column label="操作" align="center" width="150">
+              <template slot-scope="scope">
+                <el-dropdown split-button type="primary" size="small">
+                  <span @click="handleEdit(scope.row)"
+                    v-if="$permission('/workspace/folder/merge/inventorMerge/modify')">编辑</span>
+                  <span v-else :disabled="true">编辑</span>
+                  <el-dropdown-menu slot="dropdown" class="text-align_center">
+                    <el-dropdown-item class="color-red" @click.native="handleDelete(scope.row)"
+                      :disabled="!$permission('/workspace/folder/merge/inventorMerge/delete')">删除</el-dropdown-item>
+                  </el-dropdown-menu>
+                </el-dropdown>
+              </template>
+            </el-table-column>
+          </el-table>
+          <div class="pagination">
+            <el-pagination :current-page.sync="queryParams.pageNum" :page-size="queryParams.pageSize" :total="total"
+              @current-change="handleCurrentChange" layout="total, prev, pager, next, jumper" background></el-pagination>
+          </div>
+        </el-main>
+        <el-footer class="footer-common">
+          <el-button @click="close">关 闭</el-button>
+        </el-footer>
+      </el-container>
+    </el-drawer>
+
+    <patent-inventor-merge-manage-drawer ref="patentInventorMergeManageDrawer" @close="close2" />
+  </div>
+</template>
+
+<script>
+import PatentInventorMergeManageDrawer from "./MergeInventorManage";
+export default {
+  components: {
+    PatentInventorMergeManageDrawer
+  },
+  data() {
+    return {
+      drawer: false,
+      loading: false,
+      total: 0,
+      tableData: [],
+      projectId: 0,
+      queryParams: {
+        name: '',
+        // merge: true,
+        pageSize: 10,
+        pageNum: 1,
+        projectId: 0,
+        // order: 'desc'
+      },
+    }
+  },
+  mounted() {
+  },
+  methods: {
+    // 打开合并发明人抽屉弹窗
+    open(projectId) {
+      this.projectId = projectId
+      this.queryParams.projectId = projectId
+      this.drawer = true
+      this.getList()
+    },
+    // 关闭抽屉弹窗
+    close() {
+      this.drawer = false
+      this.$emit('mergeClose')
+    },
+    // 获取表格数据
+    getList() {
+      this.loading = true
+      let params = {
+        type: 2,
+        ...this.queryParams,
+      }
+      this.$api.selectMergePerson(params).then(response => {
+        if (response.code == 200) {
+          this.tableData = response.data.data
+          this.total = response.data.total
+          this.loading = false
+        }
+      }).catch(error => {
+        this.loading = false
+      })
+    },
+    // 分页信息
+    handleCurrentChange(val) {
+      this.queryParams.pageNum = val;
+      this.getList();
+    },
+    close2() {
+      this.getList()
+    },
+    // 打开新增弹窗
+    handleAdd() {
+      this.$refs.patentInventorMergeManageDrawer.open({
+        projectId: this.queryParams.projectId,
+        // mergedName: [],
+        name: '',
+        remark: '',
+      }, '新增合并')
+    },
+    // 编辑合并弹窗
+    handleEdit(row) {
+      row.projectId = this.projectId
+      this.$refs.patentInventorMergeManageDrawer.open(row, '编辑合并')
+    },
+    // 删除表格数据
+    handleDelete(row) {
+      this.$confirm('确认删除本条数据吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.loading = true
+        let params = {
+          id: row.id,
+          type: 2,
+        }
+        this.$api.delMergePerson(params).then(response => {
+          if (response.code == 200) {
+            this.$message.success('删除成功')
+            this.loading = false
+            this.getList()
+          }
+        }).catch(error => {
+          this.loading = false
+        })
+      })
+    },
+  }
+}
+</script>
+
+<style lang="scss">
+.patent-inventor-merge {
+  .pagination {
+    text-align: center;
+    margin: 20px 0;
+  }
+}
+</style>

+ 229 - 0
src/views/project/patentCollection/components/drawer/MergeInventorManage.vue

@@ -0,0 +1,229 @@
+<template>
+  <div class="patent-inventor-merge-manage">
+    <el-drawer class="custom-drawer-form" title="合并发明人" size="1000px" :visible.sync="drawer" direction="rtl"
+      :before-close="close" destroy-on-close>
+      <el-container>
+        <el-header>
+          <el-form :inline="true" class="margin-left_20">
+            <el-form-item label="名称">
+              <el-input v-model="queryParams.name" size="small" placeholder="请输入当前名称"></el-input>
+            </el-form-item>
+            <el-form-item>
+              <el-button type="" size="small" @click="getList">查询</el-button>
+            </el-form-item>
+          </el-form>
+        </el-header>
+        <el-main class="container-common-main">
+          <el-table v-loading="loading" :data="tableData" border header-row-class-name="custom-table-header">
+            <el-table-column align="center" width="55">
+              <!-- <template slot="header">
+                <el-checkbox :checked="selectAll" @change="onChange3"></el-checkbox>
+              </template> -->
+              <template slot-scope="scope">
+                <el-checkbox :label="scope.row.name" @change="onChange(scope.row)" v-if="!loading"
+                  :checked="ruleForm.mergedName.indexOf(scope.row.name) !== -1"></el-checkbox>
+              </template>
+            </el-table-column>
+            <el-table-column prop="name" label="名称" align="center" show-overflow-tooltip></el-table-column>
+            <el-table-column prop="address" label="地址" align="center" show-overflow-tooltip></el-table-column>
+            <el-table-column prop="remark" label="备注" align="center" show-overflow-tooltip></el-table-column>
+          </el-table>
+          <div class="pagination">
+            <el-pagination :current-page.sync="queryParams.pageNum" :page-size="queryParams.pageSize" :total="total"
+              @current-change="handleCurrentChange" layout="total, prev, pager, next, jumper" background></el-pagination>
+          </div>
+        </el-main>
+        <el-footer class="footer-common">
+          <el-button @click="close">关 闭</el-button>
+          <el-button type="primary" @click="dialogVisible = true">确 定</el-button>
+        </el-footer>
+      </el-container>
+    </el-drawer>
+
+    <el-dialog :title="title" :visible.sync="dialogVisible" width="500px" append-to-body destroy-on-close
+      :before-close="cancel">
+      <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="55px">
+        <el-form-item label="名称" prop="name">
+          <el-input v-model="ruleForm.name" placeholder="请输入名称"></el-input>
+        </el-form-item>
+        <el-form-item label="地址" prop="address">
+          <el-input v-model="ruleForm.address" placeholder="请输入地址" type="textarea"></el-input>
+        </el-form-item>
+        <el-form-item label="备注" prop="remark">
+          <el-input v-model="ruleForm.remark" placeholder="请输入备注" type="textarea"></el-input>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="cancel">取 消</el-button>
+        <el-button type="primary" @click="submit" :loading="btnLoading">确 定</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      selectAll: false,
+      drawer: false,
+      loading: false,
+      btnLoading: false,
+      total: 0,
+      tableData: [],
+      queryParams: {
+        name: '',
+        pageSize: 10,
+        pageNum: 1,
+        // order: 'desc',
+        // ids:'',
+      },
+      title: '',
+      dialogVisible: false,
+      ruleForm: {},
+      rules: {
+        name: [{ required: true, message: '请输入名称', trigger: 'blur' },],
+      },
+    }
+  },
+  mounted() {
+  },
+  methods: {
+    open(row, title) {
+      console.log(row);
+      this.ruleForm = { ...row }
+      if (row.id) {
+        
+      } else {
+        this.ruleForm.mergedName = []
+      }
+      this.title = title
+      this.drawer = true
+      this.selectAll = false
+      this.queryParams.projectId = row.projectId
+      this.queryParams.pageNum = 1
+      // this.queryParams.ids = row.inventorIds.toString()
+      this.getList()
+    },
+    close() {
+      this.drawer = false
+      this.$emit('close')
+    },
+    onChange2() {
+      this.ruleForm.provinceId = this.addressIds[0]
+      this.ruleForm.cityId = this.addressIds[1]
+      this.ruleForm.areaId = this.addressIds[2]
+    },
+    onChange(row) {
+      const index = this.ruleForm.mergedName.indexOf(row.name)
+      if (index === -1) {
+        this.ruleForm.mergedName.push(row.name)
+      } else {
+        this.ruleForm.mergedName.splice(index, 1)
+      }
+    },
+    onChange3() {
+      this.selectAll = !this.selectAll
+      if (this.selectAll) {
+        let params = {
+          ...this.queryParams,
+          type: 2,//发明人
+        }
+        params.pageSize = 9999999
+        this.loading = true
+        this.$api.getPatentInventorList(params).then(response => {
+          this.ruleForm.mergedName = response.data.records.map(item => item.name)
+          this.loading = false
+        }).catch(error => {
+          this.loading = false
+        })
+      } else {
+        this.loading = true
+        this.ruleForm.mergedName = []
+        this.$nextTick(() => {
+          this.loading = false
+        })
+      }
+    },
+    getList() {
+      this.loading = true
+      let params = {
+        ...this.queryParams,
+        type: 2,//发明人
+      }
+      this.$api.getMergePerson(params).then(response => {
+        if (response.code == 200) {
+          this.tableData = response.data.data
+          this.total = response.data.total
+          this.loading = false
+        }
+      }).catch(error => {
+        this.loading = false
+      })
+    },
+    handleCurrentChange(val) {
+      this.queryParams.pageNum = val;
+      this.getList();
+    },
+    cancel() {
+      this.dialogVisible = false
+    },
+    submit() {
+      if (this.ruleForm.mergedName.length === 0) {
+        this.$message.error('请选择发明人')
+        return false
+      }
+      this.$refs.ruleForm.validate((valid) => {
+        if (valid) {
+          this.btnLoading = true
+          // this.ruleForm.merge = true
+          let params = {
+            type: 2,//发明人
+            ...this.ruleForm
+          }
+          if (this.ruleForm.id) {
+            this.$api.updateMergePerson(params).then(response => {
+              if (response.code == 200) {
+                this.$message.success('编辑成功')
+                this.btnLoading = false
+                this.cancel()
+                this.close()
+              }
+            }).catch(error => {
+              this.btnLoading = false
+            })
+          } else {
+            this.$api.mergePerson(params).then(response => {
+              if (response.code == 200) {
+                this.$message.success('新增成功')
+                this.btnLoading = false
+                this.cancel()
+                this.close()
+              }
+
+            }).catch(error => {
+              this.btnLoading = false
+            })
+          }
+        } else {
+          // console.log('error submit!!');
+          return false;
+        }
+      });
+    },
+  }
+}
+</script>
+
+<style lang="scss">
+.patent-inventor-merge-manage {
+  .pagination {
+    text-align: center;
+    margin: 20px 0;
+  }
+
+  .el-checkbox__label {
+    display: none !important;
+  }
+}
+</style>

+ 7 - 8
src/views/project/patentCollection/components/mixins/index.js

@@ -79,7 +79,7 @@ export const handleData = {
   data() {
     return {
       //专利类型
-      patent_type: {
+      patentType: {
         1: '发明',
         8: '发明',
         2: '实用新型',
@@ -87,13 +87,13 @@ export const handleData = {
         3: '外观',
       },
       // 专利状态
-      simple_status: {
+      simpleStatus: {
         1: '有效',
         2: '无效',
         3: '审中',
       },
       // 法律状态(暂定)
-      legal_status: {
+      legalStatus: {
         1: '有效',
         2: '无效',
         3: '审中',
@@ -183,11 +183,10 @@ export const handleData = {
             obj.type = 'Array'
             var text = this.$commonJS.getColumnData(row, obj, prop, data)
             break;
-          case 'legal_status'://法律状态
-            break;
-          case 'simple_status'://专利状态
-            break;
-          case 'patent_type'://专利类型
+          case 'legalStatus'://法律状态
+          case 'simpleStatus'://专利状态
+          case 'patentType'://专利类型
+            var text = this[key][row[key]]
             break;
           default:
             var text = this.$commonJS.getColumnData(row, obj, prop, data)

+ 1 - 1
src/views/project/patentCollection/components/views/Abstract.vue

@@ -48,7 +48,7 @@
                     <span v-html="getView(patent, 'patentNo')"></span>
                   </el-link>
                   <el-tag class="margin-left_10" type="primary" effect="dark" size="small" v-if="patent.simpleStatus">{{
-                    simple_status[patent.simpleStatus] }}</el-tag>
+                    simpleStatus[patent.simpleStatus] }}</el-tag>
                 </div>
                 <div style="font-size: 13px;">
                   <el-row>

+ 12 - 0
src/views/project/patentCollection/components/views/Table.vue

@@ -65,6 +65,18 @@
               <span v-else>切换原文</span>
             </el-link>
           </template>
+          <!-- 法律状态 -->
+          <template v-else-if="item.value === 'legalStatus'">
+            <span v-html="getView(scope.row, 'legalStatus')"></span>
+          </template>
+          <!-- 专利状态 -->
+          <template v-else-if="item.value === 'simpleStatus'">
+            <span v-html="getView(scope.row, 'simpleStatus')"></span>
+          </template>
+          <!-- 专利类型 -->
+          <template v-else-if="item.value === 'patentType'">
+            <span v-html="getView(scope.row, 'patentType')"></span>
+          </template>
           <div v-else v-html="getView(scope.row, item.value, item.type)"></div>
         </template>
       </el-table-column>

+ 29 - 14
src/views/project/patentCollection/index.vue

@@ -78,10 +78,12 @@
                       合并<i class="el-icon-arrow-right el-icon--right"></i>
                     </p>
                     <el-dropdown-menu slot="dropdown">
-                      <el-dropdown-item @click.native="handleMerge2"
+                      <!-- <el-dropdown-item @click.native="handleMerge2"
                         :disabled="!($permission('/workspace/folder/merge/inventorMerge') && $r(projectId, [1, 2]))">发明人</el-dropdown-item>
                       <el-dropdown-item @click.native="handleMerge"
-                        :disabled="!($permission('/workspace/folder/merge/applicationMerge') && $r(projectId, [1, 2]))">申请人/权利人</el-dropdown-item>
+                        :disabled="!($permission('/workspace/folder/merge/applicationMerge') && $r(projectId, [1, 2]))">申请人/权利人</el-dropdown-item> -->
+                      <el-dropdown-item @click.native="handleMerge2">发明人</el-dropdown-item>
+                      <el-dropdown-item @click.native="handleMerge">申请人/权利人</el-dropdown-item>
                     </el-dropdown-menu>
                   </el-dropdown>
                 </el-dropdown-item>
@@ -92,7 +94,7 @@
                     </p>
                     <el-dropdown-menu slot="dropdown" style="margin-top:0px">
                       <!-- 遍历按钮 -->
-                      <el-dropdown-item @click.native="handleAnalyses(3)"
+                      <el-dropdown-item @click.native="handleAnalysesFto"
                         v-if="$permission('/workspace/createReport/FTO')">FTO调查</el-dropdown-item>
                     </el-dropdown-menu>
                   </el-dropdown>
@@ -180,6 +182,10 @@
     <addAndEditReport ref="addAndEditReport"></addAndEditReport>
     <!-- 批量那个标引 -->
     <PatentBatchIndexVue ref="PatentBatchIndexVue" :projectId="projectId"></PatentBatchIndexVue>
+    <!-- 合并权利人、申请人 -->
+    <patentApplicantMergeDrawer ref="patentApplicantMergeDrawer" @mergeClose="mergeClose"></patentApplicantMergeDrawer>
+    <!-- 合并发明人 -->
+    <patentInventorMergeDrawer ref="patentInventorMergeDrawer" @mergeClose="mergeClose"></patentInventorMergeDrawer>
   </div>
 </template>
 
@@ -197,6 +203,8 @@ import searchPatent from '@/views/report/components/patentList/components/search
 import reportFileDrawer from '@/views/report/components/drawer/reportFileDrawer.vue'
 import addAndEditReport from '@/views/report/components/dialog/addAndEditReport.vue'
 import PatentBatchIndexVue from './components/dialog/PatentBatchIndex.vue'
+import patentApplicantMergeDrawer from './components/drawer/MergeApplicant.vue'
+import patentInventorMergeDrawer from './components/drawer/MergeInventor.vue'
 export default {
   mixins: [fastSelectPatent],
   components: {
@@ -210,6 +218,8 @@ export default {
     reportFileDrawer,
     addAndEditReport,
     PatentBatchIndexVue,
+    patentApplicantMergeDrawer,
+    patentInventorMergeDrawer,
   },
   props: {},
   data() {
@@ -485,9 +495,9 @@ export default {
       this.$refs.reportFileDrawer.open(this.projectId)
     },
     //创建FTO报告
-    handleAnalyses(type) {
+    handleAnalysesFto() {
       var form = {
-        reportType: type,
+        reportType: 3,
         signPatentNo: '',
         matterId: [],
         scenarioId: [],
@@ -550,7 +560,7 @@ export default {
       }
       this.$api.pdfFirstPage(params).then(res => {
         if (res.code == 200) {
-          
+
         }
       })
       // let params = JSON.parse(JSON.stringify(this.queryParams))
@@ -589,6 +599,19 @@ export default {
       })
       window.open(router.href, '_blank');
     },
+    //合并申请人、权利人
+    handleMerge() {
+      this.$refs.patentApplicantMergeDrawer.open(this.projectId)
+    },
+    //合并发明人
+    handleMerge2() {
+      this.$refs.patentInventorMergeDrawer.open(this.projectId)
+    },
+    // 合并发明人、申请人、权利人后子组件发送的消息
+    mergeClose() {
+      this.getList()
+    },
+
 
 
 
@@ -608,14 +631,6 @@ export default {
 
 
 
-    //合并申请人
-    handleMerge() {
-      this.$refs.patentApplicantMergeDrawer.open(this.projectId)
-    },
-    //合并发明人
-    handleMerge2() {
-      this.$refs.patentInventorMergeDrawer.open(this.projectId)
-    },
 
 
     //下载PDF

+ 1 - 1
src/views/project/patentDetails/components/patentDetails.vue

@@ -18,7 +18,7 @@
               <div>
                 <span v-html="getViewDom(patent.patentNo)"></span>
                 <el-tag type="primary" effect="dark" size="mini" class="margin-left_10" v-if="patent.simpleStatus">{{
-                  simple_status[patent.simpleStatus] }}</el-tag>
+                  simpleStatus[patent.simpleStatus] }}</el-tag>
               </div>
               <div style="color: #6b6868; font-size: 15px;padding-bottom: 5px;">
                 <span v-html="getView(patent, 'title')"></span>

+ 2 - 2
src/views/project/patentDetails/components/patentMessage/PatentStatus.vue

@@ -3,13 +3,13 @@
 
     <div v-if="projectId">
       <!-- <div> <h3 class="patent-articles-patent-status-event">当前状态</h3></div>
-    <el-button type="success" size="mini">{{simple_status[patent.simpleStatus]}}</el-button> -->
+    <el-button type="success" size="mini">{{simpleStatus[patent.simpleStatus]}}</el-button> -->
       <div>
         <h3 class="patent-articles-patent-status-event">法律状态/事件</h3>
       </div>
       <!-- <el-button type="primary" size="mini">{{patent.legal_status&& patent.affair.length>0?patent.affair[0].status:''}}</el-button  > -->
       <!-- 后端没考虑好,暂时先不返 -->
-      <el-button type="primary" size="mini">{{ legal_status[patent.legal_status] }}</el-button>
+      <el-button type="primary" size="mini">{{ legalStatus[patent.legalStatus] }}</el-button>
     </div>
     <div>
       <h3 class="patent-articles-patent-status-event">事务数据</h3>