| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417 |
- <template>
- <view class="document-form">
- <uv-loading-icon v-if="loading" mode="circle" text="正在加载专利详情..."></uv-loading-icon>
- <template v-else-if="form">
- <!-- 基本信息 -->
- <CommonSection title="基本信息" :isFirst="true">
- <CommonInfoRow label="专利名称" :value="form.patentName" />
- <CommonInfoRow label="所属部门" :value="form.deptName" />
- <CommonInfoRow label="代理公司" :value="form.companyName" />
- <CommonInfoRow label="专利类型" :value="getDictLabel('sci_patent_class', form.patentClass)" />
- <CommonInfoRow label="专利范围" :value="getDictLabel('sci_patent_scope', form.patentScope)" />
- <CommonInfoRow label="专利状态" :value="getDictLabel('sci_patent_condition', form.patentCondition)" />
- <CommonInfoRow label="专利(申请)号" :value="form.patentNumber" />
- <CommonInfoRow label="申请人" :value="form.applicantName" />
- <CommonInfoRow label="第几参与人" :value="form.patentApplicationCode" />
- <CommonInfoRow label="申请日期" :value="formatDate(form.patentApplicationDate)" />
- <CommonInfoRow label="分类号" :value="form.classNum" />
- <CommonInfoRow label="公开号" :value="form.patentPublicCode" />
- <CommonInfoRow label="公开日期" :value="formatDate(form.patentPublicDate)" />
- <CommonInfoRow label="授权号" :value="form.patentAccreditCode" />
- <CommonInfoRow label="授权日期" :value="formatDate(form.effectiveTime)" />
- <CommonInfoRow label="署名" :value="getDictLabel('sci_circuit_signature', form.patentSchoolSignature)
- " />
- <CommonInfoRow label="专利权人" :value="form.patentObligee" />
- <CommonInfoRow label="专利代理机构" :value="form.entrustUnit" />
- <CommonInfoRow label="代理人" :value="form.agencyUserName" />
- <CommonInfoRow label="代理人联系电话" :value="form.agencyPhone" />
- <CommonInfoRow label="所属年份" :value="form.patentYeat ? formatDate(form.patentYeat, 'YYYY') : '-'" />
- <CommonInfoRow label="所属平台" isColumn>
- <view class="platform-tags">
- <template v-if="platformList.length > 0">
- <uv-tags v-for="(p, index) in platformList" :key="index" :text="p.platformName === '其他'
- ? '其他'
- : p.platformType
- ? p.platformName + ' (' + p.platformType + ')'
- : p.platformName
- " type="primary" plain size="mini" class="mr5"></uv-tags>
- </template>
- <text v-else>-</text>
- </view>
- </CommonInfoRow>
- <CommonInfoRow label="所属团队" :value="form.belongTeam || '-'" />
- <CommonInfoRow label="成果权属" :value="getDictLabel('achievement_owner_unit', form.achievementOwnerUnit)" />
- <CommonInfoRow label="是否失效" :value="form.patentEffectiveness === '10' ? '是' : form.patentEffectiveness === '20' ? '否' : '-'" />
- <CommonInfoRow label="是否职务专利" :value="form.patentOffice === '10' ? '是' : form.patentOffice === '20' ? '否' : '-'" />
- <CommonInfoRow label="是否为PCT专利" :value="form.patentCt === '10' ? '是' : form.patentCt === '20' ? '否' : '-'" />
- <CommonInfoRow label="专利附件" isColumn>
- <view class="file-links">
- <template v-if="patentFileList.length">
- <view class="file-item" v-for="(item, index) in patentFileList" :key="'patent-' + index" @click="handlePreview(item)">
- <text class="file-link">{{ item.name || item.fileName || '-' }}</text>
- </view>
- </template>
- <text v-else>-</text>
- </view>
- </CommonInfoRow>
- <CommonInfoRow label="专利委托合同附件" isColumn>
- <view class="file-links">
- <template v-if="agencyContractFileList.length">
- <view class="file-item" v-for="(item, index) in agencyContractFileList" :key="'agency-' + index" @click="handlePreview(item)">
- <text class="file-link">{{ item.name || item.fileName || '-' }}</text>
- </view>
- </template>
- <text v-else>-</text>
- </view>
- </CommonInfoRow>
- <CommonInfoRow label="专利简介" :value="form.patentDesc" isColumn />
- </CommonSection>
- <!-- 转化信息 -->
- <CommonSection title="转化信息" v-if="['60', '70', '80'].includes(form.patentStatus)">
- <CommonInfoRow label="转化时间" :value="formatDate(form.invertTime)" />
- <CommonInfoRow label="转化金额" :value="form.invertAmount || '-'" isAmount />
- <CommonInfoRow label="转化单位" :value="form.invertUnit || '-'" />
- <CommonInfoRow label="知识产权交易类型" :value="form.tradeType === '10' ? '转让' : form.tradeType === '20' ? '许可' : '-'" />
- <CommonInfoRow label="转化附件" isColumn>
- <view class="file-links">
- <template v-if="invertFileList.length">
- <view class="file-item" v-for="(item, index) in invertFileList" :key="'invert-' + index" @click="handlePreview(item)">
- <text class="file-link">{{ item.name || item.fileName || '-' }}</text>
- </view>
- </template>
- <text v-else>-</text>
- </view>
- </CommonInfoRow>
- </CommonSection>
- <!-- 发明(设计)人信息 -->
- <CommonSection title="发明(设计)人信息" v-if="form.memberList?.length">
- <view class="member-list">
- <view class="member-item" v-for="(member, index) in form.memberList" :key="index">
- <view class="member-avatar">{{ Number(index) + 1 }}</view>
- <view class="member-body">
- <view class="member-header">
- <text class="name">{{ member.memberName }}</text>
- <text class="badge" :class="'badge-' + getMemberBadgeType(member.memberType)">
- {{ getDictLabel("sci_paper_member_type", member.memberType) }}
- </text>
- </view>
- <view class="member-tags">
- <text class="tag" v-if="member.degree">{{
- getDictLabel("sci_academic_degree", member.degree)
- }}</text>
- <text class="tag" v-if="member.education">{{
- getDictLabel("sci_education", member.education)
- }}</text>
- <text class="tag" v-if="member.jobTitle">{{
- getDictLabel("sci_discipline_job_title", member.jobTitle)
- }}</text>
- </view>
- <view class="member-meta">
- <view class="meta-item" v-if="member.order">
- <text class="meta-label">排名</text>
- <text class="meta-value">{{ member.order }}</text>
- </view>
- <view class="meta-item" v-if="member.contributionRate">
- <text class="meta-label">贡献率</text>
- <text class="meta-value">{{ member.contributionRate }}%</text>
- </view>
- </view>
- <view class="member-dept" v-if="member.deptName">
- <uv-icon name="home" size="24rpx" color="#909399"></uv-icon>
- <text>{{ member.deptName }}</text>
- </view>
- </view>
- </view>
- </view>
- </CommonSection>
- <!-- 标注经济来源 -->
- <CommonSection title="标注经济来源" v-if="form.projList?.length">
- <view class="achievement-card" v-for="(row, index) in form.projList" :key="index">
- <view class="a-row">
- <text class="al">关联类型:</text>
- <text class="av">{{
- row.sourceType === "10" ? "项目" : "学科"
- }}</text>
- </view>
- <view class="a-row">
- <text class="al">项目/学科:</text>
- <text class="av">{{ row.projectSource || "-" }}</text>
- </view>
- </view>
- </CommonSection>
- <!-- 审批信息 -->
- <CommonSection title="审批信息">
- <FlowTable :id="form.id" :businessCode="'学术专利-' + form.patentCode" defCode="sci_academic_achievement" />
- </CommonSection>
- <!-- 授权审核进度 -->
- <CommonSection title="授权审核进度">
- <FlowTable :id="form.id" :businessCode="'学术专利授权-' + form.patentCode" defCode="sci_academic_achievement_auth" />
- </CommonSection>
- <!-- 转化审批信息 -->
- <CommonSection title="转化审批信息">
- <FlowTable :id="form.id" :businessCode="'专利转化-' + form.patentCode" defCode="sci_academic_achievement" />
- </CommonSection>
- </template>
- <uv-empty v-else mode="data" text="暂无数据"></uv-empty>
- </view>
- </template>
- <script setup lang="ts">
- import { ref, onMounted, watch, computed } from "vue";
- import { useDict } from "@/hooks/useDict";
- import { useDocumentApi } from "@/api/document";
- import { formatDate } from "@/utils/date";
- import { previewFile } from "@/utils/file";
- import to from "await-to-js";
- import FlowTable from "@/pages/project/components/detail/FlowTable.vue";
- import CommonSection from "@/components/ui/CommonSection.vue";
- import CommonInfoRow from "@/components/ui/CommonInfoRow.vue";
- const props = defineProps<{
- code: string;
- }>();
- const { getDictLabel } = useDict(
- "sci_patent_class",
- "sci_patent_scope",
- "sci_patent_condition",
- "sci_circuit_signature",
- "sci_cooperation",
- "achievement_owner_unit",
- "sci_paper_member_type",
- "sci_academic_degree",
- "sci_education",
- "sci_discipline_job_title"
- );
- const documentApi = useDocumentApi();
- const form = ref<any>(null);
- const loading = ref(false);
- const platformList = computed(() => {
- if (form.value?.belongPlatform) {
- try {
- const data = JSON.parse(form.value.belongPlatform);
- return Array.isArray(data) ? data : [];
- } catch (e) {
- if (form.value.belongPlatform === "其他")
- return [{ platformName: "其他" }];
- return [{ platformName: form.value.belongPlatform }];
- }
- }
- return [];
- });
- const parseFileList = (fileStr: string) => {
- if (!fileStr) return [];
- try {
- const files = JSON.parse(fileStr);
- return Array.isArray(files) ? files : [files];
- } catch (e) {
- return [];
- }
- };
- const patentFileList = computed(() => parseFileList(form.value?.patentFile));
- const agencyContractFileList = computed(() => parseFileList(form.value?.agencyContractFile));
- const invertFileList = computed(() => parseFileList(form.value?.invertUrl));
- const handlePreview = (file: any) => {
- const url = file.fileUrl || file.url;
- const name = file.fileName || file.name;
- if (url) {
- previewFile(url, name);
- }
- };
- const fetchData = async () => {
- if (!props.code) return;
- loading.value = true;
- const patentCode = props.code.includes("-")
- ? props.code.split("-")[1]
- : props.code;
- const [err, res] = await to(documentApi.getPatentByCode(patentCode));
- if (!err && res?.data) {
- form.value = res.data;
- }
- loading.value = false;
- };
- onMounted(() => {
- fetchData();
- });
- watch(
- () => props.code,
- () => {
- fetchData();
- }
- );
- const getMemberBadgeType = (type: string) => {
- const map: Record<string, string> = {
- "10": "primary",
- "20": "success",
- "30": "warning",
- };
- return map[type] || "default";
- };
- </script>
- <style lang="scss" scoped>
- @import "./common.scss";
- .member-list {
- .member-item {
- display: flex;
- align-items: flex-start;
- background: #fff;
- border: 2rpx solid #f0f2f5;
- border-radius: 16rpx;
- padding: 24rpx;
- margin-bottom: 20rpx;
- box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.04);
- &:last-child {
- margin-bottom: 0;
- }
- }
- .member-avatar {
- width: 56rpx;
- height: 56rpx;
- background: linear-gradient(135deg, #2979ff 0%, #1a66ff 100%);
- color: #fff;
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 26rpx;
- font-weight: 600;
- flex-shrink: 0;
- margin-right: 20rpx;
- }
- .member-body {
- flex: 1;
- min-width: 0;
- }
- .member-header {
- display: flex;
- align-items: center;
- margin-bottom: 16rpx;
- flex-wrap: wrap;
- .name {
- font-size: 32rpx;
- font-weight: 600;
- color: #1a1a1a;
- margin-right: 16rpx;
- }
- .badge {
- font-size: 22rpx;
- padding: 4rpx 16rpx;
- border-radius: 20rpx;
- color: #fff;
- }
- .badge-primary {
- background: #2979ff;
- }
- .badge-success {
- background: #19be6b;
- }
- .badge-warning {
- background: #ff9900;
- }
- .badge-default {
- background: #909399;
- }
- }
- .member-tags {
- display: flex;
- flex-wrap: wrap;
- margin-bottom: 16rpx;
- .tag {
- font-size: 24rpx;
- color: #606266;
- background: #f4f4f5;
- padding: 6rpx 16rpx;
- border-radius: 8rpx;
- margin-right: 12rpx;
- margin-bottom: 8rpx;
- &:last-child {
- margin-right: 0;
- }
- }
- }
- .member-meta {
- display: flex;
- flex-wrap: wrap;
- margin-bottom: 12rpx;
- .meta-item {
- display: flex;
- align-items: center;
- margin-right: 32rpx;
- margin-bottom: 8rpx;
- &:last-child {
- margin-right: 0;
- }
- .meta-label {
- font-size: 24rpx;
- color: #909399;
- margin-right: 8rpx;
- }
- .meta-value {
- font-size: 24rpx;
- color: #606266;
- font-weight: 500;
- }
- }
- }
- .member-dept {
- display: flex;
- align-items: center;
- font-size: 24rpx;
- color: #909399;
- text {
- margin-left: 8rpx;
- }
- }
- }
- .file-links {
- .file-item {
- padding: 6rpx 0;
- }
- .file-link {
- color: #2979ff;
- text-decoration: underline;
- word-break: break-all;
- }
- }
- </style>
|