Forráskód Böngészése

Merge branch 'product' of http://1.116.113.26:8088/zhuliu/xiaoshi_system into product

zhuhao 1 éve
szülő
commit
c1cf4e4022

+ 1 - 1
src/config/index.js

@@ -3,5 +3,5 @@ export default {
     updateTime:'2023-08-04 08:00:00',
     specialDays:['05-12','09-18','12-13'],
     host: window.location.host,
-    staticURL: process.env.NODE_ENV === 'production' ? 'http://192.168.0.7:8081' : 'http://192.168.0.7:8081',
+    staticURL: process.env.NODE_ENV === 'production' ? '139.224.24.90' : '192.168.1.24',
 }

+ 10 - 9
src/router/index.js

@@ -73,15 +73,16 @@ const routes = [
             },
             component: () => import('@/views/project/patentCollection/index.vue')
           },
-          // {
-          //   path: 'folder/:id',
-          //   meta: {
-          //     title: '专利文章',
-          //     // button: [],
-          //     showProjectName:true
-          //   },
-          //   component: () => import('@/views/workspace/folder/articles')
-          // },
+          {
+            path: 'patentDetails/:patentNo',
+            name:'patentDetails',
+            meta: {
+              title: '专利文章',
+              sign:'patentDetails',
+              // belong:'project'
+            },
+            component: () => import('@/views/project/patentDetails/index.vue')
+          },
         ],
       },
       //企业专利数据库

+ 1 - 1
src/views/layout/mixins/index.js

