Industrial-image-management.../src/views/enterprise-dashboard/overview/index.vue

267 lines
6.9 KiB
Vue

<template>
<div class="app-container">
<a-card class="general-card" title="企业数据概览" :bordered="false">
<a-row :gutter="16">
<a-col :span="6">
<a-card class="stat-card">
<a-statistic
title="项目总数"
:value="statistics.projectCount"
:precision="0"
style="margin-right: 50px"
>
<template #prefix>
<icon-file />
</template>
</a-statistic>
</a-card>
</a-col>
<a-col :span="6">
<a-card class="stat-card">
<a-statistic
title="成员总数"
:value="statistics.memberCount"
:precision="0"
>
<template #prefix>
<icon-user-group />
</template>
</a-statistic>
</a-card>
</a-col>
<a-col :span="6">
<a-card class="stat-card">
<a-statistic
title="设备总数"
:value="statistics.deviceCount"
:precision="0"
>
<template #prefix>
<icon-computer />
</template>
</a-statistic>
</a-card>
</a-col>
<a-col :span="6">
<a-card class="stat-card">
<a-statistic
title="本月完成项目"
:value="statistics.completedProjectCount"
:precision="0"
>
<template #prefix>
<icon-check-circle />
</template>
</a-statistic>
</a-card>
</a-col>
</a-row>
<a-divider />
<a-row :gutter="16">
<a-col :span="12">
<a-card title="项目进度统计" :bordered="false">
<div ref="projectProgressChart" style="height: 300px"></div>
</a-card>
</a-col>
<a-col :span="12">
<a-card title="资源使用情况" :bordered="false">
<div ref="resourceUsageChart" style="height: 300px"></div>
</a-card>
</a-col>
</a-row>
<a-divider />
<a-row :gutter="16">
<a-col :span="24">
<a-card title="近6个月业务趋势" :bordered="false">
<div ref="businessTrendChart" style="height: 300px"></div>
</a-card>
</a-col>
</a-row>
</a-card>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted, reactive, nextTick } from 'vue'
import { Statistic } from '@arco-design/web-vue'
import { IconFile, IconUserGroup, IconComputer, IconCheckCircle } from '@arco-design/web-vue/es/icon'
import * as echarts from 'echarts'
const projectProgressChart = ref(null)
const resourceUsageChart = ref(null)
const businessTrendChart = ref(null)
const statistics = reactive({
projectCount: 128,
memberCount: 356,
deviceCount: 243,
completedProjectCount: 15
})
onMounted(() => {
// 使用 nextTick 确保 DOM 已完全渲染
nextTick(() => {
// 初始化项目进度统计图表
if (projectProgressChart.value) {
const projectChart = echarts.init(projectProgressChart.value)
projectChart.setOption({
tooltip: {
trigger: 'item'
},
legend: {
orient: 'vertical',
left: 'left'
},
series: [
{
name: '项目状态',
type: 'pie',
radius: '70%',
data: [
{ value: 48, name: '进行中' },
{ value: 65, name: '已完成' },
{ value: 12, name: '已暂停' },
{ value: 3, name: '已取消' }
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
})
}
// 初始化资源使用情况图表
if (resourceUsageChart.value) {
const resourceChart = echarts.init(resourceUsageChart.value)
resourceChart.setOption({
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'value'
},
yAxis: {
type: 'category',
data: ['服务器', '存储空间', '带宽', '设备使用率', '人力资源']
},
series: [
{
name: '已使用',
type: 'bar',
stack: 'total',
label: {
show: true
},
emphasis: {
focus: 'series'
},
data: [65, 72, 58, 80, 75]
},
{
name: '剩余',
type: 'bar',
stack: 'total',
label: {
show: true
},
emphasis: {
focus: 'series'
},
data: [35, 28, 42, 20, 25]
}
]
})
}
// 初始化业务趋势图表
if (businessTrendChart.value) {
const businessChart = echarts.init(businessTrendChart.value)
businessChart.setOption({
tooltip: {
trigger: 'axis'
},
legend: {
data: ['项目数量', '营业收入', '新增客户']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['1月', '2月', '3月', '4月', '5月', '6月']
},
yAxis: {
type: 'value'
},
series: [
{
name: '项目数量',
type: 'line',
data: [10, 12, 15, 18, 22, 24]
},
{
name: '营业收入',
type: 'line',
data: [120, 132, 145, 160, 178, 190]
},
{
name: '新增客户',
type: 'line',
data: [5, 7, 8, 10, 12, 15]
}
]
})
}
// 监听窗口大小变化,调整图表大小
window.addEventListener('resize', () => {
if (projectProgressChart.value) {
const projectChart = echarts.getInstanceByDom(projectProgressChart.value)
projectChart?.resize()
}
if (resourceUsageChart.value) {
const resourceChart = echarts.getInstanceByDom(resourceUsageChart.value)
resourceChart?.resize()
}
if (businessTrendChart.value) {
const businessChart = echarts.getInstanceByDom(businessTrendChart.value)
businessChart?.resize()
}
})
})
})
</script>
<style scoped>
.general-card {
margin-bottom: 20px;
}
.stat-card {
margin-bottom: 20px;
text-align: center;
}
</style>