From a2e7e8ff9cfaa69b001d483710bddbda50d55c91 Mon Sep 17 00:00:00 2001
From: liusuyi <1951119284@qq.com>
Date: Mon, 01 Jun 2026 16:14:19 +0800
Subject: [PATCH] 优化

---
 ard-modules/ard-modules-gb28181/src/main/java/com/ard/gb28181/api/Gb28181ApiController.java |  304 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 302 insertions(+), 2 deletions(-)

diff --git a/ard-modules/ard-modules-gb28181/src/main/java/com/ard/gb28181/api/Gb28181ApiController.java b/ard-modules/ard-modules-gb28181/src/main/java/com/ard/gb28181/api/Gb28181ApiController.java
index bbaa09c..2923efb 100644
--- a/ard-modules/ard-modules-gb28181/src/main/java/com/ard/gb28181/api/Gb28181ApiController.java
+++ b/ard-modules/ard-modules-gb28181/src/main/java/com/ard/gb28181/api/Gb28181ApiController.java
@@ -5,10 +5,13 @@
 import com.ard.common.core.domain.R;
 import com.ard.common.core.domain.RtpServerParam;
 import com.ard.common.core.exception.ServiceException;
-import com.ard.gb28181.api.domain.Device;
-import com.ard.gb28181.api.domain.DeviceChannel;
+import com.ard.gb28181.api.domain.*;
 import com.ard.gb28181.config.UserSetting;
+import com.ard.gb28181.domain.GbChannel;
+import com.ard.gb28181.domain.GbDevice;
 import com.ard.gb28181.service.IDeviceService;
+import com.ard.gb28181.service.IGbChannelService;
+import com.ard.gb28181.service.IGbDeviceService;
 import com.ard.gb28181.service.ISIPCommander;
 import com.ard.gb28181.session.SipInviteSessionManager;
 import com.ard.zlm.api.RemoteZlmService;
@@ -18,11 +21,15 @@
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.context.request.async.DeferredResult;
 
 import javax.sip.ResponseEvent;
+import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeUnit;
 
@@ -48,6 +55,12 @@
 
     @Autowired
     private RemoteZlmService remoteZlmService;
