Browse Source

专利检索

zhangchuang 2 days ago
parent
commit
aec1483e4e

+ 1 - 0
package.json

@@ -14,6 +14,7 @@
     "element-plus": "^2.7.4",
     "js-sha256": "^0.11.0",
     "normalize.css": "^8.0.1",
+    "pdf-vue3": "^1.0.12",
     "pinia": "^2.1.7",
     "sass": "^1.77.4",
     "uuid": "^11.0.3",

+ 8 - 0
pnpm-lock.yaml

@@ -23,6 +23,9 @@ importers:
       normalize.css:
         specifier: ^8.0.1
         version: 8.0.1
+      pdf-vue3:
+        specifier: ^1.0.12
+        version: 1.0.12
       pinia:
         specifier: ^2.1.7
         version: 2.1.7(typescript@5.4.5)(vue@3.4.27(typescript@5.4.5))
@@ -571,6 +574,9 @@ packages:
   path-browserify@1.0.1:
     resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
 
+  pdf-vue3@1.0.12:
+    resolution: {integrity: sha512-7SMTx1RfRwdc+2WPniDzqM8MxJLqTNNzdyV0SeQTxeRLJGndb5Wv/fz5afO13oBSIvvaqcbZ/S3gF+XjqkSb9g==}
+
   picocolors@1.0.1:
     resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==}
 
@@ -1156,6 +1162,8 @@ snapshots:
 
   path-browserify@1.0.1: {}
 
+  pdf-vue3@1.0.12: {}
+
   picocolors@1.0.1: {}
 
   picomatch@2.3.1: {}

+ 19 - 0
src/api/system/system.api.ts

@@ -158,4 +158,23 @@ export const getPatentApplicationList = async (data: any) => {
   } catch {
     httpErrorHandle();
   }
+};
+
+// 专利检索
+export const getPatentsList = async (data: any) => {
+  try {
+    const res = await http(RequestHttpEnum.GET)("/patents/list", data);
+    return res;
+  } catch {
+    httpErrorHandle();
+  }
+};
+
+export const getPatentsView = async (id: any) => {
+  try {
+    const res = await http(RequestHttpEnum.GET)("/patents/view/" + id);
+    return res;
+  } catch {
+    httpErrorHandle();
+  }
 };

+ 11 - 2
src/router/modules/ps.route.ts

@@ -2,7 +2,8 @@ import { RouteRecordRaw } from "vue-router";
 
 // 引入路径
 const importPath = {
-  PatentSearch: () => import("@/views/PatentSearch/index"),
+  PatentSearch: () => import("@/views/PatentSearch/index.vue"),
+  PatentDetails: () => import("@/views/PatentSearch/details.vue"),
 };
 
 const ipRoutes: Array<RouteRecordRaw> = [
@@ -14,6 +15,14 @@ const ipRoutes: Array<RouteRecordRaw> = [
       title: "专利检索",
     },
   },
-]
+  {
+    path: "/ps/details/:id", // 使用动态参数 :id
+    name: "PatentDetails",
+    component: importPath["PatentDetails"],
+    meta: {
+      title: "专利信息详情",
+    },
+  },
+];
 
 export default ipRoutes;

+ 143 - 0
src/views/PatentSearch/details.vue

