8 changed files with 555 additions and 10 deletions
After Width: | Height: | Size: 16 KiB |
@ -1,11 +1,131 @@ |
|||
<template> |
|||
<div></div> |
|||
<div class="daily-patrol-card"> |
|||
<div class="sy-water-cart-second-title">日常巡查</div> |
|||
<div class="echart-wrapper" ref="chartRef"></div> |
|||
<div class="appraise-progress"> |
|||
<div class="tips"> |
|||
<div>问题处理进度:<span>23%</span></div> |
|||
</div> |
|||
<div class="progress"> |
|||
<div class="progress-bar" style="width: 23%"></div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import { ref, onMounted, onBeforeUnmount } from "vue"; |
|||
import * as echarts from "echarts"; |
|||
defineOptions({ |
|||
name: "DailyPatrolCard", |
|||
}); |
|||
let chart: echarts.ECharts | undefined; |
|||
const chartRef = ref(); |
|||
const handleResize = () => { |
|||
chart?.resize(); |
|||
}; |
|||
onMounted(() => { |
|||
chart = echarts.init(chartRef.value); |
|||
|
|||
// Chart options |
|||
const option = { |
|||
tooltip: { |
|||
trigger: "item", |
|||
formatter: "{a} <br/>{b}: {c} ({d}%)", |
|||
}, |
|||
color: ["#4285F4", "#FF9F40", "#FFCD56", "#FF6384"], |
|||
series: [ |
|||
{ |
|||
name: "问题类型", |
|||
type: "pie", |
|||
radius: ["50%", "70%"], |
|||
avoidLabelOverlap: false, |
|||
label: { |
|||
show: false, |
|||
}, |
|||
emphasis: { |
|||
label: { |
|||
show: false, |
|||
}, |
|||
}, |
|||
labelLine: { |
|||
show: false, |
|||
}, |
|||
data: [ |
|||
{ value: 545, name: "一般" }, |
|||
{ value: 21, name: "重大" }, |
|||
{ value: 300, name: "较大" }, |
|||
{ value: 64, name: "紧急" }, |
|||
], |
|||
}, |
|||
], |
|||
}; |
|||
|
|||
// Set options and render chart |
|||
chart.setOption(option); |
|||
|
|||
window.addEventListener("resize", handleResize); |
|||
}); |
|||
onBeforeUnmount(() => { |
|||
chart?.dispose(); |
|||
window.removeEventListener("resize", handleResize); |
|||
}); |
|||
</script> |
|||
|
|||
<style scoped></style> |
|||
<style scoped lang="less"> |
|||
.daily-patrol-card { |
|||
width: 100%; |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 16px; |
|||
.echart-wrapper { |
|||
width: 100%; |
|||
height: 164px; |
|||
} |
|||
.appraise-progress { |
|||
width: 100%; |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 16px; |
|||
.tips { |
|||
display: flex; |
|||
align-items: center; |
|||
gap: 12px; |
|||
justify-content: flex-start; |
|||
font-family: Microsoft YaHei; |
|||
font-size: 14px; |
|||
font-weight: normal; |
|||
line-height: 22px; |
|||
letter-spacing: 0px; |
|||
|
|||
font-variation-settings: "opsz" auto; |
|||
color: rgba(0, 0, 0, 0.55); |
|||
span { |
|||
font-family: DIN; |
|||
font-size: 16px; |
|||
font-weight: bold; |
|||
line-height: 22px; |
|||
letter-spacing: 0px; |
|||
|
|||
font-variation-settings: "opsz" auto; |
|||
color: #28ce8e; |
|||
} |
|||
} |
|||
.progress { |
|||
width: 100%; |
|||
background: rgba(255, 255, 255, 0.4); |
|||
height: 24px; |
|||
border-radius: 12px; |
|||
display: flex; |
|||
flex-direction: row; |
|||
align-items: center; |
|||
justify-content: flex-start; |
|||
overflow: hidden; |
|||
.progress-bar { |
|||
height: 100%; |
|||
background: #28ce8e; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
|
@ -1,11 +1,183 @@ |
|||
<template> |
|||
<div></div> |
|||
<div class="risk-inspection-card"> |
|||
<div class="sy-water-cart-second-title">病险核查</div> |
|||
<div class="inspection-content"> |
|||
<div class="left"> |
|||
<div class="title">病险核查问题</div> |
|||
<div class="echart-wrapper" ref="problemEchartRef"></div> |
|||
</div> |
|||
<div class="right"> |
|||
<div class="title">病险核查任务</div> |
|||
<div class="echart-wrapper" ref="questEchartRef"></div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import { ref, onMounted, onBeforeUnmount } from "vue"; |
|||
import * as echarts from "echarts"; |
|||
defineOptions({ |
|||
name: "RiskInspectionCard", |
|||
}); |
|||
const problemEchartRef = ref(); |
|||
const questEchartRef = ref(); |
|||
let leftChart: echarts.ECharts | undefined; |
|||
let rightChart: echarts.ECharts | undefined; |
|||
const handleResize = () => { |
|||
leftChart?.resize(); |
|||
rightChart?.resize(); |
|||
}; |
|||
onMounted(() => { |
|||
leftChart = echarts.init(problemEchartRef.value); |
|||
|
|||
// Chart options for the left side (nested pie) |
|||
const leftOption = { |
|||
tooltip: { |
|||
trigger: "item", |
|||
formatter: "{b}: {c}", |
|||
}, |
|||
color: ["#FFCD56", "#4285F4"], |
|||
series: [ |
|||
{ |
|||
type: "pie", |
|||
radius: ["65%", "90%"], |
|||
avoidLabelOverlap: false, |
|||
label: { |
|||
show: false, |
|||
position: "center", |
|||
}, |
|||
emphasis: { |
|||
label: { |
|||
show: false, |
|||
}, |
|||
}, |
|||
labelLine: { |
|||
show: false, |
|||
}, |
|||
data: [ |
|||
{ value: 98, name: "工程总数", itemStyle: { color: "#FFCD56" } }, |
|||
{ value: 0, name: "", itemStyle: { color: "transparent" } }, |
|||
], |
|||
}, |
|||
{ |
|||
type: "pie", |
|||
radius: ["40%", "60%"], |
|||
avoidLabelOverlap: false, |
|||
label: { |
|||
show: false, |
|||
position: "center", |
|||
}, |
|||
emphasis: { |
|||
label: { |
|||
show: false, |
|||
}, |
|||
}, |
|||
labelLine: { |
|||
show: false, |
|||
}, |
|||
data: [ |
|||
{ value: 56, name: "问题数", itemStyle: { color: "#4285F4" } }, |
|||
{ value: 42, name: "", itemStyle: { color: "transparent" } }, |
|||
], |
|||
}, |
|||
], |
|||
}; |
|||
|
|||
// Set options and render left chart |
|||
leftChart.setOption(leftOption); |
|||
|
|||
rightChart = echarts.init(questEchartRef.value); |
|||
|
|||
// Chart options for the right side (liquidFill) |
|||
const rightOption = { |
|||
series: [ |
|||
{ |
|||
type: "liquidFill", |
|||
radius: "80%", |
|||
data: [0.165], |
|||
label: { |
|||
normal: { |
|||
textStyle: { |
|||
fontSize: 35, |
|||
fontWeight: "bold", |
|||
color: "#000", |
|||
}, |
|||
position: ["50%", "45%"], |
|||
formatter: function () { |
|||
return "16.5%"; |
|||
}, |
|||
}, |
|||
}, |
|||
outline: { |
|||
show: true, |
|||
borderDistance: 0, |
|||
itemStyle: { |
|||
borderWidth: 1, |
|||
borderColor: "#20C997", |
|||
}, |
|||
}, |
|||
color: ["#20C997"], |
|||
backgroundStyle: { |
|||
color: "rgba(32, 201, 151, 0.1)", |
|||
}, |
|||
itemStyle: { |
|||
opacity: 0.7, |
|||
}, |
|||
emphasis: { |
|||
itemStyle: { |
|||
opacity: 0.9, |
|||
}, |
|||
}, |
|||
}, |
|||
], |
|||
}; |
|||
|
|||
// Set options and render right chart |
|||
rightChart.setOption(rightOption); |
|||
|
|||
window.addEventListener("resize", handleResize); |
|||
}); |
|||
onBeforeUnmount(() => { |
|||
leftChart?.dispose(); |
|||
rightChart?.dispose(); |
|||
window.removeEventListener("resize", handleResize); |
|||
}); |
|||
</script> |
|||
|
|||
<style scoped></style> |
|||
<style scoped lang="less"> |
|||
.risk-inspection-card { |
|||
width: 100%; |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 16px; |
|||
.inspection-content { |
|||
display: flex; |
|||
flex-direction: row; |
|||
gap: 16px; |
|||
.left, |
|||
.right { |
|||
width: 50%; |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
gap: 12px; |
|||
.title { |
|||
font-family: Microsoft YaHei; |
|||
font-size: 14px; |
|||
font-weight: normal; |
|||
line-height: 23.4px; |
|||
text-align: right; |
|||
display: flex; |
|||
align-items: center; |
|||
letter-spacing: 0px; |
|||
color: #000000; |
|||
} |
|||
.echart-wrapper { |
|||
height: 192px - 24px - 12px; |
|||
width: 170px; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
|
@ -0,0 +1,151 @@ |
|||
<template> |
|||
<div class="safety-appraise"> |
|||
<div class="sy-water-cart-second-title">安全鉴定</div> |
|||
<div class="appraise-wrapper"> |
|||
<div class="appraise-item"> |
|||
<div class="count total">456</div> |
|||
<div class="name">任务数</div> |
|||
</div> |
|||
<div class="appraise-item"> |
|||
<div class="count wait">400</div> |
|||
<div class="name">待鉴定</div> |
|||
</div> |
|||
<div class="appraise-item"> |
|||
<div class="count ok">56</div> |
|||
<div class="name">已鉴定</div> |
|||
</div> |
|||
</div> |
|||
<div class="appraise-progress"> |
|||
<div class="tips"> |
|||
<div>已完成:<span class="ok">23%</span></div> |
|||
<div>进行中:<span class="in">23%</span></div> |
|||
<div>超期未鉴定:<span class="overdue">23%</span></div> |
|||
</div> |
|||
<div class="progress"> |
|||
<div class="progress-bar ok" style="width: 23%"></div> |
|||
<div class="progress-bar in" style="width: 23%"></div> |
|||
<div class="progress-bar overdue" style="width: 23%"></div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
defineOptions({ |
|||
name: "safety-appraise", |
|||
}); |
|||
</script> |
|||
|
|||
<style scoped lang="less"> |
|||
.safety-appraise { |
|||
width: 100%; |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 16px; |
|||
.appraise-wrapper { |
|||
display: flex; |
|||
flex-direction: row; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
.appraise-item { |
|||
width: 104px; |
|||
height: 119px; |
|||
background: url("@/assets/card/safety-item-bg.png") no-repeat; |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: center; |
|||
padding-bottom: 16px; |
|||
.name { |
|||
font-family: Source Han Sans; |
|||
font-size: 14px; |
|||
font-weight: normal; |
|||
line-height: 18px; |
|||
text-align: center; |
|||
letter-spacing: 0em; |
|||
|
|||
font-variation-settings: "opsz" auto; |
|||
font-feature-settings: "kern" on; |
|||
color: #ffffff; |
|||
} |
|||
.count { |
|||
font-family: DIN; |
|||
font-size: 28px; |
|||
font-weight: bold; |
|||
line-height: normal; |
|||
letter-spacing: 0em; |
|||
&.total { |
|||
color: #7be4ff; |
|||
} |
|||
&.wait { |
|||
color: #ffc552; |
|||
} |
|||
&.ok { |
|||
color: #46ffe1; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.appraise-progress { |
|||
width: 100%; |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 16px; |
|||
.tips { |
|||
display: flex; |
|||
align-items: center; |
|||
gap: 12px; |
|||
justify-content: flex-start; |
|||
font-family: Microsoft YaHei; |
|||
font-size: 14px; |
|||
font-weight: normal; |
|||
line-height: 22px; |
|||
letter-spacing: 0px; |
|||
|
|||
font-variation-settings: "opsz" auto; |
|||
color: rgba(0, 0, 0, 0.55); |
|||
span { |
|||
font-family: DIN; |
|||
font-size: 16px; |
|||
font-weight: bold; |
|||
line-height: 22px; |
|||
letter-spacing: 0px; |
|||
|
|||
font-variation-settings: "opsz" auto; |
|||
&.ok { |
|||
color: #28ce8e; |
|||
} |
|||
&.in { |
|||
color: #faad10; |
|||
} |
|||
&.overdue { |
|||
color: #f13939; |
|||
} |
|||
} |
|||
} |
|||
.progress { |
|||
width: 100%; |
|||
background: rgba(255, 255, 255, 0.4); |
|||
height: 24px; |
|||
border-radius: 12px; |
|||
display: flex; |
|||
flex-direction: row; |
|||
align-items: center; |
|||
justify-content: flex-start; |
|||
overflow: hidden; |
|||
.progress-bar { |
|||
height: 100%; |
|||
&.ok { |
|||
background: #28ce8e; |
|||
} |
|||
&.overdue { |
|||
background: #f13939; |
|||
} |
|||
&.in { |
|||
background: #faad10; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -1,11 +1,92 @@ |
|||
<template> |
|||
<div></div> |
|||
<div class="safety-overview-card"> |
|||
<div class="sy-water-cart-title"> |
|||
安全监查情况 |
|||
<el-select class="sy-water-cart-title-select" size="small"> |
|||
<el-option label="近7日" value="1"></el-option> |
|||
</el-select> |
|||
</div> |
|||
<SafetyAppraise /> |
|||
<RiskInspectionCard /> |
|||
<DailyPatrolCard /> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import SafetyAppraise from "../SafetyAppraise/index.vue"; |
|||
import RiskInspectionCard from "../RiskInspectionCard/index.vue"; |
|||
import DailyPatrolCard from "../DailyPatrolCard/index.vue"; |
|||
defineOptions({ |
|||
name: "SafetyOverviewCard", |
|||
}); |
|||
</script> |
|||
|
|||
<style scoped></style> |
|||
<style scoped lang="less"> |
|||
.safety-overview-card { |
|||
width: 100%; |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 16px; |
|||
:deep(.sy-water-cart-title-select) { |
|||
width: 100px; |
|||
background: #36b29e; |
|||
height: 28px; |
|||
line-height: 28px; |
|||
color: #fff; |
|||
.sy-input--small .sy-input__wrapper { |
|||
padding: 1px 7px; |
|||
height: 28px; |
|||
.sy-select__caret { |
|||
color: #fff; |
|||
} |
|||
} |
|||
::-webkit-input-placeholder { |
|||
color: #fff; |
|||
} |
|||
} |
|||
.appraise-wrapper { |
|||
display: flex; |
|||
flex-direction: row; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
.appraise-item { |
|||
width: 104px; |
|||
height: 119px; |
|||
background: url("@/assets/card/safety-item-bg.png") no-repeat; |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: center; |
|||
padding-bottom: 16px; |
|||
.name { |
|||
font-family: Source Han Sans; |
|||
font-size: 14px; |
|||
font-weight: normal; |
|||
line-height: 18px; |
|||
text-align: center; |
|||
letter-spacing: 0em; |
|||
|
|||
font-variation-settings: "opsz" auto; |
|||
font-feature-settings: "kern" on; |
|||
color: #ffffff; |
|||
} |
|||
.count { |
|||
font-family: DIN; |
|||
font-size: 28px; |
|||
font-weight: bold; |
|||
line-height: normal; |
|||
letter-spacing: 0em; |
|||
&.total { |
|||
color: #7be4ff; |
|||
} |
|||
&.wait { |
|||
color: #ffc552; |
|||
} |
|||
&.ok { |
|||
color: #46ffe1; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
|
Loading…
Reference in new issue