+
+    @Autowired
+    private IGbDeviceService gbDeviceService;
+
+    @Autowired
+    private IGbChannelService gbChannelService;
 
     /**
      * 根据设备id获取设备
@@ -686,4 +699,291 @@
         }
         frontEndCommand(deviceId, channelId, cmdCode, switchId, 0, 0);
     }
+
+    // ==================== GbDevice / GbChannel 管理接口 ====================
+
+    /**
+     * 根据国标设备ID获取GbDevice
+     */
+    @GetMapping("/getGbDevice/{gbDeviceId}")
+    public R<GbDeviceDTO> getGbDevice(@PathVariable String gbDeviceId) {
+        GbDevice gbDevice = gbDeviceService.selectGbDeviceByGbDeviceId(gbDeviceId);
+        if (gbDevice == null) {
+            return R.fail("GbDevice不存在 gbDeviceId:" + gbDeviceId);
+        }
+        return R.ok(toGbDeviceDTO(gbDevice));
+    }
+
+    /**
+     * 获取所有GbDevice列表
+     */
+    @GetMapping("/getAllGbDevices")
+    public R<List<GbDeviceDTO>> getAllGbDevices() {
+        List<GbDevice> list = gbDeviceService.selectGbDeviceList(new GbDevice());
+        List<GbDeviceDTO> dtoList = new ArrayList<>();
+        for (GbDevice d : list) {
+            dtoList.add(toGbDeviceDTO(d));
+        }
+        return R.ok(dtoList);
+    }
+
+    /**
+     * 根据主键ID获取GbChannel
+     */
+    @GetMapping("/getGbChannelById/{id}")
+    public R<GbChannelDTO> getGbChannelById(@PathVariable Long id) {
+        GbChannel gbChannel = gbChannelService.selectGbChannelById(id);
+        if (gbChannel == null) {
+            return R.fail("GbChannel不存在 id:" + id);
+        }
+        return R.ok(toGbChannelDTO(gbChannel));
+    }
+
+    /**
+     * 根据国标设备ID和通道ID获取GbChannel
+     */
+    @GetMapping("/getGbChannel/{gbDeviceId}/{gbChannelId}")
+    public R<GbChannelDTO> getGbChannel(@PathVariable String gbDeviceId, @PathVariable String gbChannelId) {
+        GbChannel gbChannel = gbChannelService.selectByGbDeviceIdAndGbChannelId(gbDeviceId, gbChannelId);
+        if (gbChannel == null) {
+            return R.fail("GbChannel不存在 gbDeviceId:" + gbDeviceId + " gbChannelId:" + gbChannelId);
+        }
+        return R.ok(toGbChannelDTO(gbChannel));
+    }
+
+    /**
+     * 根据国标设备ID获取所有通道
+     */
+    @GetMapping("/getGbChannelsByDeviceId/{gbDeviceId}")
+    public R<List<GbChannelDTO>> getGbChannelsByDeviceId(@PathVariable String gbDeviceId) {
+        List<GbChannel> list = gbChannelService.selectGbChannelByGbDeviceId(gbDeviceId);
+        List<GbChannelDTO> dtoList = new ArrayList<>();
+        for (GbChannel c : list) {
+            dtoList.add(toGbChannelDTO(c));
+        }
+        return R.ok(dtoList);
+    }
+
+    /**
+     * 更新GbChannel流状态
+     */
+    @PostMapping("/updateGbChannelStream")
+    R<Boolean> updateGbChannelStream(@RequestBody GbChannelDTO dto) {
+        GbChannel gbChannel = new GbChannel();
+        gbChannel.setId(dto.getId());
+        gbChannel.setStreamStatus(dto.getStreamStatus());
+        gbChannel.setStreamKey(dto.getStreamKey());
+        gbChannel.setMediaServerId(dto.getMediaServerId());
+        gbChannel.setSnap(dto.getSnap());
+        gbChannelService.updateGbChannelStream(gbChannel);
+        return R.ok(true);
+    }
+
+    private GbDeviceDTO toGbDeviceDTO(GbDevice d) {
+        GbDeviceDTO dto = new GbDeviceDTO();
+        dto.setId(d.getId());
+        dto.setGbDeviceId(d.getGbDeviceId());
+        dto.setDeviceName(d.getDeviceName());
+        dto.setDeviceCode(d.getDeviceCode());
+        dto.setIp(d.getIp());
+        dto.setPort(d.getPort());
+        dto.setManufacturer(d.getManufacturer());
+        dto.setModel(d.getModel());
+        dto.setFirmware(d.getFirmware());
+        dto.setOnLine(d.getOnLine());
+        return dto;
+    }
+
+    private GbChannelDTO toGbChannelDTO(GbChannel c) {
+        GbChannelDTO dto = new GbChannelDTO();
+        dto.setId(c.getId());
+        dto.setGbDeviceId(c.getGbDeviceId());
+        dto.setGbChannelId(c.getGbChannelId());
+        dto.setChannelName(c.getChannelName());
+        dto.setDeviceCode(c.getDeviceCode());
+        dto.setStreamMode(c.getStreamMode());
+        dto.setEnableMp4(c.getEnableMp4());
+        dto.setStreamStatus(c.getStreamStatus());
+        dto.setMediaServerId(c.getMediaServerId());
+        dto.setStreamKey(c.getStreamKey());
+        dto.setSnap(c.getSnap());
+        return dto;
+    }
+
+    /**
+     * 一键迁移:将 Redis 中已注册的国标设备同步到 MySQL(供首次执行 SQL 后使用)
+     */
+    @Operation(summary = "迁移Redis国标设备到MySQL")
+    @PostMapping("/migrateGbDevices")
+    public R<String> migrateGbDevices() {
+        List<Device> allDevices = deviceService.getAllDevices();
+        int deviceCount = 0;
+        int channelCount = 0;
+
+        for (Device device : allDevices) {
+            try {
+                // 创建设备记录
+                GbDevice existingDevice = gbDeviceService.selectGbDeviceByGbDeviceId(device.getDeviceId());
+                if (existingDevice == null) {
+                    GbDevice gbDevice = new GbDevice();
+                    gbDevice.setGbDeviceId(device.getDeviceId());
+                    gbDevice.setDeviceName(StringUtils.hasText(device.getName()) ? device.getName() : device.getDeviceId());
+                    gbDevice.setDeviceCode(device.getDeviceId());
+                    gbDevice.setIp(device.getIp());
+                    gbDevice.setPort(device.getPort());
+                    gbDevice.setManufacturer(device.getManufacturer());
+                    gbDevice.setModel(device.getModel());
+                    gbDevice.setFirmware(device.getFirmware());
+                    gbDevice.setOnLine(device.isOnLine());
+                    gbDeviceService.insertGbDevice(gbDevice);
+                    deviceCount++;
+                    log.info("[迁移] 创建设备: {}", device.getDeviceId());
+                }
+
+                // 创建默认通道(设备自身)
+                GbChannel existingDefaultChannel = gbChannelService.selectByGbDeviceIdAndGbChannelId(
+                        device.getDeviceId(), device.getDeviceId());
+                if (existingDefaultChannel == null) {
+                    GbChannel gbChannel = new GbChannel();
+                    gbChannel.setGbDeviceId(device.getDeviceId());
+                    gbChannel.setGbChannelId(device.getDeviceId());
+                    gbChannel.setChannelName(StringUtils.hasText(device.getName()) ? device.getName() : device.getDeviceId());
+                    gbChannel.setDeviceCode(device.getDeviceId());
+                    gbChannel.setStreamMode(device.getStreamMode() != null ? device.getStreamMode() : "TCP-PASSIVE");
+                    gbChannel.setEnableMp4("0");
+                    gbChannelService.insertGbChannel(gbChannel);
+                    channelCount++;
+                }
+
+                // 创建所有通道
+                List<DeviceChannel> channels = deviceService.getChannelsByDeviceId(device.getDeviceId());
+                if (channels != null) {
+                    for (DeviceChannel channel : channels) {
+                        String channelId = channel.getDeviceId();
+                        if (channelId == null || channelId.length() <= 8) {
+                            continue;
+                        }
+                        if (channelId.length() == 20) {
+                            try {
+                                com.ard.gb28181.api.domain.GbCode gbCode = com.ard.gb28181.api.domain.GbCode.decode(channelId);
+                                if (gbCode != null && ("215".equals(gbCode.getTypeCode()) || "216".equals(gbCode.getTypeCode()))) {
+                                    continue;
+                                }
+                            } catch (Exception ignored) {}
+                        }
+                        GbChannel existing = gbChannelService.selectByGbDeviceIdAndGbChannelId(device.getDeviceId(), channelId);
+                        if (existing == null) {
+                            GbChannel gbChannel = new GbChannel();
+                            gbChannel.setGbDeviceId(device.getDeviceId());
+                            gbChannel.setGbChannelId(channelId);
+                            gbChannel.setChannelName(StringUtils.hasText(channel.getName()) ? channel.getName() : channelId);
+                            gbChannel.setDeviceCode(channelId);
+                            gbChannel.setStreamMode(device.getStreamMode() != null ? device.getStreamMode() : "TCP-PASSIVE");
+                            gbChannel.setEnableMp4("0");
+                            gbChannelService.insertGbChannel(gbChannel);
+                            channelCount++;
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                log.error("[迁移] 处理设备失败: {}", device.getDeviceId(), e);
+            }
+        }
+
+        return R.ok("迁移完成: 设备 " + deviceCount + " 条, 通道 " + channelCount + " 条");
+    }
+
+    /**
+     * 从 Redis 同步通道数据到 MySQL,使 ard_gb_channel 与 Redis 一致
+     */
+    @Operation(summary = "从Redis同步通道到MySQL")
+    @PostMapping("/syncGbChannelsFromRedis")
+    public R<String> syncGbChannelsFromRedis() {
+        List<Device> allDevices = deviceService.getAllRedisDevices();
+        int createdCount = 0;
+        int deletedCount = 0;
+        int skippedCount = 0;
+
+        for (Device device : allDevices) {
+            try {
+                String deviceId = device.getDeviceId();
+                List<DeviceChannel> redisChannels = deviceService.getChannelsByDeviceId(deviceId);
+                if (redisChannels == null) {
+                    redisChannels = new ArrayList<>();
+                }
+
+                Set<String> redisChannelIds = new HashSet<>();
+                boolean hasRealSubChannel = false;
+
+                for (DeviceChannel ch : redisChannels) {
+                    String channelId = ch.getDeviceId();
+                    if (channelId == null || channelId.length() <= 8) {
+                        continue;
+                    }
+                    if (channelId.length() == 20) {
+                        try {
+                            GbCode gbCode = GbCode.decode(channelId);
+                            if (gbCode != null && ("215".equals(gbCode.getTypeCode()) || "216".equals(gbCode.getTypeCode()))) {
+                                continue;
+                            }
+                        } catch (Exception ignored) {}
+                    }
+                    redisChannelIds.add(channelId);
+                    if (!channelId.equals(deviceId)) {
+                        hasRealSubChannel = true;
+                    }
+
+                    GbChannel existing = gbChannelService.selectByGbDeviceIdAndGbChannelId(deviceId, channelId);
+                    if (existing == null) {
+                        GbChannel gbChannel = new GbChannel();
+                        gbChannel.setGbDeviceId(deviceId);
+                        gbChannel.setGbChannelId(channelId);
+                        gbChannel.setChannelName(StringUtils.hasText(ch.getName()) ? ch.getName() : channelId);
+                        gbChannel.setDeviceCode(channelId);
+                        gbChannel.setStreamMode(device.getStreamMode() != null ? device.getStreamMode() : "TCP-PASSIVE");
+                        gbChannel.setEnableMp4("0");
+                        gbChannelService.insertGbChannel(gbChannel);
+                        createdCount++;
+                        log.info("[同步] 创建通道: deviceId={}, channelId={}", deviceId, channelId);
+                    } else if (StringUtils.hasText(ch.getName())
+                            && !ch.getName().equals(existing.getChannelName())) {
+                        existing.setChannelName(ch.getName());
+                        gbChannelService.updateGbChannel(existing);
+                        log.info("[同步] 更新通道名称: deviceId={}, channelId={}, {} -> {}",
+                                deviceId, channelId, existing.getChannelName(), ch.getName());
+                    }
+                }
+
+                List<GbChannel> mysqlChannels = gbChannelService.selectGbChannelByGbDeviceId(deviceId);
+                for (GbChannel mysqlCh : mysqlChannels) {
+                    if (!redisChannelIds.contains(mysqlCh.getGbChannelId())) {
+                        if ("1".equals(mysqlCh.getStreamStatus())) {
+                            skippedCount++;
+                            continue;
+                        }
+                        gbChannelService.deleteGbChannelById(mysqlCh.getId());
+                        deletedCount++;
+                    }
+                }
+
+                if (hasRealSubChannel) {
+                    GbChannel defaultChannel = gbChannelService.selectByGbDeviceIdAndGbChannelId(deviceId, deviceId);
+                    if (defaultChannel != null && !redisChannelIds.contains(deviceId)) {
+                        if (!"1".equals(defaultChannel.getStreamStatus())) {
+                            gbChannelService.deleteGbChannelById(defaultChannel.getId());
+                            deletedCount++;
+                        } else {
+                            skippedCount++;
+                        }
+                    }
+                }
+
+            } catch (Exception e) {
+                log.error("[同步] 处理设备失败: {}", device.getDeviceId(), e);
+            }
+        }
+
+        return R.ok(String.format("同步完成: 创建 %d 条, 删除 %d 条, 跳过 %d 条(推流中)",
+                createdCount, deletedCount, skippedCount));
+    }
 }

--
Gitblit v1.9.3