离在线状态样式修改

修复未回复200ok导致catalog一直发送的bug
修改点播接口未收到视频后回复
This commit is contained in:
648540858 2020-10-13 14:46:47 +08:00
parent 84bdfd348c
commit c7270f9320
12 changed files with 179 additions and 80 deletions

View File

@ -3,11 +3,13 @@ package com.genersoft.iot.vmp.common;
public class StreamInfo { public class StreamInfo {
private String ssrc; private String ssrc;
private String deviceID;
private String cahnnelId;
private String flv; private String flv;
private String WS_FLV; private String ws_flv;
private String RTMP; private String rtmp;
private String HLS; private String hls;
private String RTSP; private String rtsp;
public String getSsrc() { public String getSsrc() {
return ssrc; return ssrc;
@ -25,35 +27,51 @@ public class StreamInfo {
this.flv = flv; this.flv = flv;
} }
public String getWS_FLV() { public String getWs_flv() {
return WS_FLV; return ws_flv;
} }
public void setWS_FLV(String WS_FLV) { public void setWs_flv(String ws_flv) {
this.WS_FLV = WS_FLV; this.ws_flv = ws_flv;
} }
public String getRTMP() { public String getRtmp() {
return RTMP; return rtmp;
} }
public void setRTMP(String RTMP) { public void setRtmp(String rtmp) {
this.RTMP = RTMP; this.rtmp = rtmp;
} }
public String getHLS() { public String getHls() {
return HLS; return hls;
} }
public void setHLS(String HLS) { public void setHls(String hls) {
this.HLS = HLS; this.hls = hls;
} }
public String getRTSP() { public String getRtsp() {
return RTSP; return rtsp;
} }
public void setRTSP(String RTSP) { public void setRtsp(String rtsp) {
this.RTSP = RTSP; this.rtsp = rtsp;
}
public String getDeviceID() {
return deviceID;
}
public void setDeviceID(String deviceID) {
this.deviceID = deviceID;
}
public String getCahnnelId() {
return cahnnelId;
}
public void setCahnnelId(String cahnnelId) {
this.cahnnelId = cahnnelId;
} }
} }

View File

@ -242,14 +242,15 @@ public class SIPCommander implements ISIPCommander {
StreamInfo streamInfo = new StreamInfo(); StreamInfo streamInfo = new StreamInfo();
streamInfo.setSsrc(ssrc); streamInfo.setSsrc(ssrc);
// String streamId = Integer.toHexString(Integer.parseInt(streamInfo.getSsrc())); // String streamId = Integer.toHexString(Integer.parseInt(streamInfo.getSsrc()));
String streamId = String.format("%08x", Integer.parseInt(streamInfo.getSsrc())).toUpperCase(); // ZLM 要求大写且首位补零 // String streamId = String.format("%08x", Integer.parseInt(streamInfo.getSsrc())).toUpperCase(); // ZLM 要求大写且首位补零
streamInfo.setFlv(String.format("http://%s:%s/rtp/%s.flv", mediaInfo.getLocalIP(), mediaInfo.getHttpPort(), streamId)); // streamInfo.setFlv(String.format("http://%s:%s/rtp/%s.flv", mediaInfo.getLocalIP(), mediaInfo.getHttpPort(), streamId));
streamInfo.setWS_FLV(String.format("ws://%s:%s/rtp/%s.flv", mediaInfo.getLocalIP(), mediaInfo.getHttpPort(), streamId)); // streamInfo.setWS_FLV(String.format("ws://%s:%s/rtp/%s.flv", mediaInfo.getLocalIP(), mediaInfo.getHttpPort(), streamId));
streamInfo.setRTMP(String.format("rtmp://%s:%s/rtp/%s", mediaInfo.getLocalIP(), mediaInfo.getRtmpPort(), streamId)); // streamInfo.setRTMP(String.format("rtmp://%s:%s/rtp/%s", mediaInfo.getLocalIP(), mediaInfo.getRtmpPort(), streamId));
streamInfo.setHLS(String.format("http://%s:%s/rtp/%s/hls.m3u8", mediaInfo.getLocalIP(), mediaInfo.getHttpPort(), streamId)); // streamInfo.setHLS(String.format("http://%s:%s/rtp/%s/hls.m3u8", mediaInfo.getLocalIP(), mediaInfo.getHttpPort(), streamId));
streamInfo.setRTSP(String.format("rtsp://%s:%s/rtp/%s", mediaInfo.getLocalIP(), mediaInfo.getRtspPort(), streamId)); // streamInfo.setRTSP(String.format("rtsp://%s:%s/rtp/%s", mediaInfo.getLocalIP(), mediaInfo.getRtspPort(), streamId));
streamInfo.setCahnnelId(channelId);
storager.startPlay(device.getDeviceId(), channelId, streamInfo); streamInfo.setDeviceID(device.getDeviceId());
storager.startPlay(streamInfo);
return streamInfo; return streamInfo;
} catch ( SipException | ParseException | InvalidArgumentException e) { } catch ( SipException | ParseException | InvalidArgumentException e) {
e.printStackTrace(); e.printStackTrace();

View File

@ -210,8 +210,11 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
msg.setType(DeferredResultHolder.CALLBACK_CMD_CATALOG); msg.setType(DeferredResultHolder.CALLBACK_CMD_CATALOG);
msg.setData(device); msg.setData(device);
deferredResultHolder.invokeResult(msg); deferredResultHolder.invokeResult(msg);
// 回复200
responseAck(evt);
} }
} catch (DocumentException e) { } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }

View File

@ -1,11 +1,13 @@
package com.genersoft.iot.vmp.media.zlm; package com.genersoft.iot.vmp.media.zlm;
import java.math.BigInteger; import java.math.BigInteger;
import java.text.DecimalFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONArray;
import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.conf.MediaServerConfig; import com.genersoft.iot.vmp.conf.MediaServerConfig;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager; import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import com.genersoft.iot.vmp.utils.IpUtil; import com.genersoft.iot.vmp.utils.IpUtil;
@ -35,7 +37,8 @@ import javax.servlet.http.HttpServletRequest;
public class ZLMHttpHookListener { public class ZLMHttpHookListener {
private final static Logger logger = LoggerFactory.getLogger(ZLMHttpHookListener.class); private final static Logger logger = LoggerFactory.getLogger(ZLMHttpHookListener.class);
@Autowired @Autowired
private SIPCommander cmder; private SIPCommander cmder;
@ -54,7 +57,7 @@ public class ZLMHttpHookListener {
logger.debug("ZLM HOOK on_flow_report API调用参数" + json.toString()); logger.debug("ZLM HOOK on_flow_report API调用参数" + json.toString());
} }
// TODO Auto-generated method stub // TODO Auto-generated method stub
JSONObject ret = new JSONObject(); JSONObject ret = new JSONObject();
ret.put("code", 0); ret.put("code", 0);
@ -113,6 +116,21 @@ public class ZLMHttpHookListener {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("ZLM HOOK on_publish API调用参数" + json.toString()); logger.debug("ZLM HOOK on_publish API调用参数" + json.toString());
} }
String app = json.getString("app");
String streamId = json.getString("id");
// String ssrc = String.format("%10d", Integer.parseInt(streamId, 16)); // ZLM 要求大写且首位补零
String ssrc = new DecimalFormat("0000000000").format(Integer.parseInt(streamId, 16));
StreamInfo streamInfo = storager.queryPlayBySSRC(ssrc);
if ("rtp".equals(app) && streamInfo != null ) {
MediaServerConfig mediaInfo = storager.getMediaInfo();
streamInfo.setFlv(String.format("http://%s:%s/rtp/%s.flv", mediaInfo.getLocalIP(), mediaInfo.getHttpPort(), streamId));
streamInfo.setWs_flv(String.format("ws://%s:%s/rtp/%s.flv", mediaInfo.getLocalIP(), mediaInfo.getHttpPort(), streamId));
streamInfo.setRtmp(String.format("rtmp://%s:%s/rtp/%s", mediaInfo.getLocalIP(), mediaInfo.getRtmpPort(), streamId));
streamInfo.setHls(String.format("http://%s:%s/rtp/%s/hls.m3u8", mediaInfo.getLocalIP(), mediaInfo.getHttpPort(), streamId));
streamInfo.setRtsp(String.format("rtsp://%s:%s/rtp/%s", mediaInfo.getLocalIP(), mediaInfo.getRtspPort(), streamId));
storager.startPlay(streamInfo);
}
// TODO Auto-generated method stub // TODO Auto-generated method stub
JSONObject ret = new JSONObject(); JSONObject ret = new JSONObject();
@ -213,8 +231,18 @@ public class ZLMHttpHookListener {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("ZLM HOOK on_stream_changed API调用参数" + json.toString()); logger.debug("ZLM HOOK on_stream_changed API调用参数" + json.toString());
} }
// TODO Auto-generated method stub // 流消失移除redis play
String app = json.getString("app");
String streamId = json.getString("stream");
boolean regist = json.getBoolean("regist");
// String ssrc = String.format("%10d", Integer.parseInt(streamId, 16)); // ZLM 要求大写且首位补零
String ssrc = new DecimalFormat("0000000000").format(Integer.parseInt(streamId, 16));
StreamInfo streamInfo = storager.queryPlayBySSRC(ssrc);
if ("rtp".equals(app) && !regist ) {
storager.stopPlay(streamInfo);
}
JSONObject ret = new JSONObject(); JSONObject ret = new JSONObject();
ret.put("code", 0); ret.put("code", 0);
ret.put("msg", "success"); ret.put("msg", "success");

