391 lines
9.3 KiB
Vue
Raw Normal View History

2025-05-21 13:44:54 +08:00
<template>
<div class="auth-management">
<!-- 统计卡片 -->
<el-row :gutter="20">
<el-col :span="12">
<el-card shadow="hover" style="border-radius: 24px" :body-class="'card-body'">
<div class="card-left">
<img :src="getAssetsFile('images/brand/1532.png')" alt="" />
<div class="card-content flex-1 flex-column">
<div class="stat-number">999 <span></span></div>
<div class="stat-label">授权产品</div>
</div>
</div>
<div class="card-right">
<img :src="getAssetsFile('images/brand/cardLeft.png')" alt="" />
<p>较上月上涨 <span>7</span> </p>
</div>
</el-card>
</el-col>
<el-col :span="12">
<el-card shadow="hover" style="border-radius: 24px" :body-class="'card-body'">
<div class="card-left">
<img :src="getAssetsFile('images/brand/1533.png')" alt="" />
<div class="card-content flex-1 flex-column">
<div class="stat-number">999 <span></span></div>
<div class="stat-label">授权产品</div>
</div>
</div>
<div class="card-right">
<img :src="getAssetsFile('images/brand/cardRight.png')" alt="" />
<p>较上月上涨 <span>7</span> </p>
</div>
</el-card>
</el-col>
</el-row>
<!-- 产品列表 -->
<el-card shadow="hover" style="border-radius: 16px" class="product-card">
<!-- 状态筛选 -->
<el-tabs v-model="activeStatus" class="tabs-wrapper">
<el-tab-pane label="已授权" name="authorized" />
<el-tab-pane label="审批中" name="approving" />
<el-tab-pane label="已失效" name="expired" />
</el-tabs>
<div class="product-list">
<div v-for="(product, index) in filteredProducts" :key="product.id" class="product-item" :class="{ 'border-top': index > 0 }">
<div class="product-info">
<img class="product-img" :src="product.img" alt="product" />
<div class="product-text">
<span class="product-name">{{ product.name }}</span>
<div class="detail-item">
<label>检测批次</label>
<span>{{ product.batch }}</span>
</div>
<div class="detail-item">
<label>授权期限</label>
<span>{{ product.duration }}</span>
</div>
<div class="detail-item">
<label>到期时间</label>
<span class="text-expire">{{ product.expireDate }}</span>
</div>
</div>
</div>
<div class="product-action">
2025-05-22 10:38:36 +08:00
<el-tag :class="statusClass(activeStatus)" :type="statusTypeMap[product.status]">{{ product.statusLabel }}</el-tag>
2025-05-21 13:44:54 +08:00
<el-button
v-if="product.status === 'authorized'"
type="primary"
plain
:icon="Edit"
size="large"
style="border-radius: 8px"
@click="handleCertificate(product)"
>
授权证书
</el-button>
</div>
</div>
</div>
</el-card>
<!-- 证书预览 -->
<el-dialog v-model="certificateDialogVisible" title="授权证书" width="30%" destroy-on-close>
<div style="display: flex; justify-content: center">
<el-image
:src="currentCertificateImg"
fit="contain"
style="max-width: 600px; width: 80%"
:preview-src-list="[currentCertificateImg]"
:z-index="9999"
/>
</div>
</el-dialog>
</div>
</template>
<script setup>
import { ref, computed } from 'vue';
import { getAssetsFile } from '@/utils/index.js';
import { getProducts } from '@/apis/brand';
import { Edit } from '@element-plus/icons-vue';
const activeStatus = ref('authorized');
const statusTypeMap = {
authorized: 'success',
approving: 'warning',
expired: 'danger',
};
const products = ref([
{
id: 1,
name: '耿马镇沙疆西红柿',
batch: '10021',
duration: '6个月',
expireDate: '2025.01.01',
status: 'authorized',
statusLabel: '已授权',
img: getAssetsFile('images/brand/product4.png'),
},
{
id: 2,
name: '孟弄乡沙地土豆',
batch: '10022',
duration: '6个月',
expireDate: '2025.01.02',
status: 'authorized',
statusLabel: '已授权',
img: getAssetsFile('images/brand/product6.png'),
},
{
id: 3,
name: '芒洪乡水果彩椒',
batch: '10021',
duration: '6个月',
expireDate: '2025.01.01',
status: 'authorized',
statusLabel: '已授权',
img: getAssetsFile('images/brand/product2.png'),
},
{
id: 4,
name: '耿马镇沙疆西红柿',
batch: '10021',
duration: '6个月',
expireDate: '2025.01.01',
status: 'approving',
statusLabel: '审批中',
img: getAssetsFile('images/brand/product4.png'),
},
{
id: 5,
name: '孟弄乡沙地土豆',
batch: '10022',
duration: '6个月',
expireDate: '2025.01.02',
status: 'approving',
statusLabel: '审批中',
img: getAssetsFile('images/brand/product6.png'),
},
{
id: 6,
name: '芒洪乡水果彩椒',
batch: '10021',
duration: '6个月',
expireDate: '2025.01.01',
status: 'expired',
statusLabel: '已失效',
img: getAssetsFile('images/brand/product2.png'),
},
]);
const statusClass = (tab) => {
if (tab === 'approving') return 'text-warning status-tag';
if (tab === 'expired') return 'text-danger status-tag';
return 'text-success status-tag';
};
const filteredProducts = computed(() => products.value.filter((p) => p.status === activeStatus.value));
const certificateDialogVisible = ref(false);
const currentCertificateImg = ref('');
const handleCertificate = (product) => {
console.log('查看证书:', product);
// 假设每个产品都有一个证书图片路径字段,临时写死
currentCertificateImg.value = getAssetsFile('images/brand/sqzs.png'); // 你可以换成真实字段,如 product.certificate
certificateDialogVisible.value = true;
};
</script>
<style lang="scss" scoped>
.auth-management {
padding: 0 20px 0 0;
height: 100%;
display: flex;
flex-direction: column;
}
.product-card {
flex: 1;
margin-top: 20px;
}
:deep(.el-card__body) {
height: 100%;
}
.product-list {
2025-05-22 10:38:36 +08:00
height: calc(100% - 40px);
2025-05-21 13:44:54 +08:00
overflow: auto;
}
.product-list::-webkit-scrollbar {
display: none;
}
:deep(.card-body) {
display: flex;
align-items: center;
padding: 0;
width: 100%;
height: 100%;
justify-content: space-between;
}
.card-left:deep(img) {
width: 88px;
display: block;
aspect-ratio: 1/1;
padding: 20px;
margin: 0;
}
.card-right:deep(img) {
width: 133px;
height: 80px;
display: block;
// padding: 20px;
margin: 0;
padding: 8px;
}
.card-left {
width: 50%;
display: flex;
justify-content: space-between;
align-items: center;
.card-content {
height: 88px;
// background-color: #fafafa;
span {
font-size: 16px;
font-weight: 400;
text-align: left;
color: #000000;
}
}
.stat-number {
font-size: 32px;
font-weight: 600;
font-weight: 700;
text-align: left;
color: #000000;
}
.stat-label {
display: flex;
align-items: center;
font-size: 20px;
font-weight: 400;
text-align: left;
color: #999999;
}
}
.card-right {
display: flex;
flex-direction: column;
align-items: center;
width: 50%;
p {
margin: 0;
font-size: 16px;
font-weight: 400;
text-align: left;
color: #000000;
span {
font-size: 16px;
font-weight: 700;
text-align: left;
color: #25bf82;
}
}
}
.tabs-wrapper {
width: 100%;
display: flex;
align-items: center;
background-color: #fff;
:deep(.el-tabs__item) {
font-size: 24px;
font-weight: 700;
border: 1 solid #f000;
}
}
.flex {
display: flex;
flex-direction: row;
}
.flex-column {
display: flex;
flex-direction: column;
}
.flex-1 {
flex: 1;
}
.flex-space-between {
justify-content: space-between;
}
.product-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px 0;
.product-info {
display: flex;
flex: 1;
.product-img {
width: 110px;
aspect-ratio: 1 / 1;
object-fit: cover;
padding: 8px;
}
.product-text {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.product-name {
font-size: 20px;
font-weight: 700;
text-align: left;
color: #000000;
}
.detail-item {
width: 100%;
font-size: 16px;
display: flex;
justify-content: space-between;
font-weight: 400;
text-align: left;
color: #999999;
span {
color: #000000;
}
}
}
}
.product-action {
width: 200px;
height: 110px;
padding: 8px;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: end;
.status-tag {
text-align: right;
font-size: 20px;
font-weight: 700;
.text-success {
color: #67c23a;
}
.text-warning {
color: #e6a23c;
}
.text-danger {
color: #f56c6c;
}
}
}
}
</style>