2025-05-22 10:38:36 +08:00

391 lines
9.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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">
<el-tag :class="statusClass(activeStatus)" :type="statusTypeMap[product.status]">{{ product.statusLabel }}</el-tag>
<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 {
height: calc(100% - 40px);
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>