Эх сурвалжийг харах

Merge remote-tracking branch 'origin/master'

黄渊昊 6 сар өмнө
parent
commit
d4c7031f04
26 өөрчлөгдсөн 226 нэмэгдсэн , 252 устгасан
  1. 10 0
      snowy-admin-web/src/api/basicset/homeApi.js
  2. 5 0
      snowy-admin-web/src/api/coldchain/monitornotice.js
  3. BIN
      snowy-admin-web/src/assets/images/home/06.png
  4. BIN
      snowy-admin-web/src/assets/images/home/08.png
  5. BIN
      snowy-admin-web/src/assets/images/home/09.png
  6. 35 18
      snowy-admin-web/src/components/HomeCard/SysCountCard/index.vue
  7. 3 3
      snowy-admin-web/src/components/HomeCard/SysTrendCard/index.vue
  8. 76 69
      snowy-admin-web/src/components/HomeCard/SysWarningCard/index.vue
  9. 2 32
      snowy-admin-web/src/views/basicset/devicetype/form.vue
  10. 2 37
      snowy-admin-web/src/views/basicset/mem/form.vue
  11. 1 0
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/bean/NotificationChannel.java
  12. 18 18
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/config/ColdChainAlarmMessageProperties.java
  13. 15 12
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/check/DefaultSensorAlarmChecker.java
  14. 1 3
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/messagepush/MessagePushService.java
  15. 9 11
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/messagepush/SensorAlarmMessagePushService.java
  16. 2 3
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/messagepush/impl/DingTalkMessagePushService.java
  17. 3 4
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/messagepush/impl/EmailPushService.java
  18. 3 4
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/messagepush/impl/PushNotificationService.java
  19. 3 4
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/messagepush/impl/SMSPushService.java
  20. 12 9
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/messagepush/impl/WechatMessagePushService.java
  21. 2 3
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/messagepush/impl/WechatMiniMessagePushService.java
  22. 13 0
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/dataclean/impl/AbsRenkeMonitorDataProcessor.java
  23. 4 5
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/dataclean/impl/WifiCO2TempHumidityProcessor.java
  24. 3 9
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/dataclean/impl/WifiLowTempRecorderProcessor1.java
  25. 2 4
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/dataclean/impl/WifiLowTempRecorderProcessor2.java
  26. 2 4
      snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/dataclean/impl/WifiLowTempRecorderProcessor4.java

+ 10 - 0
snowy-admin-web/src/api/basicset/homeApi.js

@@ -0,0 +1,10 @@
+import { baseRequest } from '@/utils/request'
+
+const request = (url, ...arg) => baseRequest(`/coldchain/monitordevice/` + url, ...arg)
+
+// 首页中的数据统计
+export default {
+	monitorDeviceCount(data) {
+		return request('getIndexCount', data, 'get')
+	}
+}

+ 5 - 0
snowy-admin-web/src/api/coldchain/monitornotice.js

@@ -27,6 +27,11 @@ export const addMonitornotice = (data) => {
 	return request('add', data)
 }
 
