diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqAlarmRule.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqAlarmRule.java index b8c3098..d11fe27 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqAlarmRule.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqAlarmRule.java @@ -90,6 +90,8 @@ public class BjqAlarmRule implements MqttMessageRule { deviceAlarmBo.setDurationTime(durationBetween); // 0已处理,1未处理 deviceAlarmBo.setTreatmentState(0); + // 告警状态,0 解除告警, 1 告警中 + deviceAlarmBo.setAlarmState(0); deviceAlarmService.updateByBo(deviceAlarmBo); } } @@ -107,6 +109,8 @@ public class BjqAlarmRule implements MqttMessageRule { deviceAlarmBo.setStartTime(new Date()); // 0已处理,1未处理 deviceAlarmBo.setTreatmentState(1); + // 告警状态,0 解除告警, 1 告警中 + deviceAlarmBo.setAlarmState(1); // LoginUser loginUser = LoginHelper.getLoginUser(); // deviceAlarmBo.setCreateBy(loginUser.getUserId()); diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqLocationDataRule.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqLocationDataRule.java index 69637bf..0c0732d 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqLocationDataRule.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqLocationDataRule.java @@ -5,6 +5,8 @@ import com.fuyuanshen.common.core.constant.GlobalConstants; import com.fuyuanshen.common.core.utils.StringUtils; import com.fuyuanshen.common.json.utils.JsonUtils; import com.fuyuanshen.common.redis.utils.RedisUtils; +import com.fuyuanshen.equipment.mapper.DeviceMapper; +import com.fuyuanshen.equipment.service.DeviceService; import com.fuyuanshen.equipment.utils.map.GetAddressFromLatUtil; import com.fuyuanshen.equipment.utils.map.LngLonUtil; import com.fuyuanshen.global.mqtt.base.MqttMessageRule; @@ -36,8 +38,9 @@ import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVIC @RequiredArgsConstructor @Slf4j public class BjqLocationDataRule implements MqttMessageRule { - + private final MqttGateway mqttGateway; + private final DeviceService deviceService; @Override @@ -56,6 +59,8 @@ public class BjqLocationDataRule implements MqttMessageRule { // 异步发送经纬度到Redis asyncSendLocationToRedisWithFuture(context.getDeviceImei(), latitude, longitude); + // 异步保存数据 + asyncSaveLocationToMySQLWithFuture(context.getDeviceImei(), latitude, longitude); Map map = buildLocationDataMap(latitude, longitude); mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY + context.getDeviceImei(), 1, JsonUtils.toJsonString(map)); @@ -114,13 +119,13 @@ public class BjqLocationDataRule implements MqttMessageRule { public void asyncSendLocationToRedisWithFuture(String deviceImei, String latitude, String longitude) { CompletableFuture.runAsync(() -> { try { - if(StringUtils.isBlank(latitude) || StringUtils.isBlank(longitude)){ + if (StringUtils.isBlank(latitude) || StringUtils.isBlank(longitude)) { return; } // String[] latArr = latitude.split("\\."); // String[] lonArr = longitude.split("\\."); // // 将位置信息存储到Redis中 - String redisKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX+ deviceImei + DEVICE_LOCATION_KEY_PREFIX; + String redisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + deviceImei + DEVICE_LOCATION_KEY_PREFIX; // String redisObj = RedisUtils.getCacheObject(redisKey); // JSONObject jsonOBj = JSONObject.parseObject(redisObj); // if(jsonOBj != null){ @@ -153,7 +158,6 @@ public class BjqLocationDataRule implements MqttMessageRule { locationInfo.put("timestamp", System.currentTimeMillis()); - String locationJson = JsonUtils.toJsonString(locationInfo); // 存储到Redis @@ -171,12 +175,38 @@ public class BjqLocationDataRule implements MqttMessageRule { }); } + + /** + * 异步保存位置信息到MySQL数据库 + * + * @param deviceImei 设备IMEI + * @param latitude 纬度 + * @param longitude 经度 + */ + public void asyncSaveLocationToMySQLWithFuture(String deviceImei, String latitude, String longitude) { + CompletableFuture.runAsync(() -> { + try { + if (StringUtils.isBlank(latitude) || StringUtils.isBlank(longitude)) { + return; + } + + // 调用服务层方法更新设备位置信息 + deviceService.updateDeviceLocationByImei(deviceImei, longitude, latitude); + + log.info("位置信息已异步保存到MySQL: device={}, lat={}, lon={}", deviceImei, latitude, longitude); + } catch (Exception e) { + log.error("异步保存位置信息到MySQL时出错: device={}, error={}", deviceImei, e.getMessage(), e); + } + }); + } + + /** * 存储设备30天历史轨迹到Redis (使用Sorted Set) */ public void storeDeviceTrajectoryWithSortedSet(String deviceImei, String locationJson) { try { - String trajectoryKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + deviceImei + DeviceRedisKeyConstants.DEVICE_LOCATION_HISTORY_KEY_PREFIX; + String trajectoryKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + deviceImei + DeviceRedisKeyConstants.DEVICE_LOCATION_HISTORY_KEY_PREFIX; // String trajectoryKey = "device:trajectory:zset:" + deviceImei; // String locationJson = JsonUtils.toJsonString(locationInfo); long timestamp = System.currentTimeMillis(); @@ -194,20 +224,20 @@ public class BjqLocationDataRule implements MqttMessageRule { log.error("存储设备轨迹到Redis(ZSet)失败: device={}, error={}", deviceImei, e.getMessage(), e); } } - + private Map buildLocationDataMap(String latitude, String longitude) { String[] latArr = latitude.split("\\."); String[] lonArr = longitude.split("\\."); - + ArrayList intData = new ArrayList<>(); intData.add(11); intData.add(Integer.parseInt(latArr[0])); String str1 = latArr[1]; - intData.add(Integer.parseInt(str1.substring(0,4))); + intData.add(Integer.parseInt(str1.substring(0, 4))); String str2 = lonArr[1]; intData.add(Integer.parseInt(lonArr[0])); - intData.add(Integer.parseInt(str2.substring(0,4))); - + intData.add(Integer.parseInt(str2.substring(0, 4))); + Map map = new HashMap<>(); map.put("instruct", intData); return map; diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/controller/LargeScreenController.java b/fys-admin/src/main/java/com/fuyuanshen/web/controller/LargeScreenController.java new file mode 100644 index 0000000..2c312df --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/web/controller/LargeScreenController.java @@ -0,0 +1,142 @@ +package com.fuyuanshen.web.controller; + +import com.fuyuanshen.common.core.domain.R; +import com.fuyuanshen.equipment.domain.vo.*; +import com.fuyuanshen.equipment.service.IDeviceAlarmService; +import com.fuyuanshen.equipment.service.DeviceService; +import com.fuyuanshen.equipment.service.IWeatherService; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * 大屏数据 + * + * @author: 默苍璃 + * @date: 2025-09-27 08:42 + */ +@Tag(name = "大屏数据", description = "大屏数据") +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/api/largeScreen") +public class LargeScreenController { + + private final IDeviceAlarmService deviceAlarmService; + private final DeviceService deviceService; + private final IWeatherService weatherService; + + + /** + * 获取设备总览信息 + * 包含设备总数、在线设备数量、设备型号数量 + */ + @GetMapping("/getDeviceOverview") + public R getDeviceOverview() { + return R.ok(deviceService.getDeviceOverview()); + } + + + /** + * 获取 实时报警信息 + * RealtimeAlarm + */ + @GetMapping("/getRealtimeAlarm") + public R> getRealtimeAlarm() { + return R.ok(deviceAlarmService.getRealtimeAlarm()); + } + + + /** + * 获取报警统计数据 + * 包括正在报警数量、报警总数、已处理报警数量 + */ + @GetMapping("/getAlarmStatistics") + public R getAlarmStatistics() { + return R.ok(deviceAlarmService.getAlarmStatistics()); + } + + + /** + * 获取最近一年每月告警统计数据 + */ + @GetMapping("/getMonthlyAlarmStatistics") + public R getMonthlyAlarmStatistics() { + return R.ok(deviceAlarmService.getMonthlyAlarmStatistics()); + } + + + /** + * 获取设备通讯方式统计数据 + * 包含通讯方式名称、设备总数、异常设备数 + */ + @GetMapping("/getDeviceCommunicationModeStatistics") + public R> getDeviceCommunicationModeStatistics() { + return R.ok(deviceService.getDeviceCommunicationModeStatistics()); + } + + + /** + * 获取设备使用频次统计数据 + * + * @param days 天数(近一个月传30,近半年传180) + */ + @GetMapping("/getDeviceUsageFrequency") + public R> getDeviceUsageFrequency(@RequestParam int days) { + return R.ok(deviceService.getDeviceUsageFrequency(days)); + } + + + /** + * 根据条件查询设备位置信息 + * + * @param groupId 设备分组ID + * @param deviceType 设备类型 + * @param deviceImei 设备IMEI + * @return 设备位置信息列表 + */ + @GetMapping("/getDeviceLocationInfo") + public R> getDeviceLocationInfo( + @RequestParam(required = false) Long groupId, + @RequestParam(required = false) Long deviceType, + @RequestParam(required = false) String deviceImei) { + return R.ok(deviceService.getDeviceLocationInfo(groupId, deviceType, deviceImei)); + } + + + /** + * 根据经纬度获取天气信息 + * + * @param latitude 纬度 + * @param longitude 经度 + * @return 天气信息 + */ + @GetMapping("/weather") + public R getWeatherInfo( + @RequestParam Double latitude, + @RequestParam Double longitude) { + if (latitude == null || longitude == null) { + return R.fail("经纬度参数不能为空"); + } + + // 简单的经纬度范围校验 + if (latitude < -90 || latitude > 90 || longitude < -180 || longitude > 180) { + return R.fail("经纬度参数范围不正确"); + } + + WeatherInfoVo weatherInfo = weatherService.getWeatherByCoordinates(latitude, longitude); + if (weatherInfo != null) { + return R.ok(weatherInfo); + } else { + return R.fail("获取天气信息失败"); + } + } + + +} \ No newline at end of file diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/APPDeviceType.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/APPDeviceType.java index ce56330..18f9b59 100644 --- a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/APPDeviceType.java +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/APPDeviceType.java @@ -49,7 +49,7 @@ public class APPDeviceType extends TenantEntity { @Schema(name = "联网方式", example = "0:无;1:4G;2:WIFI") private String networkWay; - @Schema(name = "通讯方式", example = "0:4G;1:蓝牙") + @Schema(name = "通讯方式", example = "通讯方式 0:4G;1:蓝牙,2 4G&蓝牙") private String communicationMode; diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/AppDeviceBindRecord.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/AppDeviceBindRecord.java index 0bad2ab..575c1ba 100644 --- a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/AppDeviceBindRecord.java +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/AppDeviceBindRecord.java @@ -50,6 +50,9 @@ public class AppDeviceBindRecord extends TenantEntity { */ private Date bindingTime; + /** + * 通讯方式 0:4G;1:蓝牙,2 4G&蓝牙 + */ private Integer communicationMode; } diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/query/APPDeviceQueryCriteria.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/query/APPDeviceQueryCriteria.java index 11d4411..8064f40 100644 --- a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/query/APPDeviceQueryCriteria.java +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/query/APPDeviceQueryCriteria.java @@ -59,7 +59,7 @@ public class APPDeviceQueryCriteria { @Schema(name = "租户ID") private Long tenantId; - @Schema(name = "通讯方式", example = "0:4G;1:蓝牙") + @Schema(name = "通讯方式", example = "通讯方式 0:4G;1:蓝牙,2 4G&蓝牙") private Integer communicationMode; } diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/APPDeviceTypeVo.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/APPDeviceTypeVo.java index 26a3705..2e60a81 100644 --- a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/APPDeviceTypeVo.java +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/APPDeviceTypeVo.java @@ -10,6 +10,9 @@ public class APPDeviceTypeVo { private String typeName; + /** + * 通讯方式 0:4G;1:蓝牙,2 4G&蓝牙 + */ private String communicationMode; } diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceDetailVo.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceDetailVo.java index c172809..6f832ae 100644 --- a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceDetailVo.java +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceDetailVo.java @@ -33,7 +33,7 @@ public class AppDeviceDetailVo { private String deviceMac; /** - * 通讯方式 0:4G;1:蓝牙 + * 通讯方式 0:4G;1:蓝牙,2 4G&蓝牙 */ private Integer communicationMode; diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceShareDetailVo.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceShareDetailVo.java index f9e8483..fe933ee 100644 --- a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceShareDetailVo.java +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceShareDetailVo.java @@ -68,7 +68,7 @@ public class AppDeviceShareDetailVo implements Serializable { private String deviceMac; /** - * 通讯方式 0:4G;1:蓝牙 + * 通讯方式 0:4G;1:蓝牙,2 4G&蓝牙 */ private Integer communicationMode; diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/bo/DeviceAlarmBo.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/bo/DeviceAlarmBo.java index 2c298dc..5e3271f 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/bo/DeviceAlarmBo.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/bo/DeviceAlarmBo.java @@ -114,5 +114,9 @@ public class DeviceAlarmBo extends TenantEntity { */ private Integer treatmentState; + /** + * 告警状态,0 解除告警, 1 告警中 + */ + private Integer alarmState; } diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/AlarmStatisticsVo.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/AlarmStatisticsVo.java new file mode 100644 index 0000000..7de7149 --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/AlarmStatisticsVo.java @@ -0,0 +1,57 @@ +package com.fuyuanshen.equipment.domain.vo; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 报警统计信息 + * + * @author: fuyuanshen + * @date: 2025-09-27 + */ +@Data +public class AlarmStatisticsVo implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 正在报警数量(未处理的报警) + */ + private Integer activeAlarms = 0; + + /** + * 报警总数 + */ + private Integer totalAlarms = 0; + + /** + * 已处理报警数量 + */ + private Integer processedAlarms = 0; + + /** + * 强制报警数量 + * device_action = 0 + */ + private Integer forcedAlarms = 0; + + /** + * 撞击闯入报警数量 + * device_action = 1 + */ + private Integer intrusionImpactAlarms = 0; + + /** + * 手动报警数量 + * device_action = 2 + */ + private Integer manualAlarms = 0; + + /** + * 电子围栏告警数量 + * device_action = 3 + */ + private Integer geoFenceAlarms = 0; + +} \ No newline at end of file diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/DeviceAlarmVo.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/DeviceAlarmVo.java index c56bc1e..b1e68b3 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/DeviceAlarmVo.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/DeviceAlarmVo.java @@ -123,6 +123,7 @@ public class DeviceAlarmVo implements Serializable { private String durationTime; /** + * 处理状态 * 0已处理,1未处理 */ @ExcelProperty(value = "0已处理,1未处理") @@ -135,5 +136,4 @@ public class DeviceAlarmVo implements Serializable { @Schema(name = "设备图片") private String devicePic; - } diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/DeviceCommunicationModeStatisticsVo.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/DeviceCommunicationModeStatisticsVo.java new file mode 100644 index 0000000..729e817 --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/DeviceCommunicationModeStatisticsVo.java @@ -0,0 +1,39 @@ +package com.fuyuanshen.equipment.domain.vo; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 设备通讯方式统计Vo + * + * @author: 默苍璃 + * @date: 2025-09-27 + */ +@Data +public class DeviceCommunicationModeStatisticsVo implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 通讯方式名称 + * 0:4G;1:蓝牙;2:4G&蓝牙 + */ + private String communicationModeName; + + /** + * 通讯方式值 + * 0:4G;1:蓝牙;2:4G&蓝牙 + */ + private Integer communicationModeValue; + + /** + * 设备总数 + */ + private Integer totalDevices = 0; + + /** + * 异常设备数 + */ + private Integer abnormalDevices = 0; +} \ No newline at end of file diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/DeviceLocationVo.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/DeviceLocationVo.java new file mode 100644 index 0000000..3f3c876 --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/DeviceLocationVo.java @@ -0,0 +1,36 @@ +package com.fuyuanshen.equipment.domain.vo; + +import com.fuyuanshen.equipment.domain.DeviceGeoFence; +import com.fuyuanshen.equipment.domain.dto.FenceCheckResponse; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * 设备位置信息VO + * + * @author: 默苍璃 + * @date: 2025-09-2714:33 + */ +@Data +@Schema(description = "设备位置信息VO") +public class DeviceLocationVo { + + @Schema(description = "设备ID") + private Long deviceId; + + @Schema(description = "设备名称") + private String deviceName; + + @Schema(description = "经度") + private String longitude; + + @Schema(description = "纬度") + private String latitude; + + @Schema(description = "设备是否在电子围栏内") + private Boolean inFence; + + @Schema(description = "进入的电子围栏信息") + private DeviceGeoFence fenceInfo; + +} \ No newline at end of file diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/DeviceOverviewVo.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/DeviceOverviewVo.java new file mode 100644 index 0000000..0a4f084 --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/DeviceOverviewVo.java @@ -0,0 +1,32 @@ +package com.fuyuanshen.equipment.domain.vo; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 设备总览信息 + * + * @author: fuyuanshen + * @date: 2025-09-27 + */ +@Data +public class DeviceOverviewVo implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 设备总数 + */ + private Integer totalDevices = 0; + + /** + * 在线设备数量 + */ + private Integer onlineDevices = 0; + + /** + * 设备型号数量 + */ + private Integer deviceTypes = 0; +} \ No newline at end of file diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/DeviceUsageFrequencyVo.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/DeviceUsageFrequencyVo.java new file mode 100644 index 0000000..74f1bd2 --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/DeviceUsageFrequencyVo.java @@ -0,0 +1,27 @@ +package com.fuyuanshen.equipment.domain.vo; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 设备使用频次统计Vo + * + * @author: 默苍璃 + * @date: 2025-09-27 + */ +@Data +public class DeviceUsageFrequencyVo implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 设备名称 + */ + private String deviceName; + + /** + * 使用频次 + */ + private Integer frequency = 0; +} \ No newline at end of file diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/MonthlyAlarmStatisticsVo.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/MonthlyAlarmStatisticsVo.java new file mode 100644 index 0000000..b556774 --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/MonthlyAlarmStatisticsVo.java @@ -0,0 +1,26 @@ +package com.fuyuanshen.equipment.domain.vo; + +import lombok.Data; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +/** + * 每月告警统计信息 + * + * @author: fuyuanshen + * @date: 2025-09-27 + */ +@Data +public class MonthlyAlarmStatisticsVo implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 每月告警统计数据 + * key: 月份 (m1-m12) + * value: 告警数量 + */ + private Map monthlyStatistics = new HashMap<>(); +} \ No newline at end of file diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/WeatherInfoVo.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/WeatherInfoVo.java new file mode 100644 index 0000000..be48851 --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/WeatherInfoVo.java @@ -0,0 +1,98 @@ +package com.fuyuanshen.equipment.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.time.LocalDateTime; + +/**天气信息视图对象 + * @author: 默苍璃 + * @date: 2025-09-2715:25 + */ +@Data +@Schema(description = "天气信息视图对象") +public class WeatherInfoVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 经度 + */ + @Schema(description = "经度") + private Double longitude; + + /** + * 纬度 + */ + @Schema(description = "纬度") + private Double latitude; + + /** + * 天气状况 + */ + @Schema(description = "天气状况") + private String weatherCondition; + + /** + * 天气描述 + */ + @Schema(description = "天气描述") + private String description; + + /** + * 温度 + */ + @Schema(description = "温度(摄氏度)") + private Double temperature; + + /** + * 体感温度 + */ + @Schema(description = "体感温度(摄氏度)") + private Double feelsLike; + + /** + * 湿度 + */ + @Schema(description = "湿度(%)") + private Integer humidity; + + /** + * 气压 + */ + @Schema(description = "气压(hPa)") + private Double pressure; + + /** + * 能见度 + */ + @Schema(description = "能见度(米)") + private Integer visibility; + + /** + * 风速 + */ + @Schema(description = "风速(m/s)") + private Double windSpeed; + + /** + * 风向 + */ + @Schema(description = "风向(度)") + private Integer windDirection; + + /** + * 云量 + */ + @Schema(description = "云量(%)") + private Integer cloudiness; + + /** + * 更新时间 + */ + @Schema(description = "数据更新时间") + private LocalDateTime updateTime; +} diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceAlarmMapper.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceAlarmMapper.java index d6b5e45..d5c4246 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceAlarmMapper.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceAlarmMapper.java @@ -4,10 +4,16 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.fuyuanshen.common.mybatis.core.page.PageQuery; import com.fuyuanshen.equipment.domain.DeviceAlarm; import com.fuyuanshen.equipment.domain.bo.DeviceAlarmBo; +import com.fuyuanshen.equipment.domain.vo.AlarmStatisticsVo; import com.fuyuanshen.equipment.domain.vo.DeviceAlarmVo; +import com.fuyuanshen.equipment.domain.vo.MonthlyAlarmStatisticsVo; import com.fuyuanshen.common.mybatis.core.mapper.BaseMapperPlus; +import org.apache.ibatis.annotations.MapKey; import org.apache.ibatis.annotations.Param; +import java.util.List; +import java.util.Map; + /** * 设备告警Mapper接口 * @@ -23,7 +29,7 @@ public interface DeviceAlarmMapper extends BaseMapperPlus selectVoPage( Page pageQuery,@Param("bo") DeviceAlarmBo bo); + Page selectVoPage(Page pageQuery, @Param("bo") DeviceAlarmBo bo); /** * 根据设备IMEI查询最新的一条告警数据 @@ -34,4 +40,25 @@ public interface DeviceAlarmMapper extends BaseMapperPlus getRealtimeAlarm(); + + /** + * 获取报警统计数据 + * + * @return 报警统计数据 + */ + AlarmStatisticsVo getAlarmStatistics(); + + /** + * 获取最近一年每月告警统计数据 + * + * @return 每月告警统计数据 + */ + @MapKey("key") + List> getMonthlyAlarmStatistics(); +} \ No newline at end of file diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceFenceAccessRecordMapper.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceFenceAccessRecordMapper.java index 378635d..b20d37f 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceFenceAccessRecordMapper.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceFenceAccessRecordMapper.java @@ -40,4 +40,13 @@ public interface DeviceFenceAccessRecordMapper extends BaseMapperPlus selectVoPageByXml(Page page, @Param("bo") DeviceFenceAccessRecordBo bo); + /** + * 查询设备最新的围栏记录 + * + * @param deviceId 设备ID + * @return 围栏记录 + */ + DeviceFenceAccessRecordVo selectLatestRecordByDeviceId(String deviceId); + + } diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceMapper.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceMapper.java index 7b9a99f..0c41154 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceMapper.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceMapper.java @@ -105,6 +105,9 @@ public interface DeviceMapper extends BaseMapper { */ List> getEquipmentUsageData(@Param("deviceTypeId") Long deviceTypeId, @Param("range") Integer range); + // 在DeviceMapper.java中添加方法 + DeviceOverviewVo getDeviceOverview(); + // 在DeviceMapper.java中添加方法 int getUsageDataForMonth(@Param("deviceId") Long deviceId, @Param("year") int year, @@ -117,4 +120,19 @@ public interface DeviceMapper extends BaseMapper { * @return 设备信息 */ Device selectDeviceByImei(@Param("deviceImei") String deviceImei); + + /** + * 获取设备通讯方式统计数据 + * + * @return 通讯方式统计列表 + */ + List getDeviceCommunicationModeStatistics(); + + /** + * 获取设备使用频次统计 + * + * @param days 天数 + * @return 设备使用频次统计列表 + */ + List getDeviceUsageFrequency(@Param("days") int days); } \ No newline at end of file diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/DeviceService.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/DeviceService.java index dd86af5..f0ab814 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/DeviceService.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/DeviceService.java @@ -1,11 +1,13 @@ package com.fuyuanshen.equipment.service; +import cn.hutool.core.lang.Dict; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.fuyuanshen.common.core.domain.PageResult; import com.fuyuanshen.common.mybatis.core.page.PageQuery; import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; import com.fuyuanshen.equipment.domain.Device; +import com.fuyuanshen.equipment.domain.DeviceType; import com.fuyuanshen.equipment.domain.dto.AppDeviceBo; import com.fuyuanshen.equipment.domain.form.DeviceForm; import com.fuyuanshen.equipment.domain.query.DeviceQueryCriteria; @@ -152,4 +154,49 @@ public interface DeviceService extends IService { * @return 设备信息 */ Device selectDeviceByImei(String deviceImei); + + /** + * 获取设备总览数据 + * + * @return 设备总览数据 + */ + DeviceOverviewVo getDeviceOverview(); + + /** + * 获取设备通讯方式统计数据 + * + * @return 通讯方式统计数据列表 + */ + List getDeviceCommunicationModeStatistics(); + + /** + * 获取设备使用频次统计 + * + * @param days 天数(近一个月: 30, 近半年: 180) + * @return 设备使用频次统计列表 + */ + List getDeviceUsageFrequency(int days); + + /** + * 根据设备IMEI更新设备的经纬度信息 + * + * @param deviceImei 设备IMEI + * @param longitude 经度 + * @param latitude 纬度 + * @return 是否更新成功 + */ + boolean updateDeviceLocationByImei(String deviceImei, String longitude, String latitude); + + + /** + * 根据条件查询设备位置信息 + * + * @param groupId 设备分组ID + * @param deviceType 设备类型 + * @param deviceImei 设备IMEI + * @return 设备位置信息列表 + */ + List getDeviceLocationInfo(Long groupId, Long deviceType, String deviceImei); + + } \ No newline at end of file diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/IDeviceAlarmService.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/IDeviceAlarmService.java index 377e55e..7e594e0 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/IDeviceAlarmService.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/IDeviceAlarmService.java @@ -1,12 +1,15 @@ package com.fuyuanshen.equipment.service; -import com.fuyuanshen.equipment.domain.vo.DeviceAlarmVo; -import com.fuyuanshen.equipment.domain.bo.DeviceAlarmBo; import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; import com.fuyuanshen.common.mybatis.core.page.PageQuery; +import com.fuyuanshen.equipment.domain.bo.DeviceAlarmBo; +import com.fuyuanshen.equipment.domain.vo.AlarmStatisticsVo; +import com.fuyuanshen.equipment.domain.vo.DeviceAlarmVo; +import com.fuyuanshen.equipment.domain.vo.MonthlyAlarmStatisticsVo; -import java.util.Collection; import java.util.List; +import java.util.Collection; +import java.util.Map; /** * 设备告警Service接口 @@ -75,4 +78,24 @@ public interface IDeviceAlarmService { DeviceAlarmVo queryLatestByDeviceImei(String deviceImei); -} + /** + * 获取实时告警列表 + * + * @return 设备告警列表 + */ + List getRealtimeAlarm(); + + /** + * 获取报警统计数据 + * + * @return 报警统计数据 + */ + AlarmStatisticsVo getAlarmStatistics(); + + /** + * 获取最近一年每月告警统计数据 + * + * @return 每月告警统计数据 + */ + MonthlyAlarmStatisticsVo getMonthlyAlarmStatistics(); +} \ No newline at end of file diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/IDeviceGeoFenceService.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/IDeviceGeoFenceService.java index 69a7d8f..65eaa44 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/IDeviceGeoFenceService.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/IDeviceGeoFenceService.java @@ -1,7 +1,10 @@ package com.fuyuanshen.equipment.service; +import com.baomidou.mybatisplus.extension.service.IService; import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; import com.fuyuanshen.common.mybatis.core.page.PageQuery; +import com.fuyuanshen.equipment.domain.Device; +import com.fuyuanshen.equipment.domain.DeviceGeoFence; import com.fuyuanshen.equipment.domain.bo.DeviceGeoFenceBo; import com.fuyuanshen.equipment.domain.dto.FenceCheckResponse; import com.fuyuanshen.equipment.domain.query.FenceCheckRequest; @@ -16,7 +19,7 @@ import java.util.List; * @author Lion Li * @date 2025-09-11 */ -public interface IDeviceGeoFenceService { +public interface IDeviceGeoFenceService extends IService { /** * 查询电子围栏 diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/IWeatherService.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/IWeatherService.java new file mode 100644 index 0000000..e173266 --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/IWeatherService.java @@ -0,0 +1,20 @@ +package com.fuyuanshen.equipment.service; + +import com.fuyuanshen.equipment.domain.vo.WeatherInfoVo; + +/**天气信息服务接口 + * @author: 默苍璃 + * @date: 2025-09-2715:26 + */ +public interface IWeatherService { + + /** + * 根据经纬度获取天气信息 + * + * @param latitude 纬度 + * @param longitude 经度 + * @return 天气信息 + */ + WeatherInfoVo getWeatherByCoordinates(Double latitude, Double longitude); + +} diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceAlarmServiceImpl.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceAlarmServiceImpl.java index b345b39..8f1a62d 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceAlarmServiceImpl.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceAlarmServiceImpl.java @@ -12,7 +12,9 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import com.fuyuanshen.equipment.domain.bo.DeviceAlarmBo; +import com.fuyuanshen.equipment.domain.vo.AlarmStatisticsVo; import com.fuyuanshen.equipment.domain.vo.DeviceAlarmVo; +import com.fuyuanshen.equipment.domain.vo.MonthlyAlarmStatisticsVo; import com.fuyuanshen.equipment.domain.DeviceAlarm; import com.fuyuanshen.equipment.mapper.DeviceAlarmMapper; import com.fuyuanshen.equipment.service.IDeviceAlarmService; @@ -20,6 +22,7 @@ import com.fuyuanshen.equipment.service.IDeviceAlarmService; import java.util.List; import java.util.Map; import java.util.Collection; +import java.util.HashMap; /** * 设备告警Service业务层处理 @@ -161,4 +164,51 @@ public class DeviceAlarmServiceImpl implements IDeviceAlarmService { return baseMapper.selectLatestByDeviceImei(deviceImei); } -} + + /** + * 获取实时告警列表 + * + * @return 设备告警列表 + */ + @Override + public List getRealtimeAlarm() { + return baseMapper.getRealtimeAlarm(); + } + + /** + * 获取报警统计数据 + * + * @return 报警统计数据 + */ + @Override + public AlarmStatisticsVo getAlarmStatistics() { + return baseMapper.getAlarmStatistics(); + } + + /** + * 获取最近一年每月告警统计数据 + * + * @return 每月告警统计数据 + */ + @Override + public MonthlyAlarmStatisticsVo getMonthlyAlarmStatistics() { + List> result = baseMapper.getMonthlyAlarmStatistics(); + MonthlyAlarmStatisticsVo vo = new MonthlyAlarmStatisticsVo(); + + if (result != null && !result.isEmpty()) { + Map data = result.get(0); + Map monthlyStats = vo.getMonthlyStatistics(); + + for (Map.Entry entry : data.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + // 将数据库查询结果转换为Integer类型 + Integer count = (value != null) ? Integer.valueOf(value.toString()) : 0; + monthlyStats.put(key, count); + } + } + + return vo; + } + +} \ No newline at end of file diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceGeoFenceServiceImpl.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceGeoFenceServiceImpl.java index 086d473..3890616 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceGeoFenceServiceImpl.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceGeoFenceServiceImpl.java @@ -1,5 +1,6 @@ package com.fuyuanshen.equipment.service.impl; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.fuyuanshen.common.core.utils.MapstructUtils; @@ -8,6 +9,7 @@ import com.fuyuanshen.common.mybatis.core.page.PageQuery; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.fuyuanshen.equipment.domain.Device; import com.fuyuanshen.equipment.domain.DeviceGeoFence; import com.fuyuanshen.equipment.domain.bo.DeviceFenceAccessRecordBo; import com.fuyuanshen.equipment.domain.bo.DeviceFenceStatusBo; @@ -17,6 +19,7 @@ import com.fuyuanshen.equipment.domain.query.FenceCheckRequest; import com.fuyuanshen.equipment.domain.vo.DeviceFenceStatusVo; import com.fuyuanshen.equipment.domain.vo.DeviceGeoFenceVo; import com.fuyuanshen.equipment.mapper.DeviceGeoFenceMapper; +import com.fuyuanshen.equipment.mapper.DeviceMapper; import com.fuyuanshen.equipment.service.IDeviceFenceAccessRecordService; import com.fuyuanshen.equipment.service.IDeviceFenceStatusService; import com.fuyuanshen.equipment.service.IDeviceGeoFenceService; @@ -38,7 +41,7 @@ import java.util.*; @Slf4j @RequiredArgsConstructor @Service -public class DeviceGeoFenceServiceImpl implements IDeviceGeoFenceService { +public class DeviceGeoFenceServiceImpl extends ServiceImpl implements IDeviceGeoFenceService { private final DeviceGeoFenceMapper baseMapper; diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceServiceImpl.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceServiceImpl.java index 376584c..2b86b93 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceServiceImpl.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceServiceImpl.java @@ -11,6 +11,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.fuyuanshen.common.core.domain.model.LoginUser; import com.fuyuanshen.common.core.exception.BadRequestException; +import com.fuyuanshen.common.core.utils.SpringUtils; import com.fuyuanshen.common.core.utils.StringUtils; import com.fuyuanshen.common.mybatis.core.page.PageQuery; import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; @@ -19,11 +20,10 @@ import com.fuyuanshen.common.satoken.utils.LoginHelper; import com.fuyuanshen.customer.domain.Customer; import com.fuyuanshen.customer.mapper.CustomerMapper; import com.fuyuanshen.equipment.constants.DeviceConstants; -import com.fuyuanshen.equipment.domain.Device; -import com.fuyuanshen.equipment.domain.DeviceAssignments; -import com.fuyuanshen.equipment.domain.DeviceType; -import com.fuyuanshen.equipment.domain.DeviceTypeGrants; +import com.fuyuanshen.equipment.domain.*; +import com.fuyuanshen.equipment.domain.bo.DeviceFenceAccessRecordBo; import com.fuyuanshen.equipment.domain.dto.AppDeviceBo; +import com.fuyuanshen.equipment.domain.dto.FenceCheckResponse; import com.fuyuanshen.equipment.domain.form.DeviceForm; import com.fuyuanshen.equipment.domain.query.DeviceAssignmentQuery; import com.fuyuanshen.equipment.domain.query.DeviceQueryCriteria; @@ -32,13 +32,8 @@ import com.fuyuanshen.equipment.domain.vo.*; import com.fuyuanshen.equipment.enums.BindingStatusEnum; import com.fuyuanshen.equipment.enums.CommunicationModeEnum; import com.fuyuanshen.equipment.enums.DeviceActiveStatusEnum; -import com.fuyuanshen.equipment.mapper.DeviceAssignmentsMapper; -import com.fuyuanshen.equipment.mapper.DeviceMapper; -import com.fuyuanshen.equipment.mapper.DeviceTypeGrantsMapper; -import com.fuyuanshen.equipment.mapper.DeviceTypeMapper; -import com.fuyuanshen.equipment.service.DeviceAssignmentsService; -import com.fuyuanshen.equipment.service.DeviceService; -import com.fuyuanshen.equipment.service.DeviceTypeGrantsService; +import com.fuyuanshen.equipment.mapper.*; +import com.fuyuanshen.equipment.service.*; import com.fuyuanshen.system.domain.vo.SysOssVo; import com.fuyuanshen.system.domain.vo.SysRoleVo; import com.fuyuanshen.system.service.ISysOssService; @@ -88,6 +83,8 @@ public class DeviceServiceImpl extends ServiceImpl impleme private final DeviceTypeGrantsService deviceTypeGrantsService; private final DeviceTypeGrantsMapper deviceTypeGrantsMapper; + private final DeviceFenceAccessRecordMapper deviceFenceAccessRecordMapper; + /** * 分页查询设备 @@ -703,4 +700,120 @@ public class DeviceServiceImpl extends ServiceImpl impleme return baseMapper.selectDeviceByImei(deviceImei); } + /** + * 获取设备总览 + * + * @return + */ + @Override + public DeviceOverviewVo getDeviceOverview() { + return deviceMapper.getDeviceOverview(); + } + + /** + * 获取设备通讯方式统计 + * + * @return 设备通讯方式统计列表 + */ + @Override + public List getDeviceCommunicationModeStatistics() { + return deviceMapper.getDeviceCommunicationModeStatistics(); + } + + @Override + public List getDeviceUsageFrequency(int days) { + return deviceMapper.getDeviceUsageFrequency(days); + } + + /** + * 根据设备IMEI更新设备的经纬度信息 + * + * @param deviceImei 设备IMEI + * @param longitude 经度 + * @param latitude 纬度 + * @return 是否更新成功 + */ + @Override + public boolean updateDeviceLocationByImei(String deviceImei, String longitude, String latitude) { + // 根据设备IMEI查询设备 + Device device = deviceMapper.selectDeviceByImei(deviceImei); + if (device == null) { + return false; + } + + // 更新设备的经纬度信息 + device.setLongitude(longitude); + device.setLatitude(latitude); + + // 更新数据库中的设备信息 + return deviceMapper.updateById(device) > 0; + } + + + /** + * 根据条件查询设备位置信息 + * + * @param groupId 设备分组ID + * @param deviceType 设备类型 + * @param deviceImei 设备IMEI + * @return 设备位置信息列表 + */ + @Override + public List getDeviceLocationInfo(Long groupId, Long deviceType, String deviceImei) { + // 构建查询条件 + DeviceQueryCriteria criteria = new DeviceQueryCriteria(); + criteria.setGroupId(groupId); + criteria.setDeviceType(deviceType); + criteria.setDeviceImei(deviceImei); + + // 查询符合条件的设备 + List devices = deviceMapper.findDevices(criteria); + + // 构建返回结果 + List result = new ArrayList<>(); + + // 注入电子围栏服务 + IDeviceGeoFenceService geoFenceService = SpringUtils.getBean(IDeviceGeoFenceService.class); + + for (Device device : devices) { + DeviceLocationVo vo = new DeviceLocationVo(); + vo.setDeviceId(device.getId()); + vo.setDeviceName(device.getDeviceName()); + vo.setLongitude(device.getLongitude()); + vo.setLatitude(device.getLatitude()); + + // 检查设备是否在电子围栏内 + if (StringUtils.isNotBlank(device.getLongitude()) && StringUtils.isNotBlank(device.getLatitude())) { + // 查询设备最新的围栏进出记录 + DeviceFenceAccessRecordVo latestRecord = deviceFenceAccessRecordMapper.selectLatestRecordByDeviceId(String.valueOf(device.getId())); + + // 判断是否在围栏内 + if (latestRecord != null) { + // 如果最新的记录是进入围栏(事件类型为1),则设备在围栏内 + if (latestRecord.getEventType() != null && latestRecord.getEventType() == 1L) { + vo.setInFence(true); + + // 获取围栏完整信息 + DeviceGeoFence fenceInfo = geoFenceService.getById(latestRecord.getFenceId()); + if (fenceInfo != null) { + vo.setFenceInfo(fenceInfo); + } + } else { + vo.setInFence(false); + } + } else { + vo.setInFence(false); + } + } else { + vo.setInFence(false); + } + + result.add(vo); + } + + return result; + } + + + } diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/WeatherServiceImpl.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/WeatherServiceImpl.java new file mode 100644 index 0000000..1c80e1c --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/WeatherServiceImpl.java @@ -0,0 +1,82 @@ +package com.fuyuanshen.equipment.service.impl; + +import com.fuyuanshen.equipment.domain.vo.WeatherInfoVo; +import com.fuyuanshen.equipment.service.IWeatherService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; + +/**天气信息服务实现类 + * @author: 默苍璃 + * @date: 2025-09-2715:26 + */ +@Slf4j +@RequiredArgsConstructor +@Service +public class WeatherServiceImpl implements IWeatherService { + + // 这里使用OpenWeatherMap API作为示例 + private static final String WEATHER_API_URL = "http://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&appid={appid}&units=metric&lang=zh_cn"; + + // 需要在配置文件中配置API密钥 + private final String apiKey = ""; // 从配置文件获取 + + @Override + public WeatherInfoVo getWeatherByCoordinates(Double latitude, Double longitude) { + try { + // 注意:实际使用时需要配置API密钥并启用以下代码 + /* + RestTemplate restTemplate = new RestTemplate(); + String url = WEATHER_API_URL.replace("{lat}", latitude.toString()) + .replace("{lon}", longitude.toString()) + .replace("{appid}", apiKey); + + // 调用第三方API获取天气数据 + // 这里需要根据实际API返回的数据结构进行解析 + // 以下为示例代码,实际实现需要根据API文档调整 + + WeatherInfoVo weatherInfo = new WeatherInfoVo(); + weatherInfo.setLatitude(latitude); + weatherInfo.setLongitude(longitude); + weatherInfo.setUpdateTime(LocalDateTime.now()); + + // 模拟数据,实际应从API获取 + weatherInfo.setWeatherCondition("晴"); + weatherInfo.setDescription("晴朗"); + weatherInfo.setTemperature(25.0); + weatherInfo.setFeelsLike(26.0); + weatherInfo.setHumidity(60); + weatherInfo.setPressure(1013.0); + weatherInfo.setVisibility(10000); + weatherInfo.setWindSpeed(2.5); + weatherInfo.setWindDirection(180); + weatherInfo.setCloudiness(0); + + return weatherInfo; + */ + + // 临时返回模拟数据 + WeatherInfoVo weatherInfo = new WeatherInfoVo(); + weatherInfo.setLatitude(latitude); + weatherInfo.setLongitude(longitude); + weatherInfo.setWeatherCondition("晴"); + weatherInfo.setDescription("晴朗"); + weatherInfo.setTemperature(25.0); + weatherInfo.setFeelsLike(26.0); + weatherInfo.setHumidity(60); + weatherInfo.setPressure(1013.0); + weatherInfo.setVisibility(10000); + weatherInfo.setWindSpeed(2.5); + weatherInfo.setWindDirection(180); + weatherInfo.setCloudiness(0); + weatherInfo.setUpdateTime(LocalDateTime.now()); + + return weatherInfo; + } catch (Exception e) { + log.error("获取天气信息失败,经纬度: {},{}", latitude, longitude, e); + return null; + } + } +} diff --git a/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceAlarmMapper.xml b/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceAlarmMapper.xml index 1fbbf52..413c1da 100644 --- a/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceAlarmMapper.xml +++ b/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceAlarmMapper.xml @@ -14,7 +14,8 @@ left join device_type dt on dt.id = d.device_type - and d.device_name like concat('%', #{bo.content}, '%') or dt.type_name like concat('%', #{bo.content}, '%') + and d.device_name like concat('%', #{bo.content}, '%') or dt.type_name like concat('%', #{bo.content}, + '%') and d.device_name like concat('%', #{bo.deviceName}, '%') @@ -51,4 +52,52 @@ - + + + + + + + + + + + \ No newline at end of file diff --git a/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceFenceAccessRecordMapper.xml b/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceFenceAccessRecordMapper.xml index 8a13a04..375bec6 100644 --- a/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceFenceAccessRecordMapper.xml +++ b/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceFenceAccessRecordMapper.xml @@ -92,4 +92,15 @@ ORDER BY r.event_time DESC + + + + + \ No newline at end of file diff --git a/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceMapper.xml b/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceMapper.xml index 3d42b7a..f4681e3 100644 --- a/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceMapper.xml +++ b/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceMapper.xml @@ -1,5 +1,5 @@ - - + + @@ -319,6 +319,32 @@ a.create_time DESC + + + + + + + + +