648540858 1 年間 前
コミット
f7c98301ac

+ 0 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/bean/CommonGBChannel.java

@@ -218,7 +218,6 @@ public class CommonGBChannel {
     private String updateTime;
 
 
-
     public String encode(){
         return encode(null);
     }

+ 12 - 0
src/main/java/com/genersoft/iot/vmp/gb28181/bean/CommonGBChannelWitchGroupChannelId.java

@@ -0,0 +1,12 @@
+package com.genersoft.iot.vmp.gb28181.bean;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Data
+@Schema(description = "国标通道关联分组表ID")
+public class CommonGBChannelWitchGroupChannelId extends CommonGBChannel {
+
+    private int groupChannelId;
+
+}

+ 48 - 0
src/main/java/com/genersoft/iot/vmp/gb28181/bean/GbCode.java

@@ -0,0 +1,48 @@
+package com.genersoft.iot.vmp.gb28181.bean;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 国标编码对象
+ */
+@Data
+@Schema(description = "国标编码对象")
+public class GbCode {
+
+    @Schema(description = "中心编码,由监控中心所在地的行政区划代码确定,符合GB/T2260—2007的要求")
+    private String civilCode;
+
+    @Schema(description = "行业编码")
+    private String industryCode;
+
+    @Schema(description = "类型编码")
+    private String typeCode;
+
+    @Schema(description = "网络标识")
+    private String netCode;
+
+    @Schema(description = "序号")
+    private String sn;
+
+    /**
+     * 解析国标编号
+     */
+    public static GbCode decode(String code){
+        if (code == null || code.trim().length() != 20) {
+            return null;
+        }
+        code = code.trim();
+        GbCode gbCode = new GbCode();
+        gbCode.setCivilCode(code.substring(0, 8));
+        gbCode.setIndustryCode(code.substring(9, 10));
+        gbCode.setTypeCode(code.substring(11, 13));
+        gbCode.setNetCode(code.substring(14, 15));
+        gbCode.setSn(code.substring(15, 20));
+        return gbCode;
+    }
+
+    public String ecode(){
+        return civilCode + industryCode + typeCode + netCode + sn;
+    }
+}

+ 59 - 0
src/main/java/com/genersoft/iot/vmp/gb28181/bean/Group.java

@@ -0,0 +1,59 @@
+package com.genersoft.iot.vmp.gb28181.bean;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * 业务分组
+ */
+@Data
+@Schema(description = "业务分组")
+public class Group implements Comparable<Group>{
+    /**
+     * 数据库自增ID
+     */
+    @Schema(description = "数据库自增ID")
+    private int id;
+
+    /**
+     * 区域国标编号
+     */
+    @Schema(description = "区域国标编号")
+    private String deviceId;
+
+    /**
+     * 区域名称
+     */
+    @Schema(description = "区域名称")
+    private String name;
+
+    /**
+     * 父区域国标ID
+     */
+    @Schema(description = "父区域国标ID")
+    private String parentDeviceId;
+
+    /**
+     * 所属的业务分组国标编号
+     */
+    @Schema(description = "所属的业务分组国标编号")
+    private String businessGroup;
+
+    /**
+     * 创建时间
+     */
+    @Schema(description = "创建时间")
+    private String createTime;
+
+    /**
+     * 更新时间
+     */
+    @Schema(description = "更新时间")
+    private String updateTime;
+
+    @Override
+    public int compareTo(@NotNull Group region) {
+        return Integer.compare(Integer.parseInt(this.deviceId), Integer.parseInt(region.getDeviceId()));
+    }
+}

+ 68 - 0
src/main/java/com/genersoft/iot/vmp/gb28181/bean/GroupTree.java

@@ -0,0 +1,68 @@
+package com.genersoft.iot.vmp.gb28181.bean;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 业务分组
+ */
+@Data
+@Schema(description = "业务分组树")
+public class GroupTree {
+
+    /**
+     * 数据库Id
+     */
+    @Schema(description = "数据库Id")
+    private int dbId;
+
+    /**
+     * 区域国标编号
+     */
+    @Schema(description = "区域国标编号")
+    private String id;
+
+    /**
+     * 区域名称
+     */
+    @Schema(description = "区域名称")
+    private String label;
+
+    /**
+     * 父区域国标ID
+     */
+    @Schema(description = "父区域国标ID")
+    private String parentDeviceId;
+
+    @Schema(description = "是否有子节点")
+    private boolean isLeaf;
+
+    @Schema(description = "类型, 行政区划:0 摄像头: 1")
+    private int type;
+
+
+
+    public static GroupTree getInstance(Region region) {
+        GroupTree regionTree = new GroupTree();
+        regionTree.setId(region.getDeviceId());
+        regionTree.setLabel(region.getName());
+        regionTree.setParentDeviceId(region.getParentDeviceId());
+        regionTree.setType(0);
+        if (region.getDeviceId().length() < 8) {
+            regionTree.setLeaf(false);
+        }else {
+            regionTree.setLeaf(true);
+        }
+        return regionTree;
+    }
+
+    public static GroupTree getInstance(CommonGBChannel channel) {
+        GroupTree regionTree = new GroupTree();
+        regionTree.setId(channel.getGbDeviceId());
+        regionTree.setLabel(channel.getGbName());
+        regionTree.setParentDeviceId(channel.getGbCivilCode());
+        regionTree.setType(1);
+        regionTree.setLeaf(true);
+        return regionTree;
+    }
+}

+ 102 - 0
src/main/java/com/genersoft/iot/vmp/gb28181/controller/GroupController.java

@@ -0,0 +1,102 @@
+package com.genersoft.iot.vmp.gb28181.controller;
+
+import com.genersoft.iot.vmp.conf.exception.ControllerException;
+import com.genersoft.iot.vmp.gb28181.bean.Group;
+import com.genersoft.iot.vmp.gb28181.bean.GroupTree;
+import com.genersoft.iot.vmp.gb28181.service.IGroupService;
+import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.Assert;
+import org.springframework.util.ObjectUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@Slf4j
+@Tag(name = "分组管理")
+@RestController
+@RequestMapping("/api/group")
+public class GroupController {
+
+    @Autowired
+    private IGroupService groupService;
+
+    @Operation(summary = "添加区域")
+    @Parameter(name = "group", description = "group", required = true)
+    @ResponseBody
+    @PostMapping("/add")
+    public void add(@RequestBody Group group){
+        groupService.add(group);
+    }
+
+    @Operation(summary = "查询区域")
+    @Parameter(name = "query", description = "要搜索的内容", required = true)
+    @Parameter(name = "parent", description = "所属分组编号", required = true)
+    @ResponseBody
+    @GetMapping("/tree/list")
+    public List<GroupTree> queryForTree(
+            @RequestParam(required = false) String query,
+            @RequestParam(required = false) String parent
+    ){
+        if (ObjectUtils.isEmpty(parent)) {
+            parent = null;
+        }
+        if (ObjectUtils.isEmpty(query)) {
+            query = null;
+        }
+        return groupService.queryForTree(query, parent);
+    }
+
+    @Operation(summary = "更新区域")
+    @Parameter(name = "group", description = "Group", required = true)
+    @ResponseBody
+    @PostMapping("/update")
+    public void update(@RequestBody Group group){
+        groupService.update(group);
+    }
+
+    @Operation(summary = "删除区域")
+    @Parameter(name = "deviceId", description = "区域编码", required = true)
+    @ResponseBody
+    @DeleteMapping("/delete")
+    public void delete(String deviceId){
+        Assert.hasLength(deviceId, "区域编码(deviceId)不需要存在");
+        boolean result = groupService.deleteByDeviceId(deviceId);
+        if (!result) {
+            throw new ControllerException(ErrorCode.ERROR100.getCode(), "移除失败");
+        }
+    }
+
+    @Operation(summary = "根据区域Id查询区域")
+    @Parameter(name = "groupDeviceId", description = "分组节点编号", required = true)
+    @ResponseBody
+    @GetMapping("/one")
+    public Group queryGroupByDeviceId(
+            @RequestParam(required = true) String deviceId
+    ){
+        Assert.hasLength(deviceId, "");
+        return groupService.queryGroupByDeviceId(deviceId);
+    }
+
+    @Operation(summary = "获取所属的分组下的分组")
+    @Parameter(name = "parent", description = "所属的分组", required = false)
+    @ResponseBody
+    @GetMapping("/base/child/list")
+    public List<Group> getAllChild(@RequestParam(required = false) String parent){
+        if (ObjectUtils.isEmpty(parent)) {
+            parent = null;
+        }
+        return groupService.getAllChild(parent);
+    }
+
+    @Operation(summary = "从通道中同步分组")
+    @ResponseBody
+    @GetMapping("/sync")
+    public void sync(){
+        groupService.syncFromChannel();
+    }
+}

+ 11 - 3
src/main/java/com/genersoft/iot/vmp/gb28181/dao/CommonGBChannelMapper.java

@@ -1,8 +1,6 @@
 package com.genersoft.iot.vmp.gb28181.dao;
 
-import com.genersoft.iot.vmp.gb28181.bean.CommonGBChannel;
-import com.genersoft.iot.vmp.gb28181.bean.Region;
-import com.genersoft.iot.vmp.gb28181.bean.RegionTree;
+import com.genersoft.iot.vmp.gb28181.bean.*;
 import com.genersoft.iot.vmp.gb28181.dao.provider.ChannelProvider;
 import org.apache.ibatis.annotations.*;
 import org.springframework.stereotype.Repository;
@@ -356,4 +354,14 @@ public interface CommonGBChannelMapper {
 
     @SelectProvider(type = ChannelProvider.class, method = "queryByGbDeviceIds")
     List<CommonGBChannel> queryByGbDeviceIds(List<Integer> deviceIds);
+
+    @SelectProvider(type = ChannelProvider.class, method = "queryByGroupList")
+    List<CommonGBChannelWitchGroupChannelId> queryByGroupList(List<Group> groupList);
+
+    @Delete(value = {" <script>" +
+            " delete from wvp_common_group_channel" +
+            " where id in " +
+            " <foreach collection='channels'  item='item'  open='(' separator=',' close=')' > #{item.groupChannelId}</foreach>" +
+            "</script>"})
+    int batchDeleteGroup(List<CommonGBChannelWitchGroupChannelId> channels);
 }

+ 99 - 0
src/main/java/com/genersoft/iot/vmp/gb28181/dao/GroupMapper.java

@@ -0,0 +1,99 @@
+package com.genersoft.iot.vmp.gb28181.dao;
+
+import com.genersoft.iot.vmp.gb28181.bean.Group;
+import com.genersoft.iot.vmp.gb28181.bean.Group;
+import com.genersoft.iot.vmp.gb28181.bean.GroupTree;
+import org.apache.ibatis.annotations.*;
+
+import java.util.List;
+import java.util.Set;
+
+@Mapper
+public interface GroupMapper {
+
+    @Insert("INSERT INTO wvp_common_group (device_id, name, parent_device_id, business_group, create_time, update_time) " +
+            "VALUES (#{deviceId}, #{name}, #{parentDeviceId}, #{businessGroup}, #{createTime}, #{updateTime})")
+    @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
+    void add(Group group);
+
+    @Delete("DELETE FROM wvp_common_group WHERE id=#{id}")
+    int delete(@Param("id") int id);
+
+    @Update(" UPDATE wvp_common_group " +
+            " SET update_time=#{updateTime}, device_id=#{deviceId}, name=#{name}, parent_device_id=#{parentDeviceId}, business_group=#{businessGroup}" +
+            " WHERE id = #{id}")
+    int update(Group group);
+
+    @Select(value = {" <script>" +
+            "SELECT * from wvp_common_group WHERE 1=1 " +
+            " <if test='query != null'> AND (device_id LIKE concat('%',#{query},'%') OR name LIKE concat('%',#{query},'%'))</if> " +
+            " <if test='parentId != null and businessGroupId != null '> AND parent_device_id = #{parentId} AND business_group=#{businessGroup} </if> " +
+            "ORDER BY id " +
+            " </script>"})
+    List<Group> query(@Param("query") String query, @Param("parentId") String parentId, @Param("businessGroup") String businessGroup);
+
+    @Select("SELECT * from wvp_common_group WHERE parent_device_id = #{parentId} AND business_group=#{businessGroup} ORDER BY id ")
+    List<Group> getChildren(@Param("parentId") String parentId , @Param("businessGroup") String businessGroup);
+
+    @Select("SELECT * from wvp_common_group WHERE id = #{id} ")
+    Group queryOne(@Param("id") int id);
+
+    @Select(" select coalesce(dc.gb_civil_code, dc.civil_code) as civil_code " +
+            " from wvp_device_channel dc " +
+            " where coalesce(dc.gb_civil_code, dc.civil_code) not in " +
+            " (select device_id from wvp_common_group)")
+    List<String> getUninitializedCivilCode();
+
+    @Select(" <script>" +
+            " SELECT device_id from wvp_common_group " +
+            " where device_id in " +
+            " <foreach collection='codes'  item='item'  open='(' separator=',' close=')' > #{item}</foreach>" +
+            " </script>")
+    List<String> queryInList(Set<String> codes);
+
+
+    @Insert(" <script>" +
+            " INSERT INTO wvp_common_group (" +
+            " device_id," +
+            " name, " +
+            " parent_device_id," +
+            " create_time," +
+            " update_time) " +
+            " VALUES " +
+            " <foreach collection='groupList' index='index' item='item' separator=','> " +
+            " (#{item.deviceId}, #{item.name}, #{item.parentDeviceId},#{item.createTime},#{item.updateTime})" +
+            " </foreach> " +
+            " </script>")
+    int batchAdd(List<Group> groupList);
+
+    @Select(" <script>" +
+            " SELECT " +
+            " device_id as id," +
+            " name as label, " +
+            " parent_device_id," +
+            " id as db_id," +
+            " 0 as type," +
+            " false as is_leaf" +
+            " from wvp_common_group " +
+            " where " +
+            " <if test='parentId != null'> parent_device_id = #{parentId} </if> " +
+            " <if test='parentId == null'> parent_device_id is null </if> " +
+            " <if test='query != null'> AND (device_id LIKE concat('%',#{query},'%') OR name LIKE concat('%',#{query},'%'))</if> " +
+            " </script>")
+    List<GroupTree> queryForTree(@Param("query") String query, @Param("parentId") String parentId);
+
+    @Select("SELECT * from wvp_common_group WHERE device_id = #{deviceId} and business_group = #{businessGroup}")
+    Group queryOneByDeviceId(@Param("deviceId") String deviceId, @Param("businessGroup") String businessGroup);
+
+    @Delete("<script>" +
+            " DELETE FROM wvp_common_group WHERE id in " +
+            " <foreach collection='allChildren'  item='item'  open='(' separator=',' close=')' > #{item.id}</foreach>" +
+            " </script>")
+    void batchDelete(List<Group> allChildren);
+
+    @Select("SELECT * from wvp_common_group WHERE device_id = #{businessGroup} and business_group = #{businessGroup} ")
+    Group queryBusinessGroup(@Param("businessGroup") String businessGroup);
+
+    @Select("SELECT * from wvp_common_group WHERE business_group = #{businessGroup} ")
+    List<Group> queryByBusinessGroup(@Param("businessGroup") String businessGroup);
+}

+ 79 - 56
src/main/java/com/genersoft/iot/vmp/gb28181/dao/provider/ChannelProvider.java

@@ -1,6 +1,7 @@
 package com.genersoft.iot.vmp.gb28181.dao.provider;
 
 import com.genersoft.iot.vmp.gb28181.bean.CommonGBChannel;
+import com.genersoft.iot.vmp.gb28181.bean.Group;
 
 import java.util.Collection;
 import java.util.List;
@@ -10,65 +11,68 @@ public class ChannelProvider {
 
     public String getBaseSelectSql(){
         return "select\n" +
-                "    id as gb_id,\n" +
-                "    device_db_id as gb_device_db_id,\n" +
-                "    stream_push_id,\n" +
-                "    stream_proxy_id,\n" +
-                "    create_time,\n" +
-                "    update_time,\n" +
-                "    coalesce(gb_device_id, device_id) as gb_device_id,\n" +
-                "    coalesce(gb_name, name) as gb_name,\n" +
-                "    coalesce(gb_manufacturer, manufacturer) as gb_manufacturer,\n" +
-                "    coalesce(gb_model, model) as gb_model,\n" +
-                "    coalesce(gb_owner, owner) as gb_owner,\n" +
+                "    wdc.id as gb_id,\n" +
+                "    wdc.device_db_id as gb_device_db_id,\n" +
+                "    wcg.id as group_channel_id,\n" +
+                "    wdc.stream_push_id,\n" +
+                "    wdc.stream_proxy_id,\n" +
+                "    wdc.create_time,\n" +
+                "    wdc.update_time,\n" +
+                "    coalesce(wdc.gb_device_id, wdc.device_id) as gb_device_id,\n" +
+                "    coalesce(wdc.gb_name, wdc.name) as gb_name,\n" +
+                "    coalesce(wdc.gb_manufacturer, manufacturer) as gb_manufacturer,\n" +
+                "    coalesce(wdc.gb_model, wdc.model) as gb_model,\n" +
+                "    coalesce(wdc.gb_owner, wdc.owner) as gb_owner,\n" +
                 "    gb_civil_code,\n" +
-                "    coalesce(gb_block, block) as gb_block,\n" +
-                "    coalesce(gb_address, address) as gb_address,\n" +
-                "    coalesce(gb_parental, parental) as gb_parental,\n" +
-                "    coalesce(gb_parent_id, parent_id) as gb_parent_id,\n" +
-                "    coalesce(gb_safety_way, safety_way) as gb_safety_way,\n" +
-                "    coalesce(gb_register_way, register_way) as gb_register_way,\n" +
-                "    coalesce(gb_cert_num, cert_num) as gb_cert_num,\n" +
-                "    coalesce(gb_certifiable, certifiable) as gb_certifiable,\n" +
-                "    coalesce(gb_err_code, err_code) as gb_err_code,\n" +
-                "    coalesce(gb_end_time, end_time) as gb_end_time,\n" +
-                "    coalesce(gb_secrecy, secrecy) as gb_secrecy,\n" +
-                "    coalesce(gb_ip_address, ip_address) as gb_ip_address,\n" +
-                "    coalesce(gb_port, port) as gb_port,\n" +
-                "    coalesce(gb_password, password) as gb_password,\n" +
-                "    coalesce(gb_status, status) as gb_status,\n" +
-                "    coalesce(gb_longitude, longitude) as gb_longitude,\n" +
-                "    coalesce(gb_latitude, latitude) as gb_latitude,\n" +
-                "    coalesce(gb_ptz_type, ptz_type) as gb_ptz_type,\n" +
-                "    coalesce(gb_position_type, position_type) as gb_position_type,\n" +
-                "    coalesce(gb_room_type, room_type) as gb_room_type,\n" +
-                "    coalesce(gb_use_type, use_type) as gb_use_type,\n" +
-                "    coalesce(gb_supply_light_type, supply_light_type) as gb_supply_light_type,\n" +
-                "    coalesce(gb_direction_type, direction_type) as gb_direction_type,\n" +
-                "    coalesce(gb_resolution, resolution) as gb_resolution,\n" +
-                "    coalesce(gb_business_group_id, business_group_id) as gb_business_group_id,\n" +
-                "    coalesce(gb_download_speed, download_speed) as gb_download_speed,\n" +
-                "    coalesce(gb_svc_space_support_mod, svc_space_support_mod) as gb_svc_space_support_mod,\n" +
-                "    coalesce(gb_svc_time_support_mode,svc_time_support_mode) as gb_svc_time_support_mode\n" +
-                " from wvp_device_channel\n"
+                "    coalesce(wdc.gb_block, wdc.block) as gb_block,\n" +
+                "    coalesce(wdc.gb_address, wdc.address) as gb_address,\n" +
+                "    coalesce(wdc.gb_parental, wdc.parental) as gb_parental,\n" +
+                "    wcg.device_id as gb_parent_id,\n" +
+                "    coalesce(wdc.gb_safety_way, wdc.safety_way) as gb_safety_way,\n" +
+                "    coalesce(wdc.gb_register_way, wdc.register_way) as gb_register_way,\n" +
+                "    coalesce(wdc.gb_cert_num, wdc.cert_num) as gb_cert_num,\n" +
+                "    coalesce(wdc.gb_certifiable, wdc.certifiable) as gb_certifiable,\n" +
+                "    coalesce(wdc.gb_err_code, wdc.err_code) as gb_err_code,\n" +
+                "    coalesce(wdc.gb_end_time, wdc.end_time) as gb_end_time,\n" +
+                "    coalesce(wdc.gb_secrecy, wdc.secrecy) as gb_secrecy,\n" +
+                "    coalesce(wdc.gb_ip_address, wdc.ip_address) as gb_ip_address,\n" +
+                "    coalesce(wdc.gb_port, port) wdc.as gb_port,\n" +
+                "    coalesce(wdc.gb_password, wdc.password) as gb_password,\n" +
+                "    coalesce(wdc.gb_status, wdc.status) as gb_status,\n" +
+                "    coalesce(wdc.gb_longitude, wdc.longitude) as gb_longitude,\n" +
+                "    coalesce(wdc.gb_latitude, wdc.latitude) as gb_latitude,\n" +
+                "    coalesce(wdc.gb_ptz_type, wdc.ptz_type) as gb_ptz_type,\n" +
+                "    coalesce(wdc.gb_position_type, wdc.position_type) as gb_position_type,\n" +
+                "    coalesce(wdc.gb_room_type, wdc.room_type) as gb_room_type,\n" +
+                "    coalesce(wdc.gb_use_type, wdc.use_type) as gb_use_type,\n" +
+                "    coalesce(wdc.gb_supply_light_type, wdc.supply_light_type) as gb_supply_light_type,\n" +
+                "    coalesce(wdc.gb_direction_type, wdc.direction_type) as gb_direction_type,\n" +
+                "    coalesce(wdc.gb_resolution, wdc.resolution) as gb_resolution,\n" +
+                "    wcg.business_group as gb_business_group_id,\n" +
+                "    coalesce(wdc.gb_download_speed, wdc.download_speed) as gb_download_speed,\n" +
+                "    coalesce(wdc.gb_svc_space_support_mod, wdc.svc_space_support_mod) as gb_svc_space_support_mod,\n" +
+                "    coalesce(wdc.gb_svc_time_support_mode, wdc.svc_time_support_mode) as gb_svc_time_support_mode\n" +
+                " from wvp_device_channel wdc\n" + 
+                " left jon wvp_common_group_channel wcgc on wcgc.channel_id = wdc.id\n" + 
+                " left jon wvp_common_group wcg on wcgc.group_id = wcg.id\n"
                 ;
     }
 
 
     public String queryByDeviceId(Map<String, Object> params ){
-        return getBaseSelectSql() + " where gb_device_id = #{gbDeviceId} or device_id = #{gbDeviceId}";
+        return getBaseSelectSql() + " where wdc.gb_device_id = #{gbDeviceId} or wdc.device_id = #{gbDeviceId}";
     }
 
     public String queryById(Map<String, Object> params ){
-        return getBaseSelectSql() + " where id = #{gbId}";
+        return getBaseSelectSql() + " where wdc.id = #{gbId}";
     }
 
     public String queryByStreamPushId(Map<String, Object> params ){
-        return getBaseSelectSql() + " where stream_push_id = #{streamPushId}";
+        return getBaseSelectSql() + " where wdc.stream_push_id = #{streamPushId}";
     }
 
     public String queryByStreamProxyId(Map<String, Object> params ){
-        return getBaseSelectSql() + " where stream_proxy_id = #{streamProxyId}";
+        return getBaseSelectSql() + " where wdc.stream_proxy_id = #{streamProxyId}";
     }
 
 
@@ -77,21 +81,21 @@ public class ChannelProvider {
         sqlBuild.append(getBaseSelectSql());
         sqlBuild.append(" where 1 = 1 ");
         if (params.get("query") != null) {
-            sqlBuild.append(" AND (coalesce(gb_device_id, device_id) LIKE concat('%',#{query},'%')" +
-                    " OR coalesce(gb_name, name) LIKE concat('%',#{query},'%') )")
+            sqlBuild.append(" AND (coalesce(wdc.gb_device_id, device_id) LIKE concat('%',#{query},'%')" +
+                    " OR coalesce(wdc.gb_name, name) LIKE concat('%',#{query},'%') )")
             ;
         }
         if (params.get("online") != null && (Boolean)params.get("online")) {
-            sqlBuild.append(" AND coalesce(gb_status, status) = 'ON'");
+            sqlBuild.append(" AND coalesce(wdc.gb_status, status) = 'ON'");
         }
         if (params.get("online") != null && !(Boolean)params.get("online")) {
-            sqlBuild.append(" AND coalesce(gb_status, status) = 'OFF'");
+            sqlBuild.append(" AND coalesce(wdc.gb_status, status) = 'OFF'");
         }
         if (params.get("hasCivilCode") != null && (Boolean)params.get("hasCivilCode")) {
-            sqlBuild.append(" AND gb_civil_code is not null");
+            sqlBuild.append(" AND wdc.gb_civil_code is not null");
         }
         if (params.get("hasCivilCode") != null && !(Boolean)params.get("hasCivilCode")) {
-            sqlBuild.append(" AND gb_civil_code is null");
+            sqlBuild.append(" AND wdc.gb_civil_code is null");
         }
         return sqlBuild.toString();
     }
@@ -99,7 +103,7 @@ public class ChannelProvider {
     public String queryInListByStatus(Map<String, Object> params ){
         StringBuilder sqlBuild = new StringBuilder();
         sqlBuild.append(getBaseSelectSql());
-        sqlBuild.append("where gb_status=#{status} and id in ( ");
+        sqlBuild.append("where wdc.gb_status=#{status} and wdc.id in ( ");
 
         List<CommonGBChannel> commonGBChannelList = (List<CommonGBChannel>)params.get("ids");
         boolean first = true;
@@ -117,7 +121,7 @@ public class ChannelProvider {
     public String queryByIds(Map<String, Object> params ){
         StringBuilder sqlBuild = new StringBuilder();
         sqlBuild.append(getBaseSelectSql());
-        sqlBuild.append("where id in ( ");
+        sqlBuild.append("where wdc.id in ( ");
 
         Collection<Integer> ids = (Collection<Integer>)params.get("ids");
         boolean first = true;
@@ -135,7 +139,7 @@ public class ChannelProvider {
     public String queryByGbDeviceIds(Map<String, Object> params ){
         StringBuilder sqlBuild = new StringBuilder();
         sqlBuild.append(getBaseSelectSql());
-        sqlBuild.append("where device_db_id in ( ");
+        sqlBuild.append("where wdc.device_db_id in ( ");
 
         Collection<Integer> ids = (Collection<Integer>)params.get("deviceIds");
         boolean first = true;
@@ -155,13 +159,13 @@ public class ChannelProvider {
         sqlBuild.append(getBaseSelectSql());
         sqlBuild.append("where ");
         if (params.get("civilCode") != null) {
-            sqlBuild.append(" gb_civil_code = #{civilCode} ");
+            sqlBuild.append(" wdc.gb_civil_code = #{civilCode} ");
             if (params.get("ids") != null) {
                 sqlBuild.append(" OR ");
             }
         }
         if (params.get("ids") != null) {
-            sqlBuild.append(" id in ( ");
+            sqlBuild.append(" wdc.id in ( ");
             Collection<Integer> ids = (Collection<Integer>)params.get("ids");
             boolean first = true;
             for (Integer id : ids) {
@@ -179,7 +183,26 @@ public class ChannelProvider {
     public String queryByCivilCode(Map<String, Object> params ){
         StringBuilder sqlBuild = new StringBuilder();
         sqlBuild.append(getBaseSelectSql());
-        sqlBuild.append("where gb_civil_code = #{civilCode} ");
+        sqlBuild.append("where wdc.gb_civil_code = #{civilCode} ");
+        return sqlBuild.toString() ;
+    }
+
+    public String queryByGroupList(Map<String, Object> params ){
+        StringBuilder sqlBuild = new StringBuilder();
+        sqlBuild.append(getBaseSelectSql());
+
+        sqlBuild.append(" wcg.id in ( ");
+        Collection<Group> ids = (Collection<Group>)params.get("groupList");
+        boolean first = true;
+        for (Group group : ids) {
+            if (!first) {
+                sqlBuild.append(",");
+            }
+            sqlBuild.append(group.getId());
+            first = false;
+        }
+        sqlBuild.append(" )");
+
         return sqlBuild.toString() ;
     }
 }

+ 29 - 0
src/main/java/com/genersoft/iot/vmp/gb28181/service/IGroupService.java

@@ -0,0 +1,29 @@
+package com.genersoft.iot.vmp.gb28181.service;
+
+import com.genersoft.iot.vmp.gb28181.bean.Group;
+import com.genersoft.iot.vmp.gb28181.bean.GroupTree;
+
+import java.util.List;
+
+
+public interface IGroupService {
+
+    void add(Group group);
+
+    boolean deleteByDeviceId(String deviceId, String groupId);
+    
+    /**
+     * 更新区域
+     */
+    void update(Group group);
+
+    List<Group> getAllChild(String parent);
+
+    Group queryGroupByDeviceId(String regionDeviceId);
+
+    List<GroupTree> queryForTree(String query, String parent);
+
+    void syncFromChannel();
+
+    boolean delete(int id);
+}

+ 148 - 0
src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GroupServiceImpl.java

@@ -0,0 +1,148 @@
+package com.genersoft.iot.vmp.gb28181.service.impl;
+
+import com.genersoft.iot.vmp.gb28181.bean.*;
+import com.genersoft.iot.vmp.gb28181.dao.CommonGBChannelMapper;
+import com.genersoft.iot.vmp.gb28181.dao.GroupMapper;
+import com.genersoft.iot.vmp.gb28181.service.IGroupService;
+import com.genersoft.iot.vmp.utils.DateUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.Assert;
+import org.springframework.util.ObjectUtils;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * 区域管理类
+ */
+@Service
+@Slf4j
+public class GroupServiceImpl implements IGroupService {
+
+    @Autowired
+    private GroupMapper groupManager;
+
+    @Autowired
+    private CommonGBChannelMapper commonGBChannelMapper;
+
+    @Override
+    public void add(Group group) {
+        Assert.notNull(group, "参数不可为NULL");
+        Assert.notNull(group.getDeviceId(), "设备编号不可为NULL");
+        Assert.isTrue(group.getDeviceId().trim().length() == 20, "设备编号必须为20位");
+        Assert.isTrue(group.getParentDeviceId().trim().length() == 20, "父级编号错误");
+        Assert.notNull(group.getName(), "设备编号不可为NULL");
+
+        GbCode decode = GbCode.decode(group.getDeviceId());
+        Assert.notNull(decode, "设备编号不满足国标定义");
+        // 根据字段判断此处应使用什么规则校验
+        if (ObjectUtils.isEmpty(group.getParentDeviceId())) {
+            if (ObjectUtils.isEmpty(group.getBusinessGroup())) {
+                // 如果是建立业务分组,那么编号必须20位,且10-13必须为215,
+                Assert.isTrue("215".equals(decode.getTypeCode()), "创建业务分组时设备编号11-13位应使用215");
+                group.setBusinessGroup(group.getDeviceId());
+            }else {
+                // 建立第一个虚拟组织
+                Assert.isTrue("216".equals(decode.getTypeCode()), "创建虚拟组织时设备编号11-13位应使用216");
+            }
+        }else {
+            // 建立第一个虚拟组织
+            Assert.isTrue("216".equals(decode.getTypeCode()), "创建虚拟组织时设备编号11-13位应使用216");
+        }
+        if (!ObjectUtils.isEmpty(group.getBusinessGroup())) {
+            // 校验业务分组是否存在
+            Group businessGroup = groupManager.queryBusinessGroup(group.getBusinessGroup());
+            Assert.notNull(businessGroup, "所属的业务分组分组不存在");
+        }
+        if (!ObjectUtils.isEmpty(group.getParentDeviceId())) {
+            Group groupInDb = groupManager.queryOneByDeviceId(group.getParentDeviceId(), group.getBusinessGroup());
+            Assert.notNull(groupInDb, "所属的上级分组分组不存在");
+        }
+        group.setCreateTime(DateUtil.getNow());
+        group.setUpdateTime(DateUtil.getNow());
+        groupManager.add(group);
+    }
+
+    @Override
+    public boolean deleteByDeviceId(String deviceId, String groupId) {
+        Assert.notNull(deviceId, "设备编号不可为NULL");
+        Assert.notNull(groupId, "业务分组不可为NULL");
+        GbCode gbCode = GbCode.decode(deviceId);
+
+        Group businessGroup = groupManager.queryBusinessGroup(groupId);
+        Assert.notNull(businessGroup, "业务分组不存在");
+        // 待删除的分组
+        List<Group> groupList;
+        // 是否需要清理业务分组字段
+        if (gbCode.getTypeCode().equals("215")) {
+            // 删除业务分组
+            // 获取所有的虚拟组织
+            groupList = groupManager.queryByBusinessGroup(deviceId);
+            if (groupList.isEmpty()) {
+                return false;
+            }
+        }else {
+            // 删除虚拟组织
+            Group group = groupManager.queryOneByDeviceId(deviceId, groupId);
+            Assert.notNull(group, "分组不存在");
+            // 获取所有子分组
+            groupList = queryAllChildren(deviceId, groupId);
+            if (groupList.isEmpty()) {
+                return false;
+            }
+
+        }
+        List<CommonGBChannelWitchGroupChannelId> channels = commonGBChannelMapper.queryByGroupList(groupList);
+        if (channels.isEmpty()) {
+            return false;
+        }
+        commonGBChannelMapper.batchDeleteGroup(channels);
+
+        // TODO 待定 是否需要发送catalog事件,还是等分配的时候发送UPDATE事件
+        groupManager.batchDelete(groupList);
+        return true;
+    }
+
+    private List<Group> queryAllChildren(String deviceId, String groupId) {
+        List<Group> children = groupManager.getChildren(deviceId, groupId);
+        if (ObjectUtils.isEmpty(children)) {
+            return children;
+        }
+        for (int i = 0; i < children.size(); i++) {
+            children.addAll(queryAllChildren(children.get(i).getDeviceId(), groupId));
+        }
+        return children;
+    }
+
+    @Override
+    public void update(Group group) {
+
+    }
+
+    @Override
+    public List<Group> getAllChild(String parent) {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public Group queryGroupByDeviceId(String regionDeviceId) {
+        return null;
+    }
+
+    @Override
+    public List<GroupTree> queryForTree(String query, String parent) {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public void syncFromChannel() {
+
+    }
+
+    @Override
+    public boolean delete(int id) {
+        return false;
+    }
+}

+ 357 - 0
web_src/src/components/common/GroupTree.vue

@@ -0,0 +1,357 @@
+<template>
+  <div id="DeviceTree">
+    <div class="page-header" style="margin-bottom: 1rem;">
+      <div class="page-title">业务分组</div>
+      <div class="page-header-btn">
+        <div style="display: inline;">
+          <el-input @input="search" style="visibility:hidden; margin-right: 1rem; width: 12rem;" size="mini" placeholder="关键字"
+                    prefix-icon="el-icon-search" v-model="searchSrt" clearable></el-input>
+
+          <el-checkbox v-model="showCode">显示编号</el-checkbox>
+        </div>
+      </div>
+    </div>
+    <div>
+      <vue-easy-tree
+        class="flow-tree"
+        ref="veTree"
+        node-key="id"
+        height="78vh"
+        lazy
+        style="padding: 2rem 0 2rem 0.5rem"
+        :load="loadNode"
+        :data="treeData"
+        :default-expanded-keys="['']"
+        @node-contextmenu="contextmenuEventHandler"
+        @node-click="nodeClickHandler"
+      >
+        <span class="custom-tree-node" slot-scope="{ node, data }">
+          <span @click.stop >
+            <el-radio v-if="node.data.type === 0 && node.level !== 1 " style="margin-right: 0" v-model="chooseId" @input="chooseIdChange" :label="node.data.id">{{''}}</el-radio>
+          </span>
+          <span v-if="node.data.type === 0" style="color: #409EFF" class="iconfont icon-bianzubeifen3"></span>
+          <span v-if="node.data.type === 1" style="color: #409EFF" class="iconfont icon-shexiangtou2"></span>
+          <span style=" padding-left: 1px" v-if="node.data.id !=='' && showCode" :title="node.data.id">{{ node.label }}(编号:{{ node.data.id }})</span>
+          <span style=" padding-left: 1px" v-if="node.data.id ==='' || !showCode" :title="node.data.id">{{ node.label }}</span>
+        </span>
+      </vue-easy-tree>
+    </div>
+    <regionCode ref="regionCode"></regionCode>
+    <gbDeviceSelect ref="gbDeviceSelect"></gbDeviceSelect>
+  </div>
+</template>
+
+<script>
+import VueEasyTree from "@wchbrad/vue-easy-tree";
+import regionCode from './../dialog/regionCode'
+import gbDeviceSelect from './../dialog/GbDeviceSelect'
+
+export default {
+  name: 'DeviceTree',
+  components: {
+    VueEasyTree, regionCode, gbDeviceSelect
+  },
+  data() {
+    return {
+      showCode: false,
+      searchSrt: "",
+      chooseId: "",
+      treeData: [],
+    }
+  },
+  props: ['edit', 'clickEvent', 'chooseIdChange', 'onChannelChange'],
+  created() {
+  },
+  methods: {
+    search() {
+
+    },
+    loadNode: function (node, resolve) {
+      if (node.level === 0) {
+        resolve([{
+          id: "",
+          label: "根资源组",
+          isLeaf: false,
+          type: 0
+        }]);
+      } else if (node.data.id.length <= 8) {
+        this.$axios({
+          method: 'get',
+          url: `/api/region/tree/list`,
+          params: {
+            query: this.searchSrt,
+            parent: node.data.id
+          }
+        }).then((res) => {
+          if (res.data.code === 0) {
+            resolve(res.data.data);
+          }
+
+        }).catch(function (error) {
+          console.log(error);
+        });
+      } else {
+        resolve([]);
+      }
+    },
+    reset: function () {
+      this.$forceUpdate();
+    },
+    contextmenuEventHandler: function (event, data, node, element) {
+
+      console.log(node.level)
+      if (node.data.type === 1) {
+        data.parentId = node.parent.data.id;
+        this.$contextmenu({
+          items: [
+            {
+              label: "移除通道",
+              icon: "el-icon-delete",
+              disabled: false,
+              onClick: () => {
+                console.log(data)
+                this.$axios({
+                  method: "post",
+                  url: `/api/common/channel/region/delete`,
+                  data: {
+                    channelIds: [data.dbId]
+                  }
+                }).then((res) => {
+                  console.log("移除成功")
+                  if (this.onChannelChange) {
+                    this.onChannelChange()
+                  }
+                  node.parent.loaded = false
+                  node.parent.expand();
+                }).catch(function (error) {
+                  console.log(error);
+                });
+              }
+            }
+          ],
+          event, // 鼠标事件信息
+          customClass: "custom-class", // 自定义菜单 class
+          zIndex: 3000, // 菜单样式 z-index
+        });
+      } else if (node.data.type === 0) {
+        this.$contextmenu({
+          items: [
+            {
+              label: "刷新节点",
+              icon: "el-icon-refresh",
+              disabled: false,
+              onClick: () => {
+                this.refreshNode(node);
+              }
+            },
+            {
+              label: "新建节点",
+              icon: "el-icon-plus",
+              disabled: false,
+              onClick: () => {
+                this.addRegion(data.id, node);
+              }
+            },
+            {
+              label: "重命名",
+              icon: "el-icon-edit",
+              disabled: node.level === 1,
+              onClick: () => {
+                this.editCatalog(data, node);
+              }
+            },
+            {
+              label: "删除节点",
+              icon: "el-icon-delete",
+              disabled: node.level === 1,
+              divided: true,
+              onClick: () => {
+                this.$confirm('确定删除?', '提示', {
+                  confirmButtonText: '确定',
+                  cancelButtonText: '取消',
+                  type: 'warning'
+                }).then(() => {
+                  this.removeRegion(data.id, node)
+                }).catch(() => {
+
+                });
+              }
+            },
+            {
+              label: "添加设备",
+              icon: "el-icon-plus",
+              disabled: node.level === 1,
+              onClick: () => {
+                this.addChannelFormDevice(data.id, node)
+              }
+            },
+            {
+              label: "移除设备",
+              icon: "el-icon-delete",
+              disabled: node.level === 1,
+              onClick: () => {
+                this.removeChannelFormDevice(data.id, node)
+              }
+            },
+            // {
+            //   label: "导出",
+            //   icon: "el-icon-download",
+            //   disabled: false,
+            //   children: [
+            //     {
+            //       label: "导出到文件",
+            //       onClick: () => {
+            //
+            //       },
+            //     },
+            //     {
+            //       label: "导出到其他平台",
+            //       onClick: () => {
+            //
+            //       },
+            //     }
+            //   ]
+            // },
+
+          ],
+          event, // 鼠标事件信息
+          customClass: "custom-class", // 自定义菜单 class
+          zIndex: 3000, // 菜单样式 z-index
+        });
+      }
+
+      return false;
+    },
+    removeRegion: function (id, node) {
+      this.$axios({
+        method: "delete",
+        url: `/api/region/delete`,
+        params: {
+          deviceId: id,
+        }
+      }).then((res) => {
+        if (res.data.code === 0) {
+          console.log("移除成功")
+          node.parent.loaded = false
+          node.parent.expand();
+        }
+      }).catch(function (error) {
+          console.log(error);
+      });
+    },
+    addChannelFormDevice: function (id, node) {
+      this.$refs.gbDeviceSelect.openDialog((rows)=>{
+        let deviceIds = []
+        for (let i = 0; i < rows.length; i++) {
+          deviceIds.push(rows[i].id)
+        }
+        this.$axios({
+          method: 'post',
+          url: `/api/common/channel/region/device/add`,
+          data: {
+            civilCode: node.data.id,
+            deviceIds: deviceIds,
+          }
+        }).then((res)=> {
+          if (res.data.code === 0) {
+            this.$message.success("保存成功")
+            if (this.onChannelChange) {
+              this.onChannelChange()
+            }
+            node.loaded = false
+            node.expand();
+          }else {
+            this.$message.error(res.data.msg)
+          }
+          this.loading = false
+        }).catch((error)=> {
+          this.$message.error(error)
+          this.loading = false
+        });
+      })
+    },
+    removeChannelFormDevice: function (id, node) {
+      this.$refs.gbDeviceSelect.openDialog((rows)=>{
+        let deviceIds = []
+        for (let i = 0; i < rows.length; i++) {
+          deviceIds.push(rows[i].id)
+        }
+        this.$axios({
+          method: 'post',
+          url: `/api/common/channel/region/device/delete`,
+          data: {
+            deviceIds: deviceIds,
+          }
+        }).then((res)=> {
+          if (res.data.code === 0) {
+            this.$message.success("保存成功")
+            if (this.onChannelChange) {
+              this.onChannelChange()
+            }
+            node.loaded = false
+            node.expand();
+          }else {
+            this.$message.error(res.data.msg)
+          }
+          this.loading = false
+        }).catch((error)=> {
+          this.$message.error(error)
+          this.loading = false
+        });
+      })
+    },
+    refreshNode: function (node) {
+      node.loaded = false
+      node.expand();
+    },
+    refresh: function (id) {
+      // 查询node
+      let node = this.$refs.veTree.getNode(id)
+      node.loaded = false
+      node.expand();
+    },
+    addRegion: function (id, node) {
+
+      console.log(node)
+
+      this.$refs.regionCode.openDialog(form => {
+        node.loaded = false
+        node.expand();
+      }, id);
+    },
+    nodeClickHandler: function (data, node, tree) {
+      console.log(data)
+      console.log(node)
+      // this.chooseId = data.id;
+      // this.chooseName = data.name;
+      // if (this.catalogIdChange)this.catalogIdChange(this.chooseId, this.chooseName);
+    }
+  },
+  destroyed() {
+    // if (this.jessibuca) {
+    //   this.jessibuca.destroy();
+    // }
+    // this.playing = false;
+    // this.loaded = false;
+    // this.performance = "";
+  },
+}
+</script>
+
+<style>
+.device-tree-main-box {
+  text-align: left;
+}
+
+.device-online {
+  color: #252525;
+}
+
+.device-offline {
+  color: #727272;
+}
+.custom-tree-node .el-radio__label {
+  padding-left: 4px !important;
+}
+
+</style>

+ 287 - 0
web_src/src/components/group.vue

@@ -0,0 +1,287 @@
+<template>
+  <div id="region" style="width: 100%">
+    <el-container v-loading="loading" >
+      <el-aside width="400px" >
+        <GroupTree ref="groupTree" :edit="true" :clickEvent="treeNodeClickEvent" :chooseIdChange="chooseIdChange" :onChannelChange="getChannelList"></GroupTree>
+      </el-aside>
+      <el-main style="padding: 5px;">
+        <div class="page-header">
+          <div class="page-title">通道列表</div>
+          <div class="page-header-btn">
+            <div  style="display: inline;">
+              搜索:
+              <el-input @input="search" style="margin-right: 1rem; width: auto;" size="mini" placeholder="关键字"
+                        prefix-icon="el-icon-search" v-model="searchSrt" clearable></el-input>
+
+              在线状态:
+              <el-select size="mini" style="width: 8rem; margin-right: 1rem;" @change="search" v-model="online" placeholder="请选择"
+                         default-first-option>
+                <el-option label="全部" value=""></el-option>
+                <el-option label="在线" value="true"></el-option>
+                <el-option label="离线" value="false"></el-option>
+              </el-select>
+              添加状态:
+              <el-select size="mini" style="width: 8rem; margin-right: 1rem;" @change="search" v-model="hasCivilCode" placeholder="请选择"
+                         default-first-option>
+                <el-option label="全部" value=""></el-option>
+                <el-option label="已添加" value="true"></el-option>
+                <el-option label="未添加" value="false"></el-option>
+              </el-select>
+              <el-button size="mini" type="primary" @click="add()">
+                添加
+              </el-button>
+              <el-button icon="el-icon-refresh-right" circle size="mini" @click="getChannelList()"></el-button>
+            </div>
+          </div>
+        </div>
+        <el-table ref="channelListTable" :data="channelList" :height="winHeight" style="width: 100%"
+                  header-row-class-name="table-header" @selection-change="handleSelectionChange" @row-dblclick="rowDblclick">
+          <el-table-column type="selection" width="55" :selectable="selectable">
+          </el-table-column>
+          <el-table-column prop="gbName" label="名称" min-width="180">
+          </el-table-column>
+          <el-table-column prop="gbDeviceId" label="编号" min-width="180">
+          </el-table-column>
+          <el-table-column prop="gbManufacturer" label="厂家" min-width="100">
+          </el-table-column>
+          <el-table-column label="类型" min-width="100">
+            <template slot-scope="scope">
+              <div slot="reference" class="name-wrapper">
+                <el-tag size="medium" v-if="scope.row.gbDeviceDbId">国标设备</el-tag>
+                <el-tag size="medium" v-if="scope.row.streamPushId">推流设备</el-tag>
+                <el-tag size="medium" v-if="scope.row.streamProxyId">拉流代理</el-tag>
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column label="状态" min-width="100">
+            <template slot-scope="scope">
+              <div slot="reference" class="name-wrapper">
+                <el-tag size="medium" v-if="scope.row.gbStatus === 'ON'">在线</el-tag>
+                <el-tag size="medium" type="info" v-if="scope.row.gbStatus !== 'ON'">离线</el-tag>
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column label="添加状态" min-width="100">
+            <template slot-scope="scope">
+              <div slot="reference" class="name-wrapper">
+                <el-tag size="medium" :title="scope.row.gbCivilCode" v-if="scope.row.gbCivilCode">已添加</el-tag>
+                <el-tag size="medium" type="info" v-if="!scope.row.gbCivilCode">未添加</el-tag>
+              </div>
+            </template>
+          </el-table-column>
+        </el-table>
+        <el-pagination
+          style="float: right"
+          @size-change="handleSizeChange"
+          @current-change="currentChange"
+          :current-page="currentPage"
+          :page-size="count"
+          :page-sizes="[15, 25, 35, 50]"
+          layout="total, sizes, prev, pager, next"
+          :total="total">
+        </el-pagination>
+      </el-main>
+    </el-container>
+
+  </div>
+</template>
+
+<script>
+import uiHeader from '../layout/UiHeader.vue'
+import DeviceService from "./service/DeviceService";
+import GroupTree from "./common/GroupTree.vue";
+
+export default {
+  name: 'channelList',
+  components: {
+    uiHeader,
+    GroupTree,
+  },
+  data() {
+    return {
+      channelList: [],
+      searchSrt: "",
+      channelType: "",
+      online: "",
+      hasCivilCode: "false",
+      winHeight: window.innerHeight - 180,
+      currentPage: 1,
+      count: 15,
+      total: 0,
+      loading: false,
+      loadSnap: {},
+      regionId: "",
+      multipleSelection: []
+    };
+  },
+
+  created() {
+    this.initData();
+  },
+  destroyed() {},
+  methods: {
+    initData: function () {
+      this.getChannelList();
+    },
+    currentChange: function (val) {
+      this.currentPage = val;
+      this.initData();
+    },
+    handleSizeChange: function (val) {
+      this.count = val;
+      this.getChannelList();
+    },
+    getChannelList: function () {
+      this.$axios({
+        method: 'get',
+        url: `/api/common/channel/list`,
+        params: {
+          page: this.currentPage,
+          count: this.count,
+          query: this.searchSrt,
+          online: this.online,
+          hasCivilCode: this.hasCivilCode
+        }
+      }).then((res)=> {
+        if (res.data.code === 0) {
+          this.total = res.data.data.total;
+          this.channelList = res.data.data.list;
+          // 防止出现表格错位
+          this.$nextTick(() => {
+            this.$refs.channelListTable.doLayout();
+          })
+        }
+
+      }).catch((error)=> {
+        console.log(error);
+      });
+    },
+    handleSelectionChange: function (val){
+      this.multipleSelection = val;
+    },
+    selectable: function (row, rowIndex) {
+      if (row.gbCivilCode) {
+        return false
+      }else {
+        return true
+      }
+    },
+    rowDblclick: function (row, rowIndex) {
+      if (row.gbCivilCode) {
+        this.$refs.groupTree.refresh(row.gbCivilCode)
+      }
+    },
+    add: function (row) {
+      if (!this.regionId) {
+        this.$message.info("请选择左侧行政区划节点")
+        return;
+      }
+      let channels = []
+      for (let i = 0; i < this.multipleSelection.length; i++) {
+        channels.push(this.multipleSelection[i].gbId)
+      }
+      if (channels.length === 0) {
+        this.$message.info("请选择右侧通道")
+        return;
+      }
+      this.loading = true
+
+      this.$axios({
+        method: 'post',
+        url: `/api/common/channel/region/add`,
+        data: {
+          civilCode: this.regionId,
+          channelIds: channels
+        }
+      }).then((res)=> {
+        if (res.data.code === 0) {
+          this.$message.success("保存成功")
+          this.getChannelList()
+          // 刷新树节点
+          this.$refs.groupTree.refresh(this.regionId)
+        }else {
+          this.$message.error(res.data.msg)
+        }
+        this.loading = false
+      }).catch((error)=> {
+        this.$message.error(error)
+        this.loading = false
+      });
+    },
+    remove: function (row) {
+    },
+    getSnap: function (row) {
+      let baseUrl = window.baseUrl ? window.baseUrl : "";
+      return ((process.env.NODE_ENV === 'development') ? process.env.BASE_API : baseUrl) + '/api/device/query/snap/' + this.deviceId + '/' + row.deviceId;
+    },
+    search: function () {
+      this.currentPage = 1;
+      this.total = 0;
+      this.initData();
+    },
+    refresh: function () {
+      this.initData();
+    },
+    treeNodeClickEvent: function (device, data, isCatalog) {
+
+    },
+    chooseIdChange: function (id) {
+      this.regionId = id;
+    },
+  }
+};
+</script>
+
+<style>
+.videoList {
+  display: flex;
+  flex-wrap: wrap;
+  align-content: flex-start;
+}
+
+.video-item {
+  position: relative;
+  width: 15rem;
+  height: 10rem;
+  margin-right: 1rem;
+  background-color: #000000;
+}
+
+.video-item-img {
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  margin: auto;
+  width: 100%;
+  height: 100%;
+}
+
+.video-item-img:after {
+  content: "";
+  display: inline-block;
+  position: absolute;
+  z-index: 2;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  margin: auto;
+  width: 3rem;
+  height: 3rem;
+  background-image: url("../assets/loading.png");
+  background-size: cover;
+  background-color: #000000;
+}
+
+.video-item-title {
+  position: absolute;
+  bottom: 0;
+  color: #000000;
+  background-color: #ffffff;
+  line-height: 1.5rem;
+  padding: 0.3rem;
+  width: 14.4rem;
+}
+</style>

+ 375 - 349
数据库/2.7.2-重构/初始化-mysql-2.7.2.sql

@@ -1,385 +1,404 @@
 /*建表*/
-create table wvp_device (
-                            id serial primary key ,
-                            device_id character varying(50) not null ,
-                            name character varying(255),
-                            manufacturer character varying(255),
-                            model character varying(255),
-                            firmware character varying(255),
-                            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),
-                            port integer,
-                            expires integer,
-                            subscribe_cycle_for_catalog integer DEFAULT 0,
-                            subscribe_cycle_for_mobile_position integer DEFAULT 0,
-                            mobile_position_submission_interval integer DEFAULT 5,
-                            subscribe_cycle_for_alarm integer DEFAULT 0,
-                            host_address character varying(50),
-                            charset character varying(50),
-                            ssrc_check bool default false,
-                            geo_coord_sys character varying(50),
-                            media_server_id character varying(50),
-                            custom_name character varying(255),
-                            sdp_ip character varying(50),
-                            local_ip character varying(50),
-                            password character varying(255),
-                            as_message_channel bool default false,
-                            keepalive_interval_time integer,
-                            broadcast_push_after_ack bool default false,
-                            constraint uk_device_device unique (device_id)
+create table wvp_device
+(
+    id                                  serial primary key,
+    device_id                           character varying(50) not null,
+    name                                character varying(255),
+    manufacturer                        character varying(255),
+    model                               character varying(255),
+    firmware                            character varying(255),
+    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),
+    port                                integer,
+    expires                             integer,
+    subscribe_cycle_for_catalog         integer DEFAULT 0,
+    subscribe_cycle_for_mobile_position integer DEFAULT 0,
+    mobile_position_submission_interval integer DEFAULT 5,
+    subscribe_cycle_for_alarm           integer DEFAULT 0,
+    host_address                        character varying(50),
+    charset                             character varying(50),
+    ssrc_check                          bool    default false,
+    geo_coord_sys                       character varying(50),
+    media_server_id                     character varying(50),
+    custom_name                         character varying(255),
+    sdp_ip                              character varying(50),
+    local_ip                            character varying(50),
+    password                            character varying(255),
+    as_message_channel                  bool    default false,
+    keepalive_interval_time             integer,
+    broadcast_push_after_ack            bool    default false,
+    constraint uk_device_device unique (device_id)
 );
 
-create table wvp_device_alarm (
-                                  id serial primary key ,
-                                  device_id character varying(50) not null,
-                                  channel_id character varying(50) not null,
-                                  alarm_priority character varying(50),
-                                  alarm_method character varying(50),
-                                  alarm_time character varying(50),
-                                  alarm_description character varying(255),
-                                  longitude double precision,
-                                  latitude double precision,
-                                  alarm_type character varying(50),
-                                  create_time character varying(50) not null
+create table wvp_device_alarm
+(
+    id                serial primary key,
+    device_id         character varying(50) not null,
+    channel_id        character varying(50) not null,
+    alarm_priority    character varying(50),
+    alarm_method      character varying(50),
+    alarm_time        character varying(50),
+    alarm_description character varying(255),
+    longitude         double precision,
+    latitude          double precision,
+    alarm_type        character varying(50),
+    create_time       character varying(50) not null
 );
 
-create table wvp_device_mobile_position (
-                                            id serial primary key,
-                                            device_id character varying(50) not null,
-                                            channel_id character varying(50) not null,
-                                            device_name character varying(255),
-                                            time character varying(50),
-                                            longitude double precision,
-                                            latitude double precision,
-                                            altitude double precision,
-                                            speed double precision,
-                                            direction double precision,
-                                            report_source character varying(50),
-                                            longitude_gcj02 double precision,
-                                            latitude_gcj02 double precision,
-                                            longitude_wgs84 double precision,
-                                            latitude_wgs84 double precision,
-                                            create_time character varying(50)
+create table wvp_device_mobile_position
+(
+    id              serial primary key,
+    device_id       character varying(50) not null,
+    channel_id      character varying(50) not null,
+    device_name     character varying(255),
+    time            character varying(50),
+    longitude       double precision,
+    latitude        double precision,
+    altitude        double precision,
+    speed           double precision,
+    direction       double precision,
+    report_source   character varying(50),
+    longitude_gcj02 double precision,
+    latitude_gcj02  double precision,
+    longitude_wgs84 double precision,
+    latitude_wgs84  double precision,
+    create_time     character varying(50)
 );
 
-create table wvp_gb_stream (
-                               gb_stream_id serial primary key,
-                               app character varying(255) not null,
-                               stream character varying(255) not null,
-                               gb_id character varying(50) not null,
-                               name character varying(255),
-                               longitude double precision,
-                               latitude double precision,
-                               stream_type character varying(50),
-                               media_server_id character varying(50),
-                               create_time character varying(50),
-                               constraint uk_gb_stream_unique_gb_id unique (gb_id),
-                               constraint uk_gb_stream_unique_app_stream unique (app, stream)
+create table wvp_gb_stream
+(
+    gb_stream_id    serial primary key,
+    app             character varying(255) not null,
+    stream          character varying(255) not null,
+    gb_id           character varying(50)  not null,
+    name            character varying(255),
+    longitude       double precision,
+    latitude        double precision,
+    stream_type     character varying(50),
+    media_server_id character varying(50),
+    create_time     character varying(50),
+    constraint uk_gb_stream_unique_gb_id unique (gb_id),
+    constraint uk_gb_stream_unique_app_stream unique (app, stream)
 );
 
-create table wvp_log (
-                         id serial primary key ,
-                         name character varying(50),
-                         type character varying(50),
-                         uri character varying(200),
-                         address character varying(50),
-                         result character varying(50),
-                         timing bigint,
-                         username character varying(50),
-                         create_time character varying(50)
+create table wvp_log
+(
+    id          serial primary key,
+    name        character varying(50),
+    type        character varying(50),
+    uri         character varying(200),
+    address     character varying(50),
+    result      character varying(50),
+    timing      bigint,
+    username    character varying(50),
+    create_time character varying(50)
 );
 
-create table wvp_device_channel (
-                                    id serial primary key ,
-                                    device_db_id integer,
-                                    device_id character varying(50),
-                                    name character varying(255),
-                                    manufacturer character varying(50),
-                                    model character varying(50),
-                                    owner character varying(50),
-                                    civil_code character varying(50),
-                                    block character varying(50),
-                                    address character varying(50),
-                                    parental integer,
-                                    parent_id character varying(50),
-                                    safety_way integer,
-                                    register_way integer,
-                                    cert_num character varying(50),
-                                    certifiable integer,
-                                    err_code integer,
-                                    end_time character varying(50),
-                                    secrecy integer,
-                                    ip_address character varying(50),
-                                    port integer,
-                                    password character varying(255),
-                                    status character varying(50),
-                                    longitude double precision,
-                                    latitude double precision,
-                                    ptz_type integer,
-                                    position_type integer,
-                                    room_type integer,
-                                    use_type integer,
-                                    supply_light_type integer,
-                                    direction_type integer,
-                                    resolution character varying(255),
-                                    business_group_id character varying(255),
-                                    download_speed character varying(255),
-                                    svc_space_support_mod integer,
-                                    svc_time_support_mode integer,
-                                    create_time character varying(50) not null,
-                                    update_time character varying(50) not null,
-                                    sub_count integer,
-                                    stream_id character varying(255),
-                                    has_audio bool default false,
-                                    gps_time character varying(50),
-                                    stream_identification character varying(50),
-                                    gb_device_id character varying(50),
-                                    gb_name character varying(255),
-                                    gb_manufacturer character varying(255),
-                                    gb_model character varying(255),
-                                    gb_owner character varying(255),
-                                    gb_civil_code character varying(255),
-                                    gb_block character varying(255),
-                                    gb_address character varying(255),
-                                    gb_parental integer,
-                                    gb_parent_id character varying(255),
-                                    gb_safety_way integer,
-                                    gb_register_way integer,
-                                    gb_cert_num integer,
-                                    gb_certifiable integer,
-                                    gb_err_code integer,
-                                    gb_end_time integer,
-                                    gb_security_level_code character varying(255),
-                                    gb_secrecy integer,
-                                    gb_ip_address character varying(50),
-                                    gb_port integer,
-                                    gb_password character varying(50),
-                                    gb_status character varying(50),
-                                    gb_longitude double,
-                                    gb_latitude double,
-                                    gb_business_group_id character varying(50),
-                                    gb_ptz_type integer,
-                                    gb_position_type integer,
-                                    gb_photoelectric_imaging_typ integer,
-                                    gb_capture_position_type integer,
-                                    gb_room_type integer,
-                                    gb_use_type integer,
-                                    gb_supply_light_type integer,
-                                    gb_direction_type integer,
-                                    gb_resolution character varying(255),
-                                    gb_stream_number_list character varying(255),
-                                    gb_download_speed character varying(255),
-                                    gb_svc_space_support_mod integer,
-                                    gb_svc_time_support_mode integer,
-                                    gb_ssvc_ratio_support_list character varying(255),
-                                    gb_mobile_device_type integer,
-                                    gb_horizontal_field_angle double,
-                                    gb_vertical_field_angle double,
-                                    gb_max_view_distance double,
-                                    gb_grassroots_code character varying(255),
-                                    gb_po_type integer,
-                                    gb_po_common_name character varying(255),
-                                    gb_mac character varying(255),
-                                    gb_function_type character varying(255),
-                                    gb_encode_type character varying(255),
-                                    gb_install_time character varying(255),
-                                    gb_management_unit character varying(255),
-                                    gb_contact_info character varying(255),
-                                    gb_record_save_days integer,
-                                    gb_industrial_classification character varying(255),
-                                    stream_push_id integer,
-                                    stream_proxy_id integer,
-                                    constraint uk_wvp_device_channel_unique_device_channel unique (device_db_id, device_id),
-                                    constraint uk_wvp_unique_channel unique (gb_device_id),
-                                    constraint uk_wvp_unique_stream_push_id unique (stream_push_id),
-                                    constraint uk_wvp_unique_stream_proxy_id unique (stream_proxy_id)
+create table wvp_device_channel
+(
+    id                           serial primary key,
+    device_db_id                 integer,
+    device_id                    character varying(50),
+    name                         character varying(255),
+    manufacturer                 character varying(50),
+    model                        character varying(50),
+    owner                        character varying(50),
+    civil_code                   character varying(50),
+    block                        character varying(50),
+    address                      character varying(50),
+    parental                     integer,
+    parent_id                    character varying(50),
+    safety_way                   integer,
+    register_way                 integer,
+    cert_num                     character varying(50),
+    certifiable                  integer,
+    err_code                     integer,
+    end_time                     character varying(50),
+    secrecy                      integer,
+    ip_address                   character varying(50),
+    port                         integer,
+    password                     character varying(255),
+    status                       character varying(50),
+    longitude                    double precision,
+    latitude                     double precision,
+    ptz_type                     integer,
+    position_type                integer,
+    room_type                    integer,
+    use_type                     integer,
+    supply_light_type            integer,
+    direction_type               integer,
+    resolution                   character varying(255),
+    business_group_id            character varying(255),
+    download_speed               character varying(255),
+    svc_space_support_mod        integer,
+    svc_time_support_mode        integer,
+    create_time                  character varying(50) not null,
+    update_time                  character varying(50) not null,
+    sub_count                    integer,
+    stream_id                    character varying(255),
+    has_audio                    bool default false,
+    gps_time                     character varying(50),
+    stream_identification        character varying(50),
+    gb_device_id                 character varying(50),
+    gb_name                      character varying(255),
+    gb_manufacturer              character varying(255),
+    gb_model                     character varying(255),
+    gb_owner                     character varying(255),
+    gb_civil_code                character varying(255),
+    gb_block                     character varying(255),
+    gb_address                   character varying(255),
+    gb_parental                  integer,
+    gb_parent_id                 character varying(255),
+    gb_safety_way                integer,
+    gb_register_way              integer,
+    gb_cert_num                  integer,
+    gb_certifiable               integer,
+    gb_err_code                  integer,
+    gb_end_time                  integer,
+    gb_security_level_code       character varying(255),
+    gb_secrecy                   integer,
+    gb_ip_address                character varying(50),
+    gb_port                      integer,
+    gb_password                  character varying(50),
+    gb_status                    character varying(50),
+    gb_longitude                 double,
+    gb_latitude                  double,
+    gb_business_group_id         character varying(50),
+    gb_ptz_type                  integer,
+    gb_position_type             integer,
+    gb_photoelectric_imaging_typ integer,
+    gb_capture_position_type     integer,
+    gb_room_type                 integer,
+    gb_use_type                  integer,
+    gb_supply_light_type         integer,
+    gb_direction_type            integer,
+    gb_resolution                character varying(255),
+    gb_stream_number_list        character varying(255),
+    gb_download_speed            character varying(255),
+    gb_svc_space_support_mod     integer,
+    gb_svc_time_support_mode     integer,
+    gb_ssvc_ratio_support_list   character varying(255),
+    gb_mobile_device_type        integer,
+    gb_horizontal_field_angle    double,
+    gb_vertical_field_angle      double,
+    gb_max_view_distance         double,
+    gb_grassroots_code           character varying(255),
+    gb_po_type                   integer,
+    gb_po_common_name            character varying(255),
+    gb_mac                       character varying(255),
+    gb_function_type             character varying(255),
+    gb_encode_type               character varying(255),
+    gb_install_time              character varying(255),
+    gb_management_unit           character varying(255),
+    gb_contact_info              character varying(255),
+    gb_record_save_days          integer,
+    gb_industrial_classification character varying(255),
+    stream_push_id               integer,
+    stream_proxy_id              integer,
+    constraint uk_wvp_device_channel_unique_device_channel unique (device_db_id, device_id),
+    constraint uk_wvp_unique_channel unique (gb_device_id),
+    constraint uk_wvp_unique_stream_push_id unique (stream_push_id),
+    constraint uk_wvp_unique_stream_proxy_id unique (stream_proxy_id)
 );
 
-create table wvp_media_server (
-                                  id character varying(255) primary key ,
-                                  ip character varying(50),
-                                  hook_ip character varying(50),
-                                  sdp_ip character varying(50),
-                                  stream_ip character varying(50),
-                                  http_port integer,
-                                  http_ssl_port integer,
-                                  rtmp_port integer,
-                                  rtmp_ssl_port integer,
-                                  rtp_proxy_port integer,
-                                  rtsp_port integer,
-                                  rtsp_ssl_port integer,
-                                  flv_port integer,
-                                  flv_ssl_port integer,
-                                  ws_flv_port integer,
-                                  ws_flv_ssl_port integer,
-                                  auto_config bool default false,
-                                  secret character varying(50),
-                                  type character varying(50) default 'zlm',
-                                  rtp_enable bool default false,
-                                  rtp_port_range character varying(50),
-                                  send_rtp_port_range character varying(50),
-                                  record_assist_port integer,
-                                  default_server bool default false,
-                                  create_time character varying(50),
-                                  update_time character varying(50),
-                                  hook_alive_interval integer,
-                                  record_path character varying(255),
-                                  record_day integer default 7,
-                                  transcode_suffix character varying(255),
-                                  constraint uk_media_server_unique_ip_http_port unique (ip, http_port)
+create table wvp_media_server
+(
+    id                  character varying(255) primary key,
+    ip                  character varying(50),
+    hook_ip             character varying(50),
+    sdp_ip              character varying(50),
+    stream_ip           character varying(50),
+    http_port           integer,
+    http_ssl_port       integer,
+    rtmp_port           integer,
+    rtmp_ssl_port       integer,
+    rtp_proxy_port      integer,
+    rtsp_port           integer,
+    rtsp_ssl_port       integer,
+    flv_port            integer,
+    flv_ssl_port        integer,
+    ws_flv_port         integer,
+    ws_flv_ssl_port     integer,
+    auto_config         bool                  default false,
+    secret              character varying(50),
+    type                character varying(50) default 'zlm',
+    rtp_enable          bool                  default false,
+    rtp_port_range      character varying(50),
+    send_rtp_port_range character varying(50),
+    record_assist_port  integer,
+    default_server      bool                  default false,
+    create_time         character varying(50),
+    update_time         character varying(50),
+    hook_alive_interval integer,
+    record_path         character varying(255),
+    record_day          integer               default 7,
+    transcode_suffix    character varying(255),
+    constraint uk_media_server_unique_ip_http_port unique (ip, http_port)
 );
 
-create table wvp_platform (
-                              id serial primary key ,
-                              enable bool default false,
-                              name character varying(255),
-                              server_gb_id character varying(50),
-                              server_gb_domain character varying(50),
-                              server_ip character varying(50),
-                              server_port integer,
-                              device_gb_id character varying(50),
-                              device_ip character varying(50),
-                              device_port character varying(50),
-                              username character varying(255),
-                              password character varying(50),
-                              expires character varying(50),
-                              keep_timeout character varying(50),
-                              transport character varying(50),
-                              character_set character varying(50),
-                              catalog_id character varying(50),
-                              ptz bool default false,
-                              rtcp bool default false,
-                              status bool default false,
-                              start_offline_push bool default false,
-                              catalog_group integer,
-                              create_time character varying(50),
-                              update_time character varying(50),
-                              as_message_channel bool default false,
-                              custom_catalog bool default false,
-                              auto_push_channel bool default false,
-                              send_stream_ip character varying(50),
-                              constraint uk_platform_unique_server_gb_id unique (server_gb_id)
+create table wvp_platform
+(
+    id                 serial primary key,
+    enable             bool default false,
+    name               character varying(255),
+    server_gb_id       character varying(50),
+    server_gb_domain   character varying(50),
+    server_ip          character varying(50),
+    server_port        integer,
+    device_gb_id       character varying(50),
+    device_ip          character varying(50),
+    device_port        character varying(50),
+    username           character varying(255),
+    password           character varying(50),
+    expires            character varying(50),
+    keep_timeout       character varying(50),
+    transport          character varying(50),
+    character_set      character varying(50),
+    catalog_id         character varying(50),
+    ptz                bool default false,
+    rtcp               bool default false,
+    status             bool default false,
+    start_offline_push bool default false,
+    catalog_group      integer,
+    create_time        character varying(50),
+    update_time        character varying(50),
+    as_message_channel bool default false,
+    custom_catalog     bool default false,
+    auto_push_channel  bool default false,
+    send_stream_ip     character varying(50),
+    constraint uk_platform_unique_server_gb_id unique (server_gb_id)
 );
 
 
-create table wvp_platform_gb_channel (
-                                         id serial primary key ,
-                                         platform_id integer,
-                                         device_channel_id integer,
-                                         device_id character varying(50),
-                                         name character varying(255),
-                                         civil_code character varying(50),
-                                         business_group_id character varying(50),
-                                         parental integer,
-                                         parent_id character varying(255),
-                                         constraint uk_platform_gb_channel_platform_id_catalog_id_device_channel_id unique (platform_id, device_channel_id),
-                                         constraint uk_platform_gb_channel_device_id unique (device_id)
+create table wvp_platform_gb_channel
+(
+    id                serial primary key,
+    platform_id       integer,
+    device_channel_id integer,
+    device_id         character varying(50),
+    name              character varying(255),
+    civil_code        character varying(50),
+    group_id          integer,
+    parental          integer,
+    parent_id         character varying(255),
+    constraint uk_platform_gb_channel_platform_id_catalog_id_device_channel_id unique (platform_id, device_channel_id),
+    constraint uk_platform_gb_channel_device_id unique (device_id)
 );
 
-create table wvp_stream_proxy (
-                                  id serial primary key,
-                                  type character varying(50),
-                                  app character varying(255),
-                                  stream character varying(255),
-                                  src_url character varying(255),
-                                  timeout integer,
-                                  ffmpeg_cmd_key character varying(255),
-                                  rtsp_type character varying(50),
-                                  media_server_id character varying(50),
-                                  enable_audio bool default false,
-                                  enable_mp4 bool default false,
-                                  pulling bool default false,
-                                  enable bool default false,
-                                  enable_remove_none_reader bool default false,
-                                  create_time character varying(50),
-                                  name character varying(255),
-                                  update_time character varying(50),
-                                  stream_key character varying(255),
-                                  enable_disable_none_reader bool default false,
-                                  constraint uk_stream_proxy_app_stream unique (app, stream)
+create table wvp_stream_proxy
+(
+    id                         serial primary key,
+    type                       character varying(50),
+    app                        character varying(255),
+    stream                     character varying(255),
+    src_url                    character varying(255),
+    timeout                    integer,
+    ffmpeg_cmd_key             character varying(255),
+    rtsp_type                  character varying(50),
+    media_server_id            character varying(50),
+    enable_audio               bool default false,
+    enable_mp4                 bool default false,
+    pulling                    bool default false,
+    enable                     bool default false,
+    enable_remove_none_reader  bool default false,
+    create_time                character varying(50),
+    name                       character varying(255),
+    update_time                character varying(50),
+    stream_key                 character varying(255),
+    enable_disable_none_reader bool default false,
+    constraint uk_stream_proxy_app_stream unique (app, stream)
 );
 
-create table wvp_stream_push (
-                                 id serial primary key,
-                                 app character varying(255),
-                                 stream character varying(255),
-                                 create_time character varying(50),
-                                 media_server_id character varying(50),
-                                 server_id character varying(50),
-                                 push_time character varying(50),
-                                 status bool default false,
-                                 update_time character varying(50),
-                                 pushing bool default false,
-                                 self bool default false,
-                                 constraint uk_stream_push_app_stream unique (app, stream)
+create table wvp_stream_push
+(
+    id              serial primary key,
+    app             character varying(255),
+    stream          character varying(255),
+    create_time     character varying(50),
+    media_server_id character varying(50),
+    server_id       character varying(50),
+    push_time       character varying(50),
+    status          bool default false,
+    update_time     character varying(50),
+    pushing         bool default false,
+    self            bool default false,
+    constraint uk_stream_push_app_stream unique (app, stream)
 );
-create table wvp_cloud_record (
-                                  id serial primary key,
-                                  app character varying(255),
-                                  stream character varying(255),
-                                  call_id character varying(255),
-                                  start_time bigint,
-                                  end_time bigint,
-                                  media_server_id character varying(50),
-                                  file_name character varying(255),
-                                  folder character varying(255),
-                                  file_path character varying(255),
-                                  collect bool default false,
-                                  file_size bigint,
-                                  time_len bigint,
-                                  constraint uk_stream_push_app_stream_path unique (app, stream, file_path)
+create table wvp_cloud_record
+(
+    id              serial primary key,
+    app             character varying(255),
+    stream          character varying(255),
+    call_id         character varying(255),
+    start_time      bigint,
+    end_time        bigint,
+    media_server_id character varying(50),
+    file_name       character varying(255),
+    folder          character varying(255),
+    file_path       character varying(255),
+    collect         bool default false,
+    file_size       bigint,
+    time_len        bigint,
+    constraint uk_stream_push_app_stream_path unique (app, stream, file_path)
 );
 
-create table wvp_user (
-                          id serial primary key,
-                          username character varying(255),
-                          password character varying(255),
-                          role_id integer,
-                          create_time character varying(50),
-                          update_time character varying(50),
-                          push_key character varying(50),
-                          constraint uk_user_username unique (username)
+create table wvp_user
+(
+    id          serial primary key,
+    username    character varying(255),
+    password    character varying(255),
+    role_id     integer,
+    create_time character varying(50),
+    update_time character varying(50),
+    push_key    character varying(50),
+    constraint uk_user_username unique (username)
 );
 
-create table wvp_user_role (
-                               id serial primary key,
-                               name character varying(50),
-                               authority character varying(50),
-                               create_time character varying(50),
-                               update_time character varying(50)
+create table wvp_user_role
+(
+    id          serial primary key,
+    name        character varying(50),
+    authority   character varying(50),
+    create_time character varying(50),
+    update_time character varying(50)
 );
-create table wvp_resources_tree (
-                                    id serial primary key ,
-                                    is_catalog bool default true,
-                                    device_channel_id integer ,
-                                    gb_stream_id integer,
-                                    name character varying(255),
-                                    parentId integer,
-                                    path character varying(255)
+create table wvp_resources_tree
+(
+    id                serial primary key,
+    is_catalog        bool default true,
+    device_channel_id integer,
+    gb_stream_id      integer,
+    name              character varying(255),
+    parentId          integer,
+    path              character varying(255)
 );
 
-create table wvp_user_api_key (
-                                  id serial primary key ,
-                                  user_id bigint,
-                                  app character varying(255) ,
-                                  api_key text,
-                                  expired_at bigint,
-                                  remark character varying(255),
-                                  enable bool default true,
-                                  create_time character varying(50),
-                                  update_time character varying(50)
+create table wvp_user_api_key
+(
+    id          serial primary key,
+    user_id     bigint,
+    app         character varying(255),
+    api_key     text,
+    expired_at  bigint,
+    remark      character varying(255),
+    enable      bool default true,
+    create_time character varying(50),
+    update_time character varying(50)
 );
 
 
 /*初始数据*/
-INSERT INTO wvp_user VALUES (1, 'admin','21232f297a57a5a743894a0e4a801fc3',1,'2021-04-13 14:14:57','2021-04-13 14:14:57','3e80d1762a324d5b0ff636e0bd16f1e3');
-INSERT INTO wvp_user_role VALUES (1, 'admin','0','2021-04-13 14:14:57','2021-04-13 14:14:57');
+INSERT INTO wvp_user
+VALUES (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', 1, '2021-04-13 14:14:57', '2021-04-13 14:14:57',
+        '3e80d1762a324d5b0ff636e0bd16f1e3');
+INSERT INTO wvp_user_role
+VALUES (1, 'admin', '0', '2021-04-13 14:14:57', '2021-04-13 14:14:57');
 
 CREATE TABLE wvp_common_group
 (
@@ -387,12 +406,19 @@ CREATE TABLE wvp_common_group
     device_id        varchar(50)  NOT NULL,
     name             varchar(255) NOT NULL,
     parent_device_id varchar(50) DEFAULT NULL,
-    business_group   varchar(50) DEFAULT NULL,
+    business_group   varchar(50) NOT NULL,
     create_time      varchar(50)  NOT NULL,
     update_time      varchar(50)  NOT NULL,
     UNIQUE KEY common_group_device_id (device_id)
 );
 
+CREATE TABLE wvp_common_group_channel
+(
+    id         serial primary key,
+    group_id   integer,
+    channel_id integer
+);
+
 CREATE TABLE wvp_common_region
 (
     id               serial primary key,