Commit 4bd4f50b4165953018a9f9174056d29d087fdaee

Authored by szy833
Committed by GitHub
2 parents c6202b3b 06e22d98

Merge branch '648540858:wvp-28181-2.0' into wvp-28181-2.0

... ... @@ -161,7 +161,7 @@
161 161 <version>2.1.3</version>
162 162 </dependency>
163 163  
164   - <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
  164 + <!-- json解析库fastjson -->
165 165 <dependency>
166 166 <groupId>com.alibaba</groupId>
167 167 <artifactId>fastjson</artifactId>
... ... @@ -203,6 +203,13 @@
203 203 <version>1.12</version>
204 204 </dependency>
205 205  
  206 + <!--excel解析库-->
  207 + <dependency>
  208 + <groupId>com.alibaba</groupId>
  209 + <artifactId>easyexcel</artifactId>
  210 + <version>3.0.4</version>
  211 + </dependency>
  212 +
206 213 <dependency>
207 214 <groupId>org.springframework.session</groupId>
208 215 <artifactId>spring-session-core</artifactId>
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEventListener.java
... ... @@ -85,7 +85,7 @@ public class OnlineEventListener implements ApplicationListener&lt;OnlineEvent&gt; {
85 85  
86 86 device.setOnline(1);
87 87 Device deviceInstore = storager.queryVideoDevice(device.getDeviceId());
88   - if (deviceInstore.getOnline() == 0) {
  88 + if (deviceInstore != null && deviceInstore.getOnline() == 0) {
89 89 List<DeviceChannel> deviceChannelList = storager.queryOnlineChannelsByDeviceId(device.getDeviceId());
90 90 eventPublisher.catalogEventPublish(null, deviceChannelList, CatalogEvent.ON);
91 91 }
... ...
src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java
... ... @@ -5,6 +5,7 @@ import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
5 5 import com.genersoft.iot.vmp.media.zlm.dto.MediaItem;
6 6 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
7 7 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
  8 +import com.genersoft.iot.vmp.vmanager.bean.StreamPushExcelDto;
8 9 import com.github.pagehelper.PageInfo;
9 10  
10 11 import java.util.List;
... ... @@ -65,4 +66,6 @@ public interface IStreamPushService {
65 66 void clean();
66 67  
67 68 boolean saveToRandomGB();
  69 +
  70 + void batchAdd(List<StreamPushItem> streamPushExcelDtoList);
68 71 }
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
... ... @@ -22,6 +22,7 @@ import com.genersoft.iot.vmp.storager.dao.GbStreamMapper;
22 22 import com.genersoft.iot.vmp.storager.dao.ParentPlatformMapper;
23 23 import com.genersoft.iot.vmp.storager.dao.PlatformGbStreamMapper;
24 24 import com.genersoft.iot.vmp.storager.dao.StreamPushMapper;
  25 +import com.genersoft.iot.vmp.vmanager.bean.StreamPushExcelDto;
25 26 import com.github.pagehelper.PageHelper;
26 27 import com.github.pagehelper.PageInfo;
27 28 import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -321,4 +322,37 @@ public class StreamPushServiceImpl implements IStreamPushService {
321 322 }
322 323 return true;
323 324 }
  325 +
  326 + @Override
  327 + public void batchAdd(List<StreamPushItem> streamPushItems) {
  328 + streamPushMapper.addAll(streamPushItems);
  329 + gbStreamMapper.batchAdd(streamPushItems);
  330 + // 查找开启了全部直播流共享的上级平台
  331 + List<ParentPlatform> parentPlatforms = parentPlatformMapper.selectAllAhareAllLiveStream();
  332 + if (parentPlatforms.size() > 0) {
  333 + for (StreamPushItem stream : streamPushItems) {
  334 + for (ParentPlatform parentPlatform : parentPlatforms) {
  335 + stream.setCatalogId(parentPlatform.getCatalogId());
  336 + stream.setPlatformId(parentPlatform.getServerGBId());
  337 + String streamId = stream.getStream();
  338 + StreamProxyItem streamProxyItem = platformGbStreamMapper.selectOne(stream.getApp(), streamId, parentPlatform.getServerGBId());
  339 + if (streamProxyItem == null) {
  340 + platformGbStreamMapper.add(stream);
  341 + eventPublisher.catalogEventPublishForStream(parentPlatform.getServerGBId(), stream, CatalogEvent.ADD);
  342 + }else {
  343 + if (!streamProxyItem.getGbId().equals(stream.getGbId())) {
  344 + // 此流使用另一个国标Id已经与该平台关联,移除此记录
  345 + platformGbStreamMapper.delByAppAndStreamAndPlatform(stream.getApp(), streamId, parentPlatform.getServerGBId());
  346 + platformGbStreamMapper.add(stream);
  347 + eventPublisher.catalogEventPublishForStream(parentPlatform.getServerGBId(), stream, CatalogEvent.ADD);
  348 + stream.setGbId(streamProxyItem.getGbId());
  349 + eventPublisher.catalogEventPublishForStream(parentPlatform.getServerGBId(), stream, CatalogEvent.DEL);
  350 + }
  351 + }
  352 + }
  353 + }
  354 +
  355 +
  356 + }
  357 + }
324 358 }
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushUploadFileHandler.java 0 → 100644
  1 +package com.genersoft.iot.vmp.service.impl;
  2 +
  3 +import com.alibaba.excel.context.AnalysisContext;
  4 +import com.alibaba.excel.event.AnalysisEventListener;
  5 +import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
  6 +import com.genersoft.iot.vmp.service.IStreamPushService;
  7 +import com.genersoft.iot.vmp.vmanager.bean.StreamPushExcelDto;
  8 +
  9 +import java.util.ArrayList;
  10 +import java.util.List;
  11 +
  12 +public class StreamPushUploadFileHandler extends AnalysisEventListener<StreamPushExcelDto> {
  13 +
  14 + private IStreamPushService pushService;
  15 + private String defaultMediaServerId;
  16 + private List<StreamPushItem> streamPushItems = new ArrayList<>();
  17 +
  18 + public StreamPushUploadFileHandler(IStreamPushService pushService, String defaultMediaServerId) {
  19 + this.pushService = pushService;
  20 + this.defaultMediaServerId = defaultMediaServerId;
  21 + }
  22 +
  23 + @Override
  24 + public void invoke(StreamPushExcelDto streamPushExcelDto, AnalysisContext analysisContext) {
  25 + StreamPushItem streamPushItem = new StreamPushItem();
  26 + streamPushItem.setApp(streamPushExcelDto.getApp());
  27 + streamPushItem.setStream(streamPushExcelDto.getStream());
  28 + streamPushItem.setGbId(streamPushExcelDto.getGbId());
  29 + streamPushItem.setStatus(false);
  30 + streamPushItem.setStreamType("push");
  31 + streamPushItem.setCreateStamp(System.currentTimeMillis());
  32 + streamPushItem.setMediaServerId(defaultMediaServerId);
  33 + streamPushItem.setName(streamPushExcelDto.getName());
  34 + streamPushItem.setOriginType(2);
  35 + streamPushItem.setOriginTypeStr("rtsp_push");
  36 + streamPushItem.setTotalReaderCount("0");
  37 + streamPushItems.add(streamPushItem);
  38 + if (streamPushItems.size() > 300) {
  39 + pushService.batchAdd(streamPushItems);
  40 + // 存储完成清理 list
  41 + streamPushItems.clear();
  42 + }
  43 + }
  44 +
  45 + @Override
  46 + public void doAfterAllAnalysed(AnalysisContext analysisContext) {
  47 + // 这里也要保存数据,确保最后遗留的数据也存储到数据库
  48 + pushService.batchAdd(streamPushItems);
  49 + }
  50 +}
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/GbStreamMapper.java
... ... @@ -4,6 +4,7 @@ import com.genersoft.iot.vmp.gb28181.bean.GbStream;
4 4 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
5 5 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
6 6 import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
  7 +import com.genersoft.iot.vmp.vmanager.bean.StreamPushExcelDto;
