From 8afc12f3b6fef7c2156eacba12c811d1d31e9d15 Mon Sep 17 00:00:00 2001 From: lxj <15683799673@163.com> Date: Fri, 29 Aug 2025 11:30:00 +0800 Subject: [PATCH 01/20] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=97=A0=E6=B3=95=E8=B0=83=E7=94=A8sdk?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E7=99=BB=E5=BD=95=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dromara/sis/service/impl/SisDeviceChannelServiceImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisDeviceChannelServiceImpl.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisDeviceChannelServiceImpl.java index 90f7783c..4b05153a 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisDeviceChannelServiceImpl.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisDeviceChannelServiceImpl.java @@ -47,7 +47,7 @@ public class SisDeviceChannelServiceImpl implements ISisDeviceChannelService { private final SisDeviceChannelMapper baseMapper; private final ISisDeviceGroupService deviceGroupService; - private HikApiService hikApiService; + private final HikApiService hikApiService; @@ -239,6 +239,7 @@ public class SisDeviceChannelServiceImpl implements ISisDeviceChannelService { } } else if (DeviceTypeEnum.NVR.getType().equals(bo.getDeviceType()) || DeviceTypeEnum.DVR.getType().equals(bo.getDeviceType())) { DeviceInfo channelInfo = hikApiService.getChannelInfo(bo.getDeviceIp()); + if (channelInfo != null && CollUtil.isNotEmpty(channelInfo.getChannelInfo())) { List insertChannels = new ArrayList<>(channelInfo.getChannelInfo().size()); List updateChannels = new ArrayList<>(channelInfo.getChannelInfo().size()); From fbc07ac629403dec83aafc99a46172e30d79bfad Mon Sep 17 00:00:00 2001 From: zcxlsm Date: Fri, 29 Aug 2025 15:50:00 +0800 Subject: [PATCH 02/20] =?UTF-8?q?refactor(property):=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E8=83=BD=E6=BA=90=E8=B6=8B=E5=8A=BF=E6=8E=A5=E5=8F=A3=20-?= =?UTF-8?q?=E5=88=86=E5=88=AB=E8=BF=94=E5=9B=9E=E4=BB=8A=E6=97=A5=E5=92=8C?= =?UTF-8?q?=E6=98=A8=E6=97=A5=E3=80=81=E6=9C=AC=E6=9C=88=E5=92=8C=E4=B8=8A?= =?UTF-8?q?=E6=9C=88=E3=80=81=E4=BB=8A=E5=B9=B4=E5=92=8C=E5=8E=BB=E5=B9=B4?= =?UTF-8?q?=E7=9A=84=E8=B6=8B=E5=8A=BF=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TbMeterRecordServiceImpl.java | 98 ++++++++++++------- 1 file changed, 64 insertions(+), 34 deletions(-) diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterRecordServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterRecordServiceImpl.java index 2c206a81..de1e099e 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterRecordServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterRecordServiceImpl.java @@ -238,50 +238,80 @@ public class TbMeterRecordServiceImpl implements ITbMeterRecordService { public Map getEnergyTrend(String floorId, String meterId, Long meterType, String day, String month, String year) { Map resultMap = new HashMap<>(); - // hour - List> hourList = baseMapper.getHourTrend(StrUtil.isBlank(floorId) ? null : Long.parseLong(floorId), StrUtil.isBlank(meterId) ? null : Long.parseLong(meterId), meterType, day); + String yesterday = DateUtil.format(DateUtil.offsetDay(DateUtil.parse(day), -1), "yyyy-MM-dd"); + // todayHour + Map todayMap = trendHourData(floorId, meterId, meterType, day); + // yesterdayHour + Map yesterdayMap = trendHourData(floorId, meterId, meterType, yesterday); + Map hourMap = new HashMap<>(); - String[] hourCategories = hourList.stream() - .map(map -> map.get("hour").toString()) - .toArray(String[]::new); - BigDecimal[] hourData = hourList.stream() - .map(map -> new BigDecimal(map.get("total_consumption").toString())) - .toArray(BigDecimal[]::new); - hourMap.put("categories", hourCategories); - hourMap.put("data", hourData); - hourMap.put("total" , hourList.stream().map(map -> new BigDecimal(map.get("total_consumption").toString())).reduce(BigDecimal::add).orElse(BigDecimal.ZERO).floatValue()); + hourMap.put("today", todayMap); + hourMap.put("yesterday", yesterdayMap); + - // day String[] monthArr = month.split("-"); - List> dayList = baseMapper.getDayTrend(StrUtil.isBlank(floorId) ? null : Long.parseLong(floorId), StrUtil.isBlank(meterId) ? null : Long.parseLong(meterId), meterType, monthArr[0], monthArr[1]); + String lastMonth = Integer.parseInt(monthArr[1]) - 1 + ""; + // nowMonth + Map nowMonthMap = trendDayData(floorId, meterId, meterType, monthArr[0], monthArr[1]); + // lastMonth + Map lastMonthMap = trendDayData(floorId, meterId, meterType, monthArr[0], lastMonth); + Map dayMap = new HashMap<>(); - String[] dayCategories = dayList.stream() - .map(map -> map.get("day").toString()) - .toArray(String[]::new); - BigDecimal[] dayData = dayList.stream() - .map(map -> new BigDecimal(map.get("total_consumption").toString())) - .toArray(BigDecimal[]::new); - dayMap.put("categories", dayCategories); - dayMap.put("data", dayData); - dayMap.put("total", dayList.stream().map(map -> new BigDecimal(map.get("total_consumption").toString())).reduce(BigDecimal::add).orElse(BigDecimal.ZERO).floatValue()); + dayMap.put("nowMonth", nowMonthMap); + dayMap.put("lastMonth", lastMonthMap); + + String lastYear = Integer.parseInt(year) - 1 + ""; + // nowYear + Map nowYearMap = trendMonthData(floorId, meterId, meterType, year); + // lastYear + Map lastYearMap = trendMonthData(floorId, meterId, meterType, lastYear); - // month - List> monthList = baseMapper.getMonthTrend(StrUtil.isBlank(floorId) ? null : Long.parseLong(floorId), StrUtil.isBlank(meterId) ? null : Long.parseLong(meterId), meterType, year); Map monthMap = new HashMap<>(); - String[] monthCategories = monthList.stream() - .map(map -> map.get("month").toString()) - .toArray(String[]::new); - BigDecimal[] monthData = monthList.stream() - .map(map -> new BigDecimal(map.get("total_consumption").toString())) - .toArray(BigDecimal[]::new); - monthMap.put("categories", monthCategories); - monthMap.put("data", monthData); - monthMap.put("total", monthList.stream().map(map -> new BigDecimal(map.get("total_consumption").toString())).reduce(BigDecimal::add).orElse(BigDecimal.ZERO).floatValue()); - + monthMap.put("nowYear", nowYearMap); + monthMap.put("lastYear", lastYearMap); resultMap.put("hour", hourMap); resultMap.put("day", dayMap); resultMap.put("month", monthMap); return resultMap; } + + private Map trendHourData(String floorId, String meterId, Long meterType, String day) { + Map hourMap = new HashMap<>(); + List> hourList = baseMapper.getHourTrend(StrUtil.isBlank(floorId) ? null : Long.parseLong(floorId), StrUtil.isBlank(meterId) ? null : Long.parseLong(meterId), meterType, day); + List hourData = new ArrayList<>(); + hourList.forEach(item -> { + hourData.add(new String[]{item.get("hour").toString(), item.get("total_consumption").toString()}); + }); + Float total = hourList.stream().map(map -> new BigDecimal(map.get("total_consumption").toString())).reduce(BigDecimal::add).orElse(BigDecimal.ZERO).floatValue(); + hourMap.put("total", total); + hourMap.put("data", hourData); + return hourMap; + } + + private Map trendDayData(String floorId, String meterId, Long meterType, String year, String month) { + Map dayMap = new HashMap<>(); + List> dayList = baseMapper.getDayTrend(StrUtil.isBlank(floorId) ? null : Long.parseLong(floorId), StrUtil.isBlank(meterId) ? null : Long.parseLong(meterId), meterType, year, month); + List dayData = new ArrayList<>(); + dayList.forEach(item -> { + dayData.add(new String[]{item.get("day").toString(), item.get("total_consumption").toString()}); + }); + Float total = dayList.stream().map(map -> new BigDecimal(map.get("total_consumption").toString())).reduce(BigDecimal::add).orElse(BigDecimal.ZERO).floatValue(); + dayMap.put("total", total); + dayMap.put("data", dayData); + return dayMap; + } + + private Map trendMonthData(String floorId, String meterId, Long meterType, String year) { + Map resultMap = new HashMap<>(); + List> monthList = baseMapper.getMonthTrend(StrUtil.isBlank(floorId) ? null : Long.parseLong(floorId), StrUtil.isBlank(meterId) ? null : Long.parseLong(meterId), meterType, year); + List monthData = new ArrayList<>(); + monthList.forEach(item -> { + monthData.add(new String[]{item.get("month").toString(), item.get("total_consumption").toString()}); + }); + Float total = monthList.stream().map(map -> new BigDecimal(map.get("total_consumption").toString())).reduce(BigDecimal::add).orElse(BigDecimal.ZERO).floatValue(); + resultMap.put("total", total); + resultMap.put("data", monthData); + return resultMap; + } } From bad3ffdf4cebc825707ce2d7cde372f75a52c875 Mon Sep 17 00:00:00 2001 From: yuyongle <1150359267@qq.com> Date: Fri, 29 Aug 2025 16:46:22 +0800 Subject: [PATCH 03/20] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86=E4=BF=9D?= =?UTF-8?q?=E6=B4=81=E8=AE=A2=E5=8D=95=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../property/service/impl/ServiceWorkOrdersServiceImpl.java | 1 + .../service/impl/cleanOrderImpl/CleanOrderServiceImpl.java | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java index 623e7b85..624c7617 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java @@ -244,6 +244,7 @@ public class ServiceWorkOrdersServiceImpl implements IServiceWorkOrdersService { new LambdaQueryWrapper() .le(AttendanceUserGroup::getStartDate, today) .ge(AttendanceUserGroup::getEndDate, today) + .eq(AttendanceUserGroup::getDeptId, serviceWorkOrders.getCreateDept()) .orderByAsc(AttendanceUserGroup::getCreateTime) ); Assert.isTrue(CollUtil.isNotEmpty(attendanceUserGroups), "暂无排班人员"); diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/cleanOrderImpl/CleanOrderServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/cleanOrderImpl/CleanOrderServiceImpl.java index 6b7e2831..2a03af34 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/cleanOrderImpl/CleanOrderServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/cleanOrderImpl/CleanOrderServiceImpl.java @@ -118,10 +118,11 @@ public class CleanOrderServiceImpl implements ICleanOrderService { return baseMapper.selectVoList(lqw); } - private LambdaQueryWrapper buildQueryWrapper(CleanOrderBo bo) { + private LambdaQueryWrapperbuildQueryWrapper(CleanOrderBo bo) { Map params = bo.getParams(); LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); - lqw.orderByAsc(CleanOrder::getId); + lqw.orderByDesc(CleanOrder::getCreateTime) + .orderByDesc(CleanOrder::getUpdateTime); // lqw.eq(StringUtils.isNotBlank(bo.getLocation()), CleanOrder::getLocation, bo.getLocation()); // lqw.eq(StringUtils.isNotBlank(bo.getArea()), CleanOrder::getArea, bo.getArea()); From ce0c4b201c69d70b7b7a66c7d355fe1c58209616 Mon Sep 17 00:00:00 2001 From: yuyongle <1150359267@qq.com> Date: Fri, 29 Aug 2025 16:50:21 +0800 Subject: [PATCH 04/20] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E6=B4=BE=E5=8D=95=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../property/service/impl/ServiceWorkOrdersServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java index 624c7617..870b515d 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java @@ -245,7 +245,7 @@ public class ServiceWorkOrdersServiceImpl implements IServiceWorkOrdersService { .le(AttendanceUserGroup::getStartDate, today) .ge(AttendanceUserGroup::getEndDate, today) .eq(AttendanceUserGroup::getDeptId, serviceWorkOrders.getCreateDept()) - .orderByAsc(AttendanceUserGroup::getCreateTime) + .orderByAsc(AttendanceUserGroup::getStartDate) ); Assert.isTrue(CollUtil.isNotEmpty(attendanceUserGroups), "暂无排班人员"); // 缓存当天排班数据(假设当天不会变) From 659f3089e44da110e21ee5fdd1c3dd3bee575cb7 Mon Sep 17 00:00:00 2001 From: yuyongle <1150359267@qq.com> Date: Fri, 29 Aug 2025 17:19:48 +0800 Subject: [PATCH 05/20] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E6=B4=BE=E5=8D=95=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/ServiceWorkOrdersServiceImpl.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java index 870b515d..4acdfb3f 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java @@ -239,14 +239,15 @@ public class ServiceWorkOrdersServiceImpl implements IServiceWorkOrdersService { LocalDate today = LocalDate.now(); // 1. 获取今日排班人员(优先查缓存,未命中则查询数据库并缓存) List attendanceUserGroups = RedisUtils.getCacheList(DateUtil.today()); - if (CollUtil.isEmpty(attendanceUserGroups)) { - attendanceUserGroups = attendanceUserGroupMapper.selectList( - new LambdaQueryWrapper() - .le(AttendanceUserGroup::getStartDate, today) - .ge(AttendanceUserGroup::getEndDate, today) - .eq(AttendanceUserGroup::getDeptId, serviceWorkOrders.getCreateDept()) - .orderByAsc(AttendanceUserGroup::getStartDate) - ); + List attendanceUserGroupList = attendanceUserGroupMapper.selectList( + new LambdaQueryWrapper() + .le(AttendanceUserGroup::getStartDate, today) + .ge(AttendanceUserGroup::getEndDate, today) + .eq(AttendanceUserGroup::getDeptId, serviceWorkOrders.getCreateDept()) + .orderByAsc(AttendanceUserGroup::getStartDate) + ); + if (CollUtil.isEmpty(attendanceUserGroups)|| attendanceUserGroups.size() != attendanceUserGroupList.size()) { + attendanceUserGroups=attendanceUserGroupList; Assert.isTrue(CollUtil.isNotEmpty(attendanceUserGroups), "暂无排班人员"); // 缓存当天排班数据(假设当天不会变) RedisUtils.setCacheList(DateUtil.today(), attendanceUserGroups); From 2200ef48801e6ad6113e8331e2bb6a40d0447769 Mon Sep 17 00:00:00 2001 From: yuyongle <1150359267@qq.com> Date: Fri, 29 Aug 2025 20:16:10 +0800 Subject: [PATCH 06/20] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E6=B4=BE=E5=8D=95=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../property/service/impl/ServiceWorkOrdersServiceImpl.java | 2 +- .../ruoyi-nacos/src/main/resources/application.properties | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java index 4acdfb3f..2d4e25aa 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java @@ -243,7 +243,7 @@ public class ServiceWorkOrdersServiceImpl implements IServiceWorkOrdersService { new LambdaQueryWrapper() .le(AttendanceUserGroup::getStartDate, today) .ge(AttendanceUserGroup::getEndDate, today) - .eq(AttendanceUserGroup::getDeptId, serviceWorkOrders.getCreateDept()) + //.eq(AttendanceUserGroup::getDeptId, serviceWorkOrders.getCreateDept()) .orderByAsc(AttendanceUserGroup::getStartDate) ); if (CollUtil.isEmpty(attendanceUserGroups)|| attendanceUserGroups.size() != attendanceUserGroupList.size()) { diff --git a/ruoyi-visual/ruoyi-nacos/src/main/resources/application.properties b/ruoyi-visual/ruoyi-nacos/src/main/resources/application.properties index ef3ece6a..4385908f 100644 --- a/ruoyi-visual/ruoyi-nacos/src/main/resources/application.properties +++ b/ruoyi-visual/ruoyi-nacos/src/main/resources/application.properties @@ -40,9 +40,9 @@ spring.sql.init.platform=mysql db.num=1 ### Connect URL of DB: -db.url.0=jdbc:mysql://10.20.1.65:3306/ry-config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true +db.url.0=jdbc:mysql://113.249.101.254:18000/ry-config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true db.user.0=root -db.password.0=By@2025! +db.password.0=by@2025?? ### the maximum retry times for push nacos.config.push.maxRetryTime=50 From e2fbd251b3a6fc92c8ce0e1a059bc02ea1f7d32e Mon Sep 17 00:00:00 2001 From: yuyongle <1150359267@qq.com> Date: Fri, 29 Aug 2025 20:19:48 +0800 Subject: [PATCH 07/20] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E6=B4=BE=E5=8D=95=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruoyi-nacos/src/main/resources/application.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruoyi-visual/ruoyi-nacos/src/main/resources/application.properties b/ruoyi-visual/ruoyi-nacos/src/main/resources/application.properties index 4385908f..ef3ece6a 100644 --- a/ruoyi-visual/ruoyi-nacos/src/main/resources/application.properties +++ b/ruoyi-visual/ruoyi-nacos/src/main/resources/application.properties @@ -40,9 +40,9 @@ spring.sql.init.platform=mysql db.num=1 ### Connect URL of DB: -db.url.0=jdbc:mysql://113.249.101.254:18000/ry-config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true +db.url.0=jdbc:mysql://10.20.1.65:3306/ry-config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true db.user.0=root -db.password.0=by@2025?? +db.password.0=By@2025! ### the maximum retry times for push nacos.config.push.maxRetryTime=50 From 826684ed667225819a8fd7e60062c9291bc21a2f Mon Sep 17 00:00:00 2001 From: yuyongle <1150359267@qq.com> Date: Fri, 29 Aug 2025 20:43:58 +0800 Subject: [PATCH 08/20] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E6=B4=BE=E5=8D=95=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dromara/property/domain/ServiceWorkOrdersType.java | 4 ++++ .../property/domain/bo/ServiceWorkOrdersTypeBo.java | 6 +++++- .../property/domain/vo/ServiceWorkOrdersTypeVo.java | 4 ++++ .../service/impl/ServiceWorkOrdersServiceImpl.java | 8 ++++---- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/ServiceWorkOrdersType.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/ServiceWorkOrdersType.java index 118998aa..7dd4c22c 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/ServiceWorkOrdersType.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/ServiceWorkOrdersType.java @@ -41,6 +41,10 @@ public class ServiceWorkOrdersType extends TenantEntity { * 运作模式(0派单+抢单,1派单,2自动派单) */ private String operationMode; + /** + *部门id + */ + private Long deptId; /** * 排序值 diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/ServiceWorkOrdersTypeBo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/ServiceWorkOrdersTypeBo.java index a9a15f6c..5e97ec4b 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/ServiceWorkOrdersTypeBo.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/ServiceWorkOrdersTypeBo.java @@ -36,7 +36,11 @@ public class ServiceWorkOrdersTypeBo extends BaseEntity { */ @NotNull(message = "工单类型名称不能为空", groups = { AddGroup.class, EditGroup.class }) private String orderTypeName; - + /** + *部门id + */ + @NotNull(message = "部门id", groups = { EditGroup.class }) + private Long deptId; /** * 运作模式 */ diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServiceWorkOrdersTypeVo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServiceWorkOrdersTypeVo.java index 9b44e8a4..29d10cfb 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServiceWorkOrdersTypeVo.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServiceWorkOrdersTypeVo.java @@ -44,6 +44,10 @@ public class ServiceWorkOrdersTypeVo implements Serializable { */ @ExcelProperty(value = "工单类型名称") private String orderTypeName; + /** + *部门id + */ + private Long deptId; /** * 运作模式 diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java index 2d4e25aa..fe199976 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java @@ -227,7 +227,7 @@ public class ServiceWorkOrdersServiceImpl implements IServiceWorkOrdersService { boolean flags = workOrdersRecordMapper.insert(serviceWorkOrdersRecord) > 0; if (flags) { if (serviceWorkOrdersType.getOperationMode().equals(OrderTypeOperationEnum.AUTOMATE_DISPATCH.getValue())) { - handleServiceWorkOrder(add); + handleServiceWorkOrder(add,serviceWorkOrdersType); } } } @@ -235,7 +235,7 @@ public class ServiceWorkOrdersServiceImpl implements IServiceWorkOrdersService { } //自动派单 - private void handleServiceWorkOrder(ServiceWorkOrders serviceWorkOrders) { + private void handleServiceWorkOrder(ServiceWorkOrders serviceWorkOrders,ServiceWorkOrdersType serviceWorkOrdersType) { LocalDate today = LocalDate.now(); // 1. 获取今日排班人员(优先查缓存,未命中则查询数据库并缓存) List attendanceUserGroups = RedisUtils.getCacheList(DateUtil.today()); @@ -243,7 +243,7 @@ public class ServiceWorkOrdersServiceImpl implements IServiceWorkOrdersService { new LambdaQueryWrapper() .le(AttendanceUserGroup::getStartDate, today) .ge(AttendanceUserGroup::getEndDate, today) - //.eq(AttendanceUserGroup::getDeptId, serviceWorkOrders.getCreateDept()) + .eq(AttendanceUserGroup::getDeptId, serviceWorkOrdersType.getCreateDept()) .orderByAsc(AttendanceUserGroup::getStartDate) ); if (CollUtil.isEmpty(attendanceUserGroups)|| attendanceUserGroups.size() != attendanceUserGroupList.size()) { @@ -591,7 +591,7 @@ public class ServiceWorkOrdersServiceImpl implements IServiceWorkOrdersService { boolean flags = workOrdersRecordMapper.insert(serviceWorkOrdersRecord) > 0; if (flags) { if (serviceWorkOrdersType.getOperationMode().equals(OrderTypeOperationEnum.AUTOMATE_DISPATCH.getValue())) { - handleServiceWorkOrder(add); + handleServiceWorkOrder(add,serviceWorkOrdersType); } } } From 0b2216964941542c49efb1f7659e0ca2bd5a3aeb Mon Sep 17 00:00:00 2001 From: yuyongle <1150359267@qq.com> Date: Fri, 29 Aug 2025 21:22:59 +0800 Subject: [PATCH 09/20] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E6=B4=BE=E5=8D=95bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/vo/ServiceWorkOrdersTypeVo.java | 4 ++++ .../ServiceWorkOrdersTypeServiceImpl.java | 24 +++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServiceWorkOrdersTypeVo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServiceWorkOrdersTypeVo.java index 29d10cfb..ec128904 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServiceWorkOrdersTypeVo.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServiceWorkOrdersTypeVo.java @@ -48,6 +48,10 @@ public class ServiceWorkOrdersTypeVo implements Serializable { *部门id */ private Long deptId; + /** + *部门名称 + */ + private String deptName; /** * 运作模式 diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersTypeServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersTypeServiceImpl.java index 48912b8b..0e487feb 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersTypeServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersTypeServiceImpl.java @@ -3,6 +3,7 @@ package org.dromara.property.service.impl; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import org.apache.dubbo.config.annotation.DubboReference; import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.StringUtils; @@ -18,6 +19,8 @@ import org.dromara.property.domain.bo.ServiceWorkOrdersTypeBo; import org.dromara.property.domain.vo.ServiceWorkOrdersTypeVo; import org.dromara.property.mapper.ServiceWorkOrdersTypeMapper; import org.dromara.property.service.IServiceWorkOrdersTypeService; +import org.dromara.system.api.RemoteDeptService; +import org.dromara.system.api.domain.vo.RemoteDeptVo; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -39,6 +42,8 @@ public class ServiceWorkOrdersTypeServiceImpl implements IServiceWorkOrdersTypeS private final ServiceWorkOrdersTypeMapper baseMapper; + @DubboReference + private RemoteDeptService remoteDeptService; /** * 查询【工单类型】 * @@ -47,7 +52,11 @@ public class ServiceWorkOrdersTypeServiceImpl implements IServiceWorkOrdersTypeS */ @Override public ServiceWorkOrdersTypeVo queryById(Long id) { - return baseMapper.selectVoById(id); + ServiceWorkOrdersTypeVo serviceWorkOrdersTypeVo= baseMapper.selectVoById(id); + Long deptId = serviceWorkOrdersTypeVo.getDeptId(); + RemoteDeptVo remoteDeptVo = remoteDeptService.selectDeptVoById(deptId); + serviceWorkOrdersTypeVo.setDeptName(remoteDeptVo.getDeptName()); + return serviceWorkOrdersTypeVo; } /** @@ -61,6 +70,11 @@ public class ServiceWorkOrdersTypeServiceImpl implements IServiceWorkOrdersTypeS public TableDataInfo queryPageList(ServiceWorkOrdersTypeBo bo, PageQuery pageQuery) { LambdaQueryWrapper lqw = buildQueryWrapper(bo); Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + result.getRecords().stream().forEach(vo -> { + Long deptId = vo.getDeptId(); + RemoteDeptVo remoteDeptVo = remoteDeptService.selectDeptVoById(deptId); + vo.setDeptName(remoteDeptVo.getDeptName()); + }); return TableDataInfo.build(result); } @@ -73,7 +87,13 @@ public class ServiceWorkOrdersTypeServiceImpl implements IServiceWorkOrdersTypeS @Override public List queryList(ServiceWorkOrdersTypeBo bo) { LambdaQueryWrapper lqw = buildQueryWrapper(bo); - return baseMapper.selectVoList(lqw); + List serviceWorkOrdersTypeVoList= baseMapper.selectVoList(lqw); + serviceWorkOrdersTypeVoList.stream().forEach(vo -> { + Long deptId = vo.getDeptId(); + RemoteDeptVo remoteDeptVo = remoteDeptService.selectDeptVoById(deptId); + vo.setDeptName(remoteDeptVo.getDeptName()); + }); + return serviceWorkOrdersTypeVoList; } private LambdaQueryWrapper buildQueryWrapper(ServiceWorkOrdersTypeBo bo) { From 97a3c106cb9f65e268ab2859f638bb0b02e59c16 Mon Sep 17 00:00:00 2001 From: mocheng <3057647414@qq.com> Date: Sat, 30 Aug 2025 01:13:36 +0800 Subject: [PATCH 10/20] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=8E=92=E7=8F=ADbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../property/service/impl/ServiceWorkOrdersServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java index fe199976..6870bbc0 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java @@ -243,7 +243,7 @@ public class ServiceWorkOrdersServiceImpl implements IServiceWorkOrdersService { new LambdaQueryWrapper() .le(AttendanceUserGroup::getStartDate, today) .ge(AttendanceUserGroup::getEndDate, today) - .eq(AttendanceUserGroup::getDeptId, serviceWorkOrdersType.getCreateDept()) + .eq(AttendanceUserGroup::getDeptId, serviceWorkOrdersType.getDeptId()) .orderByAsc(AttendanceUserGroup::getStartDate) ); if (CollUtil.isEmpty(attendanceUserGroups)|| attendanceUserGroups.size() != attendanceUserGroupList.size()) { From 3c6595e591317c6181408fb6e8957bf2e0766e4e Mon Sep 17 00:00:00 2001 From: 15683799673 Date: Sat, 30 Aug 2025 06:36:27 +0800 Subject: [PATCH 11/20] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E6=8C=87=E6=B4=BE=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../property/api/RemoteAttendanceService.java | 11 ++- .../vo/RemoteAttendanceUserGroupVo.java | 1 - .../dubbo/RemoteAttendanceServiceImpl.java | 11 +++ .../AttendanceUserGroupMapper.java | 14 +++- .../IAttendanceAreaDeviceService.java | 2 + .../IAttendanceUserGroupService.java | 9 +++ .../AttendanceUserGroupServiceImpl.java | 5 ++ .../Property/AttendanceUserGroupMapper.xml | 16 +++++ .../sis/service/ISisAlarmEventsService.java | 3 +- .../service/IZeroSensationPassageService.java | 2 - .../impl/SisAlarmEventsServiceImpl.java | 9 +-- .../impl/ZeroSensationPassageServiceImpl.java | 71 ++++++++++++++++--- .../resource/controller/SysOssController.java | 27 ++++--- .../resource/service/ISysOssService.java | 1 + .../service/impl/SysOssServiceImpl.java | 1 - 15 files changed, 150 insertions(+), 33 deletions(-) diff --git a/ruoyi-api/property-api/src/main/java/org/dromara/property/api/RemoteAttendanceService.java b/ruoyi-api/property-api/src/main/java/org/dromara/property/api/RemoteAttendanceService.java index 94e6e2a8..fb1a0bbe 100644 --- a/ruoyi-api/property-api/src/main/java/org/dromara/property/api/RemoteAttendanceService.java +++ b/ruoyi-api/property-api/src/main/java/org/dromara/property/api/RemoteAttendanceService.java @@ -18,6 +18,15 @@ public interface RemoteAttendanceService { * @param date 查询时间 * @return 返回排班人员信息 */ - public List queryAttendPersonInfo(Date date); + List queryAttendPersonInfo(Date date); + + /** + * 根据时间和设备ip查询当前设备所处区域的排班人员信息 + * + * @param date 查询时间 + * @param deviceIp 设备ip + * @return 返回排班人员信息 + */ + List queryAttendByCurrDateAndDeviceIp(Date date, String deviceIp); } diff --git a/ruoyi-api/property-api/src/main/java/org/dromara/property/api/domain/vo/RemoteAttendanceUserGroupVo.java b/ruoyi-api/property-api/src/main/java/org/dromara/property/api/domain/vo/RemoteAttendanceUserGroupVo.java index 1146533a..1916b5d1 100644 --- a/ruoyi-api/property-api/src/main/java/org/dromara/property/api/domain/vo/RemoteAttendanceUserGroupVo.java +++ b/ruoyi-api/property-api/src/main/java/org/dromara/property/api/domain/vo/RemoteAttendanceUserGroupVo.java @@ -49,5 +49,4 @@ public class RemoteAttendanceUserGroupVo implements Serializable { */ private LocalDate endDate; - } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/dubbo/RemoteAttendanceServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/dubbo/RemoteAttendanceServiceImpl.java index 0acb754b..060749d7 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/dubbo/RemoteAttendanceServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/dubbo/RemoteAttendanceServiceImpl.java @@ -6,7 +6,9 @@ import lombok.RequiredArgsConstructor; import org.apache.dubbo.config.annotation.DubboService; import org.dromara.property.api.RemoteAttendanceService; import org.dromara.property.api.domain.vo.RemoteAttendanceUserGroupVo; +import org.dromara.property.domain.vo.attendanceVo.AttendanceAreaDeviceVo; import org.dromara.property.domain.vo.attendanceVo.AttendanceUserGroupVo; +import org.dromara.property.service.attendanceService.IAttendanceAreaDeviceService; import org.dromara.property.service.attendanceService.IAttendanceUserGroupService; import java.util.Date; @@ -23,6 +25,7 @@ public class RemoteAttendanceServiceImpl implements RemoteAttendanceService { private final IAttendanceUserGroupService attendanceUserGroupService; + private final IAttendanceAreaDeviceService attendanceAreaDeviceService; public List queryAttendPersonInfo(Date date) { @@ -33,4 +36,12 @@ public class RemoteAttendanceServiceImpl implements RemoteAttendanceService { return null; } + @Override + public List queryAttendByCurrDateAndDeviceIp(Date date, String deviceIp) { + List ls = attendanceUserGroupService.queryAttendByCurrDateAndDeviceIp(date, deviceIp); + if (CollUtil.isNotEmpty(ls)) { + return BeanUtil.copyToList(ls, RemoteAttendanceUserGroupVo.class); + } + return null; + } } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/mapper/attendanceMapper/AttendanceUserGroupMapper.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/mapper/attendanceMapper/AttendanceUserGroupMapper.java index 209320db..69076ad5 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/mapper/attendanceMapper/AttendanceUserGroupMapper.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/mapper/attendanceMapper/AttendanceUserGroupMapper.java @@ -1,8 +1,12 @@ package org.dromara.property.mapper.attendanceMapper; +import org.apache.ibatis.annotations.Param; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; import org.dromara.property.domain.AttendanceUserGroup; import org.dromara.property.domain.vo.attendanceVo.AttendanceUserGroupVo; -import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; + +import java.util.Date; +import java.util.List; /** * 排班明细Mapper接口 @@ -12,4 +16,12 @@ import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; */ public interface AttendanceUserGroupMapper extends BaseMapperPlus { + /** + * 根据日期和设备ip 查询当前设备所在区域的排班人员信息 + * + * @param date 查询日期 + * @param deviceIp 设备ip + * @return 返回排班人员列表 + */ + List queryAttendByCurrDateAndDeviceIp(@Param("currDate") Date currDate, @Param("deviceIp") String deviceIp); } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/attendanceService/IAttendanceAreaDeviceService.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/attendanceService/IAttendanceAreaDeviceService.java index e230c275..0889ce12 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/attendanceService/IAttendanceAreaDeviceService.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/attendanceService/IAttendanceAreaDeviceService.java @@ -6,6 +6,7 @@ import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.PageQuery; import java.util.Collection; +import java.util.Date; import java.util.List; /** @@ -65,4 +66,5 @@ public interface IAttendanceAreaDeviceService { * @return 是否删除成功 */ Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/attendanceService/IAttendanceUserGroupService.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/attendanceService/IAttendanceUserGroupService.java index b3855ffa..c32e340b 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/attendanceService/IAttendanceUserGroupService.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/attendanceService/IAttendanceUserGroupService.java @@ -75,6 +75,15 @@ public interface IAttendanceUserGroupService { */ List queryAttendPersonInfo(Date date); + TableDataInfo queryScheduleView(AttendanceUserGroupBo bo, PageQuery pageQuery); + /** + * 根据日期和设备ip 查询当前设备所在区域的排班人员信息 + * + * @param date 查询日期 + * @param deviceIp 设备ip + * @return 返回排班人员列表 + */ + List queryAttendByCurrDateAndDeviceIp(Date date, String deviceIp); } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/attendanceImpl/AttendanceUserGroupServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/attendanceImpl/AttendanceUserGroupServiceImpl.java index 8221157f..6dd3a696 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/attendanceImpl/AttendanceUserGroupServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/attendanceImpl/AttendanceUserGroupServiceImpl.java @@ -299,4 +299,9 @@ public class AttendanceUserGroupServiceImpl implements IAttendanceUserGroupServi return TableDataInfo.build(attendanceArrangementVoPage); } + + @Override + public List queryAttendByCurrDateAndDeviceIp(Date date, String deviceIp) { + return this.baseMapper.queryAttendByCurrDateAndDeviceIp(date, deviceIp); + } } diff --git a/ruoyi-modules/Property/src/main/resources/mapper/Property/AttendanceUserGroupMapper.xml b/ruoyi-modules/Property/src/main/resources/mapper/Property/AttendanceUserGroupMapper.xml index b38100ed..dd6edb9b 100644 --- a/ruoyi-modules/Property/src/main/resources/mapper/Property/AttendanceUserGroupMapper.xml +++ b/ruoyi-modules/Property/src/main/resources/mapper/Property/AttendanceUserGroupMapper.xml @@ -4,4 +4,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> + diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/ISisAlarmEventsService.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/ISisAlarmEventsService.java index f65b1a29..cda3143d 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/ISisAlarmEventsService.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/ISisAlarmEventsService.java @@ -2,6 +2,7 @@ package org.dromara.sis.service; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.sis.domain.SisAlarmEvents; import org.dromara.sis.domain.bo.SisAlarmEventsBo; import org.dromara.sis.domain.bo.alarm.AlarmAssignmentBo; import org.dromara.sis.domain.bo.alarm.AlarmCompleteBo; @@ -79,7 +80,7 @@ public interface ISisAlarmEventsService { /** * 异步生成告警记录 */ - void createAlarmRecord(String deviceIp, Integer level, EventSmallTypeEnum type, String msg, byte[] smallImg, byte[] bigImg); + SisAlarmEvents createAlarmRecord(String deviceIp, Integer level, EventSmallTypeEnum type, String msg, byte[] smallImg, byte[] bigImg); /** * 任务分配操作 diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/IZeroSensationPassageService.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/IZeroSensationPassageService.java index d5c5e353..6d8788a8 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/IZeroSensationPassageService.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/IZeroSensationPassageService.java @@ -1,7 +1,5 @@ package org.dromara.sis.service; -import cn.hutool.core.date.TimeInterval; - public interface IZeroSensationPassageService { /** diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisAlarmEventsServiceImpl.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisAlarmEventsServiceImpl.java index efe5de5b..221113ae 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisAlarmEventsServiceImpl.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisAlarmEventsServiceImpl.java @@ -37,7 +37,6 @@ import org.dromara.sis.service.ISisAlarmEventProcessService; import org.dromara.sis.service.ISisAlarmEventsService; import org.dromara.sis.service.ISisDeviceManageService; import org.dromara.system.api.model.LoginUser; -import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -179,15 +178,14 @@ public class SisAlarmEventsServiceImpl implements ISisAlarmEventsService { return baseMapper.deleteByIds(ids) > 0; } - @Async @Override @Transactional(rollbackFor = Exception.class) - public void createAlarmRecord(String deviceIp, Integer level, EventSmallTypeEnum type, String msg, byte[] smallImg, byte[] bigImg) { + public SisAlarmEvents createAlarmRecord(String deviceIp, Integer level, EventSmallTypeEnum type, String msg, byte[] smallImg, byte[] bigImg) { // 校验设备信息 SisDeviceManage sisDeviceManage = deviceManageService.queryByDeviceIp(deviceIp); if (sisDeviceManage == null) { log.error("设备信息不存在,放弃此条告警记录。"); - return; + return null; } // 生成时间信息 Date now = new Date(); @@ -223,7 +221,6 @@ public class SisAlarmEventsServiceImpl implements ISisAlarmEventsService { alarmEventProcess.setReceiveTaskTag(0L); alarmEventProcess.setTenantId(""); - // 写入附件表 List ls = new ArrayList<>(); if (smallImg != null && smallImg.length > 0) { @@ -234,7 +231,7 @@ public class SisAlarmEventsServiceImpl implements ISisAlarmEventsService { } Boolean flag = alarmEventAttachmentsService.batchInsert(ls); log.info("写入告警事件附件表完成, reslut={}, size={}", flag, ls.size()); - + return alarmEvents; } public SisAlarmEventAttachments createEventAttachments(byte[] img, SisAlarmEvents alarmEvents, SisDeviceManage sisDeviceManage) { diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/ZeroSensationPassageServiceImpl.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/ZeroSensationPassageServiceImpl.java index 5eb7e30f..6cf5e377 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/ZeroSensationPassageServiceImpl.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/ZeroSensationPassageServiceImpl.java @@ -9,8 +9,12 @@ import cn.hutool.core.util.ObjectUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.dubbo.config.annotation.DubboReference; +import org.dromara.property.api.RemoteAttendanceService; import org.dromara.property.api.RemoteFloorService; +import org.dromara.property.api.domain.vo.RemoteAttendanceUserGroupVo; import org.dromara.property.api.domain.vo.RemoteFloorVo; +import org.dromara.sis.domain.SisAlarmEvents; +import org.dromara.sis.domain.bo.alarm.AlarmAssignmentBo; import org.dromara.sis.domain.enums.ControlTypeEnum; import org.dromara.sis.domain.enums.EventSmallTypeEnum; import org.dromara.sis.domain.enums.RosterTypeEnum; @@ -22,12 +26,12 @@ import org.dromara.sis.sdk.huawei.HuaWeiBoxApi; import org.dromara.sis.sdk.huawei.domain.HWResult; import org.dromara.sis.sdk.smartDevices.utils.ElevatorControlTcpUtil; import org.dromara.sis.service.*; +import org.dromara.system.api.RemoteUserService; +import org.dromara.system.api.domain.vo.RemoteUserVo; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Objects; +import java.util.*; /** * 无感通行业务服务实现 @@ -54,8 +58,13 @@ public class ZeroSensationPassageServiceImpl implements IZeroSensationPassageSer @DubboReference private RemoteFloorService remoteFloorService; + @DubboReference + private RemoteAttendanceService remoteAttendanceService; + @DubboReference + private RemoteUserService remoteUserService; @Override + @Async public void pass(String deviceIp, byte[] smallImg, byte[] bigImg) { TimeInterval interval = new TimeInterval(); // 抓拍小图 @@ -64,7 +73,7 @@ public class ZeroSensationPassageServiceImpl implements IZeroSensationPassageSer if (result.getCode() != 200) { log.info("华为盒子比对失败,msg={}", result.getMessage()); // 产生告警数据 人脸比对失败,默认为 - alarmEventsService.createAlarmRecord(deviceIp, 2, EventSmallTypeEnum.SMART_REPORT_ZJCR, "人脸比对失败", smallImg, bigImg); + handleAlarm(deviceIp, smallImg, bigImg, 2, EventSmallTypeEnum.SMART_REPORT_ZJCR, "人脸比对失败"); return; } log.info("人脸比对执行完成,耗时:{}ms", interval.intervalMs()); @@ -75,20 +84,20 @@ public class ZeroSensationPassageServiceImpl implements IZeroSensationPassageSer if (authRecord == null) { log.info("人员[{}]没有授权记录,判定为陌生人", person); // 不是内部人员 产生紧急的告警信息 - alarmEventsService.createAlarmRecord(deviceIp, 2, EventSmallTypeEnum.SMART_REPORT_ZJCR, "陌生人员入内", smallImg, bigImg); + handleAlarm(deviceIp, smallImg, bigImg, 2, EventSmallTypeEnum.SMART_REPORT_ZJCR, "陌生人员入内"); return; } else { if (Objects.equals(authRecord.getRosterType(), RosterTypeEnum.BLACK_LIST.getCode())) { - log.info("人员[{}]在黑名单中,暂不处理。", person); - alarmEventsService.createAlarmRecord(deviceIp, 3, EventSmallTypeEnum.BLACK_PERSON, "黑名单人员入内", smallImg, bigImg); + log.info("黑名单人员[{}]。", person); + handleAlarm(deviceIp, smallImg, bigImg, 3, EventSmallTypeEnum.BLACK_PERSON, "黑名单人员"); return; } } Date now = new Date(); if (DateUtil.compare(now, authRecord.getEndDate()) > 0) { - alarmEventsService.createAlarmRecord(deviceIp, 1, EventSmallTypeEnum.AUTHORIZATION_EXPIRED, "人员授权信息已过期", smallImg, bigImg); - log.info("当前人脸已过期,暂不处理。"); + handleAlarm(deviceIp, smallImg, bigImg, 1, EventSmallTypeEnum.AUTHORIZATION_EXPIRED, "人员授权信息已过期"); + log.info("当前人脸已过期。person={}", person); return; } // 获取当前设备的绑定设备信息 @@ -128,6 +137,48 @@ public class ZeroSensationPassageServiceImpl implements IZeroSensationPassageSer log.info("权限下发执行完成,耗时:{}ms", interval.intervalMs()); } + /** + * 处理告警信息 + * + * @param deviceIp 设备ip + * @param smallImg 人脸小图 + * @param bigImg 人脸大图 + * @param smallType 事件类型 + */ + private void handleAlarm(String deviceIp, byte[] smallImg, byte[] bigImg, Integer level, EventSmallTypeEnum smallType, String desc) { + // 生成告警记录 + SisAlarmEvents alarmRecord = alarmEventsService.createAlarmRecord(deviceIp, level, smallType, desc, smallImg, bigImg); + SaTokenContextMockUtil.setMockContext(() -> { + // 如果当前设备区域存在排班人员,那么惊醒自动指派操作 + List userGroupVos = remoteAttendanceService.queryAttendByCurrDateAndDeviceIp(new Date(), deviceIp); + if (CollUtil.isEmpty(userGroupVos)) { + return; + } + // 进行自动指派操作 + RemoteAttendanceUserGroupVo currHandlePerson = null; + if (userGroupVos.size() == 1) { + currHandlePerson = userGroupVos.get(0); + } else { + // 生成一个排班人员课表的随机数 + Random random = new Random(); + int randomIndex = random.nextInt(userGroupVos.size()); + currHandlePerson = userGroupVos.get(randomIndex); + } + // 获取当前指派人员的详细信息 + RemoteUserVo userInfo = remoteUserService.getUserInfoById(currHandlePerson.getEmployeeId()); + // 任务指派操作 + AlarmAssignmentBo bo = new AlarmAssignmentBo(); + bo.setAlarmId(alarmRecord.getId()); + bo.setSolveId(userInfo.getUserId()); + bo.setSolveName(userInfo.getUserName()); + bo.setSolvePhone(userInfo.getPhonenumber()); + bo.setSolveEmail(userInfo.getEmail()); + bo.setRemark("系统自动指派"); + alarmEventsService.taskAssignment(bo); + }); + } + + /** * 电梯外部按键触发 * diff --git a/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/controller/SysOssController.java b/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/controller/SysOssController.java index 1a0beb8c..f02c6bc5 100644 --- a/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/controller/SysOssController.java +++ b/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/controller/SysOssController.java @@ -3,20 +3,18 @@ package org.dromara.resource.controller; import cn.dev33.satoken.annotation.SaCheckPermission; import cn.hutool.core.util.ObjectUtil; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.NotEmpty; import lombok.RequiredArgsConstructor; import org.apache.dubbo.config.annotation.DubboReference; -import org.apache.dubbo.config.annotation.DubboService; -import org.dromara.common.core.constant.GlobalConstants; import org.dromara.common.core.domain.R; import org.dromara.common.core.validate.QueryGroup; -import org.dromara.common.redis.utils.RedisUtils; -import org.dromara.common.web.core.BaseController; import org.dromara.common.log.annotation.Log; import org.dromara.common.log.enums.BusinessType; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.web.core.BaseController; import org.dromara.property.api.RemoteVisitoreGetCodeInfoService; -import org.dromara.resource.domain.QrCodeInfo; import org.dromara.resource.domain.bo.SysOssBo; import org.dromara.resource.domain.vo.SysOssUploadVo; import org.dromara.resource.domain.vo.SysOssVo; @@ -26,8 +24,6 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; -import jakarta.servlet.http.HttpServletResponse; -import jakarta.validation.constraints.NotEmpty; import java.io.IOException; import java.util.Arrays; import java.util.List; @@ -46,6 +42,7 @@ public class SysOssController extends BaseController { private final ISysOssService iSysOssService; @DubboReference private RemoteVisitoreGetCodeInfoService remoteVisitoreGetCodeInfoService; + /** * 查询OSS对象存储列表 */ @@ -96,17 +93,17 @@ public class SysOssController extends BaseController { // @SaCheckPermission("system:oss:upload") @Log(title = "OSS对象存储", businessType = BusinessType.INSERT) @PostMapping(value = "/qrupload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) - public R codeUpload(@RequestPart("file") MultipartFile file,String code) { + public R codeUpload(@RequestPart("file") MultipartFile file, String code) { if (ObjectUtil.isNull(file)) { return R.fail("上传文件不能为空"); } String codeInfo = remoteVisitoreGetCodeInfoService.getCodeInfo(code); // QrCodeInfo info = RedisUtils.getCacheObject(GlobalConstants.CAPTCHA_CODE_KEY+"Qrcode" + code); - if (codeInfo.isEmpty()){ + if (codeInfo.isEmpty()) { return R.fail("二维码已过期"); } - SysOssVo oss = iSysOssService.qrupload(file,codeInfo); + SysOssVo oss = iSysOssService.qrupload(file, codeInfo); SysOssUploadVo uploadVo = new SysOssUploadVo(); uploadVo.setUrl(oss.getUrl()); uploadVo.setFileName(oss.getOriginalName()); @@ -125,6 +122,16 @@ public class SysOssController extends BaseController { iSysOssService.download(ossId, response); } + /** + * 输出图片到浏览器 + * + * @param ossId OSS对象ID + */ + @GetMapping(value = "/preview/{ossId}", produces = {MediaType.IMAGE_JPEG_VALUE, MediaType.IMAGE_PNG_VALUE}) + public byte [] preview(@PathVariable Long ossId) throws IOException { + return iSysOssService.downloadToByteArray(ossId); + } + /** * 删除OSS对象存储 * diff --git a/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/service/ISysOssService.java b/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/service/ISysOssService.java index 1b2a2b9c..f0957feb 100644 --- a/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/service/ISysOssService.java +++ b/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/service/ISysOssService.java @@ -109,4 +109,5 @@ public interface ISysOssService { * @return byte[] 返回下载的字节数组 */ byte[] downloadToByteArray(Long ossId) throws IOException; + } diff --git a/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/service/impl/SysOssServiceImpl.java b/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/service/impl/SysOssServiceImpl.java index 48ab3a39..dc8359bc 100644 --- a/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/service/impl/SysOssServiceImpl.java +++ b/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/service/impl/SysOssServiceImpl.java @@ -306,5 +306,4 @@ public class SysOssServiceImpl implements ISysOssService { } return oss; } - } From 10033dd646a365feff7f2ed0d39d34d71105b7c4 Mon Sep 17 00:00:00 2001 From: zcxlsm Date: Sat, 30 Aug 2025 21:03:26 +0800 Subject: [PATCH 12/20] =?UTF-8?q?feat(Property):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=B0=B4/=E7=94=B5/=E6=B0=94=E8=A1=A8=E5=BD=93=E5=89=8D?= =?UTF-8?q?=E8=AF=BB=E6=95=B0=E5=92=8C=E7=8A=B6=E6=80=81=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TbMeterInfoController.java | 8 ++ .../TbMeterInfoServiceImpl.java | 37 +++++++- .../TbMeterRecordServiceImpl.java | 12 +-- .../ITbMeterInfoService.java | 7 +- .../property/utils/MeterRecordUtil.java | 86 +++++++++++++++++++ 5 files changed, 138 insertions(+), 12 deletions(-) create mode 100644 ruoyi-modules/Property/src/main/java/org/dromara/property/utils/MeterRecordUtil.java diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/smartDevicesController/TbMeterInfoController.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/smartDevicesController/TbMeterInfoController.java index df9b6d17..e3f4de13 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/smartDevicesController/TbMeterInfoController.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/smartDevicesController/TbMeterInfoController.java @@ -117,4 +117,12 @@ public class TbMeterInfoController extends BaseController { return R.ok(tbMeterInfoService.queryMeterInfoTree(meterType)); } + /** + * 获取水/电/气表当前读数 + */ + @GetMapping("/currentReading/{floorId}") + public R currentReading(@PathVariable("floorId") Long floorId) { + return R.ok(); + } + } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterInfoServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterInfoServiceImpl.java index a5a71bec..cefb768b 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterInfoServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterInfoServiceImpl.java @@ -12,15 +12,15 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.property.domain.bo.TbFloorBo; import org.dromara.property.domain.vo.TbBuildingVo; import org.dromara.property.domain.vo.TbCommunityVo; import org.dromara.property.domain.vo.TbFloorVo; +import org.dromara.property.rocketmq.domain.MeterResult; import org.dromara.property.service.ITbBuildingService; import org.dromara.property.service.ITbCommunityService; import org.dromara.property.service.ITbFloorService; -import org.dromara.system.api.model.LoginUser; +import org.dromara.property.utils.MeterRecordUtil; import org.springframework.stereotype.Service; import org.dromara.property.domain.bo.smartDevicesBo.TbMeterInfoBo; import org.dromara.property.domain.vo.smartDevicesVo.TbMeterInfoVo; @@ -29,6 +29,7 @@ import org.dromara.property.mapper.smartDevicesMapper.TbMeterInfoMapper; import org.dromara.property.service.smartDevicesService.ITbMeterInfoService; import org.springframework.transaction.annotation.Transactional; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -51,6 +52,8 @@ public class TbMeterInfoServiceImpl implements ITbMeterInfoService { private final ITbBuildingService buildingService; private final ITbCommunityService communityService; + private final MeterRecordUtil meterRecordUtil; + /** * 查询水电气 * @@ -239,4 +242,34 @@ public class TbMeterInfoServiceImpl implements ITbMeterInfoService { } return TreeUtils.build(treeList, 0L); } + + /** + * 获取水/电/气表当前读数/状态 + */ + @Override + public List getMeterStatus(Long floorId) { + TbMeterInfoBo meterInfoBo = new TbMeterInfoBo(); + meterInfoBo.setFloorId(floorId); + List meterInfoVoList = this.queryList(meterInfoBo); + if (meterInfoVoList.isEmpty()) return null; + + String[] hostIpArr = meterInfoVoList.stream().map(TbMeterInfoVo::getHostIp).toArray(String[]::new); + Map ipCountMap = meterInfoVoList.stream().collect(Collectors.groupingBy(TbMeterInfoVo::getHostIp, Collectors.counting())); + List meterResults = meterRecordUtil.getMeterStatus(ipCountMap, hostIpArr); + + List resultList = new ArrayList<>(); + for (MeterResult item : meterResults){ + TbMeterInfoVo meterInfoVo = meterInfoVoList.stream().filter(o -> o.getHostIp().equals(item.getIp())).findFirst().orElse(null); + if (meterInfoVo == null) continue; + + BigDecimal initReading = BigDecimal.valueOf(item.getCollectionValue().get(Integer.parseInt(meterInfoVo.getMeterCode()))); + if (initReading.equals(BigDecimal.ZERO)){ + meterInfoVo.setCommunicationState(0L); + } + meterInfoVo.setInitReading(initReading); + resultList.add(meterInfoVo); + } + + return resultList; + } } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterRecordServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterRecordServiceImpl.java index de1e099e..bf6a03b9 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterRecordServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterRecordServiceImpl.java @@ -280,9 +280,7 @@ public class TbMeterRecordServiceImpl implements ITbMeterRecordService { Map hourMap = new HashMap<>(); List> hourList = baseMapper.getHourTrend(StrUtil.isBlank(floorId) ? null : Long.parseLong(floorId), StrUtil.isBlank(meterId) ? null : Long.parseLong(meterId), meterType, day); List hourData = new ArrayList<>(); - hourList.forEach(item -> { - hourData.add(new String[]{item.get("hour").toString(), item.get("total_consumption").toString()}); - }); + hourList.forEach(item -> hourData.add(new String[]{item.get("hour").toString(), item.get("total_consumption").toString()})); Float total = hourList.stream().map(map -> new BigDecimal(map.get("total_consumption").toString())).reduce(BigDecimal::add).orElse(BigDecimal.ZERO).floatValue(); hourMap.put("total", total); hourMap.put("data", hourData); @@ -293,9 +291,7 @@ public class TbMeterRecordServiceImpl implements ITbMeterRecordService { Map dayMap = new HashMap<>(); List> dayList = baseMapper.getDayTrend(StrUtil.isBlank(floorId) ? null : Long.parseLong(floorId), StrUtil.isBlank(meterId) ? null : Long.parseLong(meterId), meterType, year, month); List dayData = new ArrayList<>(); - dayList.forEach(item -> { - dayData.add(new String[]{item.get("day").toString(), item.get("total_consumption").toString()}); - }); + dayList.forEach(item -> dayData.add(new String[]{item.get("day").toString(), item.get("total_consumption").toString()})); Float total = dayList.stream().map(map -> new BigDecimal(map.get("total_consumption").toString())).reduce(BigDecimal::add).orElse(BigDecimal.ZERO).floatValue(); dayMap.put("total", total); dayMap.put("data", dayData); @@ -306,9 +302,7 @@ public class TbMeterRecordServiceImpl implements ITbMeterRecordService { Map resultMap = new HashMap<>(); List> monthList = baseMapper.getMonthTrend(StrUtil.isBlank(floorId) ? null : Long.parseLong(floorId), StrUtil.isBlank(meterId) ? null : Long.parseLong(meterId), meterType, year); List monthData = new ArrayList<>(); - monthList.forEach(item -> { - monthData.add(new String[]{item.get("month").toString(), item.get("total_consumption").toString()}); - }); + monthList.forEach(item -> monthData.add(new String[]{item.get("month").toString(), item.get("total_consumption").toString()})); Float total = monthList.stream().map(map -> new BigDecimal(map.get("total_consumption").toString())).reduce(BigDecimal::add).orElse(BigDecimal.ZERO).floatValue(); resultMap.put("total", total); resultMap.put("data", monthData); diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/smartDevicesService/ITbMeterInfoService.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/smartDevicesService/ITbMeterInfoService.java index 7695b8f2..f3ca6e17 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/smartDevicesService/ITbMeterInfoService.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/smartDevicesService/ITbMeterInfoService.java @@ -13,7 +13,7 @@ import java.util.List; * 水电气Service接口 * * @author lsm - * @date 2025-07-19 + * @since 2025-07-19 */ public interface ITbMeterInfoService { @@ -75,4 +75,9 @@ public interface ITbMeterInfoService { * @return 水电气树结构 */ List> queryMeterInfoTree(Long meterType); + + /** + * 获取水/电/气表当前读数/状态 + */ + List getMeterStatus(Long floorId); } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/utils/MeterRecordUtil.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/utils/MeterRecordUtil.java new file mode 100644 index 00000000..82e7f2f3 --- /dev/null +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/utils/MeterRecordUtil.java @@ -0,0 +1,86 @@ +package org.dromara.property.utils; + +import cn.hutool.core.lang.TypeReference; +import cn.hutool.http.HttpUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.dromara.property.rocketmq.domain.MeterResult; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Map; + +/** + * @author lsm + * @apiNote MeterRecordUtil + * @since 2025/8/30 + */ +@Slf4j +@Component +public class MeterRecordUtil { + + @Value("${eqp.config.meter.host}") + private String meterRecordUrl; + + private static final String READING_URL = "reading"; + + @Data + public static class Result { + private Integer code; + private T data; + } + + /** + * 发起请求并解析响应结果 + * + * @param uri 请求路径 + * @param params 请求参数 + * @param 泛型类型 + * @return 解析后的数据对象 + */ + public T request(String uri, String params) { + // 参数校验 + if (uri == null || uri.isEmpty()) { + log.warn("请求URI不能为空"); + return null; + } + + String url = meterRecordUrl + uri; + log.info("发起请求 - URL: {}, 参数: {}", url, params); + + try { + // 发起POST请求 + String post = HttpUtil.post(url, params); + log.debug("接收到响应: {}", post); + + // 解析JSON响应 + Result result = JSONUtil.toBean(post, new TypeReference<>() { + }, true); + + // 判断响应是否成功 + if (result != null && result.getCode() == 200) { + return result.getData(); + } else { + log.warn("请求失败,状态码: {}", result != null ? result.getCode() : "未知"); + } + } catch (Exception e) { + log.error("请求处理异常 - URL: {}, 参数: {}", url, params, e); + } + + return null; + } + + /** + * 获取水/电/气表当前读数 + */ + public List getMeterStatus(Map ipMap, String[] ipArr) { + JSONObject jsonObject = new JSONObject(); + jsonObject.putOnce("ipMap", ipMap); + jsonObject.putOnce("ipArr", ipArr); + return request(READING_URL, jsonObject.toString()); + } + +} From 28f44a1c5ff7d8673c46c2f70e750b1677d7479d Mon Sep 17 00:00:00 2001 From: zcxlsm Date: Sat, 30 Aug 2025 21:14:04 +0800 Subject: [PATCH 13/20] feat(Property): 1 --- .../smartDevicesController/TbMeterInfoController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/smartDevicesController/TbMeterInfoController.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/smartDevicesController/TbMeterInfoController.java index e3f4de13..3a3874b4 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/smartDevicesController/TbMeterInfoController.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/smartDevicesController/TbMeterInfoController.java @@ -121,8 +121,8 @@ public class TbMeterInfoController extends BaseController { * 获取水/电/气表当前读数 */ @GetMapping("/currentReading/{floorId}") - public R currentReading(@PathVariable("floorId") Long floorId) { - return R.ok(); + public R> currentReading(@PathVariable("floorId") Long floorId) { + return R.ok(tbMeterInfoService.getMeterStatus(floorId)); } } From b1f0ce3d3c42dd003551bb1716c930af73b6e9e0 Mon Sep 17 00:00:00 2001 From: zcxlsm Date: Sat, 30 Aug 2025 22:42:12 +0800 Subject: [PATCH 14/20] =?UTF-8?q?refactor(Property):=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E4=BB=AA=E8=A1=A8=E4=BF=A1=E6=81=AF=E8=8E=B7=E5=8F=96=E5=92=8C?= =?UTF-8?q?=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TbMeterInfoServiceImpl.java | 51 ++++++++++--------- .../property/utils/MeterRecordUtil.java | 44 ++-------------- 2 files changed, 30 insertions(+), 65 deletions(-) diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterInfoServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterInfoServiceImpl.java index cefb768b..0ec6ff16 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterInfoServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterInfoServiceImpl.java @@ -30,10 +30,8 @@ import org.dromara.property.service.smartDevicesService.ITbMeterInfoService; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Collection; +import java.math.RoundingMode; +import java.util.*; import java.util.stream.Collectors; /** @@ -109,16 +107,17 @@ public class TbMeterInfoServiceImpl implements ITbMeterInfoService { LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); lqw.orderByAsc(TbMeterInfo::getId); lqw.like(StringUtils.isNotBlank(bo.getHostIp()), TbMeterInfo::getHostIp, bo.getHostIp()); - lqw.like(StringUtils.isNotBlank(bo.getMeterName()), TbMeterInfo::getMeterName, bo.getMeterName()); lqw.eq(StringUtils.isNotBlank(bo.getMeterCode()), TbMeterInfo::getMeterCode, bo.getMeterCode()); lqw.eq(StringUtils.isNotBlank(bo.getFactoryNo()), TbMeterInfo::getFactoryNo, bo.getFactoryNo()); + lqw.like(StringUtils.isNotBlank(bo.getMeterName()), TbMeterInfo::getMeterName, bo.getMeterName()); + lqw.eq(StringUtils.isNotBlank(bo.getInstallLocation()), TbMeterInfo::getInstallLocation, bo.getInstallLocation()); + lqw.eq(bo.getFloorId() != null, TbMeterInfo::getFloorId, bo.getFloorId()); + lqw.eq(bo.getMaxRang() != null, TbMeterInfo::getMaxRang, bo.getMaxRang()); lqw.eq(bo.getMeterType() != null, TbMeterInfo::getMeterType, bo.getMeterType()); lqw.eq(bo.getMeterUnit() != null, TbMeterInfo::getMeterUnit, bo.getMeterUnit()); - lqw.eq(StringUtils.isNotBlank(bo.getInstallLocation()), TbMeterInfo::getInstallLocation, bo.getInstallLocation()); lqw.eq(bo.getInitReading() != null, TbMeterInfo::getInitReading, bo.getInitReading()); - lqw.eq(bo.getMaxRang() != null, TbMeterInfo::getMaxRang, bo.getMaxRang()); - lqw.eq(bo.getCommunicationState() != null, TbMeterInfo::getCommunicationState, bo.getCommunicationState()); lqw.eq(bo.getRunningState() != null, TbMeterInfo::getRunningState, bo.getRunningState()); + lqw.eq(bo.getCommunicationState() != null, TbMeterInfo::getCommunicationState, bo.getCommunicationState()); return lqw; } @@ -253,23 +252,27 @@ public class TbMeterInfoServiceImpl implements ITbMeterInfoService { List meterInfoVoList = this.queryList(meterInfoBo); if (meterInfoVoList.isEmpty()) return null; - String[] hostIpArr = meterInfoVoList.stream().map(TbMeterInfoVo::getHostIp).toArray(String[]::new); - Map ipCountMap = meterInfoVoList.stream().collect(Collectors.groupingBy(TbMeterInfoVo::getHostIp, Collectors.counting())); - List meterResults = meterRecordUtil.getMeterStatus(ipCountMap, hostIpArr); - - List resultList = new ArrayList<>(); - for (MeterResult item : meterResults){ - TbMeterInfoVo meterInfoVo = meterInfoVoList.stream().filter(o -> o.getHostIp().equals(item.getIp())).findFirst().orElse(null); - if (meterInfoVo == null) continue; - - BigDecimal initReading = BigDecimal.valueOf(item.getCollectionValue().get(Integer.parseInt(meterInfoVo.getMeterCode()))); - if (initReading.equals(BigDecimal.ZERO)){ - meterInfoVo.setCommunicationState(0L); - } - meterInfoVo.setInitReading(initReading); - resultList.add(meterInfoVo); + String[] hostIpArr = meterInfoVoList.stream().map(TbMeterInfoVo::getHostIp).distinct().toArray(String[]::new); + Map ipCountMap = new HashMap<>(); + for (String ip : hostIpArr) { + ipCountMap.put(ip, baseMapper.selectCount(new LambdaQueryWrapper().eq(TbMeterInfo::getHostIp, ip))); } + List meterResults = meterRecordUtil.getMeterStatus(ipCountMap, hostIpArr); + log.info("获取仪表状态结果={}", meterResults); - return resultList; + for (TbMeterInfoVo item : meterInfoVoList) { + MeterResult meterResult = meterResults.stream().filter(o -> o.getIp().equals(item.getHostIp())).findFirst().orElse(null); + if (meterResult == null) continue; + + BigDecimal initReading = BigDecimal.valueOf(meterResult.getCollectionValue().get(Integer.parseInt(item.getMeterCode()))) + .setScale(2, RoundingMode.HALF_UP); + if (initReading.equals(BigDecimal.ZERO)) { + item.setCommunicationState(0L); + } else { + item.setCommunicationState(1L); + } + item.setInitReading(initReading); + } + return meterInfoVoList; } } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/utils/MeterRecordUtil.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/utils/MeterRecordUtil.java index 82e7f2f3..bfec4d8e 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/utils/MeterRecordUtil.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/utils/MeterRecordUtil.java @@ -33,46 +33,6 @@ public class MeterRecordUtil { private T data; } - /** - * 发起请求并解析响应结果 - * - * @param uri 请求路径 - * @param params 请求参数 - * @param 泛型类型 - * @return 解析后的数据对象 - */ - public T request(String uri, String params) { - // 参数校验 - if (uri == null || uri.isEmpty()) { - log.warn("请求URI不能为空"); - return null; - } - - String url = meterRecordUrl + uri; - log.info("发起请求 - URL: {}, 参数: {}", url, params); - - try { - // 发起POST请求 - String post = HttpUtil.post(url, params); - log.debug("接收到响应: {}", post); - - // 解析JSON响应 - Result result = JSONUtil.toBean(post, new TypeReference<>() { - }, true); - - // 判断响应是否成功 - if (result != null && result.getCode() == 200) { - return result.getData(); - } else { - log.warn("请求失败,状态码: {}", result != null ? result.getCode() : "未知"); - } - } catch (Exception e) { - log.error("请求处理异常 - URL: {}, 参数: {}", url, params, e); - } - - return null; - } - /** * 获取水/电/气表当前读数 */ @@ -80,7 +40,9 @@ public class MeterRecordUtil { JSONObject jsonObject = new JSONObject(); jsonObject.putOnce("ipMap", ipMap); jsonObject.putOnce("ipArr", ipArr); - return request(READING_URL, jsonObject.toString()); + String post = HttpUtil.post(meterRecordUrl + READING_URL, jsonObject.toString()); + Result> result = JSONUtil.toBean(post, new TypeReference>>() {}, true); + return result.getData(); } } From f9544ad4e1b157adf0939b4a89cc1c842b3517a8 Mon Sep 17 00:00:00 2001 From: zcxlsm Date: Sun, 31 Aug 2025 12:44:04 +0800 Subject: [PATCH 15/20] =?UTF-8?q?feat(property):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E6=B0=B4=E7=94=B5=E6=B0=94=E8=A1=A8=E6=A0=91=E7=BB=93=E6=9E=84?= =?UTF-8?q?=E5=92=8C=E7=8A=B6=E6=80=81=E8=8E=B7=E5=8F=96=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=20-=20=E5=9C=A8=20queryMeterInfoTree=20=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E4=B8=AD=E6=B7=BB=E5=8A=A0=20isMeter=20=E5=8F=82=E6=95=B0?= =?UTF-8?q?=EF=BC=8C=E7=94=A8=E4=BA=8E=E6=8E=A7=E5=88=B6=E6=98=AF=E5=90=A6?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E4=BB=AA=E8=A1=A8=E4=BF=A1=E6=81=AF=20-=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=20getMeterStatus=20=E6=96=B9=E6=B3=95?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=8A=A0=20meterType=20=E5=8F=82=E6=95=B0?= =?UTF-8?q?=EF=BC=8C=E7=94=A8=E4=BA=8E=E6=8C=87=E5=AE=9A=E6=B0=B4=E7=94=B5?= =?UTF-8?q?=E6=B0=94=E7=B1=BB=E5=9E=8B=20-=20=E4=BC=98=E5=8C=96=20TbMeterI?= =?UTF-8?q?nfoController=20=E4=B8=AD=E7=9A=84=E8=B7=AF=E7=94=B1=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=EF=BC=8C=E4=BD=BF=E7=94=A8=20query=20=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E6=9B=BF=E4=BB=A3=E8=B7=AF=E5=BE=84=E5=8F=82=E6=95=B0?= =?UTF-8?q?-=20=E5=9C=A8=E8=8E=B7=E5=8F=96=E4=BB=AA=E8=A1=A8=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E6=97=B6=E5=A2=9E=E5=8A=A0=E5=BC=82=E5=B8=B8=E5=A4=84?= =?UTF-8?q?=E7=90=86=EF=BC=8C=E7=A1=AE=E4=BF=9D=E6=95=B0=E6=8D=AE=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E5=A4=B1=E8=B4=A5=E6=97=B6=E8=83=BD=E5=A4=9F=E8=BF=94?= =?UTF-8?q?=E5=9B=9E=E6=89=80=E6=9C=89=E6=95=B0=E6=8D=AE=E5=B9=B6=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E9=80=9A=E4=BF=A1=E7=8A=B6=E6=80=81=E4=B8=BA=200=20-?= =?UTF-8?q?=20=E5=9C=A8=20HttpUtil.post=20=E6=96=B9=E6=B3=95=E4=B8=AD?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=B6=85=E6=97=B6=E8=AE=BE=E7=BD=AE=EF=BC=8C?= =?UTF-8?q?=E6=8F=90=E9=AB=98=E8=AF=B7=E6=B1=82=E7=A8=B3=E5=AE=9A=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TbMeterInfoController.java | 23 +++++---- .../TbMeterInfoServiceImpl.java | 49 ++++++++++++------- .../ITbMeterInfoService.java | 9 ++-- .../property/utils/MeterRecordUtil.java | 2 +- 4 files changed, 52 insertions(+), 31 deletions(-) diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/smartDevicesController/TbMeterInfoController.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/smartDevicesController/TbMeterInfoController.java index 3a3874b4..203a4850 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/smartDevicesController/TbMeterInfoController.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/smartDevicesController/TbMeterInfoController.java @@ -28,7 +28,7 @@ import org.dromara.common.mybatis.core.page.TableDataInfo; * 前端访问路由地址为:/property/meterInfo * * @author lsm - * @date 2025-07-19 + * @since 2025-07-19 */ @Validated @RequiredArgsConstructor @@ -66,7 +66,7 @@ public class TbMeterInfoController extends BaseController { @SaCheckPermission("property:meterInfo:query") @GetMapping("/{id}") public R getInfo(@NotNull(message = "主键不能为空") - @PathVariable("id") Long id) { + @PathVariable("id") Long id) { return R.ok(tbMeterInfoService.queryById(id)); } @@ -109,20 +109,23 @@ public class TbMeterInfoController extends BaseController { * 生成 社区/建组/单元/楼栋/(水电气表)树结构 * * @param meterType 水电气类型 - * + * @param isMeter 是否返回仪表 * @return (水电气表)树结构 */ - @GetMapping("/tree/{meterType}") - public R>> queryMeterInfoTree(@PathVariable("meterType") Long meterType) { - return R.ok(tbMeterInfoService.queryMeterInfoTree(meterType)); + @GetMapping("/tree") + public R>> queryMeterInfoTree(@RequestParam Long meterType, @RequestParam Boolean isMeter) { + return R.ok(tbMeterInfoService.queryMeterInfoTree(meterType, isMeter)); } /** - * 获取水/电/气表当前读数 + * 获取水/电/气表当前读数/状态 + * + * @param meterType 水电气类型 + * @param floorId 楼栋id */ - @GetMapping("/currentReading/{floorId}") - public R> currentReading(@PathVariable("floorId") Long floorId) { - return R.ok(tbMeterInfoService.getMeterStatus(floorId)); + @GetMapping("/currentReading") + public R> currentReading(@RequestParam Long meterType, @RequestParam Long floorId) { + return R.ok(tbMeterInfoService.getMeterStatus(meterType, floorId)); } } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterInfoServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterInfoServiceImpl.java index 0ec6ff16..a5651461 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterInfoServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterInfoServiceImpl.java @@ -179,10 +179,11 @@ public class TbMeterInfoServiceImpl implements ITbMeterInfoService { * 查询水电气树结构 * * @param meterType 水电气类型 + * @param isMeter 是否返回仪表 * @return 水电气树结构 */ @Override - public List> queryMeterInfoTree(Long meterType) { + public List> queryMeterInfoTree(Long meterType, Boolean isMeter) { // 默认加载社区树 List> treeList = new ArrayList<>(); List tbCommunityVos = communityService.queryAll(); @@ -225,30 +226,36 @@ public class TbMeterInfoServiceImpl implements ITbMeterInfoService { }).toList(); treeList.addAll(l3); - TbMeterInfoBo bo = new TbMeterInfoBo(); - bo.setMeterType(meterType); - List meterInfoVos = this.queryList(bo); - if (meterInfoVos != null && !meterInfoVos.isEmpty()) { - List> l4 = meterInfoVos.stream().map(item -> { - TreeNode node = new TreeNode<>(); - node.setLevel(4); - node.setCode(item.getId()); - node.setParentCode(item.getFloorId()); - node.setLabel(item.getMeterName()); - return node; - }).toList(); - treeList.addAll(l4); + if (isMeter){ + TbMeterInfoBo bo = new TbMeterInfoBo(); + bo.setMeterType(meterType); + List meterInfoVos = this.queryList(bo); + if (meterInfoVos != null && !meterInfoVos.isEmpty()) { + List> l4 = meterInfoVos.stream().map(item -> { + TreeNode node = new TreeNode<>(); + node.setLevel(4); + node.setCode(item.getId()); + node.setParentCode(item.getFloorId()); + node.setLabel(item.getMeterName()); + return node; + }).toList(); + treeList.addAll(l4); + } } return TreeUtils.build(treeList, 0L); } /** * 获取水/电/气表当前读数/状态 + * + * @param meterType 水电气类型 + * @param floorId 楼栋id */ @Override - public List getMeterStatus(Long floorId) { + public List getMeterStatus(Long meterType, Long floorId) { TbMeterInfoBo meterInfoBo = new TbMeterInfoBo(); meterInfoBo.setFloorId(floorId); + meterInfoBo.setMeterType(meterType); List meterInfoVoList = this.queryList(meterInfoBo); if (meterInfoVoList.isEmpty()) return null; @@ -257,8 +264,16 @@ public class TbMeterInfoServiceImpl implements ITbMeterInfoService { for (String ip : hostIpArr) { ipCountMap.put(ip, baseMapper.selectCount(new LambdaQueryWrapper().eq(TbMeterInfo::getHostIp, ip))); } - List meterResults = meterRecordUtil.getMeterStatus(ipCountMap, hostIpArr); - log.info("获取仪表状态结果={}", meterResults); + List meterResults; + try{ + meterResults = meterRecordUtil.getMeterStatus(ipCountMap, hostIpArr); + } catch (Exception e) { + // 获取数据失败,返回所有数据,设置通信状态为0 + for (TbMeterInfoVo item : meterInfoVoList) { + item.setCommunicationState(0L); + } + return meterInfoVoList; + } for (TbMeterInfoVo item : meterInfoVoList) { MeterResult meterResult = meterResults.stream().filter(o -> o.getIp().equals(item.getHostIp())).findFirst().orElse(null); diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/smartDevicesService/ITbMeterInfoService.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/smartDevicesService/ITbMeterInfoService.java index f3ca6e17..d71fb417 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/smartDevicesService/ITbMeterInfoService.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/smartDevicesService/ITbMeterInfoService.java @@ -71,13 +71,16 @@ public interface ITbMeterInfoService { * 查询水电气树结构 * * @param meterType 水电气类型 - * + * @param isMeter 是否返回仪表 * @return 水电气树结构 */ - List> queryMeterInfoTree(Long meterType); + List> queryMeterInfoTree(Long meterType, Boolean isMeter); /** * 获取水/电/气表当前读数/状态 + * + * @param meterType 水电气类型 + * @param floorId 楼栋id */ - List getMeterStatus(Long floorId); + List getMeterStatus(Long meterType, Long floorId); } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/utils/MeterRecordUtil.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/utils/MeterRecordUtil.java index bfec4d8e..aec441d0 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/utils/MeterRecordUtil.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/utils/MeterRecordUtil.java @@ -40,7 +40,7 @@ public class MeterRecordUtil { JSONObject jsonObject = new JSONObject(); jsonObject.putOnce("ipMap", ipMap); jsonObject.putOnce("ipArr", ipArr); - String post = HttpUtil.post(meterRecordUrl + READING_URL, jsonObject.toString()); + String post = HttpUtil.post(meterRecordUrl + READING_URL, jsonObject.toString(), 3000); Result> result = JSONUtil.toBean(post, new TypeReference>>() {}, true); return result.getData(); } From 4890e9c8e3cd8c4661c85f3d32a63738c173ba75 Mon Sep 17 00:00:00 2001 From: zcxlsm Date: Sun, 31 Aug 2025 14:12:45 +0800 Subject: [PATCH 16/20] refactor(property): 1 --- .../service/impl/smartDevicesImpl/TbMeterInfoServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterInfoServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterInfoServiceImpl.java index a5651461..697bc188 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterInfoServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterInfoServiceImpl.java @@ -281,7 +281,7 @@ public class TbMeterInfoServiceImpl implements ITbMeterInfoService { BigDecimal initReading = BigDecimal.valueOf(meterResult.getCollectionValue().get(Integer.parseInt(item.getMeterCode()))) .setScale(2, RoundingMode.HALF_UP); - if (initReading.equals(BigDecimal.ZERO)) { + if (initReading.compareTo(BigDecimal.ZERO) == 0) { item.setCommunicationState(0L); } else { item.setCommunicationState(1L); From d29c9013529994eee58ce1bddc26e7608dc7f81e Mon Sep 17 00:00:00 2001 From: 15683799673 Date: Sun, 31 Aug 2025 19:11:26 +0800 Subject: [PATCH 17/20] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=BA=E5=91=98?= =?UTF-8?q?=E8=81=9A=E9=9B=86=E6=8A=A5=E8=AD=A6=EF=BC=8C=E9=9D=9E=E6=B3=95?= =?UTF-8?q?=E5=81=9C=E8=BD=A6=E6=8A=A5=E8=AD=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sis/domain/enums/EventSmallTypeEnum.java | 1 + .../sis/rocketmq/RocketMqConstants.java | 5 +- .../consumer/HighDensityConsumer.java | 44 ++++++++++++++++ .../consumer/ParkingDelayConsumer.java | 43 ++++++++++++++++ .../sis/rocketmq/domain/HighDensity.java | 38 ++++++++++++++ .../sis/rocketmq/domain/ParkingReport.java | 28 ++++++++++ .../sis/service/IEventAlarmReportService.java | 26 ++++++++++ .../sis/service/ISisAlarmEventsService.java | 2 +- .../impl/EventAlarmReportServiceImpl.java | 51 +++++++++++++++++++ .../impl/SisAlarmEventsServiceImpl.java | 9 ++-- .../impl/ZeroSensationPassageServiceImpl.java | 5 +- 11 files changed, 243 insertions(+), 9 deletions(-) create mode 100644 ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/consumer/HighDensityConsumer.java create mode 100644 ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/consumer/ParkingDelayConsumer.java create mode 100644 ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/domain/HighDensity.java create mode 100644 ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/domain/ParkingReport.java create mode 100644 ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/IEventAlarmReportService.java create mode 100644 ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/EventAlarmReportServiceImpl.java diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/enums/EventSmallTypeEnum.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/enums/EventSmallTypeEnum.java index ee4720b0..8e794cf3 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/enums/EventSmallTypeEnum.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/enums/EventSmallTypeEnum.java @@ -37,6 +37,7 @@ public enum EventSmallTypeEnum { EQP_REPORT_SBSB(1025, "报警设备上报"), BLACK_PERSON(1026, "黑名单人员"), AUTHORIZATION_EXPIRED(1027, "门禁授权已过期"), + ILLEGAL_PARKING(1028,"非法停车"), /* -----------------------系统报警相关-------------------------------------*/ SYS_REPORT_WLGZ(2001, "网络连接故障"), SYS_REPORT_DLYC(2002, "用户登录异常"), diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/RocketMqConstants.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/RocketMqConstants.java index 1cfafe7a..d4f0306d 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/RocketMqConstants.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/RocketMqConstants.java @@ -20,5 +20,8 @@ public interface RocketMqConstants { String FACECAPTURE = "FACE_CAPTURE_REPORT"; // 人脸比对 String FACECOMPARE = "FACE_COMPARE_REPORT"; - + // 人员聚集上报 + String HIGH_DENSITY = "HIGH_DENSITY_REPORT"; + // 停车上报 + String PARKING_ALARM = "PARKING_ALARM_REPORT"; } diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/consumer/HighDensityConsumer.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/consumer/HighDensityConsumer.java new file mode 100644 index 00000000..ea75098f --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/consumer/HighDensityConsumer.java @@ -0,0 +1,44 @@ +package org.dromara.sis.rocketmq.consumer; + +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.rocketmq.common.message.MessageExt; +import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; +import org.apache.rocketmq.spring.core.RocketMQListener; +import org.dromara.sis.rocketmq.RocketMqConstants; +import org.dromara.sis.rocketmq.domain.FaceCapture; +import org.dromara.sis.rocketmq.domain.HighDensity; +import org.dromara.sis.service.IZeroSensationPassageService; +import org.springframework.stereotype.Component; + +/** + * 人员聚集消费者 + * + * @author lxj + */ + +@Slf4j +@Component +@RequiredArgsConstructor +@RocketMQMessageListener( + topic = RocketMqConstants.TOPIC, + consumerGroup = RocketMqConstants.CAPTUREGROUP, + selectorExpression = RocketMqConstants.HIGH_DENSITY +) +public class HighDensityConsumer implements RocketMQListener { + + private final IZeroSensationPassageService zeroSensationPassageService; + + @Override + public void onMessage(MessageExt ext) { + log.info("消费人员聚集数据,数据长度={}", ext.getBody().length); + try { + HighDensity f = JSONObject.parseObject(ext.getBody(), HighDensity.class); + + } catch (Exception e) { + log.error("消费人脸抓拍数据处理失败,", e); + } + + } +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/consumer/ParkingDelayConsumer.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/consumer/ParkingDelayConsumer.java new file mode 100644 index 00000000..2d56261d --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/consumer/ParkingDelayConsumer.java @@ -0,0 +1,43 @@ +package org.dromara.sis.rocketmq.consumer; + +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.rocketmq.common.message.MessageExt; +import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; +import org.apache.rocketmq.spring.core.RocketMQListener; +import org.dromara.sis.rocketmq.RocketMqConstants; +import org.dromara.sis.rocketmq.domain.ParkingReport; +import org.dromara.sis.service.IZeroSensationPassageService; +import org.springframework.stereotype.Component; + +/** + * 人员聚集消费者 + * + * @author lxj + */ + +@Slf4j +@Component +@RequiredArgsConstructor +@RocketMQMessageListener( + topic = RocketMqConstants.TOPIC, + consumerGroup = RocketMqConstants.CAPTUREGROUP, + selectorExpression = RocketMqConstants.HIGH_DENSITY +) +public class ParkingDelayConsumer implements RocketMQListener { + + private final IZeroSensationPassageService zeroSensationPassageService; + + @Override + public void onMessage(MessageExt ext) { + log.info("消费停车检测数据,数据长度={}", ext.getBody().length); + try { + ParkingReport report = JSONObject.parseObject(ext.getBody(), ParkingReport.class); + + } catch (Exception e) { + log.error("消费人脸抓拍数据处理失败,", e); + } + + } +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/domain/HighDensity.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/domain/HighDensity.java new file mode 100644 index 00000000..14a5f119 --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/domain/HighDensity.java @@ -0,0 +1,38 @@ +package org.dromara.sis.rocketmq.domain; + +import lombok.Data; + +/** + * 人员聚集报警 + * + * @author lxj + */ +@Data +public class HighDensity { + + /** + * 报警图片 + */ + private byte[] img; + + /** + * 设备ip + */ + private String deviceIp; + + /** + * 人员密度0.1-1.0 + */ + private Double density; + + /** + * 灵敏度参数,取值范围:[1,5] + */ + private Byte sensitivity; + + /** + * 触发人员聚集参数报警阈值,20~360s + */ + private Integer wDuration; + +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/domain/ParkingReport.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/domain/ParkingReport.java new file mode 100644 index 00000000..3930c7c3 --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/domain/ParkingReport.java @@ -0,0 +1,28 @@ +package org.dromara.sis.rocketmq.domain; + + +import lombok.Data; + +/** + * 区域停车报警 + * @author lxj + */ +@Data +public class ParkingReport { + + /** + * 报警图片 + */ + private byte[] img; + + /** + * 设备ip + */ + private String deviceIp; + + /** + * 触发人员聚集参数报警阈值,20~360s + */ + private Integer pDuration; + +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/IEventAlarmReportService.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/IEventAlarmReportService.java new file mode 100644 index 00000000..d203fe02 --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/IEventAlarmReportService.java @@ -0,0 +1,26 @@ +package org.dromara.sis.service; + +import org.dromara.sis.rocketmq.domain.HighDensity; +import org.dromara.sis.rocketmq.domain.ParkingReport; + +/** + * 事件告警上报处理服务 + * + * @author lxj + */ +public interface IEventAlarmReportService { + + /** + * 处理停车滞留上报 + * + * @param report 上报信息 + */ + void handleParking(ParkingReport report); + + /** + * 处理人员聚集事件上报 + * + * @param density 上报信息 + */ + void handleHighDensity(HighDensity density); +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/ISisAlarmEventsService.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/ISisAlarmEventsService.java index cda3143d..ec33a236 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/ISisAlarmEventsService.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/ISisAlarmEventsService.java @@ -80,7 +80,7 @@ public interface ISisAlarmEventsService { /** * 异步生成告警记录 */ - SisAlarmEvents createAlarmRecord(String deviceIp, Integer level, EventSmallTypeEnum type, String msg, byte[] smallImg, byte[] bigImg); + SisAlarmEvents createAlarmRecord(String deviceIp, Integer level, EventSmallTypeEnum type, String msg, List imgs); /** * 任务分配操作 diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/EventAlarmReportServiceImpl.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/EventAlarmReportServiceImpl.java new file mode 100644 index 00000000..e3b78a8a --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/EventAlarmReportServiceImpl.java @@ -0,0 +1,51 @@ +package org.dromara.sis.service.impl; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.dromara.sis.domain.SisAlarmEvents; +import org.dromara.sis.domain.enums.EventSmallTypeEnum; +import org.dromara.sis.rocketmq.domain.HighDensity; +import org.dromara.sis.rocketmq.domain.ParkingReport; +import org.dromara.sis.service.IEventAlarmReportService; +import org.dromara.sis.service.ISisAlarmEventsService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 处理设备告警上报服务 + * + * @author lxj + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class EventAlarmReportServiceImpl implements IEventAlarmReportService { + + private final ISisAlarmEventsService alarmEventsService; + + @Override + public void handleParking(ParkingReport report) { + handleAlarm(report.getDeviceIp(), report.getImg(), 2, EventSmallTypeEnum.ILLEGAL_PARKING, "非法停车报警"); + } + + @Override + public void handleHighDensity(HighDensity density) { + handleAlarm(density.getDeviceIp(), density.getImg(), 2, EventSmallTypeEnum.SMART_REPORT_RYJJ, "人员聚集报警"); + } + + /** + * 处理告警信息 + * + * @param deviceIp 设备ip + * @param img 图片 + * @param smallType 事件类型 + */ + private void handleAlarm(String deviceIp, byte[] img, Integer level, EventSmallTypeEnum smallType, String desc) { + // 生成告警记录 + SisAlarmEvents alarmRecord = alarmEventsService.createAlarmRecord(deviceIp, level, smallType, desc, List.of(img)); + } + + +} + diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisAlarmEventsServiceImpl.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisAlarmEventsServiceImpl.java index 221113ae..109f0c20 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisAlarmEventsServiceImpl.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisAlarmEventsServiceImpl.java @@ -180,7 +180,7 @@ public class SisAlarmEventsServiceImpl implements ISisAlarmEventsService { @Override @Transactional(rollbackFor = Exception.class) - public SisAlarmEvents createAlarmRecord(String deviceIp, Integer level, EventSmallTypeEnum type, String msg, byte[] smallImg, byte[] bigImg) { + public SisAlarmEvents createAlarmRecord(String deviceIp, Integer level, EventSmallTypeEnum type, String msg, List imgs) { // 校验设备信息 SisDeviceManage sisDeviceManage = deviceManageService.queryByDeviceIp(deviceIp); if (sisDeviceManage == null) { @@ -223,11 +223,8 @@ public class SisAlarmEventsServiceImpl implements ISisAlarmEventsService { // 写入附件表 List ls = new ArrayList<>(); - if (smallImg != null && smallImg.length > 0) { - ls.add(createEventAttachments(smallImg, alarmEvents, sisDeviceManage)); - } - if (bigImg != null && bigImg.length > 0) { - ls.add(createEventAttachments(bigImg, alarmEvents, sisDeviceManage)); + for (byte[] img : imgs) { + ls.add(createEventAttachments(img, alarmEvents, sisDeviceManage)); } Boolean flag = alarmEventAttachmentsService.batchInsert(ls); log.info("写入告警事件附件表完成, reslut={}, size={}", flag, ls.size()); diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/ZeroSensationPassageServiceImpl.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/ZeroSensationPassageServiceImpl.java index 6cf5e377..5fe6f2a5 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/ZeroSensationPassageServiceImpl.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/ZeroSensationPassageServiceImpl.java @@ -146,8 +146,11 @@ public class ZeroSensationPassageServiceImpl implements IZeroSensationPassageSer * @param smallType 事件类型 */ private void handleAlarm(String deviceIp, byte[] smallImg, byte[] bigImg, Integer level, EventSmallTypeEnum smallType, String desc) { + List ls = new ArrayList<>(2); + ls.add(smallImg); + ls.add(bigImg); // 生成告警记录 - SisAlarmEvents alarmRecord = alarmEventsService.createAlarmRecord(deviceIp, level, smallType, desc, smallImg, bigImg); + SisAlarmEvents alarmRecord = alarmEventsService.createAlarmRecord(deviceIp, level, smallType, desc, ls); SaTokenContextMockUtil.setMockContext(() -> { // 如果当前设备区域存在排班人员,那么惊醒自动指派操作 List userGroupVos = remoteAttendanceService.queryAttendByCurrDateAndDeviceIp(new Date(), deviceIp); From 046e9d925a12fe3ac06ff892a81ad4efce1093aa Mon Sep 17 00:00:00 2001 From: 15683799673 Date: Sun, 31 Aug 2025 22:40:48 +0800 Subject: [PATCH 18/20] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=BA=E5=91=98?= =?UTF-8?q?=E8=81=9A=E9=9B=86=EF=BC=8C=E5=81=9C=E8=BD=A6=E6=B6=88=E8=B4=B9?= =?UTF-8?q?=E8=80=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/dromara/sis/rocketmq/RocketMqConstants.java | 5 +++++ .../sis/rocketmq/consumer/HighDensityConsumer.java | 8 ++++---- .../sis/rocketmq/consumer/ParkingDelayConsumer.java | 10 +++++----- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/RocketMqConstants.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/RocketMqConstants.java index d4f0306d..8d055e38 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/RocketMqConstants.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/RocketMqConstants.java @@ -9,10 +9,15 @@ public interface RocketMqConstants { // mq topic String TOPIC = "SmartParks"; + /*-----------------------------------消息group------------------------------------*/ // 人比比对消费者组 String COMPAREGROUP = "SmartParks-compare"; // 人脸抓拍消费者组 String CAPTUREGROUP = "SmartParks-capture"; + // 人员聚集消费组 + String HIGH_DENSITY_GROUP = "SmartParks-highDensity"; + // 停车消费组 + String PARKING_GROUP = "SmartParks-parking"; /*-----------------------------------消息tag------------------------------------*/ String HIKADD = "ADD_HIK_DEVICE_TAG"; diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/consumer/HighDensityConsumer.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/consumer/HighDensityConsumer.java index ea75098f..677f876a 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/consumer/HighDensityConsumer.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/consumer/HighDensityConsumer.java @@ -7,8 +7,8 @@ import org.apache.rocketmq.common.message.MessageExt; import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; import org.apache.rocketmq.spring.core.RocketMQListener; import org.dromara.sis.rocketmq.RocketMqConstants; -import org.dromara.sis.rocketmq.domain.FaceCapture; import org.dromara.sis.rocketmq.domain.HighDensity; +import org.dromara.sis.service.IEventAlarmReportService; import org.dromara.sis.service.IZeroSensationPassageService; import org.springframework.stereotype.Component; @@ -23,19 +23,19 @@ import org.springframework.stereotype.Component; @RequiredArgsConstructor @RocketMQMessageListener( topic = RocketMqConstants.TOPIC, - consumerGroup = RocketMqConstants.CAPTUREGROUP, + consumerGroup = RocketMqConstants.HIGH_DENSITY, selectorExpression = RocketMqConstants.HIGH_DENSITY ) public class HighDensityConsumer implements RocketMQListener { - private final IZeroSensationPassageService zeroSensationPassageService; + private final IEventAlarmReportService eventAlarmReportService; @Override public void onMessage(MessageExt ext) { log.info("消费人员聚集数据,数据长度={}", ext.getBody().length); try { HighDensity f = JSONObject.parseObject(ext.getBody(), HighDensity.class); - + eventAlarmReportService.handleHighDensity(f); } catch (Exception e) { log.error("消费人脸抓拍数据处理失败,", e); } diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/consumer/ParkingDelayConsumer.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/consumer/ParkingDelayConsumer.java index 2d56261d..718a505a 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/consumer/ParkingDelayConsumer.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/consumer/ParkingDelayConsumer.java @@ -8,7 +8,7 @@ import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; import org.apache.rocketmq.spring.core.RocketMQListener; import org.dromara.sis.rocketmq.RocketMqConstants; import org.dromara.sis.rocketmq.domain.ParkingReport; -import org.dromara.sis.service.IZeroSensationPassageService; +import org.dromara.sis.service.IEventAlarmReportService; import org.springframework.stereotype.Component; /** @@ -22,19 +22,19 @@ import org.springframework.stereotype.Component; @RequiredArgsConstructor @RocketMQMessageListener( topic = RocketMqConstants.TOPIC, - consumerGroup = RocketMqConstants.CAPTUREGROUP, - selectorExpression = RocketMqConstants.HIGH_DENSITY + consumerGroup = RocketMqConstants.PARKING_GROUP, + selectorExpression = RocketMqConstants.PARKING_ALARM ) public class ParkingDelayConsumer implements RocketMQListener { - private final IZeroSensationPassageService zeroSensationPassageService; + private final IEventAlarmReportService eventAlarmReportService; @Override public void onMessage(MessageExt ext) { log.info("消费停车检测数据,数据长度={}", ext.getBody().length); try { ParkingReport report = JSONObject.parseObject(ext.getBody(), ParkingReport.class); - + eventAlarmReportService.handleParking(report); } catch (Exception e) { log.error("消费人脸抓拍数据处理失败,", e); } From bb4ac2bcb87b72d0e4911626dae30e2741b77de2 Mon Sep 17 00:00:00 2001 From: lxj <15683799673@163.com> Date: Mon, 1 Sep 2025 17:18:50 +0800 Subject: [PATCH 19/20] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=BA=E5=91=98?= =?UTF-8?q?=E8=81=9A=E9=9B=86=EF=BC=8C=E9=9D=9E=E6=B3=95=E5=81=9C=E8=BD=A6?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E6=8C=87=E6=B4=BE=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../consumer/FaceCaptureConsumer.java | 6 +- .../sis/service/IEventAlarmReportService.java | 10 + .../service/IZeroSensationPassageService.java | 21 -- .../impl/EventAlarmReportServiceImpl.java | 240 +++++++++++++- .../impl/ZeroSensationPassageServiceImpl.java | 296 ------------------ 5 files changed, 250 insertions(+), 323 deletions(-) delete mode 100644 ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/IZeroSensationPassageService.java delete mode 100644 ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/ZeroSensationPassageServiceImpl.java diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/consumer/FaceCaptureConsumer.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/consumer/FaceCaptureConsumer.java index 6e25325c..0cd0c935 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/consumer/FaceCaptureConsumer.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/rocketmq/consumer/FaceCaptureConsumer.java @@ -8,7 +8,7 @@ import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; import org.apache.rocketmq.spring.core.RocketMQListener; import org.dromara.sis.rocketmq.RocketMqConstants; import org.dromara.sis.rocketmq.domain.FaceCapture; -import org.dromara.sis.service.IZeroSensationPassageService; +import org.dromara.sis.service.IEventAlarmReportService; import org.springframework.stereotype.Component; /** @@ -27,14 +27,14 @@ import org.springframework.stereotype.Component; ) public class FaceCaptureConsumer implements RocketMQListener { - private final IZeroSensationPassageService zeroSensationPassageService; + private final IEventAlarmReportService eventAlarmReportService; @Override public void onMessage(MessageExt ext) { log.info("消费人脸抓拍数据,数据长度={}", ext.getBody().length); try { FaceCapture capture = JSONObject.parseObject(ext.getBody(), FaceCapture.class); - zeroSensationPassageService.pass(capture.getDeviceIp(), capture.getSmallImg(), capture.getBigImg()); + eventAlarmReportService.handleCaptureImg(capture.getDeviceIp(), capture.getSmallImg(), capture.getBigImg()); } catch (Exception e) { log.error("消费人脸抓拍数据处理失败,", e); } diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/IEventAlarmReportService.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/IEventAlarmReportService.java index d203fe02..27185929 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/IEventAlarmReportService.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/IEventAlarmReportService.java @@ -23,4 +23,14 @@ public interface IEventAlarmReportService { * @param density 上报信息 */ void handleHighDensity(HighDensity density); + + /** + * 处理人像抓拍 + * + * @param deviceIp 设备ip + * @param smallImg 小图 + * @param bigImg 大图 + */ + void handleCaptureImg(String deviceIp, byte[] smallImg, byte[] bigImg); + } diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/IZeroSensationPassageService.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/IZeroSensationPassageService.java deleted file mode 100644 index 6d8788a8..00000000 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/IZeroSensationPassageService.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.dromara.sis.service; - -public interface IZeroSensationPassageService { - - /** - * 无感通行服务 - * - * @param deviceIp 设备ip - * @param smallImp 人脸小图 - * @param bigImg 背景图片 - */ - void pass(String deviceIp, byte[] smallImp, byte[] bigImg); - - /** - * 电梯外部按键触发 - * - * @param deviceIp 设备ip - */ - void handleEleOut(String deviceIp); - -} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/EventAlarmReportServiceImpl.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/EventAlarmReportServiceImpl.java index e3b78a8a..1533f30a 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/EventAlarmReportServiceImpl.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/EventAlarmReportServiceImpl.java @@ -1,16 +1,38 @@ package org.dromara.sis.service.impl; +import cn.dev33.satoken.context.mock.SaTokenContextMockUtil; +import cn.hutool.core.codec.Base64Encoder; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.date.TimeInterval; +import cn.hutool.core.util.ObjectUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.dubbo.config.annotation.DubboReference; +import org.dromara.property.api.RemoteAttendanceService; +import org.dromara.property.api.RemoteFloorService; +import org.dromara.property.api.domain.vo.RemoteAttendanceUserGroupVo; +import org.dromara.property.api.domain.vo.RemoteFloorVo; import org.dromara.sis.domain.SisAlarmEvents; +import org.dromara.sis.domain.bo.alarm.AlarmAssignmentBo; +import org.dromara.sis.domain.enums.ControlTypeEnum; import org.dromara.sis.domain.enums.EventSmallTypeEnum; +import org.dromara.sis.domain.enums.RosterTypeEnum; +import org.dromara.sis.domain.vo.*; import org.dromara.sis.rocketmq.domain.HighDensity; import org.dromara.sis.rocketmq.domain.ParkingReport; -import org.dromara.sis.service.IEventAlarmReportService; -import org.dromara.sis.service.ISisAlarmEventsService; +import org.dromara.sis.sdk.e8.E8PlatformApi; +import org.dromara.sis.sdk.e8.domain.accessControl.req.RemoteOpenDoorReq; +import org.dromara.sis.sdk.hik.HikApiService; +import org.dromara.sis.sdk.huawei.HuaWeiBoxApi; +import org.dromara.sis.sdk.huawei.domain.HWResult; +import org.dromara.sis.sdk.smartDevices.utils.ElevatorControlTcpUtil; +import org.dromara.sis.service.*; +import org.dromara.system.api.RemoteUserService; +import org.dromara.system.api.domain.vo.RemoteUserVo; import org.springframework.stereotype.Service; -import java.util.List; +import java.util.*; /** * 处理设备告警上报服务 @@ -23,6 +45,23 @@ import java.util.List; public class EventAlarmReportServiceImpl implements IEventAlarmReportService { private final ISisAlarmEventsService alarmEventsService; + private final HuaWeiBoxApi huaWeiBoxApi; + private final ISisAuthRecordService authRecordService; + private final ISisElevatorInfoService elevatorInfoService; + private final ISisAuthGroupRefService authGroupRefService; + private final ISisDeviceBindRefService deviceBindRefService; + private final ISisAccessControlService accessControlService; + private final ISisElevatorFloorRefService elevatorFloorRefService; + private final ISisElevatorFloorChannelRefService elevatorFloorChannelRefService; + private final E8PlatformApi e8PlatformApi; + private final HikApiService hikApiService; + + @DubboReference + private RemoteFloorService remoteFloorService; + @DubboReference + private RemoteAttendanceService remoteAttendanceService; + @DubboReference + private RemoteUserService remoteUserService; @Override public void handleParking(ParkingReport report) { @@ -34,6 +73,169 @@ public class EventAlarmReportServiceImpl implements IEventAlarmReportService { handleAlarm(density.getDeviceIp(), density.getImg(), 2, EventSmallTypeEnum.SMART_REPORT_RYJJ, "人员聚集报警"); } + @Override + public void handleCaptureImg(String deviceIp, byte[] smallImg, byte[] bigImg) { + TimeInterval interval = new TimeInterval(); + // 抓拍小图 + String smallImgBase64Str = Base64Encoder.encode(smallImg); + HWResult result = huaWeiBoxApi.findPerson(smallImgBase64Str); + if (result.getCode() != 200) { + log.info("华为盒子比对失败,msg={}", result.getMessage()); + // 产生告警数据 人脸比对失败,默认为 + handleAlarm(deviceIp, smallImg, bigImg, 2, EventSmallTypeEnum.SMART_REPORT_ZJCR, "人脸比对失败"); + return; + } + log.info("人脸比对执行完成,耗时:{}ms", interval.intervalMs()); + Long person = result.getData(); + // 验证当前人原是否存在授权记录 + SisAuthRecordVo authRecord = authRecordService.checkAuth(person); + log.info("查询人员权限记录完成,耗时={}ms", interval.intervalMs()); + if (authRecord == null) { + log.info("人员[{}]没有授权记录,判定为陌生人", person); + // 不是内部人员 产生紧急的告警信息 + handleAlarm(deviceIp, smallImg, bigImg, 2, EventSmallTypeEnum.SMART_REPORT_ZJCR, "陌生人员入内"); + return; + } else { + if (Objects.equals(authRecord.getRosterType(), RosterTypeEnum.BLACK_LIST.getCode())) { + log.info("黑名单人员[{}]。", person); + handleAlarm(deviceIp, smallImg, bigImg, 3, EventSmallTypeEnum.BLACK_PERSON, "黑名单人员"); + return; + } + } + + Date now = new Date(); + if (DateUtil.compare(now, authRecord.getEndDate()) > 0) { + handleAlarm(deviceIp, smallImg, bigImg, 1, EventSmallTypeEnum.AUTHORIZATION_EXPIRED, "人员授权信息已过期"); + log.info("当前人脸已过期。person={}", person); + return; + } + // 获取当前设备的绑定设备信息 + List bindRefList = deviceBindRefService.queryByDeviceIp(deviceIp); + log.info("查询设备绑定的梯控/门禁完成,耗时={}ms", interval.intervalMs()); + + if (CollUtil.isEmpty(bindRefList)) { + log.info("当前报警设备未绑定门禁/梯控,不做处理!"); + return; + } + // 授权设备列表 + List authGroupRefVos = authGroupRefService.queryListByGroupId(authRecord.getGroupId()); + // 验证当前设备的绑定门禁和梯控是否有使用权限 + bindRefList.forEach(item -> { + SisAuthGroupRefVo r = null; + for (SisAuthGroupRefVo ref : authGroupRefVos) { + if (Objects.equals(item.getBindId(), ref.getDeviceId())) { + r = ref; + break; + } + } + if (r == null) { + log.info("人员[{}]不存在门禁/电梯[{}]的通行权限", person, item.getBindId()); + return; + } + // 判断绑定设备类型,走不同的处理方法 + if (Objects.equals(item.getControlType(), ControlTypeEnum.ACCESS_CONTROL.getCode())) { // 门禁 + handleAc(item.getBindId()); + } else if (item.getControlType().equals(ControlTypeEnum.ELEVATOR_OUT_CONTROL.getCode())) { // 电梯外面面板权限 +// handleEle(item.getBindId(), r.getAuthGroupId(), ControlTypeEnum.ELEVATOR_OUT_CONTROL.getCode(), item.getDeviceFloorId()); + } else if (item.getControlType().equals(ControlTypeEnum.ELEVATOR_IN_CONTROL.getCode())) { // 电梯里面的面板 +// handleEle(item.getBindId(), r.getAuthGroupId(), ControlTypeEnum.ELEVATOR_IN_CONTROL.getCode(), 0L); + } else { + log.info("设备绑定了未知的控制类型[{}],不处理", item.getControlType()); + } + }); + log.info("权限下发执行完成,耗时:{}ms", interval.intervalMs()); + } + + /** + * 验证电梯权限 + */ + public void handleEle(Long deviceId, Long groupId, Integer controlType, Long deviceFloorId) { + + // 获取当前电梯信息 + SisElevatorInfoVo ele = elevatorInfoService.queryById(deviceId); + // 当前电梯不允许控制 + if (!ele.getIsControl()) return; + + + // 获取权限组下电梯⇄楼层关联信息 + List groupRef = elevatorFloorRefService.queryByAuthGroupId(groupId); + if (CollUtil.isEmpty(groupRef)) return; + + // 取出当前电梯的楼层授权信息 + List eleRef = groupRef.stream().filter(o -> Objects.equals(o.getElevatorId(), deviceId)).toList(); + if (ObjectUtil.isEmpty(eleRef)) return; + + if (Objects.equals(controlType, ControlTypeEnum.ELEVATOR_OUT_CONTROL.getCode())) { + log.info("开始下发外部面板梯控权限...."); + for (SisElevatorFloorRefVo ref : eleRef) { + if (ref.getUpChannel() != null && Objects.equals(ref.getFloorId(), deviceFloorId)) { + hikApiService.controlGateway(ele.getControlIp(), ref.getUpChannel().intValue(), 2); + } + + if (ref.getDownChannel() != null && Objects.equals(ref.getFloorId(), deviceFloorId)) { + hikApiService.controlGateway(ele.getControlIp(), ref.getDownChannel().intValue(), 2); + } + } + } + + // 模拟上下文 + List floorList = SaTokenContextMockUtil.setMockContext(() -> remoteFloorService.queryByBuildingId(ele.getBuildingId())); + if (CollUtil.isEmpty(floorList)) return; + + if (Objects.equals(controlType, ControlTypeEnum.ELEVATOR_IN_CONTROL.getCode())) { + SisElevatorFloorRefVo vo; + List num = new ArrayList<>(); + for (int i = 1; i < floorList.size(); i++) { + int finalI = i; + // 取出权限楼层id与实际楼层id相等的数据 + vo = eleRef.stream().filter(o -> Objects.equals(o.getFloorId(), floorList.get(finalI - 1).getId())).findFirst().orElse(null); + // 存在权限楼层,添加到num中,梯控模块从1开始 + if (vo != null) { + num.add(i); + } + } + if (CollUtil.isEmpty(num)) return; + + ElevatorControlTcpUtil.getInstance().sendManualCommand(num); + } + log.info("梯控下发权限完成"); + } + + /** + * 处理门禁 + */ + public void handleAc(Long deviceId) { + if (deviceId != null) { + SisAccessControlVo ac = accessControlService.queryById(deviceId); + log.info("调用门禁服务远程开门,doorName:{}", ac.getAccessName()); + RemoteOpenDoorReq req = new RemoteOpenDoorReq(); + req.setType(0); + RemoteOpenDoorReq.ControlData data = new RemoteOpenDoorReq.ControlData(); + data.setDeviceId(Long.parseLong(ac.getOutCode())); + data.setDoorId(Long.parseLong(ac.getOutCode())); + req.setControlList(List.of(data)); + Boolean flag = e8PlatformApi.remoteOpenDoor(req); + log.info("远程开门结果,result={}", flag); + } + } + + /** + * 处理告警信息 + * + * @param deviceIp 设备ip + * @param smallImg 人脸小图 + * @param bigImg 人脸大图 + * @param smallType 事件类型 + */ + private void handleAlarm(String deviceIp, byte[] smallImg, byte[] bigImg, Integer level, EventSmallTypeEnum smallType, String desc) { + List ls = new ArrayList<>(2); + ls.add(smallImg); + ls.add(bigImg); + // 生成告警记录 + SisAlarmEvents alarmRecord = alarmEventsService.createAlarmRecord(deviceIp, level, smallType, desc, ls); + autoAssign(alarmRecord.getId(), deviceIp); + } + /** * 处理告警信息 * @@ -44,8 +246,40 @@ public class EventAlarmReportServiceImpl implements IEventAlarmReportService { private void handleAlarm(String deviceIp, byte[] img, Integer level, EventSmallTypeEnum smallType, String desc) { // 生成告警记录 SisAlarmEvents alarmRecord = alarmEventsService.createAlarmRecord(deviceIp, level, smallType, desc, List.of(img)); + autoAssign(alarmRecord.getId(), deviceIp); } + private void autoAssign(Long alarmId, String deviceIp) { + SaTokenContextMockUtil.setMockContext(() -> { + // 如果当前设备区域存在排班人员,那么惊醒自动指派操作 + List userGroupVos = remoteAttendanceService.queryAttendByCurrDateAndDeviceIp(new Date(), deviceIp); + if (CollUtil.isEmpty(userGroupVos)) { + return; + } + // 进行自动指派操作 + RemoteAttendanceUserGroupVo currHandlePerson = null; + if (userGroupVos.size() == 1) { + currHandlePerson = userGroupVos.get(0); + } else { + // 生成一个排班人员课表的随机数 + Random random = new Random(); + int randomIndex = random.nextInt(userGroupVos.size()); + currHandlePerson = userGroupVos.get(randomIndex); + } + // 获取当前指派人员的详细信息 + RemoteUserVo userInfo = remoteUserService.getUserInfoById(currHandlePerson.getEmployeeId()); + // 任务指派操作 + AlarmAssignmentBo bo = new AlarmAssignmentBo(); + bo.setAlarmId(alarmId); + bo.setSolveId(userInfo.getUserId()); + bo.setSolveName(userInfo.getUserName()); + bo.setSolvePhone(userInfo.getPhonenumber()); + bo.setSolveEmail(userInfo.getEmail()); + bo.setRemark("系统自动指派"); + alarmEventsService.taskAssignment(bo); + }); + } + } diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/ZeroSensationPassageServiceImpl.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/ZeroSensationPassageServiceImpl.java deleted file mode 100644 index 5fe6f2a5..00000000 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/ZeroSensationPassageServiceImpl.java +++ /dev/null @@ -1,296 +0,0 @@ -package org.dromara.sis.service.impl; - -import cn.dev33.satoken.context.mock.SaTokenContextMockUtil; -import cn.hutool.core.codec.Base64Encoder; -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.date.DateUtil; -import cn.hutool.core.date.TimeInterval; -import cn.hutool.core.util.ObjectUtil; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.apache.dubbo.config.annotation.DubboReference; -import org.dromara.property.api.RemoteAttendanceService; -import org.dromara.property.api.RemoteFloorService; -import org.dromara.property.api.domain.vo.RemoteAttendanceUserGroupVo; -import org.dromara.property.api.domain.vo.RemoteFloorVo; -import org.dromara.sis.domain.SisAlarmEvents; -import org.dromara.sis.domain.bo.alarm.AlarmAssignmentBo; -import org.dromara.sis.domain.enums.ControlTypeEnum; -import org.dromara.sis.domain.enums.EventSmallTypeEnum; -import org.dromara.sis.domain.enums.RosterTypeEnum; -import org.dromara.sis.domain.vo.*; -import org.dromara.sis.sdk.e8.E8PlatformApi; -import org.dromara.sis.sdk.e8.domain.accessControl.req.RemoteOpenDoorReq; -import org.dromara.sis.sdk.hik.HikApiService; -import org.dromara.sis.sdk.huawei.HuaWeiBoxApi; -import org.dromara.sis.sdk.huawei.domain.HWResult; -import org.dromara.sis.sdk.smartDevices.utils.ElevatorControlTcpUtil; -import org.dromara.sis.service.*; -import org.dromara.system.api.RemoteUserService; -import org.dromara.system.api.domain.vo.RemoteUserVo; -import org.springframework.scheduling.annotation.Async; -import org.springframework.stereotype.Service; - -import java.util.*; - -/** - * 无感通行业务服务实现 - * - * @author lxj, lsm - * @since 2025-08-04 - */ -@Slf4j -@Service -@RequiredArgsConstructor -public class ZeroSensationPassageServiceImpl implements IZeroSensationPassageService { - - private final HuaWeiBoxApi huaWeiBoxApi; - private final ISisAuthRecordService authRecordService; - private final ISisElevatorInfoService elevatorInfoService; - private final ISisAuthGroupRefService authGroupRefService; - private final ISisDeviceBindRefService deviceBindRefService; - private final ISisAccessControlService accessControlService; - private final ISisElevatorFloorRefService elevatorFloorRefService; - private final ISisElevatorFloorChannelRefService elevatorFloorChannelRefService; - private final E8PlatformApi e8PlatformApi; - private final ISisAlarmEventsService alarmEventsService; - private final HikApiService hikApiService; - - @DubboReference - private RemoteFloorService remoteFloorService; - @DubboReference - private RemoteAttendanceService remoteAttendanceService; - @DubboReference - private RemoteUserService remoteUserService; - - @Override - @Async - public void pass(String deviceIp, byte[] smallImg, byte[] bigImg) { - TimeInterval interval = new TimeInterval(); - // 抓拍小图 - String smallImgBase64Str = Base64Encoder.encode(smallImg); - HWResult result = huaWeiBoxApi.findPerson(smallImgBase64Str); - if (result.getCode() != 200) { - log.info("华为盒子比对失败,msg={}", result.getMessage()); - // 产生告警数据 人脸比对失败,默认为 - handleAlarm(deviceIp, smallImg, bigImg, 2, EventSmallTypeEnum.SMART_REPORT_ZJCR, "人脸比对失败"); - return; - } - log.info("人脸比对执行完成,耗时:{}ms", interval.intervalMs()); - Long person = result.getData(); - // 验证当前人原是否存在授权记录 - SisAuthRecordVo authRecord = authRecordService.checkAuth(person); - log.info("查询人员权限记录完成,耗时={}ms", interval.intervalMs()); - if (authRecord == null) { - log.info("人员[{}]没有授权记录,判定为陌生人", person); - // 不是内部人员 产生紧急的告警信息 - handleAlarm(deviceIp, smallImg, bigImg, 2, EventSmallTypeEnum.SMART_REPORT_ZJCR, "陌生人员入内"); - return; - } else { - if (Objects.equals(authRecord.getRosterType(), RosterTypeEnum.BLACK_LIST.getCode())) { - log.info("黑名单人员[{}]。", person); - handleAlarm(deviceIp, smallImg, bigImg, 3, EventSmallTypeEnum.BLACK_PERSON, "黑名单人员"); - return; - } - } - - Date now = new Date(); - if (DateUtil.compare(now, authRecord.getEndDate()) > 0) { - handleAlarm(deviceIp, smallImg, bigImg, 1, EventSmallTypeEnum.AUTHORIZATION_EXPIRED, "人员授权信息已过期"); - log.info("当前人脸已过期。person={}", person); - return; - } - // 获取当前设备的绑定设备信息 - List bindRefList = deviceBindRefService.queryByDeviceIp(deviceIp); - log.info("查询设备绑定的梯控/门禁完成,耗时={}ms", interval.intervalMs()); - - if (CollUtil.isEmpty(bindRefList)) { - log.info("当前报警设备未绑定门禁/梯控,不做处理!"); - return; - } - // 授权设备列表 - List authGroupRefVos = authGroupRefService.queryListByGroupId(authRecord.getGroupId()); - // 验证当前设备的绑定门禁和梯控是否有使用权限 - bindRefList.forEach(item -> { - SisAuthGroupRefVo r = null; - for (SisAuthGroupRefVo ref : authGroupRefVos) { - if (Objects.equals(item.getBindId(), ref.getDeviceId())) { - r = ref; - break; - } - } - if (r == null) { - log.info("人员[{}]不存在门禁/电梯[{}]的通行权限", person, item.getBindId()); - return; - } - // 判断绑定设备类型,走不同的处理方法 - if (Objects.equals(item.getControlType(), ControlTypeEnum.ACCESS_CONTROL.getCode())) { // 门禁 - handleAc(item.getBindId()); - } else if (item.getControlType().equals(ControlTypeEnum.ELEVATOR_OUT_CONTROL.getCode())) { // 电梯外面面板权限 -// handleEle(item.getBindId(), r.getAuthGroupId(), ControlTypeEnum.ELEVATOR_OUT_CONTROL.getCode(), item.getDeviceFloorId()); - } else if (item.getControlType().equals(ControlTypeEnum.ELEVATOR_IN_CONTROL.getCode())) { // 电梯里面的面板 -// handleEle(item.getBindId(), r.getAuthGroupId(), ControlTypeEnum.ELEVATOR_IN_CONTROL.getCode(), 0L); - } else { - log.info("设备绑定了未知的控制类型[{}],不处理", item.getControlType()); - } - }); - log.info("权限下发执行完成,耗时:{}ms", interval.intervalMs()); - } - - /** - * 处理告警信息 - * - * @param deviceIp 设备ip - * @param smallImg 人脸小图 - * @param bigImg 人脸大图 - * @param smallType 事件类型 - */ - private void handleAlarm(String deviceIp, byte[] smallImg, byte[] bigImg, Integer level, EventSmallTypeEnum smallType, String desc) { - List ls = new ArrayList<>(2); - ls.add(smallImg); - ls.add(bigImg); - // 生成告警记录 - SisAlarmEvents alarmRecord = alarmEventsService.createAlarmRecord(deviceIp, level, smallType, desc, ls); - SaTokenContextMockUtil.setMockContext(() -> { - // 如果当前设备区域存在排班人员,那么惊醒自动指派操作 - List userGroupVos = remoteAttendanceService.queryAttendByCurrDateAndDeviceIp(new Date(), deviceIp); - if (CollUtil.isEmpty(userGroupVos)) { - return; - } - // 进行自动指派操作 - RemoteAttendanceUserGroupVo currHandlePerson = null; - if (userGroupVos.size() == 1) { - currHandlePerson = userGroupVos.get(0); - } else { - // 生成一个排班人员课表的随机数 - Random random = new Random(); - int randomIndex = random.nextInt(userGroupVos.size()); - currHandlePerson = userGroupVos.get(randomIndex); - } - // 获取当前指派人员的详细信息 - RemoteUserVo userInfo = remoteUserService.getUserInfoById(currHandlePerson.getEmployeeId()); - // 任务指派操作 - AlarmAssignmentBo bo = new AlarmAssignmentBo(); - bo.setAlarmId(alarmRecord.getId()); - bo.setSolveId(userInfo.getUserId()); - bo.setSolveName(userInfo.getUserName()); - bo.setSolvePhone(userInfo.getPhonenumber()); - bo.setSolveEmail(userInfo.getEmail()); - bo.setRemark("系统自动指派"); - alarmEventsService.taskAssignment(bo); - }); - } - - - /** - * 电梯外部按键触发 - * - * @param deviceIp 设备ip - */ - @Override - public void handleEleOut(String deviceIp) { - TimeInterval interval = new TimeInterval(); - // 获取当前设备的绑定设备信息 - List bindRefList = deviceBindRefService.queryByDeviceIp(deviceIp); - List outRefList = bindRefList.stream().filter(item -> Objects.equals(item.getControlType(), ControlTypeEnum.ELEVATOR_OUT_CONTROL.getCode())).toList(); - - outRefList.forEach(item -> { - // 获取当前电梯信息 - SisElevatorInfoVo ele = elevatorInfoService.queryById(item.getBindId()); - - List channelRef = elevatorFloorChannelRefService.queryByFloorIds(List.of(item.getDeviceFloorId())); - SisElevatorFloorChannelRefVo channelRefVo = channelRef.stream().filter(o -> Objects.equals(o.getElevatorId(), item.getBindId())).findFirst().orElse(null); - - if (channelRefVo != null) { - if (channelRefVo.getDownChannel() != null) { - hikApiService.controlGateway(ele.getControlIp(), channelRefVo.getDownChannel().intValue(), 2); - } - - if (channelRefVo.getUpChannel() != null) { - hikApiService.controlGateway(ele.getControlIp(), channelRefVo.getUpChannel().intValue(), 2); - } - } - }); - log.info("处理电梯外部按键完成,耗时:{}ms", interval.intervalMs()); - } - - /** - * 生成告警事件 - */ - public void createAlarmRecord(String deviceIp, Integer level, Integer type, String msg, byte[] smallImg, byte[] bigImg) { -// alarmEventsService.createAlarmRecord(deviceIp, level, type, msg, smallImg, bigImg); - } - - /** - * 处理门禁 - */ - public void handleAc(Long deviceId) { - if (deviceId != null) { - SisAccessControlVo ac = accessControlService.queryById(deviceId); - log.info("调用门禁服务远程开门,doorName:{}", ac.getAccessName()); - RemoteOpenDoorReq req = new RemoteOpenDoorReq(); - req.setType(0); - RemoteOpenDoorReq.ControlData data = new RemoteOpenDoorReq.ControlData(); - data.setDeviceId(Long.parseLong(ac.getOutCode())); - data.setDoorId(Long.parseLong(ac.getOutCode())); - req.setControlList(List.of(data)); - Boolean flag = e8PlatformApi.remoteOpenDoor(req); - log.info("远程开门结果,result={}", flag); - } - } - - /** - * 验证电梯权限 - */ - public void handleEle(Long deviceId, Long groupId, Integer controlType, Long deviceFloorId) { - - // 获取当前电梯信息 - SisElevatorInfoVo ele = elevatorInfoService.queryById(deviceId); - // 当前电梯不允许控制 - if (!ele.getIsControl()) return; - - - // 获取权限组下电梯⇄楼层关联信息 - List groupRef = elevatorFloorRefService.queryByAuthGroupId(groupId); - if (CollUtil.isEmpty(groupRef)) return; - - // 取出当前电梯的楼层授权信息 - List eleRef = groupRef.stream().filter(o -> Objects.equals(o.getElevatorId(), deviceId)).toList(); - if (ObjectUtil.isEmpty(eleRef)) return; - - if (Objects.equals(controlType, ControlTypeEnum.ELEVATOR_OUT_CONTROL.getCode())) { - log.info("开始下发外部面板梯控权限...."); - for (SisElevatorFloorRefVo ref : eleRef) { - if (ref.getUpChannel() != null && Objects.equals(ref.getFloorId(), deviceFloorId)) { - hikApiService.controlGateway(ele.getControlIp(), ref.getUpChannel().intValue(), 2); - } - - if (ref.getDownChannel() != null && Objects.equals(ref.getFloorId(), deviceFloorId)) { - hikApiService.controlGateway(ele.getControlIp(), ref.getDownChannel().intValue(), 2); - } - } - } - - // 模拟上下文 - List floorList = SaTokenContextMockUtil.setMockContext(() -> remoteFloorService.queryByBuildingId(ele.getBuildingId())); - if (CollUtil.isEmpty(floorList)) return; - - if (Objects.equals(controlType, ControlTypeEnum.ELEVATOR_IN_CONTROL.getCode())) { - SisElevatorFloorRefVo vo; - List num = new ArrayList<>(); - for (int i = 1; i < floorList.size(); i++) { - int finalI = i; - // 取出权限楼层id与实际楼层id相等的数据 - vo = eleRef.stream().filter(o -> Objects.equals(o.getFloorId(), floorList.get(finalI - 1).getId())).findFirst().orElse(null); - // 存在权限楼层,添加到num中,梯控模块从1开始 - if (vo != null) { - num.add(i); - } - } - if (CollUtil.isEmpty(num)) return; - - ElevatorControlTcpUtil.getInstance().sendManualCommand(num); - } - log.info("梯控下发权限完成"); - } -} From 863366de7e2746681438bddffd3ee0e725e7e2e3 Mon Sep 17 00:00:00 2001 From: zcxlsm Date: Mon, 1 Sep 2025 18:07:33 +0800 Subject: [PATCH 20/20] =?UTF-8?q?feat(property):=20webSocket=E5=AE=9A?= =?UTF-8?q?=E6=97=B6=E6=8E=A8=E9=80=81=E4=BB=AA=E8=A1=A8=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=20-=20=E6=96=B0=E5=A2=9E=20HeartbeatTasks=20?= =?UTF-8?q?=E7=B1=BB=E7=94=A8=E4=BA=8E=E7=AE=A1=E7=90=86=E5=BF=83=E8=B7=B3?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TbMeterInfoController.java | 5 +- .../TbMeterInfoServiceImpl.java | 148 +++++++++++++++--- .../ITbMeterInfoService.java | 2 +- .../property/tasks/HeartbeatTasks.java | 42 +++++ 4 files changed, 170 insertions(+), 27 deletions(-) create mode 100644 ruoyi-modules/Property/src/main/java/org/dromara/property/tasks/HeartbeatTasks.java diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/smartDevicesController/TbMeterInfoController.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/smartDevicesController/TbMeterInfoController.java index 203a4850..967996d2 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/smartDevicesController/TbMeterInfoController.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/smartDevicesController/TbMeterInfoController.java @@ -124,8 +124,9 @@ public class TbMeterInfoController extends BaseController { * @param floorId 楼栋id */ @GetMapping("/currentReading") - public R> currentReading(@RequestParam Long meterType, @RequestParam Long floorId) { - return R.ok(tbMeterInfoService.getMeterStatus(meterType, floorId)); + public R currentReading(@RequestParam Long meterType, @RequestParam Long floorId) { + tbMeterInfoService.getMeterStatus(meterType, floorId); + return R.ok(); } } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterInfoServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterInfoServiceImpl.java index 697bc188..3c7ea77b 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterInfoServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/smartDevicesImpl/TbMeterInfoServiceImpl.java @@ -1,6 +1,8 @@ package org.dromara.property.service.impl.smartDevicesImpl; +import cn.hutool.core.date.DateUtil; import cn.hutool.core.lang.Assert; +import com.alibaba.fastjson.JSONObject; import org.dromara.common.core.domain.TreeNode; import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.StringUtils; @@ -12,6 +14,9 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.dromara.common.satoken.utils.LoginHelper; +import org.dromara.common.websocket.dto.WebSocketMessageDto; +import org.dromara.common.websocket.utils.WebSocketUtils; import org.dromara.property.domain.bo.TbFloorBo; import org.dromara.property.domain.vo.TbBuildingVo; import org.dromara.property.domain.vo.TbCommunityVo; @@ -20,7 +25,9 @@ import org.dromara.property.rocketmq.domain.MeterResult; import org.dromara.property.service.ITbBuildingService; import org.dromara.property.service.ITbCommunityService; import org.dromara.property.service.ITbFloorService; +import org.dromara.property.tasks.HeartbeatTasks; import org.dromara.property.utils.MeterRecordUtil; +import org.dromara.system.api.model.LoginUser; import org.springframework.stereotype.Service; import org.dromara.property.domain.bo.smartDevicesBo.TbMeterInfoBo; import org.dromara.property.domain.vo.smartDevicesVo.TbMeterInfoVo; @@ -32,6 +39,7 @@ import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.*; +import java.util.function.Function; import java.util.stream.Collectors; /** @@ -51,6 +59,7 @@ public class TbMeterInfoServiceImpl implements ITbMeterInfoService { private final ITbCommunityService communityService; private final MeterRecordUtil meterRecordUtil; + private final HeartbeatTasks heartbeatTasks; /** * 查询水电气 @@ -226,7 +235,7 @@ public class TbMeterInfoServiceImpl implements ITbMeterInfoService { }).toList(); treeList.addAll(l3); - if (isMeter){ + if (isMeter) { TbMeterInfoBo bo = new TbMeterInfoBo(); bo.setMeterType(meterType); List meterInfoVos = this.queryList(bo); @@ -252,42 +261,133 @@ public class TbMeterInfoServiceImpl implements ITbMeterInfoService { * @param floorId 楼栋id */ @Override - public List getMeterStatus(Long meterType, Long floorId) { + public void getMeterStatus(Long meterType, Long floorId) { + // 参数校验 + if (meterType == 0L || floorId == 0L) { + heartbeatTasks.stopTask("Meter_Status_Reading"); + return; + } + + // 获取当前登录用户 + LoginUser user = LoginHelper.getLoginUser(); + if (user == null) { + heartbeatTasks.stopTask("Meter_Status_Reading"); + return; + } + + // 初始化WebSocket消息 + WebSocketMessageDto webSocketMessage = new WebSocketMessageDto(); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("type", "meter"); + + // 查询仪表信息 TbMeterInfoBo meterInfoBo = new TbMeterInfoBo(); meterInfoBo.setFloorId(floorId); meterInfoBo.setMeterType(meterType); List meterInfoVoList = this.queryList(meterInfoBo); - if (meterInfoVoList.isEmpty()) return null; - String[] hostIpArr = meterInfoVoList.stream().map(TbMeterInfoVo::getHostIp).distinct().toArray(String[]::new); + // 如果没有仪表信息,直接返回 + if (meterInfoVoList.isEmpty()) { + heartbeatTasks.stopTask("Meter_Status_Reading"); + jsonObject.put("readingTime", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss")); + jsonObject.put("data", new ArrayList<>()); + webSocketMessage.setMessage(jsonObject.toString()); + webSocketMessage.setSessionKeys(List.of(user.getUserId())); + WebSocketUtils.publishMessage(webSocketMessage); + return; + } + + // 获取唯一的主机IP列表 + String[] hostIpArr = meterInfoVoList.stream() + .map(TbMeterInfoVo::getHostIp) + .distinct() + .toArray(String[]::new); + + // 统计每个IP对应的仪表数量 Map ipCountMap = new HashMap<>(); for (String ip : hostIpArr) { - ipCountMap.put(ip, baseMapper.selectCount(new LambdaQueryWrapper().eq(TbMeterInfo::getHostIp, ip))); + ipCountMap.put(ip, baseMapper.selectCount(new LambdaQueryWrapper() + .eq(TbMeterInfo::getHostIp, ip))); } - List meterResults; - try{ - meterResults = meterRecordUtil.getMeterStatus(ipCountMap, hostIpArr); - } catch (Exception e) { - // 获取数据失败,返回所有数据,设置通信状态为0 - for (TbMeterInfoVo item : meterInfoVoList) { - item.setCommunicationState(0L); + + // 启动定时任务 + heartbeatTasks.startHeartbeatTask("Meter_Status_Reading", () -> { + jsonObject.put("readingTime", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss")); + + List meterResults; + try { + meterResults = meterRecordUtil.getMeterStatus(ipCountMap, hostIpArr); + } catch (Exception e) { + // 获取数据失败,设置所有仪表通信状态为0并发送消息 + handleMeterCommunicationFailure(user, jsonObject, meterInfoVoList, webSocketMessage); + return; } - return meterInfoVoList; - } + + // 处理仪表读数和状态 + processMeterResults(user, jsonObject, meterResults, meterInfoVoList, webSocketMessage); + }, 30000); + } + + /** + * 处理仪表通信失败的情况 + * + * @param meterInfoVoList 仪表列表 + * @param jsonObject 消息对象 + * @param webSocketMessage WebSocket消息 + * @param user 当前用户 + */ + private void handleMeterCommunicationFailure(LoginUser user, JSONObject jsonObject, List meterInfoVoList, WebSocketMessageDto webSocketMessage) { + meterInfoVoList.forEach(item -> item.setCommunicationState(0L)); + jsonObject.put("data", meterInfoVoList); + webSocketMessage.setMessage(jsonObject.toString()); + webSocketMessage.setSessionKeys(List.of(user.getUserId())); + WebSocketUtils.publishMessage(webSocketMessage); + } + + /** + * 处理仪表读数结果 + * + * @param meterInfoVoList 仪表列表 + * @param meterResults 读数结果 + * @param jsonObject 消息对象 + * @param webSocketMessage WebSocket消息 + * @param user 当前用户 + */ + private void processMeterResults(LoginUser user, JSONObject jsonObject, List meterResults, List meterInfoVoList, WebSocketMessageDto webSocketMessage) { + // 创建IP到结果的映射,提高查找效率 + Map meterResultMap = meterResults.stream() + .collect(Collectors.toMap(MeterResult::getIp, Function.identity(), (v1, v2) -> v1)); for (TbMeterInfoVo item : meterInfoVoList) { - MeterResult meterResult = meterResults.stream().filter(o -> o.getIp().equals(item.getHostIp())).findFirst().orElse(null); - if (meterResult == null) continue; - - BigDecimal initReading = BigDecimal.valueOf(meterResult.getCollectionValue().get(Integer.parseInt(item.getMeterCode()))) - .setScale(2, RoundingMode.HALF_UP); - if (initReading.compareTo(BigDecimal.ZERO) == 0) { + MeterResult meterResult = meterResultMap.get(item.getHostIp()); + if (meterResult == null) { + // 如果没有找到对应的结果,设置通信状态为0 + item.setCommunicationState(0L); + continue; + } + + // 解析读数 + List collectionValue = meterResult.getCollectionValue(); + String meterCode = item.getMeterCode(); + + try { + int codeIndex = Integer.parseInt(meterCode); + if (codeIndex >= 0 && codeIndex < collectionValue.size()) { + BigDecimal initReading = BigDecimal.valueOf(collectionValue.get(codeIndex)) + .setScale(2, RoundingMode.HALF_UP); + item.setInitReading(initReading); + item.setCommunicationState(initReading.compareTo(BigDecimal.ZERO) == 0 ? 0L : 1L); + } else { + item.setCommunicationState(0L); + } + } catch (NumberFormatException e) { item.setCommunicationState(0L); - } else { - item.setCommunicationState(1L); } - item.setInitReading(initReading); } - return meterInfoVoList; + + jsonObject.put("data", meterInfoVoList); + webSocketMessage.setMessage(jsonObject.toString()); + webSocketMessage.setSessionKeys(List.of(user.getUserId())); + WebSocketUtils.publishMessage(webSocketMessage); } } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/smartDevicesService/ITbMeterInfoService.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/smartDevicesService/ITbMeterInfoService.java index d71fb417..7430854c 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/smartDevicesService/ITbMeterInfoService.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/smartDevicesService/ITbMeterInfoService.java @@ -82,5 +82,5 @@ public interface ITbMeterInfoService { * @param meterType 水电气类型 * @param floorId 楼栋id */ - List getMeterStatus(Long meterType, Long floorId); + void getMeterStatus(Long meterType, Long floorId); } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/tasks/HeartbeatTasks.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/tasks/HeartbeatTasks.java new file mode 100644 index 00000000..3ea0917e --- /dev/null +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/tasks/HeartbeatTasks.java @@ -0,0 +1,42 @@ +package org.dromara.property.tasks; + +import org.springframework.stereotype.Component; + +import java.util.Map; +import java.util.concurrent.*; + +/** + * @author lsm + * @apiNote HeartbeatTasks + * @since 2025/9/1 + */ +@Component +public class HeartbeatTasks { + private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); + private final Map> tasks = new ConcurrentHashMap<>(); + + public void startHeartbeatTask(String taskId, Runnable task, long intervalMs) { + // 先停止同名任务(如果存在) + stopTask(taskId); + + // 创建新任务 + ScheduledFuture future = scheduler.scheduleAtFixedRate( + task, 0, intervalMs, TimeUnit.MILLISECONDS); + + tasks.put(taskId, future); + } + + public void stopHeartbeatTask() { + // 停止所有心跳任务 + tasks.values().forEach(future -> future.cancel(true)); + tasks.clear(); + } + + public void stopTask(String taskId) { + ScheduledFuture future = tasks.get(taskId); + if (future != null) { + future.cancel(true); + tasks.remove(taskId); + } + } +}