diff --git a/pom.xml b/pom.xml index c6a626494..7ef99869c 100644 --- a/pom.xml +++ b/pom.xml @@ -60,6 +60,7 @@ ${project.build.directory}/asciidoc/html ${project.build.directory}/asciidoc/pdf + 21 21 21 diff --git a/src/main/java/com/genersoft/iot/vmp/VManageBootstrap.java b/src/main/java/com/genersoft/iot/vmp/VManageBootstrap.java index a1d3a527d..f99070f4e 100644 --- a/src/main/java/com/genersoft/iot/vmp/VManageBootstrap.java +++ b/src/main/java/com/genersoft/iot/vmp/VManageBootstrap.java @@ -1,5 +1,6 @@ package com.genersoft.iot.vmp; +import com.genersoft.iot.vmp.gb28181.event.EventPublisher; import com.genersoft.iot.vmp.jt1078.util.ClassUtil; import com.genersoft.iot.vmp.utils.GitUtil; import com.genersoft.iot.vmp.utils.SpringBeanFactory; @@ -43,6 +44,7 @@ public class VManageBootstrap extends SpringBootServletInitializer { log.info("构建时间: {}", gitUtil.getBuildDate()); log.info("GIT信息: 分支: {}, ID: {}, 时间: {}", gitUtil.getBranch(), gitUtil.getCommitIdShort(), gitUtil.getCommitTime()); } + } // 项目重启 public static void restart() { diff --git a/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java b/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java index e89695aff..e848d38f4 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java +++ b/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java @@ -19,6 +19,8 @@ public class VideoManagerConstants { public static final String ONLINE_MEDIA_SERVERS_PREFIX = "VMP_ONLINE_MEDIA_SERVERS:"; public static final String DEVICE_PREFIX = "VMP_DEVICE_INFO"; + public static final String DEVICE_KEEPALIVE_PREFIX = "VMP_DEVICE_KEEPALIVE:"; + public static final String DEVICE_REGISTER_PREFIX = "VMP_DEVICE_REGISTER:"; public static final String INVITE_PREFIX = "VMP_GB_INVITE_INFO"; diff --git a/src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java b/src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java index 3a1fb917a..44b82488b 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java @@ -2,11 +2,11 @@ package com.genersoft.iot.vmp.conf; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ObjectUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.stereotype.Component; -import jakarta.annotation.PostConstruct; import java.time.Instant; import java.util.Date; import java.util.Map; @@ -23,20 +23,12 @@ import java.util.concurrent.TimeUnit; @Component public class DynamicTask { - private ThreadPoolTaskScheduler threadPoolTaskScheduler; + @Autowired + private TaskScheduler taskScheduler; private final Map> futureMap = new ConcurrentHashMap<>(); private final Map runnableMap = new ConcurrentHashMap<>(); - @PostConstruct - public void DynamicTask() { - threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); - threadPoolTaskScheduler.setPoolSize(300); - threadPoolTaskScheduler.setWaitForTasksToCompleteOnShutdown(true); - threadPoolTaskScheduler.setAwaitTerminationSeconds(10); - threadPoolTaskScheduler.setThreadNamePrefix("dynamicTask-"); - threadPoolTaskScheduler.initialize(); - } /** * 循环执行的任务 @@ -60,7 +52,7 @@ public class DynamicTask { } // scheduleWithFixedDelay 必须等待上一个任务结束才开始计时period, cycleForCatalog表示执行的间隔 - future = threadPoolTaskScheduler.scheduleAtFixedRate(task, new Date(System.currentTimeMillis() + cycleForCatalog), cycleForCatalog); + future = taskScheduler.scheduleAtFixedRate(task, new Date(System.currentTimeMillis() + cycleForCatalog), cycleForCatalog); if (future != null){ futureMap.put(key, future); runnableMap.put(key, task); @@ -96,7 +88,7 @@ public class DynamicTask { } } // scheduleWithFixedDelay 必须等待上一个任务结束才开始计时period, cycleForCatalog表示执行的间隔 - future = threadPoolTaskScheduler.schedule(task, startInstant); + future = taskScheduler.schedule(task, startInstant); if (future != null){ futureMap.put(key, future); runnableMap.put(key, task); diff --git a/src/main/java/com/genersoft/iot/vmp/conf/ScheduleConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/ScheduleConfig.java deleted file mode 100644 index df88bcf3a..000000000 --- a/src/main/java/com/genersoft/iot/vmp/conf/ScheduleConfig.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.genersoft.iot.vmp.conf; - -import org.apache.commons.lang3.concurrent.BasicThreadFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.context.annotation.Configuration; -import org.springframework.scheduling.annotation.SchedulingConfigurer; -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; -import org.springframework.scheduling.config.ScheduledTaskRegistrar; - -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.ThreadPoolExecutor; - -import static com.genersoft.iot.vmp.conf.ThreadPoolTaskConfig.cpuNum; - -/** - * "@Scheduled"是Spring框架提供的一种定时任务执行机制,默认情况下它是单线程的,在同时执行多个定时任务时可能会出现阻塞和性能问题。 - * 为了解决这种单线程瓶颈问题,可以将定时任务的执行机制改为支持多线程 - */ -@Configuration -public class ScheduleConfig implements SchedulingConfigurer { - - /** - * 核心线程数(默认线程数) - */ - private static final int corePoolSize = Math.max(cpuNum, 20); - - /** - * 线程池名前缀 - */ - private static final String threadNamePrefix = "schedule"; - - @Override - public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { - ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(corePoolSize, - new BasicThreadFactory.Builder().namingPattern(threadNamePrefix).daemon(true).build(), - new ThreadPoolExecutor.CallerRunsPolicy()); - taskRegistrar.setScheduler(scheduledThreadPoolExecutor); - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/conf/SchedulingConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/SchedulingConfig.java new file mode 100644 index 000000000..6896ca63a --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/conf/SchedulingConfig.java @@ -0,0 +1,20 @@ +package com.genersoft.iot.vmp.conf; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.TaskScheduler; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; + +@Configuration +public class SchedulingConfig { + + @Bean + public TaskScheduler taskScheduler() { + ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); + scheduler.setPoolSize(5); + scheduler.setThreadNamePrefix("scheduled-"); + scheduler.setVirtualThreads(true); // 必须在 initialize() 之前 + scheduler.initialize(); + return scheduler; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/conf/SystemInfoTimerTask.java b/src/main/java/com/genersoft/iot/vmp/conf/SystemInfoTimerTask.java index 0c6eb2359..581fd5694 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/SystemInfoTimerTask.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/SystemInfoTimerTask.java @@ -20,22 +20,22 @@ public class SystemInfoTimerTask { @Autowired private IRedisCatchStorage redisCatchStorage; - @Scheduled(fixedRate = 2000) //每1秒执行一次 - public void execute(){ - try { - double cpuInfo = SystemInfoUtils.getCpuInfo(); - redisCatchStorage.addCpuInfo(cpuInfo); - double memInfo = SystemInfoUtils.getMemInfo(); - redisCatchStorage.addMemInfo(memInfo); - Map networkInterfaces = SystemInfoUtils.getNetworkInterfaces(); - redisCatchStorage.addNetInfo(networkInterfaces); - List> diskInfo =SystemInfoUtils.getDiskInfo(); - redisCatchStorage.addDiskInfo(diskInfo); - } catch (InterruptedException e) { - log.error("[获取系统信息失败] {}", e.getMessage()); - } - - } +// @Scheduled(fixedRate = 2000) //每1秒执行一次 +// public void execute(){ +// try { +// double cpuInfo = SystemInfoUtils.getCpuInfo(); +// redisCatchStorage.addCpuInfo(cpuInfo); +// double memInfo = SystemInfoUtils.getMemInfo(); +// redisCatchStorage.addMemInfo(memInfo); +// Map networkInterfaces = SystemInfoUtils.getNetworkInterfaces(); +// redisCatchStorage.addNetInfo(networkInterfaces); +// List> diskInfo =SystemInfoUtils.getDiskInfo(); +// redisCatchStorage.addDiskInfo(diskInfo); +// } catch (InterruptedException e) { +// log.error("[获取系统信息失败] {}", e.getMessage()); +// } +// +// } } diff --git a/src/main/java/com/genersoft/iot/vmp/conf/ThreadPoolTaskConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/ThreadPoolTaskConfig.java deleted file mode 100644 index a549a053a..000000000 --- a/src/main/java/com/genersoft/iot/vmp/conf/ThreadPoolTaskConfig.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.genersoft.iot.vmp.conf; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.annotation.Order; -import org.springframework.scheduling.annotation.EnableAsync; -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; - -import java.util.concurrent.ThreadPoolExecutor; - -/** - * ThreadPoolTask 配置类 - * @author lin - */ -@Configuration -@Order(1) -@EnableAsync(proxyTargetClass = true) -public class ThreadPoolTaskConfig { - - public static final int cpuNum = Runtime.getRuntime().availableProcessors(); - - /** - * 默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务, - * 当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中; - * 当队列满了,就继续创建线程,当线程数量大于等于maxPoolSize后,开始使用拒绝策略拒绝 - */ - - /** - * 核心线程数(默认线程数) - */ - private static final int corePoolSize = Math.max(cpuNum * 2, 16); - /** - * 最大线程数 - */ - private static final int maxPoolSize = corePoolSize * 10; - /** - * 允许线程空闲时间(单位:默认为秒) - */ - private static final int keepAliveTime = 30; - - /** - * 缓冲队列大小 - */ - private static final int queueCapacity = 10000; - /** - * 线程池名前缀 - */ - private static final String threadNamePrefix = "async-"; - - - @Bean("taskExecutor") // bean的名称,默认为首字母小写的方法名 - public ThreadPoolTaskExecutor taskExecutor() { - ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); - executor.setCorePoolSize(corePoolSize); - executor.setMaxPoolSize(maxPoolSize); - executor.setQueueCapacity(queueCapacity); - executor.setKeepAliveSeconds(keepAliveTime); - executor.setThreadNamePrefix(threadNamePrefix); - - // 线程池对拒绝任务的处理策略 - // CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务 - executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); - // 初始化 - executor.initialize(); - return executor; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java b/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java index bf059acca..ef3614258 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java @@ -224,4 +224,11 @@ public class UserSetting { */ private boolean deviceIdStrict = true; + /** + * 对于识别为设备的国标设备的,是否默认开启位置订阅 + */ + private boolean subscribeMobilePosition = false; + + + } diff --git a/src/main/java/com/genersoft/iot/vmp/conf/redis/RedisRpcConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/redis/RedisRpcConfig.java index e413d7240..779fe9eda 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/redis/RedisRpcConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/redis/RedisRpcConfig.java @@ -11,11 +11,10 @@ import com.genersoft.iot.vmp.service.redisMsg.dto.RpcController; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.core.task.TaskExecutor; import org.springframework.data.redis.connection.Message; import org.springframework.data.redis.connection.MessageListener; import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Component; import java.lang.reflect.Method; @@ -43,9 +42,8 @@ public class RedisRpcConfig implements MessageListener { private ConcurrentLinkedQueue taskQueue = new ConcurrentLinkedQueue<>(); - @Qualifier("taskExecutor") @Autowired - private ThreadPoolTaskExecutor taskExecutor; + private TaskExecutor taskExecutor; private final static Map protocolHash = new HashMap<>(); diff --git a/src/main/java/com/genersoft/iot/vmp/conf/redis/RedisTemplateConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/redis/RedisTemplateConfig.java index f36a4d555..3bfee31ba 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/redis/RedisTemplateConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/redis/RedisTemplateConfig.java @@ -6,6 +6,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.GenericToStringSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; @Configuration @@ -43,4 +44,22 @@ public class RedisTemplateConfig { return redisTemplate; } + @Bean + public RedisTemplate redisLongTemplate(RedisConnectionFactory connectionFactory) { + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(connectionFactory); + + // Key 使用 String 序列化 + template.setKeySerializer(new StringRedisSerializer()); + template.setHashKeySerializer(new StringRedisSerializer()); + + // Value 使用 GenericToStringSerializer,它能将 Long 转换为纯文本字符串存入 Redis + // 这样在 Redis 命令行输入 'get key' 看到的是 "123" 而不是二进制乱码 + template.setValueSerializer(new GenericToStringSerializer<>(Long.class)); + template.setHashValueSerializer(new GenericToStringSerializer<>(Long.class)); + + template.afterPropertiesSet(); + return template; + } + } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java index 83a302ecc..83f1a6b3c 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java @@ -89,15 +89,15 @@ public class Device { /** * 注册时间 */ - @Schema(description = "注册时间") - private String registerTime; + @Schema(description = "注册时间戳") + private Long registerTimeStamp; /** * 心跳时间 */ @Schema(description = "心跳时间") - private String keepaliveTime; + private Long keepaliveTimeStamp; /** @@ -216,4 +216,18 @@ public class Device { public boolean checkWgs84() { return geoCoordSys.equalsIgnoreCase("WGS84"); } + + public Integer getHeartBeatCount() { + if (heartBeatCount == null) { + return 3; + } + return heartBeatCount; + } + + public Integer getHeartBeatInterval() { + if (heartBeatCount == null) { + return 60; + } + return heartBeatInterval; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/TimeStatistics.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/TimeStatistics.java new file mode 100644 index 000000000..975f858ec --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/TimeStatistics.java @@ -0,0 +1,20 @@ +package com.genersoft.iot.vmp.gb28181.bean; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +@Schema(description = "时间统计信息") +public class TimeStatistics { + + @Schema(description = "时间") + private String time; + + @Schema(description = "时间差") + private Long timeDiff; +} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/DeviceQuery.java b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/DeviceQuery.java index a956ec6c0..7d8d62946 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/DeviceQuery.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/DeviceQuery.java @@ -8,6 +8,7 @@ import com.genersoft.iot.vmp.conf.security.JwtUtils; import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; import com.genersoft.iot.vmp.gb28181.bean.SyncStatus; +import com.genersoft.iot.vmp.gb28181.bean.TimeStatistics; import com.genersoft.iot.vmp.gb28181.service.IDeviceChannelService; import com.genersoft.iot.vmp.gb28181.service.IDeviceService; import com.genersoft.iot.vmp.gb28181.service.IInviteStreamService; @@ -21,8 +22,10 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.compress.utils.IOUtils; +import org.apache.commons.io.IOUtils; import org.apache.ibatis.annotations.Options; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; @@ -31,12 +34,11 @@ import org.springframework.util.ObjectUtils; import org.springframework.web.bind.annotation.*; import org.springframework.web.context.request.async.DeferredResult; -import jakarta.servlet.ServletOutputStream; -import jakarta.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; +import java.util.List; @Tag(name = "国标设备查询", description = "国标设备查询") @SuppressWarnings("rawtypes") @@ -136,7 +138,7 @@ public class DeviceQuery { log.debug("设备通道信息同步API调用,deviceId:" + deviceId); } Device device = deviceService.getDeviceByDeviceId(deviceId); - if (device.getRegisterTime() == null) { + if (device.getTransport() == null) { WVPResult wvpResult = new WVPResult<>(); wvpResult.setCode(ErrorCode.ERROR100.getCode()); wvpResult.setMsg("设备尚未注册过"); @@ -155,7 +157,7 @@ public class DeviceQuery { log.debug("设备信息删除API调用,deviceId:" + deviceId); } - // 清除redis记录 + // 清除 redis 记录 deviceService.delete(deviceId); JSONObject json = new JSONObject(); json.put("deviceId", deviceId); @@ -181,8 +183,7 @@ public class DeviceQuery { DeviceChannel deviceChannel = deviceChannelService.getOne(deviceId,channelId); if (deviceChannel == null) { - PageInfo deviceChannelPageResult = new PageInfo<>(); - return deviceChannelPageResult; + return new PageInfo<>(); } return deviceChannelService.getSubChannels(deviceChannel.getDataDeviceId(), channelId, query, channelType, online, page, count); @@ -431,6 +432,30 @@ public class DeviceQuery { deviceService.subscribeMobilePosition(id, cycle, interval); } + @GetMapping("/statistics/keepalive") + @Operation(summary = "请求心跳统计") + @Parameter(name = "deviceId", description = "设备国标编号", required = true) + @Parameter(name = "count", description = "返回的数量,按时间正向排序,返回的最新的", required = true) + public List getKeepaliveTimeStatistics(String deviceId, Integer count) { + if (ObjectUtils.isEmpty(deviceId)) { + return List.of(); + } + return deviceService.getKeepaliveTimeStatistics(deviceId, count); + } + + @GetMapping("/statistics/register") + @Operation(summary = "请求注册统计") + @Parameter(name = "deviceId", description = "设备国标编号", required = true) + @Parameter(name = "count", description = "返回的数量,按时间正向排序,返回的最新的", required = true) + public List getRegisterTimeStatistics(String deviceId, Integer count) { + if (ObjectUtils.isEmpty(deviceId)) { + return List.of(); + } + return deviceService.getRegisterTimeStatistics(deviceId, count); + } + + + @GetMapping("/subscribe/alarm") @Operation(summary = "开启/关闭报警订阅") @Parameter(name = "id", description = "通道的Id", required = true) diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/CommonGBChannelMapper.java b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/CommonGBChannelMapper.java index f24b73986..a264cf747 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/CommonGBChannelMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/CommonGBChannelMapper.java @@ -591,6 +591,9 @@ public interface CommonGBChannelMapper { @SelectProvider(type = ChannelProvider.class, method = "queryOnlineListsByGbDeviceId") List queryOnlineListsByGbDeviceId(@Param("deviceId") int deviceId); + @SelectProvider(type = ChannelProvider.class, method = "queryOnlineListsByGbDeviceIds") + List queryOnlineListsByGbDeviceIds(List deviceList); + @SelectProvider(type = ChannelProvider.class, method = "queryCommonChannelByDeviceChannel") CommonGBChannel queryCommonChannelByDeviceChannel(@Param("dataType") Integer dataType, @Param("dataDeviceId") Integer dataDeviceId, @Param("deviceId") String deviceId); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/DeviceChannelMapper.java b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/DeviceChannelMapper.java index 77e9e5ecb..b41cf183b 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/DeviceChannelMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/DeviceChannelMapper.java @@ -610,5 +610,11 @@ public interface DeviceChannelMapper { @Update(value = {"UPDATE wvp_device_channel SET status = 'OFF' WHERE data_type = 1 and data_device_id=#{deviceId}"}) void offlineByDeviceId(@Param("deviceId") int deviceId); + @Update(value = {""}) + void offlineByDeviceIds(List deviceList); + } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/DeviceMapper.java b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/DeviceMapper.java index ded02979f..a14528352 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/DeviceMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/DeviceMapper.java @@ -30,8 +30,6 @@ public interface DeviceMapper { "port," + "host_address," + "expires," + - "register_time," + - "keepalive_time," + "create_time," + "update_time," + "charset," + @@ -65,8 +63,6 @@ public interface DeviceMapper { "port," + "host_address," + "expires," + - "register_time," + - "keepalive_time," + "heart_beat_interval," + "heart_beat_count," + "position_capability," + @@ -98,8 +94,6 @@ public interface DeviceMapper { "#{port}," + "#{hostAddress}," + "#{expires}," + - "#{registerTime}," + - "#{keepaliveTime}," + "#{heartBeatInterval}," + "#{heartBeatCount}," + "#{positionCapability}," + @@ -133,8 +127,6 @@ public interface DeviceMapper { ", port=#{port}" + ", host_address=#{hostAddress}" + ", on_line=#{onLine}" + - ", register_time=#{registerTime}" + - ", keepalive_time=#{keepaliveTime}" + ", heart_beat_interval=#{heartBeatInterval}" + ", position_capability=#{positionCapability}" + ", heart_beat_count=#{heartBeatCount}" + @@ -166,8 +158,6 @@ public interface DeviceMapper { "port,"+ "host_address,"+ "expires,"+ - "register_time,"+ - "keepalive_time,"+ "create_time,"+ "update_time,"+ "charset,"+ @@ -208,8 +198,6 @@ public interface DeviceMapper { "port,"+ "host_address,"+ "expires,"+ - "register_time,"+ - "keepalive_time,"+ "create_time,"+ "update_time,"+ "charset,"+ @@ -242,8 +230,6 @@ public interface DeviceMapper { "port,"+ "host_address,"+ "expires,"+ - "register_time,"+ - "keepalive_time,"+ "create_time,"+ "update_time,"+ "charset,"+ @@ -277,8 +263,6 @@ public interface DeviceMapper { "port,"+ "host_address,"+ "expires,"+ - "register_time,"+ - "keepalive_time,"+ "create_time,"+ "update_time,"+ "charset,"+ @@ -356,8 +340,6 @@ public interface DeviceMapper { ",transport" + ",stream_mode" + ",on_line" + - ",register_time" + - ",keepalive_time" + ",ip" + ",create_time" + ",update_time" + @@ -444,8 +426,6 @@ public interface DeviceMapper { ", port=#{item.port}" + ", host_address=#{item.hostAddress}" + ", on_line=#{item.onLine}" + - ", register_time=#{item.registerTime}" + - ", keepalive_time=#{item.keepaliveTime}" + ", heart_beat_interval=#{item.heartBeatInterval}" + ", position_capability=#{item.positionCapability}" + ", heart_beat_count=#{item.heartBeatCount}" + @@ -460,7 +440,6 @@ public interface DeviceMapper { ""}) void batchUpdate(List devices); - @Select(value = {" diff --git a/数据库/2.7.4/初始化-mysql-2.7.4.sql b/数据库/2.7.4/初始化-mysql-2.7.4.sql index 4a233da00..594f77c4d 100644 --- a/数据库/2.7.4/初始化-mysql-2.7.4.sql +++ b/数据库/2.7.4/初始化-mysql-2.7.4.sql @@ -12,8 +12,6 @@ create table IF NOT EXISTS wvp_device transport character varying(50) COMMENT '信令传输协议(TCP/UDP)', stream_mode character varying(50) COMMENT '拉流方式(主动/被动)', on_line bool default false COMMENT '在线状态', - register_time character varying(50) COMMENT '注册时间', - keepalive_time character varying(50) COMMENT '最近心跳时间', ip character varying(50) COMMENT '设备IP地址', create_time character varying(50) COMMENT '创建时间', update_time character varying(50) COMMENT '更新时间', @@ -207,8 +205,7 @@ create table IF NOT EXISTS wvp_media_server record_path character varying(255) COMMENT '录像目录', record_day integer default 7 COMMENT '录像保留天数', transcode_suffix character varying(255) COMMENT '转码指令后缀', - server_id character varying(50) COMMENT '对应信令服务器ID', - constraint uk_media_server_unique_ip_http_port unique (ip, http_port, server_id) + server_id character varying(50) COMMENT '对应信令服务器ID' ); -- 上级国标平台注册信息 diff --git a/数据库/2.7.4/初始化-postgresql-kingbase-2.7.4.sql b/数据库/2.7.4/初始化-postgresql-kingbase-2.7.4.sql index 8128c1bfc..34b291a0c 100644 --- a/数据库/2.7.4/初始化-postgresql-kingbase-2.7.4.sql +++ b/数据库/2.7.4/初始化-postgresql-kingbase-2.7.4.sql @@ -11,8 +11,6 @@ create table IF NOT EXISTS wvp_device transport character varying(50), stream_mode character varying(50), on_line bool default false, - register_time character varying(50), - keepalive_time character varying(50), ip character varying(50), create_time character varying(50), update_time character varying(50), @@ -49,8 +47,6 @@ COMMENT ON COLUMN wvp_device.firmware IS '固件版本号'; COMMENT ON COLUMN wvp_device.transport IS '信令传输协议(TCP/UDP)'; COMMENT ON COLUMN wvp_device.stream_mode IS '拉流方式(主动/被动)'; COMMENT ON COLUMN wvp_device.on_line IS '在线状态'; -COMMENT ON COLUMN wvp_device.register_time IS '注册时间'; -COMMENT ON COLUMN wvp_device.keepalive_time IS '最近心跳时间'; COMMENT ON COLUMN wvp_device.ip IS '设备IP地址'; COMMENT ON COLUMN wvp_device.create_time IS '创建时间'; COMMENT ON COLUMN wvp_device.update_time IS '更新时间'; @@ -355,7 +351,6 @@ create table IF NOT EXISTS wvp_media_server record_day integer default 7, transcode_suffix character varying(255), server_id character varying(50), - constraint uk_media_server_unique_ip_http_port unique (ip, http_port, server_id) ); COMMENT ON TABLE wvp_media_server IS '媒体服务器(如 ZLM)节点信息'; COMMENT ON COLUMN wvp_media_server.id IS '媒体服务器ID'; diff --git a/数据库/2.7.4/更新-mysql-2.7.4.sql b/数据库/2.7.4/更新-mysql-2.7.4.sql index 7cca80e50..823c9a074 100644 --- a/数据库/2.7.4/更新-mysql-2.7.4.sql +++ b/数据库/2.7.4/更新-mysql-2.7.4.sql @@ -118,6 +118,29 @@ call wvp_20251027(); DROP PROCEDURE wvp_20251027; DELIMITER ; +drop index uk_media_server_unique_ip_http_port on wvp_media_server; + +/* +* 202601025 +*/ +DELIMITER // -- 重定义分隔符避免分号冲突 +CREATE PROCEDURE `wvp_202601025`() +BEGIN + IF EXISTS (SELECT column_name FROM information_schema.columns + WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_device' and column_name = 'register_time') + THEN + ALTER TABLE wvp_device DROP register_time; + END IF; + IF EXISTS (SELECT column_name FROM information_schema.columns + WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_device' and column_name = 'keepalive_time') + THEN + ALTER TABLE wvp_device DROP keepalive_time; + END IF; +END; // +call wvp_202601025(); +DROP PROCEDURE wvp_202601025; +DELIMITER ; + diff --git a/数据库/2.7.4/更新-postgresql-kingbase-2.7.4.sql b/数据库/2.7.4/更新-postgresql-kingbase-2.7.4.sql index 5cc34f980..c88765ccb 100644 --- a/数据库/2.7.4/更新-postgresql-kingbase-2.7.4.sql +++ b/数据库/2.7.4/更新-postgresql-kingbase-2.7.4.sql @@ -42,3 +42,8 @@ ALTER table wvp_device_channel ADD COLUMN IF NOT EXISTS enable_broadcast integer ALTER table wvp_device_channel ADD COLUMN IF NOT EXISTS map_level integer default 0; ALTER table wvp_common_group ADD COLUMN IF NOT EXISTS alias varchar(255) default null; ALTER table wvp_stream_proxy DROP COLUMN IF EXISTS enable_remove_none_reader; + +drop index uk_media_server_unique_ip_http_port on wvp_media_server; + +ALTER table wvp_device DROP COLUMN IF EXISTS register_time; +ALTER table wvp_device DROP COLUMN IF EXISTS keepalive_time;