| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367 | <template>  <div id="streamPushList" style="width: 100%">    <div v-if="!streamPush">      <div class="page-header">        <div class="page-title">推流列表</div>        <div class="page-header-btn">          搜索:          <el-input @input="getPushList" style="margin-right: 1rem; width: auto;" size="mini" placeholder="关键字"                    prefix-icon="el-icon-search" v-model="searchSrt" clearable></el-input>          流媒体:          <el-select size="mini" @change="getPushList" style="margin-right: 1rem;" v-model="mediaServerId"                     placeholder="请选择" default-first-option>            <el-option label="全部" value=""></el-option>            <el-option              v-for="item in mediaServerList"              :key="item.id"              :label="item.id"              :value="item.id">            </el-option>          </el-select>          推流状态:          <el-select size="mini" style="margin-right: 1rem;" @change="getPushList" v-model="pushing" 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 icon="el-icon-upload2" size="mini" style="margin-right: 1rem;" type="primary" @click="importChannel">            通道导入          </el-button>          <el-button icon="el-icon-download" size="mini" style="margin-right: 1rem;" type="primary">            <a style="color: #FFFFFF; text-align: center; text-decoration: none" href="/static/file/推流通道导入.zip"               download='推流通道导入.zip'>下载模板</a>          </el-button>          <el-button icon="el-icon-delete" size="mini" style="margin-right: 1rem;"                     :disabled="multipleSelection.length === 0" type="danger" @click="batchDel">批量移除          </el-button>          <el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="addStream">添加通道          </el-button>          <el-button icon="el-icon-refresh-right" circle size="mini" @click="refresh()"></el-button>        </div>      </div>      <el-table size=mini ref="pushListTable" :data="pushList" style="width: 100%" :height="winHeight" :loading="loading"                @selection-change="handleSelectionChange" :row-key="(row)=> row.app + row.stream">        <el-table-column  type="selection" :reserve-selection="true" min-width="55">        </el-table-column>        <el-table-column prop="gbName" label="名称" min-width="200">        </el-table-column>        <el-table-column prop="app" label="应用名" min-width="200">        </el-table-column>        <el-table-column prop="stream" label="流ID" min-width="200">        </el-table-column>        <el-table-column label="推流状态"  min-width="100">          <template slot-scope="scope">            <el-tag size="medium" v-if="scope.row.pushing">推流中</el-tag>            <el-tag size="medium" type="info" v-if="!scope.row.pushing">已停止</el-tag>          </template>        </el-table-column>        <el-table-column prop="gbDeviceId" label="国标编码" min-width="200" >        </el-table-column>        <el-table-column prop="mediaServerId" label="流媒体" min-width="200" >        </el-table-column>        <el-table-column label="开始时间"  min-width="200">          <template slot-scope="scope">            <el-button-group>              {{ scope.row.pushTime == null? "-":scope.row.pushTime }}            </el-button-group>          </template>        </el-table-column>        <el-table-column label="操作" min-width="360"  fixed="right">          <template slot-scope="scope">            <el-button size="medium" icon="el-icon-video-play"@click="playPush(scope.row)" type="text">播放            </el-button>            <el-divider direction="vertical"></el-divider>            <el-button size="medium" icon="el-icon-delete" type="text" @click="deletePush(scope.row.id)" style="color: #f56c6c" >删除</el-button>            <el-divider direction="vertical"></el-divider>            <el-button size="medium" icon="el-icon-position" type="text" @click="edit(scope.row)">              编辑            </el-button>            <el-button size="medium" icon="el-icon-cloudy" type="text" @click="queryCloudRecords(scope.row)">云端录像            </el-button>          </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>    </div>    <devicePlayer ref="devicePlayer"></devicePlayer>    <addStreamTOGB ref="addStreamTOGB"></addStreamTOGB>    <importChannel ref="importChannel"></importChannel>    <stream-push-edit v-if="streamPush" :streamPush="streamPush" :closeEdit="closeEdit"></stream-push-edit>  </div></template><script>import devicePlayer from './dialog/devicePlayer.vue'import addStreamTOGB from './dialog/pushStreamEdit.vue'import uiHeader from '../layout/UiHeader.vue'import importChannel from './dialog/importChannel.vue'import MediaServer from './service/MediaServer'import StreamPushEdit from "./StreamPushEdit";import ChannelEdit from "./ChannelEdit.vue";export default {  name: 'streamPushList',  components: {    ChannelEdit,    StreamPushEdit,    devicePlayer,    addStreamTOGB,    uiHeader,    importChannel,  },  data() {    return {      pushList: [], //设备列表      currentPusher: {}, //当前操作设备对象      updateLooper: 0, //数据刷新轮训标志      currentDeviceChannelsLenth: 0,      winHeight: window.innerHeight - 250,      mediaServerObj: new MediaServer(),      currentPage: 1,      count: 15,      total: 0,      searchSrt: "",      pushing: "",      mediaServerId: "",      mediaServerList: [],      multipleSelection: [],      loading: false,      streamPush: null,    };  },  computed: {},  mounted() {    this.initData();    this.updateLooper = setInterval(this.getPushList, 2000);  },  destroyed() {    clearTimeout(this.updateLooper);  },  methods: {    initData: function () {      this.loading = true;      this.mediaServerObj.getOnlineMediaServerList((data) => {        this.mediaServerList = data.data;      })      this.getPushList();    },    currentChange: function (val) {      this.currentPage = val;      this.getPushList();    },    handleSizeChange: function (val) {      this.count = val;      this.getPushList();    },    getPushList: function () {      let that = this;      this.$axios({        method: 'get',        url: `/api/push/list`,        params: {          page: that.currentPage,          count: that.count,          query: that.searchSrt,          pushing: that.pushing,          mediaServerId: that.mediaServerId,        }      }).then(function (res) {          if (res.data.code === 0) {            that.total = res.data.data.total;            that.pushList = res.data.data.list;          }      }).catch(function (error) {        console.error(error);      }).finally(()=>{        this.loading = false;      })    },    playPush: function (row) {      let that = this;      this.getListLoading = true;      this.$axios({        method: 'get',        url: '/api/push/start',        params: {          id: row.id        }      }).then(function (res) {        that.getListLoading = false;        if (res.data.code === 0 ) {          that.$refs.devicePlayer.openDialog("streamPlay", null, null, {            streamInfo: res.data.data,            hasAudio: true          });        }else {          that.$message.error(res.data.msg);        }      }).catch(function (error) {        console.error(error);        that.getListLoading = false;      });    },    deletePush: function (id) {      this.$confirm(`确定删除通道?`, '提示', {        confirmButtonText: '确定',        cancelButtonText: '取消',        type: 'warning'      }).then(() => {        this.loading = true;        this.$axios({          method: "post",          url: "/api/push/remove",          params: {            id: id,          }        }).then((res) => {          if (res.data.code === 0) {            this.initData()          }        }).catch(function (error) {          console.error(error);        });      }).catch(() => {      });    },    edit: function (row) {      this.streamPush = row    },    // 结束编辑    closeEdit: function (){      this.streamPush = null      this.getPushList()    },    removeFromGB: function (row) {      let that = this;      that.$axios({        method: "delete",        url: "/api/push/remove_form_gb",        data: row      }).then((res) => {        if (res.data.code === 0) {          that.initData()        }      }).catch(function (error) {        console.error(error);      });    },    queryCloudRecords: function (row) {      this.$router.push(`/cloudRecordDetail/${row.app}/${row.stream}`)    },    importChannel: function () {      this.$refs.importChannel.openDialog(() => {      })    },    addStream: function (){      // this.$refs.addStreamTOGB.openDialog(null, this.initData);      this.streamPush = {}    },    batchDel: function () {      this.$confirm(`确定删除选中的${this.multipleSelection.length}个通道?`, '提示', {        confirmButtonText: '确定',        cancelButtonText: '取消',        type: 'warning'      }).then(() => {        let ids = []        for (let i = 0; i < this.multipleSelection.length; i++) {          ids.push(this.multipleSelection[i].id)        }        let that = this;        that.$axios({          method: "delete",          url: "/api/push/batchRemove",          data: {            ids: ids          }        }).then((res) => {          this.initData();          this.$refs.pushListTable.clearSelection();        }).catch(function (error) {          console.error(error);        });      }).catch(() => {      });    },    handleSelectionChange: function (val) {      this.multipleSelection = val;    },    refresh: function () {      this.initData();    },  }};</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>
 |