数字督察一体化平台-前端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

708 lines
24 KiB

<template>
<el-scrollbar height="100vh">
<div class="wrapper">
<datav-header/>
<el-row>
<el-col :span="6"></el-col>
<el-col :span="12">
<div class="datav-col">
<span style="font-size: 22px">执法监督灵敏感知体系</span>
</div>
<div class="datav-col">
<datav-date-picker v-model="time"/>
</div>
<div class="flex gap-42">
<datav-statistic
:value="statisticsTotal.aTotal"
title="接处警"
isDecimal
style="width: 20%"
/>
<datav-statistic
:value="statisticsTotal.caseTotal"
title="执法办案"
isDecimal
style="width: 20%"
/>
<datav-statistic
:value="statisticsTotal.negativeTotal"
isDecimal
title="总问题数"
style="width: 20%"
/>
<datav-statistic
:value="statisticsTotal.peopleCount"
isDecimal
title="涉及人数"
style="width: 20%"
/>
<datav-statistic
:value="statisticsTotal.avgPeople"
title="人均问题数"
isDecimal="true"
style="width: 20%"
/>
</div>
</el-col>
<el-col :span="6"></el-col>
</el-row>
<el-row style="margin-top: 20px" :gutter="16">
<el-col :span="8">
<datav-card>
<div class="card-header">
<span class="card-title">分县市局</span>
<div class="select-container">
<el-select v-model="selectedMetric" placeholder="请选择指标">
<el-option label="问题数" value="problemNumber"></el-option>
<el-option label="涉及人数" value="personNumber"></el-option>
<el-option label="人均问题数" value="avgProblemNumber"></el-option>
</el-select>
</div>
</div>
<datav-tabs
type="bottom-button"
ref="rxsjTabs"
v-model="selectedFxsjTabs"
>
<datav-tab-item label="高业务量" name="1">
<el-scrollbar height="200px">
<datav-chart-bar-fixbug
:data="areaRiskList"
size="small"
:color="colors"
/>
</el-scrollbar>
</datav-tab-item>
<datav-tab-item label="中业务量" name="2">
<el-scrollbar height="200px">
<datav-chart-bar-fixbug
:data="areaNegativeList"
:max="11"
size="small"
:color="colors"
/>
</el-scrollbar>
</datav-tab-item>
<datav-tab-item label="低业务量" name="3">
<el-scrollbar height="200px">
<datav-chart-bar-fixbug
:data="areaRateList"
:max="11"
size="small"
:color="colors"
/>
</el-scrollbar>
</datav-tab-item>
</datav-tabs>
</datav-card>
</el-col>
<el-col :span="8">
<datav-card>
<div class="card-header">
<span class="card-title">派出所</span>
<div class="select-container">
<el-select v-model="selectedMetricPCS" placeholder="请选择指标">
<el-option label="问题数" value="problemNumber"></el-option>
<el-option label="涉及人数" value="personNumber"></el-option>
<el-option label="人均问题数" value="avgProblemNumber"></el-option>
</el-select>
</div>
</div>
<datav-tabs
type="bottom-button"
ref="pcsTabs"
v-model="selectedPcsTabs"
>
<datav-tab-item label="高业务量" name="1">
<el-scrollbar height="200px">
<datav-chart-bar-fixbug
:data="pcsRiskList"
size="small"
:color="colors"
/>
</el-scrollbar>
</datav-tab-item>
<datav-tab-item label="中业务量" name="2">
<el-scrollbar height="200px">
<datav-chart-bar-fixbug
:data="orgNegativeList"
:max="11"
size="small"
:color="colors"
/>
</el-scrollbar>
</datav-tab-item>
<datav-tab-item label="低业务量" name="3">
<el-scrollbar height="200px">
<datav-chart-bar-fixbug
:data="orgRateList"
:max="11"
size="small"
:color="colors"
/>
</el-scrollbar>
</datav-tab-item>
</datav-tabs>
</datav-card>
</el-col>
<el-col :span="8">
<datav-card>
<div class="card-header">
<span class="card-title">交警大队</span>
<div class="select-container">
<el-select v-model="selectedMetricJJDD" placeholder="请选择指标">
<el-option label="问题数" value="problemNumber"></el-option>
<el-option label="涉及人数" value="personNumber"></el-option>
<el-option label="人均问题数" value="avgProblemNumber"></el-option>
</el-select>
</div>
</div>
<datav-tabs
type="bottom-button"
ref="jjddTabs"
v-model="selectedJjddTabs"
>
<datav-tab-item label="高业务量" name="1">
<el-scrollbar height="200px">
<datav-chart-bar-fixbug
:data="carRiskList"
size="small"
:color="colors"
/>
</el-scrollbar>
</datav-tab-item>
<datav-tab-item label="中业务量" name="2">
<el-scrollbar height="200px">
<datav-chart-bar-fixbug
:data="orgCarNegativeList"
:max="11"
size="small"
:color="colors"
/>
</el-scrollbar>
</datav-tab-item>
<datav-tab-item label="低业务量" name="3">
<el-scrollbar height="200px">
<datav-chart-bar-fixbug
:data="orgCarRateList"
:max="11"
size="small"
:color="colors"
/>
</el-scrollbar>
</datav-tab-item>
</datav-tabs>
</datav-card>
</el-col>
</el-row>
<el-row style="margin-top: 20px" :gutter="16">
<el-col :span="8">
<datav-card>
<div class="card-header">
<span class="card-title">领导</span>
<div class="select-container">
<el-select v-model="selectedMetricLD" placeholder="请选择指标">
<el-option label="派出所" value="paichusuo"></el-option>
<el-option label="交警" value="jiaojing"></el-option>
</el-select>
</div>
</div>
<datav-tabs
type="bottom-button"
ref="ldTabs"
v-model="selectedLdTabs"
>
<datav-tab-item label="问题数" name="1">
<el-scrollbar height="200px">
<datav-chart-bar-fixbug
:data="leaderRiskList"
size="small"
:color="colors"
/>
</el-scrollbar>
</datav-tab-item>
<datav-tab-item label="问题涉及人数" name="2">
<el-scrollbar height="200px">
<datav-chart-bar-fixbug
:data="leaderNegativeList"
:max="11"
size="small"
:color="colors"
/>
</el-scrollbar>
</datav-tab-item>
</datav-tabs>
</datav-card>
</el-col>
<el-col :span="8">
<datav-card>
<div class="card-header">
<span class="card-title">民警</span>
<div class="select-container">
<el-select v-model="selectedMetricMJ" placeholder="请选择指标">
<el-option label="派出所" value="paichusuo"></el-option>
<el-option label="交警" value="jiaojing"></el-option>
</el-select>
</div>
</div>
<datav-tabs
type="bottom-button"
ref="mjTabs"
v-model="selectedMjTabs"
>
<datav-tab-item label="问题数" name="1">
<el-scrollbar height="200px">
<datav-chart-bar-fixbug
:data="policeANegativeList"
size="small"
:color="colors"
/>
</el-scrollbar>
</datav-tab-item>
<datav-tab-item label="问题发生率" name="2">
<el-scrollbar height="200px">
<datav-chart-bar-fixbug
:data="policeARiskList"
:max="11"
size="small"
:color="colors"
/>
</el-scrollbar>
</datav-tab-item>
</datav-tabs>
</datav-card>
</el-col>
<el-col :span="8">
<datav-card>
<div class="card-header">
<span class="card-title">协辅警</span>
<div class="select-container">
<el-select v-model="selectedMetricXFJ" placeholder="请选择指标">
<el-option label="派出所" value="paichusuo"></el-option>
<el-option label="交警" value="jiaojing"></el-option>
</el-select>
</div>
</div>
<datav-tabs
type="bottom-button"
ref="xfjTabs"
v-model="selectedXfjTabs"
>
<datav-tab-item label="问题数" name="1">
<el-scrollbar height="200px">
<datav-chart-bar-fixbug
:data="policeBRiskList"
size="small"
:color="colors"
/>
</el-scrollbar>
</datav-tab-item>
</datav-tabs>
</datav-card>
</el-col>
</el-row>
</div>
</el-scrollbar>
</template>
<script setup>
import {
totalStatistics,
areaRiskStatistics,
leaderRiskStatistics,
policeARiskStatistics,
policeBRiskStatistics,
orgCarRiskStatistics,
orgRiskStatistics,
areaNegativeStatistics,
orgNegativeStatistics,
orgCarNegativeStatistics,
policeANegativeStatistics,
policeBNegativeStatistics,
policeLeaderNegativeStatistics,
areaRateStatistics,
orgRateStatistics,
orgCarRateStatistics
} from '@/api/data/risk';
import moment from "moment";
let selectedMetric = ref('problemNumber');
let selectedMetricPCS = ref('problemNumber');
let selectedMetricJJDD = ref('problemNumber');
let selectedMetricLD = ref('paichusuo');
let selectedMetricMJ = ref('paichusuo');
let selectedMetricXFJ = ref('paichusuo');
let statisticsTotal = ref({
caseTotal: 0,
aTotal: 0,
negativeTotal: 0,
peopleCount: 0,
avgPeople: 0.0
})
let areaRiskList = ref([])
let pcsRiskList = ref([])
let carRiskList = ref([])
let policeARiskList = ref([])
let policeBRiskList = ref([])
let leaderRiskList = ref([])
let areaNegativeList = ref([])
let orgNegativeList = ref([])
let orgCarNegativeList = ref([])
let policeANegativeList = ref([])
let policeBNegativeList = ref([])
let leaderNegativeList = ref([])
let areaRateList = ref([])
let orgRateList = ref([])
let orgCarRateList = ref([])
const time = ref([
moment().startOf("year").format("YYYY-MM-DD"),
moment().format("YYYY-MM-DD"),
]);
// -- 分县市局
watch(selectedMetric,()=>{
getAreaRiskData(selectedMetric.value); // 【分县市局 高业务量】
getAreaNegativeData(selectedMetric.value);// 分县 /area/negative/statistics 【分县市局 中业务量】
getAreaRateData(selectedMetric.value);// /area/rate/statistics 【分县市局 低业务量】
},{deep:true})
// 派出所
watch(selectedMetricPCS,()=>{
console.log('-----12------')
getPCSRiskData(selectedMetricPCS.value);//分机构统计风险分 派出所 /risk/org/statistics 【派出所 高业务量】
getOrgNegativeData(selectedMetricPCS.value);// 派出所 /org/negative/statistics 【派出所 中业务量】
getOrgRateData(selectedMetricPCS.value);// 派出所 /org/rate/statistics 【派出所 低业务量】
})
//交警大队
watch(selectedMetricJJDD,()=>{
getCarRiskData(selectedMetricJJDD.value);//分机构统计风险分 交警大队 【交警大队 高业务量】
getCarOrgNegativeData(selectedMetricJJDD.value);// /org/car/negative/statistics 【交警大队 中业务量】
getCarOrgRateData(selectedMetricJJDD.value);// 交警人均率 /org/car/rate/statistics 【交警大队 低业务量】
})
//领导
watch(selectedMetricLD,()=>{
getLeaderNegativeData(selectedMetricLD.value);// 【领导 问题数】
getLeaderRiskData(selectedMetricLD.value);// 【领导 问题涉及人数】
})
//民警
watch(selectedMetricMJ,()=>{
getPoliceANegativeData(selectedMetricMJ.value);// 【民警 问题数】
getPoliceARiskData(selectedMetricMJ.value);// 【民警 问题发生率】
})
watch(selectedMetricXFJ,()=>{
getPoliceBNegativeData(selectedMetricXFJ.value);//【辅警/协警 问题数】
getPoliceBRiskData(selectedMetricXFJ.value);//【辅警/协警 问题发生率】
})
watch(time, () => {
getTotalData();//数量统计 /total/statistics
getAreaRiskData(selectedMetric.value); // 【分县市局 高业务量】
getAreaNegativeData(selectedMetric.value);// 分县 /area/negative/statistics 【分县市局 中业务量】
getAreaRateData(selectedMetric.value);// /area/rate/statistics 【分县市局 低业务量】
getPCSRiskData(selectedMetricPCS.value);//分机构统计风险分 派出所 /risk/org/statistics 【派出所 高业务量】
getOrgNegativeData(selectedMetricPCS.value);// 派出所 /org/negative/statistics 【派出所 中业务量】
getOrgRateData(selectedMetricPCS.value);// 派出所 /org/rate/statistics 【派出所 低业务量】
getCarRiskData(selectedMetricJJDD.value);//分机构统计风险分 交警大队 【交警大队 高业务量】
getCarOrgNegativeData(selectedMetricJJDD.value);// /org/car/negative/statistics 【交警大队 中业务量】
getCarOrgRateData(selectedMetricJJDD.value);// 交警人均率 /org/car/rate/statistics 【交警大队 低业务量】
getLeaderNegativeData(selectedMetricLD.value);// 【领导 问题数】
getLeaderRiskData(selectedMetricLD.value);// 【领导 问题涉及人数】
getPoliceANegativeData(selectedMetricMJ.value);// 【民警 问题数】
getPoliceARiskData(selectedMetricMJ.value);// 【民警 问题发生率】
getPoliceBNegativeData(selectedMetricXFJ.value);//【辅警/协警 问题数】
getPoliceBRiskData(selectedMetricXFJ.value);//【辅警/协警 问题发生率】
},{deep:true});
onMounted(() => {
getTotalData();//数量统计 /total/statistics
getAreaRiskData(selectedMetric.value); // 【分县市局 高业务量】
getAreaNegativeData(selectedMetric.value);// 分县 /area/negative/statistics 【分县市局 中业务量】
getAreaRateData(selectedMetric.value);// /area/rate/statistics 【分县市局 低业务量】
getPCSRiskData(selectedMetricPCS.value);//分机构统计风险分 派出所 /risk/org/statistics 【派出所 高业务量】
getOrgNegativeData(selectedMetricPCS.value);// 派出所 /org/negative/statistics 【派出所 中业务量】
getOrgRateData(selectedMetricPCS.value);// 派出所 /org/rate/statistics 【派出所 低业务量】
getCarRiskData(selectedMetricJJDD.value);//分机构统计风险分 交警大队 【交警大队 高业务量】
getCarOrgNegativeData(selectedMetricJJDD.value);// /org/car/negative/statistics 【交警大队 中业务量】
getCarOrgRateData(selectedMetricJJDD.value);// 交警人均率 /org/car/rate/statistics 【交警大队 低业务量】
getLeaderNegativeData(selectedMetricLD.value);// 【领导 问题数】
getLeaderRiskData(selectedMetricLD.value);// 【领导 问题涉及人数】
getPoliceANegativeData(selectedMetricMJ.value);// 【民警 问题数】
getPoliceARiskData(selectedMetricMJ.value);// 【民警 问题发生率】
getPoliceBNegativeData(selectedMetricXFJ.value);//【辅警/协警 问题数】
getPoliceBRiskData(selectedMetricXFJ.value);//【辅警/协警 问题发生率】
});
const getTotalData = () => {
totalStatistics(time.value).then(res => {
statisticsTotal.value.aTotal = res.atotal == undefined ? 0 : res.atotal;
statisticsTotal.value.caseTotal = res.caseTotal == undefined ? 0 : res.caseTotal;
statisticsTotal.value.negativeTotal = res.negativeTotal == undefined ? 0 : res.negativeTotal;
statisticsTotal.value.peopleCount = res.peopleCount == undefined ? 0 : res.peopleCount;
statisticsTotal.value.avgPeople = res.avgPeople == undefined ? 0.0 : res.avgPeople;
})
}
const getAreaRiskData = (type) => {
areaRiskStatistics(time.value, type).then(res => {
areaRiskList.value = eachData(res)
})
}
const getPCSRiskData = (type) => {
orgRiskStatistics(time.value, type).then(res => {
pcsRiskList.value = eachData(res)
})
}
const getCarRiskData = (type) => {
orgCarRiskStatistics(time.value, type).then(res => {
carRiskList.value = eachData(res)
})
}
const getPoliceARiskData = (type) => {
policeARiskStatistics(time.value, type).then(res => {
policeARiskList.value = eachData(res)
})
}
const getPoliceBRiskData = (type) => {
policeBRiskStatistics(time.value, type).then(res => {
policeBRiskList.value = eachData(res)
})
}
const getLeaderRiskData = (type) => {
leaderRiskStatistics(time.value, type).then(res => {
leaderRiskList.value = eachData(res)
})
}
const getAreaNegativeData = (type) => {
areaNegativeStatistics(time.value, type).then(res => {
areaNegativeList.value = eachData(res)
})
}
const getOrgNegativeData = (type) => {
orgNegativeStatistics(time.value, type).then(res => {
orgNegativeList.value = eachData(res)
})
}
const getCarOrgNegativeData = (type) => {
orgCarNegativeStatistics(time.value, type).then(res => {
orgCarNegativeList.value = eachData(res)
})
}
const getPoliceANegativeData = (type) => {
policeANegativeStatistics(time.value, type).then(res => {
policeANegativeList.value = eachData(res)
})
}
const getPoliceBNegativeData = (type) => {
policeBNegativeStatistics(time.value, type).then(res => {
policeBNegativeList.value = eachData(res)
})
}
const getLeaderNegativeData = (type) => {
policeLeaderNegativeStatistics(time.value, type).then(res => {
leaderNegativeList.value = eachData(res)
})
}
const getAreaRateData = (type) => {
areaRateStatistics(time.value, type).then(res => {
areaRateList.value = eachData(res)
})
}
const getOrgRateData = (type) => {
orgRateStatistics(time.value, type).then(res => {
orgRateList.value = eachData(res)
})
}
const getCarOrgRateData = (type) => {
orgCarRateStatistics(time.value, type).then(res => {
orgCarRateList.value = eachData(res)
})
}
const eachData = (data) => {
let arr = [];
data.forEach(item => {
arr.push({
label: item.label,
value: item['score'] != null ? Number(item.score) : Number(item.value)
});
});
return arr;
}
const colors = [
{
color: "linear-gradient( 270deg, #FB002D 0%, #822232 100%)",
percentage: 80,
},
{
color: "linear-gradient( 270deg, #FFB90E 0%, #71501D 100%)",
percentage: 60,
},
{
color: "linear-gradient( 270deg, #63E7AA 0%, #19674C 100%)",
percentage: 40,
},
];
// region 动画
const rxsjTabs = ref(null);
const pcsTabs = ref(null);
const jjddTabs = ref(null);
const ldTabs = ref(null);
const mjTabs = ref(null);
const xfjTabs = ref(null);
const selectedFxsjTabs = ref("1");
const selectedPcsTabs = ref("1");
const selectedJjddTabs = ref("1");
const selectedLdTabs = ref("1");
const selectedMjTabs = ref("1");
const selectedXfjTabs = ref("1");
let rxsjTabsIntervalId;
let pcsTabsIntervalId;
let jjddTabsIntervalId;
let ldTabsIntervalId;
let mjTabsIntervalId;
let xfjTabsIntervalId;
const rxsjTabsAnimation = () => {
selectedFxsjTabs.value = (parseInt(selectedFxsjTabs.value) % 3 + 1).toString();
};
rxsjTabsIntervalId = setInterval(rxsjTabsAnimation, 3000);
const pcsTabsAnimation = () => {
selectedPcsTabs.value = (parseInt(selectedPcsTabs.value) % 3 + 1).toString();
};
pcsTabsIntervalId = setInterval(pcsTabsAnimation, 3000);
const jjddTabsAnimation = () => {
selectedJjddTabs.value = (parseInt(selectedJjddTabs.value) % 3 + 1).toString();
};
jjddTabsIntervalId = setInterval(jjddTabsAnimation, 3000);
const ldTabsAnimation = () => {
selectedLdTabs.value = (parseInt(selectedLdTabs.value) % 2 + 1).toString();
};
ldTabsIntervalId = setInterval(ldTabsAnimation, 3000);
const mjTabsAnimation = () => {
selectedMjTabs.value = (parseInt(selectedMjTabs.value) % 2 + 1).toString();
};
mjTabsIntervalId = setInterval(mjTabsAnimation, 3000);
// endregion
// region 监听鼠标事件
onMounted(() => {
setupEventListeners();
});
const setupEventListeners = () => {
rxsjTabsAnimationStop();
pcsTabsAnimationStop();
jjddTabsAnimationStop();
ldTabsAnimationStop();
mjTabsAnimationStop();
};
const rxsjTabsAnimationStop = () => {
const temp = rxsjTabs.value?.$el;
temp.addEventListener('mouseenter', () => {
clearInterval(rxsjTabsIntervalId)
});
temp.addEventListener('mouseleave', () => {
rxsjTabsIntervalId = setInterval(rxsjTabsAnimation, 3000);
});
}
const pcsTabsAnimationStop = () => {
const temp = pcsTabs.value?.$el;
temp.addEventListener('mouseenter', () => {
clearInterval(pcsTabsIntervalId)
});
temp.addEventListener('mouseleave', () => {
pcsTabsIntervalId = setInterval(pcsTabsAnimation, 3000);
});
}
const jjddTabsAnimationStop = () => {
const temp = jjddTabs.value?.$el;
temp.addEventListener('mouseenter', () => {
clearInterval(jjddTabsIntervalId)
});
temp.addEventListener('mouseleave', () => {
jjddTabsIntervalId = setInterval(jjddTabsAnimation, 3000);
});
}
const ldTabsAnimationStop = () => {
const temp = ldTabs.value?.$el;
temp.addEventListener('mouseenter', () => {
clearInterval(ldTabsIntervalId)
});
temp.addEventListener('mouseleave', () => {
ldTabsIntervalId = setInterval(ldTabsAnimation, 3000);
});
}
const mjTabsAnimationStop = () => {
const temp = mjTabs.value?.$el;
temp.addEventListener('mouseenter', () => {
clearInterval(mjTabsIntervalId)
});
temp.addEventListener('mouseleave', () => {
mjTabsIntervalId = setInterval(mjTabsAnimation, 3000);
});
}
// endregion
</script>
<style lang="scss" scoped>
@import "@/style/datav.scss";
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
}
.card-title {
font-size: 23px;
font-weight: bold;
}
.select-container {
width: 150px;
margin-left: auto;
}
:deep(.el-select__wrapper) {
background-color: #041a75;
box-shadow: #0a113b 0px 0px 0px 1px;
}
:deep(.el-select__placeholder ) {
color: #fff;
}
</style>