Преглед изворни кода

Merge branch 'fu-dev' of uskycloud/usky-modules into master

hanzhengyi пре 5 дана
родитељ
комит
b67facfbf2

+ 1 - 1
service-meeting/service-meeting-biz/src/main/java/com/usky/meeting/controller/web/SignOnOutRequestVO.java

@@ -20,7 +20,7 @@ public class SignOnOutRequestVO {
     private Integer mothodType;
 
     /**
-     * 签到签退方式(0.人工 1.人脸)
+     * 签到签退方式(0.人工 1.人脸 3.二维码)
      */
     private Integer signType;
 

+ 3 - 2
service-meeting/service-meeting-biz/src/main/java/com/usky/meeting/domain/MeetingAttendee.java

@@ -2,6 +2,7 @@ package com.usky.meeting.domain;
 
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
+
 import java.time.LocalDateTime;
 import java.io.Serializable;
 
@@ -65,7 +66,7 @@ public class MeetingAttendee implements Serializable {
     private LocalDateTime signOutDate;
 
     /**
-     * 签到方式(0.人工签到 1.人脸签到)
+     * 签到方式(0.人工签到 1.人脸签到 3.二维码)
      */
     private Integer signType;
 
@@ -80,7 +81,7 @@ public class MeetingAttendee implements Serializable {
     private Integer tenantId;
 
     /**
-     * 签退方式(0.人工签退 1.人脸签退)
+     * 签退方式(0.人工签退 1.人脸签退 3.二维码)
      */
     private Integer signOutType;
 

+ 13 - 0
service-meeting/service-meeting-biz/src/main/java/com/usky/meeting/domain/MeetingDevice.java

@@ -151,6 +151,19 @@ public class MeetingDevice implements Serializable {
      */
     private Integer templateId;
 
+    /**
+     * 模板信息
+     */
     @TableField(exist = false)
     private MeetingTemplate meetingTemplate;
+
+    /**
+     * 设备状态 0离线 1在线
+     */
+    private Integer deviceStatus;
+
+    /**
+     * 设备方向 1横屏 2竖屏
+     */
+    private Integer deviceDirection;
 }

+ 2 - 2
service-meeting/service-meeting-biz/src/main/java/com/usky/meeting/repository/MeetingInfoRepository.java

@@ -369,11 +369,11 @@ public interface MeetingInfoRepository extends JpaRepository<MeetingInfo, Long>,
 //    void autoCloseMeetingAndRoom(@Param("updateDate") String updateDate);
 
     @Query(value = "select u.`user_id` as userId,u.`nick_name` as userName,u.sex AS sex,u.phonenumber AS phone,u.dept_id as dept," +
-            " (CASE a.is_sign WHEN 0 THEN '否' WHEN 1 THEN '是' END) as isSign,(CASE a.sign_type WHEN 0 THEN '人工签到' WHEN 1 THEN '人脸签到' END) as signType," +
+            " (CASE a.is_sign WHEN 0 THEN '否' WHEN 1 THEN '是' END) as isSign,(CASE a.sign_type WHEN 0 THEN '人工签到' WHEN 1 THEN '人脸签到' WHEN 2 THEN '二维码签到' END) as signType," +
             " a.sign_date as `date`,a.meeting_id as meetingId,m.approve_status as approveStatus,m.meeting_status as meetingStatus" +
             " from meeting_attendee as a " +
             " left join sys_user as u on a.user_id = u.user_id " +
-            " left join meeting_info as m on m.meeting_id = a.meeting_id "+
+            " left join meeting_info as m on m.meeting_id = a.meeting_id " +
             " where a.meeting_id = :meetingId and a.tenant_id = :tenantId",nativeQuery = true,countQuery = "select COUNT(DISTINCT a.id ) as subcount from meeting_attendee as a left join sys_user as u on a.user_id = u.user_id left join meeting_info as m on m.meeting_id = a.meeting_id where a.meeting_id = :meetingId")
     List<Map<String,Object>> meetingSignList(@Param("meetingId") Long meetingId,@Param("tenantId") Integer tenantId);
 //

+ 85 - 44
service-meeting/service-meeting-biz/src/main/java/com/usky/meeting/service/impl/MeetingDeviceServiceImpl.java

@@ -29,10 +29,7 @@ import org.springframework.stereotype.Repository;
 import org.springframework.stereotype.Service;
 
 import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-import java.util.Optional;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -62,6 +59,7 @@ public class MeetingDeviceServiceImpl extends AbstractCrudService<MeetingDeviceM
 
     @Override
     public CommonPage<MeetingDevice> meetingDeviceList(MeetingDeviceRequestVO requestVO) {
+        LocalDateTime now = LocalDateTime.now();
         Integer current = requestVO.getCurrent();
         Integer size = requestVO.getSize();
         IPage<MeetingDevice> page = new Page<>(current, size);
@@ -112,6 +110,8 @@ public class MeetingDeviceServiceImpl extends AbstractCrudService<MeetingDeviceM
 
         LambdaQueryWrapper<MeetingDevice> queryWrapper3 = Wrappers.lambdaQuery();
         queryWrapper3.eq(requestVO.getDeviceCode() != null, MeetingDevice::getDeviceCode, requestVO.getDeviceCode())
+                .eq(requestVO.getDeviceStatus() != null, MeetingDevice::getDeviceStatus, requestVO.getDeviceStatus())
+                .eq(requestVO.getDeviceDirection() != null, MeetingDevice::getDeviceDirection, requestVO.getDeviceDirection())
                 .like(StringUtils.isNotBlank(requestVO.getDeviceName()), MeetingDevice::getDeviceName, requestVO.getDeviceName())
                 .like(StringUtils.isNotBlank(requestVO.getNameplate()), MeetingDevice::getNameplate, requestVO.getNameplate())
                 .like(StringUtils.isNotBlank(requestVO.getMaintainer()), MeetingDevice::getMaintainer, requestVO.getMaintainer())
@@ -128,57 +128,98 @@ public class MeetingDeviceServiceImpl extends AbstractCrudService<MeetingDeviceM
         queryWrapper4.eq(MeetingTemplate::getTenantId, tenantId);
         List<MeetingTemplate> meetingTemplateList = meetingTemplateMapper.selectList(queryWrapper4);
 
-
         if (!page.getRecords().isEmpty()) {
+            // 1. 提取设备编码并过滤空值
+            List<String> validDeviceCodes = page.getRecords().stream()
+                    .map(MeetingDevice::getDeviceCode)
+                    .filter(Objects::nonNull)
+                    .collect(Collectors.toList());
 
-            if (CollectionUtils.isNotEmpty(meetingRoomsList)) {
-                for (int i = 0; i < page.getRecords().size(); i++) {
-                    if (Objects.nonNull(page.getRecords().get(i).getRoomId())) {
-                        Long RId = page.getRecords().get(i).getRoomId();
-                        for (MeetingRoom meetingRoom : meetingRoomsList) {
-                            if (RId.equals(meetingRoom.getRoomId())) {
-                                page.getRecords().get(i).setMeetingRoom(meetingRoom);
-                                break;
-                            }
-                        }
-                    }
-
-                }
+            // 2. 批量查询心跳信息并构建Map
+            Map<String, LocalDateTime> deviceHeartbeatMap;
+            if (CollectionUtils.isEmpty(validDeviceCodes)) {
+                deviceHeartbeatMap = Collections.emptyMap();
+            } else {
+                deviceHeartbeatMap = heartbeatMapper.selectList(Wrappers.<MeetingDeviceHeartbeat>lambdaQuery()
+                                .in(MeetingDeviceHeartbeat::getDeviceCode, validDeviceCodes))
+                        .stream()
+                        .collect(Collectors.toMap(
+                                MeetingDeviceHeartbeat::getDeviceCode,
+                                MeetingDeviceHeartbeat::getCreateTime,
+                                (existing, replacement) -> existing
+                        ));
             }
 
-            if (CollectionUtils.isNotEmpty(egDeviceList)) {
-                for (int i = 0; i < page.getRecords().size(); i++) {
-                    if (Objects.nonNull(page.getRecords().get(i).getEgDeviceId())) {
-                        Integer egDeviceId = page.getRecords().get(i).getEgDeviceId();
-                        for (EgDevice egDevice : egDeviceList) {
-                            if (egDeviceId.equals(egDevice.getId())) {
-                                page.getRecords().get(i).setEgDevice(egDevice);
-                                break;
-                            }
-                        }
-                    }
+            // 3. 设备状态赋值
+            page.getRecords().forEach(meetingDevice -> {
+                String deviceCode1 = meetingDevice.getDeviceCode();
+                boolean isHeartbeatValid = Objects.nonNull(deviceCode1)
+                        && deviceHeartbeatMap.containsKey(deviceCode1)
+                        && now.isBefore(deviceHeartbeatMap.get(deviceCode1).plusMinutes(5));
+                meetingDevice.setDeviceStatus(isHeartbeatValid ? 1 : 0);
+            });
 
-                }
-            }
+            // 4. 通用映射关联数据
+            mapAssociatedData(page.getRecords(),
+                    MeetingDevice::getRoomId,
+                    buildIdMap(meetingRoomsList, MeetingRoom::getRoomId),
+                    MeetingDevice::setMeetingRoom);
 
-            if (CollectionUtils.isNotEmpty(meetingTemplateList)) {
-                for (int i = 0; i < page.getRecords().size(); i++) {
-                    if (Objects.nonNull(page.getRecords().get(i).getTemplateId())) {
-                        Integer templateId = page.getRecords().get(i).getTemplateId();
-                        for (MeetingTemplate meetingTemplate : meetingTemplateList) {
-                            if (templateId.equals(meetingTemplate.getId())) {
-                                page.getRecords().get(i).setMeetingTemplate(meetingTemplate);
-                                break;
-                            }
-                        }
-                    }
-                }
-            }
+            mapAssociatedData(page.getRecords(),
+                    MeetingDevice::getEgDeviceId,
+                    buildIdMap(egDeviceList, EgDevice::getId),
+                    MeetingDevice::setEgDevice);
+
+            mapAssociatedData(page.getRecords(),
+                    MeetingDevice::getTemplateId,
+                    buildIdMap(meetingTemplateList, MeetingTemplate::getId),
+                    MeetingDevice::setMeetingTemplate);
         }
 
         return new CommonPage<>(page.getRecords(), page.getTotal(), size, current);
     }
 
+    /**
+     * 构建ID到对象的Map,用于快速查找
+     * @param dataList 待处理的列表
+     * @param idExtractor ID提取器
+     * @return ID到对象的Map
+     */
+    private <T, ID> Map<ID, T> buildIdMap(List<T> dataList, java.util.function.Function<T, ID> idExtractor) {
+        if (CollectionUtils.isEmpty(dataList)) {
+            return Collections.emptyMap();
+        }
+        return dataList.stream()
+                .filter(Objects::nonNull)
+                .collect(Collectors.toMap(
+                        idExtractor,
+                        t -> t,
+                        (existing, replacement) -> existing
+                ));
+    }
+
+    /**
+     * 通用关联数据映射方法
+     * @param mainList 主列表(MeetingDevice列表)
+     * @param keyExtractor 主对象的关联ID提取器
+     * @param dataMap 关联数据的ID->对象Map
+     * @param setter 主对象的关联数据设置器
+     */
+    private <T, ID, D> void mapAssociatedData(List<T> mainList,
+                                              java.util.function.Function<T, ID> keyExtractor,
+                                              Map<ID, D> dataMap,
+                                              java.util.function.BiConsumer<T, D> setter) {
+        if (CollectionUtils.isEmpty(mainList) || CollectionUtils.isEmpty(dataMap)) {
+            return;
+        }
+        mainList.forEach(item -> {
+            ID key = keyExtractor.apply(item);
+            if (Objects.nonNull(key) && dataMap.containsKey(key)) {
+                setter.accept(item, dataMap.get(key));
+            }
+        });
+    }
+
     @Override
     public void add(MeetingDevice meetingDevice) {
         if (checkNameUnique(meetingDevice)) {

+ 0 - 6
service-meeting/service-meeting-biz/src/main/java/com/usky/meeting/service/impl/MeetingFaceServiceImpl.java

@@ -1,10 +1,8 @@
 package com.usky.meeting.service.impl;
 
-import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.usky.common.security.utils.SecurityUtils;
-import com.usky.meet.utils.JwtUtils;
 import com.usky.meet.utils.TimeUtils;
 import com.usky.meeting.domain.MeetingDevice;
 import com.usky.meeting.domain.MeetingFace;
@@ -12,7 +10,6 @@ import com.usky.meeting.mapper.MeetingDeviceMapper;
 import com.usky.meeting.mapper.MeetingFaceMapper;
 import com.usky.meeting.repository.MeetingRoomRepository;
 import com.usky.meeting.server.FaceContrastServer;
-import com.usky.meeting.service.MeetingDeviceService;
 import com.usky.meeting.service.MeetingFaceService;
 import com.usky.common.mybatis.core.AbstractCrudService;
 import com.usky.meeting.service.vo.FaceResultVO;
@@ -21,10 +18,7 @@ import com.usky.meeting.service.vo.MeetingFaceVO;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.time.LocalDateTime;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 /**
  * <p>

+ 4 - 2
service-meeting/service-meeting-biz/src/main/java/com/usky/meeting/service/impl/MeetingInfoServiceImpl.java

@@ -521,15 +521,17 @@ public class MeetingInfoServiceImpl extends AbstractCrudService<MeetingInfoMappe
             if (requestVO.getMothodType().equals(0)) {
                 one.setIsSign(1);
                 one.setSignDate(LocalDateTime.now());
-                // 签到签退方式(0.人工 1.人脸)
+                // 签到签退方式(0.人工 1.人脸 3.二维码)
                 one.setSignType(requestVO.getSignType());
 
-            } else {
+            } else if (requestVO.getMothodType().equals(1)) {
                 one.setIsSignOut(1);
                 one.setSignOutDate(LocalDateTime.now());
                 one.setSignOutType(requestVO.getSignType());
             }
             meetingAttendeeService.updateById(one);
+        } else {
+            throw new BusinessException("您无需参加此会议!");
         }
 
     }

+ 10 - 0
service-meeting/service-meeting-biz/src/main/java/com/usky/meeting/service/vo/MeetingDeviceRequestVO.java

@@ -63,4 +63,14 @@ public class MeetingDeviceRequestVO {
      * 设备编码
      */
     private String deviceCode;
+
+    /**
+     * 设备状态 0:离线 1:在线
+     */
+    private Integer deviceStatus;
+
+    /**
+     * 设备方向 1横屏 2竖屏
+     */
+    private Integer deviceDirection;
 }

+ 1 - 1
service-meeting/service-meeting-biz/src/main/java/com/usky/meeting/utils/JwtUtils.java

@@ -1,4 +1,4 @@
-package com.usky.meet.utils;
+package com.usky.meeting.utils;
 
 import com.auth0.jwt.JWT;
 import com.auth0.jwt.JWTCreator;

+ 2 - 0
service-meeting/service-meeting-biz/src/main/resources/mapper/meeting/MeetingDeviceMapper.xml

@@ -24,6 +24,8 @@
         <result column="device_code" property="deviceCode"/>
         <result column="ip_addr" property="ipAddr"/>
         <result column="template_id" property="templateId"/>
+        <result column="device_status" property="deviceStatus"/>
+        <result column="device_direction" property="deviceDirection"/>
     </resultMap>
 
 </mapper>