风险管理
This commit is contained in:
@@ -2,12 +2,17 @@
|
||||
<div class="dashboard-container">
|
||||
<!-- 顶部标题栏 -->
|
||||
<div class="header-container">
|
||||
<div class="header-left">
|
||||
<div class="back-button" @click="openRegionSelector">
|
||||
{{ currentView }}
|
||||
<span>···</span>
|
||||
</div>
|
||||
</div>
|
||||
<HeaderSelector
|
||||
back-button-type="none"
|
||||
:show-back-button="false"
|
||||
:display-text="currentView"
|
||||
:clickable="true"
|
||||
:show-selector-indicator="true"
|
||||
selector-type="region"
|
||||
:selected-value="selectedRegion"
|
||||
theme="light"
|
||||
@selector-change="onRegionChange"
|
||||
/>
|
||||
<!-- <h1 class="header-title">集团视角数据看板</h1> -->
|
||||
<div class="header-right">
|
||||
<div class="date-range-wrapper">
|
||||
@@ -293,9 +298,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 区域选择弹窗 -->
|
||||
<RegionSelector v-model="regionSelectorVisible" :modelSelected="selectedRegion" :regions="regionOption"
|
||||
@change="onRegionChange" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -304,7 +306,7 @@ import { ref, computed, onMounted } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { Refresh } from '@element-plus/icons-vue'
|
||||
import Echart from '@/components/Echart/src/Echart.vue'
|
||||
import RegionSelector from '@/views/screen/components/RegionSelector.vue'
|
||||
import HeaderSelector from '@/views/screen/components/HeaderSelector.vue'
|
||||
import { getTableList } from '@/api/design/report'
|
||||
import type { EChartsOption } from 'echarts'
|
||||
import dayjs from 'dayjs'
|
||||
@@ -349,9 +351,7 @@ const route = useRoute()
|
||||
|
||||
// 区域选择相关
|
||||
const currentView = ref('集团')
|
||||
const regionSelectorVisible = ref(false)
|
||||
const selectedRegion = ref('')
|
||||
const regionOption = ref<RegionItem[]>([])
|
||||
|
||||
// 时间选择相关 - 默认当前月起止,如果路由中有日期范围参数则使用
|
||||
const getCurrentMonthRange = () => {
|
||||
@@ -523,6 +523,21 @@ const outsourcingChartOption = computed<EChartsOption>(() => {
|
||||
trigger: 'item',
|
||||
formatter: '{a} <br/>{b}: {c} ({d}%)'
|
||||
},
|
||||
graphic: [
|
||||
{
|
||||
type: 'text',
|
||||
left: 'center',
|
||||
top: 'center',
|
||||
style: {
|
||||
text: `${outsourcingTotal.value}\n外协人员总数`,
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
fill: '#333',
|
||||
textAlign: 'center',
|
||||
textVerticalAlign: 'middle'
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '外协人员',
|
||||
@@ -536,14 +551,7 @@ const outsourcingChartOption = computed<EChartsOption>(() => {
|
||||
borderWidth: 0
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
position: 'center',
|
||||
formatter: () => {
|
||||
return `${outsourcingTotal.value}\n外协人员总数`
|
||||
},
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
color: '#333'
|
||||
show: false
|
||||
},
|
||||
data: [
|
||||
{ value: 1, name: '暂无数据', itemStyle: { color: '#e5e7eb' } }
|
||||
@@ -558,6 +566,21 @@ const outsourcingChartOption = computed<EChartsOption>(() => {
|
||||
trigger: 'item',
|
||||
formatter: '{a} <br/>{b}: {c} ({d}%)'
|
||||
},
|
||||
graphic: [
|
||||
{
|
||||
type: 'text',
|
||||
left: 'center',
|
||||
top: 'center',
|
||||
style: {
|
||||
text: `${outsourcingTotal.value}\n外协人员总数`,
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
fill: '#333',
|
||||
textAlign: 'center',
|
||||
textVerticalAlign: 'middle'
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '外协人员',
|
||||
@@ -571,19 +594,12 @@ const outsourcingChartOption = computed<EChartsOption>(() => {
|
||||
borderWidth: 0
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
position: 'center',
|
||||
formatter: () => {
|
||||
return `${outsourcingTotal.value}\n外协人员总数`
|
||||
},
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
color: '#333'
|
||||
show: false
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true,
|
||||
fontSize: 18,
|
||||
fontSize: 14,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
@@ -595,40 +611,29 @@ const outsourcingChartOption = computed<EChartsOption>(() => {
|
||||
|
||||
// 风险管理环形图配置
|
||||
const riskChartOption = computed<EChartsOption>(() => {
|
||||
const chartData = riskDistribution.value
|
||||
.filter(item => item.count > 0) // 只显示有数据的风险等级
|
||||
.map(item => ({
|
||||
value: item.count,
|
||||
name: item.level,
|
||||
itemStyle: { color: item.color }
|
||||
}))
|
||||
|
||||
// 如果没有数据,显示空状态
|
||||
if (chartData.length === 0 || riskTotal.value === 0) {
|
||||
return {
|
||||
tooltip: { trigger: 'item', formatter: '{a} <br/>{b}: {c} ({d}%)' },
|
||||
series: [{
|
||||
name: '风险',
|
||||
type: 'pie',
|
||||
radius: ['55%', '75%'],
|
||||
center: ['50%', '50%'],
|
||||
avoidLabelOverlap: false,
|
||||
itemStyle: { borderRadius: 0, borderColor: 'transparent', borderWidth: 0 },
|
||||
label: {
|
||||
show: true,
|
||||
position: 'center',
|
||||
formatter: () => `${riskTotal.value}\n风险总数`,
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
color: '#333'
|
||||
},
|
||||
data: [{ value: 1, name: '暂无数据', itemStyle: { color: '#e5e7eb' } }]
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
const chartData = riskDistribution.value.map(item => ({
|
||||
value: item.count,
|
||||
name: item.level,
|
||||
itemStyle: { color: item.color }
|
||||
}))
|
||||
|
||||
return {
|
||||
tooltip: { trigger: 'item', formatter: '{a} <br/>{b}: {c} ({d}%)' },
|
||||
graphic: [
|
||||
{
|
||||
type: 'text',
|
||||
left: 'center',
|
||||
top: 'center',
|
||||
style: {
|
||||
text: `${riskTotal.value}\n风险总数`,
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
fill: '#333',
|
||||
textAlign: 'center',
|
||||
textVerticalAlign: 'middle'
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [{
|
||||
name: '风险',
|
||||
type: 'pie',
|
||||
@@ -638,13 +643,51 @@ const riskChartOption = computed<EChartsOption>(() => {
|
||||
itemStyle: { borderRadius: 0, borderColor: 'transparent', borderWidth: 0 },
|
||||
label: {
|
||||
show: true,
|
||||
position: 'center',
|
||||
formatter: () => `${riskTotal.value}\n风险总数`,
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
alignTo: 'edge',
|
||||
formatter: (params: any) => {
|
||||
const value = Number(params.value) || 0
|
||||
const total = Number(riskTotal.value) || 0
|
||||
if (total === 0) {
|
||||
return '0%'
|
||||
}
|
||||
const percent = ((value / total) * 100).toFixed(2) + '%'
|
||||
return percent
|
||||
},
|
||||
minMargin: 5,
|
||||
edgeDistance: 10,
|
||||
lineHeight: 15,
|
||||
fontSize: 12,
|
||||
color: '#333'
|
||||
},
|
||||
emphasis: { label: { show: true, fontSize: 18, fontWeight: 'bold' } },
|
||||
labelLine: {
|
||||
show: true,
|
||||
length: 15,
|
||||
length2: 10,
|
||||
maxSurfaceAngle: 80
|
||||
},
|
||||
labelLayout: function (params: any) {
|
||||
const isLeft = params.labelRect.x < params.labelRect.width
|
||||
const points = params.labelLinePoints
|
||||
if (points && points.length >= 3) {
|
||||
// 调整线条的终点位置
|
||||
if (isLeft) {
|
||||
points[2][0] = params.labelRect.x
|
||||
} else {
|
||||
points[2][0] = params.labelRect.x + params.labelRect.width
|
||||
}
|
||||
return {
|
||||
labelLinePoints: points
|
||||
}
|
||||
}
|
||||
return {}
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true,
|
||||
fontSize: 14,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
data: chartData
|
||||
}]
|
||||
}
|
||||
@@ -783,6 +826,21 @@ const highRiskChartOption = computed<EChartsOption>(() => {
|
||||
if (chartData.length === 0 || highRiskTotal.value === 0) {
|
||||
return {
|
||||
tooltip: { trigger: 'item', formatter: '{a} <br/>{b}: {c} ({d}%)' },
|
||||
graphic: [
|
||||
{
|
||||
type: 'text',
|
||||
left: 'center',
|
||||
top: 'center',
|
||||
style: {
|
||||
text: `${highRiskTotal.value}\n累计作业`,
|
||||
fontSize: 15,
|
||||
fontWeight: 'bold',
|
||||
fill: '#333',
|
||||
textAlign: 'center',
|
||||
textVerticalAlign: 'middle'
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [{
|
||||
name: '高危作业',
|
||||
type: 'pie',
|
||||
@@ -791,12 +849,7 @@ const highRiskChartOption = computed<EChartsOption>(() => {
|
||||
avoidLabelOverlap: false,
|
||||
itemStyle: { borderRadius: 0, borderColor: 'transparent', borderWidth: 0 },
|
||||
label: {
|
||||
show: true,
|
||||
position: 'center',
|
||||
formatter: () => `${highRiskTotal.value}\n累计作业`,
|
||||
fontSize: 15,
|
||||
fontWeight: 'bold',
|
||||
color: '#333'
|
||||
show: false
|
||||
},
|
||||
data: [{ value: 1, name: '暂无数据', itemStyle: { color: '#e5e7eb' } }]
|
||||
}]
|
||||
@@ -805,6 +858,21 @@ const highRiskChartOption = computed<EChartsOption>(() => {
|
||||
|
||||
return {
|
||||
tooltip: { trigger: 'item', formatter: '{a} <br/>{b}: {c} ({d}%)' },
|
||||
graphic: [
|
||||
{
|
||||
type: 'text',
|
||||
left: 'center',
|
||||
top: 'center',
|
||||
style: {
|
||||
text: `${highRiskTotal.value}\n累计作业`,
|
||||
fontSize: 15,
|
||||
fontWeight: 'bold',
|
||||
fill: '#333',
|
||||
textAlign: 'center',
|
||||
textVerticalAlign: 'middle'
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [{
|
||||
name: '高危作业',
|
||||
type: 'pie',
|
||||
@@ -813,14 +881,9 @@ const highRiskChartOption = computed<EChartsOption>(() => {
|
||||
avoidLabelOverlap: false,
|
||||
itemStyle: { borderRadius: 0, borderColor: 'transparent', borderWidth: 0 },
|
||||
label: {
|
||||
show: true,
|
||||
position: 'center',
|
||||
formatter: () => `${highRiskTotal.value}\n累计作业`,
|
||||
fontSize: 15,
|
||||
fontWeight: 'bold',
|
||||
color: '#333'
|
||||
show: false
|
||||
},
|
||||
emphasis: { label: { show: true, fontSize: 20, fontWeight: 'bold' } },
|
||||
emphasis: { label: { show: true, fontSize: 16, fontWeight: 'bold' } },
|
||||
data: chartData
|
||||
}]
|
||||
}
|
||||
@@ -1002,10 +1065,6 @@ const navigateToModule = (path: string): void => {
|
||||
router.push(path)
|
||||
}
|
||||
|
||||
const openRegionSelector = (): void => {
|
||||
regionSelectorVisible.value = true
|
||||
}
|
||||
|
||||
const onRegionChange = (item: RegionItem): void => {
|
||||
selectedRegion.value = item.name
|
||||
router.push({
|
||||
@@ -1030,28 +1089,6 @@ const refreshData = async () => {
|
||||
initData()
|
||||
}
|
||||
|
||||
// 初始化区域数据
|
||||
const initRegionData = async () => {
|
||||
try {
|
||||
const { records } = await getTableList('park_info_list')
|
||||
if (records && records.length > 0) {
|
||||
// 去重region字段,使用Map来确保唯一性
|
||||
const regionMap = new Map<string, RegionItem>()
|
||||
records.forEach((el: any) => {
|
||||
if (!regionMap.has(el.region)) {
|
||||
regionMap.set(el.region, {
|
||||
name: el.region,
|
||||
code: el.region_id
|
||||
})
|
||||
}
|
||||
})
|
||||
// 转换为数组
|
||||
regionOption.value = Array.from(regionMap.values())
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('初始化区域数据失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化风险管理数据
|
||||
const initRiskData = async () => {
|
||||
@@ -1108,10 +1145,10 @@ const initRiskData = async () => {
|
||||
|
||||
// 处理风险等级分布数据(用于环形图)
|
||||
const allLevels = [
|
||||
{ key: '低', level: '低风险', count: 0, percent: '0%', color: '#10b981' },
|
||||
{ key: '一般', level: '一般风险', count: 0, percent: '0%', color: '#f59e0b' },
|
||||
{ key: '较大', level: '较大风险', count: 0, percent: '0%', color: '#ef4444' },
|
||||
{ key: '重大', level: '重大风险', count: 0, percent: '0%', color: '#dc2626' }
|
||||
{ key: '低', level: '低风险', count: 0, percent: '0%', color: '#117cee' },
|
||||
{ key: '一般', level: '一般风险', count: 0, percent: '0%', color: '#fbde28' },
|
||||
{ key: '较大', level: '较大风险', count: 0, percent: '0%', color: '#ed740c' },
|
||||
{ key: '重大', level: '重大风险', count: 0, percent: '0%', color: '#df2a3f' }
|
||||
]
|
||||
|
||||
riskDistribution.value = allLevels.map(defaultItem => {
|
||||
@@ -1150,10 +1187,10 @@ const initRiskData = async () => {
|
||||
// 如果没有数据,设置为默认值
|
||||
riskTotal.value = 0
|
||||
riskDistribution.value = [
|
||||
{ level: '低风险', count: 0, percent: '0%', color: '#10b981' },
|
||||
{ level: '一般风险', count: 0, percent: '0%', color: '#f59e0b' },
|
||||
{ level: '较大风险', count: 0, percent: '0%', color: '#ef4444' },
|
||||
{ level: '重大风险', count: 0, percent: '0%', color: '#dc2626' }
|
||||
{ level: '低风险', count: 0, percent: '0%', color: '#117cee' },
|
||||
{ level: '一般风险', count: 0, percent: '0%', color: '#fbde28' },
|
||||
{ level: '较大风险', count: 0, percent: '0%', color: '#ed740c' },
|
||||
{ level: '重大风险', count: 0, percent: '0%', color: '#df2a3f' }
|
||||
]
|
||||
areaRiskDistribution.value = []
|
||||
console.log('风险管理无数据')
|
||||
@@ -1163,10 +1200,10 @@ const initRiskData = async () => {
|
||||
// 如果接口失败,设置为默认值
|
||||
riskTotal.value = 0
|
||||
riskDistribution.value = [
|
||||
{ level: '低风险', count: 0, percent: '0%', color: '#10b981' },
|
||||
{ level: '一般风险', count: 0, percent: '0%', color: '#f59e0b' },
|
||||
{ level: '较大风险', count: 0, percent: '0%', color: '#ef4444' },
|
||||
{ level: '重大风险', count: 0, percent: '0%', color: '#dc2626' }
|
||||
{ level: '低风险', count: 0, percent: '0%', color: '#117cee' },
|
||||
{ level: '一般风险', count: 0, percent: '0%', color: '#fbde28' },
|
||||
{ level: '较大风险', count: 0, percent: '0%', color: '#ed740c' },
|
||||
{ level: '重大风险', count: 0, percent: '0%', color: '#df2a3f' }
|
||||
]
|
||||
areaRiskDistribution.value = []
|
||||
}
|
||||
@@ -1558,7 +1595,6 @@ const initTrainingData = async () => {
|
||||
}
|
||||
|
||||
const initData = async () => {
|
||||
await initRegionData()
|
||||
initOutsourcingData()
|
||||
|
||||
initRiskData()
|
||||
|
||||
@@ -2,15 +2,19 @@
|
||||
<div class="dashboard-container">
|
||||
<!-- 顶部标题栏 -->
|
||||
<div class="header-container">
|
||||
<div class="header-left">
|
||||
<el-icon class="back-arrow" @click="returnToHeadquarters">
|
||||
<ArrowLeft />
|
||||
</el-icon>
|
||||
<div class="region-name-clickable" @click="openParkSelector">
|
||||
{{ selectedRegion }}
|
||||
<span>···</span>
|
||||
</div>
|
||||
</div>
|
||||
<HeaderSelector
|
||||
back-button-type="image"
|
||||
:show-back-button="true"
|
||||
:on-back="returnToHeadquarters"
|
||||
:display-text="selectedRegion"
|
||||
:clickable="true"
|
||||
:show-selector-indicator="true"
|
||||
selector-type="park"
|
||||
:selected-value="selectedPark"
|
||||
:region-code="route.query.regionCode as string"
|
||||
theme="light"
|
||||
@selector-change="onParkChange"
|
||||
/>
|
||||
<!-- <h1 class="header-title">区域视角数据看板</h1> -->
|
||||
<div class="header-right">
|
||||
<div class="date-range-wrapper">
|
||||
@@ -293,16 +297,13 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 园区选择弹窗 -->
|
||||
<RegionSelector v-model="parkSelectorVisible" :modelSelected="selectedPark" :regions="parkOption"
|
||||
@change="onParkChange" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { Refresh, ArrowLeft } from '@element-plus/icons-vue'
|
||||
import { Refresh } from '@element-plus/icons-vue'
|
||||
import Echart from '@/components/Echart/src/Echart.vue'
|
||||
import type { EChartsOption } from 'echarts'
|
||||
import dayjs from 'dayjs'
|
||||
@@ -316,8 +317,7 @@ import {
|
||||
getHiddenDangerManagementDataRegionWeek,
|
||||
getHiddenDangerManagementDataRegionMonth
|
||||
} from '@/api'
|
||||
import RegionSelector from '@/views/screen/components/RegionSelector.vue'
|
||||
import { getTableList } from '@/api/design/report'
|
||||
import HeaderSelector from '@/views/screen/components/HeaderSelector.vue'
|
||||
|
||||
defineOptions({ name: 'Home12' })
|
||||
|
||||
@@ -358,8 +358,6 @@ const route = useRoute()
|
||||
// 区域和园区选择相关
|
||||
const selectedRegion = ref<string>('')
|
||||
const selectedPark = ref<string>('')
|
||||
const parkSelectorVisible = ref<boolean>(false)
|
||||
const parkOption = ref<ParkItem[]>([])
|
||||
|
||||
// 外协管理:/person/table/view/1959187451673116674
|
||||
// 风险管理:/fx/table/view/1978723750599790594
|
||||
@@ -447,35 +445,10 @@ const operationTypeColors: Record<string, string> = {
|
||||
}
|
||||
|
||||
// 初始化区域数据 - 加载园区列表
|
||||
// 初始化区域数据 - 只设置选中区域,园区列表由 HeaderSelector 组件内部管理
|
||||
const initRegionData = async () => {
|
||||
try {
|
||||
if (typeof route.query.region === 'string') {
|
||||
selectedRegion.value = route.query.region
|
||||
}
|
||||
|
||||
// 加载园区列表
|
||||
const { records } = await getTableList('park_info_list')
|
||||
|
||||
if (records && records.length > 0) {
|
||||
// 根据regionCode过滤园区
|
||||
const regionCode = route.query.regionCode as string
|
||||
const parkMap = new Map<string, ParkItem>()
|
||||
|
||||
records
|
||||
.filter((el: any) => el.region_id == regionCode)
|
||||
.forEach((el: any) => {
|
||||
if (!parkMap.has(el.park_name)) {
|
||||
parkMap.set(el.park_name, {
|
||||
name: el.park_name,
|
||||
code: el.park_code
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
parkOption.value = Array.from(parkMap.values())
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('初始化区域数据失败:', error)
|
||||
if (typeof route.query.region === 'string') {
|
||||
selectedRegion.value = route.query.region
|
||||
}
|
||||
}
|
||||
|
||||
@@ -490,15 +463,9 @@ const returnToHeadquarters = () => {
|
||||
})
|
||||
}
|
||||
|
||||
// 打开园区选择器
|
||||
const openParkSelector = (): void => {
|
||||
parkSelectorVisible.value = true
|
||||
}
|
||||
|
||||
// 园区选择变化 - 跳转到园区页面
|
||||
const onParkChange = (item: ParkItem): void => {
|
||||
selectedPark.value = item.name
|
||||
parkSelectorVisible.value = false
|
||||
router.push({
|
||||
path: '/park',
|
||||
query: {
|
||||
@@ -630,10 +597,10 @@ const initRiskData = async () => {
|
||||
|
||||
// 处理风险等级分布数据(用于环形图)
|
||||
const allLevels = [
|
||||
{ key: '低', level: '低风险', count: 0, percent: '0%', color: '#10b981' },
|
||||
{ key: '一般', level: '一般风险', count: 0, percent: '0%', color: '#f59e0b' },
|
||||
{ key: '较大', level: '较大风险', count: 0, percent: '0%', color: '#ef4444' },
|
||||
{ key: '重大', level: '重大风险', count: 0, percent: '0%', color: '#dc2626' }
|
||||
{ key: '低', level: '低风险', count: 0, percent: '0%', color: '#117cee' },
|
||||
{ key: '一般', level: '一般风险', count: 0, percent: '0%', color: '#fbde28' },
|
||||
{ key: '较大', level: '较大风险', count: 0, percent: '0%', color: '#ed740c' },
|
||||
{ key: '重大', level: '重大风险', count: 0, percent: '0%', color: '#df2a3f' }
|
||||
]
|
||||
|
||||
riskDistribution.value = allLevels.map(defaultItem => {
|
||||
@@ -671,10 +638,10 @@ const initRiskData = async () => {
|
||||
} else {
|
||||
riskTotal.value = 0
|
||||
riskDistribution.value = [
|
||||
{ level: '低风险', count: 0, percent: '0%', color: '#10b981' },
|
||||
{ level: '一般风险', count: 0, percent: '0%', color: '#f59e0b' },
|
||||
{ level: '较大风险', count: 0, percent: '0%', color: '#ef4444' },
|
||||
{ level: '重大风险', count: 0, percent: '0%', color: '#dc2626' }
|
||||
{ level: '低风险', count: 0, percent: '0%', color: '#117cee' },
|
||||
{ level: '一般风险', count: 0, percent: '0%', color: '#fbde28' },
|
||||
{ level: '较大风险', count: 0, percent: '0%', color: '#ed740c' },
|
||||
{ level: '重大风险', count: 0, percent: '0%', color: '#df2a3f' }
|
||||
]
|
||||
parkRiskDistribution.value = []
|
||||
console.log('区域风险管理无数据')
|
||||
@@ -683,10 +650,10 @@ const initRiskData = async () => {
|
||||
console.error('获取区域风险管理数据失败:', error)
|
||||
riskTotal.value = 0
|
||||
riskDistribution.value = [
|
||||
{ level: '低风险', count: 0, percent: '0%', color: '#10b981' },
|
||||
{ level: '一般风险', count: 0, percent: '0%', color: '#f59e0b' },
|
||||
{ level: '较大风险', count: 0, percent: '0%', color: '#ef4444' },
|
||||
{ level: '重大风险', count: 0, percent: '0%', color: '#dc2626' }
|
||||
{ level: '低风险', count: 0, percent: '0%', color: '#117cee' },
|
||||
{ level: '一般风险', count: 0, percent: '0%', color: '#fbde28' },
|
||||
{ level: '较大风险', count: 0, percent: '0%', color: '#ed740c' },
|
||||
{ level: '重大风险', count: 0, percent: '0%', color: '#df2a3f' }
|
||||
]
|
||||
parkRiskDistribution.value = []
|
||||
}
|
||||
@@ -1092,6 +1059,21 @@ const outsourcingChartOption = computed<EChartsOption>(() => {
|
||||
if (chartData.length === 0 || outsourcingTotal.value === 0) {
|
||||
return {
|
||||
tooltip: { trigger: 'item', formatter: '{a} <br/>{b}: {c} ({d}%)' },
|
||||
graphic: [
|
||||
{
|
||||
type: 'text',
|
||||
left: 'center',
|
||||
top: 'center',
|
||||
style: {
|
||||
text: `${outsourcingTotal.value}\n外协人员总数`,
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
fill: '#333',
|
||||
textAlign: 'center',
|
||||
textVerticalAlign: 'middle'
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [{
|
||||
name: '外协人员',
|
||||
type: 'pie',
|
||||
@@ -1099,13 +1081,8 @@ const outsourcingChartOption = computed<EChartsOption>(() => {
|
||||
center: ['50%', '50%'],
|
||||
avoidLabelOverlap: false,
|
||||
itemStyle: { borderRadius: 0, borderColor: 'transparent', borderWidth: 0 },
|
||||
label: {
|
||||
show: true,
|
||||
position: 'center',
|
||||
formatter: () => `${outsourcingTotal.value}\n外协人员总数`,
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
color: '#333'
|
||||
label: {
|
||||
show: false
|
||||
},
|
||||
data: [{ value: 1, name: '暂无数据', itemStyle: { color: '#e5e7eb' } }]
|
||||
}]
|
||||
@@ -1114,6 +1091,21 @@ const outsourcingChartOption = computed<EChartsOption>(() => {
|
||||
|
||||
return {
|
||||
tooltip: { trigger: 'item', formatter: '{a} <br/>{b}: {c} ({d}%)' },
|
||||
graphic: [
|
||||
{
|
||||
type: 'text',
|
||||
left: 'center',
|
||||
top: 'center',
|
||||
style: {
|
||||
text: `${outsourcingTotal.value}\n外协人员总数`,
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
fill: '#333',
|
||||
textAlign: 'center',
|
||||
textVerticalAlign: 'middle'
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [{
|
||||
name: '外协人员',
|
||||
type: 'pie',
|
||||
@@ -1122,14 +1114,9 @@ const outsourcingChartOption = computed<EChartsOption>(() => {
|
||||
avoidLabelOverlap: false,
|
||||
itemStyle: { borderRadius: 0, borderColor: 'transparent', borderWidth: 0 },
|
||||
label: {
|
||||
show: true,
|
||||
position: 'center',
|
||||
formatter: () => `${outsourcingTotal.value}\n外协人员总数`,
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
color: '#333'
|
||||
show: false
|
||||
},
|
||||
emphasis: { label: { show: true, fontSize: 18, fontWeight: 'bold' } },
|
||||
emphasis: { label: { show: true, fontSize: 14, fontWeight: 'bold' } },
|
||||
data: chartData
|
||||
}]
|
||||
}
|
||||
@@ -1145,6 +1132,21 @@ const riskChartOption = computed<EChartsOption>(() => {
|
||||
|
||||
return {
|
||||
tooltip: { trigger: 'item', formatter: '{a} <br/>{b}: {c} ({d}%)' },
|
||||
graphic: [
|
||||
{
|
||||
type: 'text',
|
||||
left: 'center',
|
||||
top: 'center',
|
||||
style: {
|
||||
text: `${riskTotal.value}\n风险总数`,
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
fill: '#333',
|
||||
textAlign: 'center',
|
||||
textVerticalAlign: 'middle'
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [{
|
||||
name: '风险',
|
||||
type: 'pie',
|
||||
@@ -1154,13 +1156,51 @@ const riskChartOption = computed<EChartsOption>(() => {
|
||||
itemStyle: { borderRadius: 0, borderColor: 'transparent', borderWidth: 0 },
|
||||
label: {
|
||||
show: true,
|
||||
position: 'center',
|
||||
formatter: () => `${riskTotal.value}\n风险总数`,
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
alignTo: 'edge',
|
||||
formatter: (params: any) => {
|
||||
const value = Number(params.value) || 0
|
||||
const total = Number(riskTotal.value) || 0
|
||||
if (total === 0) {
|
||||
return '0%'
|
||||
}
|
||||
const percent = ((value / total) * 100).toFixed(2) + '%'
|
||||
return percent
|
||||
},
|
||||
minMargin: 5,
|
||||
edgeDistance: 10,
|
||||
lineHeight: 15,
|
||||
fontSize: 12,
|
||||
color: '#333'
|
||||
},
|
||||
emphasis: { label: { show: true, fontSize: 18, fontWeight: 'bold' } },
|
||||
labelLine: {
|
||||
show: true,
|
||||
length: 15,
|
||||
length2: 10,
|
||||
maxSurfaceAngle: 80
|
||||
},
|
||||
labelLayout: function (params: any) {
|
||||
const isLeft = params.labelRect.x < params.labelRect.width
|
||||
const points = params.labelLinePoints
|
||||
if (points && points.length >= 3) {
|
||||
// 调整线条的终点位置
|
||||
if (isLeft) {
|
||||
points[2][0] = params.labelRect.x
|
||||
} else {
|
||||
points[2][0] = params.labelRect.x + params.labelRect.width
|
||||
}
|
||||
return {
|
||||
labelLinePoints: points
|
||||
}
|
||||
}
|
||||
return {}
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true,
|
||||
fontSize: 14,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
data: chartData
|
||||
}]
|
||||
}
|
||||
@@ -1237,6 +1277,21 @@ const hiddenDangerChartOption = computed<EChartsOption>(() => {
|
||||
const highRiskChartOption = computed<EChartsOption>(() => {
|
||||
return {
|
||||
tooltip: { trigger: 'item', formatter: '{a} <br/>{b}: {c} ({d}%)' },
|
||||
graphic: [
|
||||
{
|
||||
type: 'text',
|
||||
left: 'center',
|
||||
top: 'center',
|
||||
style: {
|
||||
text: `${highRiskTotal.value}\n累计作业`,
|
||||
fontSize: 15,
|
||||
fontWeight: 'bold',
|
||||
fill: '#333',
|
||||
textAlign: 'center',
|
||||
textVerticalAlign: 'middle'
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [{
|
||||
name: '高危作业',
|
||||
type: 'pie',
|
||||
@@ -1245,14 +1300,9 @@ const highRiskChartOption = computed<EChartsOption>(() => {
|
||||
avoidLabelOverlap: false,
|
||||
itemStyle: { borderRadius: 0, borderColor: 'transparent', borderWidth: 0 },
|
||||
label: {
|
||||
show: true,
|
||||
position: 'center',
|
||||
formatter: () => `${highRiskTotal.value}\n累计作业`,
|
||||
fontSize: 15,
|
||||
fontWeight: 'bold',
|
||||
color: '#333'
|
||||
show: false
|
||||
},
|
||||
emphasis: { label: { show: true, fontSize: 20, fontWeight: 'bold' } },
|
||||
emphasis: { label: { show: true, fontSize: 16, fontWeight: 'bold' } },
|
||||
data: operationTypeDistribution.value.map(item => ({
|
||||
value: item.count,
|
||||
name: item.type,
|
||||
|
||||
@@ -2,12 +2,16 @@
|
||||
<div class="dashboard-container">
|
||||
<!-- 顶部标题栏 -->
|
||||
<div class="header-container">
|
||||
<div class="header-left">
|
||||
<el-icon class="back-arrow" @click="returnToRegion">
|
||||
<ArrowLeft />
|
||||
</el-icon>
|
||||
<div class="park-name">{{ selectedPark }}</div>
|
||||
</div>
|
||||
<HeaderSelector
|
||||
back-button-type="image"
|
||||
:show-back-button="true"
|
||||
:on-back="returnToRegion"
|
||||
:display-text="selectedPark"
|
||||
:clickable="false"
|
||||
:show-selector-indicator="false"
|
||||
selector-type="none"
|
||||
theme="light"
|
||||
/>
|
||||
<!-- <h1 class="header-title">园区视角数据看板</h1> -->
|
||||
<div class="header-right">
|
||||
<div class="date-range-wrapper">
|
||||
@@ -297,7 +301,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { Refresh, ArrowLeft } from '@element-plus/icons-vue'
|
||||
import { Refresh } from '@element-plus/icons-vue'
|
||||
import Echart from '@/components/Echart/src/Echart.vue'
|
||||
import type { EChartsOption } from 'echarts'
|
||||
import dayjs from 'dayjs'
|
||||
@@ -311,6 +315,7 @@ import {
|
||||
getHiddenDangerManagementDataParkWeek,
|
||||
getHiddenDangerManagementDataParkMonth
|
||||
} from '@/api'
|
||||
import HeaderSelector from '@/views/screen/components/HeaderSelector.vue'
|
||||
|
||||
defineOptions({ name: 'Home13' })
|
||||
|
||||
@@ -580,10 +585,10 @@ const initRiskData = async () => {
|
||||
|
||||
// 处理风险等级分布数据(用于环形图)
|
||||
const allLevels = [
|
||||
{ key: '低', level: '低风险', count: 0, percent: '0%', color: '#10b981' },
|
||||
{ key: '一般', level: '一般风险', count: 0, percent: '0%', color: '#f59e0b' },
|
||||
{ key: '较大', level: '较大风险', count: 0, percent: '0%', color: '#ef4444' },
|
||||
{ key: '重大', level: '重大风险', count: 0, percent: '0%', color: '#dc2626' }
|
||||
{ key: '低', level: '低风险', count: 0, percent: '0%', color: '#117cee' },
|
||||
{ key: '一般', level: '一般风险', count: 0, percent: '0%', color: '#fbde28' },
|
||||
{ key: '较大', level: '较大风险', count: 0, percent: '0%', color: '#ed740c' },
|
||||
{ key: '重大', level: '重大风险', count: 0, percent: '0%', color: '#df2a3f' }
|
||||
]
|
||||
|
||||
riskDistribution.value = allLevels.map(defaultItem => {
|
||||
@@ -621,10 +626,10 @@ const initRiskData = async () => {
|
||||
} else {
|
||||
riskTotal.value = 0
|
||||
riskDistribution.value = [
|
||||
{ level: '低风险', count: 0, percent: '0%', color: '#10b981' },
|
||||
{ level: '一般风险', count: 0, percent: '0%', color: '#f59e0b' },
|
||||
{ level: '较大风险', count: 0, percent: '0%', color: '#ef4444' },
|
||||
{ level: '重大风险', count: 0, percent: '0%', color: '#dc2626' }
|
||||
{ level: '低风险', count: 0, percent: '0%', color: '#117cee' },
|
||||
{ level: '一般风险', count: 0, percent: '0%', color: '#fbde28' },
|
||||
{ level: '较大风险', count: 0, percent: '0%', color: '#ed740c' },
|
||||
{ level: '重大风险', count: 0, percent: '0%', color: '#df2a3f' }
|
||||
]
|
||||
locationRiskDistribution.value = []
|
||||
console.log('园区风险管理无数据')
|
||||
@@ -633,10 +638,10 @@ const initRiskData = async () => {
|
||||
console.error('获取园区风险管理数据失败:', error)
|
||||
riskTotal.value = 0
|
||||
riskDistribution.value = [
|
||||
{ level: '低风险', count: 0, percent: '0%', color: '#10b981' },
|
||||
{ level: '一般风险', count: 0, percent: '0%', color: '#f59e0b' },
|
||||
{ level: '较大风险', count: 0, percent: '0%', color: '#ef4444' },
|
||||
{ level: '重大风险', count: 0, percent: '0%', color: '#dc2626' }
|
||||
{ level: '低风险', count: 0, percent: '0%', color: '#117cee' },
|
||||
{ level: '一般风险', count: 0, percent: '0%', color: '#fbde28' },
|
||||
{ level: '较大风险', count: 0, percent: '0%', color: '#ed740c' },
|
||||
{ level: '重大风险', count: 0, percent: '0%', color: '#df2a3f' }
|
||||
]
|
||||
locationRiskDistribution.value = []
|
||||
}
|
||||
@@ -1013,6 +1018,21 @@ const outsourcingChartOption = computed<EChartsOption>(() => {
|
||||
if (chartData.length === 0 || outsourcingTotal.value === 0) {
|
||||
return {
|
||||
tooltip: { trigger: 'item', formatter: '{a} <br/>{b}: {c} ({d}%)' },
|
||||
graphic: [
|
||||
{
|
||||
type: 'text',
|
||||
left: 'center',
|
||||
top: 'center',
|
||||
style: {
|
||||
text: `${outsourcingTotal.value}\n外协人员总数`,
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
fill: '#333',
|
||||
textAlign: 'center',
|
||||
textVerticalAlign: 'middle'
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [{
|
||||
name: '外协人员',
|
||||
type: 'pie',
|
||||
@@ -1020,13 +1040,8 @@ const outsourcingChartOption = computed<EChartsOption>(() => {
|
||||
center: ['50%', '50%'],
|
||||
avoidLabelOverlap: false,
|
||||
itemStyle: { borderRadius: 0, borderColor: 'transparent', borderWidth: 0 },
|
||||
label: {
|
||||
show: true,
|
||||
position: 'center',
|
||||
formatter: () => `${outsourcingTotal.value}\n外协人员总数`,
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
color: '#333'
|
||||
label: {
|
||||
show: false
|
||||
},
|
||||
data: [{ value: 1, name: '暂无数据', itemStyle: { color: '#e5e7eb' } }]
|
||||
}]
|
||||
@@ -1035,6 +1050,21 @@ const outsourcingChartOption = computed<EChartsOption>(() => {
|
||||
|
||||
return {
|
||||
tooltip: { trigger: 'item', formatter: '{a} <br/>{b}: {c} ({d}%)' },
|
||||
graphic: [
|
||||
{
|
||||
type: 'text',
|
||||
left: 'center',
|
||||
top: 'center',
|
||||
style: {
|
||||
text: `${outsourcingTotal.value}\n外协人员总数`,
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
fill: '#333',
|
||||
textAlign: 'center',
|
||||
textVerticalAlign: 'middle'
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [{
|
||||
name: '外协人员',
|
||||
type: 'pie',
|
||||
@@ -1043,14 +1073,9 @@ const outsourcingChartOption = computed<EChartsOption>(() => {
|
||||
avoidLabelOverlap: false,
|
||||
itemStyle: { borderRadius: 0, borderColor: 'transparent', borderWidth: 0 },
|
||||
label: {
|
||||
show: true,
|
||||
position: 'center',
|
||||
formatter: () => `${outsourcingTotal.value}\n外协人员总数`,
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
color: '#333'
|
||||
show: false
|
||||
},
|
||||
emphasis: { label: { show: true, fontSize: 18, fontWeight: 'bold' } },
|
||||
emphasis: { label: { show: true, fontSize: 14, fontWeight: 'bold' } },
|
||||
data: chartData
|
||||
}]
|
||||
}
|
||||
@@ -1066,6 +1091,21 @@ const riskChartOption = computed<EChartsOption>(() => {
|
||||
|
||||
return {
|
||||
tooltip: { trigger: 'item', formatter: '{a} <br/>{b}: {c} ({d}%)' },
|
||||
graphic: [
|
||||
{
|
||||
type: 'text',
|
||||
left: 'center',
|
||||
top: 'center',
|
||||
style: {
|
||||
text: `${riskTotal.value}\n风险总数`,
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
fill: '#333',
|
||||
textAlign: 'center',
|
||||
textVerticalAlign: 'middle'
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [{
|
||||
name: '风险',
|
||||
type: 'pie',
|
||||
@@ -1075,13 +1115,51 @@ const riskChartOption = computed<EChartsOption>(() => {
|
||||
itemStyle: { borderRadius: 0, borderColor: 'transparent', borderWidth: 0 },
|
||||
label: {
|
||||
show: true,
|
||||
position: 'center',
|
||||
formatter: () => `${riskTotal.value}\n风险总数`,
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
alignTo: 'edge',
|
||||
formatter: (params: any) => {
|
||||
const value = Number(params.value) || 0
|
||||
const total = Number(riskTotal.value) || 0
|
||||
if (total === 0) {
|
||||
return '0%'
|
||||
}
|
||||
const percent = ((value / total) * 100).toFixed(2) + '%'
|
||||
return percent
|
||||
},
|
||||
minMargin: 5,
|
||||
edgeDistance: 10,
|
||||
lineHeight: 15,
|
||||
fontSize: 12,
|
||||
color: '#333'
|
||||
},
|
||||
emphasis: { label: { show: true, fontSize: 18, fontWeight: 'bold' } },
|
||||
labelLine: {
|
||||
show: true,
|
||||
length: 15,
|
||||
length2: 10,
|
||||
maxSurfaceAngle: 80
|
||||
},
|
||||
labelLayout: function (params: any) {
|
||||
const isLeft = params.labelRect.x < params.labelRect.width
|
||||
const points = params.labelLinePoints
|
||||
if (points && points.length >= 3) {
|
||||
// 调整线条的终点位置
|
||||
if (isLeft) {
|
||||
points[2][0] = params.labelRect.x
|
||||
} else {
|
||||
points[2][0] = params.labelRect.x + params.labelRect.width
|
||||
}
|
||||
return {
|
||||
labelLinePoints: points
|
||||
}
|
||||
}
|
||||
return {}
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true,
|
||||
fontSize: 14,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
data: chartData
|
||||
}]
|
||||
}
|
||||
@@ -1159,6 +1237,21 @@ const hiddenDangerChartOption = computed<EChartsOption>(() => {
|
||||
const highRiskChartOption = computed<EChartsOption>(() => {
|
||||
return {
|
||||
tooltip: { trigger: 'item', formatter: '{a} <br/>{b}: {c} ({d}%)' },
|
||||
graphic: [
|
||||
{
|
||||
type: 'text',
|
||||
left: 'center',
|
||||
top: 'center',
|
||||
style: {
|
||||
text: `${highRiskTotal.value}\n累计作业`,
|
||||
fontSize: 15,
|
||||
fontWeight: 'bold',
|
||||
fill: '#333',
|
||||
textAlign: 'center',
|
||||
textVerticalAlign: 'middle'
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [{
|
||||
name: '高危作业',
|
||||
type: 'pie',
|
||||
@@ -1167,14 +1260,9 @@ const highRiskChartOption = computed<EChartsOption>(() => {
|
||||
avoidLabelOverlap: false,
|
||||
itemStyle: { borderRadius: 0, borderColor: 'transparent', borderWidth: 0 },
|
||||
label: {
|
||||
show: true,
|
||||
position: 'center',
|
||||
formatter: () => `${highRiskTotal.value}\n累计作业`,
|
||||
fontSize: 15,
|
||||
fontWeight: 'bold',
|
||||
color: '#333'
|
||||
show: false
|
||||
},
|
||||
emphasis: { label: { show: true, fontSize: 20, fontWeight: 'bold' } },
|
||||
emphasis: { label: { show: true, fontSize: 16, fontWeight: 'bold' } },
|
||||
data: operationTypeDistribution.value.map(item => ({
|
||||
value: item.count,
|
||||
name: item.type,
|
||||
|
||||
Reference in New Issue
Block a user