@@ -0,0 +1,143 @@
+<template>
+  <div class="container">
+    <el-tabs
+      v-model="activeName"
+      type="card"
+      class="demo-tabs"
+      @tab-click="handleClick"
+    >
+      <el-tab-pane label="详细信息" name="first">
+        <el-descriptions title="专利信息" border>
+          <el-descriptions-item label="专利标题">{{
+            pageForm.inventionTitle
+          }}</el-descriptions-item>
+          <el-descriptions-item label="申请号">{{
+            pageForm.applicationNumber
+          }}</el-descriptions-item>
+          <el-descriptions-item label="申请日">{{
+            pageForm.filingDate
+          }}</el-descriptions-item>
+          <el-descriptions-item label="公布号">{{
+            pageForm.publicationNumber
+          }}</el-descriptions-item>
+          <el-descriptions-item label="公布日">{{
+            pageForm.publicationDate
+          }}</el-descriptions-item>
+          <el-descriptions-item label="授权公告日">{{
+            pageForm.announcementDate
+          }}</el-descriptions-item>
+          <el-descriptions-item label="发明人"
+            >{{ pageForm.inventorNames }}
+            {{ pageForm.ohterDeviseName }}</el-descriptions-item
+          >
+          <el-descriptions-item label="申请人">{{
+            pageForm.applicantName
+          }}</el-descriptions-item>
+          <el-descriptions-item label="申请地址">{{
+            pageForm.applicantAddress
+          }}</el-descriptions-item>
+          <el-descriptions-item label="专利权人">{{
+            pageForm.patentHolderName
+          }}</el-descriptions-item>
+          <el-descriptions-item label="专利权人地址">{{
+            pageForm.patentHolderAddress
+          }}</el-descriptions-item>
+          <el-descriptions-item label="专利代理机构">{{
+            pageForm.patentAgentFirm
+          }}</el-descriptions-item>
+          <el-descriptions-item label="代理人">{{
+            pageForm.patentAgentName
+          }}</el-descriptions-item>
+          <el-descriptions-item label="IPC分类号">{{
+            pageForm.ipcClassification
+          }}</el-descriptions-item>
+        </el-descriptions>
+        <el-descriptions border style="margin-top: 1rem">
+          <el-descriptions-item label="摘要">{{
+            pageForm.abstract
+          }}</el-descriptions-item>
+        </el-descriptions>
+        <h4>公开/授权文件</h4>
+        <div style="display: flex; gap: 2rem">
+          <div>
+            {{ pageForm.publicationNumber + " " + pageForm.inventionTitle }}
+          </div>
+          <div>公布日:{{ pageForm.publicationDate }}</div>
+        </div>
+        <h4>专利附图</h4>
+        <img
+          v-for="item in pageForm.patentDrawingLinks"
+          :src="item.url"
+          alt="#"
+        />
+      </el-tab-pane>
+      <el-tab-pane label="权利要求书" name="second">
+        <div v-html="pageForm.claims"></div>
+      </el-tab-pane>
+      <el-tab-pane label="说明书全文" name="third">
+        <div v-html="pageForm.fullDescription"></div>
+      </el-tab-pane>
+      <el-tab-pane label="PDF全文" name="fourth">
+        <PDF :src="pageForm.fullTextPdfUrl" />
+      </el-tab-pane>
+    </el-tabs>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { ref, onMounted } from "vue";
+import type { TabsPaneContext } from "element-plus";
+import { useRoute } from "vue-router";
+import { getPatentsView } from "@/api";
+import PDF from "pdf-vue3";
+
+const activeName = ref("first");
+const route = useRoute();
+const routeParams = route.params; // 将routePath改为响应式变量
+const pageForm = ref<any>({
+  inventionTitle: "", // 专利标题
+  applicationNumber: "", // 申请号
+  filingDate: "", // 申请日
+  publicationNumber: "", // 公布号
+  publicationDate: "", // 公布日
+  announcementDate: "", // 授权公告日
+  inventorNames: "", // 发明人
+  ohterDeviseName: "", // 其他发明人
+  applicantName: "", // 申请人
+  applicantAddress: "", // 申请地址
+  patentHolderName: "", // 专利权人
+  patentHolderAddress: "", // 专利权人地址
+  agentNumber: "", // 专利代理地址
+  patentAgentFirm: "", // 专利代理机构
+  ipcClassification: "", // IPC分类号
+  abstract: "", // 摘要
+  patentAgentName: "",
+  claims: "",
+  fullDescription: "",
+  patentDrawingLinks: [],
+  fullTextPdfUrl: "",
+});
+
+onMounted(() => {
+  pageInit();
+});
+
+const pageInit = async () => {
+  const res = await getPatentsView(routeParams.id);
+  // 使用 Object.assign 将响应数据赋值给 pageForm
+  Object.assign(pageForm.value, res?.data);
+  console.log(pageForm.value);
+};
+
+const handleClick = (tab: TabsPaneContext, event: Event) => {
+  console.log(tab, event);
+};
+</script>
+
+<style>
+.container {
+  width: 87.5rem;
+  min-height: 500px;
+  margin: 0 auto;
+}
+</style>

+ 217 - 105
src/views/PatentSearch/index.vue

