Browse Source

视频中心

lipenghui 9 hours ago
parent
commit
872e604a1b
24 changed files with 497 additions and 98 deletions
  1. 5 5
      yudao-module-pms/yudao-module-pms-biz/pom.xml
  2. 9 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/devicegroup/IotDeviceGroupController.java
  3. 36 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/yanfan/enums/DeviceStatus.java
  4. 6 2
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/yanfan/server/VideoSessionManager.java
  5. 58 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/yanfan/sip/handler/DeviceInfoHandler.java
  6. 86 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/yanfan/sip/handler/KeepaliveHandler.java
  7. 18 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/yanfan/sip/handler/NotifyMessageHandler.java
  8. 5 1
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/yanfan/sip/vo/InviteInfo.java
  9. 25 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/yanfan/sip/vo/SipDeviceSummary.java
  10. 5 1
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/yanfan/sip/vo/VideoSessionInfo.java
  11. 2 1
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/yanfan/sip/device/YfSipDeviceMapper.java
  12. 4 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/devicegroup/IotDeviceGroupService.java
  13. 18 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/devicegroup/IotDeviceGroupServiceImpl.java
  14. 1 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/yanfan/device/YfIotDeviceService.java
  15. 37 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/yanfan/device/YfIotDeviceServiceImpl.java
  16. 1 1
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/yanfan/sip/IMqttService.java
  17. 8 6
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/yanfan/sip/InviteServiceImpl.java
  18. 66 43
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/yanfan/sip/SipCmdImpl.java
  19. 30 27
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/yanfan/sip/VideoMqttService.java
  20. 2 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/yanfan/sip/device/YfSipDeviceService.java
  21. 11 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/yanfan/sip/device/YfSipDeviceServiceImpl.java
  22. 2 1
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/yanfan/sip/device/channel/YfSipDeviceChannelServiceImpl.java
  23. 10 10
      yudao-module-pms/yudao-module-pms-biz/src/main/resources/mapper/static/yanfan/YfSipDeviceChannelMapper.xml
  24. 52 0
      yudao-module-pms/yudao-module-pms-biz/src/main/resources/mapper/static/yanfan/YfSipDeviceMapper.xml

+ 5 - 5
yudao-module-pms/yudao-module-pms-biz/pom.xml

@@ -140,11 +140,11 @@
             <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
             <version>1.2.5</version>
         </dependency>
-        <dependency>
-            <groupId>javax.sip</groupId>
-            <artifactId>jain-sip-ri</artifactId>
-            <version>1.3.0-91</version>
-        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>javax.sip</groupId>-->
+<!--            <artifactId>jain-sip-ri</artifactId>-->
+<!--            <version>1.3.0-91</version>-->
+<!--        </dependency>-->
     </dependencies>
 
 </project>

+ 9 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/devicegroup/IotDeviceGroupController.java

@@ -111,4 +111,13 @@ public class IotDeviceGroupController {
                         BeanUtils.toBean(list, IotDeviceGroupRespVO.class));
     }
 
+
+    @GetMapping("/device/group")
+    @Operation(summary = "获得某设备的成套信息")
+    @Parameter(name = "id", description = "编号", required = true, example = "1024")
+    @PreAuthorize("@ss.hasPermission('rq:iot-device-group:query')")
+    public CommonResult<PageResult<IotDeviceGroupDetailDO>> getDeviceGroup(@Valid IotDeviceGroupDetailPageReqVO reqVO) {
+        PageResult<IotDeviceGroupDetailDO> deviceGroupList = iotDeviceGroupService.getDeviceGroupList(reqVO);
+        return success(deviceGroupList);
+    }
 }

+ 36 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/yanfan/enums/DeviceStatus.java

@@ -0,0 +1,36 @@
+package cn.iocoder.yudao.module.pms.controller.admin.yanfan.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public enum DeviceStatus {
+
+    UNACTIVATED(1, "NOTACTIVE", "未激活"),
+    FORBIDDEN(2, "DISABLE", "禁用"),
+    ONLINE(3, "ONLINE", "在线"),
+    OFFLINE(4, "OFFLINE", "离线");
+
+    private int type;
+    private String code;
+    private String description;
+
+    public static DeviceStatus convert(int type) {
+        for (DeviceStatus value : DeviceStatus.values()) {
+            if (value.type == type) {
+                return value;
+            }
+        }
+        return null;
+    }
+
+    public static DeviceStatus convert(String code) {
+        for (DeviceStatus value : DeviceStatus.values()) {
+            if (value.code.equals(code)) {
+                return value;
+            }
+        }
+        return null;
+    }
+}

+ 6 - 2
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/yanfan/server/VideoSessionManager.java

@@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.pms.controller.admin.yanfan.redis.RedisKeyBuilder
 import cn.iocoder.yudao.module.pms.controller.admin.yanfan.sip.vo.InviteInfo;
 import cn.iocoder.yudao.module.pms.controller.admin.yanfan.sip.vo.VideoSessionInfo;
 import cn.iocoder.yudao.module.pms.controller.admin.yanfan.utils.SipUtil;
