diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/ServiceWorkOrdersTypeController.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/ServiceWorkOrdersTypeController.java index 90c08a0b..7c124cde 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/ServiceWorkOrdersTypeController.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/ServiceWorkOrdersTypeController.java @@ -103,4 +103,13 @@ public class ServiceWorkOrdersTypeController extends BaseController { @PathVariable("ids") Long[] ids) { return toAjax(serviceWorkOrdersTypeService.deleteWithValidByIds(List.of(ids), true)); } + + /** + * 查询【工单类型】树结构 + */ + @SaCheckPermission("system:workOrdersType:list") + @GetMapping("/typeTree") + public R> typeTree() { + return R.ok(serviceWorkOrdersTypeService.typeTree()) ; + } } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/TbVisitorManagementController.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/TbVisitorManagementController.java index 3fc2c1e2..bf854706 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/TbVisitorManagementController.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/TbVisitorManagementController.java @@ -70,8 +70,10 @@ public class TbVisitorManagementController extends BaseController { */ @PostMapping("/getcode") public R getcode(QrCodeInfo qrCodeInfo) { - Long string = (Long) StpUtil.getLoginId(); - qrCodeInfo.setUserid(string); + String userid =StpUtil.getLoginId().toString(); + String[] split = userid.split(":"); + Long s1 = Long.valueOf(split[1]); + qrCodeInfo.setUserid(s1); String s = remoteConfigService.selectQrTimeOut(); int i = Integer.parseInt(s); UUID value = UUID.randomUUID(); 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 95677afb..4837b99e 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 @@ -62,4 +62,9 @@ public class ServiceWorkOrdersType extends TenantEntity { */ private String searchValue; + /** + *上级类型id + */ + private Long parentId; + } 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 ab0d9a20..3d7d0ca9 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 @@ -60,4 +60,9 @@ public class ServiceWorkOrdersTypeBo extends BaseEntity { */ private Integer isTransfers; + /** + *上级类型id + */ + private Long parentId; + } 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 b56c3c54..c6c49fab 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 @@ -8,7 +8,8 @@ import org.dromara.property.domain.ServiceWorkOrdersType; import java.io.Serial; import java.io.Serializable; - +import java.util.ArrayList; +import java.util.List; /** @@ -75,4 +76,14 @@ public class ServiceWorkOrdersTypeVo implements Serializable { @ExcelProperty(value = "搜索值") private String searchValue; + /** + * 上级类型id + */ + private Long parentId; + + /** + * 子级类型 + */ + private List children = new ArrayList<>(); + } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/dubbo/RemoteFloorServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/dubbo/RemoteFloorServiceImpl.java index 835f7345..46ea27fa 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/dubbo/RemoteFloorServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/dubbo/RemoteFloorServiceImpl.java @@ -5,17 +5,14 @@ import lombok.extern.slf4j.Slf4j; import org.apache.dubbo.config.annotation.DubboService; import org.dromara.common.core.domain.TreeNode; import org.dromara.common.core.utils.MapstructUtils; -import org.dromara.common.redis.utils.RedisUtils; import org.dromara.property.api.RemoteFloorService; import org.dromara.property.api.domain.vo.RemoteFloorVo; 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.domain.vo.TbUnitVo; import org.dromara.property.service.ITbBuildingService; import org.dromara.property.service.ITbCommunityService; import org.dromara.property.service.ITbFloorService; -import org.dromara.property.service.ITbUnitService; import java.util.ArrayList; import java.util.List; @@ -32,7 +29,6 @@ public class RemoteFloorServiceImpl implements RemoteFloorService { private final ITbCommunityService tbCommunityService; private final ITbBuildingService tbBuildingService; - private final ITbUnitService unitService; private final ITbFloorService floorService; @Override @@ -72,20 +68,6 @@ public class RemoteFloorServiceImpl implements RemoteFloorService { return node; }).toList(); treeList.addAll(l2); - - List tbUnitVos = unitService.queryAll(); - if (tbUnitVos == null || tbUnitVos.isEmpty()) { - return treeList; - } - List> l3 = tbUnitVos.stream().map(item -> { - TreeNode node = new TreeNode<>(); - node.setLevel(3); - node.setCode(item.getId()); - node.setParentCode(item.getBuildingId()); - node.setLabel(item.getUnitName()); - return node; - }).toList(); - treeList.addAll(l3); List tbFloorVos = floorService.queryAll(); if (tbFloorVos == null || tbFloorVos.isEmpty()) { return treeList; @@ -94,7 +76,7 @@ public class RemoteFloorServiceImpl implements RemoteFloorService { TreeNode node = new TreeNode<>(); node.setLevel(4); node.setCode(item.getId()); - node.setParentCode(item.getUnitId()); + node.setParentCode(item.getBuildingId()); node.setLabel(item.getFloorName()); return node; }).toList(); @@ -109,7 +91,7 @@ public class RemoteFloorServiceImpl implements RemoteFloorService { * @return 楼层 */ @Override - public List queryByBuildingId(Long buildingId){ + public List queryByBuildingId(Long buildingId) { List tbFloorVo = floorService.queryByBuildingId(buildingId); List remoteFloorVos = new ArrayList<>(); diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/IServiceWorkOrdersTypeService.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/IServiceWorkOrdersTypeService.java index a838a21e..a578ced8 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/IServiceWorkOrdersTypeService.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/IServiceWorkOrdersTypeService.java @@ -65,4 +65,10 @@ public interface IServiceWorkOrdersTypeService { * @return 是否删除成功 */ Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 查询【工单类型】树结构 + * @return 工单类型树结构 + */ + List typeTree(); } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceArrangementServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceArrangementServiceImpl.java index 5a45e370..b57b6b20 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceArrangementServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/AttendanceArrangementServiceImpl.java @@ -2,6 +2,7 @@ package org.dromara.property.service.impl; import cn.hutool.core.date.DateUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.RequiredArgsConstructor; @@ -44,6 +45,7 @@ public class AttendanceArrangementServiceImpl implements IAttendanceArrangementS private final AttendanceGroupMapper attendanceGroupMapper; + // private final AttendanceArrangementGroupMapper arrangementGroupMapper; private final AttendanceWeekSetMapper weekSetMapper; @@ -125,7 +127,7 @@ public class AttendanceArrangementServiceImpl implements IAttendanceArrangementS vo.setShift(attendanceShift); - }else if (Objects.equals(attendanceGroup.getAttendanceType(), StatusConstant.SHIFTSCHEDULE)) { + } else if (Objects.equals(attendanceGroup.getAttendanceType(), StatusConstant.SHIFTSCHEDULE)) { //3.2排班制 //将startDate作为第一天,endDate作为最后一天,循环判断当前日期是第几天,取出当前天数的班次信息。 @@ -163,7 +165,6 @@ public class AttendanceArrangementServiceImpl implements IAttendanceArrangementS } - //根据cycleDay查询出当前日期的班次信息 AttendanceScheduleCycle cycle = scheduleCycleMapper.selectOne(Wrappers.lambdaQuery().eq(AttendanceScheduleCycle::getGroupId, groupId).eq(AttendanceScheduleCycle::getDayNumber, cycleDay)); //将cycle存到vo中 @@ -260,85 +261,153 @@ public class AttendanceArrangementServiceImpl implements IAttendanceArrangementS public TableDataInfo queryList(AttendanceArrangementBo bo) { LocalDate month = bo.getMonth().atEndOfMonth(); - // 1. 拿到日历的开始时间和结束时间 LocalDate calendarStartDate = month.withDayOfMonth(1); LocalDate calendarEndDate = month.withDayOfMonth(calendarStartDate.lengthOfMonth()); - // 2. 根据日历的开始时间和结束时间查询出每一天的排班信息 - // 2.1 循环日历的开始时间和结束时间,判断 calendarStartDate 在哪些排班中 - List result = new ArrayList<>(); + //使用mybatisplus的between查询在calendarStartDate和calendarEndDate之间的排班信息 + List startResult = baseMapper.selectVoList(Wrappers.lambdaQuery() + .between(AttendanceArrangement::getStartDate, calendarStartDate.atStartOfDay(ZoneId.systemDefault()).toInstant(), + calendarEndDate.atStartOfDay(ZoneId.systemDefault()).plusDays(1).toInstant().minusSeconds(1))); + //查询结束时间在calendarStartDate和calendarEndDate之间的排班信息 + List endResult = baseMapper.selectList(Wrappers.lambdaQuery() + .between(AttendanceArrangement::getEndDate, calendarStartDate.atStartOfDay(ZoneId.systemDefault()).toInstant(), + calendarEndDate.atStartOfDay(ZoneId.systemDefault()).plusDays(1).toInstant().minusSeconds(1))); - for (LocalDate date = calendarStartDate; date.isBefore(calendarEndDate); date = date.plusDays(1)) { - // 2.2 根据当前日期查询在开始时间和结束时间之间的排班信息 - //查询当前日期在哪些排班中,当前日期大于等于排班开始日期,小于等于排班结束日期 - // 查询指定日期在哪些排班中 - List arrangementList = baseMapper.selectList( - Wrappers.lambdaQuery() - .between(AttendanceArrangement::getStartDate, date.atStartOfDay(ZoneId.systemDefault()).toInstant(), - date.atStartOfDay(ZoneId.systemDefault()).plusDays(1).toInstant().minusSeconds(1))); + //合并两个list,并去重 + List result = new ArrayList<>(startResult.stream().distinct().toList()); + result.addAll(endResult.stream().map(vo -> { + AttendanceArrangementVo newVo = MapstructUtils.convert(vo, AttendanceArrangementVo.class); + newVo.setStartDate(vo.getStartDate()); + newVo.setEndDate(vo.getEndDate()); + return newVo; + }).toList()); -// //根据arrangementList查询出排班的id -// List scheduleIdList = arrangementList.stream().map(AttendanceArrangement::getId).toList(); -// //根据排班的id查询出排班的人员详细信息 -// List userGroupList = userGroupMapper.selectList(Wrappers.lambdaQuery().in(AttendanceUserGroup::getScheduleId, scheduleIdList)); + //去掉result中id重复的排班信息 + result = result.stream().distinct().toList(); - - // 根据排班查询出考勤组id - List groupIds = arrangementList.stream() - .map(AttendanceArrangement::getGroupId) - .distinct() - .toList(); - - // 如果当前日期没有排班,则跳过当前日期 - if (groupIds.isEmpty()) { - continue; - } - - // 循环 groupIds,循环和 AttendanceGroup 中的 id 做对比,如果有相同的,则取出 attendanceGroup 中的所有数据 - for (Long groupId : groupIds) { - AttendanceGroup attendanceGroup = attendanceGroupMapper.selectById(groupId); - if (attendanceGroup != null) { - // 创建 AttendanceArrangementVo 对象并设置属性 - AttendanceArrangementVo vo = new AttendanceArrangementVo(); - vo.setId(arrangementList.get(0).getId()); - vo.setStartDate(arrangementList.get(0).getStartDate()); - vo.setEndDate(arrangementList.get(0).getEndDate()); - - //获取到第一个排班的id - Long arrangementId = arrangementList.get(0).getId(); - //根据arrangementId查询出人员组的详细信息 - AttendanceGroup group = attendanceGroupMapper.selectById(arrangementId); - //将group存到vo中 - vo.setAttendanceGroup(group); - - //根据arrangementList查询出排班的id - List scheduleIdList = arrangementList.stream().map(AttendanceArrangement::getId).distinct().toList(); - //根据排班的id查询出排班的人员详细信息 - List userGroupList = userGroupMapper.selectList(Wrappers.lambdaQuery().in(AttendanceUserGroup::getScheduleId, scheduleIdList)); - - - //新建attendanceGroup对象,将排班信息和考勤组信息添加到vo中 - vo.setAttendanceGroup(attendanceGroup); - //将排班人员信息添加到排班信息中 - vo.setUserGroupList(userGroupList); - - result.add(vo); + //根据排班查询出考勤组id + List groupIds = result.stream().map(AttendanceArrangementVo::getGroupId).distinct().toList(); + // 循环 groupIds,循环和 AttendanceGroup 中的 id 做对比,如果有相同的,则取出 attendanceGroup 中的所有数据 + for (Long groupId : groupIds) { + AttendanceGroup attendanceGroup = attendanceGroupMapper.selectById(groupId); + if (attendanceGroup != null) { + // 循环排班列表,将排班信息和考勤组信息添加到vo中 + for (AttendanceArrangementVo vo : result) { + if (vo.getGroupId().equals(groupId)) { + vo.setAttendanceGroup(attendanceGroup); + } } } + } + + // 循环排班列表,查询排班人员信息 + for (AttendanceArrangementVo vo : result) { + // 根据排班查询出人员组的详细信息 + List userGroupList = userGroupMapper.selectList(Wrappers.lambdaQuery().eq(AttendanceUserGroup::getScheduleId, vo.getId())); + // 将排班人员信息添加到排班信息中 + vo.setUserGroupList(userGroupList); } + +// LocalDate month = bo.getMonth().atEndOfMonth(); +// // 1. 拿到日历的开始时间和结束时间 +// LocalDate calendarStartDate = month.withDayOfMonth(1); +// LocalDate calendarEndDate = month.withDayOfMonth(calendarStartDate.lengthOfMonth()); +// +// // 2. 根据日历的开始时间和结束时间查询出每一天的排班信息 +// // 2.1 循环日历的开始时间和结束时间,判断 calendarStartDate 在哪些排班中 +// List result = new ArrayList<>(); +// +// +// //查询所有排班信息 +// List arrangementList1 = baseMapper.selectList(); +// //取出排班的开始时间和结束时间 +// List startDateList = arrangementList1.stream().map(AttendanceArrangement::getStartDate).toList(); +// List endDateList = arrangementList1.stream().map(AttendanceArrangement::getEndDate).toList(); +// +// int count = 0; +// +// for (LocalDate date = calendarStartDate; date.isBefore(calendarEndDate); date = date.plusDays(1)) { +// // 2.2 根据当前日期查询在开始时间和结束时间之间的排班信息 +// //查询当前日期在哪些排班中,当前日期大于等于排班开始日期,小于等于排班结束日期 +// +// if (count >= startDateList.size() || count >= endDateList.size()){ +// continue; +// } +// +// +// +//// // 查询指定日期在哪些排班中 +//// List arrangementList = baseMapper.selectList( +//// Wrappers.lambdaQuery() +//// .between(AttendanceArrangement::getStartDate, date.atStartOfDay(ZoneId.systemDefault()).toInstant(), +//// date.atStartOfDay(ZoneId.systemDefault()).plusDays(1).toInstant().minusSeconds(1))); +// +// +// // 查询指定日期在哪些排班中 +// List arrangementList = baseMapper.selectList( +// Wrappers.lambdaQuery() +// .between(AttendanceArrangement::getStartDate, startDateList.get(count).atStartOfDay(ZoneId.systemDefault()).toInstant(), +// endDateList.get(count).atStartOfDay(ZoneId.systemDefault()).plusDays(1).toInstant().minusSeconds(1))); +// +// +// +// +//// //根据arrangementList查询出排班的id +//// List scheduleIdList = arrangementList.stream().map(AttendanceArrangement::getId).toList(); +//// //根据排班的id查询出排班的人员详细信息 +//// List userGroupList = userGroupMapper.selectList(Wrappers.lambdaQuery().in(AttendanceUserGroup::getScheduleId, scheduleIdList)); +// +// +// // 根据排班查询出考勤组id +// List groupIds = arrangementList.stream() +// .map(AttendanceArrangement::getGroupId) +// .distinct() +// .toList(); +// +// // 如果当前日期没有排班,则跳过当前日期 +// if (groupIds.isEmpty()) { +// count++; +// continue; +// } +// +// // 循环 groupIds,循环和 AttendanceGroup 中的 id 做对比,如果有相同的,则取出 attendanceGroup 中的所有数据 +// for (Long groupId : groupIds) { +// AttendanceGroup attendanceGroup = attendanceGroupMapper.selectById(groupId); +// if (attendanceGroup != null) { +// // 创建 AttendanceArrangementVo 对象并设置属性 +// AttendanceArrangementVo vo = new AttendanceArrangementVo(); +// vo.setId(arrangementList.get(0).getId()); +// vo.setStartDate(arrangementList.get(0).getStartDate()); +// vo.setEndDate(arrangementList.get(0).getEndDate()); +// +// //获取到第一个排班的id +// Long arrangementId = arrangementList.get(0).getId(); +// //根据arrangementId查询出人员组的详细信息 +// AttendanceGroup group = attendanceGroupMapper.selectById(arrangementId); +// //将group存到vo中 +// vo.setAttendanceGroup(group); +// +// //根据arrangementList查询出排班的id +// List scheduleIdList = arrangementList.stream().map(AttendanceArrangement::getId).distinct().toList(); +// //根据排班的id查询出排班的人员详细信息 +// List userGroupList = userGroupMapper.selectList(Wrappers.lambdaQuery().in(AttendanceUserGroup::getScheduleId, scheduleIdList)); +// +// +// //新建attendanceGroup对象,将排班信息和考勤组信息添加到vo中 +// vo.setAttendanceGroup(attendanceGroup); +// //将排班人员信息添加到排班信息中 +// vo.setUserGroupList(userGroupList); +// +// result.add(vo); +// } +// } +// +// count++; +// } return TableDataInfo.build(result); -// // 计算交集的开始时间(取较晚的开始时间)和结束时间(取较早的结束时间) -// Date overlapStart = calendarStartDate.after(startDate) -// ? calendarStartDate : startDate; -// Date overlapEnd = calendarEndTimeDate.before(endDate) -// ? calendarEndTimeDate : endDate; - - //根据交集的时间范围查询排班信息 - - } 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 ca7db910..4256baea 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 @@ -18,6 +18,7 @@ import org.dromara.property.service.IServiceWorkOrdersTypeService; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Collection; @@ -138,4 +139,35 @@ public class ServiceWorkOrdersTypeServiceImpl implements IServiceWorkOrdersTypeS } return baseMapper.deleteByIds(ids) > 0; } + + /** + * 查询【工单类型】树结构 + * @return 工单类型树结构 + */ + @Override + public List typeTree() { + List list = baseMapper.selectVoList(); + return buildTree(list,null); + } + + + /** + * 递归构建树结构 + * @param types 所有类型列表 + * @param parentId 父节点id + * @return 树结构列表 + */ + public static List buildTree(List types, Long parentId) { + List tree = new ArrayList<>(); + for (ServiceWorkOrdersTypeVo type : types) { + Long currentParentId = type.getParentId(); + if ((parentId == null && currentParentId == null) || + (parentId != null && parentId.equals(currentParentId))) { + List children = buildTree(types, type.getId()); + type.getChildren().addAll(children); + tree.add(type); + } + } + return tree; + } } diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/SisAcDeviceRef.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/SisAcDeviceRef.java new file mode 100644 index 00000000..18302933 --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/SisAcDeviceRef.java @@ -0,0 +1,40 @@ +package org.dromara.sis.domain; + +import org.dromara.common.tenant.core.TenantEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; + +/** + * 门禁⇄监控点关联对象 sis_ac_device_ref + * + * @author lxj + * @date 2025-08-05 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("sis_ac_device_ref") +public class SisAcDeviceRef extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * + */ + @TableId(value = "id") + private Long id; + + /** + * 门禁设备id + */ + private Long acId; + + /** + * 监控点设备id + */ + private Long dpId; + +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/bo/SisAcDeviceRefBo.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/bo/SisAcDeviceRefBo.java new file mode 100644 index 00000000..789cbc30 --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/bo/SisAcDeviceRefBo.java @@ -0,0 +1,42 @@ +package org.dromara.sis.domain.bo; + +import io.github.linpeilie.annotations.AutoMapper; +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.sis.domain.SisAcDeviceRef; + +/** + * 门禁⇄监控点关联业务对象 sis_ac_device_ref + * + * @author lxj + * @date 2025-08-05 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = SisAcDeviceRef.class, reverseConvertGenerate = false) +public class SisAcDeviceRefBo extends BaseEntity { + + /** + * + */ + @NotNull(message = "不能为空", groups = {EditGroup.class}) + private Long id; + + /** + * 门禁设备id + */ + @NotNull(message = "门禁设备id不能为空", groups = {AddGroup.class, EditGroup.class}) + private Long acId; + + /** + * 监控点设备id + */ + @NotNull(message = "监控点设备id不能为空", groups = {AddGroup.class, EditGroup.class}) + private Long dpId; + + +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/bo/SisAccessControlBo.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/bo/SisAccessControlBo.java index 877395fb..970b7dd4 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/bo/SisAccessControlBo.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/bo/SisAccessControlBo.java @@ -10,6 +10,8 @@ import org.dromara.common.core.validate.EditGroup; import org.dromara.common.mybatis.core.domain.BaseEntity; import org.dromara.sis.domain.SisAccessControl; +import java.util.List; + /** * 门禁设备业务对象 sis_access_control * @@ -104,4 +106,9 @@ public class SisAccessControlBo extends BaseEntity { */ private Long bindDeviceId; + /** + * 监控点列表 + */ + private List devicePoint; + } 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 new file mode 100644 index 00000000..22088fbb --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/model/SisAcDevice.java @@ -0,0 +1,13 @@ +package org.dromara.sis.domain.model; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.sis.domain.SisDeviceManage; + +@EqualsAndHashCode(callSuper = true) +@Data +public class SisAcDevice extends SisDeviceManage { + + private Long acId; + +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/vo/SisAcDeviceRefVo.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/vo/SisAcDeviceRefVo.java new file mode 100644 index 00000000..b80d5a73 --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/domain/vo/SisAcDeviceRefVo.java @@ -0,0 +1,50 @@ +package org.dromara.sis.domain.vo; + +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import org.dromara.common.excel.annotation.ExcelDictFormat; +import org.dromara.common.excel.convert.ExcelDictConvert; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import org.dromara.sis.domain.SisAcDeviceRef; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + + + +/** + * 门禁⇄监控点关联视图对象 sis_ac_device_ref + * + * @author lxj + * @date 2025-08-05 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = SisAcDeviceRef.class) +public class SisAcDeviceRefVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * + */ + @ExcelProperty(value = "") + private Long id; + + /** + * 门禁设备id + */ + @ExcelProperty(value = "门禁设备id") + private Long acId; + + /** + * 监控点设备id + */ + @ExcelProperty(value = "监控点设备id") + private Long dpId; + + +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/mapper/SisAcDeviceRefMapper.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/mapper/SisAcDeviceRefMapper.java new file mode 100644 index 00000000..799b9aaa --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/mapper/SisAcDeviceRefMapper.java @@ -0,0 +1,25 @@ +package org.dromara.sis.mapper; + +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; +import org.dromara.sis.domain.SisAcDeviceRef; +import org.dromara.sis.domain.model.SisAcDevice; +import org.dromara.sis.domain.vo.SisAcDeviceRefVo; + +import java.util.List; + +/** + * 门禁⇄监控点关联Mapper接口 + * + * @author lxj + * @date 2025-08-05 + */ +public interface SisAcDeviceRefMapper extends BaseMapperPlus { + + /** + * 通过门禁id列表查询设备信息 + * + * @param acIds 门禁设备id + * @return 查询数据 + */ + List queryByAcIds(List acIds); +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/huawei/HuaWeiBoxApi.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/huawei/HuaWeiBoxApi.java index 8abea6e4..c99b6069 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/huawei/HuaWeiBoxApi.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/huawei/HuaWeiBoxApi.java @@ -36,5 +36,5 @@ public interface HuaWeiBoxApi { * @param base64Img 入参 * @return Map */ - HWResult findPerson(String base64Img); + HWResult findPerson(String base64Img); } diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/huawei/domain/HWResult.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/huawei/domain/HWResult.java index f4c27163..a30b7884 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/huawei/domain/HWResult.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/huawei/domain/HWResult.java @@ -10,9 +10,12 @@ import lombok.Data; */ @Data @AllArgsConstructor -public class HWResult { +public class HWResult { public Integer code; public String message; + + public T data; + } diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/huawei/service/HuaWeiBoxApiService.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/huawei/service/HuaWeiBoxApiService.java index 2613406b..77ed048e 100644 --- a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/huawei/service/HuaWeiBoxApiService.java +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/huawei/service/HuaWeiBoxApiService.java @@ -13,9 +13,7 @@ import org.dromara.sis.sdk.huawei.utils.HuaWeiHttp; import org.springframework.stereotype.Service; import java.util.Collection; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.stream.Collectors; /** @@ -89,7 +87,7 @@ public class HuaWeiBoxApiService implements HuaWeiBoxApi { * @return Long */ @Override - public HWResult findPerson(String base64Img) { + public HWResult findPerson(String base64Img) { String url = "/sdk_service/rest/facerepositories/peoples"; FinaHWPersonReq req = new FinaHWPersonReq(); @@ -103,9 +101,9 @@ public class HuaWeiBoxApiService implements HuaWeiBoxApi { if (jsonRes.getInt("resultCode") != 0) { return switch (jsonRes.getInt("resultCode")) { - case 912322041 -> new HWResult(912322041, "特征值提取失败"); - case 912333003 -> new HWResult(912333003, "base64参数非法"); - default -> new HWResult(jsonRes.getInt("resultCode"), jsonRes.getStr("resultMsg")); + case 912322041 -> new HWResult<>(912322041, "特征值提取失败", 0L); + case 912333003 -> new HWResult<>(912333003, "base64参数非法", 0L); + default -> new HWResult<>(jsonRes.getInt("resultCode"), jsonRes.getStr("resultMsg"), 0L); }; } @@ -114,12 +112,12 @@ public class HuaWeiBoxApiService implements HuaWeiBoxApi { if (Integer.parseInt(obj.getStr("number")) == 0) { log.info("无人脸比对数据"); - return new HWResult(201, "无匹配数据"); + return new HWResult<>(201, "无人脸比对数据", 0L); } JSONArray peopleList = obj.getJSONArray("peopleList"); JSONObject people = peopleList.getJSONObject(0); - return new HWResult(200, people.getStr("peopleId")); + return new HWResult<>(200, "ok", people.getLong("peopleId")); } } diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/ISisAcDeviceRefService.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/ISisAcDeviceRefService.java new file mode 100644 index 00000000..86b00b93 --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/ISisAcDeviceRefService.java @@ -0,0 +1,94 @@ +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.SisAcDeviceRef; +import org.dromara.sis.domain.SisDeviceManage; +import org.dromara.sis.domain.bo.SisAcDeviceRefBo; +import org.dromara.sis.domain.model.SisAcDevice; +import org.dromara.sis.domain.vo.SisAcDeviceRefVo; + +import java.util.Collection; +import java.util.List; + +/** + * 门禁⇄监控点关联Service接口 + * + * @author lxj + * @date 2025-08-05 + */ +public interface ISisAcDeviceRefService { + + /** + * 查询门禁⇄监控点关联 + * + * @param id 主键 + * @return 门禁⇄监控点关联 + */ + SisAcDeviceRefVo queryById(Long id); + + /** + * 分页查询门禁⇄监控点关联列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 门禁⇄监控点关联分页列表 + */ + TableDataInfo queryPageList(SisAcDeviceRefBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的门禁⇄监控点关联列表 + * + * @param bo 查询条件 + * @return 门禁⇄监控点关联列表 + */ + List queryList(SisAcDeviceRefBo bo); + + /** + * 新增门禁⇄监控点关联 + * + * @param bo 门禁⇄监控点关联 + * @return 是否新增成功 + */ + Boolean insertByBo(SisAcDeviceRefBo bo); + + /** + * 修改门禁⇄监控点关联 + * + * @param bo 门禁⇄监控点关联 + * @return 是否修改成功 + */ + Boolean updateByBo(SisAcDeviceRefBo bo); + + /** + * 校验并批量删除门禁⇄监控点关联信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 通过 门禁设备id 删除 门禁和设备的关联关系 + * + * @param acId 门禁设备id + * @return 是否删除成功 + */ + Boolean deleteByAcId(Long acId); + + /** + * 批量写入关联关系 + * + * @param refs 写入数据 + * @return 返回是否写入成功 + */ + Boolean batchInsert(List refs); + + /** + * 通过acids查询关联记录 + * @param acIds 门禁id列表 + * @return 返回查询数据 + */ + List queryByAcIds(List acIds); +} 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 c6f05eef..5184d126 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 @@ -69,6 +69,6 @@ public interface ISisAlarmEventsService { /** * 异步生成告警记录 */ - void createAlarmRecord(String deviceIp, Integer level, Integer type, byte[] smallImg, byte[] bigImg); + void createAlarmRecord(String deviceIp, Integer level, Integer type, String msg, byte[] smallImg, byte[] bigImg); } diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisAcDeviceRefServiceImpl.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisAcDeviceRefServiceImpl.java new file mode 100644 index 00000000..74b05459 --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/service/impl/SisAcDeviceRefServiceImpl.java @@ -0,0 +1,151 @@ +package org.dromara.sis.service.impl; + +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.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.sis.domain.SisAcDeviceRef; +import org.dromara.sis.domain.SisDeviceManage; +import org.dromara.sis.domain.bo.SisAcDeviceRefBo; +import org.dromara.sis.domain.model.SisAcDevice; +import org.dromara.sis.domain.vo.SisAcDeviceRefVo; +import org.dromara.sis.mapper.SisAcDeviceRefMapper; +import org.dromara.sis.service.ISisAcDeviceRefService; +import org.springframework.stereotype.Service; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * 门禁⇄监控点关联Service业务层处理 + * + * @author lxj + * @date 2025-08-05 + */ +@Slf4j +@RequiredArgsConstructor +@Service +public class SisAcDeviceRefServiceImpl implements ISisAcDeviceRefService { + + private final SisAcDeviceRefMapper baseMapper; + + /** + * 查询门禁⇄监控点关联 + * + * @param id 主键 + * @return 门禁⇄监控点关联 + */ + @Override + public SisAcDeviceRefVo queryById(Long id) { + return baseMapper.selectVoById(id); + } + + /** + * 分页查询门禁⇄监控点关联列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 门禁⇄监控点关联分页列表 + */ + @Override + public TableDataInfo queryPageList(SisAcDeviceRefBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的门禁⇄监控点关联列表 + * + * @param bo 查询条件 + * @return 门禁⇄监控点关联列表 + */ + @Override + public List queryList(SisAcDeviceRefBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(SisAcDeviceRefBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.orderByAsc(SisAcDeviceRef::getId); + lqw.eq(bo.getAcId() != null, SisAcDeviceRef::getAcId, bo.getAcId()); + lqw.eq(bo.getDpId() != null, SisAcDeviceRef::getDpId, bo.getDpId()); + return lqw; + } + + /** + * 新增门禁⇄监控点关联 + * + * @param bo 门禁⇄监控点关联 + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(SisAcDeviceRefBo bo) { + SisAcDeviceRef add = MapstructUtils.convert(bo, SisAcDeviceRef.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setId(add.getId()); + } + return flag; + } + + /** + * 修改门禁⇄监控点关联 + * + * @param bo 门禁⇄监控点关联 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(SisAcDeviceRefBo bo) { + SisAcDeviceRef update = MapstructUtils.convert(bo, SisAcDeviceRef.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(SisAcDeviceRef entity) { + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除门禁⇄监控点关联信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if (isValid) { + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } + + @Override + public Boolean deleteByAcId(Long acId) { + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(SisAcDeviceRef::getAcId, acId); + return baseMapper.delete(lqw) > 0; + } + + @Override + public Boolean batchInsert(List refs) { + return baseMapper.insertBatch(refs); + } + + @Override + public List queryByAcIds(List acIds) { + return baseMapper.queryByAcIds(acIds); + } +} 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 07a780c1..01b6f66d 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 @@ -1,5 +1,6 @@ package org.dromara.sis.service.impl; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -15,16 +16,19 @@ import org.dromara.common.core.utils.TreeUtils; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.property.api.RemoteFloorService; +import org.dromara.sis.domain.SisAcDeviceRef; import org.dromara.sis.domain.SisAccessControl; import org.dromara.sis.domain.SisDeviceBindRef; import org.dromara.sis.domain.bo.SisAccessControlBo; import org.dromara.sis.domain.enums.ControlTypeEnum; +import org.dromara.sis.domain.model.SisAcDevice; import org.dromara.sis.domain.vo.SisAccessControlVo; import org.dromara.sis.domain.vo.SisDeviceManageVo; import org.dromara.sis.mapper.SisAccessControlMapper; import org.dromara.sis.sdk.e8.E8PlatformApi; import org.dromara.sis.sdk.e8.domain.accessControl.req.RemoteOpenDoorReq; import org.dromara.sis.sdk.e8.domain.door.res.AuthDoorDeviceFindRes; +import org.dromara.sis.service.ISisAcDeviceRefService; import org.dromara.sis.service.ISisAccessControlService; import org.dromara.sis.service.ISisDeviceBindRefService; import org.dromara.sis.service.ISisDeviceManageService; @@ -51,6 +55,7 @@ public class SisAccessControlServiceImpl implements ISisAccessControlService { private final E8PlatformApi e8PlatformApi; private final ISisDeviceManageService sisDeviceManageService; private final ISisDeviceBindRefService sisDeviceBindRefService; + private final ISisAcDeviceRefService sisAcDeviceRefService; @DubboReference private RemoteFloorService remoteFloorService; @@ -135,10 +140,12 @@ public class SisAccessControlServiceImpl implements ISisAccessControlService { @Transactional(rollbackFor = Exception.class) public Boolean updateByBo(SisAccessControlBo bo) { SisAccessControl update = MapstructUtils.convert(bo, SisAccessControl.class); - sisDeviceBindRefService.deleteByBindId(bo.getId()); + boolean b = baseMapper.updateById(update) > 0; if (bo.getBindDeviceId() != null) { + // 检验设备是否存在 SisDeviceManageVo sisDeviceManageVo = sisDeviceManageService.queryById(bo.getBindDeviceId()); + Assert.isTrue(sisDeviceManageVo != null, "设备-{}信息不存在.", bo.getBindDeviceId()); // 写入关联关系表中 SisDeviceBindRef sisDeviceBindRef = new SisDeviceBindRef(); sisDeviceBindRef.setDeviceId(sisDeviceManageVo.getId()); @@ -146,11 +153,33 @@ public class SisAccessControlServiceImpl implements ISisAccessControlService { sisDeviceBindRef.setDeviceFloorId(sisDeviceManageVo.getFloorId()); sisDeviceBindRef.setBindId(bo.getId()); sisDeviceBindRef.setControlType(ControlTypeEnum.ACCESS_CONTROL.getCode()); + // 删除绑定关系 + sisDeviceBindRefService.deleteByBindId(bo.getId()); + // 重新构建绑定关系 Boolean insert = sisDeviceBindRefService.insert(sisDeviceBindRef); Assert.isTrue(insert, "写入设备关联表失败!"); } - return baseMapper.updateById(update) > 0; + if (CollUtil.isNotEmpty(bo.getDevicePoint())) { + // 检测设备是否存在 + List refs = new ArrayList<>(bo.getDevicePoint().size()); + bo.getDevicePoint().forEach(devicePoint -> { + // 暂时放弃设备校验 +// SisDeviceManageVo sisDeviceManageVo = sisDeviceManageService.queryById(bo.getBindDeviceId()); +// Assert.isTrue(sisDeviceManageVo != null, "设备-{}信息不存在.", bo.getBindDeviceId()); + SisAcDeviceRef ref = new SisAcDeviceRef(); + ref.setAcId(bo.getId()); + ref.setDpId(devicePoint); + refs.add(ref); + }); + // 删除原始的关联关系 + Boolean b1 = sisAcDeviceRefService.deleteByAcId(bo.getId()); + log.info("门禁-监控关联关系删除完成, result={}, acId={}", b1, bo.getId()); + // 构建新的关联关系 + Boolean b2 = sisAcDeviceRefService.batchInsert(refs); + log.info("门禁-监控设备关联关系构建完成, result={}", b2); + } + return b; } /** @@ -189,7 +218,9 @@ public class SisAccessControlServiceImpl implements ISisAccessControlService { // 查询所有的门禁 List sisAccessControlVos = baseMapper.selectVoList(); if (sisAccessControlVos != null && !sisAccessControlVos.isEmpty()) { + List acIds = new ArrayList<>(sisAccessControlVos.size()); List> l1 = sisAccessControlVos.stream().map(item -> { + acIds.add(item.getId()); TreeNode node = new TreeNode<>(); node.setLevel(5); node.setCode(item.getId()); @@ -198,6 +229,18 @@ public class SisAccessControlServiceImpl implements ISisAccessControlService { return node; }).toList(); treeNodes.addAll(l1); + + // 查询所有的监控点 + List refs = sisAcDeviceRefService.queryByAcIds(acIds); + List> l2 = refs.stream().map(item -> { + TreeNode node = new TreeNode<>(); + node.setLevel(6); + node.setCode(item.getId()); + node.setParentCode(item.getAcId()); + node.setLabel(item.getDeviceName()); + return node; + }).toList(); + treeNodes.addAll(l2); } return TreeUtils.build(treeNodes, 0L); } 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 f0ed7bbc..9427887f 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 @@ -151,7 +151,7 @@ public class SisAlarmEventsServiceImpl implements ISisAlarmEventsService { @Async @Override @Transactional(rollbackFor = Exception.class) - public void createAlarmRecord(String deviceIp, Integer level, Integer type, byte[] smallImg, byte[] bigImg) { + public void createAlarmRecord(String deviceIp, Integer level, Integer type,String msg, byte[] smallImg, byte[] bigImg) { // 校验设备信息 SisDeviceManage sisDeviceManage = deviceManageService.queryByDeviceIp(deviceIp); if (sisDeviceManage == null) { 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 927d7388..c4aa0f75 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 @@ -14,6 +14,7 @@ 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.service.*; import org.springframework.stereotype.Service; @@ -52,30 +53,35 @@ public class ZeroSensationPassageServiceImpl implements IZeroSensationPassageSer TimeInterval interval = new TimeInterval(); // 抓拍小图 String smallImgBase64Str = Base64Encoder.encode(smallImg); - Long person = huaWeiBoxApi.findPerson(smallImgBase64Str); - log.info("人脸比对执行完成,耗时:{}ms", interval); - if (person == null) { - log.info("未命中人脸数据,暂不处理。"); + HWResult result = huaWeiBoxApi.findPerson(smallImgBase64Str); + if (result.getCode() == 0) { + log.info("华为盒子比对失败,msg={}", result.getMessage()); + // 产生告警数据 + alarmEventsService.createAlarmRecord(deviceIp, 1, 1, "人脸比对失败", smallImg, bigImg); return; } + log.info("人脸比对执行完成,耗时:{}ms", interval.intervalMs()); + Long person = result.getData(); // 验证当前人原是否存在授权记录 SisAuthRecordVo authRecord = authRecordService.checkAuth(person); - log.info("查询人员权限记录完成,耗时={}ms", interval.interval()); + log.info("查询人员权限记录完成,耗时={}ms", interval.intervalMs()); if (authRecord == null) { - // todo 产生高危告警记录 - log.info("当前人脸未授权,暂不处理。"); - return; - } - Date now = new Date(); - if (DateUtil.compare(now, authRecord.getEndDate()) > 0) { - // todo 生成一般告警记录 - log.info("当前人脸已过期,暂不处理。"); + log.info("人员[{}]没有授权记录,判定为陌生人", person); + // 不是内部人员 产生紧急的告警信息 + alarmEventsService.createAlarmRecord(deviceIp, 1, 1, "陌生人员入内", smallImg, bigImg); return; } + Date now = new Date(); + if (DateUtil.compare(now, authRecord.getEndDate()) > 0) { + alarmEventsService.createAlarmRecord(deviceIp, 3, 1, "人员授权信息已过期", smallImg, bigImg); + log.info("当前人脸已过期,暂不处理。"); + return; + } // 获取当前设备的绑定设备信息 List bindRefList = deviceBindRefService.queryByDeviceIp(deviceIp); - log.info("查询设备绑定的梯控/门禁完成,耗时={}ms", interval.interval()); + log.info("查询设备绑定的梯控/门禁完成,耗时={}ms", interval.intervalMs()); + if (CollUtil.isEmpty(bindRefList)) { log.info("当前报警设备未绑定门禁/梯控,不做处理!"); return; @@ -106,14 +112,14 @@ public class ZeroSensationPassageServiceImpl implements IZeroSensationPassageSer log.info("设备绑定了未知的控制类型[{}],不处理", item.getControlType()); } }); - log.info("权限下发执行完成,耗时:{}ms", interval.interval()); + log.info("权限下发执行完成,耗时:{}ms", interval.intervalMs()); } /** * 生成告警事件 */ - public void createAlarmRecord(String deviceIp, Integer level, Integer type, byte[] smallImg, byte[] bigImg) { - alarmEventsService.createAlarmRecord(deviceIp, level, type, smallImg, bigImg); + public void createAlarmRecord(String deviceIp, Integer level, Integer type, String msg, byte[] smallImg, byte[] bigImg) { + alarmEventsService.createAlarmRecord(deviceIp, level, type, msg, smallImg, bigImg); } /** diff --git a/ruoyi-modules/Sis/src/main/resources/mapper/sis/SisAcDeviceRefMapper.xml b/ruoyi-modules/Sis/src/main/resources/mapper/sis/SisAcDeviceRefMapper.xml new file mode 100644 index 00000000..9119e40f --- /dev/null +++ b/ruoyi-modules/Sis/src/main/resources/mapper/sis/SisAcDeviceRefMapper.xml @@ -0,0 +1,19 @@ + + + + + + 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 77beb930..f8c469ba 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 @@ -6,11 +6,13 @@ import cn.hutool.core.util.ObjectUtil; import lombok.RequiredArgsConstructor; 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.resource.domain.QrCodeInfo; import org.dromara.resource.domain.bo.SysOssBo; import org.dromara.resource.domain.vo.SysOssUploadVo; import org.dromara.resource.domain.vo.SysOssVo; @@ -80,6 +82,32 @@ public class SysOssController extends BaseController { return R.ok(uploadVo); } + + /** + * 上传OSS对象存储 + * + * @param file 文件 + */ + @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) { + if (ObjectUtil.isNull(file)) { + return R.fail("上传文件不能为空"); + } + QrCodeInfo info = RedisUtils.getCacheObject("Qrcode" + code); + if (info==null){ + return R.fail("二维码已过期"); + } + + SysOssVo oss = iSysOssService.qrupload(file,info); + SysOssUploadVo uploadVo = new SysOssUploadVo(); + uploadVo.setUrl(oss.getUrl()); + uploadVo.setFileName(oss.getOriginalName()); + uploadVo.setOssId(oss.getOssId().toString()); + return R.ok(uploadVo); + } + /** * 下载OSS对象存储 * diff --git a/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/domain/QrCodeInfo.java b/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/domain/QrCodeInfo.java new file mode 100644 index 00000000..975ed6b2 --- /dev/null +++ b/ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/domain/QrCodeInfo.java @@ -0,0 +1,10 @@ +package org.dromara.resource.domain; +import lombok.Data; + +@Data +public class QrCodeInfo { + private String deviceCode; // 对应“设备码” + private String generateTime; // 对应“生成时间” + private String qrCodeId; // 对应“二维码ID” + private Long userid; +} 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 76c545ee..22472437 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 @@ -3,6 +3,7 @@ package org.dromara.resource.service; import jakarta.servlet.http.HttpServletResponse; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.resource.domain.QrCodeInfo; import org.dromara.resource.domain.bo.SysOssBo; import org.dromara.resource.domain.vo.SysOssVo; import org.springframework.web.multipart.MultipartFile; @@ -60,6 +61,14 @@ public interface ISysOssService { */ SysOssVo upload(MultipartFile file); + /** + * 上传 MultipartFile 到对象存储服务,并保存文件信息到数据库 + * + * @param file 要上传的 MultipartFile 对象 + * @return 上传成功后的 SysOssVo 对象,包含文件信息 + */ + SysOssVo qrupload(MultipartFile file, QrCodeInfo qrCodeInfo); + /** * 上传文件到对象存储服务,并保存文件信息到数据库 * 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 2e94612c..6069bc5d 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 @@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import org.dromara.common.core.constant.CacheNames; +import org.dromara.common.core.domain.R; import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.SpringUtils; @@ -20,6 +21,8 @@ import org.dromara.common.oss.core.OssClient; import org.dromara.common.oss.entity.UploadResult; import org.dromara.common.oss.enums.AccessPolicyType; import org.dromara.common.oss.factory.OssFactory; +import org.dromara.common.redis.utils.RedisUtils; +import org.dromara.resource.domain.QrCodeInfo; import org.dromara.resource.domain.SysOss; import org.dromara.resource.domain.bo.SysOssBo; import org.dromara.resource.domain.vo.SysOssVo; @@ -33,10 +36,7 @@ import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; import java.time.Duration; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; /** @@ -199,6 +199,21 @@ public class SysOssServiceImpl implements ISysOssService { return buildResultEntity(originalfileName, suffix, storage.getConfigKey(), uploadResult); } + @Override + public SysOssVo qrupload(MultipartFile file, QrCodeInfo info) { + String originalfileName = file.getOriginalFilename(); + String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."), originalfileName.length()); + OssClient storage = OssFactory.instance(); + UploadResult uploadResult; + try { + uploadResult = storage.uploadSuffix(file.getBytes(), suffix, file.getContentType()); + } catch (IOException e) { + throw new ServiceException(e.getMessage()); + } + // 保存文件信息 + return buildResultEntityQr(originalfileName, suffix, storage.getConfigKey(), uploadResult,info); + } + /** * 上传文件到对象存储服务,并保存文件信息到数据库 * @@ -227,6 +242,20 @@ public class SysOssServiceImpl implements ISysOssService { return this.matchingUrl(sysOssVo); } + private SysOssVo buildResultEntityQr(String originalfileName, String suffix, String configKey, UploadResult uploadResult,QrCodeInfo info) { + SysOss oss = new SysOss(); + oss.setUrl(uploadResult.getUrl()); + oss.setFileSuffix(suffix); + oss.setFileName(uploadResult.getFilename()); + oss.setOriginalName(originalfileName); + oss.setService(configKey); + oss.setCreateBy(info.getUserid()); + oss.setCreateTime(new Date()); + baseMapper.insert(oss); + SysOssVo sysOssVo = MapstructUtils.convert(oss, SysOssVo.class); + return this.matchingUrl(sysOssVo); + } + /** * 新增OSS对象存储 *