+/** 获取监控通知列表不分页 */
+export const getList = (data) => {
+	return request('list', data, 'get')
+}
+
 export default {
 	getPage,
 	getDetail,

BIN
snowy-admin-web/src/assets/images/home/06.png


BIN
snowy-admin-web/src/assets/images/home/08.png


BIN
snowy-admin-web/src/assets/images/home/09.png


+ 35 - 18
snowy-admin-web/src/components/HomeCard/SysCountCard/index.vue

@@ -2,8 +2,8 @@
 	<div class="home_count">
 		<div class="ant-card-body">
 			<div class="card-left">
-				<div class="left-title">监控点总数</div>
-				<div class="left-count">{{ dataSource.jkdzs }}</div>
+				<div class="left-title">监测器总数</div>
+				<div class="left-count">{{ data.deviceCount || 0 }}</div>
 			</div>
 			<div class="card-right">
 				<img src="/src/assets/images/home/01.png" class="right-img" />
@@ -12,7 +12,7 @@
 		<div class="ant-card-body">
 			<div class="card-left">
 				<div class="left-title">正常</div>
-				<div class="left-count">{{ dataSource.zc }}</div>
+				<div class="left-count">{{ data.onlineDeviceCount || 0 }}</div>
 			</div>
 			<div class="card-right">
 				<img src="/src/assets/images/home/02.png" class="right-img" />
@@ -21,8 +21,17 @@
 
 		<div class="ant-card-body">
 			<div class="card-left">
-				<div class="left-title">断线</div>
-				<div class="left-count">{{ dataSource.dx }}</div>
+				<div class="left-title">离线</div>
+				<div class="left-count">{{ data.offlineDeviceCount || 0 }}</div>
+			</div>
+			<div class="card-right">
+				<img src="/src/assets/images/home/03.png" class="right-img" />
+			</div>
+		</div>
+		<div class="ant-card-body">
+			<div class="card-left">
+				<div class="left-title">总路数</div>
+				<div class="left-count">{{ data.sensorCount || 0 }}</div>
 			</div>
 			<div class="card-right">
 				<img src="/src/assets/images/home/04.png" class="right-img" />
@@ -30,30 +39,38 @@
 		</div>
 		<div class="ant-card-body">
 			<div class="card-left">
-				<div class="left-title">未绑定</div>
-				<div class="left-count">{{ dataSource.xzwx }}</div>
+				<div class="left-title">已使用路数</div>
+				<div class="left-count">{{ data.usedSensorCount || 0 }}</div>
 			</div>
 			<div class="card-right">
 				<img src="/src/assets/images/home/05.png" class="right-img" />
 			</div>
 		</div>
+		<div class="ant-card-body">
+			<div class="card-left">
+				<div class="left-title">未使用路数</div>
+				<div class="left-count">{{ data.unusedSensorCount || 0 }}</div>
+			</div>
+			<div class="card-right">
+				<img src="/src/assets/images/home/06.png" class="right-img" />
+			</div>
+		</div>
 	</div>
 </template>
 
 <script setup name="SysCountCard">
-	import indexApi from '@/api/sys/indexApi'
+	import homeApi from '@/api/basicset/homeApi'
 
-	const apiLoading = ref(false)
-	const dataSource = ref({
-		jkdzs: 673,
-		zc: 136,
-		cx: 351,
-		dx: 94,
-		xzwx: 92
-	})
+	const data = ref({})
 	onMounted(() => {
-		apiLoading.value = true
+		loadData()
 	})
+
+	const loadData = () => {
+		homeApi.monitorDeviceCount().then((res) => {
+			data.value = res
+		})
+	}
 </script>
 
 <style lang="less" scoped>
@@ -64,7 +81,7 @@
 		justify-content: space-between;
 
 		.ant-card-body {
-			flex: 0 0 calc(25% - 10px);
+			flex: 0 0 calc(16.6% - 10px);
 			width: 100%;
 			height: 150px;
 			margin-bottom: 10px;

+ 3 - 3
snowy-admin-web/src/components/HomeCard/SysTrendCard/index.vue

@@ -4,7 +4,7 @@
 	<div class="home_count">
 		<div class="ant-card-body">
 			<div class="card-left">
-				<img src="/src/assets/images/home/06.png" class="right-img" />
+				<img src="/src/assets/images/home/07.png" class="right-img" />
 				<div class="left-title">前天</div>
 			</div>
 			<div class="card-right">
@@ -13,7 +13,7 @@
 		</div>
 		<div class="ant-card-body">
 			<div class="card-left">
-				<img src="/src/assets/images/home/07.png" class="right-img" />
+				<img src="/src/assets/images/home/08.png" class="right-img" />
 				<div class="left-title">昨天</div>
 			</div>
 			<div class="card-right">
@@ -22,7 +22,7 @@
 		</div>
 		<div class="ant-card-body">
 			<div class="card-left">
-				<img src="/src/assets/images/home/08.png" class="right-img" />
+				<img src="/src/assets/images/home/09.png" class="right-img" />
 				<div class="left-title">今天</div>
 			</div>
 			<div class="card-right">

+ 76 - 69
snowy-admin-web/src/components/HomeCard/SysWarningCard/index.vue

@@ -1,119 +1,126 @@
 <template>
 	<div class="home_count">
 		<div class="warning-title">
-			<div>报警管理</div>
+			<div>通知列表</div>
 			<a-button type="link" @click="leaveFor('/motoring/report')">更多</a-button>
 		</div>
-		<a-table :columns="columns" :data-source="dataSource" size="small" :pagination="false" :scroll="{ y: 260 }">
+		<a-table
+			:columns="columns"
+			:data-source="dataSource"
+			size="small"
+			:pagination="false"
+			:scroll="{ y: 260 }"
+			:loading="loading"
+		>
 			<template #bodyCell="{ column, record }">
-				<template v-if="column.dataIndex === 'state'">
-					<span>
-						<a-tag :color="record.state == '1' ? '#87d068' : record.state == '2' ? '#cd201f' : '#50cd7c'">
-							{{ record.stateVlaue }}
-						</a-tag>
-					</span>
-				</template>
 				<template v-if="column.dataIndex === 'action'">
-					<a-button type="link" size="small">编辑</a-button>
+					<a-button type="link" size="small" @click="handlerEdit(record)">编辑</a-button>
 					<a-divider type="vertical" />
 					<a-popconfirm title="删除此数据?" @confirm="deleteData(record)">
 						<a-button type="link" danger size="small">删除</a-button>
 					</a-popconfirm>
 					<a-divider type="vertical" />
-					<a-button type="link" size="small">记录</a-button>
 				</template>
 			</template>
 		</a-table>
+
+		<DetailModal ref="detailModalRef" @successful="loadData" />
 	</div>
 </template>
 
 <script setup name="SysWarningCard">
-	import bizIndexApi from '@/api/biz/bizIndexApi'
+	import { debounce } from 'lodash-es'
+	import DetailModal from '@/views/motoring/report/components/DetailModal.vue'
+	import { getList, deleteMonitornotice } from '@/api/coldchain/monitornotice'
 	import router from '@/router'
 	const columns = [
 		{
-			title: '时间',
-			dataIndex: 'createTime',
-			ellipsis: true
-		},
-		{
-			title: '名称',
+			title: '通知标题',
 			dataIndex: 'title',
+			align: 'center',
 			ellipsis: true
 		},
 		{
-			title: '报警原因',
-			dataIndex: 'reason',
-			ellipsis: true
+			title: '通知类型',
+			dataIndex: 'type',
+			align: 'center',
+			ellipsis: true,
+			customRender({ value }) {
+				return value == '1' ? '系统' : '预警'
+			}
 		},
 		{
-			title: '状态',
-			dataIndex: 'state',
+			title: '通知内容',
+			dataIndex: 'content',
+			align: 'center',
 			ellipsis: true
 		},
 		{
-			title: '操作',
-			dataIndex: 'action',
+			title: '传感器路数',
+			dataIndex: 'sensorRoute',
 			align: 'center',
-			width: '200px'
-		}
-	]
-	const dataSource = ref([
-		{
-			createTime: '2024-09-28 07:03:24',
-			title: 'ABSL-1超低温冰箱',
-			reason: '温度异常',
-			state: '1',
-			stateVlaue: '异常'
-		},
-		{
-			createTime: '2024-09-28 09:21:51',
-			title: 'ABSL-2超低温冰箱',
-			reason: '温度异常',
-			state: '1',
-			stateVlaue: '异常'
-		},
-		{
-			createTime: '2024-09-28 11:06:20',
-			title: 'ABSL-3超低温冰箱',
-			reason: '温度异常',
-			state: '1',
-			stateVlaue: '异常'
+			ellipsis: true
 		},
 		{
-			createTime: '2024-09-28 11:54:19',
-			title: 'ABSL-4超低温冰箱',
-			reason: '温度异常',
-			state: '1',
-			stateVlaue: '异常'
+			title: '创建人',
+			dataIndex: 'createUserName',
+			align: 'center',
+			ellipsis: true
 		},
 		{
-			createTime: '2024-09-28 16:17:36',
-			title: 'ABSL-5超低温冰箱',
-			reason: '温度异常',
-			state: '1',
-			stateVlaue: '异常'
+			title: '创建时间',
+			dataIndex: 'createTime',
+			align: 'center',
+			ellipsis: true
 		},
 		{
-			createTime: '2024-09-28 19:35:58',
-			title: 'ABSL-6超低温冰箱',
-			reason: '温度异常',
-			state: '1',
-			stateVlaue: '异常'
+			title: '操作',
+			dataIndex: 'action',
+			align: 'center'
 		}
-	])
-	const apiLoading = ref(false)
-	onMounted(() => {})
-	const leaveFor = (url = '/') => {
+	]
+	const dataSource = ref([])
+	const loading = ref(false)
+	onMounted(() => {
+		loadData()
+	})
+	const leaveFor = (url) => {
 		router.replace({
 			path: url
 		})
 	}
 
+	const loadData = () => {
+		loading.value = true
+		return getList()
+			.then((res) => {
+				dataSource.value = res
+				loading.value = false
+			})
+			.catch((e) => {
+				loading.value = false
+			})
+	}
+
 	// 删除
 	const deleteData = (record) => {
-		console.log(record.title, 'params')
+		if (loading.value) return
+		loading.value = true
+
+		deleteMonitornotice({ id: record.id })
+			.then(() => {
+				loading.value = false
+				loadData()
+			})
+			.catch(() => {
+				loading.value = false
+			})
 	}
+	const detailModalRef = ref()
+	/** 编辑 */
+	const handlerEdit = debounce((rowItem) => {
+		detailModalRef.value.open(rowItem, 'edit')
+	}, 300)
 </script>
 
 <style lang="less" scoped>

+ 2 - 32
snowy-admin-web/src/views/basicset/devicetype/form.vue

@@ -16,18 +16,12 @@
 			<a-row :gutter="10">
 				<a-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
 					<a-form-item label="型号名称" name="name">
-						<a-input v-model:value="formData.name" placeholder="请输入型号名称" allow-clear @blur="handleNameBlur" />
+						<a-input v-model:value="formData.name" placeholder="请输入型号名称" allow-clear />
 					</a-form-item>
 				</a-col>
 				<a-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
 					<a-form-item label="型号编号" name="code">
-						<a-input
-							v-model:value="formData.code"
-							placeholder="请输入型号编号"
-							allow-clear
-							:maxlength="10"
-							@blur="handleCodeBlur"
-						/>
+						<a-input v-model:value="formData.code" placeholder="请输入型号编号" allow-clear :maxlength="10" />
 					</a-form-item>
 				</a-col>
 
@@ -195,30 +189,6 @@
 		}
 	}
 