7 8 import org.apache.ibatis.annotations.*;
8 9 import org.springframework.stereotype.Repository;
9 10  
... ... @@ -82,7 +83,7 @@ public interface GbStreamMapper {
82 83 void batchDel(List<StreamProxyItem> streamProxyItemList);
83 84  
84 85 @Insert("<script> " +
85   - "insert into gb_stream " +
  86 + "REPLACE into gb_stream " +
86 87 "(app, stream, gbId, name, " +
87 88 "longitude, latitude, streamType, mediaServerId, status)" +
88 89 "values " +
... ... @@ -94,7 +95,6 @@ public interface GbStreamMapper {
94 95 "</script>")
95 96 void batchAdd(List<StreamPushItem> subList);
96 97  
97   -
98 98 @Update({"<script>" +
99 99 "<foreach collection='gpsMsgInfos' item='item' separator=';'>" +
100 100 " UPDATE" +
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/StreamPushMapper.java
... ... @@ -52,7 +52,7 @@ public interface StreamPushMapper {
52 52 @Insert("<script>" +
53 53 "INSERT INTO stream_push (app, stream, totalReaderCount, originType, originTypeStr, " +
54 54 "createStamp, aliveSecond, mediaServerId) " +
55   - "VALUES <foreach collection='streamPushItems' item='item' index='index' >" +
  55 + "VALUES <foreach collection='streamPushItems' item='item' index='index' separator=','>" +
56 56 "( '${item.app}', '${item.stream}', '${item.totalReaderCount}', '${item.originType}', " +
57 57 "'${item.originTypeStr}','${item.createStamp}', '${item.aliveSecond}', '${item.mediaServerId}' )" +
58 58 " </foreach>" +
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamPushExcelDto.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.bean;
  2 +
  3 +import com.alibaba.excel.annotation.ExcelProperty;
  4 +
  5 +public class StreamPushExcelDto {
  6 +
  7 + @ExcelProperty("名称")
  8 + private String name;
  9 +
  10 + @ExcelProperty("应用名")
  11 + private String app;
  12 +
  13 + @ExcelProperty("流ID")
  14 + private String stream;
  15 +
  16 + @ExcelProperty("国标ID")
  17 + private String gbId;
  18 +
  19 + public String getName() {
  20 + return name;
  21 + }
  22 +
  23 + public void setName(String name) {
  24 + this.name = name;
  25 + }
  26 +
  27 + public String getApp() {
  28 + return app;
  29 + }
  30 +
  31 + public void setApp(String app) {
  32 + this.app = app;
  33 + }
  34 +
  35 + public String getStream() {
  36 + return stream;
  37 + }
  38 +
  39 + public void setStream(String stream) {
  40 + this.stream = stream;
  41 + }
  42 +
  43 + public String getGbId() {
  44 + return gbId;
  45 + }
  46 +
  47 + public void setGbId(String gbId) {
  48 + this.gbId = gbId;
  49 + }
  50 +}
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java
1 1 package com.genersoft.iot.vmp.vmanager.streamPush;
2 2  
  3 +import com.alibaba.excel.EasyExcel;
  4 +import com.alibaba.excel.ExcelReader;
  5 +import com.alibaba.excel.read.metadata.ReadSheet;
3 6 import com.genersoft.iot.vmp.gb28181.bean.GbStream;
4 7 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
  8 +import com.genersoft.iot.vmp.service.IMediaServerService;
5 9 import com.genersoft.iot.vmp.service.IStreamPushService;
6   -import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
  10 +import com.genersoft.iot.vmp.service.impl.StreamPushUploadFileHandler;
  11 +import com.genersoft.iot.vmp.vmanager.bean.StreamPushExcelDto;
7 12 import com.github.pagehelper.PageInfo;
8 13 import io.swagger.annotations.Api;
9 14 import io.swagger.annotations.ApiImplicitParam;
10 15 import io.swagger.annotations.ApiImplicitParams;
11 16 import io.swagger.annotations.ApiOperation;
  17 +import org.apache.poi.sl.usermodel.Sheet;
12 18 import org.slf4j.Logger;
13 19 import org.slf4j.LoggerFactory;
14 20 import org.springframework.beans.factory.annotation.Autowired;
15 21 import org.springframework.stereotype.Controller;
16 22 import org.springframework.web.bind.annotation.*;
  23 +import org.springframework.web.multipart.MultipartFile;
  24 +
  25 +import java.io.IOException;
  26 +import java.io.InputStream;
17 27  
18 28 @Api(tags = "推流信息管理")
19 29 @Controller
... ... @@ -26,6 +36,9 @@ public class StreamPushController {
26 36 @Autowired
27 37 private IStreamPushService streamPushService;
28 38  
  39 + @Autowired
  40 + private IMediaServerService mediaServerService;
  41 +
29 42 @ApiOperation("推流列表查询")
30 43 @ApiImplicitParams({
31 44 @ApiImplicitParam(name="page", value = "当前页", required = true, dataTypeClass = Integer.class),
... ... @@ -88,5 +101,28 @@ public class StreamPushController {
88 101 return "fail";
89 102 }
90 103 }
  104 + @PostMapping(value = "upload")
  105 + @ResponseBody
  106 + public String uploadChannelFile(@RequestParam(value = "file") MultipartFile file){
  107 + if (file.isEmpty()) {
  108 + return "fail";
  109 + }
  110 + //获取文件流
  111 + InputStream inputStream = null;
  112 + try {
  113 + String name = file.getName();
  114 + inputStream = file.getInputStream();
  115 + } catch (IOException e) {
  116 + e.printStackTrace();
  117 + }
  118 + //传入参数
  119 + ExcelReader excelReader = EasyExcel.read(inputStream, StreamPushExcelDto.class,
  120 + new StreamPushUploadFileHandler(streamPushService, mediaServerService.getDefaultMediaServer().getId())).build();
  121 + ReadSheet readSheet = EasyExcel.readSheet(0).build();
  122 + excelReader.read(readSheet);
  123 + excelReader.finish();
  124 + return "success";
  125 + }
  126 +
91 127  
92 128 }
... ...
web_src/src/components/PushVideoList.vue
... ... @@ -8,6 +8,13 @@
8 8 <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;">
9 9 <span style="font-size: 1rem; font-weight: bold;">推流列表</span>
10 10 </div>
  11 + <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;">
  12 + <el-button icon="el-icon-upload2" size="mini" style="margin-right: 1rem;" type="primary" @click="importChannel">通道导入</el-button>
  13 + <el-button icon="el-icon-download" size="mini" style="margin-right: 1rem;" type="primary" >
  14 + <a style="color: #FFFFFF; text-align: center; text-decoration: none" href="/static/file/推流通道导入.zip" download='推流通道导入.zip' >下载模板</a>
  15 + </el-button>
  16 +
  17 + </div>
11 18 <devicePlayer ref="devicePlayer"></devicePlayer>
12 19 <addStreamTOGB ref="addStreamTOGB"></addStreamTOGB>
13 20 <el-table :data="pushList" border style="width: 100%" :height="winHeight">
... ... @@ -54,6 +61,7 @@
54 61 :total="total">
55 62 </el-pagination>
56 63 <streamProxyEdit ref="streamProxyEdit" ></streamProxyEdit>
  64 + <importChannel ref="importChannel" ></importChannel>
57 65 </el-main>
58 66 </el-container>
59 67 </div>
... ... @@ -64,13 +72,15 @@
64 72 import devicePlayer from './dialog/devicePlayer.vue'
65 73 import addStreamTOGB from './dialog/addStreamTOGB.vue'
66 74 import uiHeader from './UiHeader.vue'
  75 + import importChannel from './dialog/importChannel.vue'
67 76 export default {
68 77 name: 'pushVideoList',
69 78 components: {
70 79 devicePlayer,
71 80 addStreamTOGB,
72 81 streamProxyEdit,
73   - uiHeader
  82 + uiHeader,
  83 + importChannel,
74 84 },
75 85 data() {
76 86 return {
... ... @@ -196,8 +206,12 @@
196 206 s = t.getSeconds();
197 207 // 可根据需要在这里定义时间格式
198 208 return y+'-'+(m<10?'0'+m:m)+'-'+(d<10?'0'+d:d)+' '+(h<10?'0'+h:h)+':'+(i<10?'0'+i:i)+':'+(s<10?'0'+s:s);
199   - }
  209 + },
  210 + importChannel: function () {
  211 + this.$refs.importChannel.openDialog(()=>{
200 212  
  213 + })
  214 + },
201 215 }
202 216 };
203 217 </script>
... ...
web_src/src/components/dialog/importChannel.vue 0 → 100644
  1 +<template>
  2 + <div id="importChannel" v-loading="isLoging">
  3 + <el-dialog
  4 + title="导入通道数据"
  5 + width="30rem"
  6 + top="2rem"
  7 + :append-to-body="true"
  8 + :close-on-click-modal="false"
  9 + :visible.sync="showDialog"
  10 + :destroy-on-close="true"
  11 + @close="close()"
  12 + >
  13 + <div>
  14 + <el-upload
  15 + class="upload-box"
  16 + drag
  17 + action="debug/api/push/upload"
  18 + name="file"
  19 + >
  20 + <i class="el-icon-upload"></i>
  21 + <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
  22 + <div class="el-upload__tip" slot="tip">只能上传 csv / xls / xlsx 文件</div>
  23 + </el-upload>
  24 + </div>
  25 + </el-dialog>
  26 + </div>
  27 +</template>
  28 +
  29 +<script>
  30 +
  31 +export default {
  32 + name: "importChannel",
  33 + computed: {},
  34 + created() {},
  35 + data() {
  36 + return {
  37 + submitCallback: null,
  38 + showDialog: false,
  39 + isLoging: false,
  40 + isEdit: false,
  41 + };
  42 + },
  43 + methods: {
  44 + openDialog: function (callback) {
  45 + this.showDialog = true;
  46 + this.submitCallback = callback;
  47 + },
  48 + onSubmit: function () {
  49 + console.log("onSubmit");
  50 + console.log(this.form);
  51 + this.$axios({
  52 + method:"post",
  53 + url:`/api/platform/catalog/${!this.isEdit? "add":"edit"}`,
  54 + data: this.form
  55 + })
  56 + .then((res)=> {
  57 + if (res.data.code === 0) {
  58 + console.log("添加/修改成功")
  59 + if (this.submitCallback)this.submitCallback()
  60 + }else {
  61 + this.$message({
  62 + showClose: true,
  63 + message: res.data.msg,
  64 + type: "error",
  65 + });
  66 + }
  67 + this.close();
  68 + })
  69 + .catch((error)=> {
  70 + console.log(error);
  71 + });
  72 + },
  73 + close: function () {
  74 + this.showDialog = false;
  75 + this.$refs.form.resetFields();
  76 + },
  77 + },
  78 +};
  79 +</script>
  80 +<style>
  81 +.upload-box{
  82 + text-align: center;
  83 +}
  84 +</style>
... ...