@@ -2,12 +2,23 @@
   <div class="container">
     <div class="search">
       <div class="search-global">
-        <img class="global" src="@/assets/icon/ap/ap_04.png" alt="#">
+        <img class="global" src="@/assets/icon/ap/ap_04.png" alt="#" />
         <span>全球数据库</span>
-        <img class="direction" src="@/assets/icon/ap/ap_05.png" alt="#">
+        <img class="direction" src="@/assets/icon/ap/ap_05.png" alt="#" />
       </div>
-      <el-input class="search-input" v-model="input" style="width: 240px" />
-      <el-button :icon="Search" class="search-button" type="primary" round
+      <el-input
+        clearable
+        class="search-input"
+        v-model="trademarkForm.inventionTitle"
+        @clear="pageInitData"
+        style="width: 240px"
+      />
+      <el-button
+        :icon="Search"
+        class="search-button"
+        type="primary"
+        round
+        @click="onSubmit"
         >检索</el-button
       >
     </div>
@@ -15,44 +26,105 @@
       <div class="aside">
         <el-collapse>
           <el-collapse-item title="专利类型" name="1">
-            <div style="display: flex; flex-direction: column">
-              <el-checkbox label="发明" size="large" />
-              <el-checkbox label="实用新型" size="large" />
-              <el-checkbox label="外观设计" size="large" />
-            </div>
+            <el-radio-group
+              v-model="trademarkForm.patentType"
+              @change="pageInitData"
+            >
+              <el-radio v-for="item in patents_type" :value="item.value">{{
+                item.label
+              }}</el-radio>
+            </el-radio-group>
           </el-collapse-item>
           <el-collapse-item title="专利有效性" name="2">
-            <div style="display: flex; flex-direction: column">
-              <el-checkbox label="有效" size="large" />
-              <el-checkbox label="审中" size="large" />
-              <el-checkbox label="生效" size="large" />
+            <el-radio-group
+              v-model="trademarkForm.validityStatus"
+              @change="handleValidityStatus"
+            >
+              <el-radio
+                v-for="item in patent_validity_status"
+                :value="item.value"
+                >{{ item.label }}</el-radio
+              >
+            </el-radio-group>
+            <div v-if="trademarkForm.validityStatus === '2'">
+              <h4>审查状态</h4>
+              <el-radio-group
+                v-model="trademarkForm.auditStatus"
+                @change="pageInitData"
+              >
+                <el-radio
+                  v-for="item in patent_examination_status"
+                  :value="item.value"
+                  >{{ item.label }}</el-radio
+                >
+              </el-radio-group>
+            </div>
+            <div v-else>
+              <h4>法律状态</h4>
+              <el-radio-group
+                v-model="trademarkForm.legalStatus"
+                @change="pageInitData"
+              >
+                <el-radio
+                  :disabled="isEffective && item.value !== '7'"
+                  v-for="item in patent_law_status"
+                  :value="item.value"
+                  >{{ item.label }}</el-radio
+                >
+              </el-radio-group>
             </div>
           </el-collapse-item>
           <el-collapse-item title="申请日" name="3">
             <el-date-picker
+              v-model="trademarkForm.filingDate"
+              format="YYYY/MM/DD"
+              value-format="YYYY-MM-DD"
               type="daterange"
-              range-separator="To"
-              start-placeholder="Start date"
-              end-placeholder="End date"
+              range-separator="至"
+              start-placeholder="开始时间"
+              end-placeholder="结束时间"
+              style="width: 12rem"
+              @change="pageInitData"
+              @clear="pageInitData"
             />
           </el-collapse-item>
           <el-collapse-item title="公布(公告)日" name="4">
             <el-date-picker
+              v-model="trademarkForm.publicationDate"
+              format="YYYY/MM/DD"
+              value-format="YYYY-MM-DD"
               type="daterange"
-              range-separator="To"
-              start-placeholder="Start date"
-              end-placeholder="End date"
+              range-separator="至"
+              start-placeholder="开始时间"
+              end-placeholder="结束时间"
+              style="width: 12rem"
+              @change="pageInitData"
+              @clear="pageInitData"
             />
           </el-collapse-item>
