数据看板优化
This commit is contained in:
@@ -3,6 +3,9 @@
|
||||
<!-- 顶部标题栏 -->
|
||||
<div class="header-container">
|
||||
<div class="header-left">
|
||||
<el-icon class="back-arrow" @click="returnToHeadquarters">
|
||||
<ArrowLeft />
|
||||
</el-icon>
|
||||
<div class="back-button" @click="openRegionSelector">
|
||||
{{ selectedPark || selectedRegion }}
|
||||
<span>···</span>
|
||||
@@ -138,9 +141,9 @@
|
||||
<el-button type="text" class="manage-btn">管理</el-button>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<div class="high-risk-content">
|
||||
<div class="high-risk-top">
|
||||
<div class="donut-chart-wrapper-small">
|
||||
<Echart :options="highRiskChartOption" width="100%" height="180px" />
|
||||
<Echart :options="highRiskChartOption" width="100%" height="250px" />
|
||||
</div>
|
||||
<div class="operation-type-list">
|
||||
<div class="operation-type-item" v-for="item in operationTypeDistribution" :key="item.type">
|
||||
@@ -174,9 +177,9 @@
|
||||
<el-button type="text" class="manage-btn">管理</el-button>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<div class="emergency-plan-content">
|
||||
<div class="emergency-plan-top">
|
||||
<div class="progress-chart-wrapper">
|
||||
<Echart :options="emergencyPlanChartOption" width="100%" height="180px" />
|
||||
<Echart :options="emergencyPlanChartOption" width="100%" height="250px" />
|
||||
</div>
|
||||
<div class="drill-info">
|
||||
<div class="drill-item">
|
||||
@@ -243,7 +246,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { Refresh } from '@element-plus/icons-vue'
|
||||
import { Refresh, ArrowLeft } from '@element-plus/icons-vue'
|
||||
import Echart from '@/components/Echart/src/Echart.vue'
|
||||
import RegionSelector from '@/views/screen/components/RegionSelector.vue'
|
||||
import { getTableList } from '@/api/design/report'
|
||||
@@ -262,6 +265,8 @@ interface RegionItem {
|
||||
interface DistributionItem {
|
||||
region?: string
|
||||
park?: string
|
||||
level?: string
|
||||
type?: string
|
||||
count: number
|
||||
percent?: string
|
||||
color: string
|
||||
@@ -323,7 +328,11 @@ const emergencyPlanCompleted = ref<number>(0)
|
||||
const parkDrillProgress = ref<DistributionItem[]>([])
|
||||
|
||||
// 安全培训数据
|
||||
const trainingChartData = ref<any>({})
|
||||
const trainingBarData = ref<{ regions: string[]; trainingCount: number[]; participants: number[] }>({
|
||||
regions: [],
|
||||
trainingCount: [],
|
||||
participants: []
|
||||
})
|
||||
const parkTrainingProgress = ref<DistributionItem[]>([])
|
||||
|
||||
// 区域颜色配置
|
||||
@@ -366,6 +375,13 @@ const initRegionData = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 返回总部页面
|
||||
const returnToHeadquarters = () => {
|
||||
router.push({
|
||||
path: '/index'
|
||||
})
|
||||
}
|
||||
|
||||
// 打开区域选择器
|
||||
const openRegionSelector = (): void => {
|
||||
regionSelectorVisible.value = true
|
||||
@@ -375,7 +391,7 @@ const openRegionSelector = (): void => {
|
||||
const onRegionChange = (item: RegionItem): void => {
|
||||
selectedPark.value = item.name
|
||||
router.push({
|
||||
path: '/home/park',
|
||||
path: '/park',
|
||||
query: { region: selectedRegion.value, regionCode: route.query.regionCode, park: item.name, parkCode: item.code }
|
||||
})
|
||||
}
|
||||
@@ -487,9 +503,9 @@ const initHighRiskData = async () => {
|
||||
]
|
||||
|
||||
parkOperationDistribution.value = [
|
||||
{ park: '雄安园区', count: 42 },
|
||||
{ park: '重庆园区', count: 31 },
|
||||
{ park: '北京园区', count: 21 }
|
||||
{ park: '雄安园区', count: 42, color: '#3b82f6' },
|
||||
{ park: '重庆园区', count: 31, color: '#8b5cf6' },
|
||||
{ park: '北京园区', count: 21, color: '#06b6d4' }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -499,25 +515,25 @@ const initEmergencyPlanData = async () => {
|
||||
emergencyPlanTotal.value = 36
|
||||
emergencyPlanCompleted.value = 28
|
||||
parkDrillProgress.value = [
|
||||
{ park: '雄安园区', percent: '85%', color: '#10b981' },
|
||||
{ park: '重庆园区', percent: '78%', color: '#10b981' },
|
||||
{ park: '北京园区', percent: '70%', color: '#10b981' }
|
||||
{ park: '雄安园区', percent: '85%', color: '#10b981', count: 0 },
|
||||
{ park: '重庆园区', percent: '78%', color: '#10b981', count: 0 },
|
||||
{ park: '北京园区', percent: '70%', color: '#10b981', count: 0 }
|
||||
]
|
||||
}
|
||||
|
||||
// 初始化安全培训数据
|
||||
const initSafetyTrainingData = async () => {
|
||||
// TODO: 调用安全培训API
|
||||
trainingChartData.value = {
|
||||
parks: ['雄安', '重庆', '北京'],
|
||||
trainingCount: [12, 10, 8],
|
||||
participants: [25, 15, 12]
|
||||
trainingBarData.value = {
|
||||
regions: ['雄安园区', '重庆园区', '北京园区'],
|
||||
trainingCount: [25, 15, 12],
|
||||
participants: [12, 10, 8]
|
||||
}
|
||||
|
||||
|
||||
parkTrainingProgress.value = [
|
||||
{ park: '雄安园区', percent: '92%', color: '#8b5cf6' },
|
||||
{ park: '重庆园区', percent: '88%', color: '#8b5cf6' },
|
||||
{ park: '北京园区', percent: '85%', color: '#8b5cf6' }
|
||||
{ park: '雄安园区', percent: '92%', color: '#8b5cf6', count: 0 },
|
||||
{ park: '重庆园区', percent: '88%', color: '#8b5cf6', count: 0 },
|
||||
{ park: '北京园区', percent: '85%', color: '#8b5cf6', count: 0 }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -651,19 +667,19 @@ const highRiskChartOption = computed<EChartsOption>(() => {
|
||||
series: [{
|
||||
name: '高危作业',
|
||||
type: 'pie',
|
||||
radius: ['55%', '75%'],
|
||||
center: ['50%', '50%'],
|
||||
radius: ['60%', '75%'],
|
||||
center: ['50%', '45%'],
|
||||
avoidLabelOverlap: false,
|
||||
itemStyle: { borderRadius: 0, borderColor: 'transparent', borderWidth: 0 },
|
||||
label: {
|
||||
show: true,
|
||||
position: 'center',
|
||||
formatter: () => `${highRiskTotal.value}\n本月作业`,
|
||||
fontSize: 16,
|
||||
fontSize: 18,
|
||||
fontWeight: 'bold',
|
||||
color: '#333'
|
||||
},
|
||||
emphasis: { label: { show: true, fontSize: 18, fontWeight: 'bold' } },
|
||||
emphasis: { label: { show: true, fontSize: 20, fontWeight: 'bold' } },
|
||||
data: operationTypeDistribution.value.map(item => ({
|
||||
value: item.count,
|
||||
name: item.type,
|
||||
@@ -684,15 +700,15 @@ const emergencyPlanChartOption = computed<EChartsOption>(() => {
|
||||
series: [{
|
||||
name: '演练完成率',
|
||||
type: 'pie',
|
||||
radius: ['55%', '75%'],
|
||||
center: ['50%', '50%'],
|
||||
radius: ['60%', '75%'],
|
||||
center: ['50%', '45%'],
|
||||
avoidLabelOverlap: false,
|
||||
itemStyle: { borderRadius: 0, borderColor: 'transparent', borderWidth: 0, color: '#10b981' },
|
||||
label: {
|
||||
show: true,
|
||||
position: 'center',
|
||||
formatter: () => `${percent}%\n演练完成率`,
|
||||
fontSize: 16,
|
||||
fontSize: 18,
|
||||
fontWeight: 'bold',
|
||||
color: '#333'
|
||||
},
|
||||
@@ -712,24 +728,33 @@ const safetyTrainingChartOption = computed<EChartsOption>(() => {
|
||||
data: ['培训次数', '参与人次'],
|
||||
top: 10
|
||||
},
|
||||
grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
|
||||
grid: { left: '6%', right: '4%', bottom: '8%', containLabel: true },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: trainingChartData.value.parks || []
|
||||
data: trainingBarData.value.regions,
|
||||
axisLine: { lineStyle: { color: '#d1d5db' } }
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisLine: { lineStyle: { color: '#d1d5db' } },
|
||||
splitLine: { lineStyle: { color: '#f3f4f6' } }
|
||||
},
|
||||
yAxis: { type: 'value' },
|
||||
series: [
|
||||
{
|
||||
name: '培训次数',
|
||||
type: 'bar',
|
||||
data: trainingChartData.value.trainingCount || [],
|
||||
itemStyle: { color: '#8b5cf6' }
|
||||
data: trainingBarData.value.trainingCount,
|
||||
barWidth: 24,
|
||||
itemStyle: { color: '#8b5cf6' },
|
||||
label: { show: true, position: 'insideBottom', color: '#fff' }
|
||||
},
|
||||
{
|
||||
name: '参与人次',
|
||||
type: 'bar',
|
||||
data: trainingChartData.value.participants || [],
|
||||
itemStyle: { color: '#3b82f6' }
|
||||
data: trainingBarData.value.participants,
|
||||
barWidth: 24,
|
||||
itemStyle: { color: '#c4b5fd' },
|
||||
label: { show: true, position: 'top', color: '#7c3aed' }
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -774,7 +799,19 @@ onMounted(() => {
|
||||
.header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.back-arrow {
|
||||
font-size: 20px;
|
||||
color: #3b82f6;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
color: #2563eb;
|
||||
transform: translateX(-2px);
|
||||
}
|
||||
}
|
||||
|
||||
.back-button {
|
||||
@@ -981,17 +1018,27 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
.high-risk-content {
|
||||
.high-risk-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.donut-chart-wrapper-small {
|
||||
flex: 1.5;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.operation-type-list {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
gap: 8px;
|
||||
min-width: 0;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.operation-type-item {
|
||||
@@ -1001,8 +1048,8 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
.operation-name {
|
||||
width: 80px;
|
||||
font-size: 13px;
|
||||
width: 70px;
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
@@ -1020,27 +1067,37 @@ onMounted(() => {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.emergency-plan-content {
|
||||
.emergency-plan-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.progress-chart-wrapper {
|
||||
flex: 1.5;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.drill-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
gap: 8px;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.drill-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
padding: 8px 10px;
|
||||
background-color: #f0fdf4;
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user