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.
1251 lines
33 KiB
1251 lines
33 KiB
<template> |
|
<!--头部--> |
|
<div class="body"> |
|
<div class="header"> |
|
<img src="@/assets/logo.png"> |
|
</div> |
|
<!--主体--> |
|
<div class="main clearfix"> |
|
<div class="main-left"> |
|
<div class="box-container"> |
|
<div class="name-title"> |
|
今日值班 |
|
</div> |
|
<div> |
|
<el-tabs v-model="dutyActiveName" class="echart-tabs" type="card" @tab-click="dutyResetTimer"> |
|
<el-tab-pane label="市局" name="dutySj"> |
|
<div class="boxRightMailCon"> |
|
<ul class="dutyUl"> |
|
<li v-for="item in dutySjList" :key="item.id"> |
|
<p><span class="dutyDept">{{ item.departName }}</span> <span class="dutyULspan">{{ item.mobile |
|
}}</span> <span class="dutyULspan">{{ item.policeName }}</span></p> |
|
</li> |
|
|
|
</ul> |
|
</div> |
|
|
|
</el-tab-pane> |
|
<el-tab-pane label="本单位" name="dutyFj"> |
|
<ul class="dutyUl"> |
|
<li v-for="item in dutyList.dutyFjList" :key="item.id"> |
|
<p><span class="dutyDept">{{ item.departName }}</span> <span class="dutyULspan">{{ item.mobile |
|
}}</span> <span class="dutyULspan">{{ item.policeName }}</span></p> |
|
</li> |
|
|
|
</ul> |
|
|
|
</el-tab-pane> |
|
<el-tab-pane label="大队" name="dutyZd"> |
|
<ul class="dutyUl"> |
|
<li v-for="item in dutyList.dutyDdList" :key="item.id"> |
|
<p><span class="dutyDept">{{ item.departName }}</span> <span class="dutyULspan">{{ item.mobile |
|
}}</span> <span class="dutyULspan">{{ item.policeName }}</span></p> |
|
</li> |
|
|
|
</ul> |
|
</el-tab-pane> |
|
<el-tab-pane label="派出所" name="dutyBw"> |
|
<ul class="dutyUl"> |
|
<li v-for="item in dutyList.dutyPcsList" :key="item.id"> |
|
<p><span class="dutyDept">{{ item.departName }}</span> <span class="dutyULspan">{{ item.mobile |
|
}}</span> <span class="dutyULspan">{{ item.policeName }}</span></p> |
|
</li> |
|
|
|
</ul> |
|
</el-tab-pane> |
|
</el-tabs> |
|
</div> |
|
|
|
</div> |
|
<div class="box-container"> |
|
<div class="name-title"> |
|
派出所三率排名 |
|
</div> |
|
<div id="graduate"> |
|
<el-tabs v-model="rateActiveName" class="echart-tabs" @tab-click="rateResetTimer" type="card"> |
|
<el-tab-pane label="办结率" name="completionRate"> |
|
<div class="ratesbox rates"> |
|
<ul class="h100"> |
|
<li v-for="item in completeList" :key="item.id"> |
|
<span>{{ item.name }}</span> |
|
<div class="ratenav"> |
|
<div class="ratebar"><span :style="{ width: item.rate }"></span></div> |
|
</div> |
|
<div class="ratesum"> |
|
<p>{{ item.rate }}<span class="ratespan"><i>{{ item.completed }} / </i>{{ item.sum }}</span></p> |
|
</div> |
|
</li> |
|
</ul> |
|
|
|
</div> |
|
</el-tab-pane> |
|
<el-tab-pane label="解决率" name="resolutionRate"> |
|
<div class="ratesbox rates"> |
|
<ul class="h100"> |
|
<li v-for="item in rateMap.resolvedList" :key="item.id"> |
|
<span>{{ item.name }}</span> |
|
<div class="ratenav"> |
|
<div class="ratebar"><span :style="{ width: item.rate }"></span></div> |
|
</div> |
|
<div class="ratesum"> |
|
<p>{{ item.rate }}<span class="ratespan"><i>{{ item.resolved }} / </i>{{ item.sum }}</span></p> |
|
</div> |
|
</li> |
|
</ul> |
|
|
|
</div> |
|
</el-tab-pane> |
|
<el-tab-pane label="满意率" name="satisfactionRate"> |
|
<div class="ratesbox rates"> |
|
<ul class="h100"> |
|
<li v-for="item in rateMap.satisfiedList" :key="item.id"> |
|
<span>{{ item.name }}</span> |
|
<div class="ratenav"> |
|
<div class="ratebar"><span :style="{ width: item.rate }"></span></div> |
|
</div> |
|
<div class="ratesum"> |
|
<p>{{ item.rate }}<span class="ratespan"><i>{{ item.satisfied }} / </i>{{ item.sum }}</span></p> |
|
</div> |
|
</li> |
|
</ul> |
|
|
|
</div> |
|
|
|
</el-tab-pane> |
|
</el-tabs> |
|
|
|
</div> |
|
|
|
</div> |
|
</div> |
|
<div class="main-middle"> |
|
<div class="border-console "> |
|
<div class="console-div"> |
|
<ul class="clearfix"> |
|
<li> |
|
<h2 class="bulebg">{{ consoleMap.todaySum }}</h2><span>今日来信</span> |
|
</li> |
|
<li> |
|
<h2 class="yellowbg">{{ consoleMap.allSum }}</h2><span>来信总数</span> |
|
</li> |
|
<li> |
|
<h2 class="bulebg">{{ consoleMap.completed }}</h2><span>办结总数</span> |
|
</li> |
|
<li> |
|
<el-popover placement="right-start" title="办结率计算方式" :width="200" trigger="hover" show-after="700" |
|
:content="completedrateContent" popper-class="custom-popover-style"> |
|
<template #reference> |
|
<h2 class="yellowbg" v-show="consoleMap.completedrate">{{ consoleMap.completedrate }}</h2> |
|
</template> |
|
</el-popover> |
|
<span>办结率</span> |
|
</li> |
|
<li> |
|
<el-popover placement="right-start" title="满意率计算方式" :width="200" trigger="hover" show-after="700" |
|
:content="satisfiedrateContent" popper-class="custom-popover-style"> |
|
<template #reference> |
|
<h2 class="bulebg" v-show="consoleMap.satisfiedrate">{{ consoleMap.satisfiedrate }}</h2> |
|
</template> |
|
</el-popover> |
|
<span>满意率</span> |
|
</li> |
|
<li> |
|
<el-popover placement="right-start" title="解决率计算方式" :width="200" trigger="hover" show-after="700" |
|
:content="resolvedrateContent" popper-class="custom-popover-style"> |
|
<template #reference> |
|
<h2 class="yellowbg" v-show="consoleMap.resolvedrate">{{ consoleMap.resolvedrate }}</h2> |
|
</template> |
|
</el-popover> |
|
<span>解决率</span> |
|
</li> |
|
</ul> |
|
</div> |
|
|
|
</div> |
|
<div class="border-console"> |
|
<div id="map" ref="map"></div> |
|
</div> |
|
<div class="mail-container"> |
|
<div class="name-title"> |
|
来信趋势 |
|
</div> |
|
<div v-if="seenDay" class="trendOptions"> |
|
<el-select v-model="trendDayValue" class="m-2" :placeholder="selectTrend" size="small" |
|
style="width: 100px;z-index: 3000;" @change="getMailTrend" popper-class="blueBack"> |
|
<el-option v-for="item in trendDayOptions" :key="item.value" :label="item.label" :value="item.value" /> |
|
</el-select> |
|
</div> |
|
<div v-if="seenWeek" class="trendOptions"> |
|
<el-select v-model="trendWeekValue" class="m-2" :placeholder="selectTrend" size="small" |
|
style="width: 100px;z-index: 3000" @change="getMailTrend" popper-class="blueBack"> |
|
<el-option v-for="item in trendWeekOptions" :key="item.value" :label="item.label" :value="item.value" /> |
|
</el-select> |
|
</div> |
|
|
|
<div v-if="seenMonth" class="trendOptions"> |
|
<el-select v-model="trendMonthValue" class="m-2" :placeholder="selectTrend" size="small" |
|
style="width: 100px;z-index: 3000" @change="getMailTrend" popper-class="blueBack"> |
|
<el-option v-for="item in trendMonthOptions" :key="item.value" :label="item.label" :value="item.value" |
|
style="height:auto;max-height:300px;padding:0;" /> |
|
</el-select> |
|
</div> |
|
|
|
<div ref="tabsContainer"> |
|
|
|
<el-tabs v-model="trendActiveName" class="trend-tabs" type="card" @tab-click="trendResetTimer"> |
|
<el-tab-pane label="按天计算" name="dayTrend"> |
|
<div ref="day_echart" id="dayEchart" :style="{ width: chartWidth + 'px' }"></div> |
|
</el-tab-pane> |
|
<el-tab-pane label="按周计算" name="weekTrend"> |
|
<div ref="week_echart" id="weekEchart" :style="{ width: chartWidth + 'px' }"></div> |
|
</el-tab-pane> |
|
<el-tab-pane label="按月计算" name="monthTrend"> |
|
<div ref="month_echart" id="monthEchart" :style="{ width: chartWidth + 'px' }"></div> |
|
</el-tab-pane> |
|
</el-tabs> |
|
</div> |
|
|
|
</div> |
|
</div> |
|
<div class="main-right"> |
|
<div class="box-container"> |
|
<div class="name-title"> |
|
信件动态 |
|
</div> |
|
<div class="boxLeftMailCon"> |
|
<ul class="mailUl"> |
|
<li v-for="item in peopleMaillist" :key="item.id" @click="queryDetails(item)"> |
|
<p>{{ item.contactName }} :{{ item.contactPhone }}<span class="mailULspan">{{ item.mailState }}</span> |
|
</p> |
|
<p>{{ formatDate(item.createTime) }}</p> |
|
</li> |
|
</ul> |
|
</div> |
|
|
|
|
|
</div> |
|
<div class="box-container"> |
|
<div class="name-title"> |
|
信件类型排名 |
|
</div> |
|
<div class=" boxnav paim"> |
|
<ul class="h100"> |
|
<li v-for="item in mailTypeRankList" :key="item.id"> |
|
<span>{{ item.rownumber }}</span> |
|
<div class="pmnav"> |
|
<p>{{ item.category }}</p> |
|
<div class="pmbar"><span :style="{ width: item.countrate }"></span><i></i></div> |
|
</div> |
|
<div class="pmsum"> |
|
<p>{{ item.sumcount }}</p> |
|
</div> |
|
</li> |
|
|
|
|
|
</ul> |
|
|
|
</div> |
|
</div> |
|
|
|
</div> |
|
<details-popup v-if="showDetails" ref="detailsRef" @success="closeDetails" @close="closeDetails" /> |
|
</div> |
|
</div> |
|
</template> |
|
<style> |
|
@import 'assets/css/index.css'; |
|
|
|
body { |
|
background-color: #030b39; |
|
} |
|
|
|
.body { |
|
|
|
background-image: url('@/assets/bg.png'); |
|
/* 背景图片的路径 */ |
|
background-size: cover; |
|
/* 背景图片大小适应容器 */ |
|
|
|
|
|
} |
|
|
|
.ratebar i { |
|
line-height: 2rem; |
|
font-style: normal; |
|
padding-left: 1rem; |
|
color: #49bcf7; |
|
font-size: 1.6rem; |
|
} |
|
|
|
.ratenav { |
|
/* width:calc(100% - 5rem)*/ |
|
width: 200px; |
|
} |
|
|
|
.ratenav p { |
|
color: #fff; |
|
font-size: 1.5rem; |
|
padding-bottom: 0.5rem; |
|
white-space: nowrap; |
|
overflow: hidden; |
|
text-overflow: ellipsis; |
|
} |
|
|
|
.rates li>span { |
|
width: 120px; |
|
height: 3rem; |
|
font-family: PingFang-SC-Regular; |
|
font-size: 16px; |
|
color: #FFFFFF; |
|
text-align: right; |
|
font-weight: 400; |
|
line-height: 3rem; |
|
padding-right: 5px; |
|
border-radius: .05rem; |
|
margin-right: .1rem; |
|
} |
|
|
|
.ratesum { |
|
font-size: 1.6rem; |
|
} |
|
</style> |
|
|
|
|
|
<script lang="ts" setup> |
|
import { ref, onMounted, watch, onBeforeUpdate, onBeforeMount, onUnmounted } from 'vue' |
|
import type { TabsPaneContext } from 'element-plus' |
|
import * as echarts from 'echarts'; |
|
import chinaJSON from "./changsha.json"; |
|
import yuhuaJSON from "@/static/430111.json"; |
|
import { peopleMail, dutyDay, threeRate, consoleData, mailTypeRank, mailTrend, mapCountyData, currentCountyMapJSON } from '@/api/datascreen' |
|
import { useRouter } from "vue-router"; |
|
import { menuLists } from "~/api/perms/menu.ts"; |
|
import DetailsPopup from './details.vue' |
|
const detailsRef = shallowRef<InstanceType<typeof DetailsPopup>>() |
|
const showDetails = ref(false) |
|
const router = useRouter(); |
|
|
|
const rateActiveName = ref('completionRate') |
|
const trendActiveName = ref('dayTrend') |
|
const dutyActiveName = ref('dutySj') |
|
|
|
|
|
let currentParams = reactive([]) as any[]; |
|
let currentMapJSON = reactive([]) as any[]; |
|
let peopleMaillist = ref([]); |
|
let dutyList = ref([]); |
|
let typeRankList = ref([]); |
|
let rateMap = ref([]); |
|
let mailTrendMap = ref([]); |
|
let consoleMap = ref([]); |
|
let mailTypeRankList = reactive([]) as any[]; |
|
let completeList = reactive([]) as any[]; |
|
let dutySjList = reactive([]) as any[]; |
|
|
|
const intervalTimeRate = 3500; // 自动切换的间隔时间,单位为毫秒 |
|
const intervalTimeTrend = 3000; // 自动切换的间隔时间,单位为毫秒 |
|
const intervalTimeDuty = 3200; // 自动切换的间隔时间,单位为毫秒 |
|
let intervalIdRate: NodeJS.Timeout | null = null; |
|
let intervalIdTrend: NodeJS.Timeout | null = null; |
|
let intervalIdDuty: NodeJS.Timeout | null = null; |
|
|
|
let carouselTime: NodeJS.Timeout | null = null; |
|
|
|
let dayXList = reactive([]) as any[]; |
|
let dayYList = reactive([]) as any[]; |
|
let weekXList = reactive([]) as any[]; |
|
let weekYList = reactive([]) as any[]; |
|
let monthXList = reactive([]) as any[]; |
|
let monthYList = reactive([]) as any[]; |
|
let map = ref('map'); |
|
|
|
|
|
let mapDataList = reactive([]) as any[]; |
|
let dataIndex = 0 |
|
|
|
let currentIndex = 0; |
|
let chartWidth = 900; |
|
const tabsContainer = ref(null); |
|
|
|
let day_echart = ref(null); |
|
let month_echart = ref(null); |
|
let week_echart = ref(null); |
|
|
|
let trendDayValue = ref('15') |
|
let trendWeekValue = ref('7') |
|
let trendMonthValue = ref('2024') |
|
const selectTrend = "请选择" |
|
let seenDay = true |
|
let seenWeek = false |
|
let seenMonth = false |
|
let mapShow = true |
|
let trendDayOptions = [ |
|
{ |
|
value: '15', |
|
label: '最近15天', |
|
}, |
|
{ |
|
value: '30', |
|
label: '最近30天', |
|
} |
|
] |
|
|
|
let trendWeekOptions = [ |
|
|
|
{ |
|
value: '7', |
|
label: '最近7周', |
|
}, |
|
{ |
|
value: '15', |
|
label: '最近15周', |
|
} |
|
] |
|
|
|
let trendMonthOptions = reactive([]) as any[]; |
|
|
|
const selectYear = (year) => { |
|
var myDate = new Date(); |
|
var startYear = myDate.getFullYear() - year;//起始年份 |
|
var endYear = myDate.getFullYear();//结束年份 |
|
for (var i = startYear; i <= endYear; i++) { |
|
var obj = { "value": i, "label": i }; |
|
trendMonthOptions.push(obj); |
|
} |
|
} |
|
|
|
//console大屏数据 |
|
const getConsoleDataMap = async () => { |
|
try { |
|
consoleMap = await consoleData(currentParams) |
|
completedrateContent.value = '办结率=解决数/已办结数\n' + consoleMap.value.completedrate + '=' + consoleMap.value.completed + '/' + consoleMap.value.completedsum |
|
satisfiedrateContent.value = '满意率=满意数/已办结数\n' + consoleMap.value.satisfiedrate + '=' + consoleMap.value.satisfied + '/' + consoleMap.value.satisfiedsum |
|
resolvedrateContent.value = '解决率=解决数/来信总数\n' + consoleMap.value.resolvedrate + '=' + consoleMap.value.resolved + '/' + consoleMap.value.resolvedsum |
|
|
|
} catch (error) { |
|
} |
|
} |
|
|
|
const getCurrentMapJSON = async () => { |
|
try { |
|
currentMapJSON = await currentCountyMapJSON(currentParams) |
|
changsMap() |
|
} catch (error) { |
|
} |
|
} |
|
|
|
//类型排行 |
|
const getMailTypeRankList = async () => { |
|
try { |
|
typeRankList = await mailTypeRank(currentParams) |
|
|
|
typeRankList.forEach((element: any) => { |
|
mailTypeRankList.push(element);//循环赋值 |
|
}); |
|
} catch (error) { |
|
} |
|
} |
|
|
|
//获取最近来信 |
|
const getPopleMailLists = async () => { |
|
try { |
|
peopleMaillist = await peopleMail(currentParams) |
|
} catch (error) { |
|
} |
|
} |
|
|
|
//获取今日值班 |
|
const getDutyDay = async () => { |
|
try { |
|
dutyList = await dutyDay(currentParams) |
|
dutyList.dutySjList.forEach((element: any) => { |
|
dutySjList.push(element);//循环赋值 |
|
}); |
|
} catch (error) { |
|
} |
|
} |
|
const getThreeRate = async () => { |
|
try { |
|
rateMap = await threeRate(currentParams) |
|
rateMap.completeList.forEach((element: any) => { |
|
completeList.push(element);//循环赋值 |
|
}); |
|
} catch (error) { |
|
} |
|
} |
|
|
|
const getMailTrend = async () => { |
|
try { |
|
const params = reactive({ |
|
day: trendDayValue.value, |
|
week: trendWeekValue.value, |
|
year: trendMonthValue.value, |
|
id: currentParams.id |
|
}) |
|
mailTrendMap = await mailTrend(params) |
|
|
|
dayXList = mailTrendMap.dayXList |
|
dayYList = mailTrendMap.dayYList; |
|
dayEcharts() |
|
weekXList = mailTrendMap.weekXList; |
|
weekYList = mailTrendMap.weekYList; |
|
weekEcharts() |
|
monthXList = mailTrendMap.monthXList; |
|
monthYList = mailTrendMap.monthYList; |
|
monthEcharts() |
|
} catch (error) { |
|
} |
|
} |
|
|
|
const getMapDataList = async () => { |
|
try { |
|
|
|
mapDataList = await mapCountyData(currentParams) |
|
changsMap() |
|
} catch (error) { |
|
} |
|
} |
|
|
|
|
|
|
|
onMounted(() => { |
|
|
|
// let reg = new RegExp('(^|&)name=([^&]*)(&|$)', 'i'); |
|
// let r = window.location.href.substr(1).match(reg); //获取url中"?"符后的字符串并正则匹配 |
|
// let context = ''; |
|
// if (r) context = r[2]; |
|
currentParams = router.currentRoute.value.query |
|
selectYear(10) |
|
getCurrentMapJSON() |
|
getThreeRate(); |
|
getPopleMailLists(); |
|
getDutyDay(); |
|
getMailTypeRankList(); |
|
getMailTrend(); |
|
getMapDataList() |
|
getConsoleDataMap() |
|
startRateAutoSwitch(); |
|
startTrendAutoSwitch(); |
|
startDutyAutoSwitch(); |
|
dayEcharts() |
|
const width = tabsContainer.value.offsetWidth - 40; |
|
chartWidth = width; |
|
|
|
}); |
|
|
|
|
|
|
|
// 在组件卸载前清除计时器 |
|
onUnmounted(() => { |
|
clearRateTimer() |
|
clearTrendTimer() |
|
clearDutyTimer() |
|
|
|
clearCarouselTime() |
|
}); |
|
|
|
|
|
const formatDate = (value) => { |
|
const date = new Date(value); |
|
return date.toLocaleString(); |
|
} |
|
const startRateAutoSwitch = () => { |
|
intervalIdRate = setInterval(() => { |
|
if (rateActiveName.value === 'completionRate') { |
|
rateActiveName.value = 'resolutionRate'; |
|
} else if (rateActiveName.value === 'resolutionRate') { |
|
rateActiveName.value = 'satisfactionRate'; |
|
} else { |
|
rateActiveName.value = 'completionRate'; |
|
} |
|
}, intervalTimeRate); |
|
}; |
|
|
|
const startTrendAutoSwitch = () => { |
|
var dayChart = echarts.init(day_echart.value); |
|
var monthChart = echarts.init(month_echart.value); |
|
var weekChart = echarts.init(week_echart.value); |
|
monthChart.resize(chartWidth) |
|
dayChart.resize(chartWidth) |
|
weekChart.resize(chartWidth) |
|
intervalIdTrend = setInterval(() => { |
|
if (trendActiveName.value === 'dayTrend') { |
|
trendActiveName.value = 'weekTrend'; |
|
seenDay = false |
|
seenWeek = true |
|
seenMonth = false |
|
weekEcharts() |
|
} else if (trendActiveName.value === 'weekTrend') { |
|
trendActiveName.value = 'monthTrend'; |
|
seenDay = false |
|
seenWeek = false |
|
seenMonth = true |
|
monthEcharts() |
|
} else { |
|
trendActiveName.value = 'dayTrend'; |
|
seenDay = true |
|
seenWeek = false |
|
seenMonth = false |
|
dayEcharts() |
|
} |
|
}, intervalTimeTrend); |
|
}; |
|
|
|
const startDutyAutoSwitch = () => { |
|
intervalIdDuty = setInterval(() => { |
|
if (dutyActiveName.value === 'dutySj') { |
|
dutyActiveName.value = 'dutyFj'; |
|
} else if (dutyActiveName.value === 'dutyFj') { |
|
dutyActiveName.value = 'dutyZd'; |
|
} else if (dutyActiveName.value === 'dutyZd') { |
|
dutyActiveName.value = 'dutyBw'; |
|
} else { |
|
dutyActiveName.value = 'dutySj'; |
|
} |
|
}, intervalTimeDuty); |
|
}; |
|
|
|
|
|
const clearCarouselTime = () => { |
|
if (carouselTime) { |
|
clearInterval(carouselTime); |
|
carouselTime = null; |
|
} |
|
}; |
|
const clearRateTimer = () => { |
|
if (intervalIdRate) { |
|
clearInterval(intervalIdRate); |
|
intervalIdRate = null; |
|
} |
|
|
|
}; |
|
|
|
const clearTrendTimer = () => { |
|
if (intervalIdTrend) { |
|
clearInterval(intervalIdTrend); |
|
intervalIdTrend = null; |
|
} |
|
}; |
|
const clearDutyTimer = () => { |
|
if (intervalIdDuty) { |
|
clearInterval(intervalIdDuty); |
|
intervalIdDuty = null; |
|
} |
|
}; |
|
const rateResetTimer = () => { |
|
const width = tabsContainer.value.offsetWidth; |
|
chartWidth = width; |
|
clearRateTimer(); |
|
startRateAutoSwitch(); |
|
}; |
|
|
|
|
|
const trendResetTimer = (pane: TabsPaneContext, ev: Event) => { |
|
const width = tabsContainer.value.offsetWidth; |
|
chartWidth = width; |
|
if (pane.paneName === 'dayTrend') { |
|
seenDay = true |
|
seenWeek = false |
|
seenMonth = false |
|
} else if (pane.paneName === 'weekTrend') { |
|
seenDay = false |
|
seenWeek = true |
|
seenMonth = false |
|
} else { |
|
seenDay = false |
|
seenWeek = false |
|
seenMonth = true |
|
} |
|
dayEcharts() |
|
monthEcharts() |
|
weekEcharts() |
|
clearTrendTimer(); |
|
startTrendAutoSwitch(); |
|
}; |
|
|
|
const dutyResetTimer = () => { |
|
const width = tabsContainer.value.offsetWidth; |
|
chartWidth = width; |
|
clearDutyTimer(); |
|
startDutyAutoSwitch(); |
|
}; |
|
|
|
|
|
|
|
|
|
const changsMap = () => { |
|
echarts.registerMap("map", currentMapJSON.geometry as any); |
|
let myMap = echarts.init(map.value); |
|
//设置配置项 |
|
myMap.setOption({ |
|
geo: { |
|
// 是上面注册时的名字哦,registerMap('名字保持一致') |
|
map: "map", |
|
}, |
|
tooltip: { |
|
show: mapShow, |
|
trigger: 'item', |
|
position: 'right', |
|
formatter: function (params) { |
|
|
|
if (typeof params.data === 'undefined') { |
|
|
|
} else { |
|
var tt = '<div class="tooltip">' + |
|
'<div class="tooltip-title" > ' + params.name + '</div>' + |
|
'<div class="tooltip-content" >' + |
|
'<ul class="tooltip-ul">' + |
|
'<li>今日来信 <span>' + params.data.todaysum + '</span></li>' + |
|
'<li>来信总数 <span>' + params.data.allsum + '</span></li>' + |
|
'<li>办结总数 <span>' + params.data.completed + '</span></li>' + |
|
'<li>办结率 <span>' + params.data.completedrate + '</span></li>' + |
|
'<li>解决率 <span>' + params.data.resolvedrate + '</span></li>' + |
|
'<li>满意率 <span>' + params.data.satisfiedrate + '</span></li>' + |
|
' </ul></div></div>' |
|
return tt; |
|
} |
|
}, |
|
backgroundColor: '#031577', // |
|
borderColor: '#0A2F86', |
|
borderWidth: 0, // 设置边框宽度为1像素 |
|
borderRadius: 3, // 设置边框半径为3像素 |
|
shadowBlur: 0, // 设置阴影模糊程度为8像素 |
|
shadowOffsetX: 0, // 设置水平阴影位移量为0像素 |
|
shadowOffsetY: 0, // 设置垂直阴影位移量为6像素 |
|
|
|
}, |
|
visualMap: { |
|
type: 'piecewise', |
|
bottom: 10, |
|
pieces: [ |
|
{ gte: 85, lte: 100, label: '办结率高于85%' }, |
|
{ gte: 65, lte: 85, label: '办结率低于85%' }, |
|
{ gte: 0, lte: 65, label: '办结率低于65%' }, |
|
], |
|
// text: ['办结率'], |
|
right: 10, // 右边距 |
|
bottom: 10, // 底边距 |
|
realtime: false, |
|
orient: 'horizontal', // 水平显示 |
|
textStyle: { |
|
color: '#fff', // 文字颜色 |
|
}, |
|
calculable: true, |
|
inRange: { |
|
color: ['#D34343', '#F6A149', '#4987F6'] |
|
} |
|
}, |
|
series: [ |
|
{ |
|
name: '长沙', |
|
type: 'map', |
|
map: 'map', |
|
hoverAnimation: true, |
|
label: { |
|
show: true, |
|
color: "white", |
|
}, |
|
itemStyle: { |
|
normal: { |
|
areaColor: '#02215E' // 这里将地图区域的颜色修改为红色 |
|
} |
|
}, |
|
data: mapDataList, |
|
} |
|
] |
|
}); |
|
|
|
//switchRegion(); // 开始自动切换 |
|
|
|
} |
|
|
|
|
|
|
|
const switchRegion = () => { |
|
const chart = echarts.getInstanceByDom(map.value); |
|
const option = chart.getOption(); |
|
const mapSeriesIndex = option.series.findIndex((series) => series.type === 'map'); |
|
|
|
if (mapSeriesIndex >= 0) { |
|
const mapData = option.series[mapSeriesIndex].data; |
|
const regionCount = mapData.length; |
|
const prevIndex = currentIndex; |
|
currentIndex = (currentIndex + 1) % regionCount; |
|
|
|
|
|
//mapData[prevIndex].selected = false; // 取消上一个区域的选中状态 |
|
// mapData[currentIndex].selected = true; // 设置当前区域为选中状态 |
|
|
|
var hourIndex = 0; |
|
|
|
|
|
carouselTime = setInterval(() => { |
|
//dispatchAction echarts的API:触发图表行为 |
|
chart.dispatchAction({ |
|
type: "downplay", //downplay 取消高亮指定的数据图形 |
|
seriesIndex: 0 |
|
}); |
|
chart.dispatchAction({ |
|
type: "highlight", //highLight 高亮指定的数据图形 |
|
seriesIndex: 0, //系列index |
|
dataIndex: hourIndex //数据index |
|
}); |
|
chart.dispatchAction({ |
|
type: "showTip", //showTip 显示提示框 |
|
seriesIndex: 0, |
|
dataIndex: hourIndex |
|
}); |
|
hourIndex++; |
|
//当循环到数组当中的最后一条数据后,重新进行循环 |
|
if (hourIndex > mapData.length) { |
|
hourIndex = 0; |
|
} |
|
}, 3000); |
|
//鼠标移入组件时停止轮播 |
|
chart.on("mousemove", (e) => { |
|
clearInterval(carouselTime); //清除循环 |
|
chart.dispatchAction({ |
|
type: "downplay", |
|
seriesIndex: 0, |
|
}); |
|
chart.dispatchAction({ |
|
type: "highlight", |
|
seriesIndex: 0, |
|
dataIndex: e.dataIndex |
|
}); |
|
chart.dispatchAction({ |
|
type: "showTip", |
|
seriesIndex: 0, |
|
dataIndex: e.dataIndex |
|
}); |
|
}); |
|
//鼠标移出组件时恢复轮播 |
|
chart.on("mouseout", () => { |
|
carouselTime = setInterval(() => { |
|
chart.dispatchAction({ |
|
type: "downplay", |
|
seriesIndex: 0, |
|
|
|
}); |
|
chart.dispatchAction({ |
|
type: "highlight", |
|
seriesIndex: 0, |
|
dataIndex: hourIndex |
|
}); |
|
chart.dispatchAction({ |
|
type: "showTip", |
|
seriesIndex: 0, |
|
dataIndex: hourIndex |
|
}); |
|
hourIndex++; |
|
if (hourIndex > mapData.length) { |
|
hourIndex = 0; |
|
} |
|
}, 3000); |
|
}); |
|
chart.setOption(option); |
|
} |
|
}; |
|
|
|
const dayEcharts = () => { |
|
// 基于准备好的dom,初始化echarts实例 |
|
var myChart = echarts.init(day_echart.value); |
|
|
|
let option = { |
|
tooltip: { |
|
trigger: 'axis', |
|
axisPointer: { |
|
lineStyle: { |
|
color: '#dddc6b' |
|
} |
|
} |
|
}, |
|
legend: { |
|
top: '0%', |
|
right: '0%', |
|
data: ['信件数'], |
|
textStyle: { |
|
color: 'rgba(255,255,255,.5)', |
|
fontSize: '12', |
|
} |
|
}, |
|
grid: { |
|
left: '10', |
|
top: '30', |
|
right: '10', |
|
bottom: '10', |
|
containLabel: true |
|
}, |
|
|
|
xAxis: [{ |
|
type: 'category', |
|
boundaryGap: false, |
|
axisLabel: { |
|
textStyle: { |
|
color: "rgba(255,255,255,.6)", |
|
fontSize: 12, |
|
}, |
|
}, |
|
axisLine: { |
|
lineStyle: { |
|
color: 'rgba(255,255,255,.2)' |
|
} |
|
|
|
}, |
|
|
|
data: dayXList |
|
|
|
}, { |
|
|
|
axisPointer: { show: false }, |
|
axisLine: { show: false }, |
|
position: 'bottom', |
|
offset: 20, |
|
|
|
|
|
|
|
}], |
|
|
|
yAxis: [{ |
|
type: 'value', |
|
axisTick: { show: false }, |
|
axisLine: { |
|
lineStyle: { |
|
color: 'rgba(255,255,255,.1)' |
|
} |
|
}, |
|
axisLabel: { |
|
textStyle: { |
|
color: "rgba(255,255,255,.6)", |
|
fontSize: 12, |
|
}, |
|
}, |
|
|
|
splitLine: { |
|
lineStyle: { |
|
color: 'rgba(255,255,255,.1)' |
|
} |
|
} |
|
}], |
|
series: [ |
|
{ |
|
name: '信件数', |
|
type: 'line', |
|
smooth: true, |
|
symbol: 'circle', |
|
symbolSize: 5, |
|
showSymbol: false, |
|
lineStyle: { |
|
|
|
normal: { |
|
color: '#0184d5', |
|
width: 2 |
|
} |
|
}, |
|
areaStyle: { |
|
normal: { |
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ |
|
offset: 0, |
|
color: 'rgba(1, 132, 213, 0.4)' |
|
}, { |
|
offset: 0.8, |
|
color: 'rgba(1, 132, 213, 0.1)' |
|
}], false), |
|
shadowColor: 'rgba(0, 0, 0, 0.1)', |
|
} |
|
}, |
|
itemStyle: { |
|
normal: { |
|
color: '#0184d5', |
|
borderColor: 'rgba(221, 220, 107, .1)', |
|
borderWidth: 12 |
|
} |
|
}, |
|
data: dayYList |
|
|
|
} |
|
|
|
] |
|
|
|
}; |
|
|
|
// 使用刚指定的配置项和数据显示图表。 |
|
myChart.setOption(option); |
|
window.addEventListener("resize", function () { |
|
myChart.resize(chartWidth); |
|
}); |
|
} |
|
|
|
const monthEcharts = () => { |
|
// 基于准备好的dom,初始化echarts实例 |
|
var myChart = echarts.init(month_echart.value); |
|
let option1 = { |
|
tooltip: { |
|
trigger: 'axis', |
|
axisPointer: { |
|
lineStyle: { |
|
color: '#dddc6b' |
|
} |
|
} |
|
}, |
|
legend: { |
|
top: '0%', |
|
right: '0%', |
|
data: ['信件数'], |
|
textStyle: { |
|
color: 'rgba(255,255,255,.5)', |
|
fontSize: '12', |
|
} |
|
}, |
|
grid: { |
|
left: '10', |
|
top: '30', |
|
right: '10', |
|
bottom: '10', |
|
containLabel: true |
|
}, |
|
|
|
xAxis: [{ |
|
type: 'category', |
|
boundaryGap: false, |
|
axisLabel: { |
|
textStyle: { |
|
color: "rgba(255,255,255,.6)", |
|
fontSize: 12, |
|
}, |
|
}, |
|
axisLine: { |
|
lineStyle: { |
|
color: 'rgba(255,255,255,.2)' |
|
} |
|
|
|
}, |
|
|
|
data: monthXList |
|
|
|
}, { |
|
|
|
axisPointer: { show: false }, |
|
axisLine: { show: false }, |
|
position: 'bottom', |
|
offset: 20, |
|
|
|
|
|
|
|
}], |
|
|
|
yAxis: [{ |
|
type: 'value', |
|
axisTick: { show: false }, |
|
axisLine: { |
|
lineStyle: { |
|
color: 'rgba(255,255,255,.1)' |
|
} |
|
}, |
|
axisLabel: { |
|
textStyle: { |
|
color: "rgba(255,255,255,.6)", |
|
fontSize: 12, |
|
}, |
|
}, |
|
|
|
splitLine: { |
|
lineStyle: { |
|
color: 'rgba(255,255,255,.1)' |
|
} |
|
} |
|
}], |
|
series: [ |
|
{ |
|
name: '信件数', |
|
type: 'line', |
|
smooth: true, |
|
symbol: 'circle', |
|
symbolSize: 5, |
|
showSymbol: false, |
|
lineStyle: { |
|
|
|
normal: { |
|
color: '#0184d5', |
|
width: 2 |
|
} |
|
}, |
|
areaStyle: { |
|
normal: { |
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ |
|
offset: 0, |
|
color: 'rgba(1, 132, 213, 0.4)' |
|
}, { |
|
offset: 0.8, |
|
color: 'rgba(1, 132, 213, 0.1)' |
|
}], false), |
|
shadowColor: 'rgba(0, 0, 0, 0.1)', |
|
} |
|
}, |
|
itemStyle: { |
|
normal: { |
|
color: '#0184d5', |
|
borderColor: 'rgba(221, 220, 107, .1)', |
|
borderWidth: 12 |
|
} |
|
}, |
|
data: monthYList |
|
|
|
} |
|
|
|
] |
|
|
|
}; |
|
// 使用刚指定的配置项和数据显示图表。 |
|
myChart.setOption(option1); |
|
|
|
window.addEventListener("resize", function () { |
|
myChart.resize(chartWidth); |
|
}); |
|
} |
|
|
|
|
|
const weekEcharts = () => { |
|
// 基于准备好的dom,初始化echarts实例 |
|
var myChart = echarts.init(week_echart.value); |
|
let option1 = { |
|
tooltip: { |
|
trigger: 'axis', |
|
axisPointer: { |
|
lineStyle: { |
|
color: '#dddc6b' |
|
} |
|
} |
|
}, |
|
legend: { |
|
top: '0%', |
|
right: '0%', |
|
data: ['信件数'], |
|
textStyle: { |
|
color: 'rgba(255,255,255,.5)', |
|
fontSize: '12', |
|
} |
|
}, |
|
grid: { |
|
left: '10', |
|
top: '30', |
|
right: '10', |
|
bottom: '10', |
|
containLabel: true |
|
}, |
|
|
|
xAxis: [{ |
|
type: 'category', |
|
boundaryGap: false, |
|
axisLabel: { |
|
textStyle: { |
|
color: "rgba(255,255,255,.6)", |
|
fontSize: 12, |
|
}, |
|
}, |
|
axisLine: { |
|
lineStyle: { |
|
color: 'rgba(255,255,255,.2)' |
|
} |
|
|
|
}, |
|
|
|
data: weekXList |
|
|
|
}, { |
|
|
|
axisPointer: { show: false }, |
|
axisLine: { show: false }, |
|
position: 'bottom', |
|
offset: 20, |
|
|
|
|
|
|
|
}], |
|
|
|
yAxis: [{ |
|
type: 'value', |
|
axisTick: { show: false }, |
|
axisLine: { |
|
lineStyle: { |
|
color: 'rgba(255,255,255,.1)' |
|
} |
|
}, |
|
axisLabel: { |
|
textStyle: { |
|
color: "rgba(255,255,255,.6)", |
|
fontSize: 12, |
|
}, |
|
}, |
|
|
|
splitLine: { |
|
lineStyle: { |
|
color: 'rgba(255,255,255,.1)' |
|
} |
|
} |
|
}], |
|
series: [ |
|
{ |
|
name: '信件数', |
|
type: 'line', |
|
smooth: true, |
|
symbol: 'circle', |
|
symbolSize: 5, |
|
showSymbol: false, |
|
lineStyle: { |
|
|
|
normal: { |
|
color: '#0184d5', |
|
width: 2 |
|
} |
|
}, |
|
areaStyle: { |
|
normal: { |
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ |
|
offset: 0, |
|
color: 'rgba(1, 132, 213, 0.4)' |
|
}, { |
|
offset: 0.8, |
|
color: 'rgba(1, 132, 213, 0.1)' |
|
}], false), |
|
shadowColor: 'rgba(0, 0, 0, 0.1)', |
|
} |
|
}, |
|
itemStyle: { |
|
normal: { |
|
color: '#0184d5', |
|
borderColor: 'rgba(221, 220, 107, .1)', |
|
borderWidth: 12 |
|
} |
|
}, |
|
data: weekYList |
|
|
|
} |
|
|
|
] |
|
|
|
}; |
|
// 使用刚指定的配置项和数据显示图表。 |
|
myChart.setOption(option1); |
|
|
|
window.addEventListener("resize", function () { |
|
myChart.resize(chartWidth); |
|
}); |
|
} |
|
const queryDetails = async (data: any) => { |
|
mapShow = false |
|
changsMap() |
|
showDetails.value = true |
|
await nextTick() |
|
detailsRef.value?.open('details') |
|
detailsRef.value?.getDetail(data) |
|
} |
|
|
|
const closeDetails = () => { |
|
mapShow = true |
|
changsMap() |
|
showDetails.value = false |
|
} |
|
|
|
</script> |
|
<style lang="less"></style> |