|
@@ -0,0 +1,202 @@
|
|
|
+<template>
|
|
|
+ <div class="left-center">
|
|
|
+ <div class="left-center-title flex items-center">
|
|
|
+ <img src="@/assets/img/home/title_arrow.png" alt="">
|
|
|
+ 受理类型办件分析
|
|
|
+ </div>
|
|
|
+ <div class="left-center-content">
|
|
|
+ <template v-if="xData.length">
|
|
|
+ <v-chart class="chart" :option="option" :loading="loading" :loading-options="loadingOptions"/>
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <EmptyCom></EmptyCom>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+<script setup lang="ts">
|
|
|
+import {ref, onMounted, watch} from "vue";
|
|
|
+import {acceptType} from "@/api/home";
|
|
|
+import dayjs from "dayjs";
|
|
|
+import EmptyCom from "@/components/empty-com";
|
|
|
+import {loadingOptions} from "@/utils/constants";
|
|
|
+
|
|
|
+const props = defineProps({
|
|
|
+ dateArray: {
|
|
|
+ type: Array,
|
|
|
+ default: () => []
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+const date = ref([]);
|
|
|
+watch(() => props.dateArray, (val: any) => {
|
|
|
+ date.value = val;
|
|
|
+}, {immediate: true})
|
|
|
+
|
|
|
+watch(() => props.dateArray, (val: any) => {
|
|
|
+ getData();
|
|
|
+})
|
|
|
+
|
|
|
+
|
|
|
+const option = ref({});
|
|
|
+const xData = ref([]);
|
|
|
+const loading = ref(true);
|
|
|
+const getData = async () => {
|
|
|
+ loading.value = true;
|
|
|
+ try {
|
|
|
+ const {result} = await acceptType({StartDate: dayjs(date.value[0]).format('YYYY-MM-DD'), EndDate: dayjs(date.value[1]).format('YYYY-MM-DD')});
|
|
|
+ xData.value = result.map((item: any) => item.acceptType);
|
|
|
+ const totalData = result.reduce((pre: any, cur: any) => {
|
|
|
+ pre.push(cur.sumCount);
|
|
|
+ return pre;
|
|
|
+ }, []);
|
|
|
+ const handlingCount = result.reduce((pre: any, cur: any) => {
|
|
|
+ pre.push(cur.handlingCount);
|
|
|
+ return pre;
|
|
|
+ }, []);
|
|
|
+ const filedCount = result.reduce((pre: any, cur: any) => {
|
|
|
+ pre.push(cur.filedCount);
|
|
|
+ return pre;
|
|
|
+ }, []);
|
|
|
+ const overTimeCount = result.reduce((pre: any, cur: any) => {
|
|
|
+ pre.push(cur.overTimeCount);
|
|
|
+ return pre;
|
|
|
+ }, []);
|
|
|
+ // mock 数据
|
|
|
+ let dataArr = {
|
|
|
+ xData: xData.value,
|
|
|
+ result: [
|
|
|
+ {name: '总数', data: totalData},
|
|
|
+ {name: '已办', data: handlingCount},
|
|
|
+ {name: '在办', data: filedCount},
|
|
|
+ {name: '超期', data: overTimeCount},
|
|
|
+ ],
|
|
|
+ series: []
|
|
|
+ }
|
|
|
+ const diamondData = dataArr.result.reduce((pre, cur, index) => {
|
|
|
+ pre[index] = cur.data.map((el, id) => el + (pre[index - 1] ? pre[index - 1][id] : 0))
|
|
|
+ return pre
|
|
|
+ }, [])
|
|
|
+ const color = [
|
|
|
+ [{offset: 0, color: "#efff37",}, {offset: 1, color: "#d5e700",}],
|
|
|
+ [{offset: 0, color: "#32ffee",}, {offset: 1, color: "#00e8d5",}],
|
|
|
+ [{offset: 0, color: "#46c9ff",}, {offset: 1, color: "#00b4ff",}],
|
|
|
+ [{offset: 0, color: "#54a0ff",}, {offset: 1, color: "#1f83ff",}],
|
|
|
+ ]
|
|
|
+
|
|
|
+ dataArr.series = dataArr.result.reduce((p, c, i, array) => {
|
|
|
+ p.push({
|
|
|
+ z: i + 1,
|
|
|
+ stack: true,
|
|
|
+ type: 'bar',
|
|
|
+ name: c.name,
|
|
|
+ barWidth: 15,
|
|
|
+ data: c.data,
|
|
|
+ itemStyle: {
|
|
|
+ color:
|
|
|
+ {type: 'linear', x: 0, x2: 0, y: 0, y2: 1, colorStops: color[i]}
|
|
|
+ },
|
|
|
+ }, {
|
|
|
+ z: i + 10,
|
|
|
+ name: c.name,
|
|
|
+ type: 'pictorialBar',
|
|
|
+ symbolPosition: 'end',
|
|
|
+ symbol: 'circle',
|
|
|
+ symbolOffset: [0, '-50%'],
|
|
|
+ symbolSize: [15, 12.5],
|
|
|
+ data: diamondData[i],
|
|
|
+ itemStyle: {
|
|
|
+ color: color[i + 1] ? color[i + 1][0].color : null
|
|
|
+ },
|
|
|
+ tooltip: {show: false},
|
|
|
+ })
|
|
|
+
|
|
|
+ return p
|
|
|
+ }, [])
|
|
|
+
|
|
|
+
|
|
|
+// 最上边顶
|
|
|
+ dataArr.series.push({
|
|
|
+ name: dataArr.result[dataArr.result.length - 1].name,
|
|
|
+ z: 20,
|
|
|
+ type: "pictorialBar",
|
|
|
+ symbolPosition: "end",
|
|
|
+ data: diamondData[diamondData.length - 1],
|
|
|
+ symbol: "circle",
|
|
|
+ symbolOffset: ["0%", "-50%"],
|
|
|
+ symbolSize: [15, 12.5],
|
|
|
+ itemStyle: {
|
|
|
+ color: color[color.length - 1][0].color
|
|
|
+ },
|
|
|
+ tooltip: {show: false},
|
|
|
+ })
|
|
|
+
|
|
|
+// 最下边底
|
|
|
+ dataArr.series.push({
|
|
|
+ name: dataArr.result[0].name,
|
|
|
+ z: 30,
|
|
|
+ type: "pictorialBar",
|
|
|
+ symbolPosition: "start",
|
|
|
+ data: diamondData[0],
|
|
|
+ symbol: "circle",
|
|
|
+ symbolOffset: ["0%", "50%"],
|
|
|
+ symbolSize: [15, 12.5],
|
|
|
+ itemStyle: {
|
|
|
+ color: color[0][0].color
|
|
|
+ },
|
|
|
+ tooltip: {show: false},
|
|
|
+ })
|
|
|
+ setOption(dataArr);
|
|
|
+ loading.value = false;
|
|
|
+ } catch (e) {
|
|
|
+ console.log(e);
|
|
|
+ loading.value = false;
|
|
|
+ }
|
|
|
+};
|
|
|
+const setOption = (data: any) => {
|
|
|
+ option.value = {
|
|
|
+ tooltip: {trigger: "axis", backgroundColor: "rgba(0,0,0,0.7)", borderColor: "#000", borderWidth: 1, textStyle: {color: "#fff"}},
|
|
|
+ xAxis: {
|
|
|
+ axisTick: {show: true},
|
|
|
+ axisLine: {lineStyle: {color: 'rgba(255,255,255, .2)'}},
|
|
|
+ axisLabel: {fontSize: 12, color: '#fff'},
|
|
|
+ data: data.xData
|
|
|
+ },
|
|
|
+ yAxis: [{
|
|
|
+ name: '单位:件',
|
|
|
+ nameTextStyle: {color: '#fff', fontSize: 14},
|
|
|
+ nameGap: 25,
|
|
|
+ splitLine: {lineStyle: {color: 'rgba(255,255,255, .05)'}},
|
|
|
+ axisLine: {show: false,},
|
|
|
+ axisLabel: {fontSize: 12, color: '#fff'}
|
|
|
+ }],
|
|
|
+ grid: {top: '20%', left: '10%', right: '3%', bottom: '10%'},
|
|
|
+ legend: {
|
|
|
+ data: data.result.map(item => item.name),
|
|
|
+ textStyle: {fontSize: 12, color: '#fff'},
|
|
|
+ itemWidth: 15,
|
|
|
+ itemHeight: 10,
|
|
|
+ top: '10%',
|
|
|
+ right: '20'
|
|
|
+ },
|
|
|
+ series: data.series
|
|
|
+ };
|
|
|
+};
|
|
|
+onMounted(() => {
|
|
|
+ getData();
|
|
|
+});
|
|
|
+</script>
|
|
|
+<style scoped lang="scss">
|
|
|
+.left-center {
|
|
|
+ padding: 0 30px;
|
|
|
+
|
|
|
+ &-title {
|
|
|
+ font-size: 20px;
|
|
|
+ color: #fff;
|
|
|
+ }
|
|
|
+
|
|
|
+ .left-center-content {
|
|
|
+ height: calc(100% - 30px);
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|