فهرست منبع

添加录制计划的页面与通道查询接口

648540858 11 ماه پیش
والد
کامیت
ea2751e29b

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

@@ -126,6 +126,9 @@ public class CommonGBChannel {
     @Schema(description = "关联的国标设备数据库ID")
     private Integer gbDeviceDbId;
 
+    @Schema(description = "二进制保存的录制计划, 每一位表示每个小时的前半个小时")
+    private Long recordPLan;
+
     @Schema(description = "关联的推流Id(流来源是推流时有效)")
     private Integer streamPushId;
 

+ 21 - 0
src/main/java/com/genersoft/iot/vmp/gb28181/controller/CommonChannelController.java

@@ -101,11 +101,31 @@ public class CommonChannelController {
         return channel;
     }
 
+    @Operation(summary = "获取通道列表", security = @SecurityRequirement(name = JwtUtils.HEADER))
+    @Parameter(name = "page", description = "当前页", required = true)
+    @Parameter(name = "count", description = "每页查询数量", required = true)
+    @Parameter(name = "query", description = "查询内容")
+    @Parameter(name = "online", description = "是否在线")
+    @Parameter(name = "hasRecordPlan", description = "是否已设置录制计划")
+    @Parameter(name = "channelType", description = "通道类型, 0:国标设备,1:推流设备,2:拉流代理")
+    @GetMapping("/list")
+    public PageInfo<CommonGBChannel> queryList(int page, int count,
+                                                          @RequestParam(required = false) String query,
+                                                          @RequestParam(required = false) Boolean online,
+                                                          @RequestParam(required = false) Boolean hasRecordPlan,
+                                                          @RequestParam(required = false) Integer channelType){
+        if (ObjectUtils.isEmpty(query)){
+            query = null;
+        }
+        return channelService.queryList(page, count, query, online, hasRecordPlan, channelType);
+    }
+
     @Operation(summary = "获取关联行政区划通道列表", security = @SecurityRequirement(name = JwtUtils.HEADER))
     @Parameter(name = "page", description = "当前页", required = true)
     @Parameter(name = "count", description = "每页查询数量", required = true)
     @Parameter(name = "query", description = "查询内容")
     @Parameter(name = "online", description = "是否在线")
+    @Parameter(name = "channelType", description = "通道类型, 0:国标设备,1:推流设备,2:拉流代理")
     @Parameter(name = "civilCode", description = "行政区划")
     @GetMapping("/civilcode/list")
     public PageInfo<CommonGBChannel> queryListByCivilCode(int page, int count,
@@ -124,6 +144,7 @@ public class CommonChannelController {
     @Parameter(name = "count", description = "每页查询数量", required = true)
     @Parameter(name = "query", description = "查询内容")
     @Parameter(name = "online", description = "是否在线")
+    @Parameter(name = "channelType", description = "通道类型, 0:国标设备,1:推流设备,2:拉流代理")
     @Parameter(name = "groupDeviceId", description = "业务分组下的父节点ID")
     @GetMapping("/parent/list")
     public PageInfo<CommonGBChannel> queryListByParentId(int page, int count,

+ 2 - 0
src/main/java/com/genersoft/iot/vmp/gb28181/dao/CommonGBChannelMapper.java

@@ -457,4 +457,6 @@ public interface CommonGBChannelMapper {
             " </script>"})
     void updateGpsByDeviceIdForStreamPush(List<CommonGBChannel> channels);
 
+    @SelectProvider(type = ChannelProvider.class, method = "queryList")
+    List<CommonGBChannel> queryList(@Param("query") String query, @Param("online") Boolean online, @Param("hasRecordPlan") Boolean hasRecordPlan, @Param("channelType") Integer channelType);
 }

+ 32 - 0
src/main/java/com/genersoft/iot/vmp/gb28181/dao/provider/ChannelProvider.java

@@ -17,6 +17,7 @@ public class ChannelProvider {
             "    stream_proxy_id,\n" +
             "    create_time,\n" +
             "    update_time,\n" +
+            "    record_plan,\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" +
@@ -182,6 +183,37 @@ public class ChannelProvider {
         return sqlBuild.toString();
     }
 
+    public String queryList(Map<String, Object> params ){
+        StringBuilder sqlBuild = new StringBuilder();
+        sqlBuild.append(BASE_SQL);
+        sqlBuild.append(" where channel_type = 0 ");
+        if (params.get("query") != null) {
+            sqlBuild.append(" AND (coalesce(gb_device_id, device_id) LIKE concat('%',#{query},'%') escape '/'" +
+                    " OR coalesce(gb_name, name) LIKE concat('%',#{query},'%') escape '/' )")
+            ;
+        }
+        if (params.get("online") != null && (Boolean)params.get("online")) {
+            sqlBuild.append(" AND coalesce(gb_status, status) = 'ON'");
+        }
+        if (params.get("online") != null && !(Boolean)params.get("online")) {
+            sqlBuild.append(" AND coalesce(gb_status, status) = 'OFF'");
+        }
+        if (params.get("hasRecordPlan") != null && !(Boolean)params.get("hasRecordPlan")) {
+            sqlBuild.append(" AND record_plan == 0");
+        }
+
+        if (params.get("channelType") != null) {
+            if ((Integer)params.get("channelType") == 0) {
+                sqlBuild.append(" AND device_db_id is not null");
+            }else if ((Integer)params.get("channelType") == 1) {
+                sqlBuild.append(" AND stream_push_id is not null");
+            }else if ((Integer)params.get("channelType") == 2) {
+                sqlBuild.append(" AND stream_proxy_id is not null");
+            }
+        }
+        return sqlBuild.toString();
+    }
+
     public String queryInListByStatus(Map<String, Object> params ){
         StringBuilder sqlBuild = new StringBuilder();
         sqlBuild.append(BASE_SQL);

+ 3 - 0
src/main/java/com/genersoft/iot/vmp/gb28181/service/IGbChannelService.java

@@ -84,4 +84,7 @@ public interface IGbChannelService {
     List<CommonGBChannel> queryListByStreamPushList(List<StreamPush> streamPushList);
 
     void updateGpsByDeviceIdForStreamPush(List<CommonGBChannel> channels);
+
+    PageInfo<CommonGBChannel> queryList(int page, int count, String query, Boolean online, Boolean hasRecordPlan, Integer channelType);
+
 }

+ 12 - 0
src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GbChannelServiceImpl.java

@@ -714,4 +714,16 @@ public class GbChannelServiceImpl implements IGbChannelService {
     public void updateGpsByDeviceIdForStreamPush(List<CommonGBChannel> channels) {
         commonGBChannelMapper.updateGpsByDeviceIdForStreamPush(channels);
     }
+
+    @Override
+    public PageInfo<CommonGBChannel> queryList(int page, int count, String query, Boolean online, Boolean hasRecordPlan, Integer channelType) {
+        PageHelper.startPage(page, count);
+        if (query != null) {
+            query = query.replaceAll("/", "//")
+                    .replaceAll("%", "/%")
+                    .replaceAll("_", "/_");
+        }
+        List<CommonGBChannel> all = commonGBChannelMapper.queryList(query, online,  hasRecordPlan, channelType);
+        return new PageInfo<>(all);
+    }
 }

+ 15 - 0
src/main/java/com/genersoft/iot/vmp/vmanager/recordPlan/RecordPlanController.java

@@ -0,0 +1,15 @@
+package com.genersoft.iot.vmp.vmanager.recordPlan;
+
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@Tag(name = "录制计划")
+@Slf4j
+@RestController
+@RequestMapping("/api/record/plan")
+public class RecordPlanController {
+
+
+}

+ 241 - 0
web_src/src/components/RecordPLan.vue

@@ -0,0 +1,241 @@
+<template>
+  <div id="recordPLan" style="width: 100%">
+    <div class="page-header">
+        <div class="page-title">
+          <div >录像计划</div>
+        </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="hasRecordPlan"
+                       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="getChannelList"
+                       v-model="channelType" placeholder="请选择"
+                       default-first-option>
+              <el-option label="全部" value=""></el-option>
+              <el-option label="国标设备" :value="0"></el-option>
+              <el-option label="推流设备" :value="1"></el-option>
+              <el-option label="拉流代理" :value="2"></el-option>
+            </el-select>
+            <el-button size="mini" type="primary" @click="add()">
+              按国标设备添加
+            </el-button>
+            <el-button size="mini" type="danger" @click="remove()">
+              按国标设备移除
+            </el-button>
+            <el-button icon="el-icon-refresh-right" circle size="mini" @click="getChannelList()"></el-button>
+          </div>
+        </div>
+      </div>
+      <el-table size="medium" ref="channelListTable" :data="channelList" :height="winHeight" style="width: 100%"
+                header-row-class-name="table-header" >
+        <el-table-column type="selection" width="55" >
+        </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 v-slot:default="scope">
+            <div slot="reference" class="name-wrapper">
+              <el-tag size="medium" effect="plain" v-if="scope.row.gbDeviceDbId">国标设备</el-tag>
+              <el-tag size="medium" effect="plain" type="success" v-if="scope.row.streamPushId">推流设备</el-tag>
+              <el-tag size="medium" effect="plain" type="warning" v-if="scope.row.streamProxyId">拉流代理</el-tag>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column label="状态" min-width="100">
+          <template v-slot:default="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 v-slot:default="scope">
+            <div slot="reference" class="name-wrapper">
+              <el-tag size="medium" effect="dark" v-if="scope.row.recordPlan">已设置</el-tag>
+              <el-tag size="medium" effect="dark" v-else>未设置</el-tag>
+            </div>
+          </template>
+        </el-table-column>
+      </el-table>
+      <el-pagination
+        style="text-align: 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>
+  </div>
+</template>
+
+<script>
+import uiHeader from '../layout/UiHeader.vue'
+
+export default {
+  name: 'recordPLan',
+  components: {
+    uiHeader,
+  },
+  data() {
+    return {
+      channelList: [],
+      searchSrt: "",
+      channelType: "",
+      online: "",
+      hasRecordPlan: "",
+      hasGroup: "false",
+      winHeight: window.innerHeight - 180,
+      currentPage: 1,
+      count: 15,
+      total: 0,
+      loading: false,
+      loadSnap: {},
+      groupId: "",
+      businessGroup: "",
+      regionParents: ["请选择虚拟组织"],
+      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,
+          hasRecordPlan: this.hasRecordPlan,
+          channelType: this.channelType,
+        }
+      }).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);
+      });
+    },
+    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();
+    },
+    onChannelChange: function (deviceId) {
+      //
+    },
+  }
+};
+</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>

