forked from gzt/A8000
7 changed files with 112 additions and 141 deletions
-
3components.d.ts
-
129src/components/AlarmLight.vue
-
7src/components/dialogs/AlarmDetailByType.vue
-
3src/components/dialogs/AlarmModal.vue
-
67src/components/dialogs/AlarmRecordModal.vue
-
1src/pages/Index/Index.vue
-
43src/pages/Index/Regular/Running.vue
@ -1,129 +0,0 @@ |
|||
<template> |
|||
<div class="alarm-light-container" @click="onShowAlarmDetail"> |
|||
<div |
|||
class="alarm-light" |
|||
:style="{ '--light-color': getColor }" |
|||
:class="{ 'pulse-animation': isActive }" |
|||
> |
|||
<span class="light-text">{{ text }}</span> |
|||
</div> |
|||
<el-dialog v-model="detailVisible" width="700" style="z-index: 999"> |
|||
<AlarmDetailByType :currEventReport="alarmItem"/> |
|||
</el-dialog> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import { defineProps, computed, ref } from 'vue'; |
|||
import AlarmDetailByType from './dialogs/AlarmDetailByType.vue' |
|||
|
|||
const detailVisible = ref(false) |
|||
const props = defineProps({ |
|||
color: { |
|||
type: String, |
|||
default: 'red', |
|||
validator: (val: string) => |
|||
['red', 'green', 'yellow', 'blue', 'custom'].includes(val) || |
|||
val.startsWith('#') |
|||
}, |
|||
customColor: { |
|||
type: String, |
|||
default: '#ff0000' |
|||
}, |
|||
text: { |
|||
type: String, |
|||
default: 'ALERT' |
|||
}, |
|||
// 动画周期(秒) |
|||
cycleDuration: { |
|||
type: Number, |
|||
default: 2 |
|||
}, |
|||
// 是否激活动画 |
|||
active: { |
|||
type: Boolean, |
|||
default: true |
|||
}, |
|||
alarmItem: { |
|||
type: Object, |
|||
default: () => {} |
|||
} |
|||
}); |
|||
|
|||
const getColor = computed(() => { |
|||
const colorMap: Record<string, string> = { |
|||
'red': '#ff0000', |
|||
'green': '#00cc00', |
|||
'yellow': '#ffff00', |
|||
'blue': '#0066ff', |
|||
'custom': props.customColor |
|||
}; |
|||
return colorMap[props.color] || props.color; |
|||
}); |
|||
|
|||
const isActive = computed(() => props.active); |
|||
|
|||
const onShowAlarmDetail = () => { |
|||
detailVisible.value = true; |
|||
console.log('alarm ==11= ', props.alarmItem) |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.alarm-light-container { |
|||
display: inline-block; |
|||
position: relative; |
|||
} |
|||
|
|||
.alarm-light { |
|||
width: 7rem; |
|||
height: 7rem; |
|||
border-radius: 50%; |
|||
border: 2px solid rgba(255, 255, 255, 0.5); |
|||
position: relative; |
|||
overflow: hidden; |
|||
z-index: 1; |
|||
|
|||
/* 基础样式 */ |
|||
background-color: var(--light-color); |
|||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); |
|||
} |
|||
|
|||
.light-text { |
|||
position: absolute; |
|||
top: 50%; |
|||
left: 50%; |
|||
transform: translate(-50%, -50%); |
|||
font-size: 14px; |
|||
color: white; |
|||
font-weight: bold; |
|||
text-shadow: 0 0 3px rgba(0, 0, 0, 0.8); |
|||
z-index: 2; |
|||
} |
|||
|
|||
/* 从弱到强的脉动动画 */ |
|||
.pulse-animation { |
|||
animation: pulse 2s infinite ease-in-out; |
|||
animation-duration: calc(var(--cycle-duration, 2) * 1s); |
|||
} |
|||
|
|||
@keyframes pulse { |
|||
0%, 100% { |
|||
box-shadow: |
|||
0 0 5px var(--light-color), |
|||
0 0 8px var(--light-color), |
|||
0 0 10px var(--light-color); |
|||
opacity: 0.6; |
|||
transform: scale(0.95); |
|||
} |
|||
50% { |
|||
box-shadow: |
|||
0 0 10px var(--light-color), |
|||
0 0 15px var(--light-color), |
|||
0 0 18px var(--light-color), |
|||
0 0 20px var(--light-color); |
|||
opacity: 1; |
|||
transform: scale(1); |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,67 @@ |
|||
<template> |
|||
<div > |
|||
<!-- 左边报警列表 --> |
|||
<div v-if="alarmList && alarmList.length"> |
|||
<el-table |
|||
ref="tableRef" |
|||
:data="alarmList" |
|||
show-overflow-tooltip |
|||
header-cell-class-name="table-header" |
|||
row-class-name="table-row"> |
|||
<el-table-column type="index" label="序号" width="50"></el-table-column> |
|||
<el-table-column prop="keyName" label="名称" width="170"> |
|||
<template #default="scope"> |
|||
{{ scope.row.flagType === 'NormalFlag' ? scope.row.notTriggeredDisName : scope.row.triggeredStateName}} |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column prop="flagType" label="类型" width="170"> |
|||
<template #default="scope"> |
|||
{{ scope.row.flagType === 'NormalFlag' ? '正常' : scope.row.flagType === 'WarningFlag' ? '警告' : '异常'}} |
|||
</template> |
|||
</el-table-column> |
|||
</el-table> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script lang="ts" setup> |
|||
import { useDeviceStore } from '@/store' |
|||
import type { WarningState } from '@/websocket/socket' |
|||
import { ref, watchEffect } from 'vue' |
|||
const deviceStore = useDeviceStore() |
|||
const alarmList = ref<WarningState[]>([]) |
|||
watchEffect(() => { |
|||
alarmList.value = deviceStore.alarmList |
|||
}) |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.alarm-container { |
|||
min-height: 20vh; |
|||
text-align: start; |
|||
} |
|||
.alarm-item { |
|||
height: 17vh; |
|||
cursor: pointer; |
|||
border-radius: 10px; |
|||
} |
|||
.alarm-item-title{ |
|||
font-weight: bold |
|||
} |
|||
.alarm-name { |
|||
flex: 1; |
|||
} |
|||
.alarm-type { |
|||
margin: 0 10px; |
|||
padding: 2px 6px; |
|||
border-radius: 4px; |
|||
color: #fff; |
|||
} |
|||
|
|||
.clear-alarm-btn{ |
|||
margin-top: 10px; |
|||
height: 4rem; |
|||
font-size: 20px; |
|||
width:7rem; |
|||
} |
|||
</style> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue