ZaiZai 1 year ago
parent
commit
2cfbd3e9b4

+ 11 - 1
src/components/echarts/echarts.vue

@@ -15,12 +15,15 @@ const props = defineProps({
     },
 })
 
+//事件
+const emit = defineEmits(['resize'])
+
 defineOptions({
     name: 'HcCharts',
 })
 
 //初始变量
-let chart = null
+let chart = null, iTime
 const echart = ref(null)
 
 //深度监听
@@ -39,11 +42,18 @@ const initChart = () => {
 //监听浏览器窗口变化
 const windowResize = () => {
     window.addEventListener('resize', resizeEvent)
+    nextTick(() => {
+        emit('resize', chart.getWidth())
+    })
 }
 
 const resizeEvent = () => {
     window.requestAnimationFrame(() => {
         chart.resize()
+        clearTimeout(iTime)
+        iTime = setTimeout(() => {
+            emit('resize', chart.getWidth())
+        }, 500)
     })
 }
 

+ 27 - 0
src/styles/home/home.scss

@@ -0,0 +1,27 @@
+.hc-home-chart-body {
+    .chart-title {
+        display: flex;
+        font-weight: 700;
+        font-size: 16px;
+        color: #1A1A1A;
+        img {
+            width: 44px;
+            height: 44px;
+        }
+        .title-body {
+            line-height: 2.1;
+            .text {
+                margin-left: 5px;
+                font-size: 14px;
+                color: #838791;
+            }
+        }
+    }
+    .chart-select {
+        margin-top: -10px;
+        .el-input__wrapper {
+            background-color: #F7F9FD;
+            border-radius: 64px;
+        }
+    }
+}

+ 123 - 3
src/views/home/index.vue

@@ -1,6 +1,54 @@
 <template>
     <hc-body scrollbar padding="12px">
         <HcAgentCharge :active="agentChargeIndex" @load="agentChargeLoad" />
+        <div class="hc-home-chart-body relative mt-5 h-[500px]">
+            <el-row :gutter="20" class="h-full">
+                <el-col :span="8" class="h-full">
+                    <hc-new-card>
+                        <template #header>
+                            <div class="chart-title">
+                                <img :src="frame001" alt="">
+                                <div class="title-body">
+                                    <span class="title">证书统计</span>
+                                    <span class="text">(总计{{ pfxAmountVal }}个)</span>
+                                </div>
+                            </div>
+                        </template>
+                        <HcChartPfx :datas="pfxLists" />
+                    </hc-new-card>
+                </el-col>
+                <el-col :span="8" class="h-full">
+                    <hc-new-card>
+                        <template #header>
+                            <div class="chart-title">
+                                <img :src="frame002" alt="">
+                                <div class="title-body">
+                                    <span class="title">人员账户统计</span>
+                                    <span class="text">(总计{{ personAmount }}个)</span>
+                                </div>
+                            </div>
+                        </template>
+                        <HcChartPerson :datas="personUsers" />
+                    </hc-new-card>
+                </el-col>
+                <el-col :span="8" class="h-full">
+                    <hc-new-card>
+                        <template #header>
+                            <div class="chart-title">
+                                <img :src="frame003" alt="">
+                                <div class="title-body">维护类型统计汇总</div>
+                            </div>
+                        </template>
+                        <template #extra>
+                            <el-select v-model="projectId" placeholder="请选择项目" size="small" class="chart-select" @change="selectProjectOpinion">
+                                <el-option v-for="item in projectList" :key="item.id" :label="item.projectName" :value="item.id" />
+                            </el-select>
+                        </template>
+                        <HcChartType :datas="userTypeList" />
+                    </hc-new-card>
+                </el-col>
+            </el-row>
+        </div>
     </hc-body>
 </template>
 
@@ -10,12 +58,15 @@ import HcAgentCharge from './modules/agent-charge.vue'
 import frame001 from '~src/assets/home/Frame001.png'
 import frame002 from '~src/assets/home/Frame002.png'
 import frame003 from '~src/assets/home/Frame003.png'
+import HcChartPfx from './modules/chart-pfx.vue'
+import HcChartPerson from './modules/chart-person.vue'
+import HcChartType from './modules/chart-type.vue'
 import { getArrValue, getObjValue } from 'js-fast-way'
 import mainApi from '~api/home/index'
 
 //激活
 onActivated(() => {
-
+    getChartData()
 })
 
 //工单类型
@@ -72,8 +123,77 @@ const queryBusinessUserOpinionAll = async () => {
     agentChargeTags.value.tag2 = allToDoNumber ?? 0
     agentChargeData.value = getArrValue(userOpinionFlowList)
 }
-</script>
 
-<style lang="scss" scoped>
+//获取图表数据
+const getChartData = () => {
+    queryProjectPfx()
+    queryProjectUserAmount()
+    queryOpinionTypeAmount()
+}
+
+//证书统计
+const pfxAmountVal = ref('0')
+const pfxLists = ref([])
+const queryProjectPfx = async () => {
+    const { data } = await mainApi.queryProjectPfx()
+    const { pfxList, pfxAmount } = getObjValue(data)
+    pfxAmountVal.value = pfxAmount ?? '0'
+    pfxLists.value = getArrValue(pfxList)
+}
+
+//人员账户统计
+const personAmount = ref('0')
+const personUsers = ref([])
+const queryProjectUserAmount = async () => {
+    const { data } = await mainApi.queryProjectUserAmount()
+    const { projectUserAmountVOList, projectUserAmount } = getObjValue(data)
+    pfxAmountVal.value = projectUserAmount ?? '0'
+    personUsers.value = getArrValue(projectUserAmountVOList)
+}
+
+//项目ID
+const projectId = ref(null)
+const projectList = ref([])
+const queryOpinionTypeAmount = async () => {
+    const { data } = await mainApi.queryOpinionTypeAmount()
+    const { userOpinionList, projectInfos } = getObjValue(data)
+    const userOpinionTypeList = getArrValue(userOpinionList)
+    projectList.value = getArrValue(projectInfos)
+    userOpinionTypeLists.value = getArrValue(userOpinionTypeList)
+    //处理数据
+    if (userOpinionTypeList.length > 0) {
+        setUserTypeList(userOpinionTypeList[0])
+        projectId.value = userOpinionTypeList[0].projectId ?? null
+    } else {
+        projectId.value = null
+    }
+}
+
+//项目被选择
+const userOpinionTypeLists = ref([])
+const selectProjectOpinion = () => {
+    const list = userOpinionTypeLists.value
+    for (let i = 0; i < list.length; i++) {
+        if (list[i].projectId === projectId.value) {
+            setUserTypeList(list[i])
+        }
+    }
+}
+
+//设置项目图表
+const userTypeList = ref([])
+const setUserTypeList = ({ problemType, problemTypeAmount }) => {
+    let newArr = []
+    for (let i = 0; i < problemType.length; i++) {
+        newArr.push({
+            value: problemTypeAmount[i],
+            name: problemType[i],
+        })
+    }
+    userTypeList.value = newArr
+}
+</script>
 
+<style lang="scss">
+@import '~src/styles/home/home';
 </style>

+ 83 - 0
src/views/home/modules/chart-person.vue

@@ -0,0 +1,83 @@
+<template>
+    <hc-charts :option="setOption" />
+</template>
+
+<script setup>
+import { nextTick, onMounted, ref, watch } from 'vue'
+
+const props = defineProps({
+    datas: {
+        type: Array,
+        default: () => ([]),
+    },
+})
+
+//初始变量
+const setOption = ref({})
+
+//深度监听数据变化
+const datas = ref(props.datas)
+watch(() => props.datas, (data) => {
+    datas.value = data
+    setDataFormat()
+}, { deep: true })
+
+//处理数据
+const setDataFormat = () => {
+    let data = datas.value, names = []
+    for (let i = 0; i < data.length; i++) {
+        const { projectName, contractor, supervision, owner } = data[i]
+        if (projectName) {
+            names.push([projectName, contractor ? contractor : 0, supervision ? supervision : 0, owner ? owner : 0])
+        }
+    }
+    setOptions(names)
+}
+
+//设置图表
+const setOptions = (datas = []) => {
+    setOption.value = {
+        color: ['#5B8FF9', '#5AD8A6', '#5D7092'],
+        legend: {},
+        tooltip: {
+            trigger: 'axis',
+            axisPointer: {
+                type: 'cross',
+            },
+        },
+        dataset: {
+            source: [
+                ['product', '施工方', '监理方', '指挥部'],
+                ...datas,
+            ],
+        },
+        grid: {
+            top: '20px',
+            left: '0',
+            right: '4px',
+            bottom: '0',
+            containLabel: true,
+        },
+        xAxis: {
+            type: 'category',
+            axisLabel: {
+                overflow: 'breakAll',
+                interval: 0,
+                rotate: -50,
+                formatter: function (value) {
+                    return value.length > 5 ? value.slice(0, 3) + '...' : value
+                },
+            },
+        },
+        yAxis: {},
+        series: [{ type: 'bar' }, { type: 'bar' }, { type: 'bar' }],
+    }
+}
+
+//渲染完成
+onMounted(() => {
+    nextTick(() => {
+        setDataFormat()
+    })
+})
+</script>

+ 104 - 0
src/views/home/modules/chart-pfx.vue

@@ -0,0 +1,104 @@
+<template>
+    <hc-charts :option="setOption" />
+</template>
+
+<script setup>
+import { nextTick, onMounted, ref, watch } from 'vue'
+
+const props = defineProps({
+    datas: {
+        type: Array,
+        default: () => ([]),
+    },
+})
+
+//初始变量
+const setOption = ref({})
+
+//深度监听数据变化
+const datas = ref(props.datas)
+watch(() => props.datas, (data) => {
+    datas.value = data
+    setDataFormat()
+}, { deep: true })
+
+//处理数据
+const setDataFormat = () => {
+    const data = datas.value
+    let names = [], personalCount = [], enterpriseCount = []
+    for (let i = 0; i < data.length; i++) {
+        const item = data[i]
+        if (item.projectName) {
+            names.push(item.projectName)
+            personalCount.push(item.personalCount ? item.personalCount : '0')
+            enterpriseCount.push(item.enterpriseCount ? item.enterpriseCount : '0')
+        }
+    }
+    setOptions(names, personalCount, enterpriseCount)
+}
+
+//设置图表
+const setOptions = (names = [], personalCount = [], enterpriseCount = []) => {
+    setOption.value = {
+        color: ['#5B8FF9', '#5AD8A6'],
+        tooltip: {
+            trigger: 'axis',
+            axisPointer: {
+                type: 'cross',
+            },
+        },
+        legend: {
+            data: ['个人证书', '企业证书'],
+        },
+        grid: {
+            top: '40px',
+            left: '0',
+            right: '10px',
+            bottom: '0',
+            containLabel: true,
+        },
+        xAxis: [
+            {
+                type: 'category',
+                axisLabel: {
+                    overflow: 'breakAll',
+                    interval: 0,
+                    rotate: -50,
+                    formatter: function (value) {
+                        return value.length > 5 ? value.slice(0, 3) + '...' : value
+                    },
+                },
+                boundaryGap: false,
+                data: names,
+            },
+        ],
+        yAxis: [
+            {
+                type: 'value',
+                interval: 30,
+            },
+        ],
+        series: [
+            {
+                name: '个人证书',
+                type: 'line',
+                areaStyle: {},
+                data: personalCount,
+            },
+            {
+                name: '企业证书',
+                type: 'line',
+                areaStyle: {},
+                data: enterpriseCount,
+            },
+        ],
+    }
+}
+
+//渲染完成
+onMounted(() => {
+    nextTick(() => {
+        setDataFormat()
+    })
+})
+</script>

+ 61 - 0
src/views/home/modules/chart-type.vue

@@ -0,0 +1,61 @@
+<template>
+    <hc-charts :option="setOption" />
+</template>
+
+<script setup>
+import { nextTick, onMounted, ref, watch } from 'vue'
+
+const props = defineProps({
+    datas: {
+        type: Array,
+        default: () => ([]),
+    },
+})
+
+//初始变量
+const setOption = ref({})
+
+//深度监听数据变化
+const datas = ref(props.datas)
+watch(() => props.datas, (data) => {
+    datas.value = data
+    setDataFormat()
+}, { deep: true })
+
+//处理数据
+const setDataFormat = () => {
+    setOptions(datas.value)
+}
+
+//设置图表
+const setOptions = (datas = []) => {
+    setOption.value = {
+        color: ['#5B8FF9', '#5AD8A6', '#5D7092'],
+        tooltip: {
+            trigger: 'item',
+        },
+        grid: {
+            top: '20px',
+            left: '0',
+            right: '4px',
+            bottom: '0',
+            containLabel: true,
+        },
+        legend: {},
+        series: [
+            {
+                type: 'pie',
+                radius: '60%',
+                data: datas,
+            },
+        ],
+    }
+}
+
+//渲染完成
+onMounted(() => {
+    nextTick(() => {
+        setDataFormat()
+    })
+})
+</script>