2025-10-17 10:31:13 +08:00
|
|
|
<template>
|
|
|
|
|
<div class="center-container">
|
|
|
|
|
<div class="center-content">
|
2025-10-31 14:58:49 +08:00
|
|
|
<!-- 隐患排查治理 这个标题需要隐藏 2025-10-31 -->
|
|
|
|
|
<span class="title"></span>
|
2025-10-17 10:31:13 +08:00
|
|
|
<img class="bottom-border-line" src="@/assets/images/title_border_line_1.png" />
|
2025-10-31 14:58:49 +08:00
|
|
|
<span class="sub-title">隐患等级</span>
|
2025-10-17 10:31:13 +08:00
|
|
|
<img width="50%" src="@/assets/images/line_1.png" />
|
|
|
|
|
|
|
|
|
|
<div class="type-wrapper">
|
|
|
|
|
<div class="type-item">
|
|
|
|
|
<span class="type-btn">重大</span>
|
|
|
|
|
<span class="type-num">{{ hiddenDangerData?.major || 0 }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="type-item">
|
|
|
|
|
<span class="type-btn active">一般</span>
|
|
|
|
|
<span class="type-num">{{ hiddenDangerData?.general || 0 }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="clasic-wrapper">
|
|
|
|
|
<div class="clasic-item">
|
|
|
|
|
<span>处理进度</span>
|
|
|
|
|
<img width="100%" src="@/assets/images/line_1.png" />
|
|
|
|
|
</div>
|
|
|
|
|
<div class="clasic-item">
|
|
|
|
|
<span>Top3隐患类</span>
|
|
|
|
|
<img width="100%" src="@/assets/images/line_1.png" />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="echart-wrapper">
|
|
|
|
|
<div class="lf-rt">
|
|
|
|
|
<Echart :options="progressChartOption" class="progress-chart" height="80%" />
|
|
|
|
|
<div class="progress-legend">
|
|
|
|
|
<div class="legend-item"><span class="dot red"></span>已逾期</div>
|
|
|
|
|
<div class="legend-item"><span class="dot green"></span>已处理</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="progress-legend">
|
|
|
|
|
<!-- <div class="legend-item"><span class="dot yellow"></span>待排查</div>-->
|
|
|
|
|
<div class="legend-item"><span class="dot blue"></span>处理中</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="lf-rt">
|
|
|
|
|
<Echart :options="top3TypesChartOption" class="progress-chart" height="80%" />
|
|
|
|
|
<div class="progress-legend-column">
|
|
|
|
|
<div class="legend-item">
|
|
|
|
|
<span class="dot blue"></span>
|
|
|
|
|
<span class="legend-text">{{ props.hiddenDangerData?.top3Types?.[0]?.order_type_path_name || "--" }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="legend-item">
|
|
|
|
|
<span class="dot green"></span>
|
|
|
|
|
<span class="legend-text">{{ props.hiddenDangerData?.top3Types?.[1]?.order_type_path_name || "--" }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="legend-item">
|
|
|
|
|
<span class="dot yellow"></span>
|
|
|
|
|
<span class="legend-text">{{ props.hiddenDangerData?.top3Types?.[2]?.order_type_path_name || "--" }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="safe-wrapper">
|
|
|
|
|
<span class="safe-title">
|
|
|
|
|
<img width="22" style="margin: 3px 5px 0 0" src="@/assets/images/ybp_icon.png" />
|
|
|
|
|
安全指数:
|
|
|
|
|
</span>
|
|
|
|
|
<span class="pending-count">{{ hiddenDangerData?.safetyIndex || 0 }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
import { ref, onMounted, watch } from 'vue'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
interface Props {
|
|
|
|
|
hiddenDangerData?: {
|
|
|
|
|
general: number
|
|
|
|
|
major: number
|
|
|
|
|
safetyIndex: number
|
|
|
|
|
progress: {
|
|
|
|
|
overdue: number
|
|
|
|
|
processed: number
|
|
|
|
|
pending: number
|
|
|
|
|
processing: number
|
|
|
|
|
}
|
|
|
|
|
top3Types: Array<{
|
|
|
|
|
num: string
|
|
|
|
|
order_type_path_name: string
|
|
|
|
|
row_id: string
|
|
|
|
|
}>
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const props = defineProps<Props>()
|
|
|
|
|
|
|
|
|
|
// 图表引用
|
|
|
|
|
const progressChartOption = ref<any>({
|
|
|
|
|
series: [
|
|
|
|
|
{
|
|
|
|
|
type: 'pie' as const,
|
|
|
|
|
radius: '55%',
|
|
|
|
|
center: ['50%', '50%'],
|
|
|
|
|
left: 0,
|
|
|
|
|
top: 0,
|
|
|
|
|
bottom: 0,
|
|
|
|
|
data: [],
|
|
|
|
|
label: {
|
|
|
|
|
alignTo: 'edge' as const,
|
|
|
|
|
formatter: '{time|{c} %}\n',
|
|
|
|
|
minMargin: 5,
|
|
|
|
|
edgeDistance: 10,
|
|
|
|
|
lineHeight: 15,
|
|
|
|
|
rich: {
|
|
|
|
|
time: {
|
|
|
|
|
fontSize: 10,
|
|
|
|
|
color: '#fff'
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
labelLine: {
|
|
|
|
|
length: 5,
|
|
|
|
|
length2: 0,
|
|
|
|
|
maxSurfaceAngle: 10
|
|
|
|
|
},
|
|
|
|
|
labelLayout: function (params: any) {
|
|
|
|
|
const isLeft = params.labelRect.x < (params.labelRect.width ? params.labelRect.width : 200) / 2;
|
|
|
|
|
const points = params.labelLinePoints;
|
|
|
|
|
|
|
|
|
|
// 添加安全检查
|
|
|
|
|
if (points && points.length >= 3 && points[2]) {
|
|
|
|
|
points[2][0] = isLeft
|
|
|
|
|
? params.labelRect.x
|
|
|
|
|
: params.labelRect.x + params.labelRect.width;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
labelLinePoints: points
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
})
|
|
|
|
|
const top3TypesChartOption = ref<any>({
|
|
|
|
|
series: [
|
|
|
|
|
{
|
|
|
|
|
type: 'pie' as const,
|
|
|
|
|
roseType: 'radius' as const,
|
|
|
|
|
radius: [30, 50],
|
|
|
|
|
center: ['50%', '50%'],
|
|
|
|
|
left: 0,
|
|
|
|
|
top: 0,
|
|
|
|
|
bottom: 0,
|
|
|
|
|
data: [],
|
|
|
|
|
label: {
|
|
|
|
|
alignTo: 'edge' as const,
|
|
|
|
|
formatter: '{time|{c}}\n',
|
|
|
|
|
minMargin: 5,
|
|
|
|
|
edgeDistance: 10,
|
|
|
|
|
lineHeight: 15,
|
|
|
|
|
rich: {
|
|
|
|
|
time: {
|
|
|
|
|
fontSize: 10,
|
|
|
|
|
color: '#fff'
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
labelLine: {
|
|
|
|
|
length: 5,
|
|
|
|
|
length2: 0,
|
|
|
|
|
maxSurfaceAngle: 10
|
|
|
|
|
},
|
|
|
|
|
labelLayout: function (params: any) {
|
|
|
|
|
const isLeft = params.labelRect.x < (params.labelRect.width ? params.labelRect.width : 200) / 2;
|
|
|
|
|
const points = params.labelLinePoints;
|
|
|
|
|
|
|
|
|
|
// 添加安全检查
|
|
|
|
|
if (points && points.length >= 3 && points[2]) {
|
|
|
|
|
points[2][0] = isLeft
|
|
|
|
|
? params.labelRect.x
|
|
|
|
|
: params.labelRect.x + params.labelRect.width;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
labelLinePoints: points
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
watch(() => props.hiddenDangerData?.progress, (newVal) => {
|
|
|
|
|
refreshProcessCharts(newVal)
|
|
|
|
|
}, { deep: true })
|
|
|
|
|
|
|
|
|
|
// 更新图表数据
|
|
|
|
|
const refreshProcessCharts = (process): void => {
|
|
|
|
|
if (!props.hiddenDangerData?.progress) {
|
|
|
|
|
console.warn('process is undefined or null')
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
const option = { ...progressChartOption.value }
|
|
|
|
|
option.series[0].data = [
|
|
|
|
|
{ value: process.overdue || 0, name: '已逾期', itemStyle: { color: '#ef4444' } },
|
|
|
|
|
{ value: process.processed || 0, name: '已处理', itemStyle: { color: '#10b981' } },
|
|
|
|
|
// { value: process.pending || 0, name: '待排查', itemStyle: { color: '#eab308' } },
|
|
|
|
|
{ value: process.processing || 0, name: '处理中', itemStyle: { color: '#3b82f6' } }
|
|
|
|
|
]
|
|
|
|
|
progressChartOption.value = option
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
watch(() => props.hiddenDangerData?.top3Types, (newVal) => {
|
|
|
|
|
refreshTop3TypesCharts(newVal)
|
|
|
|
|
}, { deep: true })
|
|
|
|
|
|
|
|
|
|
// 更新图表数据
|
|
|
|
|
const refreshTop3TypesCharts = (top3Types): void => {
|
|
|
|
|
if (!top3Types || !Array.isArray(top3Types) || top3Types.length === 0) {
|
|
|
|
|
console.warn('top3Types is undefined, null, or empty array')
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
const option = { ...top3TypesChartOption.value }
|
|
|
|
|
|
|
|
|
|
// 定义颜色数组
|
|
|
|
|
const colors = ['#5470c6', '#9edf7f', '#fac858']
|
|
|
|
|
|
|
|
|
|
// 将数组数据转换为图表数据格式
|
|
|
|
|
option.series[0].data = top3Types.slice(0, 3).map((item, index) => ({
|
|
|
|
|
value: Number(item.num) || 0,
|
|
|
|
|
name: item.order_type_path_name || `类型${index + 1}`,
|
|
|
|
|
itemStyle: { color: colors[index] || '#999' }
|
|
|
|
|
}))
|
|
|
|
|
|
|
|
|
|
top3TypesChartOption.value = option
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
|
|
|
|
|
})
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
|
/* 响应式设计 */
|
|
|
|
|
@media (width <=1200px) {
|
|
|
|
|
.center-container {
|
|
|
|
|
width: 60vh;
|
|
|
|
|
height: 60vh;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@media (width <=1024px) {
|
|
|
|
|
.center-container {
|
|
|
|
|
width: 55vh;
|
|
|
|
|
height: 55vh;
|
|
|
|
|
|
|
|
|
|
.center-content {
|
|
|
|
|
.title {
|
|
|
|
|
font-size: 0.8rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.sub-title {
|
|
|
|
|
font-size: 0.7rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.type-wrapper {
|
|
|
|
|
width: 85%;
|
|
|
|
|
|
|
|
|
|
.type-item .type-btn {
|
|
|
|
|
padding: 2px 25px;
|
|
|
|
|
font-size: 0.65rem;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@media (width <=768px) {
|
|
|
|
|
.center-container {
|
|
|
|
|
top: 60%;
|
|
|
|
|
width: 50vh;
|
|
|
|
|
height: 50vh;
|
|
|
|
|
|
|
|
|
|
.center-content {
|
|
|
|
|
.title {
|
|
|
|
|
margin-top: 1.5vh;
|
|
|
|
|
font-size: 0.7rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.sub-title {
|
|
|
|
|
font-size: 0.65rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.type-wrapper {
|
|
|
|
|
width: 90%;
|
|
|
|
|
margin-top: 0.3vh;
|
|
|
|
|
|
|
|
|
|
.type-item {
|
|
|
|
|
.type-btn {
|
|
|
|
|
padding: 2px 20px;
|
|
|
|
|
font-size: 0.6rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.type-num {
|
|
|
|
|
font-size: 0.9rem;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.clasic-wrapper {
|
|
|
|
|
width: 90%;
|
|
|
|
|
margin-top: 1vh;
|
|
|
|
|
|
|
|
|
|
.clasic-item {
|
|
|
|
|
font-size: 0.7rem;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.echart-wrapper {
|
|
|
|
|
width: 90%;
|
|
|
|
|
|
|
|
|
|
.lf-rt .progress-legend .legend-item {
|
|
|
|
|
font-size: 0.6rem;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.safe-wrapper {
|
|
|
|
|
width: 50%;
|
|
|
|
|
|
|
|
|
|
.safe-title {
|
|
|
|
|
font-size: 0.7rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pending-count {
|
|
|
|
|
font-size: 1.4rem;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@media (width <=480px) {
|
|
|
|
|
.center-container {
|
|
|
|
|
top: 65%;
|
|
|
|
|
width: 45vh;
|
|
|
|
|
height: 45vh;
|
|
|
|
|
|
|
|
|
|
.center-content {
|
|
|
|
|
.title {
|
|
|
|
|
margin-top: 1vh;
|
|
|
|
|
font-size: 0.65rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.sub-title {
|
|
|
|
|
font-size: 0.6rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.type-wrapper {
|
|
|
|
|
width: 95%;
|
|
|
|
|
|
|
|
|
|
.type-item .type-btn {
|
|
|
|
|
padding: 1px 15px;
|
|
|
|
|
font-size: 0.55rem;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.echart-wrapper {
|
|
|
|
|
width: 95%;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.safe-wrapper {
|
|
|
|
|
width: 60%;
|
|
|
|
|
|
|
|
|
|
.safe-title {
|
|
|
|
|
font-size: 0.65rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pending-count {
|
|
|
|
|
font-size: 1.2rem;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.center-container {
|
|
|
|
|
position: fixed;
|
|
|
|
|
top: 55%;
|
|
|
|
|
left: 50%;
|
|
|
|
|
z-index: 1;
|
|
|
|
|
display: flex;
|
|
|
|
|
width: 65vh;
|
|
|
|
|
height: 65vh;
|
|
|
|
|
color: #fff;
|
|
|
|
|
background-image: url('@/assets/images/circle_bg.png');
|
|
|
|
|
background-size: cover;
|
|
|
|
|
transform: translate(-50%, -50%);
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
|
|
|
|
.center-content {
|
|
|
|
|
display: flex;
|
|
|
|
|
width: 77%;
|
|
|
|
|
height: 77%;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
align-items: center;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
|
|
|
|
.title {
|
|
|
|
|
margin-top: 2vh;
|
|
|
|
|
font-size: 0.9rem;
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.bottom-border-line {
|
|
|
|
|
width: 20%;
|
|
|
|
|
margin: 1vh 0 1.2vh;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.sub-title {
|
|
|
|
|
font-size: 0.8rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.type-wrapper {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-around;
|
|
|
|
|
width: 80%;
|
|
|
|
|
font-size: 0.8rem;
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
|
|
|
|
.type-item {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
align-items: center;
|
|
|
|
|
margin-top: 0.5vh;
|
|
|
|
|
|
|
|
|
|
.type-btn {
|
|
|
|
|
padding: 2px 30px;
|
|
|
|
|
margin-bottom: 5px;
|
|
|
|
|
font-size: 0.7rem;
|
|
|
|
|
background-color: #d97706;
|
|
|
|
|
border-radius: 15px;
|
|
|
|
|
|
|
|
|
|
&.active {
|
|
|
|
|
background-color: #059669;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.type-num {
|
|
|
|
|
font-size: 1rem;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.clasic-wrapper {
|
|
|
|
|
display: flex;
|
|
|
|
|
width: 80%;
|
|
|
|
|
margin-top: 1.2vh;
|
|
|
|
|
font-size: 0.8rem;
|
|
|
|
|
color: #fff;
|
|
|
|
|
justify-content: space-around;
|
|
|
|
|
|
|
|
|
|
.clasic-item {
|
|
|
|
|
display: flex;
|
|
|
|
|
width: 45%;
|
|
|
|
|
margin-top: 0.6vh;
|
|
|
|
|
margin-bottom: -1vh;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
|
|
img {
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 2px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.echart-wrapper {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
align-items: center;
|
|
|
|
|
width: 85%;
|
|
|
|
|
height: 75%;
|
|
|
|
|
|
|
|
|
|
.lf-rt {
|
|
|
|
|
display: flex;
|
|
|
|
|
width: 50%;
|
|
|
|
|
height: 100%;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
|
|
|
|
.progress-chart {
|
|
|
|
|
display: flex;
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 80%;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.progress-legend {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
gap: 8px;
|
|
|
|
|
|
|
|
|
|
.legend-item {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 4px;
|
|
|
|
|
font-size: 0.7rem;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.progress-legend-column {
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 8px;
|
|
|
|
|
|
|
|
|
|
.legend-item {
|
|
|
|
|
display: flex;
|
|
|
|
|
width: 60%;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 4px;
|
|
|
|
|
|
|
|
|
|
.legend-text {
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
font-size: 0.7rem;
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
flex: 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.safe-wrapper {
|
|
|
|
|
display: flex;
|
|
|
|
|
width: 40%;
|
|
|
|
|
height: 20%;
|
|
|
|
|
margin-bottom: 5%;
|
|
|
|
|
align-items: center;
|
|
|
|
|
column-gap: 1vw;
|
|
|
|
|
|
|
|
|
|
.safe-title {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
margin-left: 1vw;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pending-count {
|
|
|
|
|
margin-bottom: 0.7vh;
|
|
|
|
|
font-size: 1.6rem;
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
color: yellow;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.dot {
|
|
|
|
|
width: 8px;
|
|
|
|
|
height: 8px;
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.dot.red {
|
|
|
|
|
background-color: #ef4444;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.dot.green {
|
|
|
|
|
background-color: #9edf7f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.dot.yellow {
|
|
|
|
|
background-color: #eab308;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.dot.blue {
|
|
|
|
|
background-color: #3b82f6;
|
|
|
|
|
}
|
|
|
|
|
</style>
|