+import com.alibaba.fastjson.JSON;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import org.springframework.util.ObjectUtils;
@@ -74,7 +75,9 @@ public class VideoSessionManager {
         if (scanResult.size() == 0) {
             return null;
         }
-        return (VideoSessionInfo) redisCache.getCacheObject((String) scanResult.get(0));
+//        return (VideoSessionInfo) redisCache.getCacheObject((String) scanResult.get(0));
+        System.out.println(scanResult.get(0).toString());
+        return JSON.parseObject(JSON.toJSONString(scanResult.get(0)), VideoSessionInfo.class);
     }
 
     public VideoSessionInfo getSessionInfoByCallId(String callId) {
@@ -124,7 +127,8 @@ public class VideoSessionManager {
         }
         List<VideoSessionInfo> result = new ArrayList<>();
         for (Object keyObj : scanResult) {
-            result.add((VideoSessionInfo) redisCache.getCacheObject((String) keyObj));
+//            result.add((VideoSessionInfo) redisCache.getCacheObject((String) keyObj));
+            result.add(JSON.parseObject(JSON.toJSONString(keyObj), VideoSessionInfo.class));
         }
         return result;
     }

+ 58 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/yanfan/sip/handler/DeviceInfoHandler.java

@@ -0,0 +1,58 @@
+package cn.iocoder.yudao.module.pms.controller.admin.yanfan.sip.handler;
+
+import cn.iocoder.yudao.module.pms.controller.admin.yanfan.utils.XmlUtil;
+import cn.iocoder.yudao.module.pms.dal.dataobject.yanfan.sip.device.YfSipDeviceDO;
+import cn.iocoder.yudao.module.pms.service.yanfan.sip.IMqttService;
+import cn.iocoder.yudao.module.pms.service.yanfan.sip.device.YfSipDeviceService;
+import org.dom4j.DocumentException;
+import org.dom4j.Element;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+
+import javax.sip.InvalidArgumentException;
+import javax.sip.RequestEvent;
+import javax.sip.SipException;
+import java.text.ParseException;
+
+@Component
+public class DeviceInfoHandler extends ReqAbstractHandler implements InitializingBean, IMessageHandler {
+
+    @Autowired
+    private ResponseMessageHandler responseMessageHandler;
+
+    @Autowired
+    private YfSipDeviceService sipDeviceService;
+
+    @Autowired
+    private IMqttService mqttService;
+    @Override
+    public void handlerCmdType(RequestEvent evt, YfSipDeviceDO device, Element element) {
+        try {
+            Element rootElement = getRootElement(evt);
+            device.setDeviceName(XmlUtil.getText(rootElement, "DeviceName"));
+            device.setManufacturer(XmlUtil.getText(rootElement, "Manufacturer"));
+            device.setModel(XmlUtil.getText(rootElement, "Model"));
+            device.setFirmware(XmlUtil.getText(rootElement, "Firmware"));
+            if (StringUtils.isEmpty(device.getStreamMode())) {
+                device.setStreamMode("UDP");
+            }
+            // 更新到数据库
+            sipDeviceService.updateDevice(device);
+            // 发布设备info到emqx
+            mqttService.publishInfo(device);
+            // 回复200 OK
+            responseAck(evt);
+
+        } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void afterPropertiesSet() throws Exception {
+        String cmdType = "DeviceInfo";
+        responseMessageHandler.addHandler(cmdType, this);
+    }
+}

+ 86 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/yanfan/sip/handler/KeepaliveHandler.java

@@ -0,0 +1,86 @@
+package cn.iocoder.yudao.module.pms.controller.admin.yanfan.sip.handler;
+
+import cn.iocoder.yudao.module.pms.controller.admin.yanfan.enums.DeviceStatus;
+import cn.iocoder.yudao.module.pms.controller.admin.yanfan.utils.XmlUtil;
+import cn.iocoder.yudao.module.pms.dal.dataobject.yanfan.device.YfIotDeviceDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.yanfan.sip.device.YfSipDeviceDO;
+import cn.iocoder.yudao.module.pms.service.yanfan.device.YfIotDeviceService;
+import cn.iocoder.yudao.module.pms.service.yanfan.sip.MessageInvoker;
+import cn.iocoder.yudao.module.pms.service.yanfan.sip.device.YfSipDeviceService;
+import lombok.extern.slf4j.Slf4j;
+import org.dom4j.DocumentException;
+import org.dom4j.Element;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+
+import javax.sip.InvalidArgumentException;
+import javax.sip.RequestEvent;
+import javax.sip.SipException;
+import javax.sip.header.ViaHeader;
+import java.text.ParseException;
+import java.time.LocalDateTime;
+
+@Slf4j
+@Component
+public class KeepaliveHandler extends ReqAbstractHandler implements InitializingBean, IMessageHandler {
+
+    @Autowired
+    private NotifyMessageHandler notifyMessageHandler;
+
+    @Autowired
+    private YfSipDeviceService sipDeviceService;
+
+    @Autowired
+    private MessageInvoker messageInvoker;
+
+    @Autowired
+    private YfIotDeviceService deviceService;
+
+    @Override
+    public void handlerCmdType(RequestEvent evt, YfSipDeviceDO device, Element element) {
+        try {
+            Element rootElement = getRootElement(evt);
+            String deviceId = XmlUtil.getText(rootElement, "DeviceID");
+            if (sipDeviceService.exists(deviceId)) {
+                ViaHeader viaHeader = (ViaHeader) evt.getRequest().getHeader(ViaHeader.NAME);
+                String received = viaHeader.getReceived();
+                int rPort = viaHeader.getRPort();
+                if (StringUtils.isEmpty(received) || rPort == -1) {
+                    log.warn("本地地址替代! received:{},rPort:{} [{}:{}]", received, rPort, viaHeader.getHost(), viaHeader.getPort());
+                    received = viaHeader.getHost();
+                    rPort = viaHeader.getPort();
+                }
+                device.setLastConnectTime(LocalDateTime.now());
+                device.setIp(received);
+                device.setPort(rPort);
+                device.setHostAddress(received.concat(":").concat(String.valueOf(rPort)));
+                log.info("设备:{} 心跳上报时间:{}", deviceId, device.getLastConnectTime());
+                //log.warn("设备:{} 心跳上报时间:{}",deviceId,device.getLastconnecttime());
+                // 更新在线状态到emqx
+                // mqttService.publishStatus(device, 3);
+                // 更新在线状态
+                sipDeviceService.updateSipDeviceStatus(device);
+                YfIotDeviceDO dev = deviceService.selectDeviceBySerialNumber(deviceId);
+                if (dev != null && dev.getStatus() != DeviceStatus.ONLINE.getType()) {
+                    dev.setStatus(DeviceStatus.ONLINE.getType());
+                    deviceService.updateDevice(dev);
+                }
+                // 更新通道状态
+                messageInvoker.catalogQuery(device);
+                // 回复200 OK
+                responseAck(evt);
+            }
+
+        } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void afterPropertiesSet() throws Exception {
+        String cmdType = "Keepalive";
+        notifyMessageHandler.addHandler(cmdType, this);
+    }
+}

+ 18 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/yanfan/sip/handler/NotifyMessageHandler.java

@@ -0,0 +1,18 @@
+package cn.iocoder.yudao.module.pms.controller.admin.yanfan.sip.handler;
+
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class NotifyMessageHandler extends MessageHandlerAbstract implements InitializingBean {
+
+    @Autowired
+    private MessageRequestProcessor messageRequestProcessor;
+
+    @Override
+    public void afterPropertiesSet() throws Exception {
+        String messageType = "Notify";
+        messageRequestProcessor.addHandler(messageType, this);
+    }
+}

+ 5 - 1
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/yanfan/sip/vo/InviteInfo.java

@@ -1,10 +1,14 @@
 package cn.iocoder.yudao.module.pms.controller.admin.yanfan.sip.vo;
 
+import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 
 @Data
-@Builder
+//@Builder
+@AllArgsConstructor
+@NoArgsConstructor
 public class InviteInfo {
     private String ssrc;
     private String callId;

+ 25 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/yanfan/sip/vo/SipDeviceSummary.java

@@ -0,0 +1,25 @@
+package cn.iocoder.yudao.module.pms.controller.admin.yanfan.sip.vo;
+
+import cn.iocoder.yudao.module.pms.dal.dataobject.yanfan.sip.device.YfSipDeviceDO;
+import lombok.Data;
+
+@Data
+public class SipDeviceSummary {
+    public SipDeviceSummary(YfSipDeviceDO device) {
+        this.manufacturer = device.getManufacturer();
+        this.firmware = device.getFirmware();
+        this.transport = device.getTransport();
+        this.streammode = device.getStreamMode();
+        this.port = device.getPort();
+        this.hostaddress = device.getHostAddress();
+    }
+    public SipDeviceSummary() {
+
+    }
+    private String manufacturer;
+    private String firmware;
+    private String transport;
+    private String streammode;
+    private Integer port;
+    private String hostaddress;
+}

+ 5 - 1
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/yanfan/sip/vo/VideoSessionInfo.java

@@ -1,11 +1,15 @@
 package cn.iocoder.yudao.module.pms.controller.admin.yanfan.sip.vo;
 
 import cn.iocoder.yudao.module.pms.controller.admin.yanfan.enums.SessionType;
+import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 
 @Data
-@Builder
+//@Builder
+@NoArgsConstructor
+@AllArgsConstructor
 public class VideoSessionInfo {
     //流基本信息
     private String mediaServerId;

+ 2 - 1
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/yanfan/sip/device/YfSipDeviceMapper.java

@@ -16,7 +16,8 @@ import org.apache.ibatis.annotations.Mapper;
  */
 @Mapper
 public interface YfSipDeviceMapper extends BaseMapperX<YfSipDeviceDO> {
-
+    int updateSipDeviceStatus(YfSipDeviceDO sipDevice);
+    YfSipDeviceDO selectSipDeviceBySipId(String sipId);
     default PageResult<YfSipDeviceDO> selectPage(YfSipDevicePageReqVO reqVO) {
         return selectPage(reqVO, new LambdaQueryWrapperX<YfSipDeviceDO>()
                 .eqIfPresent(YfSipDeviceDO::getProductId, reqVO.getProductId())

+ 4 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/devicegroup/IotDeviceGroupService.java

@@ -1,11 +1,14 @@
 package cn.iocoder.yudao.module.pms.service.devicegroup;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.pms.controller.admin.devicegroup.IotDeviceGroupDetailPageReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.devicegroup.IotDeviceGroupPageReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.devicegroup.IotDeviceGroupSaveReqVO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.devicegroup.IotDeviceGroupDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.devicegroup.IotDeviceGroupDetailDO;
 
 import javax.validation.Valid;
+import java.util.List;
 
 /**
  * PMS成套 Service 接口
@@ -51,5 +54,6 @@ public interface IotDeviceGroupService {
      * @return PMS成套分页
      */
     PageResult<IotDeviceGroupDO> getIotDeviceGroupPage(IotDeviceGroupPageReqVO pageReqVO);
+    PageResult<IotDeviceGroupDetailDO> getDeviceGroupList(IotDeviceGroupDetailPageReqVO reqVO);
 
 }

+ 18 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/devicegroup/IotDeviceGroupServiceImpl.java

@@ -2,13 +2,16 @@ package cn.iocoder.yudao.module.pms.service.devicegroup;
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.iocoder.yudao.framework.common.exception.ErrorCode;
+import cn.iocoder.yudao.module.pms.controller.admin.devicegroup.IotDeviceGroupDetailPageReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.devicegroup.IotDeviceGroupDetailSaveReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.devicegroup.IotDeviceGroupPageReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.devicegroup.IotDeviceGroupSaveReqVO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.IotDeviceDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.devicegroup.IotDeviceGroupDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.devicegroup.IotDeviceGroupDetailDO;
 import cn.iocoder.yudao.module.pms.dal.mysql.devicegroup.IotDeviceGroupDetailMapper;
 import cn.iocoder.yudao.module.pms.dal.mysql.devicegroup.IotDeviceGroupMapper;
+import cn.iocoder.yudao.module.pms.service.IotDeviceService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -20,6 +23,7 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 
 import javax.annotation.Resource;
 
+import java.util.Collections;
 import java.util.List;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -37,6 +41,8 @@ public class IotDeviceGroupServiceImpl implements IotDeviceGroupService {
     private IotDeviceGroupMapper iotDeviceGroupMapper;
     @Autowired
     private IotDeviceGroupDetailMapper iotDeviceGroupDetailMapper;
+    @Autowired
+    private IotDeviceService iotDeviceService;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -104,4 +110,16 @@ public class IotDeviceGroupServiceImpl implements IotDeviceGroupService {
         return iotDeviceGroupMapper.selectPage(pageReqVO);
     }
 
+    @Override
+    public PageResult<IotDeviceGroupDetailDO> getDeviceGroupList(IotDeviceGroupDetailPageReqVO reqVO) {
+        IotDeviceDO iotDevice = iotDeviceService.getIotDevice(reqVO.getDeviceId());
+        List<IotDeviceGroupDetailDO> deviceCodes = iotDeviceGroupDetailMapper.selectList("device_code", iotDevice.getDeviceCode());
+        IotDeviceGroupDetailDO iotDeviceGroupDetailDO = deviceCodes.get(0);
+        Long groupId = iotDeviceGroupDetailDO.getGroupId();
+//        IotDeviceGroupDetailPageReqVO pageReqVO = new IotDeviceGroupDetailPageReqVO();
+        reqVO.setGroupId(groupId);
+        PageResult<IotDeviceGroupDetailDO> iotDeviceGroupDetailDOPageResult = iotDeviceGroupDetailMapper.selectPage(reqVO);
+        return iotDeviceGroupDetailDOPageResult;
+    }
+
 }

+ 1 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/yanfan/device/YfIotDeviceService.java

@@ -19,6 +19,7 @@ import javax.validation.Valid;
  * @author 超级管理员
  */
 public interface YfIotDeviceService {
+    void updateDevice(YfIotDeviceDO device);
     int updateDeviceStatusAndLocation(YfIotDeviceDO device, String ipAddress);
     YfIotDeviceDO selectDeviceBySerialNumber(String serialNumber);
     void deleteDeviceByDeviceId(Long deviceId) throws SchedulerException;

+ 37 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/yanfan/device/YfIotDeviceServiceImpl.java

@@ -38,6 +38,7 @@ import org.quartz.SchedulerException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.cache.annotation.Cacheable;
+import org.springframework.cache.annotation.Caching;
 import org.springframework.context.annotation.Bean;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -89,6 +90,42 @@ public class YfIotDeviceServiceImpl implements YfIotDeviceService {
     private IotYfProductMapper iotYfProductMapper;
 
 
+    /**
+     * 修改设备
+     *
+     * @param device 设备
+     * @return 结果
+     */
+    @Caching(evict = {
+            @CacheEvict(value = "device", key = "'selectDeviceBySerialNumber_' + #device.getSerialNumber()"),
+            @CacheEvict(value = "device", key = "'selectDeviceByDeviceId_' + #device.getDeviceId()"),
+            @CacheEvict(value = "device", key = "'selectShortDeviceBySerialNumber_' + #device.getSerialNumber()")
+    })
+    @Override
+    public void updateDevice(YfIotDeviceDO device) {
+        // 设备编号唯一检查
+        YfIotDeviceRespVO oldDevice = yfIotDeviceMapper.selectDeviceByDeviceId(device.getDeviceId());
+        if (!oldDevice.getSerialNumber().equals(device.getSerialNumber())) {
+            YfIotDeviceDO existDevice = yfIotDeviceMapper.selectDeviceBySerialNumber(device.getSerialNumber());
+            if (existDevice != null) {
+                log.error("设备编号:" + device.getSerialNumber() + " 已经存在,新增设备失败");
+//                return AjaxResult.error("设备编号:" + device.getSerialNumber() + " 已经存在,修改失败", 0);
+                throw new ServiceException(new ErrorCode(2, "设备编号:" + device.getSerialNumber() + " 已经存在,修改失败"));
+            }
+        }
+        device.setUpdateTime(LocalDateTime.now());
+        // 未激活状态,可以修改产品以及物模型值
+        if (device.getStatus() == 1) {
+            // 缓存设备状态(物模型值)
+            itslValueCache.addCacheDeviceStatus(device.getProductId(), device.getSerialNumber());
+
+        } else {
+            device.setProductId(null);
+            device.setProductName(null);
+        }
+        yfIotDeviceMapper.updateById(device);
+    }
+
     /**
      * 根据设备编号查询设备
      *

+ 1 - 1
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/yanfan/sip/IMqttService.java

@@ -9,7 +9,7 @@ import liquibase.pro.packaged.Y;
 import java.util.List;
 
 public interface IMqttService {
-//    void publishInfo(YfSipDeviceDO device);
+    void publishInfo(YfSipDeviceDO device);
     void publishStatus(YfSipDeviceDO device, int deviceStatus);
 //    void publishEvent(Alarm alarm);
 //    void publishProperty(Long productId, String deviceNum, List<ThingsModelSimpleItem> thingsList, int delay);

+ 8 - 6
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/yanfan/sip/InviteServiceImpl.java

@@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.pms.controller.admin.yanfan.redis.RedisCache;
 import cn.iocoder.yudao.module.pms.controller.admin.yanfan.redis.RedisKeyBuilder;
 import cn.iocoder.yudao.module.pms.controller.admin.yanfan.sip.vo.InviteInfo;
 import cn.iocoder.yudao.module.pms.controller.admin.yanfan.sip.vo.VideoSessionInfo;
+import com.alibaba.fastjson.JSON;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -63,7 +64,7 @@ public class InviteServiceImpl implements IInviteService {
             log.warn("[获取InviteInfo] 发现 key: {}存在多条", key);
         }
 
-        return (InviteInfo) redisCache.getCacheObject((String) scanResult.get(0));
+        return JSON.parseObject(JSON.toJSONString(scanResult.get(0)), InviteInfo.class);
     }
 
     @Override
@@ -81,7 +82,8 @@ public class InviteServiceImpl implements IInviteService {
         if (scanResult.size() > 0) {
             List<InviteInfo> list = new ArrayList<>();
             for (Object keyObj : scanResult) {
-                list.add((InviteInfo) redisCache.getCacheObject((String) keyObj));
+//                list.add((InviteInfo) redisCache.getCacheObject((String) keyObj));
+                list.add(JSON.parseObject(JSON.toJSONString(keyObj),  InviteInfo.class));
             }
             return list;
         } else {
@@ -100,7 +102,8 @@ public class InviteServiceImpl implements IInviteService {
         if (scanResult.size() != 1) {
             return null;
         }
-        return (InviteInfo) redisCache.getCacheObject((String) scanResult.get(0));
+//        return (InviteInfo) redisCache.getCacheObject((String) scanResult.get(0));
+        return JSON.parseObject(JSON.toJSONString(scanResult.get(0)), InviteInfo.class);
     }
 
     @Override
@@ -114,12 +117,11 @@ public class InviteServiceImpl implements IInviteService {
         List<Object> scanResult = redisCache.scan(scanKey);
         if (scanResult.size() > 0) {
             for (Object keyObj : scanResult) {
-                String key = (String) keyObj;
-                InviteInfo inviteInfo = (InviteInfo) redisCache.getCacheObject(key);
+                InviteInfo inviteInfo = JSON.parseObject(JSON.toJSONString(keyObj),  InviteInfo.class);
                 if (inviteInfo == null) {
                     continue;
                 }
-                redisCache.deleteObject(key);
+                redisCache.deleteObject(scanKey);
             }
         }
     }

+ 66 - 43
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/yanfan/sip/SipCmdImpl.java

@@ -71,12 +71,12 @@ public class SipCmdImpl implements ISipCmd {
                 log.error("playStreamCmd mediaInfo is null");
                 return null;
             }
-            VideoSessionInfo info = VideoSessionInfo.builder()
-                    .mediaServerId(mediaInfo.getServerId())
-                    .deviceId(device.getDeviceSipId())
-                    .channelId(channelId)
-                    .streamMode(device.getStreamMode().toUpperCase())
-                    .build();
+            VideoSessionInfo info = new VideoSessionInfo();
+            info.setMediaServerId(mediaInfo.getServerId());
+            info.setDeviceId(device.getDeviceSipId());
+            info.setChannelId(channelId);
+            info.setStreamMode(device.getStreamMode().toUpperCase());
+
             String fromTag;
             if (record) {
                 info.setType(SessionType.playrecord);
@@ -93,11 +93,11 @@ public class SipCmdImpl implements ISipCmd {
             //发送消息
             ClientTransaction transaction = transmitRequest(request);
             log.info("playStreamCmd streamSession: {}", info);
-            InviteInfo invite = InviteInfo.builder()
-                    .ssrc(info.getSsrc())
-                    .fromTag(fromTag)
-                    .callId(transaction.getDialog().getCallId().getCallId())
-                    .port(info.getPort()).build();
+            InviteInfo invite = new  InviteInfo();
+                    invite.setSsrc(info.getSsrc());
+                    invite.setFromTag(fromTag);
+                    invite.setCallId(transaction.getDialog().getCallId().getCallId());
+                    invite.setPort(info.getPort());
             log.warn("playStreamCmd invite: {}", invite);
             inviteService.updateInviteInfo(info, invite);
             streamSession.put(info, transaction);
@@ -121,15 +121,15 @@ public class SipCmdImpl implements ISipCmd {
                 log.error("playbackStreamCmd mediaInfo is null");
                 return null;
             }
-            VideoSessionInfo info = VideoSessionInfo.builder()
-                    .mediaServerId(mediaInfo.getServerId())
-                    .deviceId(device.getDeviceSipId())
-                    .channelId(channelId)
-                    .streamMode(device.getStreamMode().toUpperCase())
-                    .type(SessionType.playback)
-                    .startTime(startTime)
-                    .endTime(endTime)
-                    .build();
+            VideoSessionInfo info = new VideoSessionInfo();
+
+                    info.setMediaServerId(mediaInfo.getServerId());
+                    info.setDeviceId(device.getDeviceSipId());
+                    info.setChannelId(channelId);
+                    info.setStreamMode(device.getStreamMode().toUpperCase());
+                    info.setType(SessionType.playback);
+                    info.setStartTime(startTime);
+                    info.setEndTime(endTime);
             //创建rtp服务器
             info = mediaServerService.createRTPServer(sipConfig, mediaInfo, device, info);
             //创建Invite会话
@@ -140,12 +140,18 @@ public class SipCmdImpl implements ISipCmd {
             //发送消息
             ClientTransaction transaction = transmitRequest(request);
             log.info("playbackStreamCmd streamSession: {}", info);
-            InviteInfo invite = InviteInfo.builder()
-                    .ssrc(info.getSsrc())
-                    .fromTag(fromTag)
-                    .viaTag(viaTag)
-                    .callId(transaction.getDialog().getCallId().getCallId())
-                    .port(info.getPort()).build();
+//            InviteInfo invite = InviteInfo.builder()
+//                    .ssrc(info.getSsrc())
+//                    .fromTag(fromTag)
+//                    .viaTag(viaTag)
+//                    .callId(transaction.getDialog().getCallId().getCallId())
+//                    .port(info.getPort()).build();
+            InviteInfo invite = new  InviteInfo();
+            invite.setSsrc(info.getSsrc());
+            invite.setFromTag(fromTag);
+            invite.setViaTag(viaTag);
+            invite.setCallId(transaction.getDialog().getCallId().getCallId());
+            invite.setPort(info.getPort());
             log.warn("playbackStreamCmd invite: {}", invite);
             inviteService.updateInviteInfo(info, invite);
             streamSession.put(info, transaction);
@@ -170,17 +176,28 @@ public class SipCmdImpl implements ISipCmd {
                 log.error("downloadStreamCmd mediaInfo is null");
                 return null;
             }
-            VideoSessionInfo info = VideoSessionInfo.builder()
-                    .mediaServerId(mediaInfo.getServerId())
-                    .deviceId(device.getDeviceSipId())
-                    .channelId(channelId)
-                    .streamMode(device.getStreamMode().toUpperCase())
-                    .type(SessionType.download)
-                    .startTime(startTime)
-                    .endTime(endTime)
-                    .downloadSpeed(downloadSpeed)
-                    .build();
-            ;
+//            VideoSessionInfo info = VideoSessionInfo.builder()
+//                    .mediaServerId(mediaInfo.getServerId())
+//                    .deviceId(device.getDeviceSipId())
+//                    .channelId(channelId)
+//                    .streamMode(device.getStreamMode().toUpperCase())
+//                    .type(SessionType.download)
+//                    .startTime(startTime)
+//                    .endTime(endTime)
+//                    .downloadSpeed(downloadSpeed)
+//                    .build();
+//            ;
+
+            VideoSessionInfo info = new VideoSessionInfo();
+
+            info.setMediaServerId(mediaInfo.getServerId());
+            info.setDeviceId(device.getDeviceSipId());
+            info.setChannelId(channelId);
+            info.setStreamMode(device.getStreamMode().toUpperCase());
+            info.setType(SessionType.playback);
+            info.setStartTime(startTime);
+            info.setEndTime(endTime);
+            info.setDownloadSpeed(downloadSpeed);
             //创建rtp服务器
             info = mediaServerService.createRTPServer(sipConfig, mediaInfo, device, info);
             //创建Invite会话
@@ -191,12 +208,18 @@ public class SipCmdImpl implements ISipCmd {
             //发送消息
             ClientTransaction transaction = transmitRequest(request);
             log.info("downloadStreamCmd streamSession: {}", info);
-            InviteInfo invite = InviteInfo.builder()
-                    .ssrc(info.getSsrc())
-                    .fromTag(fromTag)
-                    .viaTag(viaTag)
-                    .callId(transaction.getDialog().getCallId().getCallId())
-                    .port(info.getPort()).build();
+//            InviteInfo invite = InviteInfo.builder()
+//                    .ssrc(info.getSsrc())
+//                    .fromTag(fromTag)
+//                    .viaTag(viaTag)
+//                    .callId(transaction.getDialog().getCallId().getCallId())
+//                    .port(info.getPort()).build();
+            InviteInfo invite = new  InviteInfo();
+            invite.setSsrc(info.getSsrc());
+            invite.setFromTag(fromTag);
+            invite.setViaTag(viaTag);
+            invite.setCallId(transaction.getDialog().getCallId().getCallId());
+            invite.setPort(info.getPort());
             log.warn("downloadStreamCmd invite: {}", invite);
             inviteService.updateInviteInfo(info, invite);
             streamSession.put(info, transaction);

+ 30 - 27
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/yanfan/sip/VideoMqttService.java

@@ -2,10 +2,13 @@ package cn.iocoder.yudao.module.pms.service.yanfan.sip;
 
 import cn.iocoder.yudao.module.pms.controller.admin.yanfan.enums.TopicType;
 import cn.iocoder.yudao.module.pms.controller.admin.yanfan.mqtt.PubMqttClient;
+import cn.iocoder.yudao.module.pms.controller.admin.yanfan.sip.vo.SipDeviceSummary;
 import cn.iocoder.yudao.module.pms.controller.admin.yanfan.utils.TopicsUtils;
+import cn.iocoder.yudao.module.pms.dal.dataobject.yanfan.device.YfIotDeviceDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.yanfan.sip.config.IotSipConfigDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.yanfan.sip.device.YfSipDeviceDO;
 import cn.iocoder.yudao.module.pms.service.IDeviceService;
+import cn.iocoder.yudao.module.pms.service.yanfan.device.YfIotDeviceService;
 import cn.iocoder.yudao.module.pms.service.yanfan.sip.config.IotSipConfigService;
 import cn.iocoder.yudao.module.pms.service.yanfan.sip.model.RecordList;
 import cn.iocoder.yudao.module.pms.service.yanfan.sip.msg.Alarm;
@@ -30,37 +33,37 @@ public class VideoMqttService implements IMqttService {
     private IotSipConfigService sipConfigService;
 
     @Autowired
-    private IDeviceService deviceService;
+    private YfIotDeviceService deviceService;
 
     @Resource
     private TopicsUtils topicsUtils;
 
-//    @Override
-//    public void publishInfo(SipDevice device) {
-//        SipConfig sipConfig = sipConfigService.selectSipConfigBydeviceSipId(device.getDeviceSipId());
-//        if (null != sipConfig) {
-//            Device iotdevice = deviceService.selectDeviceBySerialNumber(device.getDeviceSipId());
-//            if (iotdevice == null ) {
-//                iotdevice = new Device();
-//                iotdevice.setSerialNumber(device.getDeviceSipId());
-//                iotdevice.setDeviceName(device.getDeviceName());
-//            }
-//            iotdevice.setProductId(sipConfig.getProductId());
-//            iotdevice.setProductName(device.getModel());
-//            iotdevice.setRssi(0);
-//            iotdevice.setStatus(3);
-//            iotdevice.setFirmwareVersion(BigDecimal.valueOf(1.0));
-//            iotdevice.setNetworkIp(device.getIp());
-//            SipDeviceSummary deviceSummary = new SipDeviceSummary(device);
-//            iotdevice.setSummary(JSON.toJSONString(deviceSummary));
-//            deviceService.updateDevice(iotdevice);
-//            Long productId = sipConfig.getProductId();
-//            if (null != productId && productId != -1L && productId != 0L) {
-//                String topic = topicsUtils.buildTopic(productId, device.getDeviceSipId(), TopicType.DEV_INFO_POST);
-//                mqttClient.publish(1, false, topic, JSON.toJSONString(iotdevice));
-//            }
-//        }
-//    }
+    @Override
+    public void publishInfo(YfSipDeviceDO device) {
+        IotSipConfigDO sipConfig = sipConfigService.selectSipConfigBydeviceSipId(device.getDeviceSipId());
+        if (null != sipConfig) {
+            YfIotDeviceDO iotdevice = deviceService.selectDeviceBySerialNumber(device.getDeviceSipId());
+            if (iotdevice == null ) {
+                iotdevice = new YfIotDeviceDO();
+                iotdevice.setSerialNumber(device.getDeviceSipId());
+                iotdevice.setDeviceName(device.getDeviceName());
+            }
+            iotdevice.setProductId(sipConfig.getProductId());
+            iotdevice.setProductName(device.getModel());
+            iotdevice.setRssi(0);
+            iotdevice.setStatus(3);
+            iotdevice.setFirmwareVersion(BigDecimal.valueOf(1.0));
+            iotdevice.setNetworkIp(device.getIp());
+            SipDeviceSummary deviceSummary = new SipDeviceSummary(device);
+            iotdevice.setSummary(JSON.toJSONString(deviceSummary));
+            deviceService.updateDevice(iotdevice);
+            Long productId = sipConfig.getProductId();
+            if (null != productId && productId != -1L && productId != 0L) {
+                String topic = topicsUtils.buildTopic(productId, device.getDeviceSipId(), TopicType.DEV_INFO_POST);
+                mqttClient.publish(1, false, topic, JSON.toJSONString(iotdevice));
+            }
+        }
+    }
 
     @Override
     public void publishStatus(YfSipDeviceDO device, int deviceStatus) {

+ 2 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/yanfan/sip/device/YfSipDeviceService.java

@@ -16,6 +16,8 @@ import javax.validation.Valid;
  * @author 超级管理员
  */
 public interface YfSipDeviceService {
+    int updateSipDeviceStatus(YfSipDeviceDO sipDevice);
+    boolean exists(String sipId);
     boolean updateDevice(YfSipDeviceDO device);
     YfSipDeviceDO selectSipDeviceBySipId(String sipId);
     /**

+ 11 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/yanfan/sip/device/YfSipDeviceServiceImpl.java

@@ -11,6 +11,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.time.LocalDateTime;
 import java.util.*;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
@@ -38,6 +39,16 @@ public class YfSipDeviceServiceImpl implements YfSipDeviceService {
     {
         return yfSipDeviceMapper.selectOne("device_sip_id", sipId);
     }
+    @Override
+    public boolean exists(String sipId) {
+        return yfSipDeviceMapper.selectSipDeviceBySipId(sipId) != null;
+    }
+
+    @Override
+    public int updateSipDeviceStatus(YfSipDeviceDO sipDevice) {
+        sipDevice.setUpdateTime(LocalDateTime.now());
+        return yfSipDeviceMapper.updateSipDeviceStatus(sipDevice);
+    }
 
 
     @Override

+ 2 - 1
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/yanfan/sip/device/channel/YfSipDeviceChannelServiceImpl.java

@@ -168,15 +168,16 @@ public class YfSipDeviceChannelServiceImpl implements YfSipDeviceChannelService
         String playrsid = String.format("%s_%s_%s", SipUtil.PREFIX_PLAYRECORD, channel.getDeviceSipId(), channel.getChannelSipId());
         VideoSessionInfo pinfo = streamSession.getSessionInfo(channel.getDeviceSipId(),
                 channel.getChannelSipId(), playsid, SessionType.play.name());
-        //todo yf
         if (pinfo != null) {
             channel.setStreamPush(pinfo.isPushing() ? 1 : 0);
+//        channel.setStreamPush(1);
         }
         VideoSessionInfo prinfo = streamSession.getSessionInfo(channel.getDeviceSipId(),
                 channel.getChannelSipId(), playrsid, SessionType.playrecord.name());
         if (prinfo != null) {
             channel.setStreamRecord(prinfo.isRecording() ? 1 : 0);
         }
+//        channel.setStreamRecord(0);
         return channel;
     }
 

+ 10 - 10
yudao-module-pms/yudao-module-pms-biz/src/main/resources/mapper/static/yanfan/YfSipDeviceChannelMapper.xml

@@ -9,7 +9,7 @@
         文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
      -->
        <update id="updateSipDeviceChannel" parameterType="cn.iocoder.yudao.module.pms.dal.dataobject.yanfan.sip.device.channel.YfSipDeviceChannelDO">
-              update sip_device_channel
+              update rq_yf_sip_device_channel
               <trim prefix="SET" suffixOverrides=",">
                      <if test="tenantId != null">tenant_id = #{tenantId},</if>
                      <if test="tenantName != null and tenantName != ''">tenant_name = #{tenantName},</if>
@@ -23,26 +23,26 @@
                      <if test="registerTime != null">register_time = #{registerTime},</if>
                      <if test="deviceType != null">device_type = #{deviceType},</if>
                      <if test="channelType != null">channel_type = #{channelType},</if>
-                     <if test="cityCode != null and cityCode != ''">cityCode = #{cityCode},</if>
-                     <if test="civilCode != null and civilCode != ''">civilCode = #{civilCode},</if>
+                     <if test="cityCode != null and cityCode != ''">city_code = #{cityCode},</if>
+                     <if test="civilCode != null and civilCode != ''">civil_code = #{civilCode},</if>
                      <if test="manufacture != null and manufacture != ''">manufacture = #{manufacture},</if>
                      <if test="model != null and model != ''">model = #{model},</if>
                      <if test="owner != null and owner != ''">owner = #{owner},</if>
                      <if test="block != null and block != ''">block = #{block},</if>
                      <if test="address != null and address != ''">address = #{address},</if>
-                     <if test="parentId != null and parentId != ''">parentId = #{parentId},</if>
-                     <if test="ipAddress != null">ipAddress = #{ipAddress},</if>
+                     <if test="parentId != null and parentId != ''">parent_id = #{parentId},</if>
+                     <if test="ipAddress != null">ip_address = #{ipAddress},</if>
                      <if test="port != null">port = #{port},</if>
                      <if test="password != null and password != ''">password = #{password},</if>
-                     <if test="ptzType != null">ptzType = #{ptzType},</if>
-                     <if test="ptzTypeText != null and ptzTypeText != ''">ptzTypeText = #{ptzTypeText},</if>
+                     <if test="ptzType != null">ptz_type = #{ptzType},</if>
+                     <if test="ptzTypeText != null and ptzTypeText != ''">ptz_type_text = #{ptzTypeText},</if>
                      <if test="status != null">status = #{status},</if>
                      <if test="longitude != null">longitude = #{longitude},</if>
                      <if test="latitude != null">latitude = #{latitude},</if>
-                     <if test="streamId != null and streamId != ''">streamId = #{streamId},</if>
-                     <if test="subCount != null">subCount = #{subCount},</if>
+                     <if test="streamId != null and streamId != ''">stream_id = #{streamId},</if>
+                     <if test="subCount != null">sub_count = #{subCount},</if>
                      <if test="parental != null">parental = #{parental},</if>
-                     <if test="hasAudio != null">hasAudio = #{hasAudio},</if>
+                     <if test="hasAudio != null">has_audio = #{hasAudio},</if>
                      <if test="delFlag != null and delFlag != ''">del_flag = #{delFlag},</if>
                      <if test="createBy != null and createBy != ''">create_by = #{createBy},</if>
                      <if test="createTime != null">create_time = #{createTime},</if>

+ 52 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/resources/mapper/static/yanfan/YfSipDeviceMapper.xml

@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.iocoder.yudao.module.pms.dal.mysql.yanfan.sip.device.YfSipDeviceMapper">
+
+    <!--
+        一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
+        无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
+        代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
+        文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
+     -->
+    <update id="updateSipDeviceStatus" parameterType="cn.iocoder.yudao.module.pms.dal.dataobject.yanfan.sip.device.YfSipDeviceDO">
+        update rq_yf_sip_device
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="online != null">online = #{online},</if>
+            <if test="lastConnectTime != null">last_connect_time = #{lastConnectTime},</if>
+            <if test="activeTime != null">active_time = #{activeTime},</if>
+            <if test="ip != null">ip = #{ip},</if>
+            <if test="port != null">port = #{port},</if>
+            <if test="hostAddress != null">host_address = #{hostAddress},</if>
+        </trim>
+        where device_sip_id = #{deviceSipId}
+    </update>
+
+
+    <select id="selectSipDeviceBySipId" parameterType="String" resultType="cn.iocoder.yudao.module.pms.dal.dataobject.yanfan.sip.device.YfSipDeviceDO">
+        select device_id,
+               product_id,
+               product_name,
+               device_sip_id,
+               device_name,
+               manufacturer,
+               model,
+               firmware,
+               transport,
+               stream_mode,
+               online,
+               register_time,
+               last_connect_time,
+               active_time,
+               ip,
+               port,
+               host_address,
+               del_flag,
+               create_by,
+               create_time,
+               update_by,
+               update_time,
+               remark
+        from rq_yf_sip_device
+        where device_sip_id = #{deviceSipId}
+    </select>
+</mapper>