247 lines
4.5 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<teleport to="body">
<transition name="emergency-modal">
<div class="modal-mask" @click.self="$emit('close')">
<div class="emergency-modal" :class="{ 'emergency-pulse': show }">
<div class="glow"></div>
<div class="modal-header">
<div class="warning-icon"></div>
<h2>{{ title }}</h2>
</div>
<div class="modal-content">
<p>{{ content }}</p>
</div>
<button class="emergency-button" @click="handleAudioEnd">
<span class="button-text">立即处理</span>
<div class="button-glow"></div>
</button>
<!-- <audio ref="audioPlayer" autoplay loop>
<source src="../assets/audio/alarm.mp3" type="video/mp3" />
</audio> -->
</div>
</div>
</transition>
</teleport>
</template>
<script setup lang="ts">
import { onMounted, ref } from "vue";
const audioPlayer = ref(null);
defineProps({
show: Boolean,
title: {
type: String,
default: "紧急警报!",
},
content: {
type: String,
default: "检测到危险操作,请立即处理!",
},
});
defineEmits(["close", "confirm"]);
const handleAudioEnd = () => {
if (audioPlayer.value) {
audioPlayer.value.play().catch((error) => {
console.error("自动播放被阻止:", error);
});
}
};
onMounted(() => {
// 确保在DOM完全加载后播放音频
// if (audioPlayer.value) {
// setTimeout(() => {
// audioPlayer.value.play();
// });
// audioPlayer.value.play();
// // 设置音频静音,浏览器允许自动播放
// audioPlayer.value
// .play()
// .then(() => {
// // 自动播放成功后取消静音
// audioPlayer.value.muted = false;
// })
// .catch((error) => {
// console.log("自动播放失败", error);
// });
// }
});
</script>
<style scoped>
.modal-mask {
position: fixed;
z-index: 9998;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(4px);
display: flex;
justify-content: center;
align-items: center;
}
.emergency-modal {
position: relative;
width: 300px;
padding: 2rem;
background: #2a0a0a;
border-radius: 12px;
border: 2px solid #ff4444;
box-shadow: 0 0 40px rgba(255, 68, 68, 0.3);
transform-origin: center;
overflow: hidden;
display: flex;
flex-direction: column;
align-items: center;
}
.glow {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: radial-gradient(circle at 50% 50%, rgba(255, 68, 68, 0.3) 0%, rgba(255, 68, 68, 0) 70%);
animation: glow-pulse 2s infinite;
}
.modal-header {
display: flex;
align-items: center;
margin-bottom: 1.5rem;
}
.warning-icon {
font-size: 3rem;
margin-right: 1rem;
animation: shake 0.8s ease infinite;
}
h2 {
color: #ff4444;
font-size: 1.8rem;
margin: 0;
}
.modal-content {
color: #ffaaaa;
margin-bottom: 2rem;
line-height: 1.5;
}
.emergency-button {
position: relative;
padding: 1rem 2rem;
background: linear-gradient(45deg, #ff4444, #ff0000);
border: none;
border-radius: 8px;
color: white;
font-weight: bold;
cursor: pointer;
overflow: hidden;
transition: transform 0.2s;
}
.button-glow {
position: absolute;
top: 0;
left: -100%;
width: 200%;
height: 100%;
background: linear-gradient(45deg, transparent 25%, rgba(255, 255, 255, 0.2) 50%, transparent 75%);
animation: slide 1.5s infinite;
}
.emergency-button:hover {
transform: scale(1.05);
}
.emergency-button:active {
transform: scale(0.95);
}
/* 动画效果 */
@keyframes emergency-pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(1.02);
}
100% {
transform: scale(1);
}
}
@keyframes shake {
0% {
transform: translateX(0);
}
25% {
transform: translateX(-5px);
}
50% {
transform: translateX(5px);
}
75% {
transform: translateX(-3px);
}
100% {
transform: translateX(0);
}
}
@keyframes glow-pulse {
0% {
opacity: 0.6;
}
50% {
opacity: 1;
}
100% {
opacity: 0.6;
}
}
@keyframes slide {
to {
left: 100%;
}
}
.emergency-modal-enter-active {
animation: emergency-modal-in 0.3s;
}
.emergency-modal-leave-active {
animation: emergency-modal-in 0.3s reverse;
}
@keyframes emergency-modal-in {
0% {
transform: scale(0.5);
opacity: 0;
}
60% {
transform: scale(1.05);
}
100% {
transform: scale(1);
opacity: 1;
}
}
.emergency-pulse {
animation: emergency-pulse 1.5s infinite;
}
</style>