zhangchuang 3 дней назад
Родитель
Сommit
78870d1603

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

@@ -69,6 +69,16 @@ export const postPatentApplication  = async (data: any) => {
   }
 };
 
+// 国内专利申请
+export const postPatentEnforcement  = async (data: any) => {
+  try {
+    const res = await http(RequestHttpEnum.POST)("/intellectual-property/patent-enforcement/create", data);
+    return res;
+  } catch {
+    httpErrorHandle();
+  }
+};
+
 // 商标注册
 export const postTrademarkApplication  = async (data: any) => {
   try {

+ 18 - 0
src/router/modules/ip.route.ts

@@ -11,6 +11,8 @@ const importPath = {
   revokePage: () => import("@/views/ip/revoke.vue"),
   invalidPage: () => import("@/views/ip/invalid.vue"),
   reviewPage: () => import("@/views/ip/review.vue"),
+  enforcementPage: () => import("@/views/ip/enforcement.vue"),
+  operationsPage: () => import("@/views/ip/operations.vue"),
 };
 
 const ipRoutes: Array<RouteRecordRaw> = [
@@ -86,6 +88,22 @@ const ipRoutes: Array<RouteRecordRaw> = [
       title: "商标驳回复审",
     },
   },
+  {
+    path: "/enforcement",
+    name: "enforcement",
+    component: importPath["enforcementPage"],
+    meta: {
+      title: "专利维权",
+    },
+  },
+  {
+    path: "/operations",
+    name: "operations",
+    component: importPath["operationsPage"],
+    meta: {
+      title: "专利运营需求",
+    },
+  },
 ];
 
 export default ipRoutes;

+ 187 - 0
src/views/ip/enforcement.vue

@@ -0,0 +1,187 @@
+<template>
+  <div class="page">
+    <el-breadcrumb>
+      <el-breadcrumb-item>知识产权</el-breadcrumb-item>
+      <el-breadcrumb-item>专利维权</el-breadcrumb-item>
+    </el-breadcrumb>
+    <el-card shadow="never" style="margin-top: 1rem; padding: 1rem;">
+      <h1>维权信息填写</h1>
+      <el-form
+        :model="trademarkForm"
+        class="rights-form"
+        label-width="120px"
+        label-position="left"
+      >
+        <el-form-item class="form-item" label="用户名称">
+          <el-input
+            class="custom-input"
+            v-model="trademarkForm.userName"
+            placeholder="请输入用户名称"
+          ></el-input>
+        </el-form-item>
+
+        <el-form-item class="form-item" label="联系方式">
+          <el-input
+            class="custom-input"
+            v-model="trademarkForm.contactDetails"
+            placeholder="请输入联系方式"
+          ></el-input>
+        </el-form-item>
+
+        <el-form-item class="form-item" label="专利号">
+          <el-input
+            class="custom-input"
+            v-model="trademarkForm.patentNumber"
+            placeholder="请输入专利号"
+          ></el-input>
+        </el-form-item>
+
+        <el-form-item class="form-item" label="问题描述">
+          <el-input
+            type="textarea"
+            class="custom-input"
+            v-model="trademarkForm.description"
+            placeholder="请输入问题描述"
+          ></el-input>
+        </el-form-item>
+
+        <div class="button-container">
+          <el-button type="primary" @click="submitApplication">提交信息</el-button>
+        </div>
+      </el-form>
+    </el-card>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { ref } from "vue";
+import { ElMessage } from "element-plus";
+import { postPatentEnforcement } from "@/api";
+
+interface RightsForm {
+  userName: string; // 用户名称
+  contactDetails: string; // 联系方式
+  patentNumber: string; // 专利号
+  description: string; // 问题描述
+}
+
+const trademarkForm = ref<RightsForm>({
+  userName: "",
+  contactDetails: "",
+  patentNumber: "",
+  description: ""
+});
+
+const submitApplication = async () => {
+  const res = (await postPatentEnforcement(
+    trademarkForm.value
+  )) as unknown as any;
+  if (res.code === 200) {
+    ElMessage({
+      type: "success",
+      message: "创建成功",
+    });
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.page {
+  height: calc(100vh - 4rem);
+  box-sizing: border-box;
+  padding: 2rem 18rem;
+  color: #333;
+  background-image: url("@/assets/pic/bg.png"); /* 设置背景图片 */
+  background-repeat: repeat; /* 上下重复 */
+  background-size: cover; /* 左右满铺 */
+  background-position: center; /* 居中对齐 */
+  .form-item {
+    margin-right: 20px; // 根据需要设置间距
+    .logo {
+      width: 178px;
+      height: 178px;
+    }
+    .logo-uploader {
+      width: 178px;
+      height: 178px;
+      border: 1px dashed var(--el-border-color);
+      border-radius: 6px;
+      cursor: pointer;
+      position: relative;
+      overflow: hidden;
+      transition: var(--el-transition-duration-fast);
+    }
+    .logo-uploader-icon {
+      font-size: 28px;
+      color: #8c939d;
+      width: 178px;
+      height: 178px;
+      text-align: center;
+    }
+  }
+  .custom-input {
+    max-width: 20rem;
+    width: 100%; // 可选
+  }
+  .button-container {
+    display: flex;
+    justify-content: flex-end; /* 使按钮靠右对齐 */
+    width: 100%;
+  }
+  .page-title {
+    margin-top: 1rem;
+    margin-bottom: 1rem;
+    font-family: "源黑体 CN", sans-serif;
+    font-weight: 500;
+    font-size: 1.25rem;
+    line-height: 2rem;
+    text-align: left;
+  }
+
+  .trademark-form {
+    margin-bottom: 2rem;
+  }
+
+  .section-title {
+    font-size: 1.2rem;
+    margin: 1.5rem 0 0.5rem;
+    font-weight: 500;
+  }
+}
+
+.trademark {
+  display: flex;
+  width: 100%;
+  height: 500px;
+  border: 1px solid #c1c1c1;
+  .trademark-aside {
+    width: 300px;
+    border-right: 1px solid #c1c1c1;
+    .trademark-aside-search {
+      width: 100%;
+      height: 50px;
+      display: flex;
+      align-items: center;
+      box-sizing: border-box;
+      padding-left: 10px;
+    }
+  }
+  .trademark-main {
+    flex: 1;
+    .trademark-main-header {
+      width: 100%;
+      height: 50px;
+      border-bottom: 1px solid #c1c1c1;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      box-sizing: border-box;
+      padding: 0 20px;
+    }
+    .trademark-main-content {
+      box-sizing: border-box;
+      padding: 20px;
+    }
+  }
+}
+</style>

+ 2 - 2
src/views/ip/index.vue

@@ -37,11 +37,11 @@
             </div>
             <div class="card-button-item">
               <img class="item-icon" src="@/assets/icon/ip_05.png" alt="#" />
-              <div class="item-text">专利维权</div>
+              <div class="item-text" @click="hanlePath('/enforcement')">专利维权</div>
             </div>
             <div class="card-button-item">
               <img class="item-icon" src="@/assets/icon/ip_05.png" alt="#" />
-              <div class="item-text">专利运营需求</div>
+              <div class="item-text" @click="hanlePath('/operations')">专利运营需求</div>
             </div>
           </div>
         </div>

+ 384 - 0
src/views/ip/operations.vue

@@ -0,0 +1,384 @@
+<template>
+  <div class="page">
+    <el-breadcrumb>
+      <el-breadcrumb-item> 知识产权 </el-breadcrumb-item>
+      <el-breadcrumb-item> 专利运营需求 </el-breadcrumb-item>
+    </el-breadcrumb>
+    <el-card shadow="never" style="margin-top: 1rem; padding: 1rem;">
+      <h1>专利运营需求表填写</h1>
+      <div class="page-title">商标信息</div>
+      <el-form
+        :model="trademarkForm"
+        class="trademark-form"
+        label-width="120px"
+        label-position="left"
+      >
+        <el-form-item class="form-item" label="商标注册号">
+          <el-input
+            class="custom-input"
+            v-model="trademarkForm.logoRegistrationNumber"
+            placeholder="请输入商标注册号"
+          ></el-input>
+        </el-form-item>
+
+        <el-form-item class="form-item" label="商标图样变更">
+          <el-radio-group v-model="trademarkForm.isLogoModify">
+            <el-radio label="是" value="1">是</el-radio>
+            <el-radio label="否" value="2">否</el-radio>
+          </el-radio-group>
+        </el-form-item>
+
+        <el-form-item
+          class="form-item"
+          label="商标图样"
+          v-if="trademarkForm.isLogoModify === '1'"
+        >
+          <el-upload
+            class="logo-uploader"
+            :show-file-list="false"
+            :http-request="handleUploadTrademark"
+          >
+            <img
+              v-if="trademarkDiagramPath"
+              :src="trademarkDiagramPath"
+              class="logo"
+            />
+            <el-icon v-else class="logo-uploader-icon"><Plus /></el-icon>
+          </el-upload>
+        </el-form-item>
+
+        <div class="section-title">申请人信息</div>
+        <el-form-item class="form-item" label="申请人类型">
+          <el-radio-group v-model="trademarkForm.applicantType" @change="handleApplicantTypeChange">
+            <el-radio label="个人" value="0">个人</el-radio>
+            <el-radio label="企业" value="1">企业</el-radio>
+          </el-radio-group>
+        </el-form-item>
+
+        <el-form-item class="form-item" label="国家地区">
+          <el-cascader
+            placeholder="请选择国家地区"
+            v-model="trademarkForm.country"
+            :options="country"
+            :props="{
+              emitPath: false,
+            }"
+          />
+        </el-form-item>
+
+        <el-form-item class="form-item" v-if="trademarkForm.applicantType === '0'" label="申请人名称">
+          <el-input
+            class="custom-input"
+            v-model="trademarkForm.applicant"
+            placeholder="请输入申请人名称"
+          ></el-input>
+        </el-form-item>
+
+        <el-form-item class="form-item" v-if="trademarkForm.applicantType === '1'" label="申请企业名称">
+          <el-input
+            class="custom-input"
+            v-model="trademarkForm.corporationsName"
+            placeholder="请输入申请企业名称"
+          ></el-input>
+        </el-form-item>
+
+        <el-form-item class="form-item" label="证件号码" v-if="trademarkForm.applicantType === '0'">
+          <el-input
+            class="custom-input"
+            v-model="trademarkForm.idCard"
+            placeholder="请输入证件号码"
+          ></el-input>
+        </el-form-item>
+
+        <el-form-item class="form-item" v-if="trademarkForm.applicantType === '1'" label="营业执照">
+          <el-upload
+            class="logo-uploader"
+            :show-file-list="false"
+            :http-request="handleUploadBusinessLicense"
+          >
+            <img
+              v-if="businessLicensePath"
+              :src="businessLicensePath"
+              class="logo"
+            />
+            <el-icon v-else class="logo-uploader-icon"><Plus /></el-icon>
+          </el-upload>
+        </el-form-item>
+
+        <el-form-item class="form-item" label="身份证正面" v-if="trademarkForm.applicantType === '0'">
+          <el-upload
+            class="logo-uploader"
+            :show-file-list="false"
+            :http-request="handleUploadIdCardFront"
+          >
+            <img v-if="idCardPath" :src="idCardPath" class="logo" />
+            <el-icon v-else class="logo-uploader-icon"><Plus /></el-icon>
+          </el-upload>
+        </el-form-item>
+
+        <el-form-item class="form-item" label="身份证反面" v-if="trademarkForm.applicantType === '0'">
+          <el-upload
+            class="logo-uploader"
+            :show-file-list="false"
+            :http-request="handleUploadIdCardBackside"
+          >
+            <img
+              v-if="idCardBacksidePath"
+              :src="idCardBacksidePath"
+              class="logo"
+            />
+            <el-icon v-else class="logo-uploader-icon"><Plus /></el-icon>
+          </el-upload>
+        </el-form-item>
+
+        <el-form-item class="form-item" label="申请地址" v-if="trademarkForm.applicantType === '0'">
+          <el-input
+            class="custom-input"
+            v-model="trademarkForm.applicantAddr"
+            placeholder="请输入申请地址"
+          ></el-input>
+        </el-form-item>
+
+        <el-form-item class="form-item" v-if="trademarkForm.applicantType === '1'" label="商标网上申请委托书">
+          <el-upload
+            class="logo-uploader"
+            :show-file-list="false"
+            :http-request="handleUploadAuthorization"
+          >
+            <img
+              v-if="authorizationPath"
+              :src="authorizationPath"
+              class="logo"
+            />
+            <el-icon v-else class="logo-uploader-icon"><Plus /></el-icon>
+          </el-upload>
+        </el-form-item>
+
+        <div class="button-container">
+          <el-button type="primary" @click="submitApplication">提交申请</el-button>
+        </div>
+      </el-form>
+    </el-card>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { ref, onMounted } from "vue";
+import { postFileUpload, postTrademarkAmendment } from "@/api";
+import { useDictStore } from "@/store/modules/useDictStore/index";
+import { ElMessage } from "element-plus";
+
+interface TrademarkForm {
+  logoRegistrationNumber: string; // 商标注册号
+  isLogoModify: string; // 商标图样是否变更
+  logoPath: string; // 图样地址
+  applicantType: string; // 申请人类型
+  country: string; //地区
+  applicant: string; // 申请人名称
+  corporationsName: string; // 企业名称
+  idCard: string; // 证件号码
+  idCardPath: string; // 身份证证明ID
+  idCardBacksidePath: string; // 身份证反面ID
+  applicantAddr: string; // 申请人地址
+  businessLicensePath: string; // 个体营业执照
+  authorizationPath: string; // 商标网上申请委托书
+}
+
+const trademarkForm = ref<TrademarkForm>({
+  logoRegistrationNumber: "",
+  isLogoModify: "1",
+  logoPath: "",
+  applicantType: "0",
+  country: "",
+  applicant: "",
+  corporationsName: "",
+  idCard: "",
+  idCardPath: "",
+  idCardBacksidePath: "",
+  applicantAddr: "",
+  businessLicensePath: "",
+  authorizationPath: ""
+});
+
+// 字典
+const dictStore = useDictStore();
+const country = dictStore.dictData.country;
+
+// logo地址
+const trademarkDiagramPath = ref("");
+const idCardPath = ref("");
+const idCardBacksidePath = ref("");
+const businessLicensePath = ref("");
+const authorizationPath = ref("");
+
+// 初始化数据
+onMounted(() => {
+  pageInitData();
+});
+
+const pageInitData = () => {};
+
+const handleUploadTrademark = async (option: any) => {
+  await handleUpload(option, "logoPath", trademarkDiagramPath);
+};
+
+const handleUploadIdCardFront = async (option: any) => {
+  await handleUpload(option, "idCardPath", idCardPath);
+};
+
+const handleUploadIdCardBackside = async (option: any) => {
+  await handleUpload(option, "idCardBacksidePath", idCardBacksidePath);
+};
+
+const handleUploadBusinessLicense = async (option: any) => {
+  await handleUpload(option, "businessLicensePath", businessLicensePath);
+};
+
+const handleUploadAuthorization = async (option: any) => {
+  await handleUpload(option, "authorizationPath", authorizationPath);
+};
+
+// 通用上传处理函数
+const handleUpload = async (
+  option: any,
+  formField: keyof TrademarkForm,
+  pathRef: any
+) => {
+  try {
+    const file = new FormData();
+    file.append("file", option.file);
+    const res = (await postFileUpload(file)) as unknown as any;
+    trademarkForm.value[formField] = res.uuid;
+    pathRef.value = import.meta.env.VITE_DEV_IMG + "/" + res.uuid;
+    console.log("res ===>", res);
+  } catch (error) {
+    console.error("文件上传失败:", error);
+  }
+};
+
+const submitApplication = async () => {
+  const res = (await postTrademarkAmendment(trademarkForm.value)) as unknown as any;
+  if (res.code === 200) {
+    ElMessage({
+      type: "success",
+      message: "创建成功",
+    });
+  }
+};
+
+// 处理申请人类型变化
+const handleApplicantTypeChange = () => {
+  // 重置企业名称和相关字段
+  if (trademarkForm.value.applicantType === '0') {
+    trademarkForm.value.corporationsName = "";
+    trademarkForm.value.businessLicensePath = "";
+    authorizationPath.value = "";
+  } else {
+    trademarkForm.value.applicant = "";
+    trademarkForm.value.idCard = "";
+    idCardPath.value = "";
+    idCardBacksidePath.value = "";
+  }
+};
+</script>
+
+
+<style lang="scss" scoped>
+.page {
+  box-sizing: border-box;
+  padding: 2rem 18rem;
+  color: #333;
+  background-image: url("@/assets/pic/bg.png"); /* 设置背景图片 */
+  background-repeat: repeat; /* 上下重复 */
+  background-size: cover; /* 左右满铺 */
+  background-position: center; /* 居中对齐 */
+  .form-item {
+    margin-right: 20px; // 根据需要设置间距
+    .logo {
+      width: 178px;
+      height: 178px;
+    }
+    .logo-uploader {
+      width: 178px;
+      height: 178px;
+      border: 1px dashed var(--el-border-color);
+      border-radius: 6px;
+      cursor: pointer;
+      position: relative;
+      overflow: hidden;
+      transition: var(--el-transition-duration-fast);
+    }
+    .logo-uploader-icon {
+      font-size: 28px;
+      color: #8c939d;
+      width: 178px;
+      height: 178px;
+      text-align: center;
+    }
+  }
+  .custom-input {
+    max-width: 20rem;
+    width: 100%; // 可选
+  }
+  .button-container {
+    display: flex;
+    justify-content: flex-end; /* 使按钮靠右对齐 */
+    width: 100%;
+  }
+  .page-title {
+    margin-top: 1rem;
+    margin-bottom: 1rem;
+    font-family: "源黑体 CN", sans-serif;
+    font-weight: 500;
+    font-size: 1.25rem;
+    line-height: 2rem;
+    text-align: left;
+  }
+
+  .trademark-form {
+    margin-bottom: 2rem;
+  }
+
+  .section-title {
+    font-size: 1.2rem;
+    margin: 1.5rem 0 0.5rem;
+    font-weight: 500;
+  }
+}
+
+.trademark {
+  display: flex;
+  width: 100%;
+  height: 500px;
+  border: 1px solid #c1c1c1;
+  .trademark-aside {
+    width: 300px;
+    border-right: 1px solid #c1c1c1;
+    .trademark-aside-search {
+      width: 100%;
+      height: 50px;
+      display: flex;
+      align-items: center;
+      box-sizing: border-box;
+      padding-left: 10px;
+    }
+  }
+  .trademark-main {
+    flex: 1;
+    .trademark-main-header {
+      width: 100%;
+      height: 50px;
+      border-bottom: 1px solid #c1c1c1;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      box-sizing: border-box;
+      padding: 0 20px;
+    }
+    .trademark-main-content {
+      box-sizing: border-box;
+      padding: 20px;
+    }
+  }
+}
+</style>