|
|
|
<template>
|
|
|
|
<div class="title">
|
|
|
|
<h3>{{ titleData }}</h3>
|
|
|
|
</div>
|
|
|
|
<div class="weather">
|
|
|
|
<div class="users">{{ timePeriod }} {{ userStore.nickname }}</div>
|
|
|
|
<div class="timeTips">
|
|
|
|
<div class="time">{{ currentTime }} {{ lunarDay.ncWeek }}</div>
|
|
|
|
<div class="line"></div>
|
|
|
|
<div class="forecast">
|
|
|
|
<span>{{ weatherData.city }}:{{ weatherData.weather }} {{ weatherData.temperature }}℃</span>
|
|
|
|
<svg-icon class="weatherSvg" :icon-class="weatherData.weatherImg" />
|
|
|
|
<!-- <img src="../../../assets/images/weather/duoyun.png" /> -->
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="seeting">
|
|
|
|
<n-tooltip trigger="hover">
|
|
|
|
<template #trigger>
|
|
|
|
<n-button class="tooltips" circle dashed @click="returnBack">
|
|
|
|
<template #icon>
|
|
|
|
<n-icon>
|
|
|
|
<ReturnDownBack />
|
|
|
|
</n-icon>
|
|
|
|
</template>
|
|
|
|
</n-button>
|
|
|
|
</template>
|
|
|
|
返回上一页
|
|
|
|
</n-tooltip>
|
|
|
|
<n-tooltip trigger="hover">
|
|
|
|
<template #trigger>
|
|
|
|
<n-button class="tooltips" circle dashed @click="lineClick">
|
|
|
|
<template #icon>
|
|
|
|
<n-icon>
|
|
|
|
<ChartLine />
|
|
|
|
</n-icon>
|
|
|
|
</template>
|
|
|
|
</n-button>
|
|
|
|
</template>
|
|
|
|
图表
|
|
|
|
</n-tooltip>
|
|
|
|
<n-tooltip trigger="hover" v-if="settingShow">
|
|
|
|
<template #trigger>
|
|
|
|
<n-button class="tooltips" circle dashed @click="showClick">
|
|
|
|
<template #icon>
|
|
|
|
<n-icon>
|
|
|
|
<Settings />
|
|
|
|
</n-icon>
|
|
|
|
</template>
|
|
|
|
</n-button>
|
|
|
|
</template>
|
|
|
|
显示项
|
|
|
|
</n-tooltip>
|
|
|
|
<n-tooltip trigger="hover" v-if="warningShow">
|
|
|
|
<template #trigger>
|
|
|
|
<n-badge class="warningbadge" :value="waringData.length" :max="15">
|
|
|
|
<n-button class="tooltips" circle dashed @click="waringClick">
|
|
|
|
<template #icon>
|
|
|
|
<n-icon>
|
|
|
|
<Bell />
|
|
|
|
</n-icon>
|
|
|
|
</template>
|
|
|
|
</n-button>
|
|
|
|
</n-badge>
|
|
|
|
</template>
|
|
|
|
报警
|
|
|
|
</n-tooltip>
|
|
|
|
</div>
|
|
|
|
<n-drawer class="waringDrawer" v-model:show="waringDrawer" :default-width="420" resizable placement="right">
|
|
|
|
<n-drawer-content closable>
|
|
|
|
<template #header>
|
|
|
|
<div class="title">
|
|
|
|
<span>消息</span>
|
|
|
|
<span class="button" @click="waringMore">更多</span>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
<div class="waringList">
|
|
|
|
<div class="item" v-for="(item, index) in waringData" :key="index">
|
|
|
|
<div class="name">
|
|
|
|
<div class="title">
|
|
|
|
<svg-icon icon-class="alarm" v-if="audioType === true && item.alertSwitch === '1'" />
|
|
|
|
<span>{{ item.deviceName }}</span>
|
|
|
|
</div>
|
|
|
|
<span class="time">{{ item.alertTime }}</span>
|
|
|
|
</div>
|
|
|
|
<div class="info">
|
|
|
|
<span>{{ item.paramName }}</span>
|
|
|
|
<!-- <n-button type="info" size="small" @click="waringConfirm(item)">确认</n-button> -->
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</n-drawer-content>
|
|
|
|
</n-drawer>
|
|
|
|
<n-modal class="waringModal" v-model:show="waringModal">
|
|
|
|
<n-card :bordered="false" size="huge" role="dialog" aria-modal="true">
|
|
|
|
<el-table
|
|
|
|
class="waringTable"
|
|
|
|
:data="waringList"
|
|
|
|
header-row-class-name="headerRowClass"
|
|
|
|
header-cell-class-name="headerCellClass"
|
|
|
|
row-class-name="rowClass"
|
|
|
|
cell-class-name="cellClass"
|
|
|
|
height="350"
|
|
|
|
stripe
|
|
|
|
>
|
|
|
|
<el-table-column prop="deviceName" label="设备名称" align="center" />
|
|
|
|
<el-table-column prop="paramName" label="变量名称" align="center" />
|
|
|
|
<el-table-column prop="alertName" label="告警级别" align="center">
|
|
|
|
<template #default="scope">
|
|
|
|
<span class="level">{{ scope.row.alertName }}</span>
|
|
|
|
</template>
|
|
|
|
</el-table-column>
|
|
|
|
<el-table-column prop="totalCounts" label="告警累计" align="center" />
|
|
|
|
<el-table-column label="报警时间" align="center">
|
|
|
|
<el-table-column prop="alertFirstTimeS" label="首次告警时间" align="center" />
|
|
|
|
<el-table-column prop="alertLastTimeS" label="末次告警时间" align="center" />
|
|
|
|
</el-table-column>
|
|
|
|
<el-table-column fixed="right" label="操作" align="center">
|
|
|
|
<template #default="scope">
|
|
|
|
<el-switch
|
|
|
|
v-model="scope.row.alertSwitchBoolean"
|
|
|
|
inline-prompt
|
|
|
|
active-text="开"
|
|
|
|
inactive-text="关"
|
|
|
|
@change="alarrmChange($event, scope.row)"
|
|
|
|
/>
|
|
|
|
<el-button class="confirm" type="info" size="small" @click="waringConfirm(scope.row)">确认</el-button>
|
|
|
|
</template>
|
|
|
|
</el-table-column>
|
|
|
|
</el-table>
|
|
|
|
<el-pagination
|
|
|
|
class="waringPagination"
|
|
|
|
layout="prev, pager, next"
|
|
|
|
:current-page.sync="params.pageNum"
|
|
|
|
:page-size="params.pageSize"
|
|
|
|
:total="params.total"
|
|
|
|
hide-on-single-page
|
|
|
|
@current-change="handleCurrentChange"
|
|
|
|
/>
|
|
|
|
<div class="warClose" @click="warClose">
|
|
|
|
<CloseCircleOutline />
|
|
|
|
</div>
|
|
|
|
</n-card>
|
|
|
|
</n-modal>
|
|
|
|
<div class="alarm">
|
|
|
|
<audio loop autoplay ref="alarsRef" ebkit-playsinline="true" playsinline="true" controls="controls" muted hidden>
|
|
|
|
<source :src="audisUrl" type="audio/mp3" />
|
|
|
|
</audio>
|
|
|
|
<audio
|
|
|
|
loop
|
|
|
|
autoplay
|
|
|
|
ref="alarmRef"
|
|
|
|
ebkit-playsinline="true"
|
|
|
|
playsinline="true"
|
|
|
|
:src="audioUrl"
|
|
|
|
muted
|
|
|
|
hidden
|
|
|
|
></audio>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
<script setup>
|
|
|
|
import { useRoute, useRouter } from 'vue-router';
|
|
|
|
import { useUserStore } from '@/store/modules/user';
|
|
|
|
import { getWeather } from '@/api/user/index';
|
|
|
|
import { getWarList, process, setAlarm } from '@/api/waring/index';
|
|
|
|
// import { waringVo } from '@/api/waring/types';
|
|
|
|
import { Filter, Maximize, Settings, Power, Bell, ChartLine } from '@vicons/tabler';
|
|
|
|
import { CloseCircleOutline, ReturnDownBack } from '@vicons/ionicons5';
|
|
|
|
import { useDateFormat, useNow } from '@vueuse/core';
|
|
|
|
// import { uniqueArrayObject } from '@/utils/index';
|
|
|
|
import canAutoPlay from 'can-autoplay';
|
|
|
|
import mitt from '@/plugins/bus';
|
|
|
|
import calendar from '@/utils/lunar';
|
|
|
|
import audioUrl from '@/assets/media/alarm.mp3';
|
|
|
|
|
|
|
|
const audisUrl = ref('');
|
|
|
|
const userStore = useUserStore();
|
|
|
|
const hoursNow = useNow().value.getHours();
|
|
|
|
const route = useRoute();
|
|
|
|
const router = useRouter();
|
|
|
|
|
|
|
|
const currentTime = useDateFormat(useNow(), 'YYYY-MM-DD HH:mm:ss');
|
|
|
|
const emit = defineEmits(['showModalClick', 'returnClick']);
|
|
|
|
const timer = ref();
|
|
|
|
const isCurrentRoute = ref(true);
|
|
|
|
const waringDrawer = ref(false);
|
|
|
|
const waringModal = ref(false);
|
|
|
|
// const waringData = ref<waringVo[]>([]);
|
|
|
|
// const waringList = ref<waringVo[]>([]);
|
|
|
|
const waringData = ref([]);
|
|
|
|
const waringList = ref([]);
|
|
|
|
const routerType = ref('');
|
|
|
|
const deptId = ref(0);
|
|
|
|
const params = reactive({
|
|
|
|
total: 10,
|
|
|
|
pageSize: 10,
|
|
|
|
pageNum: 1
|
|
|
|
});
|
|
|
|
|
|
|
|
const alarmRef = ref();
|
|
|
|
const alarsRef = ref();
|
|
|
|
const audioType = ref(false);
|
|
|
|
|
|
|
|
const weatherData = ref({ city: '', weather: '', temperature: '', weatherImg: '' });
|
|
|
|
|
|
|
|
const lunarDay = calendar.solarToLunar(
|
|
|
|
useNow().value.getUTCFullYear(),
|
|
|
|
useNow().value.getUTCMonth() + 1,
|
|
|
|
useNow().value.getUTCDate()
|
|
|
|
);
|
|
|
|
const props = defineProps({
|
|
|
|
titleData: {
|
|
|
|
type: String,
|
|
|
|
default: '数据大屏'
|
|
|
|
},
|
|
|
|
settingShow: {
|
|
|
|
type: Boolean,
|
|
|
|
default: false
|
|
|
|
},
|
|
|
|
warningShow: {
|
|
|
|
type: Boolean,
|
|
|
|
default: false
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
deptId.value = sessionStorage.getItem('deptId') === null ? 0 : Number(sessionStorage.getItem('deptId'));
|
|
|
|
routerType.value = route.query?.id === undefined ? '0' : '1';
|
|
|
|
getWeatherData();
|
|
|
|
document.body.addEventListener('mousedown', function () {
|
|
|
|
console.log('鼠标按下');
|
|
|
|
alarsRef.value.play();
|
|
|
|
alarsRef.value.muted = false;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
const timePeriod = computed(() => {
|
|
|
|
if (hoursNow >= 3 && hoursNow < 8) {
|
|
|
|
return '早安!';
|
|
|
|
} else if (hoursNow >= 8 && hoursNow < 11) {
|
|
|
|
return '上午好!';
|
|
|
|
} else if (hoursNow >= 11 && hoursNow < 13) {
|
|
|
|
return '中午好!';
|
|
|
|
} else if (hoursNow >= 13 && hoursNow < 17) {
|
|
|
|
return '下午好!';
|
|
|
|
} else if (hoursNow >= 17 && hoursNow < 23) {
|
|
|
|
return '晚上好!';
|
|
|
|
} else if (hoursNow >= 23 && hoursNow < 3) {
|
|
|
|
return '晚安!';
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
mitt.on('waringMessage', res => {
|
|
|
|
//监听报警信息
|
|
|
|
console.log('waringMessage--', res.data);
|
|
|
|
waringData.value = res.data;
|
|
|
|
res.data.map(item => {
|
|
|
|
// console.log(item.deviceName, item.alertSwitch);
|
|
|
|
if (item.alertSwitch === '1') {
|
|
|
|
// alarmRef.value.play();
|
|
|
|
// debugger;
|
|
|
|
// if (alarmRef.value) {
|
|
|
|
// // 模拟用户点击事件
|
|
|
|
// alarmRef.value.addEventListener('canplay', () => {
|
|
|
|
// audioType.value = true;
|
|
|
|
// alarmRef.value.play();
|
|
|
|
// // alarmRef.value.muted = false;
|
|
|
|
// });
|
|
|
|
// const playPromise = alarmRef.value.play();
|
|
|
|
// if (playPromise !== undefined) {
|
|
|
|
// playPromise.catch(error => {
|
|
|
|
// console.error(`Failed to play audio: ${error}`);
|
|
|
|
// });
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
canAutoPlay.audio().then(({ result }) => {
|
|
|
|
console.log('result--', result);
|
|
|
|
if (result === true) {
|
|
|
|
audioType.value = true;
|
|
|
|
alarmRef.value.play();
|
|
|
|
alarmRef.value.muted = false;
|
|
|
|
} else {
|
|
|
|
ElMessageBox.alert('检测到您的浏览器不支持媒体自动播放,是否同意播放提示音?', '提示', {
|
|
|
|
// if you want to disable its autofocus
|
|
|
|
// autofocus: false,
|
|
|
|
showClose: false,
|
|
|
|
confirmButtonText: '同意',
|
|
|
|
callback: action => {
|
|
|
|
audioType.value = true;
|
|
|
|
alarmRef.value.play();
|
|
|
|
alarmRef.value.muted = false;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
// waringData.value.push(res.data)
|
|
|
|
// console.log("waringData--", waringData.value);
|
|
|
|
// waringData.value = uniqueArrayObject(waringData.value, "id")
|
|
|
|
// console.log("waringData--", waringData.value);
|
|
|
|
});
|
|
|
|
|
|
|
|
function showClick() {
|
|
|
|
//显示/隐藏表格配置栏
|
|
|
|
emit('showModalClick', true);
|
|
|
|
// showModal.value = true;
|
|
|
|
}
|
|
|
|
function returnBack() {
|
|
|
|
//返回首页
|
|
|
|
// emit('returnClick', '');
|
|
|
|
if (routerType.value === '1' && route.path != '/screen') {
|
|
|
|
router.push({
|
|
|
|
path: '/screen',
|
|
|
|
query: { id: sessionStorage.getItem('id') }
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
router.replace('/dashboard');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function waringClick() {
|
|
|
|
//点击报警按钮
|
|
|
|
// if (waringData.value.length === 0) {
|
|
|
|
// ElNotification({
|
|
|
|
// message: '暂没有报警信息!',
|
|
|
|
// type: 'info',
|
|
|
|
// })
|
|
|
|
// } else {
|
|
|
|
waringDrawer.value = true;
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
|
|
|
|
function lineClick() {
|
|
|
|
//跳转图表
|
|
|
|
router.push({
|
|
|
|
path: '/details'
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function handleCurrentChange(val) {
|
|
|
|
//点击分页
|
|
|
|
params.pageNum = val;
|
|
|
|
getwaringList();
|
|
|
|
}
|
|
|
|
|
|
|
|
function getWeatherData() {
|
|
|
|
//获取天气
|
|
|
|
getWeather().then(res => {
|
|
|
|
if (res.code === 200) {
|
|
|
|
if (isCurrentRoute.value) {
|
|
|
|
timer.value = setTimeout(async () => {
|
|
|
|
await (timer.value && clearTimeout(timer.value));
|
|
|
|
await getWeatherData();
|
|
|
|
}, 600000);
|
|
|
|
}
|
|
|
|
weatherData.value = res.data;
|
|
|
|
} else {
|
|
|
|
clearTimeout(timer.value);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function waringMore() {
|
|
|
|
//点击报警更多
|
|
|
|
waringDrawer.value = false;
|
|
|
|
waringModal.value = true;
|
|
|
|
getwaringList();
|
|
|
|
}
|
|
|
|
function getwaringList() {
|
|
|
|
//报警列表
|
|
|
|
const paramsr = {
|
|
|
|
beginTime: '',
|
|
|
|
endTime: '',
|
|
|
|
orgCode: sessionStorage.getItem('deptId') === null ? 0 : Number(sessionStorage.getItem('deptId')),
|
|
|
|
params
|
|
|
|
};
|
|
|
|
getWarList(paramsr).then(res => {
|
|
|
|
if (res.code === 200) {
|
|
|
|
waringList.value = res.rows;
|
|
|
|
params.total = res.total;
|
|
|
|
// page.pageSize = res.size;
|
|
|
|
// page.pageSize = res.current;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
function alarrmChange(val, row) {
|
|
|
|
//关闭报警
|
|
|
|
const paramsr = {
|
|
|
|
id: row.id,
|
|
|
|
flag: val === true ? '1' : '0'
|
|
|
|
};
|
|
|
|
setAlarm(paramsr).then(res => {
|
|
|
|
if (res.code === 200) {
|
|
|
|
if (val === false) {
|
|
|
|
audioType.value = false;
|
|
|
|
alarmRef.value.pause();
|
|
|
|
alarmRef.value.muted = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
function waringConfirm(item) {
|
|
|
|
//报警确认
|
|
|
|
ElMessageBox.confirm('是否确认操作?', '提示', {
|
|
|
|
confirmButtonText: '确认',
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
type: 'warning'
|
|
|
|
})
|
|
|
|
.then(() => {
|
|
|
|
const params = item.id;
|
|
|
|
process(params).then(res => {
|
|
|
|
if (res.code === 200) {
|
|
|
|
waringList.value = res.data;
|
|
|
|
// waringDrawer.value = false
|
|
|
|
// waringModal.value = false
|
|
|
|
getwaringList();
|
|
|
|
ElMessage({
|
|
|
|
message: res.msg,
|
|
|
|
grouping: true, //分组消息合并
|
|
|
|
type: 'success'
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
})
|
|
|
|
.catch(() => {});
|
|
|
|
}
|
|
|
|
function warClose() {
|
|
|
|
//报警列表关闭
|
|
|
|
waringModal.value = false;
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
.header {
|
|
|
|
display: flex;
|
|
|
|
justify-content: space-between;
|
|
|
|
align-items: center;
|
|
|
|
// height: 5.7rem;
|
|
|
|
|
|
|
|
.title {
|
|
|
|
width: 80%;
|
|
|
|
height: 70px;
|
|
|
|
line-height: 70px;
|
|
|
|
// background: url(@/assets/images/title-bg.png);
|
|
|
|
// background-size: 100%;
|
|
|
|
text-align: center;
|
|
|
|
// padding-bottom: 22px;
|
|
|
|
margin: 0 auto;
|
|
|
|
|
|
|
|
h3 {
|
|
|
|
font-size: 4.2rem;
|
|
|
|
font-family: 'YouSheBiaoTiHei';
|
|
|
|
font-weight: 400;
|
|
|
|
letter-spacing: 4px;
|
|
|
|
background: linear-gradient(180deg, #fefdff 0%, #1677b3 100%);
|
|
|
|
background-clip: text;
|
|
|
|
-webkit-background-clip: text;
|
|
|
|
-webkit-text-fill-color: transparent;
|
|
|
|
margin: 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.weather {
|
|
|
|
position: absolute;
|
|
|
|
top: 10px;
|
|
|
|
left: 7rem;
|
|
|
|
font-size: 1.6rem;
|
|
|
|
font-family: 'AlibabaPuHuiTiRegular';
|
|
|
|
.timeTips {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
// color: #b2d4ff;
|
|
|
|
}
|
|
|
|
|
|
|
|
.line {
|
|
|
|
width: 2px;
|
|
|
|
height: 2rem;
|
|
|
|
background: linear-gradient(to top, #000e38, #1ea8dd, #000e38);
|
|
|
|
margin: 0 1rem;
|
|
|
|
}
|
|
|
|
|
|
|
|
.forecast {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
.weatherSvg {
|
|
|
|
width: 1.5em !important;
|
|
|
|
height: 1.5em !important;
|
|
|
|
margin-left: 10px;
|
|
|
|
}
|
|
|
|
|
|
|
|
// img {
|
|
|
|
// width: 25px;
|
|
|
|
// margin-left: 10px;
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.seeting {
|
|
|
|
position: absolute;
|
|
|
|
top: 20px;
|
|
|
|
right: 7rem;
|
|
|
|
|
|
|
|
.warningbadge {
|
|
|
|
margin-top: -10px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.tooltips {
|
|
|
|
width: 36px;
|
|
|
|
height: 36px;
|
|
|
|
// background: linear-gradient(180deg, #003269 1%, rgba(3, 79, 163, 0.2314) 56%, #003269 100%);
|
|
|
|
border-radius: 0px 0px 0px 0px;
|
|
|
|
opacity: 1;
|
|
|
|
|
|
|
|
// :deep(span) {
|
|
|
|
// color: #5beff9;
|
|
|
|
// }
|
|
|
|
|
|
|
|
margin-left: 10px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.waringModal {
|
|
|
|
.waringPagination {
|
|
|
|
justify-content: right;
|
|
|
|
margin-top: 5px;
|
|
|
|
:deep(button) {
|
|
|
|
color: #b1e3ff;
|
|
|
|
background: transparent;
|
|
|
|
}
|
|
|
|
:deep(.el-pager) {
|
|
|
|
.number,
|
|
|
|
.more {
|
|
|
|
color: #b1e3ff;
|
|
|
|
background: transparent;
|
|
|
|
}
|
|
|
|
.number.is-active {
|
|
|
|
color: #409eff;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</style>
|