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 13793fdd..2c206a81 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 @@ -249,6 +249,7 @@ public class TbMeterRecordServiceImpl implements ITbMeterRecordService { .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()); // day String[] monthArr = month.split("-"); @@ -262,6 +263,7 @@ public class TbMeterRecordServiceImpl implements ITbMeterRecordService { .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()); // month List> monthList = baseMapper.getMonthTrend(StrUtil.isBlank(floorId) ? null : Long.parseLong(floorId), StrUtil.isBlank(meterId) ? null : Long.parseLong(meterId), meterType, year); @@ -274,6 +276,7 @@ public class TbMeterRecordServiceImpl implements ITbMeterRecordService { .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()); resultMap.put("hour", hourMap); diff --git a/ruoyi-modules/Sis/Dockerfile b/ruoyi-modules/Sis/Dockerfile index b2372fc7..a821c055 100644 --- a/ruoyi-modules/Sis/Dockerfile +++ b/ruoyi-modules/Sis/Dockerfile @@ -11,7 +11,7 @@ RUN mkdir -p /smartparks/Sis/logs \ WORKDIR /ruoyi/sis -ENV SERVER_PORT=10002 LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS="" +ENV SERVER_PORT=10002 LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS="-Duser.timezone=Asia/Shanghai" EXPOSE ${SERVER_PORT} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/controller/SisVisitorController.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/controller/SisVisitorController.java index 588bd650..01d34f98 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/controller/SisVisitorController.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/controller/SisVisitorController.java @@ -1,36 +1,26 @@ package org.dromara.sis.controller; - -import cn.dev33.satoken.annotation.SaCheckPermission; import cn.hutool.core.date.DateField; import cn.hutool.core.date.DateUtil; -import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; -import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; -import org.dromara.sis.domain.bo.SisPersonLibImgBo; -import org.dromara.sis.domain.vo.SisPersonLibImgVo; import org.dromara.sis.sdk.e8.E8PlatformApi; import org.dromara.sis.sdk.e8.domain.QueryDto; import org.dromara.sis.sdk.e8.domain.accessControl.req.AccessRecordFindReq; import org.dromara.sis.sdk.e8.domain.accessControl.res.AccessRecordFindRes; -import org.dromara.sis.service.ISisPersonLibImgService; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import java.util.ArrayList; import java.util.Date; -import java.util.List; /** * @author yuyongle * @version 1.0 - * @description: - * @date 2025/8/27 15:57 + * @since 2025/8/27 15:57 */ @Validated @RequiredArgsConstructor @@ -43,15 +33,15 @@ public class SisVisitorController { * 查询人员通行记录 */ @GetMapping("/list") - public TableDataInfo list(@RequestParam(required = false) String beginTime, + public TableDataInfo list(@RequestParam(required = false) String begTime, @RequestParam(required = false) String endTime, @NotNull(message = "页码不能为空") @RequestParam Integer pageNum, @NotNull(message = "页数不能为空") @RequestParam Integer pageSize, @RequestParam(required = false) String personName, @RequestParam(required = false) Integer recordType) { AccessRecordFindReq req = new AccessRecordFindReq(); - if (beginTime != null && !beginTime.isEmpty()) { - req.setStartTime(DateUtil.format(DateUtil.parse(beginTime), "yyyy-MM-dd 00:00:00")); + if (begTime != null && !begTime.isEmpty()) { + req.setStartTime(DateUtil.format(DateUtil.parse(begTime), "yyyy-MM-dd 00:00:00")); } else { // 默认设置为7天前 req.setStartTime(DateUtil.format(DateUtil.offset(new Date(), DateField.DAY_OF_MONTH, -7), "yyyy-MM-dd 00:00:00")); 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 72b116c5..ee4720b0 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 @@ -35,6 +35,8 @@ public enum EventSmallTypeEnum { SMART_REPORT_YW(1023, "烟雾报警"), SMART_REPORT_RYSLCX(1024, "人员数量超限报警"), EQP_REPORT_SBSB(1025, "报警设备上报"), + BLACK_PERSON(1026, "黑名单人员"), + AUTHORIZATION_EXPIRED(1027, "门禁授权已过期"), /* -----------------------系统报警相关-------------------------------------*/ SYS_REPORT_WLGZ(2001, "网络连接故障"), SYS_REPORT_DLYC(2002, "用户登录异常"), diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/model/SisAcDevice.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/model/SisAcDevice.java index 22088fbb..4d13565b 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/model/SisAcDevice.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/model/SisAcDevice.java @@ -10,4 +10,44 @@ public class SisAcDevice extends SisDeviceManage { private Long acId; + /** + * 设备通道编号 + */ + private String channelNo; + + /** + * 通道状态.0-离线;1-在线 + */ + private Integer channelState; + + /** + * nvr 设备厂商编号 + */ + private String nvrFactoryNo; + + /** + * nvr设备ip + */ + private String nvrIp; + + /** + * nvr 端口 + */ + private Integer nvrPort; + + /** + * nvr 账号 + */ + private String nvrAccount; + + /** + * nvr 密码 + */ + private String nvrPwd; + + /** + * nvr 通道编号 + */ + private String nvrChannelNo; + } 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 768ccfff..f65b1a29 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 @@ -5,6 +5,7 @@ import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.sis.domain.bo.SisAlarmEventsBo; import org.dromara.sis.domain.bo.alarm.AlarmAssignmentBo; import org.dromara.sis.domain.bo.alarm.AlarmCompleteBo; +import org.dromara.sis.domain.enums.EventSmallTypeEnum; import org.dromara.sis.domain.vo.SisAlarmEventsVo; import java.util.Collection; @@ -78,7 +79,7 @@ public interface ISisAlarmEventsService { /** * 异步生成告警记录 */ - void createAlarmRecord(String deviceIp, Integer level, Integer type, String msg, byte[] smallImg, byte[] bigImg); + void 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/impl/SisAccessControlServiceImpl.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisAccessControlServiceImpl.java index 9cbe0b2a..79d435f0 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisAccessControlServiceImpl.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisAccessControlServiceImpl.java @@ -142,7 +142,6 @@ public class SisAccessControlServiceImpl implements ISisAccessControlService { SisAccessControl update = MapstructUtils.convert(bo, SisAccessControl.class); boolean b = baseMapper.updateById(update) > 0; if (bo.getBindDeviceId() != null) { - // 检验设备是否存在 SisDeviceManageVo sisDeviceManageVo = sisDeviceManageService.queryById(bo.getBindDeviceId()); Assert.isTrue(sisDeviceManageVo != null, "设备-{}信息不存在.", bo.getBindDeviceId()); @@ -158,6 +157,9 @@ public class SisAccessControlServiceImpl implements ISisAccessControlService { // 重新构建绑定关系 Boolean insert = sisDeviceBindRefService.insert(sisDeviceBindRef); Assert.isTrue(insert, "写入设备关联表失败!"); + } else { + // 删除设备绑定关系 + sisDeviceBindRefService.deleteByBindId(bo.getId()); } if (CollUtil.isNotEmpty(bo.getDevicePoint())) { @@ -178,6 +180,10 @@ public class SisAccessControlServiceImpl implements ISisAccessControlService { // 构建新的关联关系 Boolean b2 = sisAcDeviceRefService.batchInsert(refs); log.info("门禁-监控设备关联关系构建完成, result={}", b2); + } else { + // 删除监控点管理 + Boolean b1 = sisAcDeviceRefService.deleteByAcId(bo.getId()); + log.info("门禁-监控关联关系删除完成, result={}, acId={}", b1, bo.getId()); } return b; } 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 1c1b215a..efe5de5b 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 @@ -182,7 +182,7 @@ public class SisAlarmEventsServiceImpl implements ISisAlarmEventsService { @Async @Override @Transactional(rollbackFor = Exception.class) - public void createAlarmRecord(String deviceIp, Integer level, Integer type, String msg, byte[] smallImg, byte[] bigImg) { + public void createAlarmRecord(String deviceIp, Integer level, EventSmallTypeEnum type, String msg, byte[] smallImg, byte[] bigImg) { // 校验设备信息 SisDeviceManage sisDeviceManage = deviceManageService.queryByDeviceIp(deviceIp); if (sisDeviceManage == null) { @@ -193,7 +193,7 @@ public class SisAlarmEventsServiceImpl implements ISisAlarmEventsService { Date now = new Date(); SisAlarmEvents alarmEvents = new SisAlarmEvents(); alarmEvents.setBigType(EventBigTypeEnum.EQUIPMENT_UP.getCode()); - alarmEvents.setSmallType(EventSmallTypeEnum.SMART_REPORT_ZJCR.getCode()); + alarmEvents.setSmallType(type.getCode()); alarmEvents.setLevel(Long.valueOf(level)); alarmEvents.setDeviceIp(deviceIp); alarmEvents.setDeviceName(sisDeviceManage.getDeviceName()); diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisPersonLibImgServiceImpl.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisPersonLibImgServiceImpl.java index 5ce974c4..6468eeb2 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisPersonLibImgServiceImpl.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisPersonLibImgServiceImpl.java @@ -1,12 +1,14 @@ package org.dromara.sis.service.impl; import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.IdUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.dubbo.config.annotation.DubboReference; +import org.dromara.common.core.constant.CodePrefixConstants; import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.mybatis.core.page.PageQuery; @@ -17,10 +19,12 @@ import org.dromara.sis.domain.bo.SisPersonLibImgBo; import org.dromara.sis.domain.vo.*; import org.dromara.sis.mapper.SisPersonLibImgMapper; import org.dromara.sis.sdk.huawei.HuaWeiBoxApi; +import org.dromara.sis.sdk.huawei.domain.AddHWPersonReq; import org.dromara.sis.service.*; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.security.MessageDigest; import java.util.*; /** @@ -109,9 +113,71 @@ public class SisPersonLibImgServiceImpl implements ISisPersonLibImgService { Assert.notNull(add, "数据处理失败"); boolean flag = baseMapper.insert(add) > 0; Assert.isTrue(flag, "新增数据失败"); + + if (bo.getResidentPersonId() == null){ + try { + bo.setId(add.getId()); + // 记录图片md5值 + byte[] imgByte = remoteFileService.downloadToByteArray(bo.getImgOssId()); + String md5 = calculateMD5(imgByte); + bo.setImgMd5Value(md5); + + AddHWPersonReq req = new AddHWPersonReq(); + req.setIndex(CodePrefixConstants.PERSON_LIB_IMAGE_CODE_PREFIX + IdUtil.getSnowflakeNextIdStr()); + req.setName(bo.getImgName()); + req.setCredentialType("5"); + req.setCredentialNumber(add.getId().toString()); + req.setGender(bo.getSex() == 1 ? "0" : bo.getSex() == 2 ? "1" : "-1"); + + ArrayList pictures = new ArrayList<>(); + pictures.add(Base64.getEncoder().encodeToString(imgByte)); + req.setPictures(pictures); + Long pId = huaWeiBoxApi.addPerson(List.of(req)); + Assert.notNull(pId, "调用华为盒子新增图片失败"); + bo.setRemoteHwId(pId); + this.updateByBo(bo); + } catch (Exception e) { + log.info(e.getMessage()); + } + + + + } + return flag; } + /** + * 直接计算字节数组的MD5值 + * + * @param data 图片的字节数组 + * @return 32位小写MD5字符串 + */ + private String calculateMD5(byte[] data) throws Exception { + if (data == null) { + throw new IllegalArgumentException("输入数据不能为null"); + } + + MessageDigest md = MessageDigest.getInstance("MD5"); + md.update(data); + return bytesToHex(md.digest()); + } + + /** + * 字节数组转十六进制字符串 + * + * @param bytes 字节数组 + * @return 32位十六进制字符串 + */ + private String bytesToHex(byte[] bytes) { + StringBuilder sb = new StringBuilder(); + for (byte b : bytes) { + // %02x 表示两位小写十六进制,不足两位补0 + sb.append(String.format("%02x", b)); + } + return sb.toString(); + } + /** * 修改人像信息 * 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 aeb09875..5eb7e30f 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 @@ -12,6 +12,7 @@ import org.apache.dubbo.config.annotation.DubboReference; import org.dromara.property.api.RemoteFloorService; import org.dromara.property.api.domain.vo.RemoteFloorVo; 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; @@ -62,8 +63,8 @@ public class ZeroSensationPassageServiceImpl implements IZeroSensationPassageSer HWResult result = huaWeiBoxApi.findPerson(smallImgBase64Str); if (result.getCode() != 200) { log.info("华为盒子比对失败,msg={}", result.getMessage()); - // 产生告警数据 - alarmEventsService.createAlarmRecord(deviceIp, 1, 1, "人脸比对失败", smallImg, bigImg); + // 产生告警数据 人脸比对失败,默认为 + alarmEventsService.createAlarmRecord(deviceIp, 2, EventSmallTypeEnum.SMART_REPORT_ZJCR, "人脸比对失败", smallImg, bigImg); return; } log.info("人脸比对执行完成,耗时:{}ms", interval.intervalMs()); @@ -74,19 +75,19 @@ public class ZeroSensationPassageServiceImpl implements IZeroSensationPassageSer if (authRecord == null) { log.info("人员[{}]没有授权记录,判定为陌生人", person); // 不是内部人员 产生紧急的告警信息 - alarmEventsService.createAlarmRecord(deviceIp, 1, 1, "陌生人员入内", smallImg, bigImg); + alarmEventsService.createAlarmRecord(deviceIp, 2, EventSmallTypeEnum.SMART_REPORT_ZJCR, "陌生人员入内", smallImg, bigImg); return; } else { if (Objects.equals(authRecord.getRosterType(), RosterTypeEnum.BLACK_LIST.getCode())) { log.info("人员[{}]在黑名单中,暂不处理。", person); -// alarmEventsService.createAlarmRecord(deviceIp, 3, 1, "黑名单人员入内", smallImg, bigImg); + alarmEventsService.createAlarmRecord(deviceIp, 3, EventSmallTypeEnum.BLACK_PERSON, "黑名单人员入内", smallImg, bigImg); return; } } Date now = new Date(); if (DateUtil.compare(now, authRecord.getEndDate()) > 0) { -// alarmEventsService.createAlarmRecord(deviceIp, 3, 1, "人员授权信息已过期", smallImg, bigImg); + alarmEventsService.createAlarmRecord(deviceIp, 1, EventSmallTypeEnum.AUTHORIZATION_EXPIRED, "人员授权信息已过期", smallImg, bigImg); log.info("当前人脸已过期,暂不处理。"); return; } diff --git a/ruoyi-modules/Sis/src/main/resources/mapper/sis/SisAcDeviceRefMapper.xml b/ruoyi-modules/Sis/src/main/resources/mapper/sis/SisAcDeviceRefMapper.xml index 9119e40f..d533b0fa 100644 --- a/ruoyi-modules/Sis/src/main/resources/mapper/sis/SisAcDeviceRefMapper.xml +++ b/ruoyi-modules/Sis/src/main/resources/mapper/sis/SisAcDeviceRefMapper.xml @@ -7,10 +7,19 @@