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">
|
2025-06-12 16:54:13 +08:00
|
|
|
|
<div class="stat-number">{{ statisticsData.advent }} <span>件</span></div>
|
2025-05-21 13:44:54 +08:00
|
|
|
|
<div class="stat-label">授权产品</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2025-06-12 16:54:13 +08:00
|
|
|
|
<div v-if="statisticsData.adventNum >= 0" class="card-right">
|
2025-05-21 13:44:54 +08:00
|
|
|
|
<img :src="getAssetsFile('images/brand/cardLeft.png')" alt="" />
|
2025-06-12 16:54:13 +08:00
|
|
|
|
<p>
|
|
|
|
|
较上月上涨 <span>{{ statisticsData.adventNum }}</span> 件
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
<div v-else class="card-right">
|
|
|
|
|
<img :src="getAssetsFile('images/brand/cardRight.png')" alt="" />
|
|
|
|
|
<p>
|
|
|
|
|
较上月下降 <span>{{ -statisticsData.adventNum }}</span> 件
|
|
|
|
|
</p>
|
2025-05-21 13:44:54 +08:00
|
|
|
|
</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">
|
2025-06-12 16:54:13 +08:00
|
|
|
|
<div class="stat-number">{{ statisticsData.total }} <span>件</span></div>
|
2025-06-09 10:59:28 +08:00
|
|
|
|
<div class="stat-label">临期产品</div>
|
2025-05-21 13:44:54 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2025-06-12 16:54:13 +08:00
|
|
|
|
<div v-if="statisticsData.totalNum >= 0" class="card-right">
|
|
|
|
|
<img :src="getAssetsFile('images/brand/cardLeft.png')" alt="" />
|
|
|
|
|
<p>
|
|
|
|
|
较上月上涨 <span>{{ statisticsData.totalNum }}</span> 件
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
<div v-else class="card-right">
|
2025-05-21 13:44:54 +08:00
|
|
|
|
<img :src="getAssetsFile('images/brand/cardRight.png')" alt="" />
|
2025-06-12 16:54:13 +08:00
|
|
|
|
<p>
|
|
|
|
|
较上月下降 <span>{{ -statisticsData.totalNum }}</span> 件
|
|
|
|
|
</p>
|
2025-05-21 13:44:54 +08:00
|
|
|
|
</div>
|
|
|
|
|
</el-card>
|
|
|
|
|
</el-col>
|
|
|
|
|
</el-row>
|
|
|
|
|
|
|
|
|
|
<!-- 产品列表 -->
|
|
|
|
|
<el-card shadow="hover" style="border-radius: 16px" class="product-card">
|
|
|
|
|
<!-- 状态筛选 -->
|
2025-06-06 15:19:52 +08:00
|
|
|
|
<el-tabs v-model="activeStatus" class="tabs-wrapper" @tab-change="changeStatus">
|
2025-06-11 14:38:40 +08:00
|
|
|
|
<el-tab-pane label="已授权" name="2" />
|
|
|
|
|
<el-tab-pane label="审批中" name="1" />
|
2025-06-06 15:19:52 +08:00
|
|
|
|
<el-tab-pane label="被驳回" name="3" />
|
|
|
|
|
<el-tab-pane label="已失效" name="4" />
|
2025-05-21 13:44:54 +08:00
|
|
|
|
</el-tabs>
|
|
|
|
|
<div class="product-list">
|
2025-06-06 15:19:52 +08:00
|
|
|
|
<div v-for="(product, index) in products" :key="product.id" class="product-item" :class="{ 'border-top': index > 0 }">
|
2025-05-21 13:44:54 +08:00
|
|
|
|
<div class="product-info">
|
2025-06-13 14:26:02 +08:00
|
|
|
|
<img class="product-img" :src="product.goodsUrl ? product.goodsUrl.split(',')[0] : ''" alt="product" />
|
2025-05-21 13:44:54 +08:00
|
|
|
|
<div class="product-text">
|
2025-06-06 15:19:52 +08:00
|
|
|
|
<span class="product-name">{{ product.productName }}</span>
|
2025-05-21 13:44:54 +08:00
|
|
|
|
<div class="detail-item">
|
|
|
|
|
<label>检测批次:</label>
|
2025-06-06 15:19:52 +08:00
|
|
|
|
<span>2</span>
|
2025-05-21 13:44:54 +08:00
|
|
|
|
</div>
|
|
|
|
|
<div class="detail-item">
|
|
|
|
|
<label>授权期限:</label>
|
2025-06-06 15:19:52 +08:00
|
|
|
|
<span
|
|
|
|
|
>{{ product.timeNum
|
|
|
|
|
}}{{ product.timeNumUnit === 1 ? '天' : product.timeNumUnit === 2 ? '月' : product.timeNumUnit === 3 ? '年' : '' }}</span
|
|
|
|
|
>
|
2025-05-21 13:44:54 +08:00
|
|
|
|
</div>
|
|
|
|
|
<div class="detail-item">
|
|
|
|
|
<label>到期时间:</label>
|
2025-06-06 15:19:52 +08:00
|
|
|
|
<span class="text-expire">{{ product.endTime }}</span>
|
2025-05-21 13:44:54 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="product-action">
|
2025-06-11 14:38:40 +08:00
|
|
|
|
<el-tag v-if="product.status == 2" size="large" class="text-success status-tag" type="success">已授权</el-tag>
|
|
|
|
|
<el-tag v-if="product.status == 1" size="large" class="text-warning status-tag" type="warning">审批中</el-tag>
|
2025-06-06 15:19:52 +08:00
|
|
|
|
<el-tag v-if="product.status == 3" size="large" class="text-danger status-tag" type="danger">被驳回</el-tag>
|
|
|
|
|
<el-tag v-if="product.status == 4" size="large" class="text-info status-tag" type="info">已失效</el-tag>
|
2025-06-10 18:19:58 +08:00
|
|
|
|
<div style="display: flex">
|
|
|
|
|
<el-button
|
2025-06-11 14:38:40 +08:00
|
|
|
|
v-if="product.status == 2"
|
2025-06-10 18:19:58 +08:00
|
|
|
|
type="primary"
|
|
|
|
|
plain
|
|
|
|
|
:icon="Edit"
|
|
|
|
|
size="large"
|
|
|
|
|
style="border-radius: 8px"
|
|
|
|
|
@click="handleCertificate(product)"
|
|
|
|
|
>
|
|
|
|
|
授权证书
|
|
|
|
|
</el-button>
|
2025-06-13 14:26:02 +08:00
|
|
|
|
<!-- <el-button size="large" class="button" @click="onInspect(product)">溯源报告</el-button>-->
|
|
|
|
|
<!-- <el-button v-if="product.status == 2" size="large" class="button" type="danger" @click="onRevoke(product)">取消授权</el-button>-->
|
2025-06-10 18:19:58 +08:00
|
|
|
|
</div>
|
2025-05-21 13:44:54 +08:00
|
|
|
|
</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>
|
2025-06-10 18:19:58 +08:00
|
|
|
|
<!-- 抽查弹窗 -->
|
|
|
|
|
<el-dialog v-model="dialogVisible" width="720px" top="20px" modal="false" :before-close="() => (dialogVisible = false)" title="追溯记录">
|
|
|
|
|
<div v-if="traceData" class="trace-record">
|
|
|
|
|
<!-- 基本信息 -->
|
|
|
|
|
<section class="section">
|
|
|
|
|
<h3>基本信息</h3>
|
|
|
|
|
<el-row :gutter="12">
|
|
|
|
|
<el-col :span="6">产品名称:</el-col><el-col :span="18">{{ traceData.productName }}</el-col> <el-col :span="6">产品数量:</el-col
|
|
|
|
|
><el-col :span="18">{{ traceData.quantity }}</el-col> <el-col :span="6">生产经营主体:</el-col
|
|
|
|
|
><el-col :span="18">{{ traceData.producer }}</el-col> <el-col :span="6">原产地:</el-col
|
|
|
|
|
><el-col :span="18">{{ traceData.origin }}</el-col> <el-col :span="6">生产日期:</el-col
|
|
|
|
|
><el-col :span="18">{{ traceData.productionDate }}</el-col> <el-col :span="6">追溯码:</el-col
|
|
|
|
|
><el-col :span="18">{{ traceData.traceCode }}</el-col> <el-col :span="6">追溯次数:</el-col
|
|
|
|
|
><el-col :span="18">{{ traceData.traceCount }} 次</el-col>
|
|
|
|
|
</el-row>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<!-- 基地信息 -->
|
|
|
|
|
<section class="section">
|
|
|
|
|
<h3>基地信息</h3>
|
|
|
|
|
<el-row :gutter="12">
|
|
|
|
|
<el-col :span="6">基地地址:</el-col><el-col :span="18">{{ traceData.base.address }}</el-col> <el-col :span="6">地理位置:</el-col
|
|
|
|
|
><el-col :span="18">{{ traceData.base.location }}</el-col> <el-col :span="6">面积:</el-col
|
|
|
|
|
><el-col :span="18">{{ traceData.base.area }} 亩</el-col> <el-col :span="6">气候条件:</el-col
|
|
|
|
|
><el-col :span="18">{{ traceData.base.climate }}</el-col> <el-col :span="6">土壤类型:</el-col
|
|
|
|
|
><el-col :span="18">{{ traceData.base.soil }}</el-col>
|
|
|
|
|
</el-row>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<!-- 农事信息 -->
|
|
|
|
|
<section class="section">
|
|
|
|
|
<h3>农事信息</h3>
|
|
|
|
|
<el-table :data="traceData.farmingRecords" stripe border style="width: 100%">
|
|
|
|
|
<el-table-column prop="date" label="日期" width="120" />
|
|
|
|
|
<el-table-column prop="operation" label="操作" />
|
|
|
|
|
<el-table-column prop="operator" label="作业人" width="120" />
|
|
|
|
|
</el-table>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<!-- 包装信息 -->
|
|
|
|
|
<section class="section">
|
|
|
|
|
<h3>分拣包装</h3>
|
|
|
|
|
<el-row :gutter="12">
|
|
|
|
|
<el-col :span="6">包装企业:</el-col><el-col :span="18">{{ traceData.packaging.company }}</el-col> <el-col :span="6">包装类型:</el-col
|
|
|
|
|
><el-col :span="18">{{ traceData.packaging.type }}</el-col> <el-col :span="6">包装人:</el-col
|
|
|
|
|
><el-col :span="18">{{ traceData.packaging.person }}</el-col> <el-col :span="6">包装时间:</el-col
|
|
|
|
|
><el-col :span="18">{{ traceData.packaging.time }}</el-col>
|
|
|
|
|
</el-row>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<!-- 仓储物流 -->
|
|
|
|
|
<section class="section">
|
|
|
|
|
<h3>仓储物流信息</h3>
|
|
|
|
|
<el-row :gutter="12">
|
|
|
|
|
<el-col :span="6">存储类型:</el-col><el-col :span="18">{{ traceData.logistics.storageType }}</el-col>
|
|
|
|
|
<el-col :span="6">存储温度:</el-col><el-col :span="18">{{ traceData.logistics.temperature }}</el-col>
|
|
|
|
|
<el-col :span="6">发货地址:</el-col><el-col :span="18">{{ traceData.logistics.shipFrom }}</el-col> <el-col :span="6">收货地址:</el-col
|
|
|
|
|
><el-col :span="18">{{ traceData.logistics.shipTo }}</el-col>
|
|
|
|
|
</el-row>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<!-- 交易信息 -->
|
|
|
|
|
<section class="section">
|
|
|
|
|
<h3>交易信息</h3>
|
|
|
|
|
<el-row :gutter="12">
|
|
|
|
|
<el-col :span="6">交易时间:</el-col><el-col :span="18">{{ traceData.trade.time }}</el-col> <el-col :span="6">买家:</el-col
|
|
|
|
|
><el-col :span="18">{{ traceData.trade.buyer }}</el-col>
|
|
|
|
|
</el-row>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<!-- 右侧图片 -->
|
|
|
|
|
<div class="trace-img">
|
2025-06-11 14:38:40 +08:00
|
|
|
|
<img :src="traceData.img" alt="产品图" width="150" />
|
2025-06-10 18:19:58 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</el-dialog>
|
2025-05-21 13:44:54 +08:00
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup>
|
2025-06-06 15:19:52 +08:00
|
|
|
|
import { ref, computed, onMounted } from 'vue';
|
2025-05-21 13:44:54 +08:00
|
|
|
|
import { getAssetsFile } from '@/utils/index.js';
|
2025-06-06 15:19:52 +08:00
|
|
|
|
import { authList, getProducts } from '@/apis/brand';
|
2025-05-21 13:44:54 +08:00
|
|
|
|
import { Edit } from '@element-plus/icons-vue';
|
2025-06-12 16:54:13 +08:00
|
|
|
|
import { getStatisticsData } from '@/apis/brand.js';
|
|
|
|
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
|
|
|
|
import { cancelAuth } from '@/apis/brand.js';
|
2025-05-21 13:44:54 +08:00
|
|
|
|
|
2025-06-10 18:19:58 +08:00
|
|
|
|
const dialogVisible = ref(false);
|
|
|
|
|
const traceData = ref(null);
|
|
|
|
|
|
2025-06-11 15:08:27 +08:00
|
|
|
|
const activeStatus = ref('2');
|
2025-05-21 13:44:54 +08:00
|
|
|
|
|
|
|
|
|
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'),
|
|
|
|
|
},
|
|
|
|
|
]);
|
|
|
|
|
|
2025-06-12 16:54:13 +08:00
|
|
|
|
const statisticsData = ref({
|
|
|
|
|
advent: 817,
|
|
|
|
|
adventNum: 13,
|
|
|
|
|
total: 125,
|
|
|
|
|
totalNum: -5,
|
|
|
|
|
});
|
|
|
|
|
|
2025-06-10 18:19:58 +08:00
|
|
|
|
const onRevoke = (p) => {
|
2025-06-12 16:54:13 +08:00
|
|
|
|
ElMessageBox.confirm('是否确认取消该商品的授权?', '注意!', {
|
|
|
|
|
confirmButtonText: '确认',
|
|
|
|
|
cancelButtonText: '放弃',
|
|
|
|
|
type: 'error',
|
|
|
|
|
})
|
|
|
|
|
.then(() => {
|
|
|
|
|
cancelAuth({ id: p.id }).then((res) => {
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
ElMessage({
|
|
|
|
|
type: 'success',
|
|
|
|
|
message: '已取消授权',
|
|
|
|
|
});
|
|
|
|
|
getAuthList(2);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
})
|
|
|
|
|
.catch(() => {
|
|
|
|
|
// ElMessage({
|
|
|
|
|
// type: 'info',
|
|
|
|
|
// message: 'Delete canceled',
|
|
|
|
|
// });
|
|
|
|
|
});
|
2025-06-10 18:19:58 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function onInspect(item) {
|
|
|
|
|
// 这里用硬编码模拟请求,实际中可换成接口调用:getTraceById(id).then(res=> traceData.value = res)
|
|
|
|
|
const mocks = [
|
|
|
|
|
{
|
|
|
|
|
productName: '耿马镇沙疆西红柿',
|
|
|
|
|
quantity: '300KG',
|
|
|
|
|
producer: '北大荒技术有限公司',
|
|
|
|
|
origin: '耿马县孟定镇下坝村',
|
|
|
|
|
productionDate: '2025-6-3',
|
|
|
|
|
traceCode: '10.5487542154785XSE254.1040201',
|
|
|
|
|
traceCount: 30,
|
|
|
|
|
base: {
|
|
|
|
|
address: '耿马县孟定镇下坝村',
|
|
|
|
|
location: '东经102° · 北纬24°',
|
|
|
|
|
area: 9000,
|
|
|
|
|
climate: '亚热带高原季风型,温和多雨',
|
|
|
|
|
soil: '红壤',
|
|
|
|
|
},
|
|
|
|
|
farmingRecords: [
|
|
|
|
|
{ date: '2025/3/14', operation: '播种西红柿种', operator: '李强' },
|
|
|
|
|
{ date: '2025/4/2', operation: '施肥 氮肥', operator: '李强' },
|
|
|
|
|
{ date: '2025/5/17', operation: '浇水', operator: '李强' },
|
|
|
|
|
{ date: '2025/6/14', operation: '采摘', operator: '李强' },
|
|
|
|
|
],
|
|
|
|
|
packaging: {
|
|
|
|
|
company: '瑞禾农产品包装公司',
|
|
|
|
|
type: '纸箱',
|
|
|
|
|
person: '李明瑞',
|
|
|
|
|
time: '2025-1-20 16:27:41',
|
|
|
|
|
},
|
|
|
|
|
logistics: {
|
|
|
|
|
storageType: '冷藏',
|
|
|
|
|
temperature: '2°C',
|
|
|
|
|
shipFrom: '北京市朝阳区解放路24号',
|
|
|
|
|
shipTo: '上海市黄浦区南京路36号',
|
|
|
|
|
},
|
|
|
|
|
trade: {
|
|
|
|
|
time: '2025-4-2 08:13:52',
|
|
|
|
|
buyer: '李楠',
|
|
|
|
|
},
|
|
|
|
|
img: 'images/brand/product4.png',
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
traceData.value = mocks[0];
|
|
|
|
|
traceData.value.img = item.goodsUrl;
|
|
|
|
|
traceData.value.productName = item.productName;
|
|
|
|
|
console.log(item);
|
|
|
|
|
dialogVisible.value = true;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-06 15:19:52 +08:00
|
|
|
|
// const filteredProducts = computed(() => products.value.filter((p) => p.status === activeStatus.value));
|
2025-05-21 13:44:54 +08:00
|
|
|
|
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;
|
|
|
|
|
};
|
2025-06-06 15:19:52 +08:00
|
|
|
|
|
|
|
|
|
const changeStatus = (tab) => {
|
|
|
|
|
getAuthList(tab);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getAuthList = (status) => {
|
|
|
|
|
products.value = [];
|
|
|
|
|
authList({ status: status }).then((res) => {
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
products.value = res.data.records;
|
|
|
|
|
for (let i in products.value) {
|
|
|
|
|
if (products.value[i].endTime) {
|
|
|
|
|
products.value[i].endTime = products.value[i].endTime.split(' ')[0];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2025-06-12 16:54:13 +08:00
|
|
|
|
const getStatusData = () => {
|
|
|
|
|
getStatisticsData().then((res) => {
|
|
|
|
|
console.log(res);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2025-06-06 15:19:52 +08:00
|
|
|
|
onMounted(() => {
|
2025-06-11 14:38:40 +08:00
|
|
|
|
getAuthList(2);
|
2025-06-12 16:54:13 +08:00
|
|
|
|
getStatusData();
|
2025-06-06 15:19:52 +08:00
|
|
|
|
});
|
2025-05-21 13:44:54 +08:00
|
|
|
|
</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;
|
2025-06-10 18:19:58 +08:00
|
|
|
|
border: 0;
|
2025-05-21 13:44:54 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
.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%;
|
|
|
|
|
display: flex;
|
2025-06-06 15:19:52 +08:00
|
|
|
|
gap: 10px;
|
|
|
|
|
font-size: 16px;
|
2025-05-21 13:44:54 +08:00
|
|
|
|
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>
|