feat:溯源首页统计
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 4.8 KiB |
After Width: | Height: | Size: 4.1 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 2.6 KiB |
@ -6,47 +6,53 @@ export default [
|
|||||||
path: '/sub-government-affairs-service/trace',
|
path: '/sub-government-affairs-service/trace',
|
||||||
name: 'trace',
|
name: 'trace',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
redirect: '/sub-government-affairs-service/breeding',
|
redirect: '/sub-government-affairs-service/trace-home',
|
||||||
meta: { title: '溯源管理', icon: 'Document' },
|
meta: { title: '溯源管理', icon: 'Document' },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: '/sub-government-affairs-service/planting',
|
path: '/sub-government-affairs-service/trace-index',
|
||||||
name: 'planting',
|
name: 'trace-index',
|
||||||
|
component: () => import('@/views/trace/statistic/index.vue'),
|
||||||
|
meta: { title: '溯源首页', icon: 'Document' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/sub-government-affairs-service/record',
|
||||||
|
name: 'record',
|
||||||
component: Views,
|
component: Views,
|
||||||
meta: { title: '种植档案', icon: 'Document' },
|
meta: { title: '种养植档案', icon: 'Document' },
|
||||||
redirect: '/sub-government-affairs-service/planting-base',
|
redirect: '/sub-government-affairs-service/record-base',
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: '/sub-government-affairs-service/planting-base',
|
path: '/sub-government-affairs-service/record-base',
|
||||||
component: () => import('@/views/trace/planting/base/index.vue'),
|
component: () => import('@/views/trace/record/base/index.vue'),
|
||||||
name: 'planting-base',
|
name: 'record-base',
|
||||||
meta: { title: '基地档案', icon: 'Document' },
|
meta: { title: '基地档案', icon: 'Document' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/sub-government-affairs-service/planting-seed',
|
path: '/sub-government-affairs-service/record-seed',
|
||||||
component: () => import('@/views/trace/planting/seed/index.vue'),
|
component: () => import('@/views/trace/record/seed/index.vue'),
|
||||||
name: 'planting-seed',
|
name: 'record-seed',
|
||||||
meta: { title: '种子档案', icon: 'Document' },
|
meta: { title: '种源档案', icon: 'Document' },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/sub-government-affairs-service/breeding',
|
path: '/sub-government-affairs-service/agricultural',
|
||||||
name: 'breeding',
|
name: 'agricultural',
|
||||||
component: Views,
|
component: Views,
|
||||||
meta: { title: '农事管理', icon: 'Document' },
|
meta: { title: '农事管理', icon: 'Document' },
|
||||||
redirect: '/sub-government-affairs-service/breeding-coding',
|
redirect: '/sub-government-affairs-service/agricultural-coding',
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: '/sub-government-affairs-service/breeding-coding',
|
path: '/sub-government-affairs-service/agricultural-coding',
|
||||||
component: () => import('@/views/trace/breeding/coding/index.vue'),
|
component: () => import('@/views/trace/agricultural/coding/index.vue'),
|
||||||
name: 'breeding-coding',
|
name: 'agricultural-coding',
|
||||||
meta: { title: '采收与赋码管理', icon: 'Document' },
|
meta: { title: '采收与赋码管理', icon: 'Document' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/sub-government-affairs-service/breeding-quality',
|
path: '/sub-government-affairs-service/agricultural-quality',
|
||||||
component: () => import('@/views/trace/breeding/quality/index.vue'),
|
component: () => import('@/views/trace/agricultural/quality/index.vue'),
|
||||||
name: 'breeding-quality',
|
name: 'agricultural-quality',
|
||||||
meta: { title: '产品质检管理', icon: 'Document' },
|
meta: { title: '产品质检管理', icon: 'Document' },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -0,0 +1,384 @@
|
|||||||
|
<template>
|
||||||
|
<div class="statistic">
|
||||||
|
<el-row :gutter="16" style="margin-bottom: 20px">
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-card shadow="hover">
|
||||||
|
<dl class="statistic-display d1" :style="`background-image: url(${getAssetsFile('images/trace/statistic-card-bg1.png')})`">
|
||||||
|
<dt>
|
||||||
|
<i><img :src="getAssetsFile('images/trace/statistic-card1.png')" /></i>
|
||||||
|
<span>发放溯源码</span>
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
<avue-count-up end="100086"></avue-count-up>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-card shadow="hover">
|
||||||
|
<dl class="statistic-display d2" :style="`background-image: url(${getAssetsFile('images/trace/statistic-card-bg2.png')})`">
|
||||||
|
<dt>
|
||||||
|
<i><img :src="getAssetsFile('images/trace/statistic-card2.png')" /></i>
|
||||||
|
<span>有效期内溯源码</span>
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
<avue-count-up end="37498"></avue-count-up>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-card shadow="hover">
|
||||||
|
<dl class="statistic-display d3" :style="`background-image: url(${getAssetsFile('images/trace/statistic-card-bg3.png')})`">
|
||||||
|
<dt>
|
||||||
|
<i><img :src="getAssetsFile('images/trace/statistic-card3.png')" /></i>
|
||||||
|
<span>追溯主体数</span>
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
<avue-count-up end="38479"></avue-count-up>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-card shadow="hover">
|
||||||
|
<dl class="statistic-display d4" :style="`background-image: url(${getAssetsFile('images/trace/statistic-card-bg4.png')})`">
|
||||||
|
<dt>
|
||||||
|
<i><img :src="getAssetsFile('images/trace/statistic-card4.png')" /></i>
|
||||||
|
<span>产品溯源次数</span>
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
<avue-count-up end="899967"></avue-count-up>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16" style="margin-bottom: 20px">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-card shadow="hover">
|
||||||
|
<custom-echart-bar :chart-data="state.areaData" height="400px" :option="state.areaOption" />
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-card shadow="hover">
|
||||||
|
<custom-echart-bar :chart-data="state.cropData" height="400px" :option="state.cropOption" />
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="18">
|
||||||
|
<el-card shadow="hover">
|
||||||
|
<avue-crud ref="crudRef" :table-loading="state.loading" :data="state.data" :option="state.options" :header-cell-style="headerCellStyle">
|
||||||
|
<template #header>
|
||||||
|
<div class="statistic-table">
|
||||||
|
<b class="statistic-title">检测记录</b>
|
||||||
|
<el-select v-model="state.date" placeholder="请选择" style="width: 240px">
|
||||||
|
<el-option v-for="item in state.dateOption" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</avue-crud>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-card shadow="hover">
|
||||||
|
<b class="statistic-title">溯源主体统计</b>
|
||||||
|
<ul class="statistic-rank">
|
||||||
|
<li v-for="item in state.rankList" :key="item.id">
|
||||||
|
<i><img :src="getAssetsFile(`images/trace/statistic-traceability-${item.icon}.png`)" /></i>
|
||||||
|
<span>
|
||||||
|
<b>{{ item.num }}</b>
|
||||||
|
<em>{{ item.name }}</em>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { reactive } from 'vue';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
import { useApp } from '@/hooks';
|
||||||
|
import { CRUD_VIEW_OPTIONS } from '@/config';
|
||||||
|
import { getAssetsFile, mockData, sleep } from '@/utils';
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
const app = useApp();
|
||||||
|
const headerCellStyle = () => {
|
||||||
|
return {
|
||||||
|
background: 'none',
|
||||||
|
// border: 0,
|
||||||
|
// color: '#999',
|
||||||
|
};
|
||||||
|
};
|
||||||
|
const state = reactive({
|
||||||
|
areaOption: {
|
||||||
|
title: {
|
||||||
|
text: '溯源码发放区域分布',
|
||||||
|
textStyle: {
|
||||||
|
color: '#333',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
name: '区域',
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value',
|
||||||
|
name: '次',
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
formatter: function (params) {
|
||||||
|
return `${params.value}次`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
barStyle: {
|
||||||
|
barWidth: 20,
|
||||||
|
showBackground: true,
|
||||||
|
itemStyle: {
|
||||||
|
borderRadius: 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
areaData: [
|
||||||
|
{ value: 230, name: '耿马镇' },
|
||||||
|
{ value: 165, name: '勐永镇' },
|
||||||
|
{ value: 217, name: '勐撒镇' },
|
||||||
|
{ value: 200, name: '孟定镇' },
|
||||||
|
{ value: 305, name: '大兴乡' },
|
||||||
|
],
|
||||||
|
cropOption: {
|
||||||
|
title: {
|
||||||
|
text: '溯源农产品月度统计',
|
||||||
|
textStyle: {
|
||||||
|
color: '#333',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
name: '月份',
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value',
|
||||||
|
name: '次',
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
formatter: function (params) {
|
||||||
|
return `${params.value}次`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
barStyle: {
|
||||||
|
barWidth: 20,
|
||||||
|
showBackground: true,
|
||||||
|
itemStyle: {
|
||||||
|
borderRadius: 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
cropData: [
|
||||||
|
{ value: 230, name: '1月' },
|
||||||
|
{ value: 165, name: '2月' },
|
||||||
|
{ value: 217, name: '3月' },
|
||||||
|
{ value: 200, name: '4月' },
|
||||||
|
{ value: 305, name: '5月' },
|
||||||
|
],
|
||||||
|
loading: false,
|
||||||
|
date: 'week',
|
||||||
|
dateOption: [
|
||||||
|
{
|
||||||
|
label: '近一周',
|
||||||
|
value: 'week',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '近一月',
|
||||||
|
value: 'month',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '近一年',
|
||||||
|
value: 'year',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
options: {
|
||||||
|
...CRUD_VIEW_OPTIONS,
|
||||||
|
index: false,
|
||||||
|
column: [
|
||||||
|
{
|
||||||
|
label: '送检单位',
|
||||||
|
prop: 'p1',
|
||||||
|
width: 200,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '检测单位',
|
||||||
|
prop: 'p2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '检测结果',
|
||||||
|
prop: 'p3',
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
label: '送检时间',
|
||||||
|
prop: 'p4',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
data: [],
|
||||||
|
rankList: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
// 加载
|
||||||
|
const loadData = async () => {
|
||||||
|
state.loading = true;
|
||||||
|
await sleep(500);
|
||||||
|
state.rankList = [
|
||||||
|
{
|
||||||
|
name: '个人',
|
||||||
|
num: 1000,
|
||||||
|
icon: '1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '合作社',
|
||||||
|
num: 1000,
|
||||||
|
icon: '2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '农业企业',
|
||||||
|
num: 1000,
|
||||||
|
icon: '3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '种植企业',
|
||||||
|
num: 1000,
|
||||||
|
icon: '4',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
state.data = mockData(
|
||||||
|
{
|
||||||
|
p1: '红星农业合作社',
|
||||||
|
p2: '农残检测中心',
|
||||||
|
p3: '合格',
|
||||||
|
p4: '2025-01-01',
|
||||||
|
},
|
||||||
|
10
|
||||||
|
);
|
||||||
|
state.loading = false;
|
||||||
|
// GetEntityList(state.query)
|
||||||
|
// .then((res) => {
|
||||||
|
// if (res.code === 200) {
|
||||||
|
// const { current, size, total, records } = res.data;
|
||||||
|
// state.data = records;
|
||||||
|
// state.pageData = {
|
||||||
|
// currentPage: current || 1,
|
||||||
|
// pageSize: size || 10,
|
||||||
|
// total: total,
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// .catch((err) => {
|
||||||
|
// app.$message.error(err.msg);
|
||||||
|
// state.data = [];
|
||||||
|
// })
|
||||||
|
// .finally(() => {
|
||||||
|
// state.loading = false;
|
||||||
|
// });
|
||||||
|
};
|
||||||
|
|
||||||
|
loadData();
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.statistic {
|
||||||
|
.el-card {
|
||||||
|
border: 0 !important;
|
||||||
|
border-radius: 16px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bolder;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-display {
|
||||||
|
@include flex-column();
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: right bottom;
|
||||||
|
|
||||||
|
dt {
|
||||||
|
@include flex-row();
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
|
||||||
|
i {
|
||||||
|
display: inline-block;
|
||||||
|
width: 72px;
|
||||||
|
height: 72px;
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dd {
|
||||||
|
span {
|
||||||
|
font-size: 22px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.d1 {
|
||||||
|
dt span {
|
||||||
|
color: #ff4975;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.d2 {
|
||||||
|
dt span {
|
||||||
|
color: #41b879;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.d3 {
|
||||||
|
dt span {
|
||||||
|
color: #3685fe;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.d4 {
|
||||||
|
dt span {
|
||||||
|
color: #6b66ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-table {
|
||||||
|
@include flex-row();
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-rank {
|
||||||
|
li {
|
||||||
|
@include flex-row();
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 16px;
|
||||||
|
|
||||||
|
i {
|
||||||
|
width: 72px;
|
||||||
|
height: 72px;
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
@include flex-column();
|
||||||
|
flex: 1;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
em {
|
||||||
|
font-style: normal;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|