View File

@ -136,30 +136,24 @@ public interface IVideoManagerStorager {
/** /**
* 开始播放时将流存入 * 开始播放时将流存入
* *
* @param deviceId 设备ID
* @param channelId 通道ID
* @param stream 流信息 * @param stream 流信息
* @return * @return
*/ */
public boolean startPlay(String deviceId, String channelId, StreamInfo stream); public boolean startPlay(StreamInfo stream);
/** /**
* 停止播放时删除 * 停止播放时删除
* *
* @param deviceId 设备ID
* @param channelId 通道ID
* @return * @return
*/ */
public boolean stopPlay(String deviceId, String channelId); public boolean stopPlay(StreamInfo streamInfo);
/** /**
* 查找视频流 * 查找视频流
* *
* @param deviceId 设备ID
* @param channelId 通道ID
* @return * @return
*/ */
public StreamInfo queryPlay(String deviceId, String channelId); public StreamInfo queryPlay(StreamInfo streamInfo);
/** /**
* 查询子设备 * 查询子设备
@ -182,4 +176,8 @@ public interface IVideoManagerStorager {
* @param deviceId * @param deviceId
*/ */
void cleanChannelsForDevice(String deviceId); void cleanChannelsForDevice(String deviceId);
StreamInfo queryPlayBySSRC(String ssrc);
StreamInfo queryPlayByDevice(String deviceId, String code);
} }

View File

@ -148,17 +148,12 @@ public class VideoManagerJdbcStoragerImpl implements IVideoManagerStorager {
} }
@Override @Override
public boolean startPlay(String deviceId, String channelId, StreamInfo stream) { public boolean stopPlay(StreamInfo streamInfo) {
return false; return false;
} }
@Override @Override
public boolean stopPlay(String deviceId, String channelId) { public StreamInfo queryPlay(StreamInfo streamInfo) {
return false;
}
@Override
public StreamInfo queryPlay(String deviceId, String channelId) {
return null; return null;
} }
@ -176,4 +171,19 @@ public class VideoManagerJdbcStoragerImpl implements IVideoManagerStorager {
public void cleanChannelsForDevice(String deviceId) { public void cleanChannelsForDevice(String deviceId) {
} }
@Override
public boolean startPlay(StreamInfo stream) {
return false;
}
@Override
public StreamInfo queryPlayBySSRC(String ssrc) {
return null;
}
@Override
public StreamInfo queryPlayByDevice(String deviceId, String code) {
return null;
}
} }

