284 lines
8.3 KiB
Vue
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>
|