@@ -4,7 +4,7 @@ import Store from '@/store'
 export const webSocket = {
   methods: {
     connectWebSocket(userId) {
-      let webSocket = new WebSocket(`ws://192.168.1.18:8877/api/xiaoshi/ws/` + userId)
+      let webSocket = new WebSocket(`ws://${this.$c.staticURL}:8877/api/xiaoshi/ws/` + userId)
       // let webSocket = new WebSocket(`ws://139.224.24.90:8871/permission/api/ws/` + userId)
       Store.commit('SET_WEB_SOCKET', webSocket)
       webSocket.onopen = () => {

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

@@ -35,7 +35,13 @@ export const projectData = {
   },
   methods: {
     // 点击专利号
-    handleClick(row,key){},
+    handleClick(row,key){
+      this.$router.push(
+        {
+          path:'patentDetails/'+row.patentNo
+        }
+      )
+    },
   },
 }
 

+ 1 - 1
src/views/project/patentCollection/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <div>
+  <div class="height_100">
     <el-container>
       <el-aside width="200px">Aside</el-aside>
       <el-container>

+ 17 - 3
src/views/project/patentDetails/components/patentDetails.vue

@@ -78,7 +78,7 @@
                     <my-view :position="this.positionList.find(item=>item.value == radio).position" :showView="radio!=1 && activeMenu != activeMenu2">
                         <div slot="left">
                             <component :activeName="activeName" style="width:100%;padding-right: 10px;"
-                              :is="componentName" :project-id="projectId" :patent="patent" :patentNo="[patent.patentNo]"
+                              :is="activeName" :project-id="projectId" :patent="patent" :patentNo="[patent.patentNo]"
                               :domId="patent.patentNo + '1'" 
                               @refresh="getPatent()"></component>
                         </div>
@@ -112,8 +112,23 @@
 </template>
 
 <script>
+import PatentBasic from './patentMessage/PatentBasic.vue'
+import PatentRight from './patentMessage/PatentRight.vue'
+import PatentImage from './patentMessage/PatentImage.vue'
+import PatentInstruction from './patentMessage/PatentInstruction.vue'
+import PatentFamily from './patentMessage/PatentFamily.vue'
+import PatentStatus from './patentMessage/PatentStatus.vue'
+import PatentPDF from './patentMessage/PatentPDF.vue'
 export default {
-  components: {},
+  components: {
+    PatentBasic,
+    PatentRight,
+    PatentImage,
+    PatentInstruction,
+    PatentFamily,
+    PatentStatus,
+    PatentPDF
+  },
   props: {
     projectId:{
         default:0
@@ -269,7 +284,6 @@ export default {
         this.changePosition(this.radio)
       }
       this.activeMenu = index
-      this.componentName = index
     },
     ending(val) {
       this.activeMenu2 = val

+ 15 - 8
src/views/project/patentDetails/components/patentMessage/PatentBasic.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="patent-basic"  @mouseup="mouseup">
+  <div class="patent-basic height_100"  @mouseup="mouseup">
     <el-row :gutter="24">
       <el-col :span="18" >
         <el-row :gutter="24">
@@ -18,8 +18,12 @@
           <tr v-if="$permission('/workspace/details/links')">
             <td width="80"><span class="patent-basic-label">外部链接:</span></td>
             <td>
-              <el-link type="primary" :href="`https://worldwide.espacenet.com/patent/search?q=${patent.publicNo}`" target="_blank" v-html="getViewDom('Espacenet')" style="margin-right: 15px;"></el-link>
-              <el-link type="primary" :href="`http://epub.cnipa.gov.cn/patent/${patent.publicNo}`" target="_blank" v-html="getViewDom('CNIPA')"></el-link>
+              <el-link type="primary" :href="`https://worldwide.espacenet.com/patent/search?q=${patent.publicNo}`" target="_blank"  style="margin-right: 15px;">
+                <span v-html="getViewDom('Espacenet')"></span>
+              </el-link>
+              <el-link type="primary" :href="`http://epub.cnipa.gov.cn/patent/${patent.publicNo}`" target="_blank" >
+                <span v-html="getViewDom('CNIPA')"></span>
+              </el-link>
             </td>
           </tr>
           <tr>
@@ -27,8 +31,13 @@
             <td>
               <div class="patent-label">
                 <template >
-                  <el-tag v-if="$permission('/workspace/details/deleteLabel') && $r(projectId,[1,2])" v-for="(label, index) in patent.label" effect="dark" type="primary" size="small" closable :disable-transitions="false" @close="handleCloseLabel(index)">{{ label.name }}</el-tag>
-                 <el-tag v-else v-for="(label, index) in patent.label" effect="dark" type="primary" size="small">{{ label.name }}</el-tag>
+                  <span v-if="$permission('/workspace/details/deleteLabel') && $r(projectId,[1,2])">
+                    <el-tag  v-for="(label, index) in patent.label" :key="label.name" effect="dark" type="primary" size="small" closable :disable-transitions="false" @close="handleCloseLabel(index)">{{ label.name }}</el-tag>
+                  </span>
+                 <span  v-else>
+                  <el-tag v-for="(label) in patent.label" :key="label.name" effect="dark" type="primary" size="small">{{ label.name }}</el-tag>
+                 </span>
+                 
                   <el-input
                       class="input-new-tag"
                       v-if="inputLabelVisible"
@@ -155,11 +164,9 @@
 </template>
 
 <script>
-import { commonMixins ,addContrast } from "./mixins"
-import { changeTranslation ,patentKeywordsHighlight} from "@/views/workspace/folder/components/mixins";
 
 export default {
-  mixins: [commonMixins, changeTranslation,addContrast,patentKeywordsHighlight],
+  mixins: [],
   data() {
     return {
       inputLabelVisible: false,

+ 187 - 0
src/views/project/patentDetails/components/patentMessage/PatentFamily.vue

@@ -0,0 +1,187 @@
+<template>
+  <div class="patent-articles-patent-family height_100">
+    <el-container>
+      <el-header>
+        <el-form :inline="true" style="" v-if="projectId">
+          <el-form-item label="同族类型">
+            <el-select v-model="type" size="small" @change="onChange">
+              <el-option label="简单同族" :value="1"></el-option>
+              <el-option label="INPADOC同族" :value="2"></el-option>
+              <el-option label="扩展同族" :value="3"></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="专利号">
+            <el-input v-model="queryParams.patentNo" 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>
+        <el-table v-loading="loading" :data="tableData" header-row-class-name="custom-table-header">
+          <el-table-column label="摘要附图" align="center" min-width="120px" show-overflow-tooltip> 
+            <template slot-scope="scope">
+              <div style="height: 150px;" class="picture">
+                <el-image v-if="scope.row.patentId !== -1 || (!projectId && scope.row.abstractPath2)" :src="scope.row.abstractPath2?scope.row.abstractPath2:getImagePath1(scope.row)" :preview-src-list="[scope.row.abstractPath2]"  :style="{width:style.width,height:style.height}">
+                  <div slot="error" class="image-slot">
+                    <img src="https://www.patentstar.com.cn/img/Common/nopic.jpg" alt="">
+                  </div>
+                </el-image>
+                <span v-else v-html="getViewDom(scope.row.name)"></span>
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column label="专利号" align="center" show-overflow-tooltip>
+            <template slot-scope="scope">
+              <span v-html="getViewDom(scope.row.patentNo)"></span>
+            </template>
+          </el-table-column>
+          <el-table-column label="专利名称" align="center" show-overflow-tooltip>
+            <template slot-scope="scope">
+              <span v-html="getViewDom(scope.row.name)"></span>
+            </template>
+          </el-table-column>
+          <el-table-column label="申请人" align="center" show-overflow-tooltip>
+            <template slot-scope="scope">
+              <div v-if="scope.row.patentId !== -1">
+                <span v-for="item in scope.row.applicant.filter(a => a.dataType === 2)" :key="item.name">
+                  <span v-html="getViewDom(item.name)"></span> <span>;</span>
+                </span>
+              </div>
+              <span v-else v-html="getViewDom(scope.row.name)"></span>
+            </template>
+          </el-table-column>
+          <el-table-column label="权利人" align="center" show-overflow-tooltip>
+            <template slot-scope="scope">
+              <div v-if="scope.row.patentId !== -1">
+                <span v-for="item in scope.row.applicant.filter(a => a.dataType === 1)" :key="item.name">
+                  <span v-html="getViewDom(item.name)"></span> <span>;</span>
+                </span>
+              </div>
+              <span v-else v-html="getViewDom(scope.row.name)"></span>
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-main>
+      <el-footer 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>
+      </el-footer>
+    </el-container>
+  </div>
+</template>
+
+<script>
+import { commonMixins } from "./mixins"
+
+export default {
+  mixins: [commonMixins],
+  data() {
+    return {
+      type: 1,
+      queryParams: {
+        familyId: 0,
+        patentNo: '',
+        current: 1,
+        size: 10,
+      },
+      loading: false,
+      tableData: [],
+      total: 0
+    }
+  },
+  watch: {
+    patentId() {
+      this.queryParams.current = 1
+      this.onChange()
+    },
+    patentNo(){
+      if(!this.projectId){
+        this.queryParams.current = 1
+        this.onChange()
+      }
+    }
+  },
+  mounted() {
+    this.onChange()
+  },
+  methods: {
+    getList() {
+      this.loading = true
+      this.$api.getPatentFamilyList(this.queryParams).then(response => {
+        this.tableData = response.data.records
+        this.total = response.data.total
+        this.loading = false
+      })
+    },
+    getData(){
+      this.loading = true
+        var params = {
+            patentCell:5,
+            patentNo:this.patent.publicNo,
+            appNo:this.patent.applicationNo,
+            current:this.queryParams.current,
+            size:this.queryParams.size
+          }
+        this.$api.getPatentPart(params).then(response=>{
+            if(response.code == 200){
+              this.tableData = response.data.familyPatentResult.records
+              this.tableData.forEach(item=>{
+                this.getFamilyImage(item)
+              })
+              this.total = response.data.familyPatentResult.total
+              this.loading = false
+            }
+        }).catch(error=>{
+          this.tableData= []
+          this.total = 0
+          this.loading = false
+        })
+    },
+    getFamilyImage(patent){
+      var params = {
+        patentCell:4,
+        patentNo:patent.publicNo,
+        appNo:patent.applicationNo,
+      }
+       this.$api.getPatentPart(params).then(response=>{
+            if(response.code == 200){
+              if(Object.keys(response.data).length>0 && response.data.image.length>0){
+                this.$set(patent,'abstractPath2',response.data.image[0].url)
+              }else{
+                this.$set(patent,'abstractPath2','q')
+              }
+              
+              this.getHeight(patent.abstractPath2, patent)
+            }
+        })
+    },
+    onChange() {
+      if(!this.projectId){
+        this.getData()
+        return false;
+      }
+      if (this.type === 1) {
+        this.queryParams.familyId = this.patent.simpleFamily
+      } else if(this.type === 2) {
+        this.queryParams.familyId = this.patent.inpadocFamily
+      }else{
+        this.queryParams.familyId = this.patent.patSnapFamily
+      }
+      this.getList()
+    },
+    handleCurrentChange(val) {
+      this.queryParams.current = val;
+      this.getList();
+    },
+  }
+}
+</script>
+
+<style lang="scss">
+.patent-articles-patent-family {
+  .el-image {
+    width: 100%;
+  }
+}
+</style>

+ 249 - 0
src/views/project/patentDetails/components/patentMessage/PatentImage.vue

@@ -0,0 +1,249 @@
+<template>
+  <div class="patent-image">
+    <div class="block">
+      <div class="demonstration">图片大小:</div>
+      <el-slider v-model="value"  @change="changeWidth" :min="25" :max="100" style="padding-left:90px"></el-slider>
+    </div>
+    <div class="imageCard">
+      <el-card class="preview" v-for="(item, index) in patent.image" :key="index" shadow="hover" :style="{width:width}">
+          <div slot="header" class="card-header" v-if="projectId">
+            <span></span>
+            <el-button :disabled="!$permission('/workspace/details/figureDelete')" class="delete" type="text" @click="handleDelete(item)">删除</el-button>
+            <el-button :disabled="!$permission('/workspace/details/figuremodify')" class="edit" type="text" @click="handleEdit(item)">编辑</el-button>
+          </div>
+          <div class="text-align_center">
+            <el-image :src="!projectId?item.url:getImagePath(item.url)" :preview-src-list="srcList" style="height: 100%; min-height:125px;"></el-image>
+          </div>
+      </el-card>
+    </div>
+
+    <div type="primary" class="up" v-if="$permission('/workspace/details/figureUpdata')&& projectId && $r(projectId,[1,2])" @click="handleAdd">上传图片</div>   
+
+    <el-dialog :title="title" :visible.sync="visible" width="500px" append-to-body destroy-on-close :before-close="close" top="22vh">
+      <el-form :model="form">
+        <el-form-item label="是否设置为摘要附图">
+          <el-radio-group v-model="form.status">
+            <el-radio :label="1">是</el-radio>
+            <el-radio :label="0">否</el-radio>
+          </el-radio-group>
+        </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="!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>
+      <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>
+import { commonMixins } from "./mixins"
+
+export default {
+  mixins: [commonMixins],
+  data() {
+    return {
+      value:25,
+      width:"25%",
+      srcList: [],
+      url: '',
+      title: '',
+      visible: false,
+      form: {},
+      file: null,
+      btnLoading: false
+    }
+  },
+  watch: {
+    patentId() {
+      this.srcList = this.patent.image.map(item => this.getImagePath(item.url))
+    },
+    'patent'(){
+
+    },
+    patentNo(){
+      if(!this.projectId){
+        this.getData()
+      }
+    }
+  },
+  mounted() {
+    if(this.patent.image){
+      this.srcList = this.patent.image.map(item => this.getImagePath(item.url))
+    }else{
+      if(!this.projectId){
+        this.getData()
+      }
+    }
+    
+    // console.log(this.patent)
+  },
+  methods: {
+    getData(){
+      var params = {
+            patentCell:4,
+            patentNo:this.patent.publicNo,
+            appNo:this.patent.applicationNo,
+          }
+        this.$api.getPatentPart(params).then(response=>{
+            if(response.code == 200){
+              if(Object.keys(response.data).length>0 && response.data.image.length>0){
+                this.$set(this.patent,'image',response.data.image)
+              }else{
+                this.$set(this.patent,'image',[])
+              }
+              this.srcList = this.patent.image.map(item=>item.url)
+            }
+        })
+    },
+    changeWidth(){
+      this.width=this.value+'%'
+    },
+    close() {
+      this.visible = false
+    },
+    onChange(file, fileList) {
+      this.file = file.raw
+    },
+    handleAdd() {
+      this.visible = true
+      this.title = '新增附图'
+      this.form = {
+        patentId: this.patent.id,
+        status: 0,
+        url: ''
+      }
+    },
+    handleEdit(row) {
+      this.visible = true
+      this.title = '编辑附图'
+      this.form = { ...row }
+    },
+    handleDelete(row) {
+      this.$confirm('确认删除本条数据吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.$api.deletePatentImage({ id: row.id }).then(response => {
+          this.$message.success('删除成功')
+          this.refreshPatent()
+        }).catch(error => {
+        })
+      })
+    },
+    refreshPatent() {
+      this.$emit('refresh')
+    },
+    submit() {
+      let formData = new FormData()
+      formData.append('patentId', this.form.patentId)
+      formData.append('status', this.form.status)
+      formData.append('url', this.form.url)
+      if (this.file) {
+        formData.append('file', this.file)
+      }
+      if (this.form.id) {
+        this.btnLoading = true
+        formData.append('id', this.form.id)
+        this.$api.editPatentImage(formData).then(response => {
+          this.btnLoading = false
+          this.$message.success('操作成功')
+          this.visible = false
+          this.file = null
+          this.refreshPatent()
+        }).catch(error => {
+          this.btnLoading = false
+        })
+      } else {
+        if (!this.file) {
+          this.$message.error('请选择文件')
+          return false
+        }
+        this.btnLoading = true
+        this.$api.uploadPatentImage(formData).then(response => {
+          this.btnLoading = false
+          this.$message.success('操作成功')
+          this.visible = false
+          this.file = null
+          this.refreshPatent()
+        }).catch(error => {
+          this.btnLoading = false
+        })
+      }
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+.up{
+  width: 70px;
+  height:30px;
+  line-height: 30px;
+  color: rgb(65, 65, 224);
+  cursor: pointer;
+  position: absolute;
+  right: 20px;
+  top: 0px;
+}
+.up:hover{
+  border-bottom: 1px solid rgb(45, 45, 235);
+}
+.block{
+  width: 60%;
+  margin: 0 auto;
+}
+.imageCard{
+  display: flex;
+  flex-direction: row;
+  flex-wrap: wrap;
+  justify-content: center;
+}
+.demonstration{
+  float: left;
+  line-height: 38px;
+  text-align: center;
+}
+.patent-image {
+  position: relative;
+  .delete {
+    float: right;
+    padding: 3px 0;
+    color: red;
+    padding-left: 10px;
+  }
+  .edit {
+    float: right;
+    padding: 3px 0;
+  }
+  .add {
+    font-size: 80px;
+    color: #6b6868;
+    margin-top: 60px;
+  }
+  .preview {
+    // height: 300px;
+    margin-right: 20px;
+    cursor: pointer;
+    text-align: center;
+    .card-header {
+      height: 20px;
+    }
+    .el-card__header {
+      border-bottom: 1px solid #EBEEF5;
+      font-weight: normal;
+    }
+  }
+  .el-image {
+    width: 100%;
+  }
+}
+</style>

+ 101 - 0
src/views/project/patentDetails/components/patentMessage/PatentInstruction.vue

@@ -0,0 +1,101 @@
+<template>
+  <div class="patent-instruction height_100"  @mouseup="mouseup">
+    <el-container>
+      <el-header>
+        <el-tabs v-model="name" @tab-click="handleClick">
+          <el-tab-pane v-for="item in tabs" :key="item.label" :label="item.label"  :name="item.name"></el-tab-pane>
+        </el-tabs>
+      </el-header>
+      <el-main>
+        <div v-html="getViewDom(patent.instruction, '说明书文本'+tabItem.label, tabItem.field)" :style="setStyle()" :data-type="'说明书文本'+tabItem.label"></div>
+      </el-main>
+    </el-container>
+  </div>
+</template>
+
+<script>
+// import { commonMixins,addContrast } from "./mixins"
+// import { patentKeywordsHighlight,changeTranslation } from "@/views/workspace/folder/components/mixins";
+export default {
+  // mixins: [commonMixins, patentKeywordsHighlight, changeTranslation, addContrast],
+  data() {
+    return {
+      height: null,
+      fullHeight: document.documentElement.clientHeight,
+      tabs:[
+        {
+          label:'原文',
+          name:0,
+          field:'manual'
+        },
+        {
+          label:'译文',
+          name:1,
+          field:'manualOut'
+        },
+      ],
+      tabItem:{
+          label:'原文',
+          name:0,
+          field:'manual'
+        },
+    }
+  },
+  watch: {
+    fullHeight() {
+      this.refresh()
+    },
+    patentNo(){
+      if(!this.projectId){
+        this.getData()
+      }
+    }
+  },
+  created() {
+    window.addEventListener('resize', this.handleResize)
+  },
+  mounted() {
+    this.handleResize()
+    if(!this.projectId){
+      this.getData()
+    }
+  },
+  methods: {
+    handleClick(){
+      this.tabItem  = this.tabs.find(item=>{
+        return item.name == this.name
+      })
+    },
+    getData(){
+      var params = {
+            patentCell:2,
+            patentNo:this.patent.publicNo,
+            appNo:this.patent.applicationNo,
+          }
+        this.$api.getPatentPart(params).then(response=>{
+            if(response.code == 200){
+              this.$set(this.patent,'instruction',response.data.instruction)
+            }
+        })
+    },
+    handleResize(event) {
+      this.fullHeight = document.documentElement.clientHeight
+      this.height = this.fullHeight - 300
+    },
+  }
+}
+</script>
+
+<style lang="scss">
+.patent-instruction {
+  margin-bottom: 20px;
+  .common {
+    overflow-y: auto;
+    white-space: pre-line;
+    font-size: 14px;
+    margin-top: 0;
+    padding-right: 5px;
+    word-break: break-all;
+  }
+}
+</style>

+ 215 - 0
src/views/project/patentDetails/components/patentMessage/PatentPDF.vue

@@ -0,0 +1,215 @@
+<template>
+  <div class="patent-pdf height_100">
+    <div v-if="!sign">
+      <el-button-group class="float_left margin-bottom_10" v-if="patent.pdf && patent.pdf.length>1">
+        <el-button size="small" :type="pdfType === 2 ? 'primary' : ''" @click="handleSelect(2)">授权文档</el-button>
+        <el-button size="small" :type="pdfType === 1 ? 'primary' : ''" @click="handleSelect(1)">公开文档</el-button>
+      </el-button-group>
+      <el-upload
+          class="float_right"
+          action="#"
+          :auto-upload="false"
+          :show-file-list="false"
+          :on-change="handleChange"
+          :multiple="false"
+      >
+        <el-button type="success" size="small" :loading="btnLoading" v-if="projectId" :disabled="!($permission('/workspace/details/updataInstruction') && $r(projectId,[1,2]))">上传文档</el-button>
+        <div slot="tip" class="el-upload__tip"></div>
+      </el-upload>
+    </div>
+    <iframe v-if="show" :src="src" frameborder="0" :height="height" width="100%"></iframe>
+    <div v-else class="no-pdf-file">
+      <span>暂无文档</span>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  props: ['patent', 'projectId','pdfType1','sign','patentNo'],
+  components: {},
+  data() {
+    return {
+      src: '',
+      fullHeight: document.documentElement.clientHeight,
+      height: 0,
+      show: false,
+      btnLoading: false,
+      pdfType: this.pdfType1||2,
+      pdf: null
+    }
+  },
+  watch: {
+    fullHeight() {
+      if(this.projectId){
+        this.refresh()
+      }
+    },
+    patent() {
+      if(this.projectId){
+        this.refresh()
+      }
+      
+    },
+    patentId() {
+      if(this.projectId){
+        this.refresh()
+      }
+    },
+    patentNo(){
+      if(!this.projectId){
+        this.getData()
+      }
+    }
+  },
+  created(){
+    window.addEventListener('resize', this.handleResize)
+  },
+  mounted() {
+    if(!this.projectId){
+      if(this.patent.pdf && this.patent.pdf.length>0){
+        this.show = false
+        this.height = (this.fullHeight - 230) + 'px'
+        var index = this.patent.pdf.findIndex(item => {
+          return item.type == 2
+        })
+        if (index != -1) {
+          this.pdfType = 2
+        } else {
+          this.pdfType = 1
+        }
+        this.getPDFSrc(this.pdfType)
+        // let blob = this.base64ToBlob(this.patent.pdf[0])
+        // this.$set(this,'src',URL.createObjectURL(blob))
+        // // this.src = this.patent.pdf[0].url
+        // this.$nextTick(() => {
+        //   this.show = true
+        // })
+      }else{
+        this.getData()
+      }
+      
+    }else{
+      this.refresh()
+    }
+  },
+  methods: {
+    getData(){
+      if(this.patent.pdf && this.patent.pdf.length>0){
+        return false
+      }
+      this.show  =false
+      this.height = (this.fullHeight - 230) + 'px'
+      var params = {
+            patentCell:3,
+            patentNo:this.patent.publicNo,
+            appNo:this.patent.applicationNo,
+          }
+        this.$api.getPatentPart(params).then(response=>{
+            if(response.code == 200){
+              if(Object.keys(response.data).length == 0){
+                return false
+              }
+              if(response.data.pdf.length==0){
+                return false
+              }
+              this.$set(this.patent,'pdf',response.data.pdf)
+              var index = this.patent.pdf.findIndex(item => {
+                return item.type == 2
+              })
+              if (index != -1) {
+                this.pdfType = 2
+              } else {
+                this.pdfType = 1
+              }
+              this.getPDFSrc(this.pdfType)
+            }
+        })
+    },
+    getPDFSrc(type) {
+      let blob = this.base64ToBlob(this.patent.pdf.find(item => { return item.type == type }))
+      this.$set(this, 'src', URL.createObjectURL(blob))
+      this.$nextTick(() => {
+        this.show = true
+      })
+    },
+    base64ToBlob(row){
+      var dataUrl = row.pictureStringData
+      let bstr = window.atob(dataUrl)
+      let n = bstr.length
+      let u8arr = new Uint8Array(n)
+      while (n--) {
+          u8arr[n] = bstr.charCodeAt(n);
+      }
+      return new Blob([u8arr], { type: "application/pdf" });
+    },
+    handleSelect(type) {
+      this.pdfType = type
+      if(!this.projectId){
+        this.show = false
+        this.height = (this.fullHeight - 230) + 'px'
+        this.getPDFSrc(type)
+        return false
+      }
+      this.refresh()
+    },
+    handleChange(file, fileList) {
+      if (file.name.split('.')[1].toLowerCase() !== 'pdf') {
+        this.$message.error('请选择PDF格式文件')
+        return false
+      }
+      let formData = new FormData()
+      formData.append('file', file.raw)
+      formData.append('type', this.pdfType)
+      formData.append('patentNo', this.patent.patentNo)
+      if (this.pdf) {
+        formData.append('url', this.pdf.url)
+      }
+      this.btnLoading = true
+      this.$api.editPatentInstruction(formData).then(response => {
+        this.$message.success('操作成功')
+        this.btnLoading = false
+        this.$emit('refresh')
+        this.refresh()
+      }).catch(error => {
+        this.btnLoading = false
+      })
+    },
+    refresh() {
+      this.show = false
+      this.height = (this.fullHeight - 230) + 'px'
+      this.pdf = this.patent.pdf.find(item => item.type === this.pdfType)
+      if (this.pdf) {
+        this.$api.getPatentInstructionFile({ patentNo: this.patent.patentNo, type: this.pdfType }).then(response => {
+          this.src = '/pdfjs/web/viewer.html?file=' + encodeURIComponent(window.URL.createObjectURL(response))
+          this.$nextTick(() => {
+            this.show = true
+          })
+        }).catch(error => {
+          this.$message.error('加载失败')
+        })
+      }
+    },
+    handleResize(event) {
+      this.fullHeight = document.documentElement.clientHeight
+    },
+  }
+}
+</script>
+
+<style lang="scss">
+.patent-pdf {
+  height: 100%;
+  .no-pdf-file {
+    float: left;
+    text-align: center;
+    width: 100%;
+    background: #e3e2e2;
+    height: calc(100% - 120px);
+    padding-top: 50px;
+    span {
+      font-size: 50px;
+    }
+  }
+}
+</style>

+ 392 - 0
src/views/project/patentDetails/components/patentMessage/PatentRight.vue

@@ -0,0 +1,392 @@
+<template>
+  <div class="patent-articles-patent-right height_100" @mouseup="mouseup">
+    <el-container>
+      <el-header>
+        <el-tabs v-model="name" @tab-click="handleClick">
+          <el-tab-pane v-for="item in tabs" :key="item.label" :label="item.label"  :name="item.name"></el-tab-pane>
+        </el-tabs>
+      </el-header>
+      <el-main>
+        <div v-if="name != 2" v-html="getViewDom1(patent.rights, '权利要求'+tabItem.label, tabItem.field)" :style="setStyle()" :data-type="'权利要求'+tabItem.label"></div>
+        <div v-else>
+          <my-view>
+            <div slot="left">
+              <myTree :list="patent.patentRightTree" style="height: 100%" :props="{
+                name:'content',
+                children:'children'
+              }" nodeKey="sort" :expends="expends"></myTree>
+            </div>
+            <div slot="right">
+              <div id="charts" style="max-width: 100%; min-width: 300px;position:relative;padding-top: 10px;"  v-if="show">
+                <div v-for="(item,index) in this.patent.patentRightTree" :key="index" :id="'chart'+index" style="width:500px;margin:0 auto;"></div>
+              </div>
+              <div style="position:absolute;top:10px;right:20px;">
+                <el-link type="primary" @click="imageDownLoad">下载为图片</el-link>
+              </div>
+            </div>
+          </my-view>
+        </div>
+      </el-main>
+    </el-container>
+  </div>
+</template>
+
+<script>
+// import { commonMixins, addContrast } from "./mixins";
+// import { patentKeywordsHighlight, changeTranslation} from "@/views/workspace/folder/components/mixins";
+import html2canvas from "html2canvas"
+export default {
+  // mixins: [
+  //   commonMixins,
+  //   patentKeywordsHighlight,
+  //   changeTranslation,
+  //   addContrast,
+  // ],
+  data() {
+    return {
+      expends: [],
+      show:false,
+      isClickId: "",
+      height: null,
+      fullHeight: document.documentElement.clientHeight,
+      records: {
+        original: [],
+        translation: [],
+      },
+      scrollTop:0,
+      isClick:false,
+      tabs:[
+        {
+          label:'原文',
+          name:0,
+          field:'content'
+        },
+        {
+          label:'译文',
+          name:1,
+          field:'contentOut'
+        },
+        {
+          label:'权要树',
+          name:2,
+          field:'contentOut'
+        },
+      ],
+      tabItem:{
+          label:'原文',
+          name:0,
+          field:'content'
+        },
+    };
+  },
+  watch: {
+    // fullHeight() {
+    //   this.refresh();
+    // },
+    patentId() {
+      this.initData();
+      if(this.name == 2){
+        this.show = false
+        this.expends = []
+        this.isClickId  = ''
+        this.$nextTick(()=>{
+           this.handleClick()
+        })
+      }
+    },
+    patentNo() {
+      if (!this.patentId) {
+        this.initData();
+        if(this.name == 2){
+          this.show = false
+          this.expends = []
+          this.isClickId  = ''
+          this.$nextTick(()=>{
+            this.handleClick()
+          })
+        }
+      }
+    },
+    name(){
+      if(this.name!=2){
+        this.show = false
+      }
+    },
+  },
+  created() {
+    window.addEventListener("resize", this.handleResize);
+  },
+  mounted() {
+    this.handleResize();
+    this.initData();
+  },
+  methods: {
+    handleClick(tab, event) {
+      this.tabItem  = this.tabs.find(item=>{
+        return item.name == this.name
+      })
+      this.show = true
+      if (this.name == 2 && !this.patent.patentRightTree) {
+        this.$api
+          .queryPatentRightTree({ patentNo: this.patent.patentNo })
+          .then((response) => {
+            if (response.code == 200) {
+              this.$set(this.patent, "patentRightTree", response.data);
+              this.$nextTick(()=>{
+                this.getEchart();
+              })
+             
+            }
+          });
+      } else if(this.name == 2 && this.patent.patentRightTree) {
+        this.$nextTick(()=>{
+          this.getEchart();
+        })
+      }
+    },
+    imageDownLoad(){
+      var dom = document.getElementById('charts')
+      html2canvas(dom).then(canvas => {
+        // 转成图片,生成图片地址
+         var imgUrl = canvas.toDataURL("image/png");
+         var blob = this.base64ToBlob(imgUrl)
+         var eleLink = document.createElement("a");
+          eleLink.href = URL.createObjectURL(blob); // 转换后的图片地址
+          eleLink.download = "权要树";
+          document.body.appendChild(eleLink);
+          // 触发点击
+          eleLink.click();
+          // 然后移除
+          document.body.removeChild(eleLink);
+        
+        // const link = document.createElement('a')
+        // let url = URL.createObjectURL(blob)
+        // link.href = url
+        // link.download = item.url.substring(0,item.url.indexOf('?'))
+        // link.click()
+    });
+    },
+    base64ToBlob(data){
+      var dataUrl = data.replace('data:image/png;base64,','')
+      let bstr = window.atob(dataUrl)
+      let n = bstr.length
+      let u8arr = new Uint8Array(n)
+      while (n--) {
+          u8arr[n] = bstr.charCodeAt(n);
+      }
+      return new Blob([u8arr], { type: "image/png" });
+    },
+    getData(data) {
+      data.forEach((item) => {
+        item.name = Number(item.sort) + 1;
+        if (item.children && item.children.length > 0) {
+          this.getData(item.children);
+        }
+      });
+    },
+    getEchart() {
+      var data = JSON.parse(JSON.stringify(this.patent.patentRightTree));
+      this.getData(data);
+      var that = this
+      data.forEach((item,index) => {
+        var option = {
+        // height: "100%",
+        backgroundColor: "#fbfbfb",
+        series: [
+          {
+          itemStyle: {
+            normal: {
+              color: "#06c",
+              borderColor: "#06c",
+            },
+            emphasis: {
+              borderColor: "#06c",
+              color: "#06c",
+            },
+          },
+          lineStyle: {
+            color: "#2979ff",
+          },
+          type: "tree",
+          data: [item],
+          // top: "1%",
+          left: "100px",
+          // bottom: "1%",
+          right: "100px",
+          symbolSize: 0,
+          symbol: "emptyCircle",
+          label: {
+            position: "left",
+            verticalAlign: "middle",
+            align: "right",
+            color: "#293c55",
+            margin: [2, 4],
+            borderWidth: 1,
+            borderColor: "#aaa",
+            backgroundColor: "white",
+            borderRadius: 2,
+            padding: [5, 4],
+            rich: {
+              keywords: {
+                color: "red",
+                fontSize: "12",
+              },
+              index: {
+                fontSize: 12,
+                color: "#2979ff",
+                position: "10%",
+              },
+            },
+            formatter: function(data, data1) {
+              // rgb(178, 215, 255)
+              if(data.data.sort+'' == that.isClickId){
+                data.data.label = {
+                  fontSize: 12,
+                  padding: [5, 4],
+                  backgroundColor: 'rgb(178, 215, 255)',
+                  borderColor: '#aaa',
+                  color: '#293c55',
+                }
+              // }else{
+                // data.data.label = {
+                //   fontSize: 12,
+                //   padding: [5, 4],
+                //   backgroundColor: 'white',
+                //   borderColor: '#aaa',
+                //   color: '#293c55',
+                // }
+              }
+            },
+          },
+          leaves: {
+            label: {
+              position: "right",
+              verticalAlign: "middle",
+              align: "left",
+            },
+          },
+
+          expandAndCollapse: false,
+          animationDuration: 550,
+          animationDurationUpdate: 750,
+        }
+        ],
+      };
+      this.sendingChart(option,index);
+      });
+      
+    },
+    sendingChart(option,index) {
+      var myChart = this.$echarts.init(document.getElementById("chart"+index));
+      myChart.clear();
+      var option = option;
+      option && myChart.setOption(option);
+      myChart.on("click", (param) => {
+        this.showRightPosition(param.data.sort);
+        var dom = document.getElementById("chart")
+        if(!this.isClick){
+          this.scrollTop = dom.scrollTop
+        }
+        this.isClick = true
+       this.show = false
+        this.$nextTick(()=>{
+          this.show = true
+          this.$nextTick(()=>{
+            this.getEchart()
+            this.isClick = false
+            document.getElementById("chart").scrollTop = this.scrollTop
+          })
+          
+        })
+      });
+      const eleArr = Array.from(new Set(myChart._chartsViews[0]._data._graphicEls))
+        const itemHeight = 50
+        const currentHeight = itemHeight * (eleArr.length-1) || itemHeight
+        const newHeight = Math.max(currentHeight,itemHeight)
+        myChart.resize({
+          height:newHeight+50
+        })
+
+    },
+    showRightPosition(id) {
+      var index = this.expends.indexOf(id);
+      if (index == -1) {
+        this.expends.push(id);
+      }else{
+        this.expends.splice(1,index)
+        this.expends.push(id);
+      }
+      if (this.isClickId + "") {
+        var dom1 = document.getElementById("right" + this.isClickId);
+        dom1.style.background = "";
+      }
+      this.isClickId = id;
+      var dom = document.getElementById("right" + id);
+      dom.style.background = "rgb(178, 215, 255)";
+      this.$nextTick(()=>{
+        this.tiaozhuan(id)
+      })
+      
+    },
+    tiaozhuan(id) {
+      const href = `#right${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;
+    },
+    initData() {
+      if (this.patent.rights) {
+        this.records.original = this.patent.rights.map((item) => item.content);
+        this.records.translation = this.patent.rights.map(
+          (item) => item.contentOut
+        );
+      } else {
+        if (!this.projectId) {
+          var params = {
+            patentCell: 1,
+            patentNo: this.patent.publicNo,
+            appNo: this.patent.applicationNo,
+          };
+          this.$api.getPatentPart(params).then((response) => {
+            if (response.code == 200) {
+              this.$set(this.patent, "rights", response.data.rights);
+            }
+          });
+        }
+      }
+    },
+    handleResize(event) {
+      this.fullHeight = document.documentElement.clientHeight;
+      this.height = this.fullHeight - 350;
+    },
+  },
+};
+</script>
+
+<style lang="scss">
+.patent-articles-patent-right {
+  margin-bottom: 20px;
+  .common {
+    // font-size: 14px;
+    margin-top: 0;
+    padding-right: 5px;
+    word-break: break-all;
+  }
+  .title {
+    font-weight: bold;
+    border-bottom: 1px solid #e6e6e6;
+    padding-bottom: 5px;
+    margin-top: 0;
+  }
+}
+</style>
+<style lang="scss" scoped>
+
+
+</style>

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

@@ -0,0 +1,103 @@
+<template>
+  <div class="patent-articles-patent-status height_100">
+
+    <div v-if="projectId">
+      <div> <h3 class="patent-articles-patent-status-event">当前状态</h3></div>
+    <el-button type="success" size="mini">{{patent.affair&& patent.affair.length>0?patent.affair[0].createSimpleStatus:''}}</el-button>
+    <div> <h3 class="patent-articles-patent-status-event">法律状态/事件</h3></div>
+    <el-button type="primary" size="mini">{{patent.affair&& patent.affair.length>0?patent.affair[0].status:''}}</el-button  >
+    </div>
+    <div> <h3 class="patent-articles-patent-status-event">事务数据</h3></div>
+    <div class="block" style="width:100%">
+      <el-timeline v-if="patent.affair&& patent.affair.length>0">
+        <el-timeline-item v-for="(item,index1) in patent.affair[0].inpadoc" :key="index1" :timestamp="item.inpadocData[0].content+'('+ item.inpadocData[1].content +')'" placement="top">
+          <el-card >
+            <div v-for="(i,index) in item.inpadocData" :key="i.content"  style="padding:5px 0;">
+              <span v-if="index!=0 && index!=1 && i.content" v-html="getViewDom(i.content)" ></span>
+            </div>
+          </el-card>
+        </el-timeline-item>
+      
+      </el-timeline>
+    </div>
+  </div>
+</template>
+
+<script>
+import { commonMixins } from "./mixins"
+
+export default {
+  components: {  },
+  mixins: [commonMixins],
+  data() {
+    return {
+      tableData: [],
+      tableDataList:[]
+    }
+  },
+  watch: {
+    patentId() {
+      this.tableData = this.patent.affair
+    },
+    patentNo(){
+      if(!this.projectId){
+        this.getData()
+      }
+    }
+  },
+  mounted() {
+    // this.tableData = this.patent.affair
+    // this.tableDataList=this.tableData[0].inpadoc
+    // console.log(this.tableData[0].inpadoc, this.tableDataList[0].length);
+    // for(var i in this.tableData[0].inpadoc[0]){
+    //   console.log(i)
+    // }
+    if(!this.projectId){
+        this.getData()
+      }
+  },
+  methods: {
+    getData(){
+      var params = {
+            patentCell:6,
+            patentNo:this.patent.publicNo,
+            appNo:this.patent.applicationNo,
+          }
+        this.$api.getPatentPart(params).then(response=>{
+            if(response.code == 200){
+              this.$set(this.patent,'affair',response.data.affair)
+            }
+        })
+    },
+  }
+}
+</script>
+
+<style lang="scss" scope="this api replaced by slot-scope in 2.5.0+">
+*{
+  box-sizing: border-box;
+}
+.el-table__body{
+  margin-top: 10px;
+}
+.patent-articles-patent-status-event{
+  font-weight: 800;
+  font-size: 16px;
+}
+.el-button--mini{
+  margin-left: 50px;
+}
+// .legal-status{
+//   color: #515a6e;
+//   font-size: 13px;
+//   font-weight: 800;
+// }
+// .yyyy{
+  // border:1px solid rgb(235, 238, 245);
+  // border:1px solid skyblue
+ 
+
+// }
+
+
+</style>

+ 9 - 3
src/views/project/patentDetails/index.vue

@@ -3,8 +3,12 @@
     <articleMenu></articleMenu>
     <div class="height_100">
         <my-View>
-            <div slot="left"></div>
-            <div slot="right"></div>
+            <div slot="left">
+              <Patent-Details></Patent-Details>
+            </div>
+            <div slot="right">
+              <Patent-Details></Patent-Details>
+            </div>
         </my-View>
     </div>
     
@@ -13,9 +17,11 @@
 
 <script>
 import articleMenu from './components/menu.vue'
+import PatentDetails from './components/patentDetails.vue'
 export default {
   components: {
-    articleMenu
+    articleMenu,
+    PatentDetails
   },
   props: {},
   data() {