-	// 检查设备名称是否已注册  编辑的时候不调用接口
-	const handleNameBlur = () => {
-		if (formData.value.name) {
-			devicetypeApi
-				.submitDeviceTypeName({ name: formData.value.name })
-				.then((res) => {})
-				.catch(() => {
-					formData.value.name = ''
-				})
-		}
-	}
-
-	// 检查型号编号是否已注册
-	const handleCodeBlur = () => {
-		if (formData.value.code) {
-			devicetypeApi
-				.submitDeviceTypeCode({ code: formData.value.code })
-				.then((res) => {})
-				.catch(() => {
-					formData.value.code = ''
-				})
-		}
-	}
-
 	// 打开抽屉
 	const onOpen = (record) => {
 		visible.value = true

+ 2 - 37
snowy-admin-web/src/views/basicset/mem/form.vue

@@ -16,23 +16,12 @@
 			<a-row :gutter="10">
 				<a-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
 					<a-form-item label="设备名称" name="deviceName">
-						<a-input
-							v-model:value="formData.deviceName"
-							placeholder="请输入设备名称"
-							allow-clear
-							@blur="handleNameBlur"
-						/>
+						<a-input v-model:value="formData.deviceName" placeholder="请输入设备名称" allow-clear />
 					</a-form-item>
 				</a-col>
 				<a-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
 					<a-form-item label="设备编号" name="deviceCode">
-						<a-input
-							v-model:value="formData.deviceCode"
-							placeholder="请输入设备编号"
-							allow-clear
-							:maxlength="10"
-							@blur="handleCodeBlur"
-						/>
+						<a-input v-model:value="formData.deviceCode" placeholder="请输入设备编号" allow-clear :maxlength="10" />
 					</a-form-item>
 				</a-col>
 				<a-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
@@ -187,30 +176,6 @@
 		})
 	}
 