-          <el-collapse-item title="发明人" name="5">
-            <el-input placeholder="Type something">
+          <el-collapse-item title="发明(设计)人" name="5">
+            <el-input
+              clearable
+              @change="pageInitData"
+              @clear="pageInitData"
+              v-model="trademarkForm.inventorNames"
+              placeholder="请输入发明设计人姓名"
+              style="width: 14rem"
+            >
               <template #prefix>
                 <el-icon class="el-input__icon"><search /></el-icon>
               </template>
             </el-input>
           </el-collapse-item>
-          <el-collapse-item title="当前权利人" name="6">
-            <el-input placeholder="Type something">
+          <el-collapse-item title="专利权人" name="6">
+            <el-input
+              clearable
+              @change="pageInitData"
+              @clear="pageInitData"
+              v-model="trademarkForm.patentHolderName"
+              placeholder="请输入当前权利人姓名"
+              style="width: 14rem"
+            >
               <template #prefix>
                 <el-icon class="el-input__icon"><search /></el-icon>
               </template>
@@ -62,39 +134,43 @@
       </div>
       <div class="content">
         <el-table :data="tableData">
-          <el-table-column prop="date" label="序号" width="280">
-            <template #default="scope">
-              <div style="display: flex; gap: 0.3rem;">
-                <span>{{ scope.row.date }}</span>
-                <el-tag type="primary">发明公开</el-tag>
-                <el-tag type="primary">发明授权</el-tag>
-                <el-tag type="primary">有权</el-tag>
-                <el-tag type="primary">无效</el-tag>
-              </div>
-            </template>
-          </el-table-column>
-          <el-table-column prop="name" label="公开(公告)号" width="180" />
-          <el-table-column prop="title" label="标题"/>
-          <el-table-column prop="applicationDate" label="申请日" width="180" />
+          <el-table-column
+            prop="publicationNumber"
+            label="公布号"
+            width="180"
+          />
+          <el-table-column prop="inventionTitle" width="180" label="标题" />
+          <el-table-column prop="filingDate" label="申请日" width="180" />
           <el-table-column
             prop="publicationDate"
             label="公开(公告)日"
             width="180"
           />
-          <el-table-column prop="currentOwner" label="当前权利人" width="150" />
-          <el-table-column prop="inventor" label="发明(设计)人" width="150" />
+          <el-table-column
+            prop="patentHolderName"
+            label="专利权人"
+            width="150"
+          />
+          <el-table-column prop="inventorNames" label="发明(设计)人" />
+          <el-table-column
+            fixed="right"
+            label="操作"
+            width="200"
+            align="center"
+          >
+            <template v-slot="scope">
+              <el-button type="primary" text @click="onShow(scope.row)"
+                >详情</el-button
+              >
+            </template>
+          </el-table-column>
         </el-table>
         <div class="pagination">
           <el-pagination
-            v-model:current-page="currentPage4"
-            v-model:page-size="pageSize4"
-            :page-sizes="[100, 200, 300, 400]"
-            :size="size"
-            :disabled="disabled"
-            :background="background"
-            layout="total, sizes, prev, pager, next, jumper"
-            :total="400"
-            @size-change="handleSizeChange"
+            v-model:current-page="currentPage"
+            v-model:page-size="pageSize"
+            layout="total, prev, pager, next, jumper"
+            :total="total"
             @current-change="handleCurrentChange"
           />
         </div>
@@ -104,68 +180,104 @@
 </template>
 
 <script lang="ts" setup>
-import { ref } from 'vue'
+import { ref, onMounted } from "vue";
 import { Search } from "@element-plus/icons-vue";
