2025-04-07 07:59:59 +01:00

284 lines
8.3 KiB
Vue

<template>
<div class="detail">
<div class="detail-left">
<el-menu class="menu-vertical" :default-active="state.active" @select="onSelect">
<el-menu-item v-for="item in state.tabList" :key="item.value" :index="item.value">
<!-- <i :class="`iconfont ${item.icon}`"></i> -->
<span>{{ item.label }}</span>
</el-menu-item>
</el-menu>
</div>
<div v-loading="state.loading" class="detail-right">
<div class="detail-right-header">
<span>{{ state.activeLabel }}</span>
<el-button icon="Back" circle @click="onBack" />
</div>
<div class="detail-right-content">
<el-card class="detail-card">
<div v-if="state.active == 1" class="detail-card-info">
<div class="product-left">
<el-descriptions :column="1" border>
<el-descriptions-item label="产品名称">{{ data.basicInfo?.productName }}</el-descriptions-item>
<el-descriptions-item label="产品数量">{{ data.basicInfo?.number }}{{ data.basicInfo?.unit }}</el-descriptions-item>
<el-descriptions-item label="生产经营主体">{{ data.basicInfo?.businessName }}</el-descriptions-item>
<el-descriptions-item label="原产地">{{ data.basicInfo?.originAddress }}</el-descriptions-item>
<el-descriptions-item label="生产日期">{{ data.basicInfo?.harvestTime }}</el-descriptions-item>
<el-descriptions-item label="保质期">{{ data.basicInfo?.qualityGuaranteePeriod }}</el-descriptions-item>
<el-descriptions-item label="溯源码">{{ data.basicInfo?.originCode }}</el-descriptions-item>
<el-descriptions-item label="追溯次数">{{ data.basicInfo?.count }}</el-descriptions-item>
</el-descriptions>
</div>
<div class="product-right">
<el-image :src="data.basicInfo?.productUrl" fit="cover" class="product-image" />
</div>
</div>
<ul v-if="state.active == 2" class="detail-card-info flex-column">
<li v-for="(item, index) in data.secureDetections" :key="index" class="product">
<div class="product-text">{{ item.qualityDescribe }}</div>
<div v-if="item.qualityReportUrl" class="product-file">
<el-image
style="width: 300px; height: 300px"
:src="item.qualityReportUrl"
:zoom-rate="1.2"
:max-scale="7"
:min-scale="0.2"
:preview-src-list="state.qualityReportUrls"
:initial-index="0"
fit="cover"
lazy
/>
<!-- <el-empty v-else description="暂时没有相关信息!" /> -->
</div>
</li>
</ul>
<!-- <div v-if="state.active == 3" class="detail-card-info">
<div class="product-left">
<el-descriptions :column="1" border>
<el-descriptions-item label="经营主体名称">{{ data.basicInfo?.productName }}</el-descriptions-item>
<el-descriptions-item label="主体类型">{{ data.basicInfo?.number }}</el-descriptions-item>
<el-descriptions-item label="统一社会信用代码">{{ data.basicInfo?.businessName }}</el-descriptions-item>
<el-descriptions-item label="经营项目">{{ data.basicInfo?.originAddress }}</el-descriptions-item>
<el-descriptions-item label="公司地址">{{ data.basicInfo?.harvestTime }}</el-descriptions-item>
<el-descriptions-item label="负责人">{{ data.basicInfo?.qualityGuaranteePeriod }}</el-descriptions-item>
</el-descriptions>
</div>
<div class="product-right">
<el-image :src="data.basicInfo?.productUrl" fit="cover" class="product-image" />
</div>
</div> -->
<div v-if="state.active == 4" class="detail-card-info">
<avue-crud ref="crudRef" :data="data.list" :option="state.options"> </avue-crud>
</div>
<div v-if="state.active == 5" class="detail-card-info">
<div class="product">
<div class="product-file">
<el-image
v-if="data.blockchainUrl"
style="width: 300px; height: 300px"
:src="data.blockchainUrl"
:zoom-rate="1.2"
:max-scale="7"
:min-scale="0.2"
:preview-src-list="state.blockchainUrls"
:initial-index="0"
fit="cover"
/>
<el-empty v-else description="暂时没有相关信息!" />
</div>
</div>
</div>
</el-card>
</div>
</div>
</div>
</template>
<script setup>
import { reactive, ref } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { useApp } from '@/hooks';
import { CRUD_VIEW_OPTIONS } from '@/config';
import { isEmpty } from '@/utils';
import { GetTraceDetail } from '@/apis/trace/coding';
const { VITE_APP_NAME } = import.meta.env;
const router = useRouter();
const route = useRoute();
const app = useApp();
const crudRef = ref(null);
const state = reactive({
loading: false,
active: 1,
activeLabel: '基本信息',
tabList: [
{
label: '基本信息',
value: 1,
icon: 'InfoFilled',
},
{
label: '安全检测',
value: 2,
icon: 'Warning',
},
// {
// label: '经营主体',
// value: 3,
// icon: 'User',
// },
{
label: '农事活动',
value: 4,
icon: 'Calendar',
},
{
label: '区块链认证',
value: 5,
icon: 'Connection',
},
],
options: {
...CRUD_VIEW_OPTIONS,
column: [
{
label: '活动时间',
prop: 'qualityPerson',
},
{
label: '活动名称',
prop: 'harvestBatch',
width: 200,
},
{
label: '投入品',
prop: 'productName',
},
{
label: '作业人',
prop: 'qualityPerson',
},
],
},
qualityReportUrls: [],
blockchainUrls: [],
});
const data = ref({
basicInfo: {},
secureDetections: [],
list: [],
});
const loadData = () => {
state.loading = true;
state.qualityReportUrls = [];
GetTraceDetail({ id: route.query.code })
.then((res) => {
if (res.code === 200) {
data.value = res.data;
if (!isEmpty(res.data.secureDetections)) {
res.data.secureDetections.forEach((item) => {
if (!isEmpty(item.qualityReportUrl)) {
state.qualityReportUrls.push(item.qualityReportUrl);
}
});
}
}
})
.catch((err) => {
app.$message.error(err.msg);
data.value = {
basicInfo: {},
secureDetections: [],
list: [],
};
})
.finally(() => {
state.loading = false;
});
};
loadData();
const onSelect = (index) => {
const current = state.tabList.find((item) => item.value == index);
state.active = index;
state.activeLabel = current.label ?? '';
};
const onBack = () => {
router.push({ path: `/${VITE_APP_NAME}/trace-search` });
};
</script>
<style lang="scss" scoped>
.detail {
display: flex;
min-height: 100%;
&-left {
width: 200px;
.menu-vertical {
height: 100%;
border-right: 0 !important;
}
}
&-right {
flex: 1;
padding: 20px;
&-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
span {
font-size: 16px;
color: $color-999;
}
}
}
&-card {
margin-bottom: 20px;
&-info {
display: flex;
gap: 40px;
.info-card {
margin-bottom: 20px;
}
}
}
}
.product {
width: 100%;
text-align: center;
&-left {
flex: 1;
}
&-right {
width: 300px;
}
&-image {
width: 100%;
height: 300px;
border-radius: 8px;
object-fit: cover;
}
&-text {
padding: 40px 0;
font-size: 16px;
color: $color-primary;
}
}
:deep(.el-descriptions__label) {
width: 120px;
}
:deep(.el-menu-item) {
display: flex;
align-items: center;
}
:deep(.el-menu-item .el-icon) {
margin-right: 8px;
}
</style>