feat: update report detail presentation
This commit is contained in:
@@ -5,9 +5,23 @@ import { appApi, type EvidenceAttachmentAsset, type ReportDetailData } from "../
|
||||
import { reportDetailFallback } from "../../mocks/app";
|
||||
import { resolveErrorMessage } from "../../utils/feedback";
|
||||
|
||||
type ReportTab = "product" | "trace";
|
||||
type ReportTab = "product" | "center" | "trace";
|
||||
type ProductDisplayItem = ReportDetailData["product_display"]["items"][number];
|
||||
|
||||
const centerIntroParagraphs = [
|
||||
"安心验(深圳)商品检验鉴定有限责任公司立足深港核心产业服务区,是一家专业从事商品检验、鉴定、测试及技术咨询的第三方服务机构。",
|
||||
"公司依托粤港澳大湾区雄厚的产业基础与国际贸易枢纽优势,致力于为 C 端消费者及 B 端电商平台、商家提供网购商品真伪鉴定、成色评估、价值评估及争议仲裁等一站式解决方案。",
|
||||
];
|
||||
const institutionBannerTitle = "安心验(深圳)商品检验鉴定有限责任公司";
|
||||
const institutionBannerSubtitle = "ANXINYAN (SHENZHEN) COMMODITY INSPECTION AND APPRAISAL CO., LTD.";
|
||||
const anxinyanStatementItems = [
|
||||
"本电子意见书鉴定结果仅对送检样品负责,整体任一部分损毁或丢失则意见书失效。",
|
||||
"若对意见书的内容和结论持有异议,需在意见书出具后15日内提出,逾期不予受理,本电子意见书不得用于司法用途。",
|
||||
"品牌方为商品的设计及制造方,如品牌方确认该鉴定样品为品牌方制造及销售商品,以品牌方的结论为准。",
|
||||
"如因我司鉴定结果失误给申请人造成损失且无法挽回的,我司予以赔偿。赔偿范围仅限于申请人的直接损失,且赔偿金额总计不超过该检验项目鉴定费用的三倍。",
|
||||
"企业信息和产品信息均由委托单位提供,鉴定结论不涉及样品品质检测等信息。",
|
||||
];
|
||||
|
||||
const detail = ref<ReportDetailData>(reportDetailFallback);
|
||||
const downloading = ref(false);
|
||||
const loading = ref(false);
|
||||
@@ -92,6 +106,11 @@ const productSpecItems = computed(() => {
|
||||
].filter((item) => item.value && item.value !== "-");
|
||||
});
|
||||
const traceInfoVisible = computed(() => Boolean(detail.value.trace_info?.visible || detail.value.report_header.trace_info_visible));
|
||||
const centerTabVisible = computed(() => {
|
||||
const serviceProvider = textValue(detail.value.report_header.service_provider).toLowerCase();
|
||||
const serviceProviderTextValue = textValue(detail.value.report_header.service_provider_text);
|
||||
return serviceProvider !== "zhongjian" && serviceProviderTextValue !== "中检鉴定";
|
||||
});
|
||||
const traceNodes = computed(() => (traceInfoVisible.value ? detail.value.trace_info?.nodes || [] : []));
|
||||
const zhongjianReportFiles = computed(() => detail.value.zhongjian_report_files || []);
|
||||
const zhongjianImageFiles = computed(() => zhongjianReportFiles.value.filter((item) => item.file_type === "image"));
|
||||
@@ -206,12 +225,6 @@ function openAsset(item: EvidenceAttachmentAsset, files: EvidenceAttachmentAsset
|
||||
uni.showToast({ title: "当前附件类型暂不支持预览", icon: "none" });
|
||||
}
|
||||
|
||||
function contactService() {
|
||||
uni.navigateTo({
|
||||
url: `/pages/support/create?ticket_type=report_issue&prefill_title=${encodeURIComponent("报告咨询")}`,
|
||||
});
|
||||
}
|
||||
|
||||
function openAntiModal() {
|
||||
antiCode.value = "";
|
||||
antiResult.value = null;
|
||||
@@ -306,8 +319,8 @@ function downloadPdf() {
|
||||
});
|
||||
}
|
||||
|
||||
watch(traceInfoVisible, (visible) => {
|
||||
if (!visible && activeTab.value === "trace") {
|
||||
watch([traceInfoVisible, centerTabVisible], ([traceVisible, centerVisible]) => {
|
||||
if ((!traceVisible && activeTab.value === "trace") || (!centerVisible && activeTab.value === "center")) {
|
||||
activeTab.value = "product";
|
||||
}
|
||||
});
|
||||
@@ -364,6 +377,13 @@ onLoad(async (options) => {
|
||||
<template v-else>
|
||||
<view class="report-shell">
|
||||
<view class="report-shell__watermark" aria-hidden="true"></view>
|
||||
<view class="report-institution-banner">
|
||||
<image class="report-institution-banner__logo" src="/static/logo.png" mode="aspectFit" />
|
||||
<view class="report-institution-banner__text">
|
||||
<view class="report-institution-banner__title">{{ institutionBannerTitle }}</view>
|
||||
<view class="report-institution-banner__subtitle">{{ institutionBannerSubtitle }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="report-cover">
|
||||
<swiper v-if="reportImages.length" class="report-cover__swiper" indicator-dots circular>
|
||||
<swiper-item v-for="item in reportImages" :key="item.file_url || item.file_id">
|
||||
@@ -378,28 +398,29 @@ onLoad(async (options) => {
|
||||
<view v-else class="report-cover__empty">暂无鉴定图片</view>
|
||||
</view>
|
||||
|
||||
<view class="report-meta">
|
||||
<view class="report-meta__row">
|
||||
<text class="report-meta__label">产品名称</text>
|
||||
<text class="report-meta__value">{{ productName }}</text>
|
||||
<view class="report-product-summary">
|
||||
<view class="report-product-summary__row">
|
||||
<text class="report-product-summary__tag">产品名称</text>
|
||||
<text class="report-product-summary__value">{{ productName }}</text>
|
||||
</view>
|
||||
<view class="report-meta__row">
|
||||
<text class="report-meta__label">检测机构</text>
|
||||
<text class="report-meta__value">{{ institutionName }}</text>
|
||||
<view class="report-product-summary__row">
|
||||
<text class="report-product-summary__tag report-product-summary__tag--muted">鉴定机构</text>
|
||||
<text class="report-product-summary__value">{{ institutionName }}</text>
|
||||
</view>
|
||||
<view class="report-meta__row">
|
||||
<text class="report-meta__label">报告编号</text>
|
||||
<text class="report-meta__value">{{ reportNo || "-" }}</text>
|
||||
<view class="report-product-summary__row">
|
||||
<text class="report-product-summary__tag report-product-summary__tag--muted">报告编号</text>
|
||||
<text class="report-product-summary__value">{{ reportNo || "-" }}</text>
|
||||
</view>
|
||||
<view class="report-meta__row report-meta__row--date">
|
||||
<text class="report-meta__label">出具日期</text>
|
||||
<text class="report-meta__download" @click="downloadPdf">{{ downloading ? "下载中" : "下载PDF" }}</text>
|
||||
<text class="report-meta__value">{{ publishTime }}</text>
|
||||
<view class="report-product-summary__row">
|
||||
<text class="report-product-summary__tag report-product-summary__tag--muted">出具日期</text>
|
||||
<text class="report-product-summary__value">{{ publishTime }}</text>
|
||||
<text class="report-product-summary__download" @click="downloadPdf">{{ downloading ? "下载中" : "下载PDF" }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="report-tabs">
|
||||
<view :class="['report-tab', activeTab === 'product' ? 'report-tab--active' : '']" @click="activeTab = 'product'">产品信息</view>
|
||||
<view v-if="centerTabVisible" :class="['report-tab', activeTab === 'center' ? 'report-tab--active' : '']" @click="activeTab = 'center'">鉴定中心</view>
|
||||
<view v-if="traceInfoVisible" :class="['report-tab', activeTab === 'trace' ? 'report-tab--active' : '']" @click="activeTab = 'trace'">追溯信息</view>
|
||||
</view>
|
||||
|
||||
@@ -446,9 +467,34 @@ onLoad(async (options) => {
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="report-statement">
|
||||
<view class="report-statement__title">安心验声明:</view>
|
||||
<view v-for="(item, index) in anxinyanStatementItems" :key="item" class="report-statement__item">
|
||||
{{ index + 1 }}、{{ item }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-else-if="traceInfoVisible" class="report-panel report-panel--trace">
|
||||
<view v-else-if="activeTab === 'center' && centerTabVisible" class="report-panel report-panel--center">
|
||||
<view class="center-profile">
|
||||
<view class="center-profile__brand">
|
||||
<image class="center-profile__logo" src="/static/logo.png" mode="aspectFit" />
|
||||
<view class="center-profile__text">
|
||||
<view class="center-profile__name">{{ institutionBannerTitle }}</view>
|
||||
<view class="center-profile__subtitle">{{ institutionBannerSubtitle }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="center-profile__divider"></view>
|
||||
<view class="center-profile__body">
|
||||
<view v-for="item in centerIntroParagraphs" :key="item" class="center-profile__paragraph">
|
||||
{{ item }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-else-if="activeTab === 'trace' && traceInfoVisible" class="report-panel report-panel--trace">
|
||||
<view v-if="traceNodes.length === 0" class="trace-empty">暂无追溯信息</view>
|
||||
<view v-for="node in traceNodes" :key="node.code" class="trace-node">
|
||||
<view class="trace-node__head">
|
||||
@@ -481,7 +527,6 @@ onLoad(async (options) => {
|
||||
</view>
|
||||
|
||||
<view class="fixed-action-bar report-actions">
|
||||
<view class="btn btn--secondary" @click="contactService">联系我们</view>
|
||||
<view class="btn btn--primary" @click="openAntiModal">防伪查询</view>
|
||||
</view>
|
||||
|
||||
@@ -542,23 +587,24 @@ onLoad(async (options) => {
|
||||
max-width: 100vw;
|
||||
box-sizing: border-box;
|
||||
overflow-x: hidden;
|
||||
padding: 28rpx 32rpx 170rpx;
|
||||
background: #f1f3f6;
|
||||
padding: 0 0 150rpx;
|
||||
background: #eef1f5;
|
||||
color: #3c3f45;
|
||||
}
|
||||
|
||||
.report-shell {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border-radius: 28rpx;
|
||||
width: 100%;
|
||||
border-radius: 0;
|
||||
background: #ffffff;
|
||||
box-shadow: 0 18rpx 48rpx rgba(31, 36, 48, 0.08);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.report-shell__watermark {
|
||||
position: absolute;
|
||||
z-index: 0;
|
||||
top: 374rpx;
|
||||
top: 530rpx;
|
||||
left: 28rpx;
|
||||
right: 28rpx;
|
||||
height: 560rpx;
|
||||
@@ -568,18 +614,63 @@ onLoad(async (options) => {
|
||||
}
|
||||
|
||||
.report-cover,
|
||||
.report-meta,
|
||||
.report-institution-banner,
|
||||
.report-product-summary,
|
||||
.report-tabs,
|
||||
.report-panel {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.report-cover {
|
||||
height: 356rpx;
|
||||
margin: 28rpx 28rpx 0;
|
||||
.report-institution-banner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14rpx;
|
||||
min-height: 124rpx;
|
||||
padding: 0 28rpx;
|
||||
border-bottom: 1px solid rgba(229, 229, 229, 0.7);
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.report-institution-banner__logo {
|
||||
flex: 0 0 auto;
|
||||
display: block;
|
||||
width: 66rpx;
|
||||
height: 66rpx;
|
||||
}
|
||||
|
||||
.report-institution-banner__text {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.report-institution-banner__title {
|
||||
color: #34363b;
|
||||
font-size: 21rpx;
|
||||
font-weight: 900;
|
||||
line-height: 1.24;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
border-radius: 10rpx;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.report-institution-banner__subtitle {
|
||||
margin-top: 5rpx;
|
||||
color: #737982;
|
||||
font-size: 13rpx;
|
||||
font-weight: 700;
|
||||
line-height: 1.25;
|
||||
letter-spacing: 0;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.report-cover {
|
||||
height: 412rpx;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
border-radius: 0;
|
||||
background: #e8eaee;
|
||||
}
|
||||
|
||||
@@ -602,78 +693,89 @@ onLoad(async (options) => {
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
|
||||
.report-meta {
|
||||
padding: 34rpx 28rpx 12rpx;
|
||||
}
|
||||
|
||||
.report-meta__row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 18rpx;
|
||||
min-width: 0;
|
||||
min-height: 48rpx;
|
||||
}
|
||||
|
||||
.report-meta__row + .report-meta__row {
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.report-meta__label {
|
||||
flex: 0 0 138rpx;
|
||||
display: block;
|
||||
color: #7d828a;
|
||||
font-size: 28rpx;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.report-meta__value {
|
||||
flex: 1;
|
||||
display: block;
|
||||
min-width: 0;
|
||||
color: #44474d;
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
line-height: 1.35;
|
||||
text-align: right;
|
||||
white-space: normal;
|
||||
word-break: break-all;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.report-meta__row--date .report-meta__value {
|
||||
flex: 0 1 auto;
|
||||
margin-left: auto;
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
.report-meta__download {
|
||||
flex: 0 0 auto;
|
||||
display: block;
|
||||
min-height: 38rpx;
|
||||
padding: 0 16rpx;
|
||||
border: 1px solid rgba(221, 179, 47, 0.74);
|
||||
border-radius: 6rpx;
|
||||
background: #fff9e6;
|
||||
color: var(--color-accent);
|
||||
font-size: 22rpx;
|
||||
font-weight: 700;
|
||||
line-height: 36rpx;
|
||||
}
|
||||
|
||||
.report-tabs {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 104rpx;
|
||||
padding: 26rpx 40rpx 34rpx;
|
||||
padding: 24rpx 20rpx 34rpx;
|
||||
border-top: 1px solid rgba(229, 229, 229, 0.72);
|
||||
border-bottom: 1px solid rgba(229, 229, 229, 0.72);
|
||||
}
|
||||
|
||||
.report-product-summary {
|
||||
display: grid;
|
||||
gap: 14rpx;
|
||||
padding: 20rpx 28rpx 22rpx;
|
||||
background: #e7e9ef;
|
||||
}
|
||||
|
||||
.report-product-summary__row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14rpx;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.report-product-summary__tag {
|
||||
flex: 0 0 auto;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 36rpx;
|
||||
padding: 0 14rpx;
|
||||
border: 1px solid rgba(237, 189, 0, 0.78);
|
||||
border-radius: 6rpx;
|
||||
color: var(--color-accent);
|
||||
font-size: 22rpx;
|
||||
font-weight: 800;
|
||||
line-height: 1;
|
||||
background: rgba(255, 255, 255, 0.62);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.report-product-summary__tag--muted {
|
||||
border-color: #b8bdc6;
|
||||
color: #5d636d;
|
||||
}
|
||||
|
||||
.report-product-summary__value {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
color: #2f333a;
|
||||
font-size: 24rpx;
|
||||
font-weight: 800;
|
||||
line-height: 1.45;
|
||||
word-break: break-all;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.report-product-summary__download {
|
||||
flex: 0 0 auto;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 34rpx;
|
||||
padding: 0 12rpx;
|
||||
border: 1px solid rgba(237, 189, 0, 0.78);
|
||||
border-radius: 6rpx;
|
||||
color: var(--color-accent);
|
||||
font-size: 21rpx;
|
||||
font-weight: 800;
|
||||
line-height: 1;
|
||||
background: rgba(255, 255, 255, 0.68);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.report-tab {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
color: #8e9298;
|
||||
font-size: 32rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
line-height: 1.6;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.report-tab--active {
|
||||
@@ -817,6 +919,99 @@ onLoad(async (options) => {
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.report-statement {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
margin-top: 32rpx;
|
||||
padding-top: 10rpx;
|
||||
color: #343840;
|
||||
}
|
||||
|
||||
.report-statement__title {
|
||||
font-size: 28rpx;
|
||||
font-weight: 900;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.report-statement__item {
|
||||
margin-top: 16rpx;
|
||||
color: #3f444c;
|
||||
font-size: 26rpx;
|
||||
font-weight: 700;
|
||||
line-height: 2;
|
||||
word-break: break-all;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.report-panel--center {
|
||||
padding-top: 28rpx;
|
||||
}
|
||||
|
||||
.center-profile {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.center-profile__brand {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 18rpx;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.center-profile__logo {
|
||||
flex: 0 0 auto;
|
||||
display: block;
|
||||
width: 72rpx;
|
||||
height: 72rpx;
|
||||
}
|
||||
|
||||
.center-profile__text {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.center-profile__name {
|
||||
color: #30333a;
|
||||
font-size: 26rpx;
|
||||
font-weight: 900;
|
||||
line-height: 1.34;
|
||||
word-break: break-all;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.center-profile__subtitle {
|
||||
margin-top: 6rpx;
|
||||
color: #66707c;
|
||||
font-size: 18rpx;
|
||||
font-weight: 700;
|
||||
line-height: 1.25;
|
||||
letter-spacing: 0;
|
||||
word-break: break-all;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.center-profile__divider {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
margin: 26rpx 0 24rpx;
|
||||
background: #e5e5e5;
|
||||
}
|
||||
|
||||
.center-profile__body {
|
||||
display: grid;
|
||||
gap: 18rpx;
|
||||
}
|
||||
|
||||
.center-profile__paragraph {
|
||||
color: #767b84;
|
||||
font-size: 26rpx;
|
||||
line-height: 1.82;
|
||||
text-align: justify;
|
||||
word-break: break-all;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.report-panel--trace {
|
||||
padding-top: 2rpx;
|
||||
}
|
||||
@@ -964,34 +1159,27 @@ onLoad(async (options) => {
|
||||
}
|
||||
|
||||
.report-actions {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 28rpx;
|
||||
display: block;
|
||||
width: 100vw;
|
||||
box-sizing: border-box;
|
||||
padding: 22rpx 32rpx calc(22rpx + env(safe-area-inset-bottom));
|
||||
background: rgba(241, 243, 246, 0.96);
|
||||
padding: 0 0 env(safe-area-inset-bottom);
|
||||
background: #ffffff;
|
||||
border-top: 0;
|
||||
box-shadow: 0 -10rpx 34rpx rgba(31, 36, 48, 0.05);
|
||||
}
|
||||
|
||||
.report-actions .btn {
|
||||
min-width: 0;
|
||||
min-height: 76rpx;
|
||||
border-radius: 999rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.report-actions .btn--secondary {
|
||||
border: 0;
|
||||
background: #ffffff;
|
||||
color: #4f535a;
|
||||
.report-actions .btn {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
min-height: 112rpx;
|
||||
border-radius: 0;
|
||||
font-size: 32rpx;
|
||||
font-weight: 800;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.report-actions .btn--primary {
|
||||
background: #dfb733;
|
||||
background: #edbd00;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,24 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from "vue";
|
||||
import { computed, ref, watch } from "vue";
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app";
|
||||
import { adminApi, type AdminFileAsset, type AdminReportDetail } from "../../api/admin";
|
||||
import { showErrorToast, showInfoToast } from "../../utils/feedback";
|
||||
|
||||
type ReportTab = "product" | "attachments";
|
||||
type ReportTab = "product" | "center" | "attachments";
|
||||
|
||||
const centerIntroParagraphs = [
|
||||
"安心验(深圳)商品检验鉴定有限责任公司立足深港核心产业服务区,是一家专业从事商品检验、鉴定、测试及技术咨询的第三方服务机构。",
|
||||
"公司依托粤港澳大湾区雄厚的产业基础与国际贸易枢纽优势,致力于为 C 端消费者及 B 端电商平台、商家提供网购商品真伪鉴定、成色评估、价值评估及争议仲裁等一站式解决方案。",
|
||||
];
|
||||
const institutionBannerTitle = "安心验(深圳)商品检验鉴定有限责任公司";
|
||||
const institutionBannerSubtitle = "ANXINYAN (SHENZHEN) COMMODITY INSPECTION AND APPRAISAL CO., LTD.";
|
||||
const anxinyanStatementItems = [
|
||||
"本电子意见书鉴定结果仅对送检样品负责,整体任一部分损毁或丢失则意见书失效。",
|
||||
"若对意见书的内容和结论持有异议,需在意见书出具后15日内提出,逾期不予受理,本电子意见书不得用于司法用途。",
|
||||
"品牌方为商品的设计及制造方,如品牌方确认该鉴定样品为品牌方制造及销售商品,以品牌方的结论为准。",
|
||||
"如因我司鉴定结果失误给申请人造成损失且无法挽回的,我司予以赔偿。赔偿范围仅限于申请人的直接损失,且赔偿金额总计不超过该检验项目鉴定费用的三倍。",
|
||||
"企业信息和产品信息均由委托单位提供,鉴定结论不涉及样品品质检测等信息。",
|
||||
];
|
||||
|
||||
const loading = ref(false);
|
||||
const pageReady = ref(false);
|
||||
@@ -16,7 +30,12 @@ const returnConfirming = ref(false);
|
||||
const activeTab = ref<ReportTab>("product");
|
||||
const activeVideo = ref<AdminFileAsset | null>(null);
|
||||
|
||||
const isZhongjian = computed(() => detail.value?.report_header.service_provider === "zhongjian");
|
||||
const isZhongjian = computed(() => {
|
||||
const serviceProvider = textValue(detail.value?.report_header.service_provider).toLowerCase();
|
||||
const serviceProviderTextValue = textValue(detail.value?.report_header.service_provider_text);
|
||||
return serviceProvider === "zhongjian" || serviceProviderTextValue === "中检鉴定";
|
||||
});
|
||||
const centerTabVisible = computed(() => !isZhongjian.value);
|
||||
const isReturnReview = computed(() => Boolean(returnInternalTagNo.value && reportId.value));
|
||||
const evidenceAttachments = computed(() => detail.value?.evidence_attachments || []);
|
||||
const zhongjianReportFiles = computed(() => isZhongjian.value ? (detail.value?.zhongjian_report_files || []) : []);
|
||||
@@ -246,6 +265,12 @@ async function confirmReturnFromReport() {
|
||||
}
|
||||
}
|
||||
|
||||
watch(centerTabVisible, (visible) => {
|
||||
if (!visible && activeTab.value === "center") {
|
||||
activeTab.value = "product";
|
||||
}
|
||||
});
|
||||
|
||||
onLoad((options) => {
|
||||
reportId.value = Number(options?.id || 0);
|
||||
returnInternalTagNo.value = readQueryString(options?.return_internal_tag_no);
|
||||
@@ -283,6 +308,13 @@ onShow(() => {
|
||||
|
||||
<view class="report-shell">
|
||||
<view class="report-shell__watermark" aria-hidden="true"></view>
|
||||
<view class="report-institution-banner">
|
||||
<image class="report-institution-banner__logo" src="/static/logo.png" mode="aspectFit" />
|
||||
<view class="report-institution-banner__text">
|
||||
<view class="report-institution-banner__title">{{ institutionBannerTitle }}</view>
|
||||
<view class="report-institution-banner__subtitle">{{ institutionBannerSubtitle }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="report-cover">
|
||||
<swiper v-if="reportImages.length" class="report-cover__swiper" indicator-dots circular>
|
||||
<swiper-item v-for="item in reportImages" :key="item.file_url || item.file_id">
|
||||
@@ -297,28 +329,29 @@ onShow(() => {
|
||||
<view v-else class="report-cover__empty">暂无鉴定图片</view>
|
||||
</view>
|
||||
|
||||
<view class="report-meta">
|
||||
<view class="report-meta__row">
|
||||
<text class="report-meta__label">产品名称</text>
|
||||
<text class="report-meta__value">{{ productName }}</text>
|
||||
<view class="report-product-summary">
|
||||
<view class="report-product-summary__row">
|
||||
<text class="report-product-summary__tag">产品名称</text>
|
||||
<text class="report-product-summary__value">{{ productName }}</text>
|
||||
</view>
|
||||
<view class="report-meta__row">
|
||||
<text class="report-meta__label">检测机构</text>
|
||||
<text class="report-meta__value">{{ institutionName }}</text>
|
||||
<view class="report-product-summary__row">
|
||||
<text class="report-product-summary__tag report-product-summary__tag--muted">鉴定机构</text>
|
||||
<text class="report-product-summary__value">{{ institutionName }}</text>
|
||||
</view>
|
||||
<view class="report-meta__row">
|
||||
<text class="report-meta__label">报告编号</text>
|
||||
<text class="report-meta__value">{{ reportNo }}</text>
|
||||
<view class="report-product-summary__row">
|
||||
<text class="report-product-summary__tag report-product-summary__tag--muted">报告编号</text>
|
||||
<text class="report-product-summary__value">{{ reportNo }}</text>
|
||||
</view>
|
||||
<view class="report-meta__row report-meta__row--date">
|
||||
<text class="report-meta__label">出具日期</text>
|
||||
<text class="report-meta__tag">{{ detail.report_header.report_status_text }}</text>
|
||||
<text class="report-meta__value">{{ publishTime }}</text>
|
||||
<view class="report-product-summary__row">
|
||||
<text class="report-product-summary__tag report-product-summary__tag--muted">出具日期</text>
|
||||
<text class="report-product-summary__value">{{ publishTime }}</text>
|
||||
<text class="report-product-summary__status">{{ detail.report_header.report_status_text }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="report-tabs">
|
||||
<view :class="['report-tab', activeTab === 'product' ? 'report-tab--active' : '']" @click="activeTab = 'product'">产品信息</view>
|
||||
<view v-if="centerTabVisible" :class="['report-tab', activeTab === 'center' ? 'report-tab--active' : '']" @click="activeTab = 'center'">鉴定中心</view>
|
||||
<view :class="['report-tab', activeTab === 'attachments' ? 'report-tab--active' : '']" @click="activeTab = 'attachments'">核验附件</view>
|
||||
</view>
|
||||
|
||||
@@ -340,6 +373,31 @@ onShow(() => {
|
||||
<view v-if="item.remark" class="product-spec__remark">{{ item.remark }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="report-statement">
|
||||
<view class="report-statement__title">安心验声明:</view>
|
||||
<view v-for="(item, index) in anxinyanStatementItems" :key="item" class="report-statement__item">
|
||||
{{ index + 1 }}、{{ item }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-else-if="activeTab === 'center' && centerTabVisible" class="report-panel report-panel--center">
|
||||
<view class="center-profile">
|
||||
<view class="center-profile__brand">
|
||||
<image class="center-profile__logo" src="/static/logo.png" mode="aspectFit" />
|
||||
<view class="center-profile__text">
|
||||
<view class="center-profile__name">{{ institutionBannerTitle }}</view>
|
||||
<view class="center-profile__subtitle">{{ institutionBannerSubtitle }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="center-profile__divider"></view>
|
||||
<view class="center-profile__body">
|
||||
<view v-for="item in centerIntroParagraphs" :key="item" class="center-profile__paragraph">
|
||||
{{ item }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-else class="report-panel report-panel--attachments">
|
||||
@@ -421,9 +479,10 @@ onShow(() => {
|
||||
.report-page {
|
||||
width: 100vw;
|
||||
max-width: 100vw;
|
||||
padding: 28rpx 32rpx 48rpx;
|
||||
box-sizing: border-box;
|
||||
padding: 0 0 48rpx;
|
||||
overflow-x: hidden;
|
||||
background: #f1f3f6;
|
||||
background: #eef1f5;
|
||||
color: #3c3f45;
|
||||
}
|
||||
|
||||
@@ -432,6 +491,7 @@ onShow(() => {
|
||||
}
|
||||
|
||||
.notice-card {
|
||||
margin: 28rpx 32rpx;
|
||||
padding: 42rpx 34rpx;
|
||||
border-radius: 22rpx;
|
||||
background: #ffffff;
|
||||
@@ -457,7 +517,7 @@ onShow(() => {
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 22rpx;
|
||||
margin-bottom: 22rpx;
|
||||
margin: 22rpx 28rpx;
|
||||
padding: 22rpx 24rpx;
|
||||
border: 1px solid rgba(223, 183, 51, 0.34);
|
||||
border-radius: 18rpx;
|
||||
@@ -493,15 +553,16 @@ onShow(() => {
|
||||
.report-shell {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border-radius: 28rpx;
|
||||
width: 100%;
|
||||
border-radius: 0;
|
||||
background: #ffffff;
|
||||
box-shadow: 0 18rpx 48rpx rgba(31, 36, 48, 0.08);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.report-shell__watermark {
|
||||
position: absolute;
|
||||
z-index: 0;
|
||||
top: 374rpx;
|
||||
top: 530rpx;
|
||||
left: 28rpx;
|
||||
right: 28rpx;
|
||||
height: 560rpx;
|
||||
@@ -511,18 +572,63 @@ onShow(() => {
|
||||
}
|
||||
|
||||
.report-cover,
|
||||
.report-meta,
|
||||
.report-institution-banner,
|
||||
.report-product-summary,
|
||||
.report-tabs,
|
||||
.report-panel {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.report-cover {
|
||||
height: 356rpx;
|
||||
margin: 28rpx 28rpx 0;
|
||||
.report-institution-banner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14rpx;
|
||||
min-height: 124rpx;
|
||||
padding: 0 28rpx;
|
||||
border-bottom: 1px solid rgba(229, 229, 229, 0.7);
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.report-institution-banner__logo {
|
||||
flex: 0 0 auto;
|
||||
display: block;
|
||||
width: 66rpx;
|
||||
height: 66rpx;
|
||||
}
|
||||
|
||||
.report-institution-banner__text {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.report-institution-banner__title {
|
||||
overflow: hidden;
|
||||
border-radius: 10rpx;
|
||||
color: #34363b;
|
||||
font-size: 21rpx;
|
||||
font-weight: 900;
|
||||
line-height: 1.24;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.report-institution-banner__subtitle {
|
||||
margin-top: 5rpx;
|
||||
overflow: hidden;
|
||||
color: #737982;
|
||||
font-size: 13rpx;
|
||||
font-weight: 700;
|
||||
line-height: 1.25;
|
||||
letter-spacing: 0;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.report-cover {
|
||||
height: 412rpx;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
border-radius: 0;
|
||||
background: #e8eaee;
|
||||
}
|
||||
|
||||
@@ -545,78 +651,89 @@ onShow(() => {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.report-meta {
|
||||
padding: 34rpx 28rpx 12rpx;
|
||||
.report-product-summary {
|
||||
display: grid;
|
||||
gap: 14rpx;
|
||||
padding: 20rpx 28rpx 22rpx;
|
||||
background: #e7e9ef;
|
||||
}
|
||||
|
||||
.report-meta__row {
|
||||
.report-product-summary__row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 18rpx;
|
||||
align-items: center;
|
||||
gap: 14rpx;
|
||||
min-width: 0;
|
||||
min-height: 48rpx;
|
||||
}
|
||||
|
||||
.report-meta__row + .report-meta__row {
|
||||
margin-top: 20rpx;
|
||||
.report-product-summary__tag {
|
||||
flex: 0 0 auto;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 36rpx;
|
||||
padding: 0 14rpx;
|
||||
border: 1px solid rgba(237, 189, 0, 0.78);
|
||||
border-radius: 6rpx;
|
||||
background: rgba(255, 255, 255, 0.62);
|
||||
color: var(--work-accent);
|
||||
font-size: 22rpx;
|
||||
font-weight: 800;
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.report-meta__label {
|
||||
flex: 0 0 138rpx;
|
||||
display: block;
|
||||
color: #7d828a;
|
||||
font-size: 28rpx;
|
||||
line-height: 1.4;
|
||||
.report-product-summary__tag--muted {
|
||||
border-color: #b8bdc6;
|
||||
color: #5d636d;
|
||||
}
|
||||
|
||||
.report-meta__value {
|
||||
.report-product-summary__value {
|
||||
flex: 1;
|
||||
display: block;
|
||||
min-width: 0;
|
||||
color: #44474d;
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
line-height: 1.35;
|
||||
text-align: right;
|
||||
white-space: normal;
|
||||
color: #2f333a;
|
||||
font-size: 24rpx;
|
||||
font-weight: 800;
|
||||
line-height: 1.45;
|
||||
word-break: break-all;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.report-meta__row--date .report-meta__value {
|
||||
flex: 0 1 auto;
|
||||
margin-left: auto;
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
.report-meta__tag {
|
||||
.report-product-summary__status {
|
||||
flex: 0 0 auto;
|
||||
display: block;
|
||||
min-height: 38rpx;
|
||||
padding: 0 16rpx;
|
||||
border: 1px solid rgba(221, 179, 47, 0.74);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 34rpx;
|
||||
padding: 0 12rpx;
|
||||
border: 1px solid rgba(237, 189, 0, 0.78);
|
||||
border-radius: 6rpx;
|
||||
background: #fff9e6;
|
||||
color: #9f8433;
|
||||
font-size: 22rpx;
|
||||
font-weight: 700;
|
||||
line-height: 36rpx;
|
||||
background: rgba(255, 255, 255, 0.68);
|
||||
color: var(--work-accent);
|
||||
font-size: 21rpx;
|
||||
font-weight: 800;
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.report-tabs {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 104rpx;
|
||||
padding: 26rpx 40rpx 34rpx;
|
||||
padding: 24rpx 20rpx 34rpx;
|
||||
border-top: 1px solid rgba(229, 229, 229, 0.72);
|
||||
border-bottom: 1px solid rgba(229, 229, 229, 0.72);
|
||||
}
|
||||
|
||||
.report-tab {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
color: #8e9298;
|
||||
font-size: 32rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
line-height: 1.6;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.report-tab--active {
|
||||
@@ -650,7 +767,11 @@ onShow(() => {
|
||||
gap: 24rpx;
|
||||
min-height: 132rpx;
|
||||
padding: 10rpx 136rpx 30rpx 0;
|
||||
border: 0;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.report-result__content {
|
||||
@@ -742,6 +863,99 @@ onShow(() => {
|
||||
line-height: 1.45;
|
||||
}
|
||||
|
||||
.report-statement {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
margin-top: 32rpx;
|
||||
padding-top: 10rpx;
|
||||
color: #343840;
|
||||
}
|
||||
|
||||
.report-statement__title {
|
||||
font-size: 28rpx;
|
||||
font-weight: 900;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.report-statement__item {
|
||||
margin-top: 16rpx;
|
||||
color: #3f444c;
|
||||
font-size: 26rpx;
|
||||
font-weight: 700;
|
||||
line-height: 2;
|
||||
word-break: break-all;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.report-panel--center {
|
||||
padding-top: 28rpx;
|
||||
}
|
||||
|
||||
.center-profile {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.center-profile__brand {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 18rpx;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.center-profile__logo {
|
||||
flex: 0 0 auto;
|
||||
display: block;
|
||||
width: 72rpx;
|
||||
height: 72rpx;
|
||||
}
|
||||
|
||||
.center-profile__text {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.center-profile__name {
|
||||
color: #30333a;
|
||||
font-size: 26rpx;
|
||||
font-weight: 900;
|
||||
line-height: 1.34;
|
||||
word-break: break-all;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.center-profile__subtitle {
|
||||
margin-top: 6rpx;
|
||||
color: #66707c;
|
||||
font-size: 18rpx;
|
||||
font-weight: 700;
|
||||
line-height: 1.25;
|
||||
letter-spacing: 0;
|
||||
word-break: break-all;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.center-profile__divider {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
margin: 26rpx 0 24rpx;
|
||||
background: #e5e5e5;
|
||||
}
|
||||
|
||||
.center-profile__body {
|
||||
display: grid;
|
||||
gap: 18rpx;
|
||||
}
|
||||
|
||||
.center-profile__paragraph {
|
||||
color: #767b84;
|
||||
font-size: 26rpx;
|
||||
line-height: 1.82;
|
||||
text-align: justify;
|
||||
word-break: break-all;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.report-panel--attachments {
|
||||
padding-top: 2rpx;
|
||||
}
|
||||
@@ -840,9 +1054,9 @@ onShow(() => {
|
||||
bottom: 0;
|
||||
width: 100vw;
|
||||
box-sizing: border-box;
|
||||
padding: 22rpx 32rpx calc(22rpx + env(safe-area-inset-bottom));
|
||||
background: rgba(241, 243, 246, 0.96);
|
||||
box-shadow: 0 -10rpx 34rpx rgba(31, 36, 48, 0.05);
|
||||
padding: 0 0 env(safe-area-inset-bottom);
|
||||
background: #ffffff;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.report-actions__button {
|
||||
@@ -850,13 +1064,18 @@ onShow(() => {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
min-height: 82rpx;
|
||||
border-radius: 999rpx;
|
||||
background: #dfb733;
|
||||
min-height: 112rpx;
|
||||
border-radius: 0;
|
||||
background: #edbd00;
|
||||
color: #ffffff;
|
||||
font-size: 28rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: 800;
|
||||
line-height: 82rpx;
|
||||
line-height: 112rpx;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.report-actions__button::after {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.video-preview-mask {
|
||||
|
||||
Reference in New Issue
Block a user