Compare commits
2 Commits
ed3ab7ed50
...
a9c4ad5c35
| Author | SHA1 | Date |
|---|---|---|
|
|
a9c4ad5c35 | |
|
|
06d39ed24c |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 285 B |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 342 B |
|
|
@ -1,20 +1,46 @@
|
|||
import { defHttp } from '@/utils/http/axios';
|
||||
|
||||
enum Api {
|
||||
GetTrendData = '/api/DroneScreenDisplay/GetTrendData',
|
||||
GetTuBanSummary = '/api/DroneScreenDisplay/GetTuBanSummary',
|
||||
GetTotalAndAreaByType = '/api/DroneScreenDisplay/GetTotalAndAreaByType',
|
||||
GetTotalAndArea = '/api/DroneScreenDisplay/GetTotalAndArea'
|
||||
GetTotalAndArea = '/api/DroneScreenDisplay/GetTotalAndArea',
|
||||
GetAnalysisData = '/api/DroneScreenDisplay/GetAnalysisData',
|
||||
CaseOffenceEcharts = '/api/DroneScreenDisplay/CaseOffenceEcharts',
|
||||
GetTrendEchartsData = '/api/DroneScreenDisplay/GetTrendEchartsData',
|
||||
}
|
||||
export function GetTrendData(params:{countyid:string;type:string;datatype:number;begindate?:string;enddate?:string;}) {
|
||||
export function GetTrendData(params: {
|
||||
countyid: string;
|
||||
type: string;
|
||||
datatype: number;
|
||||
begindate?: string;
|
||||
enddate?: string;
|
||||
}) {
|
||||
// datatype 0按天统计,1按月统计
|
||||
return defHttp.get({ url: Api.GetTrendData, params });
|
||||
}
|
||||
export function GetTuBanSummary(params:{countyid:string;type:string;}) {
|
||||
export function GetTuBanSummary(params: { countyid: string; type: string }) {
|
||||
return defHttp.get({ url: Api.GetTuBanSummary, params });
|
||||
}
|
||||
export function GetTotalAndAreaByType(params:{countyid:string;type:string;}) {
|
||||
export function GetTotalAndAreaByType(params: { countyid: string; type: string }) {
|
||||
return defHttp.get({ url: Api.GetTotalAndAreaByType, params });
|
||||
}
|
||||
export function GetTotalAndArea(params:{countyid:string;type:string;}) {
|
||||
export function GetTotalAndArea(params: { countyid: string; type: string }) {
|
||||
return defHttp.get({ url: Api.GetTotalAndArea, params });
|
||||
}
|
||||
export function getAnalysisData(params: { countyid: string; month: number }) {
|
||||
return defHttp.get({ url: Api.GetAnalysisData, params });
|
||||
}
|
||||
|
||||
export function caseOffenceEcharts(params: { type: number; month: number }) {
|
||||
return defHttp.get({ url: Api.CaseOffenceEcharts, params });
|
||||
}
|
||||
export function getTrendEchartsData(params: {
|
||||
type: number;
|
||||
month: number;
|
||||
datatype: number;
|
||||
begindate: string;
|
||||
enddate: string;
|
||||
}) {
|
||||
return defHttp.get({ url: Api.GetTrendEchartsData, params });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -138,3 +138,31 @@ export const nowStatusOptions = [
|
|||
{ label: '县级审核', value: '县级审核' },
|
||||
{ label: '已归档', value: '已归档' },
|
||||
];
|
||||
//获取近7个月的时间
|
||||
export const getMonth = () => {
|
||||
//创建现在的时间
|
||||
const data = new Date();
|
||||
//获取年
|
||||
let year = data.getFullYear();
|
||||
//获取月
|
||||
let mon = data.getMonth() + 1;
|
||||
let arry: any = [];
|
||||
for (let i = 0; i < 6; i++) {
|
||||
if (mon <= 0) {
|
||||
year = year - 1;
|
||||
mon = mon + 12;
|
||||
}
|
||||
arry.push({
|
||||
label: `${mon}月`,
|
||||
value: mon,
|
||||
});
|
||||
mon = mon - 1;
|
||||
}
|
||||
return arry.reverse();
|
||||
};
|
||||
export const monthOptions = getMonth();
|
||||
export const monthAllOptions = () => {
|
||||
let arr: any = getMonth();
|
||||
arr.reverse().unshift({ label: '全部', value: 0 });
|
||||
return arr;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,381 @@
|
|||
<template>
|
||||
<div class="brokenline-container">
|
||||
<!-- brokenline 下发图斑趋势 折线图 -->
|
||||
<div class="brokenline-title">
|
||||
<div class="title">{{ props.typeName }}趋势</div>
|
||||
<div class="month">
|
||||
<div class="month-list">
|
||||
<div
|
||||
v-for="item in options"
|
||||
:key="item.value"
|
||||
@click="monthClick(item.value)"
|
||||
:class="item.value == monthVal ? 'active' : ''"
|
||||
>{{ item.name }}</div
|
||||
>
|
||||
</div>
|
||||
<div class="filter-container">
|
||||
<div class="filter-name" @click="handlerChangeFilterOptions">{{ currentFilterName }}</div>
|
||||
<div class="filter-icon" @click="handlerChangeFilterOptions">
|
||||
<img src="/statistical/up.png" alt="" v-if="showFilterOptions" />
|
||||
<img src="/statistical/down.png" alt="" v-else />
|
||||
</div>
|
||||
<div class="filter-item-container" v-if="showFilterOptions">
|
||||
<div
|
||||
v-for="(item, index) in props.countyList"
|
||||
:class="item.id == currentFilter ? 'filter-item active' : 'filter-item'"
|
||||
:key="index"
|
||||
@click="handlerCheckedFilter(item)"
|
||||
>{{ item.name }}</div
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="brokenline-content">
|
||||
<div id="brokenline" style="height: 30vh"> </div>
|
||||
<span class="brokenline-unit">单位:</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import { getTrendEchartsData } from '@/api/statistical/index';
|
||||
|
||||
const options = ref([
|
||||
{
|
||||
name: '天',
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
name: '月',
|
||||
value: 1,
|
||||
},
|
||||
]);
|
||||
const monthVal = ref(0);
|
||||
|
||||
function monthClick(val) {
|
||||
monthVal.value = val;
|
||||
getData();
|
||||
}
|
||||
|
||||
const showFilterOptions = ref(false);
|
||||
const currentFilter = ref();
|
||||
const currentFilterName = ref();
|
||||
|
||||
function handlerChangeFilterOptions() {
|
||||
showFilterOptions.value = !showFilterOptions.value;
|
||||
}
|
||||
|
||||
function handlerCheckedFilter(item) {
|
||||
currentFilter.value = item.id;
|
||||
currentFilterName.value = item.name;
|
||||
showFilterOptions.value = false;
|
||||
getData();
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
typeName: {
|
||||
type: String,
|
||||
default: '下发图斑',
|
||||
},
|
||||
type: {
|
||||
type: Number,
|
||||
default: 1,
|
||||
},
|
||||
countyList: Object,
|
||||
});
|
||||
watch(
|
||||
() => props.countyList,
|
||||
(val) => {
|
||||
currentFilter.value = props.countyList[0].id;
|
||||
currentFilterName.value = props.countyList[0].name;
|
||||
getData();
|
||||
},
|
||||
);
|
||||
watch(
|
||||
() => props.type,
|
||||
(val) => {
|
||||
getData();
|
||||
},
|
||||
);
|
||||
const timeList: any = ref([]);
|
||||
const tbAreaList: any = ref([]);
|
||||
const gdAreaList: any = ref([]);
|
||||
const ntAreaList: any = ref([]);
|
||||
const xfAreaList: any = ref([]);
|
||||
function getData() {
|
||||
timeList.value = [];
|
||||
tbAreaList.value = [];
|
||||
gdAreaList.value = [];
|
||||
ntAreaList.value = [];
|
||||
xfAreaList.value = [];
|
||||
const querys = {
|
||||
type: props.type,
|
||||
countyid: currentFilter.value,
|
||||
datatype: monthVal.value,
|
||||
};
|
||||
getTrendEchartsData(querys).then((res) => {
|
||||
res.forEach((element) => {
|
||||
timeList.value.push(element.time);
|
||||
tbAreaList.value.push(element.tnmj);
|
||||
gdAreaList.value.push(element.gdmj);
|
||||
ntAreaList.value.push(element.yjjbntmj);
|
||||
xfAreaList.value.push(element.tbzs);
|
||||
});
|
||||
chartData();
|
||||
});
|
||||
}
|
||||
|
||||
function chartData() {
|
||||
var chartDom = document.getElementById('brokenline');
|
||||
var myChart = echarts.init(chartDom);
|
||||
var option = {
|
||||
legend: {
|
||||
data: ['基本农田面积', '图斑面积', '耕地面积', '数量'],
|
||||
top: '4%',
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontSize: 14,
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '3%',
|
||||
containLabel: true,
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: timeList.value,
|
||||
axisLabel: {
|
||||
show: true,
|
||||
textStyle: {
|
||||
color: '#fff', //X轴文字颜色
|
||||
fontSize: 12,
|
||||
},
|
||||
interval: 0,
|
||||
// rotate: 30,
|
||||
},
|
||||
},
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
axisLabel: {
|
||||
show: true,
|
||||
textStyle: {
|
||||
color: '#396A87',
|
||||
fontSize: 14,
|
||||
},
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
width: 0.5,
|
||||
color: '#3d5269',
|
||||
type: 'dashed',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'value',
|
||||
name: '',
|
||||
nameTextStyle: {
|
||||
color: '#396A87',
|
||||
fontSize: 14,
|
||||
},
|
||||
position: 'right',
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
axisLine: {
|
||||
show: false,
|
||||
lineStyle: {
|
||||
color: '#396A87',
|
||||
width: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
color: ['#0C725D', '#069EC3', '#3249CD'],
|
||||
series: [
|
||||
{
|
||||
name: '基本农田面积',
|
||||
type: 'line',
|
||||
stack: 'Total',
|
||||
symbol: 'none',
|
||||
areaStyle: {},
|
||||
emphasis: {
|
||||
focus: 'series',
|
||||
},
|
||||
data: ntAreaList.value,
|
||||
},
|
||||
{
|
||||
name: '图斑面积',
|
||||
type: 'line',
|
||||
stack: 'Total',
|
||||
symbol: 'none',
|
||||
areaStyle: {},
|
||||
emphasis: {
|
||||
focus: 'series',
|
||||
},
|
||||
data: tbAreaList.value,
|
||||
},
|
||||
{
|
||||
name: '耕地面积',
|
||||
type: 'line',
|
||||
stack: 'Total',
|
||||
symbol: 'none',
|
||||
areaStyle: {},
|
||||
emphasis: {
|
||||
focus: 'series',
|
||||
},
|
||||
data: gdAreaList.value,
|
||||
},
|
||||
{
|
||||
name: '数量',
|
||||
type: 'line',
|
||||
yAxisIndex: 1, //使用的 y 轴的 index,在单个图表实例中存在多个 y轴的时候有用
|
||||
showAllSymbol: true, //显示所有图形。
|
||||
symbol: 'circle', //标记的图形为实心圆
|
||||
symbolSize: 6, //标记的大小
|
||||
itemStyle: {
|
||||
//折线拐点标志的样式
|
||||
color: '#FF9C5D',
|
||||
borderColor: '#FF9C5D',
|
||||
width: 2,
|
||||
shadowColor: '#FF9C5D',
|
||||
shadowBlur: 2,
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
color: '#fff',
|
||||
},
|
||||
lineStyle: {
|
||||
color: '#FF9C5D',
|
||||
width: 2,
|
||||
shadowBlur: 2,
|
||||
},
|
||||
data: xfAreaList.value,
|
||||
},
|
||||
],
|
||||
};
|
||||
option && myChart.setOption(option);
|
||||
}
|
||||
onMounted(() => {
|
||||
chartData();
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.brokenline-container {
|
||||
z-index: 10;
|
||||
}
|
||||
.brokenline-title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 18px;
|
||||
align-items: center;
|
||||
.title {
|
||||
padding-left: 10px;
|
||||
width: 258px;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
background-image: url('/statistical/right-title-bg.png');
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
.brokenline-content {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
.brokenline-unit {
|
||||
position: absolute;
|
||||
left: 100px;
|
||||
top: 16px;
|
||||
color: #fff;
|
||||
z-index: 10;
|
||||
font-size: 14px;
|
||||
}
|
||||
.month {
|
||||
display: flex;
|
||||
.month-list {
|
||||
display: flex;
|
||||
div {
|
||||
width: 61px;
|
||||
height: 27px;
|
||||
background: #22293d;
|
||||
border-radius: 3px 0px 0px 3px;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
line-height: 27px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.active {
|
||||
background: linear-gradient(-38deg, #3058e1, #4cbbf5);
|
||||
box-shadow: 0px 1px 3px 0px rgba(3, 10, 26, 0.25);
|
||||
}
|
||||
}
|
||||
}
|
||||
.filter-container {
|
||||
z-index: 10;
|
||||
position: relative;
|
||||
width: 104px;
|
||||
border-radius: 6px;
|
||||
height: 29px;
|
||||
background-image: url('/statistical/select-bg.png');
|
||||
line-height: 29px;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-left: 10px;
|
||||
img {
|
||||
width: 10px;
|
||||
}
|
||||
.filter-name {
|
||||
width: 70px;
|
||||
text-align: center;
|
||||
padding: 0px 2px;
|
||||
font-size: 14px;
|
||||
position: relative;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
margin-left: 4px;
|
||||
}
|
||||
.filter-item-container {
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
background: rgba(11, 39, 68, 0.8);
|
||||
border: 1px solid #0a62c6;
|
||||
top: 36px;
|
||||
left: 0px;
|
||||
height: 140px;
|
||||
overflow: auto;
|
||||
.filter-item {
|
||||
height: 36px;
|
||||
text-align: center;
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
background: #054234;
|
||||
}
|
||||
}
|
||||
.filter-item.active {
|
||||
background: #054234;
|
||||
color: #e1ecf8;
|
||||
}
|
||||
.filter-item {
|
||||
background: #086953;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,293 @@
|
|||
<template>
|
||||
<div class="circulation-container">
|
||||
<!-- circulation 下发图斑趋势 折线图 -->
|
||||
<div class="circulation-title">
|
||||
<div class="title">数据分析</div>
|
||||
<div class="month">
|
||||
<div class="month-list">
|
||||
<div
|
||||
v-for="item in monthOptions"
|
||||
:key="item.value"
|
||||
@click="monthClick(item.value)"
|
||||
:class="item.value == monthVal ? 'active' : ''"
|
||||
>{{ item.label }}</div
|
||||
>
|
||||
</div>
|
||||
<div class="filter-container">
|
||||
<div class="filter-name" @click="handlerChangeFilterOptions">{{ currentFilterName }}</div>
|
||||
<div class="filter-icon" @click="handlerChangeFilterOptions">
|
||||
<img src="/statistical/up.png" alt="" v-if="showFilterOptions" />
|
||||
<img src="/statistical/down.png" alt="" v-else />
|
||||
</div>
|
||||
<div class="filter-item-container" v-if="showFilterOptions">
|
||||
<div
|
||||
v-for="(item, index) in props.countyList"
|
||||
:key="index"
|
||||
:class="item.id == currentFilter ? 'filter-item active' : 'filter-item'"
|
||||
@click="handlerCheckedFilter(item)"
|
||||
>{{ item.name }}</div
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="circulation-content">
|
||||
<div class="circulation-left">
|
||||
<div class="circulation-left-left">
|
||||
<div class="circulation-content-title">下发图斑</div>
|
||||
<div class="circulation-content-number">
|
||||
<div>
|
||||
<span>下发图斑(宗数)</span>
|
||||
<span>{{ data.xftb }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span>耕地面积(亩)</span>
|
||||
<span>{{ data.gdmj }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="circulation-content-compare">
|
||||
<div class="compare-title">环比</div>
|
||||
<div>
|
||||
<img src="/statistical/go-up.png" alt="" v-if="data.xftbhb > 0" />
|
||||
<img src="/statistical/decline.png" alt="" v-else />
|
||||
<span> {{ data.xftbhb }}%</span>
|
||||
</div>
|
||||
<div>
|
||||
<img src="/statistical/go-up.png" alt="" v-if="data.gdmjhb > 0" />
|
||||
<img src="/statistical/decline.png" alt="" v-else />
|
||||
<span> {{ data.gdmjhb }}%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="circulation-right">
|
||||
<div class="circulation-left-left">
|
||||
<div class="circulation-content-title">新增违法</div>
|
||||
<div class="circulation-content-number">
|
||||
<div>
|
||||
<span>下发图斑(宗数)</span>
|
||||
<span>{{ data.xzwf }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span>耕地面积(亩)</span>
|
||||
<span>{{ data.xzwfmj }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="circulation-content-compare">
|
||||
<div class="compare-title">环比</div>
|
||||
<div>
|
||||
<img src="/statistical/go-up.png" alt="" v-if="data.wftbhb > 0" />
|
||||
<img src="/statistical/decline.png" alt="" v-else />
|
||||
<span> {{ data.wftbhb }}%</span>
|
||||
</div>
|
||||
<div>
|
||||
<img src="/statistical/go-up.png" alt="" v-if="data.xzwfgdmjhb > 0" />
|
||||
<img src="/statistical/decline.png" alt="" v-else />
|
||||
<span> {{ data.xzwfgdmjhb }}%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
import { monthOptions } from '@/utils/global';
|
||||
import { getAnalysisData } from '@/api/statistical/index';
|
||||
|
||||
const props = defineProps({
|
||||
countyList: Object,
|
||||
});
|
||||
watch(
|
||||
() => props.countyList,
|
||||
(val) => {
|
||||
currentFilter.value = props.countyList[0].id;
|
||||
currentFilterName.value = props.countyList[0].name;
|
||||
getCount();
|
||||
},
|
||||
);
|
||||
|
||||
const monthVal = ref(monthOptions[monthOptions.length - 1].value);
|
||||
const data: any = ref({});
|
||||
function monthClick(val) {
|
||||
monthVal.value = val;
|
||||
getCount();
|
||||
}
|
||||
const showFilterOptions = ref(false);
|
||||
const currentFilter = ref();
|
||||
const currentFilterName = ref();
|
||||
|
||||
function handlerChangeFilterOptions() {
|
||||
showFilterOptions.value = !showFilterOptions.value;
|
||||
}
|
||||
|
||||
function handlerCheckedFilter(item) {
|
||||
currentFilter.value = item.id;
|
||||
currentFilterName.value = item.name;
|
||||
showFilterOptions.value = false;
|
||||
getCount();
|
||||
}
|
||||
function getCount() {
|
||||
const querys = {
|
||||
month: monthVal.value,
|
||||
countyid: currentFilter.value,
|
||||
};
|
||||
getAnalysisData(querys).then((res) => {
|
||||
data.value = res;
|
||||
});
|
||||
}
|
||||
onMounted(() => {});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.circulation-container {
|
||||
z-index: 10;
|
||||
}
|
||||
.circulation-title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 18px;
|
||||
.title {
|
||||
padding-left: 10px;
|
||||
width: 258px;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
background-image: url('/statistical/right-title-bg.png');
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
.month {
|
||||
display: flex;
|
||||
.month-list {
|
||||
display: flex;
|
||||
div {
|
||||
width: 61px;
|
||||
height: 27px;
|
||||
background: #22293d;
|
||||
border-radius: 3px 0px 0px 3px;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
line-height: 27px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.active {
|
||||
background: linear-gradient(-38deg, #3058e1, #4cbbf5);
|
||||
box-shadow: 0px 1px 3px 0px rgba(3, 10, 26, 0.25);
|
||||
}
|
||||
}
|
||||
}
|
||||
.circulation-content {
|
||||
color: #7ebbff;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
.circulation-content-title {
|
||||
width: 28px;
|
||||
height: 106px;
|
||||
padding: 10px 0;
|
||||
background-image: url('/statistical/data-analysis-title-bg.png');
|
||||
background-size: 100% 100%;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.circulation-left-left {
|
||||
display: flex;
|
||||
}
|
||||
.circulation-content-number {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-left: 18px;
|
||||
div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
span:last-child {
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
font-size: 28px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.circulation-content-compare {
|
||||
border: 1px solid rgb(42, 137, 218, 0.39);
|
||||
width: 240px;
|
||||
margin-left: 32px;
|
||||
.compare-title {
|
||||
height: 38px;
|
||||
line-height: 38px;
|
||||
text-align: center;
|
||||
background-image: url('/statistical/huanbi.webp');
|
||||
}
|
||||
div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
span {
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
font-size: 28px;
|
||||
margin: 10px;
|
||||
}
|
||||
img {
|
||||
width: 30px;
|
||||
}
|
||||
}
|
||||
.filter-container {
|
||||
z-index: 10;
|
||||
position: relative;
|
||||
width: 104px;
|
||||
border-radius: 6px;
|
||||
height: 29px;
|
||||
background-image: url('/statistical/select-bg.png');
|
||||
line-height: 29px;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-left: 10px;
|
||||
img {
|
||||
width: 10px;
|
||||
}
|
||||
.filter-name {
|
||||
width: 70px;
|
||||
text-align: center;
|
||||
padding: 0px 2px;
|
||||
font-size: 14px;
|
||||
position: relative;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
margin-left: 4px;
|
||||
}
|
||||
.filter-item-container {
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
background: rgba(11, 39, 68, 0.8);
|
||||
border: 1px solid #0a62c6;
|
||||
top: 36px;
|
||||
left: 0px;
|
||||
height: 140px;
|
||||
overflow: auto;
|
||||
.filter-item {
|
||||
height: 36px;
|
||||
text-align: center;
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
background: #054234;
|
||||
}
|
||||
}
|
||||
.filter-item.active {
|
||||
background: #054234;
|
||||
color: #e1ecf8;
|
||||
}
|
||||
.filter-item {
|
||||
background: #086953;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,380 @@
|
|||
<template>
|
||||
<div class="columnar-container">
|
||||
<!-- columnar 下发图斑 柱状图 -->
|
||||
<div class="columnar-title">
|
||||
<div class="title">{{ props.typeName }}</div>
|
||||
<div class="month">
|
||||
<div class="filter-container">
|
||||
<div class="filter-name" @click="handlerChangeFilterOptions">{{ currentFilterName }}</div>
|
||||
<div class="filter-icon" @click="handlerChangeFilterOptions">
|
||||
<img src="/statistical/up.png" alt="" v-if="showFilterOptions" />
|
||||
<img src="/statistical/down.png" alt="" v-else />
|
||||
</div>
|
||||
<div class="filter-item-container" v-if="showFilterOptions">
|
||||
<div
|
||||
v-for="(item, index) in filters"
|
||||
:key="index"
|
||||
:class="item.value === currentFilter ? 'filter-item active' : 'filter-item'"
|
||||
@click="handlerCheckedFilter(item)"
|
||||
>{{ item.label }}</div
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="columnar-content">
|
||||
<div id="columnar" style="height: 30vh"> </div>
|
||||
<span class="columnar-unit">单位:</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import { monthAllOptions } from '@/utils/global';
|
||||
import { caseOffenceEcharts } from '@/api/statistical/index';
|
||||
|
||||
const filters = monthAllOptions();
|
||||
const showFilterOptions = ref(false);
|
||||
const currentFilter = ref(0);
|
||||
const currentFilterName = ref('全部');
|
||||
|
||||
function handlerChangeFilterOptions() {
|
||||
showFilterOptions.value = !showFilterOptions.value;
|
||||
}
|
||||
|
||||
function handlerCheckedFilter(item) {
|
||||
currentFilter.value = item.value;
|
||||
currentFilterName.value = item.label;
|
||||
showFilterOptions.value = false;
|
||||
getData();
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
typeName: {
|
||||
type: String,
|
||||
default: '下发图斑',
|
||||
},
|
||||
type: {
|
||||
type: Number,
|
||||
default: 1,
|
||||
},
|
||||
});
|
||||
watch(
|
||||
() => props.type,
|
||||
(val) => {
|
||||
getData();
|
||||
},
|
||||
);
|
||||
const countyList: any = ref([]);
|
||||
const tbAreaList: any = ref([]);
|
||||
const gdAreaList: any = ref([]);
|
||||
const ntAreaList: any = ref([]);
|
||||
const xfAreaList: any = ref([]);
|
||||
function getData() {
|
||||
countyList.value = [];
|
||||
tbAreaList.value = [];
|
||||
gdAreaList.value = [];
|
||||
ntAreaList.value = [];
|
||||
xfAreaList.value = [];
|
||||
const querys = {
|
||||
type: props.type,
|
||||
month: currentFilter.value,
|
||||
};
|
||||
caseOffenceEcharts(querys).then((res) => {
|
||||
res.forEach((element) => {
|
||||
countyList.value.push(element.countyname);
|
||||
tbAreaList.value.push(element.tbmj);
|
||||
gdAreaList.value.push(element.gdmj);
|
||||
ntAreaList.value.push(element.yjjbntmj);
|
||||
xfAreaList.value.push(element.tbzs);
|
||||
});
|
||||
chartData();
|
||||
});
|
||||
}
|
||||
function chartData() {
|
||||
var chartDom = document.getElementById('columnar');
|
||||
var myChart = echarts.init(chartDom);
|
||||
var option = {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
label: {
|
||||
show: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
left: '4%',
|
||||
top: '18%',
|
||||
right: '5%',
|
||||
bottom: '22%',
|
||||
},
|
||||
legend: {
|
||||
data: ['图斑面积', '耕地面积', '永久基本农田面积', '下发个数'],
|
||||
top: '4%',
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontSize: 14,
|
||||
},
|
||||
},
|
||||
xAxis: {
|
||||
data: countyList.value,
|
||||
axisLine: {
|
||||
show: true, //隐藏X轴轴线
|
||||
lineStyle: {
|
||||
color: '#3d5269',
|
||||
width: 1,
|
||||
},
|
||||
},
|
||||
axisTick: {
|
||||
show: true, //隐藏X轴刻度
|
||||
alignWithLabel: true,
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
textStyle: {
|
||||
color: '#fff', //X轴文字颜色
|
||||
fontSize: 12,
|
||||
},
|
||||
interval: 0,
|
||||
// rotate: 30,
|
||||
},
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
name: '',
|
||||
nameTextStyle: {
|
||||
color: '#396A87',
|
||||
fontSize: 14,
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
width: 0.5,
|
||||
color: '#3d5269',
|
||||
type: 'dashed',
|
||||
},
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
axisLine: {
|
||||
show: false,
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
textStyle: {
|
||||
color: '#396A87',
|
||||
fontSize: 14,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'value',
|
||||
name: '',
|
||||
nameTextStyle: {
|
||||
color: '#396A87',
|
||||
fontSize: 14,
|
||||
},
|
||||
position: 'right',
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
axisLine: {
|
||||
show: false,
|
||||
lineStyle: {
|
||||
color: '#396A87',
|
||||
width: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '图斑面积',
|
||||
type: 'bar',
|
||||
barWidth: 18,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{
|
||||
offset: 0,
|
||||
color: '#E5410E',
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: '#172830',
|
||||
},
|
||||
]),
|
||||
},
|
||||
},
|
||||
data: tbAreaList.value,
|
||||
},
|
||||
{
|
||||
name: '耕地面积',
|
||||
type: 'bar',
|
||||
barWidth: 18,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{
|
||||
offset: 0,
|
||||
color: '#E5A10E',
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: '#172830',
|
||||
},
|
||||
]),
|
||||
},
|
||||
},
|
||||
data: gdAreaList.value,
|
||||
},
|
||||
{
|
||||
name: '永久基本农田面积',
|
||||
type: 'bar',
|
||||
barWidth: 18,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{
|
||||
offset: 0,
|
||||
color: '#00D532',
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: '#172830',
|
||||
},
|
||||
]),
|
||||
},
|
||||
},
|
||||
data: ntAreaList.value,
|
||||
},
|
||||
{
|
||||
name: '下发个数',
|
||||
type: 'line',
|
||||
yAxisIndex: 1, //使用的 y 轴的 index,在单个图表实例中存在多个 y轴的时候有用
|
||||
showAllSymbol: true, //显示所有图形。
|
||||
symbol: 'circle', //标记的图形为实心圆
|
||||
symbolSize: 6, //标记的大小
|
||||
itemStyle: {
|
||||
//折线拐点标志的样式
|
||||
color: '#FF9C5D',
|
||||
borderColor: '#FF9C5D',
|
||||
width: 2,
|
||||
shadowColor: '#FF9C5D',
|
||||
shadowBlur: 2,
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
color: '#fff',
|
||||
position: 'top',
|
||||
},
|
||||
lineStyle: {
|
||||
color: '#FF9C5D',
|
||||
width: 2,
|
||||
shadowBlur: 2,
|
||||
},
|
||||
data: xfAreaList.value,
|
||||
},
|
||||
],
|
||||
};
|
||||
option && myChart.setOption(option);
|
||||
}
|
||||
onMounted(() => {
|
||||
getData();
|
||||
// chartData();
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.columnar-container {
|
||||
z-index: 10;
|
||||
}
|
||||
.columnar-title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 18px;
|
||||
align-items: center;
|
||||
.title {
|
||||
padding-left: 10px;
|
||||
width: 258px;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
background-image: url('/statistical/right-title-bg.png');
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
.columnar-content {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
.columnar-unit {
|
||||
position: absolute;
|
||||
left: 100px;
|
||||
top: 16px;
|
||||
color: #fff;
|
||||
z-index: 10;
|
||||
font-size: 14px;
|
||||
}
|
||||
.filter-container {
|
||||
z-index: 10;
|
||||
position: relative;
|
||||
width: 104px;
|
||||
border-radius: 6px;
|
||||
height: 29px;
|
||||
background-image: url('/statistical/select-bg.png');
|
||||
line-height: 29px;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-left: 10px;
|
||||
img {
|
||||
width: 10px;
|
||||
}
|
||||
.filter-name {
|
||||
width: 70px;
|
||||
text-align: center;
|
||||
padding: 0px 2px;
|
||||
font-size: 14px;
|
||||
position: relative;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
margin-left: 4px;
|
||||
}
|
||||
.filter-item-container {
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
background: rgba(11, 39, 68, 0.8);
|
||||
border: 1px solid #0a62c6;
|
||||
top: 36px;
|
||||
left: 0px;
|
||||
height: 140px;
|
||||
overflow: auto;
|
||||
.filter-item {
|
||||
height: 36px;
|
||||
text-align: center;
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
background: #054234;
|
||||
}
|
||||
}
|
||||
.filter-item.active {
|
||||
background: #054234;
|
||||
color: #e1ecf8;
|
||||
}
|
||||
.filter-item {
|
||||
background: #086953;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
<template>
|
||||
<div style="background: rgba(0, 0, 0, 0.8)">
|
||||
<a-segmented
|
||||
v-model:value="type"
|
||||
:options="data"
|
||||
style="
|
||||
width: 100%;
|
||||
height: 37px;
|
||||
border-radius: 19px;
|
||||
background: #102649;
|
||||
margin-bottom: 23px;
|
||||
border-top: 1px solid #4bb8f4;
|
||||
border-top: 1px solid #4bb8f4;
|
||||
border-left: 1px solid #4bb8f4;
|
||||
"
|
||||
@change="changeType"
|
||||
/>
|
||||
<!-- columnar 下发图斑 柱状图 -->
|
||||
<Columnar :type="type" :typeName="typeName" />
|
||||
<!-- brokenline 下发图斑趋势 折线图 -->
|
||||
<Brokenline :type="type" :typeName="typeName" :countyList="list" />
|
||||
<!-- circulation 数据分析 环比 -->
|
||||
<Circulation :countyList="list" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { Columnar, Brokenline, Circulation } from './page';
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { getUserOrgs } from '@/api/tiankongdi';
|
||||
import { getChildrenTree } from '@/api/demo/system';
|
||||
|
||||
const type: any = ref(1);
|
||||
const typeName: any = ref('下发图斑');
|
||||
const data = ref([
|
||||
{
|
||||
label: '下发图斑',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '核实后新增违法',
|
||||
value: 2,
|
||||
},
|
||||
{
|
||||
label: '整改后剩余违法',
|
||||
value: 3,
|
||||
},
|
||||
]);
|
||||
function changeType(val) {
|
||||
console.log(val);
|
||||
type.value = val;
|
||||
typeName.value = data.value.find((item) => item.value == val)?.label;
|
||||
}
|
||||
// 初始数据
|
||||
const list = ref();
|
||||
async function getOptions() {
|
||||
const data = await getChildrenTree({
|
||||
parentId: 371300,
|
||||
});
|
||||
data.forEach((item) => {
|
||||
item.isClick = false;
|
||||
});
|
||||
list.value = data;
|
||||
let linyishi = {
|
||||
id: '',
|
||||
name: '临沂市',
|
||||
};
|
||||
list.value.unshift(linyishi);
|
||||
}
|
||||
// 获取用户可以访问的机构信息
|
||||
async function handlerGetOrgs() {
|
||||
let orgs = await getUserOrgs({});
|
||||
let isLevel = orgs.find((item, index) => {
|
||||
return item.name == '临沂市' || item.parentId == 0 || item.parentName == '根节点';
|
||||
});
|
||||
if (isLevel) {
|
||||
// 市级
|
||||
getOptions();
|
||||
} else {
|
||||
// 县区级
|
||||
let levesl = orgs.filter((item, index) => {
|
||||
return item.parentName == '临沂市' || item.parentId == 371300;
|
||||
});
|
||||
list.value = levesl;
|
||||
}
|
||||
}
|
||||
onMounted(async () => {
|
||||
await handlerGetOrgs();
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
:deep(.ant-segmented-thumb) {
|
||||
background: linear-gradient(-38deg, #3058e1, #4cbbf5);
|
||||
border-radius: 19px;
|
||||
}
|
||||
:deep(.ant-segmented-item) {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 19px;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: 400;
|
||||
font-size: 15px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
:deep(.ant-segmented-group) {
|
||||
height: 100%;
|
||||
}
|
||||
:deep(.ant-segmented-item-selected) {
|
||||
background: linear-gradient(-38deg, #3058e1, #4cbbf5);
|
||||
box-shadow: 0px 1px 3px 0px rgba(3, 10, 26, 0.25);
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: 400;
|
||||
font-size: 15px;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
export { default as Columnar } from './columnar/index.vue';
|
||||
export { default as Brokenline } from './brokenline/index.vue';
|
||||
export { default as Circulation } from './circulation/index.vue';
|
||||