View File

@ -329,40 +329,53 @@ public class VideoManagerRedisStoragerImpl implements IVideoManagerStorager {
/** /**
* 开始播放时将流存入redis * 开始播放时将流存入redis
* *
* @param deviceId 设备ID
* @param channelId 通道ID
* @return * @return
*/ */
@Override @Override
public boolean startPlay(String deviceId, String channelId, StreamInfo stream) { public boolean startPlay(StreamInfo stream) {
return redis.set(String.format("%S_%s_%s", VideoManagerConstants.PLAYER_PREFIX, deviceId, channelId), return redis.set(String.format("%S_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX, stream.getSsrc(),stream.getDeviceID(), stream.getCahnnelId()),
stream); stream);
} }
/** /**
* 停止播放时从redis删除 * 停止播放时从redis删除
* *
* @param deviceId 设备ID
* @param channelId 通道ID
* @return * @return
*/ */
@Override @Override
public boolean stopPlay(String deviceId, String channelId) { public boolean stopPlay(StreamInfo streamInfo) {
return redis.del(String.format("%S_%s_%s", VideoManagerConstants.PLAYER_PREFIX, deviceId, channelId)); return redis.del(String.format("%S_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX,
streamInfo.getSsrc(),
streamInfo.getDeviceID(),
streamInfo.getCahnnelId()));
} }
/** /**
* 查询播放列表 * 查询播放列表
* @param deviceId 设备ID
* @param channelId 通道ID
* @return * @return
*/ */
@Override @Override
public StreamInfo queryPlay(String deviceId, String channelId) { public StreamInfo queryPlay(StreamInfo streamInfo) {
return (StreamInfo)redis.get(String.format("%S_%s_%s", VideoManagerConstants.PLAYER_PREFIX, deviceId, channelId)); return (StreamInfo)redis.get(String.format("%S_%s_%s_%s",
VideoManagerConstants.PLAYER_PREFIX,
streamInfo.getSsrc(),
streamInfo.getDeviceID(),
streamInfo.getCahnnelId()));
}
@Override
public StreamInfo queryPlayBySSRC(String ssrc) {
List<Object> playLeys = redis.keys(String.format("%S_%s_*", VideoManagerConstants.PLAYER_PREFIX, ssrc));
if (playLeys.size() == 0) return null;
return (StreamInfo)redis.get(playLeys.get(0).toString());
} }
@Override
public StreamInfo queryPlayByDevice(String deviceId, String code) {
List<Object> playLeys = redis.keys(String.format("%S_*_%s_%s", VideoManagerConstants.PLAYER_PREFIX,
deviceId,
code));
return (StreamInfo)redis.get(playLeys.get(0).toString());
}
/** /**
* 更新流媒体信息 * 更新流媒体信息
@ -423,4 +436,7 @@ public class VideoManagerRedisStoragerImpl implements IVideoManagerStorager {
} }
} }
} }
} }

View File

@ -37,7 +37,18 @@ public class PlayController {
Device device = storager.queryVideoDevice(deviceId); Device device = storager.queryVideoDevice(deviceId);
StreamInfo streamInfo = cmder.playStreamCmd(device, channelId); StreamInfo streamInfo = cmder.playStreamCmd(device, channelId);
// 等待推流, TODO 默认超时15s
long startTime = System.currentTimeMillis();
while (storager.queryPlay(streamInfo) == null || storager.queryPlay(streamInfo).getFlv() == null) {
try {
if (System.currentTimeMillis() - startTime > 15 * 1000)
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
streamInfo = storager.queryPlay(streamInfo);
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug(String.format("设备预览 API调用deviceId%s channelId%s",deviceId, channelId)); logger.debug(String.format("设备预览 API调用deviceId%s channelId%s",deviceId, channelId));
logger.debug("设备预览 API调用ssrc"+streamInfo.getSsrc()+",ZLMedia streamId:"+Integer.toHexString(Integer.parseInt(streamInfo.getSsrc()))); logger.debug("设备预览 API调用ssrc"+streamInfo.getSsrc()+",ZLMedia streamId:"+Integer.toHexString(Integer.parseInt(streamInfo.getSsrc())));
@ -55,7 +66,8 @@ public class PlayController {
public ResponseEntity<String> playStop(@PathVariable String ssrc){ public ResponseEntity<String> playStop(@PathVariable String ssrc){
cmder.streamByeCmd(ssrc); cmder.streamByeCmd(ssrc);
StreamInfo streamInfo = storager.queryPlayBySSRC(ssrc);
storager.stopPlay(streamInfo);
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug(String.format("设备预览停止API调用ssrc%s", ssrc)); logger.debug(String.format("设备预览停止API调用ssrc%s", ssrc));
} }

View File

@ -70,7 +70,7 @@ public class ApiStreamController {
return result; return result;
} }
// 查询是否已经在播放 // 查询是否已经在播放
StreamInfo streamInfo = storager.queryPlay(device.getDeviceId(), code); StreamInfo streamInfo = storager.queryPlayByDevice(device.getDeviceId(), code);
if (streamInfo == null) streamInfo = cmder.playStreamCmd(device, code); if (streamInfo == null) streamInfo = cmder.playStreamCmd(device, code);
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
@ -86,10 +86,10 @@ public class ApiStreamController {
result.put("ChannelName", deviceChannel.getName()); result.put("ChannelName", deviceChannel.getName());
result.put("ChannelCustomName ", ""); result.put("ChannelCustomName ", "");
result.put("FLV ", streamInfo.getFlv()); result.put("FLV ", streamInfo.getFlv());
result.put("WS_FLV ", streamInfo.getWS_FLV()); result.put("WS_FLV ", streamInfo.getWs_flv());
result.put("RTMP", streamInfo.getRTMP()); result.put("RTMP", streamInfo.getRtmp());
result.put("HLS", streamInfo.getHLS()); result.put("HLS", streamInfo.getHls());
result.put("RTSP", streamInfo.getRTSP()); result.put("RTSP", streamInfo.getRtsp());
result.put("CDN", ""); result.put("CDN", "");
result.put("SnapURL", ""); result.put("SnapURL", "");
result.put("Transport", device.getTransport()); result.put("Transport", device.getTransport());
@ -135,14 +135,14 @@ public class ApiStreamController {
@RequestParam(required = false)String check_outputs @RequestParam(required = false)String check_outputs
){ ){
StreamInfo streamInfo = storager.queryPlay(serial, code); StreamInfo streamInfo = storager.queryPlayByDevice(serial, code);
if (streamInfo == null) { if (streamInfo == null) {
JSONObject result = new JSONObject(); JSONObject result = new JSONObject();
result.put("error","未找到流信息"); result.put("error","未找到流信息");
return result; return result;
} }
cmder.streamByeCmd(streamInfo.getSsrc()); cmder.streamByeCmd(streamInfo.getSsrc());
storager.stopPlay(serial, code); storager.stopPlay(streamInfo);
return null; return null;
} }
@ -151,7 +151,6 @@ public class ApiStreamController {
* @param serial 设备编号 * @param serial 设备编号
* @param channel 通道序号 * @param channel 通道序号
* @param code 通道国标编号 * @param code 通道国标编号
* @param check_outputs
* @return * @return
*/ */
@RequestMapping(value = "/touch") @RequestMapping(value = "/touch")

View File

@ -35,8 +35,16 @@
</el-table-column> </el-table-column>
<el-table-column prop="subCount" label="子节点数"> <el-table-column prop="subCount" label="子节点数">
</el-table-column> </el-table-column>
<el-table-column prop="ptztypeText" label="云台类型"> <el-table-column label="状态" width="180" align="center">
</el-table-column> <template slot-scope="scope">
<div slot="reference" class="name-wrapper">
<el-tag size="medium" v-if="scope.row.status == 1">在线</el-tag>
<el-tag size="medium" type="info" v-if="scope.row.status == 0">离线</el-tag>
</div>
</template>
</el-table-column>
<el-table-column prop="ptztypeText" label="云台类型">
</el-table-column>
<el-table-column label="操作" width="240" align="center" fixed="right"> <el-table-column label="操作" width="240" align="center" fixed="right">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button size="mini" icon="el-icon-video-play" v-if="scope.row.parental == 0" @click="sendDevicePush(scope.row)">预览视频</el-button> <el-button size="mini" icon="el-icon-video-play" v-if="scope.row.parental == 0" @click="sendDevicePush(scope.row)">预览视频</el-button>
@ -58,17 +66,20 @@
</el-main> </el-main>
</el-container> </el-container>
<Loading v-if="isLoging" marginTop="-50%"></Loading>
</div> </div>
</template> </template>
<script> <script>
import devicePlayer from './gb28181/devicePlayer.vue' import devicePlayer from './gb28181/devicePlayer.vue'
import uiHeader from './UiHeader.vue' import uiHeader from './UiHeader.vue'
import Loading from './Loading.vue'
export default { export default {
name: 'channelList', name: 'channelList',
components: { components: {
devicePlayer, devicePlayer,
uiHeader uiHeader,
Loading
}, },
data() { data() {
return { return {
@ -85,7 +96,8 @@
currentPage: parseInt(this.$route.params.page), currentPage: parseInt(this.$route.params.page),
count: parseInt(this.$route.params.count), count: parseInt(this.$route.params.count),
total:0, total:0,
beforeUrl:"/videoList" beforeUrl:"/videoList",
isLoging: false
}; };
}, },
@ -182,7 +194,7 @@
// //
sendDevicePush: function(itemData) { sendDevicePush: function(itemData) {
let deviceId = this.deviceId; let deviceId = this.deviceId;
this.isLoging = true;
let channelId = itemData.channelId; let channelId = itemData.channelId;
console.log("通知设备推流1" + deviceId + " : " + channelId); console.log("通知设备推流1" + deviceId + " : " + channelId);
let that = this; let that = this;
@ -191,6 +203,7 @@
url: '/api/play/' + deviceId + '/' + channelId url: '/api/play/' + deviceId + '/' + channelId
}).then(function(res) { }).then(function(res) {
let ssrc = res.data.ssrc; let ssrc = res.data.ssrc;
that.isLoging = false
that.$refs.devicePlayer.play(res.data,deviceId,channelId); that.$refs.devicePlayer.play(res.data,deviceId,channelId);
}).catch(function(e) { }).catch(function(e) {
}); });

View File

@ -115,6 +115,7 @@
deviceId: '', deviceId: '',
channelId: '', channelId: '',
tabActiveName: 'media' tabActiveName: 'media'
}; };
}, },
methods: { methods: {

View File

@ -1,7 +1,6 @@
<template> <template>
<div id="app"> <div id="app">
<el-container> <el-container>
<el-header> <el-header>
<uiHeader></uiHeader> <uiHeader></uiHeader>
</el-header> </el-header>
@ -37,14 +36,15 @@
<el-table-column label="状态" width="180" align="center"> <el-table-column label="状态" width="180" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<div slot="reference" class="name-wrapper"> <div slot="reference" class="name-wrapper">
<el-tag size="medium">{{ scope.row.online==1?'在线' :'离线'}}</el-tag> <el-tag size="medium" v-if="scope.row.online == 1">在线</el-tag>
<el-tag size="medium" type="info" v-if="scope.row.online == 0">离线</el-tag>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" width="240" align="center" fixed="right"> <el-table-column label="操作" width="240" align="center" fixed="right">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button size="mini" icon="el-icon-refresh" @click="refDevice(scope.row)">刷新</el-button> <el-button size="mini" icon="el-icon-refresh" @click="refDevice(scope.row)">刷新通道</el-button>
<el-button size="mini" icon="el-icon-s-open" type="primary" @click="showChannelList(scope.row)">查看通道</el-button> <el-button size="mini" icon="el-icon-s-open" type="primary" @click="showChannelList(scope.row)">查看通道</el-button>
</template> </template>
</el-table-column> </el-table-column>