|
@@ -76,7 +76,10 @@
|
|
|
class="elderly-card-large"
|
|
class="elderly-card-large"
|
|
|
v-for="elderly in filteredElderlyList"
|
|
v-for="elderly in filteredElderlyList"
|
|
|
:key="elderly.id"
|
|
:key="elderly.id"
|
|
|
- :class="{ active: selectedElderly?.id === elderly.id }"
|
|
|
|
|
|
|
+ :class="{
|
|
|
|
|
+ active: selectedElderly?.id === elderly.id,
|
|
|
|
|
+ flashing: elderly._flashEffect
|
|
|
|
|
+ }"
|
|
|
@click="selectElderly(elderly)"
|
|
@click="selectElderly(elderly)"
|
|
|
>
|
|
>
|
|
|
<div class="elderly-avatar-large">
|
|
<div class="elderly-avatar-large">
|
|
@@ -525,7 +528,7 @@ const healthIconMap: Record<string, string> = {
|
|
|
血脂: 'mdi:blood-bag',
|
|
血脂: 'mdi:blood-bag',
|
|
|
呼吸频率: 'mdi:lungs',
|
|
呼吸频率: 'mdi:lungs',
|
|
|
步数: 'mdi:walk',
|
|
步数: 'mdi:walk',
|
|
|
- 睡眠质量: 'mdi:sleep',
|
|
|
|
|
|
|
+ 睡眠: 'mdi:sleep',
|
|
|
体重: 'mdi:scale',
|
|
体重: 'mdi:scale',
|
|
|
身高: 'mdi:human-male-height',
|
|
身高: 'mdi:human-male-height',
|
|
|
BMI: 'mdi:human-male-height-variant',
|
|
BMI: 'mdi:human-male-height-variant',
|
|
@@ -1290,9 +1293,10 @@ const handleOpen = (event) => {
|
|
|
// 发送身份验证消息
|
|
// 发送身份验证消息
|
|
|
let postData = {
|
|
let postData = {
|
|
|
type: 'AUTH',
|
|
type: 'AUTH',
|
|
|
- clientType: 'monitor',
|
|
|
|
|
|
|
+ clientType: 'homecare-web',
|
|
|
clientId: generateClientId(),
|
|
clientId: generateClientId(),
|
|
|
- timestamp: Date.now()
|
|
|
|
|
|
|
+ timestamp: Date.now(),
|
|
|
|
|
+ accessToken: `Bearer ${getAccessToken()}`
|
|
|
}
|
|
}
|
|
|
sendMessage(postData)
|
|
sendMessage(postData)
|
|
|
}
|
|
}
|
|
@@ -1530,6 +1534,9 @@ const processIncomingData = (data) => {
|
|
|
// 需要展示的数据
|
|
// 需要展示的数据
|
|
|
handleSOSAlert(data)
|
|
handleSOSAlert(data)
|
|
|
break
|
|
break
|
|
|
|
|
+ case 'HEALTH_ALERT':
|
|
|
|
|
+ handleHealthAlert(data)
|
|
|
|
|
+ break
|
|
|
case 'DEVICE_DATA_UPDATE':
|
|
case 'DEVICE_DATA_UPDATE':
|
|
|
handleDeviceData(data)
|
|
handleDeviceData(data)
|
|
|
break
|
|
break
|
|
@@ -1564,47 +1571,99 @@ const handleSOSAlert = (alertData) => {
|
|
|
alertId: alertData.timestamp,
|
|
alertId: alertData.timestamp,
|
|
|
timestamp: Date.now()
|
|
timestamp: Date.now()
|
|
|
})
|
|
})
|
|
|
- // notification.warning({
|
|
|
|
|
- // message: h('div', {
|
|
|
|
|
- // style: {
|
|
|
|
|
- // color: '#fff',
|
|
|
|
|
- // // fontSize: '18px'
|
|
|
|
|
- // fontSize: '0.1rem'
|
|
|
|
|
- // },
|
|
|
|
|
- // innerHTML: `
|
|
|
|
|
- // <div>🚨🚨 SOS紧急预警 🚨🚨</div>
|
|
|
|
|
- // `
|
|
|
|
|
- // }),
|
|
|
|
|
- // duration: 10,
|
|
|
|
|
- // // duration: null,
|
|
|
|
|
- // class: 'my-warning-notification',
|
|
|
|
|
- // style: {
|
|
|
|
|
- // background: 'linear-gradient(135deg, #1e4184 0%, #3469e3 100%) !important',
|
|
|
|
|
- // border: '1px solid rgba(42, 157, 143, 0.3) !important',
|
|
|
|
|
- // 'box-shadow': '0 4px 20px rgba(0, 0, 0, 0.5) !important',
|
|
|
|
|
- // color: '#fff !important',
|
|
|
|
|
- // width: '2rem !important'
|
|
|
|
|
- // },
|
|
|
|
|
- // description: h('div', {
|
|
|
|
|
- // style: {
|
|
|
|
|
- // color: '#fff',
|
|
|
|
|
- // fontSize: '0.1rem'
|
|
|
|
|
- // },
|
|
|
|
|
- // innerHTML: `
|
|
|
|
|
- // <div>院区名称: ${alert.organizationName || '未知'}</div>
|
|
|
|
|
- // <div>长者姓名: ${alert.elderName || '未知'}</div>
|
|
|
|
|
- // <div>长者房间: ${alert.roomName || '未知'}</div>
|
|
|
|
|
- // <div>设备类型: ${alert.deviceType || '未知'}</div>
|
|
|
|
|
- // <div>设备电量: ${alert.batteryLevel || '0%'}</div>
|
|
|
|
|
- // <div>时间: ${new Date(alertData.timestamp).toLocaleString()}</div>
|
|
|
|
|
- // `
|
|
|
|
|
- // })
|
|
|
|
|
- // })
|
|
|
|
|
|
|
+ ElNotification({
|
|
|
|
|
+ title: '🚨🚨 SOS紧急预警 🚨🚨',
|
|
|
|
|
+ customClass: 'my-warning-notification',
|
|
|
|
|
+ message: h('div', {
|
|
|
|
|
+ style: {
|
|
|
|
|
+ color: '#fff'
|
|
|
|
|
+ },
|
|
|
|
|
+ innerHTML: `
|
|
|
|
|
+ <div>院区名称: ${alert.organizationName || '未知'}</div>
|
|
|
|
|
+ <div>长者姓名: ${alert.elderName || '未知'}</div>
|
|
|
|
|
+ <div>长者房间: ${alert.roomName || '未知'}</div>
|
|
|
|
|
+ <div>设备类型: ${alert.deviceType || '未知'}</div>
|
|
|
|
|
+ <div>设备电量: ${alert.batteryLevel || '0%'}</div>
|
|
|
|
|
+ <div>时间: ${new Date(alertData.timestamp).toLocaleString()}</div>
|
|
|
|
|
+ `
|
|
|
|
|
+ }),
|
|
|
|
|
+ type: 'warning',
|
|
|
|
|
+ duration: 10000
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ // 找出elderlyList.value里面id和healthAlertData.elderId一致的老人,将这个老人排序到elderlyList.value第一个,并且边框红色闪烁
|
|
|
|
|
+ if (alert.elderId && elderlyList.value.length > 0) {
|
|
|
|
|
+ const elderIndex = elderlyList.value.findIndex((elder) => elder.id === alert.elderId)
|
|
|
|
|
+ if (elderIndex !== -1) {
|
|
|
|
|
+ // 创建一个新数组,将指定的老人移到第一位
|
|
|
|
|
+ const reorderedList = [...elderlyList.value]
|
|
|
|
|
+ const [selectedElder] = reorderedList.splice(elderIndex, 1)
|
|
|
|
|
+ reorderedList.unshift(selectedElder)
|
|
|
|
|
+ // 更新列表
|
|
|
|
|
+ elderlyList.value = reorderedList
|
|
|
|
|
+ // 为对应的老人卡片添加闪烁效果
|
|
|
|
|
+ addFlashingEffect(selectedElder)
|
|
|
|
|
+ getElderDeviceMessage(alert.elderId)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
console.error('处理SOS告警错误:', error)
|
|
console.error('处理SOS告警错误:', error)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// 健康数据推送处理逻辑
|
|
|
|
|
+const handleHealthAlert = (healthAlert) => {
|
|
|
|
|
+ console.log('healthAlert', healthAlert)
|
|
|
|
|
+ const healthAlertData = healthAlert.data
|
|
|
|
|
+
|
|
|
|
|
+ ElNotification({
|
|
|
|
|
+ title: `🚨🚨 ${healthAlertData.eventType} 🚨🚨`,
|
|
|
|
|
+ customClass: 'my-warning-notification',
|
|
|
|
|
+ message: h('div', {
|
|
|
|
|
+ style: {
|
|
|
|
|
+ color: '#fff'
|
|
|
|
|
+ },
|
|
|
|
|
+ innerHTML: `
|
|
|
|
|
+ <div>长者姓名: ${healthAlertData.elderName || '未知'}</div>
|
|
|
|
|
+ <div>预警指标: ${healthAlertData.indicatorName || '未知'}</div>
|
|
|
|
|
+ <div>预警信息: ${healthAlertData.message || '未知'}</div>
|
|
|
|
|
+ <div>处理建议: ${healthAlertData.suggestion || '未知'}</div>
|
|
|
|
|
+ <div>预警程度: ${healthAlertData.alertLevel || '0%'}</div>
|
|
|
|
|
+ <div>时间: ${new Date(healthAlertData.timestamp).toLocaleString()}</div>
|
|
|
|
|
+ `
|
|
|
|
|
+ }),
|
|
|
|
|
+ type: 'warning',
|
|
|
|
|
+ duration: 10000
|
|
|
|
|
+ })
|
|
|
|
|
+ // 找出elderlyList.value里面id和healthAlertData.elderId一致的老人,将这个老人排序到elderlyList.value第一个,并且边框红色闪烁
|
|
|
|
|
+ if (healthAlertData.elderId && elderlyList.value.length > 0) {
|
|
|
|
|
+ const elderIndex = elderlyList.value.findIndex((elder) => elder.id === healthAlertData.elderId)
|
|
|
|
|
+ if (elderIndex !== -1) {
|
|
|
|
|
+ // 创建一个新数组,将指定的老人移到第一位
|
|
|
|
|
+ const reorderedList = [...elderlyList.value]
|
|
|
|
|
+ const [selectedElder] = reorderedList.splice(elderIndex, 1)
|
|
|
|
|
+ reorderedList.unshift(selectedElder)
|
|
|
|
|
+ // 更新列表
|
|
|
|
|
+ elderlyList.value = reorderedList
|
|
|
|
|
+ // 为对应的老人卡片添加闪烁效果
|
|
|
|
|
+ addFlashingEffect(selectedElder)
|
|
|
|
|
+ getElderDeviceMessage(healthAlertData.elderId)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 添加一个方法来处理闪烁效果
|
|
|
|
|
+const addFlashingEffect = (elder) => {
|
|
|
|
|
+ // 添加一个临时的闪烁类名
|
|
|
|
|
+ elder._flashEffect = true
|
|
|
|
|
+ // 5秒后移除闪烁效果
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ elder._flashEffect = false
|
|
|
|
|
+ // 强制重新渲染列表
|
|
|
|
|
+ elderlyList.value = [...elderlyList.value]
|
|
|
|
|
+ }, 10000)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
const handleDeviceData = (deviceData) => {
|
|
const handleDeviceData = (deviceData) => {
|
|
|
console.log('deviceData', deviceData)
|
|
console.log('deviceData', deviceData)
|
|
|
}
|
|
}
|
|
@@ -1699,6 +1758,20 @@ $transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// 添加闪烁动画
|
|
|
|
|
+@keyframes borderFlash {
|
|
|
|
|
+ 0%,
|
|
|
|
|
+ 100% {
|
|
|
|
|
+ border-color: rgb(255 255 255 / 8%);
|
|
|
|
|
+ box-shadow: 0 0 0 0 rgb(255 107 107 / 0%);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ 50% {
|
|
|
|
|
+ border-color: $danger-color;
|
|
|
|
|
+ box-shadow: 0 0 20px 5px rgb(255 107 107 / 50%);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
/* 大屏专用样式 */
|
|
/* 大屏专用样式 */
|
|
|
.large-screen {
|
|
.large-screen {
|
|
|
position: relative;
|
|
position: relative;
|
|
@@ -1958,6 +2031,32 @@ $transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+.elderly-card-large {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ padding: 20px;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ background: rgb(255 255 255 / 5%);
|
|
|
|
|
+ border: 1px solid rgb(255 255 255 / 8%);
|
|
|
|
|
+ border-radius: 12px;
|
|
|
|
|
+ transition: $transition;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 15px;
|
|
|
|
|
+
|
|
|
|
|
+ &:hover,
|
|
|
|
|
+ &.active {
|
|
|
|
|
+ background: rgb(26 115 232 / 20%);
|
|
|
|
|
+ border-color: rgb(26 115 232 / 50%);
|
|
|
|
|
+ transform: translateX(5px);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 添加闪烁样式
|
|
|
|
|
+ &.flashing {
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ z-index: 1;
|
|
|
|
|
+ animation: borderFlash 1s ease-in-out infinite;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
.elderly-avatar-large {
|
|
.elderly-avatar-large {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
width: 60px;
|
|
width: 60px;
|
|
@@ -2595,7 +2694,6 @@ $transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
|
.el-dialog__header {
|
|
.el-dialog__header {
|
|
|
padding: 25px !important;
|
|
padding: 25px !important;
|
|
|
margin-top: 20px;
|
|
margin-top: 20px;
|
|
|
- // margin: 0 !important;
|
|
|
|
|
color: white !important;
|
|
color: white !important;
|
|
|
background: linear-gradient(90deg, var(--el-color-primary), #7b61ff) !important;
|
|
background: linear-gradient(90deg, var(--el-color-primary), #7b61ff) !important;
|
|
|
border-radius: 16px 16px 0 0 !important;
|
|
border-radius: 16px 16px 0 0 !important;
|
|
@@ -2614,10 +2712,15 @@ $transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.my-warning-notification {
|
|
.my-warning-notification {
|
|
|
- width: '2rem !important';
|
|
|
|
|
- color: '#fff !important';
|
|
|
|
|
- background: 'linear-gradient(135deg, #1e4184 0%, #3469e3 100%) !important';
|
|
|
|
|
- border: '1px solid rgba(42, 157, 143, 0.3) !important';
|
|
|
|
|
- box-shadow: '0 4px 20px rgba(0, 0, 0, 0.5) !important';
|
|
|
|
|
|
|
+ color: #fff !important;
|
|
|
|
|
+ background: linear-gradient(135deg, #1e4184 0%, #3469e3 100%) !important;
|
|
|
|
|
+ border: 1px solid rgb(42 157 143 / 30%) !important;
|
|
|
|
|
+ box-shadow: 0 4px 20px rgb(0 0 0 / 50%) !important;
|
|
|
|
|
+
|
|
|
|
|
+ .el-notification__group {
|
|
|
|
|
+ .el-notification__title {
|
|
|
|
|
+ color: #fff !important;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
</style>
|
|
</style>
|