|
|
@@ -50,9 +50,8 @@ type RiskZone = {
|
|
|
|
|
|
type PermitStat = {
|
|
|
label: string
|
|
|
- value: string
|
|
|
- accent: string
|
|
|
- soft: string
|
|
|
+ value: number
|
|
|
+ color: string
|
|
|
}
|
|
|
|
|
|
type BottomCard = {
|
|
|
@@ -65,12 +64,14 @@ type BottomCard = {
|
|
|
|
|
|
const wrapperRef = ref<HTMLDivElement>()
|
|
|
const hazardChartRef = ref<HTMLDivElement>()
|
|
|
+const socChartRef = ref<HTMLDivElement>()
|
|
|
const scale = ref(1)
|
|
|
const supportsZoom = ref(false)
|
|
|
|
|
|
let resizeObserver: ResizeObserver | null = null
|
|
|
let resizeRaf = 0
|
|
|
let hazardChart: echarts.ECharts | null = null
|
|
|
+let socChart: echarts.ECharts | null = null
|
|
|
|
|
|
const pageTitle = 'QHSE管理看板'
|
|
|
|
|
|
@@ -94,15 +95,15 @@ const summaryCards: SummaryCard[] = [
|
|
|
{
|
|
|
title: '隐患整改率',
|
|
|
value: '92.3%',
|
|
|
- note: '较昨日 +1.6%',
|
|
|
+ note: '',
|
|
|
accent: '#2ac7c9',
|
|
|
glow: 'rgba(42, 199, 201, 0.26)',
|
|
|
icon: DataAnalysis
|
|
|
},
|
|
|
{
|
|
|
- title: '本月在线作业许可',
|
|
|
+ title: '本月作业许可',
|
|
|
value: '11',
|
|
|
- note: 'Active',
|
|
|
+ note: '',
|
|
|
accent: '#4f8dff',
|
|
|
glow: 'rgba(79, 141, 255, 0.22)',
|
|
|
icon: DocumentChecked
|
|
|
@@ -136,8 +137,11 @@ const riskZones: RiskZone[] = [
|
|
|
]
|
|
|
|
|
|
const permitStats: PermitStat[] = [
|
|
|
- { label: '在线作业', value: '11', accent: '#4d8cff', soft: 'rgba(77, 140, 255, 0.16)' },
|
|
|
- { label: '异常预警', value: '2', accent: '#d0a400', soft: 'rgba(208, 164, 0, 0.14)' }
|
|
|
+ { label: '个人防护', value: 18, color: '#4f8dff' },
|
|
|
+ { label: '规范操作', value: 26, color: '#43c7ca' },
|
|
|
+ { label: '规范指挥', value: 12, color: '#ffb14a' },
|
|
|
+ { label: '人员位置', value: 9, color: '#ff7a7a' },
|
|
|
+ { label: '作业场所', value: 15, color: '#8d8cff' }
|
|
|
]
|
|
|
|
|
|
const qualificationWarnings = [
|
|
|
@@ -165,7 +169,7 @@ const bottomCards: BottomCard[] = [
|
|
|
icon: AlarmClock,
|
|
|
accent: '#ff5b61',
|
|
|
glow: 'rgba(255, 91, 97, 0.22)',
|
|
|
- lines: ['年度计划完成率', '89%(需补1次)']
|
|
|
+ lines: ['年度应急演练:80次']
|
|
|
},
|
|
|
{
|
|
|
title: '质量检验',
|
|
|
@@ -226,16 +230,20 @@ onMounted(() => {
|
|
|
resizeObserver.observe(wrapperRef.value)
|
|
|
}
|
|
|
initHazardChart()
|
|
|
+ initSocChart()
|
|
|
window.addEventListener('resize', updateScale)
|
|
|
window.addEventListener('resize', resizeHazardChart)
|
|
|
+ window.addEventListener('resize', resizeSocChart)
|
|
|
})
|
|
|
|
|
|
onUnmounted(() => {
|
|
|
resizeObserver?.disconnect()
|
|
|
window.removeEventListener('resize', updateScale)
|
|
|
window.removeEventListener('resize', resizeHazardChart)
|
|
|
+ window.removeEventListener('resize', resizeSocChart)
|
|
|
cancelAnimationFrame(resizeRaf)
|
|
|
destroyHazardChart()
|
|
|
+ destroySocChart()
|
|
|
})
|
|
|
|
|
|
function getHazardChartOption(): echarts.EChartsOption {
|
|
|
@@ -361,6 +369,123 @@ function destroyHazardChart() {
|
|
|
hazardChart = null
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+function getSocChartOption(): echarts.EChartsOption {
|
|
|
+ return {
|
|
|
+ ...ANIMATION,
|
|
|
+ tooltip: createTooltip({
|
|
|
+ trigger: 'item',
|
|
|
+ formatter(params: any) {
|
|
|
+ return `${params.name}<br/>数量:${params.value}<br/>占比:${params.percent}%`
|
|
|
+ }
|
|
|
+ }),
|
|
|
+ legend: {
|
|
|
+ orient: 'vertical',
|
|
|
+ right: 4,
|
|
|
+ top: 'center',
|
|
|
+ itemWidth: 12,
|
|
|
+ itemHeight: 12,
|
|
|
+ icon: 'circle',
|
|
|
+ textStyle: {
|
|
|
+ color: '#5b6f8f',
|
|
|
+ fontSize: 15,
|
|
|
+ fontWeight: 600,
|
|
|
+ fontFamily: FONT_FAMILY
|
|
|
+ }
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: 'SOC卡类型',
|
|
|
+ type: 'pie',
|
|
|
+ radius: ['50%', '74%'],
|
|
|
+ center: ['34%', '54%'],
|
|
|
+ avoidLabelOverlap: true,
|
|
|
+ itemStyle: {
|
|
|
+ borderColor: 'rgba(255, 255, 255, 0.85)',
|
|
|
+ borderWidth: 2,
|
|
|
+ shadowBlur: 10,
|
|
|
+ shadowColor: 'rgba(31, 91, 184, 0.12)'
|
|
|
+ },
|
|
|
+ label: {
|
|
|
+ show: true,
|
|
|
+ color: '#4e6483',
|
|
|
+ fontSize: 13,
|
|
|
+ fontWeight: 700,
|
|
|
+ formatter: '{d}%'
|
|
|
+ },
|
|
|
+ labelLine: {
|
|
|
+ lineStyle: {
|
|
|
+ color: 'rgba(91, 111, 143, 0.5)'
|
|
|
+ },
|
|
|
+ length: 10,
|
|
|
+ length2: 8
|
|
|
+ },
|
|
|
+ data: permitStats.map((item) => ({
|
|
|
+ name: item.label,
|
|
|
+ value: item.value,
|
|
|
+ itemStyle: {
|
|
|
+ color: item.color
|
|
|
+ }
|
|
|
+ })),
|
|
|
+ emphasis: {
|
|
|
+ scale: true,
|
|
|
+ scaleSize: 6
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ graphic: [
|
|
|
+ {
|
|
|
+ type: 'text',
|
|
|
+ left: '28.8%',
|
|
|
+ top: '43%',
|
|
|
+ style: {
|
|
|
+ text: 'SOC卡',
|
|
|
+
|
|
|
+ fill: '#6b7f9c',
|
|
|
+ fontSize: 18,
|
|
|
+ fontWeight: 700,
|
|
|
+ fontFamily: FONT_FAMILY
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: 'text',
|
|
|
+ left: '26.5%',
|
|
|
+ top: '50%',
|
|
|
+ textAlign: 'center',
|
|
|
+ style: {
|
|
|
+ text: `${permitStats.reduce((sum, item) => sum + item.value, 0)}`,
|
|
|
+
|
|
|
+ fill: '#114a9b',
|
|
|
+ fontSize: 30,
|
|
|
+ fontWeight: 700,
|
|
|
+ fontFamily: 'YouSheBiaoTiHei, sans-serif'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function initSocChart() {
|
|
|
+ if (!socChartRef.value) return
|
|
|
+ if (socChart) {
|
|
|
+ socChart.dispose()
|
|
|
+ }
|
|
|
+ socChart = echarts.init(socChartRef.value, undefined, {
|
|
|
+ renderer: CHART_RENDERER
|
|
|
+ })
|
|
|
+ socChart.setOption(getSocChartOption(), true)
|
|
|
+}
|
|
|
+
|
|
|
+function resizeSocChart() {
|
|
|
+ socChart?.resize()
|
|
|
+}
|
|
|
+
|
|
|
+function destroySocChart() {
|
|
|
+ if (socChart) {
|
|
|
+ socChart.dispose()
|
|
|
+ socChart = null
|
|
|
+ }
|
|
|
+}
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
@@ -460,18 +585,9 @@ function destroyHazardChart() {
|
|
|
<section class="panel board-panel kb-stage-card kb-stage-card--5">
|
|
|
<div class="panel-title">
|
|
|
<span class="icon-decorator"><span></span><span></span></span>
|
|
|
- 作业许可实时监控
|
|
|
- </div>
|
|
|
- <div class="permit-grid">
|
|
|
- <div
|
|
|
- v-for="item in permitStats"
|
|
|
- :key="item.label"
|
|
|
- class="permit-card"
|
|
|
- :style="{ '--permit-accent': item.accent, '--permit-soft': item.soft } as any">
|
|
|
- <div class="permit-card__label">{{ item.label }}</div>
|
|
|
- <div class="permit-card__value">{{ item.value }}</div>
|
|
|
- </div>
|
|
|
+ SOC卡类型
|
|
|
</div>
|
|
|
+ <div ref="socChartRef" class="soc-chart-panel"></div>
|
|
|
</section>
|
|
|
|
|
|
<section class="panel board-panel kb-stage-card kb-stage-card--6">
|
|
|
@@ -628,7 +744,7 @@ function destroyHazardChart() {
|
|
|
|
|
|
.incident-panel {
|
|
|
display: grid;
|
|
|
- margin-top: 22px;
|
|
|
+ margin-top: 50px;
|
|
|
grid-template-columns: 180px 1fr;
|
|
|
align-items: center;
|
|
|
gap: 28px;
|
|
|
@@ -738,38 +854,9 @@ function destroyHazardChart() {
|
|
|
line-height: 1.55;
|
|
|
}
|
|
|
|
|
|
-.permit-grid {
|
|
|
- display: grid;
|
|
|
- // margin-top: 32px;
|
|
|
- padding: 28px;
|
|
|
- grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
|
- gap: 20px;
|
|
|
-}
|
|
|
-
|
|
|
-.permit-card {
|
|
|
- min-height: 128px;
|
|
|
- padding: 28px 20px;
|
|
|
- text-align: center;
|
|
|
- background: linear-gradient(180deg, var(--permit-soft) 0%, rgb(255 255 255 / 18%) 100%);
|
|
|
- border: 1px solid rgb(255 255 255 / 54%);
|
|
|
- border-radius: 18px;
|
|
|
- box-shadow:
|
|
|
- inset 0 1px 0 rgb(255 255 255 / 68%),
|
|
|
- 0 8px 18px rgb(63 103 171 / 6%);
|
|
|
-}
|
|
|
-
|
|
|
-.permit-card__label {
|
|
|
- font-size: 18px;
|
|
|
- font-weight: 700;
|
|
|
- color: #506684;
|
|
|
-}
|
|
|
-
|
|
|
-.permit-card__value {
|
|
|
- margin-top: 18px;
|
|
|
- font-family: YouSheBiaoTiHei, sans-serif;
|
|
|
- font-size: 44px;
|
|
|
- line-height: 1;
|
|
|
- color: var(--permit-accent);
|
|
|
+.soc-chart-panel {
|
|
|
+ height: 220px;
|
|
|
+ // margin-top: 10px;
|
|
|
}
|
|
|
|
|
|
.qualification-panel {
|