+ 1 - 0
web_src/src/layout/UiHeader.vue

@@ -15,6 +15,7 @@
         <el-menu-item index="/channel/region">行政区划</el-menu-item>
         <el-menu-item index="/channel/group">业务分组</el-menu-item>
       </el-submenu>
+      <el-menu-item index="/recordPlan">录制计划</el-menu-item>
       <el-menu-item index="/cloudRecord">云端录像</el-menu-item>
       <el-menu-item index="/mediaServerManger">节点管理</el-menu-item>
       <el-menu-item index="/platformList/15/1">国标级联</el-menu-item>

+ 5 - 0
web_src/src/router/index.js

@@ -26,6 +26,7 @@ import rtcPlayer from '../components/dialog/rtcPlayer.vue'
 import region from '../components/region.vue'
 import group from '../components/group.vue'
 import operations from '../components/operations.vue'
+import recordPLan from '../components/RecordPLan.vue'
 
 const originalPush = VueRouter.prototype.push
 VueRouter.prototype.push = function push(location) {
@@ -148,6 +149,10 @@ export default new VueRouter({
           path: '/operations',
           component: operations,
         },
+        {
+          path: '/recordPLan',
+          component: recordPLan,
+        },
         ]
     },
     {

+ 1 - 0
数据库/2.7.3/初始化-mysql-2.7.3.sql

@@ -147,6 +147,7 @@ create table wvp_device_channel
     gb_download_speed            character varying(255),
     gb_svc_space_support_mod     integer,
     gb_svc_time_support_mode     integer,
+    record_plan                  integer,
     stream_push_id               integer,
     stream_proxy_id              integer,
     constraint uk_wvp_device_channel_unique_device_channel unique (device_db_id, device_id),

+ 1 - 0
数据库/2.7.3/初始化-postgresql-kingbase-2.7.3.sql

@@ -163,6 +163,7 @@ create table wvp_device_channel
     gb_download_speed            character varying(255),
     gb_svc_space_support_mod     integer,
     gb_svc_time_support_mode     integer,
+    record_plan                  integer,
     stream_push_id               integer,
     stream_proxy_id              integer,
     constraint uk_wvp_device_channel_unique_device_channel unique (device_db_id, device_id),