-	// 检查设备名称是否已注册  编辑的时候不调用接口
-	const handleNameBlur = () => {
-		if (formData.value.deviceName) {
-			memApi
-				.submitDeviceName({ deviceName: formData.value.deviceName })
-				.then((res) => {})
-				.catch(() => {
-					formData.value.deviceName = ''
-				})
-		}
-	}
-
-	// 检查设备编号是否已注册  编辑的时候不调用接口
-	const handleCodeBlur = () => {
-		if (formData.value.deviceCode) {
-			memApi
-				.submitDeviceCode({ deviceCode: formData.value.deviceCode })
-				.then((res) => {})
-				.catch(() => {
-					formData.value.deviceCode = ''
-				})
-		}
-	}
-
 	// 选中设备型号获取上下限值
 	const modelNameChange = (value) => {
 		if (value) {

+ 1 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/bean/NotificationChannel.java

@@ -79,4 +79,5 @@ public enum NotificationChannel {
         // 默认返回系统通知
         return SYSTEM;
     }
+
 }

+ 18 - 18
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/config/ColdChainAlarmMessageProperties.java

@@ -8,27 +8,27 @@ import org.springframework.stereotype.Component;
 @ConfigurationProperties(prefix = "cold-chain.alarm.message")
 @Data
 public class ColdChainAlarmMessageProperties {
-    private String temperatureOverLimit = "温度报警:设备【{deviceName}】的温度超标!\n" +
-            "当前温度:{value} {unit},已超出上限(阈值:{thresholdUp})。\n" +
-            "报警时间{time}";
+    private String temperatureOverLimit = "温度报警:{deviceName}的温度超标!\n" +
+            "当前温度:{value} {unit},已超出上限(阈值:{threshold})。\n" +
+            "报警时间:{time}";
 
-    private String temperatureBelowLimit = "温度报警:设备【{deviceName}】的温度过低!\n" +
-            "当前温度:{value} {unit},已低于下限(阈值:{thresholdDown})。\n" +
-            "报警时间{time}";
+    private String temperatureBelowLimit = "温度报警:{deviceName}的温度过低!\n" +
+            "当前温度:{value} {unit},已低于下限(阈值:{threshold})。\n" +
+            "报警时间:{time}";
 
-    private String humidityOverLimit = "湿度报警:设备【{deviceName}】的湿度超标!\n" +
-            "当前湿度:{value} {unit},已超出上限(阈值:{thresholdUp})。\n" +
-            "报警时间{time}";
+    private String humidityOverLimit = "湿度报警:{deviceName}的湿度超标!\n" +
+            "当前湿度:{value} {unit},已超出上限(阈值:{threshold})。\n" +
+            "报警时间:{time}";
 
-    private String humidityBelowLimit = "湿度报警:设备【{deviceName}】的湿度过低!\n" +
-            "当前湿度:{value} {unit},已低于下限(阈值:{thresholdDown})。\n" +
-            "报警时间{time}";
+    private String humidityBelowLimit = "湿度报警:{deviceName}的湿度过低!\n" +
+            "当前湿度:{value} {unit},已低于下限(阈值:{threshold})。\n" +
+            "报警时间:{time}";
 
-    private String co2OverLimit = "二氧化碳报警:设备【{deviceName}】的二氧化碳浓度超标!\n" +
-            "当前浓度:{value} {unit},已超出上限(阈值:{thresholdUp})。\n" +
-            "报警时间{time}";
+    private String co2OverLimit = "二氧化碳报警:{deviceName}的二氧化碳浓度超标!\n" +
+            "当前浓度:{value} {unit},已超出上限(阈值:{threshold})。\n" +
+            "报警时间:{time}";
 
-    private String co2BelowLimit = "二氧化碳报警:设备【{deviceName}】的二氧化碳浓度过低!\n" +
-            "当前浓度:{value} {unit},已低于下限(阈值:{thresholdDown})。\n" +
-            "报警时间{time}";
+    private String co2BelowLimit = "二氧化碳报警:{deviceName}的二氧化碳浓度过低!\n" +
+            "当前浓度:{value} {unit},已低于下限(阈值:{threshold})。\n" +
+            "报警时间:{time}";
 }

+ 15 - 12
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/check/DefaultSensorAlarmChecker.java

@@ -37,16 +37,16 @@ public class DefaultSensorAlarmChecker implements SensorAlarmChecker {
             log.warn("没有找到设备 {} 的阈值配置", sensorData.getDeviceId());
             return false;
         }
-        final String deviceName = threshold.getMonitorTargetRegion().getDeviceName();
+        final String deviceName = threshold.getMonitorTargetRegion().getName();
         // 检查传感器数据并触发报警
         boolean alarmTriggered = false;
-        if (sensorData.getTemperature() != null) {
+        if (isNull(sensorData.getTemperature())) {
             alarmTriggered = checkThreshold(sensorData.getTemperature(), threshold.getTemperatureUp(), threshold.getTemperatureDown(), "温度", deviceName);
         }
-        if (sensorData.getHumidity() != null) {
+        if (isNull(sensorData.getHumidity())) {
             alarmTriggered |= checkThreshold(sensorData.getHumidity(), threshold.getHumidityUp(), threshold.getHumidityDown(), "湿度", deviceName);
         }
-        if (sensorData.getCo2() != null) {
+        if (isNull(sensorData.getCo2())) {
             alarmTriggered |= checkThreshold(sensorData.getCo2(), threshold.getCo2Up(), threshold.getCo2Down(), "二氧化碳", deviceName);
         }
         return alarmTriggered;
@@ -90,7 +90,7 @@ public class DefaultSensorAlarmChecker implements SensorAlarmChecker {
      */
     private void publishAlarm(String alarmType, Float value, String unit, String deviceName, String time, float threshold) {
         // 获取对应的报警消息模板
-        String alarmMessage = getAlarmMessage(alarmType, value, unit, deviceName, time);
+        String alarmMessage = getAlarmMessage(alarmType, value, unit, deviceName, time, threshold);
         // 构建 SensorAlarm 对象
         SensorAlarm sensorAlarm = new SensorAlarm();
         sensorAlarm.setAlarmType(alarmType);  // 设置报警类型(例如 温度超标、湿度过低等)
@@ -103,10 +103,9 @@ public class DefaultSensorAlarmChecker implements SensorAlarmChecker {
         sensorAlarm.setAlarmTime(time);  // 设置报警时间
         sensorAlarm.setMessage(alarmMessage);  // 设置报警消息
         sensorAlarm.setThreshold(threshold);  // 设置预警值
-        sensorAlarm.getAlarmUsers().add(new SensorAlarmUser(null,"oltp26cDdkiAAsualbzKMyiZbJrU"));
-        sensorAlarm.getAlarmUsers().add(new SensorAlarmUser(null,"oltp26fXeljOKUxYGhAx_dRqVAak"));
-        // 打印日志(可选)
-        log.warn("触发报警: 类型: {}, 设备: {}, 值: {} {}, 时间: {}", alarmType, deviceName, value, unit, time);
+        sensorAlarm.getAlarmUsers().add(new SensorAlarmUser(null, "oltp26cDdkiAAsualbzKMyiZbJrU"));
+        sensorAlarm.getAlarmUsers().add(new SensorAlarmUser(null, "oltp26fXeljOKUxYGhAx_dRqVAak"));
+        log.warn("触发报警: 类型: {},详细报警内容 : {}", alarmType, alarmMessage);
         // 发布报警事件
         applicationEventPublisher.publishEvent(new SensorAlarmEvent(this, sensorAlarm));
     }
@@ -122,7 +121,7 @@ public class DefaultSensorAlarmChecker implements SensorAlarmChecker {
      * @param time       时间戳
      * @return 格式化后的报警消息
      */
-    private String getAlarmMessage(String alarmType, Float value, String unit, String deviceName, String time) {
+    private String getAlarmMessage(String alarmType, Float value, String unit, String deviceName, String time, float threshold) {
         String messageTemplate = "";
         // 根据报警类型获取对应的消息模板
         switch (alarmType) {
@@ -148,9 +147,9 @@ public class DefaultSensorAlarmChecker implements SensorAlarmChecker {
                 messageTemplate = "{alarmType}: 当前值:{value} {unit}";
                 break;
         }
-
         // 替换模板中的占位符
-        return messageTemplate.replace("{value}", String.format("%.2f", value)).replace("{unit}", unit).replace("{alarmType}", alarmType).replace("{time}", time).replace("{deviceName}", deviceName);
+        String replace = messageTemplate.replace("{value}", String.format("%.2f", value)).replace("{unit}", unit).replace("{alarmType}", alarmType).replace("{time}", time).replace("{deviceName}", deviceName).replace("{threshold}", String.format("%.2f", threshold));
+        return replace;
     }
 
     private String getUnit(String sensorType) {
@@ -161,4 +160,8 @@ public class DefaultSensorAlarmChecker implements SensorAlarmChecker {
             default -> "";
         };
     }
+
+    private boolean isNull(Float value) {
+        return value != null && value != 0.0;
+    }
 }

+ 1 - 3
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/messagepush/MessagePushService.java

@@ -9,7 +9,6 @@ package vip.xiaonuo.coldchain.core.alarm.service.messagepush;
  */
 
 import vip.xiaonuo.coldchain.core.alarm.bean.SensorAlarm;
-import vip.xiaonuo.coldchain.core.alarm.bean.SensorAlarmUser;
 
 /**
  * @author jackzhou
@@ -25,7 +24,6 @@ public interface MessagePushService {
      * 发送告警消息
      *
      * @param alarm 告警信息
-     * @param user  告警接收人
      */
-    boolean sendAlarmMessage(SensorAlarm alarm, SensorAlarmUser user);
+    boolean sendAlarmMessage(SensorAlarm alarm);
 }

+ 9 - 11
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/messagepush/SensorAlarmMessagePushService.java

@@ -5,7 +5,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import vip.xiaonuo.coldchain.core.alarm.bean.NotificationChannel;
 import vip.xiaonuo.coldchain.core.alarm.bean.SensorAlarm;
-import vip.xiaonuo.coldchain.core.alarm.bean.SensorAlarmUser;
 import vip.xiaonuo.coldchain.core.alarm.mapper.SensorAlarmMapper;
 
 import java.util.Map;
@@ -15,13 +14,13 @@ import java.util.Map;
 public class SensorAlarmMessagePushService {
 
     // 用一个 Map 来存储不同的推送渠道服务
-    private final Map<NotificationChannel, MessagePushService> pushServices;
+    private final Map<String, MessagePushService> pushServices;
 
     @Autowired
     private SensorAlarmMapper sensorAlarmMapper;  // 注入 MyBatis-Plus 的 Mapper
 
     @Autowired
-    public SensorAlarmMessagePushService(Map<NotificationChannel, MessagePushService> pushServices) {
+    public SensorAlarmMessagePushService(Map<String, MessagePushService> pushServices) {
         this.pushServices = pushServices;
     }
 
@@ -32,14 +31,13 @@ public class SensorAlarmMessagePushService {
      */
     public void pushAlarmMessage(SensorAlarm alarm) {
         // 遍历每个接收人和通知渠道,发送告警信息
-        for (SensorAlarmUser user : alarm.getAlarmUsers()) {
-            for (NotificationChannel channel : alarm.getNotificationChannel()) {
-                MessagePushService pushService = pushServices.get(channel);
-                if (pushService != null) {
-                    pushService.sendAlarmMessage(alarm, user);
-                } else {
-                    log.info("不支持的通知渠道:" + channel);
-                }
+        for (NotificationChannel channel : alarm.getNotificationChannel()) {
+            MessagePushService pushService = pushServices.get(channel.name());
+            log.info("推送消息渠道: {}", channel.getChannelName());
+            if (pushService != null) {
+                pushService.sendAlarmMessage(alarm);
+            } else {
+                log.info("不支持的通知渠道:" + channel);
             }
         }
         // 设置已通知状态

+ 2 - 3
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/messagepush/impl/DingTalkMessagePushService.java

@@ -2,7 +2,6 @@ package vip.xiaonuo.coldchain.core.alarm.service.messagepush.impl;
 
 import org.springframework.stereotype.Service;
 import vip.xiaonuo.coldchain.core.alarm.bean.SensorAlarm;
-import vip.xiaonuo.coldchain.core.alarm.bean.SensorAlarmUser;
 import vip.xiaonuo.coldchain.core.alarm.service.messagepush.MessagePushService;
 
 /**
@@ -10,11 +9,11 @@ import vip.xiaonuo.coldchain.core.alarm.service.messagepush.MessagePushService;
  *
  * @author jackzhou
  */
-@Service
+@Service("DINGTALK")
 public class DingTalkMessagePushService implements MessagePushService {
 
     @Override
-    public boolean sendAlarmMessage(SensorAlarm alarm, SensorAlarmUser user) {
+    public boolean sendAlarmMessage(SensorAlarm alarm/*, SensorAlarmUser user*/) {
         System.out.println("发送钉钉通知:");
         System.out.println("消息内容:" + alarm.getMessage());
         System.out.println("发送渠道:" + alarm);

+ 3 - 4
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/messagepush/impl/EmailPushService.java

@@ -2,7 +2,6 @@ package vip.xiaonuo.coldchain.core.alarm.service.messagepush.impl;
 
 import org.springframework.stereotype.Service;
 import vip.xiaonuo.coldchain.core.alarm.bean.SensorAlarm;
-import vip.xiaonuo.coldchain.core.alarm.bean.SensorAlarmUser;
 import vip.xiaonuo.coldchain.core.alarm.service.messagepush.MessagePushService;
 
 /**
@@ -12,14 +11,14 @@ import vip.xiaonuo.coldchain.core.alarm.service.messagepush.MessagePushService;
  * @description 邮件推送实现类
  * @date 2024/11/26
  */
-@Service
+@Service("EMAIL")
 public class EmailPushService implements MessagePushService {
 
     @Override
-    public boolean sendAlarmMessage(SensorAlarm alarm, SensorAlarmUser user) {
+    public boolean sendAlarmMessage(SensorAlarm alarm/*, SensorAlarmUser user*/) {
         // 这里是模拟发送邮件的实现,具体可以集成第三方邮件服务
         String message = buildMessage(alarm);
-        System.out.println("发送邮件到: " + user.getEmail() + " 内容: " + message);
+        System.out.println("发送邮件到:  内容: " + message);
         return false;
     }
 

+ 3 - 4
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/messagepush/impl/PushNotificationService.java

@@ -2,7 +2,6 @@ package vip.xiaonuo.coldchain.core.alarm.service.messagepush.impl;
 
 import org.springframework.stereotype.Service;
 import vip.xiaonuo.coldchain.core.alarm.bean.SensorAlarm;
-import vip.xiaonuo.coldchain.core.alarm.bean.SensorAlarmUser;
 import vip.xiaonuo.coldchain.core.alarm.service.messagepush.MessagePushService;
 
 /**
@@ -12,14 +11,14 @@ import vip.xiaonuo.coldchain.core.alarm.service.messagepush.MessagePushService;
  * @description 推送通知实现类
  * @date 2024/11/26
  */
-@Service
+@Service("PUSH_NOTIFICATION")
 public class PushNotificationService implements MessagePushService {
 
     @Override
-    public boolean sendAlarmMessage(SensorAlarm alarm, SensorAlarmUser user) {
+    public boolean sendAlarmMessage(SensorAlarm alarm/*, SensorAlarmUser user*/) {
         // 这里是模拟推送通知的实现,具体可以集成推送服务如 Firebase 或者其它
         String message = buildMessage(alarm);
-        System.out.println("推送通知到: " + user.getOpenId() + " 内容: " + message);
+        System.out.println("推送通知到: 内容: " + message);
         return false;
     }
 

+ 3 - 4
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/messagepush/impl/SMSPushService.java

@@ -2,7 +2,6 @@ package vip.xiaonuo.coldchain.core.alarm.service.messagepush.impl;
 
 import org.springframework.stereotype.Service;
 import vip.xiaonuo.coldchain.core.alarm.bean.SensorAlarm;
-import vip.xiaonuo.coldchain.core.alarm.bean.SensorAlarmUser;
 import vip.xiaonuo.coldchain.core.alarm.service.messagepush.MessagePushService;
 
 /**
@@ -12,14 +11,14 @@ import vip.xiaonuo.coldchain.core.alarm.service.messagepush.MessagePushService;
  * @description 短信推送实现类
  * @date 2024/11/26
  */
-@Service
+@Service("SMS")
 public class SMSPushService implements MessagePushService {
 
     @Override
-    public boolean sendAlarmMessage(SensorAlarm alarm, SensorAlarmUser user) {
+    public boolean sendAlarmMessage(SensorAlarm alarm/*, SensorAlarmUser user*/) {
         // 这里是模拟发送短信的实现,具体可以集成第三方短信服务
         String message = buildMessage(alarm);
-        System.out.println("发送短信到: " + user.getPhone() + " 内容: " + message);
+        System.out.println("发送短信到:  内容: " + message);
         return false;
     }
 

+ 12 - 9
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/messagepush/impl/WechatMessagePushService.java

@@ -1,7 +1,6 @@
 package vip.xiaonuo.coldchain.core.alarm.service.messagepush.impl;
 
 import cn.hutool.core.util.StrUtil;
-import com.google.common.collect.Lists;
 import org.springframework.stereotype.Service;
 import vip.xiaonuo.coldchain.core.alarm.bean.SensorAlarm;
 import vip.xiaonuo.coldchain.core.alarm.bean.SensorAlarmUser;
@@ -10,27 +9,31 @@ import vip.xiaonuo.coldchain.modular.push.param.PushParam;
 import vip.xiaonuo.coldchain.modular.push.utils.PushUtil;
 
 import java.util.Date;
-import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * 微信公众号通知推送服务
  *
  * @author jackzhou
  */
-@Service
+@Service("WECHAT")
 public class WechatMessagePushService implements MessagePushService {
 
     @Override
-    public boolean sendAlarmMessage(SensorAlarm alarm, SensorAlarmUser user) {
-        String message = alarm.getMessage();
-
-        PushParam pushParam = new PushParam(alarm.getValue()+"");
-        pushParam.setContext(message);
+    public boolean sendAlarmMessage(SensorAlarm alarm/*, SensorAlarmUser user*/) {
+        PushParam pushParam = new PushParam(alarm.getValue() + "");
+        if (alarm.getMessage().length() > 17) {
+            pushParam.setContext(alarm.getMessage().substring(0, 17) + "...");
+        } else {
+            pushParam.setContext(alarm.getMessage());
+        }
         pushParam.setDeviceName(alarm.getSource());
         pushParam.setNoticeTime(new Date());
         pushParam.setType(alarm.getAlarmType());
+        pushParam.setUserIdList(alarm.getAlarmUsers().stream().map(SensorAlarmUser::getOpenId).collect(Collectors.toSet()));
         //推送到公众号
-        String pushCode = PushUtil.push(pushParam);
+        String pushCode = null;
+        pushCode = PushUtil.push(pushParam);
         alarm.setWeixinRequestCode(pushCode);
         return !StrUtil.isBlank(pushCode);
     }

+ 2 - 3
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/alarm/service/messagepush/impl/WechatMiniMessagePushService.java

@@ -2,7 +2,6 @@ package vip.xiaonuo.coldchain.core.alarm.service.messagepush.impl;
 
 import org.springframework.stereotype.Service;
 import vip.xiaonuo.coldchain.core.alarm.bean.SensorAlarm;
-import vip.xiaonuo.coldchain.core.alarm.bean.SensorAlarmUser;
 import vip.xiaonuo.coldchain.core.alarm.service.messagepush.MessagePushService;
 
 /**
@@ -10,11 +9,11 @@ import vip.xiaonuo.coldchain.core.alarm.service.messagepush.MessagePushService;
  *
  * @author jackzhou
  */
-@Service
+@Service("WECHAT_MINI")
 public class WechatMiniMessagePushService implements MessagePushService {
 
     @Override
-    public boolean sendAlarmMessage(SensorAlarm alarm, SensorAlarmUser user) {
+    public boolean sendAlarmMessage(SensorAlarm alarm/*, SensorAlarmUser user*/) {
         System.out.println("发送微信小程序通知:");
         return false;
     }

+ 13 - 0
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/dataclean/impl/AbsRenkeMonitorDataProcessor.java

@@ -173,7 +173,13 @@ public abstract class AbsRenkeMonitorDataProcessor implements MonitorDataProcess
         sensorData.setTime(defaultTime);
         sensorData.setCreateTime(InfluxdbTypeConverter.instantStr(defaultTime));
         //设置模型型号
+        float lat = data.getLat();
+        float lng = data.getLng();
+        double latDouble = lat;
+        double lngDouble = lng;
         sensorData.setModelName(modelName);
+        sensorData.setLat(latDouble);
+        sensorData.setLng(lngDouble);
         sensorData.setDeviceId(deviceId);
         return sensorData;
     }
@@ -203,4 +209,11 @@ public abstract class AbsRenkeMonitorDataProcessor implements MonitorDataProcess
         publishDeviceEvent(deviceId, timestamp, MonitorDeviceHeartBeatEvent.class);
     }
 
+    protected Float floatValue(float value) {
+        if (value != 0.0) {
+            return value;
+        } else {
+            return null;
+        }
+    }
 }

+ 4 - 5
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/dataclean/impl/WifiCO2TempHumidityProcessor.java

@@ -39,13 +39,12 @@ public class WifiCO2TempHumidityProcessor extends AbsRenkeMonitorDataProcessor {
         // 最后一路的温度的值0=电源供电  100 电池供电
         final String plugInStatus = nodeList.get(numNodes - 1).getTem() < 1 ? PowerEnum.AC.getCode() : PowerEnum.DC.getCode();
         // 最后一路的湿度的值 * 10 表示CO2的含量
-        float CO2 = nodeList.get(numNodes - 1).getHum() * 10;
+        Float hum = floatValue(nodeList.get(numNodes - 1).getHum());
+        Float CO2 = hum == null ? null : hum * 10;
         NodeData nodeData = nodeList.get(0);
         SensorData sensorData = defaultSensorData(data);
-        sensorData.setTemperature(nodeData.getTem());
-        sensorData.setHumidity(nodeData.getHum());
-        sensorData.setLat(nodeData.getLat());
-        sensorData.setLng(nodeData.getLng());
+        sensorData.setTemperature(floatValue(nodeData.getTem()));
+        sensorData.setHumidity(floatValue(nodeData.getHum()));
         // c02含量
         sensorData.setCo2(CO2);
         return Lists.newArrayList(sensorData);

+ 3 - 9
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/dataclean/impl/WifiLowTempRecorderProcessor1.java

@@ -36,15 +36,9 @@ public class WifiLowTempRecorderProcessor1 extends AbsRenkeMonitorDataProcessor
         // 最后一路的温度的值0=电源供电  100 电池供电
         final String plugInStatus = nodeList.get(numNodes - 1).getTem() < 1 ? PowerEnum.AC.getCode() : PowerEnum.DC.getCode();
         SensorData sensorData = defaultSensorData(data);
-        // 只处理有效数据:温度和湿度不为0
-        if (nodeData.getTem() != 0.0 || nodeData.getHum() != 0.0) {
-//            log.info("记录ID: {}, 记录时间: {}, 温度: {}, 湿度: {}", sensorData.getDeviceId() + " : " + nodeData.getNodeId(), nodeData.getRecordTime(), nodeData.getTem(), nodeData.getHum());
-            sensorData.setTemperature(nodeData.getTem());
-            sensorData.setHumidity(nodeData.getHum());
-            sensorData.setLat(nodeData.getLat());
-            sensorData.setLng(nodeData.getLng());
-            sensorData.setPlugInStatus(plugInStatus);
-        }
+        sensorData.setTemperature(floatValue(nodeData.getTem()));
+        sensorData.setHumidity(floatValue(nodeData.getHum()));
+        sensorData.setPlugInStatus(plugInStatus);
         return Lists.newArrayList(sensorData);
     }
 

+ 2 - 4
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/dataclean/impl/WifiLowTempRecorderProcessor2.java

@@ -44,10 +44,8 @@ public class WifiLowTempRecorderProcessor2 extends AbsRenkeMonitorDataProcessor
         for (int i = 0; i < 2; i++) {
             NodeData nodeData = nodeList.get(i);
             SensorData sensorData = defaultSensorData(data);
-            sensorData.setTemperature(nodeData.getTem());
-            sensorData.setHumidity(nodeData.getHum());
-            sensorData.setLat(nodeData.getLat());
-            sensorData.setLng(nodeData.getLng());
+            sensorData.setTemperature(floatValue(nodeData.getTem()));
+            sensorData.setHumidity(floatValue(nodeData.getHum()));
             //设置路数
             sensorData.setRoads((i + 1));
             sensorData.setBattery(battery);//第三路温度表示电量

+ 2 - 4
snowy-plugin/snowy-plugin-coldchain/src/main/java/vip/xiaonuo/coldchain/core/service/dataprocess/dataclean/impl/WifiLowTempRecorderProcessor4.java

@@ -43,10 +43,8 @@ public class WifiLowTempRecorderProcessor4 extends AbsRenkeMonitorDataProcessor
         for (int i = 0; i < 4; i++) {
             NodeData nodeData = nodeList.get(i);
             SensorData sensorData = defaultSensorData(data);
-            sensorData.setTemperature(nodeData.getTem());
-            sensorData.setHumidity(nodeData.getHum());
-            sensorData.setLat(nodeData.getLat());
-            sensorData.setLng(nodeData.getLng());
+            sensorData.setTemperature(floatValue(nodeData.getTem()));
+            sensorData.setHumidity(floatValue(nodeData.getHum()));
             //设置路数
             sensorData.setRoads((i + 1));
             sensorData.setBattery(battery);