-const currentPage4 = ref(4);
-const pageSize4 = ref(100);
-const size = ref("default");
-const background = ref(false);
-const disabled = ref(false);
+import { useDictStore } from "@/store/modules/useDictStore/index";
+import { getPatentsList } from "@/api";
+import { useRouter, useRoute } from "vue-router";
+
+interface TrademarkForm {
+  inventionTitle: string; //专利名
+  patentType: string; //专利类型
+  validityStatus: string; //专利有效性
+  filingDate: string[]; //申请日
+  publicationDate: string[]; //公布日
+  inventorNames: string; //发明人
+  patentHolderName: string; //专利权人
+  auditStatus: string; //法律状态
+  legalStatus: string; //法律状态
+}
+
+const trademarkForm = ref<TrademarkForm>({
+  inventionTitle: "",
+  patentType: "",
+  validityStatus: "",
+  filingDate: [],
+  publicationDate: [],
+  inventorNames: "",
+  patentHolderName: "",
+  auditStatus: "",
+  legalStatus: "",
+});
+
+const router = useRouter();
+
+// 字典
+const dictStore = useDictStore();
+// 专利类型
+const patents_type = dictStore.dictData.patents_type;
+// 有效性
+const patent_validity_status = dictStore.dictData.patent_validity_status;
+// 	专利检索专利审查状态
+const patent_examination_status = dictStore.dictData.patent_examination_status;
+// 	专利检索法律状态
+const patent_law_status = dictStore.dictData.patent_law_status;
+const currentPage = ref(1);
+const pageSize = ref(10);
+const total = ref(0);
+const isEffective = ref(false);
+const tableData = ref([]);
 
-const handleSizeChange = (val: number) => {
-  console.log(`${val} items per page`);
+onMounted(() => {
+  pageInitData();
+});
+
+const onShow = (row: any) => {
+  router.push({
+    path: "/ps/details/" + row.id,
+  });
 };
+
+const handleValidityStatus = (v: string) => {
+  if (Number(v) === 0) {
+    isEffective.value = true;
+    trademarkForm.value.legalStatus = "7";
+  } else {
+    isEffective.value = false;
+  }
+  console.log("handleValidityStatus ===>", v);
+};
+
+const pageInitData = async () => {
+  const data = {
+    pageSize: pageSize.value,
+    pageNumber: currentPage.value,
+    inventionTitle: trademarkForm.value.inventionTitle,
+    patentType: trademarkForm.value.patentType,
+    validityStatus: trademarkForm.value.validityStatus,
+    inventorNames: trademarkForm.value.inventorNames,
+    patentHolderName: trademarkForm.value.patentHolderName,
+    auditStatus: trademarkForm.value.auditStatus,
+    legalStatus: trademarkForm.value.legalStatus,
+    beginFilingDate: trademarkForm.value.filingDate[0],
+    endFilingDate: trademarkForm.value.filingDate[0],
+    beginPublicationDate: trademarkForm.value.publicationDate[0],
+    endPublicationDate: trademarkForm.value.publicationDate[1],
+  };
+  const res = (await getPatentsList(data)) as unknown as any;
+  tableData.value = res.data.list;
+  total.value = res.data.total;
+  console.log("res ===>", res.data.list);
+};
+
+const onSubmit = () => {
+  pageInitData();
+};
+
 const handleCurrentChange = (val: number) => {
-  console.log(`current page: ${val}`);
+  pageSize.value = val;
+  pageInitData();
 };
-const input = ref("医药");
-const tableData = [
-  {
-    date: "1",
-    name: "CN123456789A",
-    title: "一种新型环保材料的制备方法",
-    applicationDate: "2022-01-15",
-    publicationDate: "2022-07-20",
-    currentOwner: "张三",
-    inventor: "李四",
-  },
-  {
-    date: "2",
-    name: "CN987654321B",
-    title: "智能家居控制系统",
-    applicationDate: "2021-05-10",
-    publicationDate: "2021-11-25",
-    currentOwner: "王五",
-    inventor: "赵六",
-  },
-  {
-    date: "3",
-    name: "CN456789123C",
-    title: "高效能太阳能电池",
-    applicationDate: "2020-03-22",
-    publicationDate: "2020-09-30",
-    currentOwner: "钱七",
-    inventor: "孙八",
-  },
-  {
-    date: "4",
-    name: "CN321654987D",
-    title: "新型电动汽车动力系统",
-    applicationDate: "2019-08-05",
-    publicationDate: "2020-02-15",
-    currentOwner: "周九",
-    inventor: "吴十",
-  },
-  {
-    date: "5",
-    name: "CN654321789E",
-    title: "智能穿戴设备的设计",
-    applicationDate: "2023-02-18",
-    publicationDate: "2023-08-12",
-    currentOwner: "郑十一",
-    inventor: "冯十二",
-  },
-];
 </script>
 
 <style lang="scss" scoped>