Commit 9b9a13ab36fe93153148a489436e04b12aabcdd6

Authored by 648540858
1 parent fd3a4ef4

国标录像UI重构

src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java
@@ -10,6 +10,7 @@ import org.slf4j.Logger; @@ -10,6 +10,7 @@ import org.slf4j.Logger;
10 import org.slf4j.LoggerFactory; 10 import org.slf4j.LoggerFactory;
11 import org.springframework.beans.factory.annotation.Autowired; 11 import org.springframework.beans.factory.annotation.Autowired;
12 import org.springframework.http.HttpStatus; 12 import org.springframework.http.HttpStatus;
  13 +import org.springframework.util.ObjectUtils;
13 import org.springframework.web.filter.OncePerRequestFilter; 14 import org.springframework.web.filter.OncePerRequestFilter;
14 15
15 import javax.servlet.*; 16 import javax.servlet.*;
@@ -51,6 +52,9 @@ public class ApiAccessFilter extends OncePerRequestFilter { @@ -51,6 +52,9 @@ public class ApiAccessFilter extends OncePerRequestFilter {
51 52
52 LogDto logDto = new LogDto(); 53 LogDto logDto = new LogDto();
53 logDto.setName(uriName); 54 logDto.setName(uriName);
  55 + if (ObjectUtils.isEmpty(username)) {
  56 + username = "";
  57 + }
54 logDto.setUsername(username); 58 logDto.setUsername(username);
55 logDto.setAddress(servletRequest.getRemoteAddr()); 59 logDto.setAddress(servletRequest.getRemoteAddr());
56 logDto.setResult(HttpStatus.valueOf(servletResponse.getStatus()).toString()); 60 logDto.setResult(HttpStatus.valueOf(servletResponse.getStatus()).toString());
web_src/src/components/CloudRecordDetail.vue
@@ -30,7 +30,7 @@ @@ -30,7 +30,7 @@
30 </el-aside> 30 </el-aside>
31 <el-main style="padding: 22px"> 31 <el-main style="padding: 22px">
32 <div class="playBox" :style="playerStyle"> 32 <div class="playBox" :style="playerStyle">
33 - <player ref="recordVideoPlayer" :videoUrl="videoUrl" fluent autoplay :height="true" ></player> 33 + <player ref="recordVideoPlayer" :videoUrl="videoUrl" :height="true" style="width: 100%" ></player>
34 </div> 34 </div>
35 <div class="player-option-box" > 35 <div class="player-option-box" >
36 <el-slider 36 <el-slider
@@ -310,7 +310,20 @@ @@ -310,7 +310,20 @@
310 let h = parseInt(val/3600); 310 let h = parseInt(val/3600);
311 let m = parseInt((val - h*3600)/60); 311 let m = parseInt((val - h*3600)/60);
312 let s = parseInt(val - h*3600 - m*60); 312 let s = parseInt(val - h*3600 - m*60);
313 - return h + ":" + m + ":" + s 313 +
  314 + let hStr = h;
  315 + let mStr = m;
  316 + let sStr = s;
  317 + if (h < 10) {
  318 + hStr = "0" + hStr;
  319 + }
  320 + if (m < 10) {
  321 + mStr = "0" + mStr;s
  322 + }
  323 + if (s < 10) {
  324 + sStr = "0" + sStr;
  325 + }
  326 + return hStr + ":" + mStr + ":" + sStr
314 }, 327 },
315 deleteRecord(){ 328 deleteRecord(){
316 // TODO 329 // TODO
web_src/src/components/GBRecordDetail.vue 0 → 100644
  1 +<template>
  2 + <div style="width: 100%">
  3 + <div class="page-header" >
  4 + <div class="page-title">
  5 + <el-page-header @back="goBack" content="国标录像"></el-page-header>
  6 + </div>
  7 + </div>
  8 + <el-container>
  9 + <el-aside width="300px">
  10 + <div class="record-list-box-box">
  11 + <el-date-picker size="mini" v-model="chooseDate" type="date" value-format="yyyy-MM-dd" placeholder="日期" @change="dateChange()"></el-date-picker>
  12 + <div class="record-list-box" v-loading="recordsLoading" :style="recordListStyle">
  13 + <ul v-if="detailFiles.length >0" class="infinite-list record-list" >
  14 + <li v-for="item in detailFiles" class="infinite-list-item record-list-item" >
  15 +
  16 + <el-tag v-if="chooseFile != item" @click="checkedFile(item)">
  17 + <i class="el-icon-video-camera" ></i>
  18 + {{ moment(item.startTime).format('HH:mm:ss')}}-{{ moment(item.endTime).format('HH:mm:ss')}}
  19 + </el-tag>
  20 + <el-tag v-if="chooseFile == item" type="danger" >
  21 + <i class="el-icon-video-camera" ></i>
  22 + {{ moment(item.startTime).format('HH:mm:ss')}}-{{ moment(item.endTime).format('HH:mm:ss')}}
  23 + </el-tag>
  24 + <i style="color: #409EFF;margin-left: 5px;" class="el-icon-download" @click="downloadRecord(item)" ></i>
  25 + </li>
  26 + </ul>
  27 + </div>
  28 + <div size="mini" v-if="detailFiles.length ==0" class="record-list-no-val" >暂无数据</div>
  29 + </div>
  30 +
  31 + </el-aside>
  32 + <el-main style="padding-bottom: 10px;">
  33 + <div class="playBox" :style="playerStyle">
  34 + <player ref="recordVideoPlayer"
  35 + :videoUrl="videoUrl"
  36 + :error="videoError"
  37 + :message="videoError"
  38 + :hasAudio="hasAudio"
  39 + style="max-height: 100%"
  40 + fluent autoplay live ></player>
  41 + </div>
  42 + <div class="player-option-box">
  43 + <div>
  44 + <el-button-group >
  45 + <el-button size="mini" class="iconfont icon-zanting" title="开始" @click="gbPause()"></el-button>
  46 + <el-button size="mini" class="iconfont icon-kaishi" title="暂停" @click="gbPlay()"></el-button>
  47 + <el-dropdown size="mini" title="播放倍速" style="margin-left: 1px;" @command="gbScale">
  48 + <el-button size="mini">
  49 + 倍速 <i class="el-icon-arrow-down el-icon--right"></i>
  50 + </el-button>
  51 + <el-dropdown-menu slot="dropdown">
  52 + <el-dropdown-item command="0.25">0.25倍速</el-dropdown-item>
  53 + <el-dropdown-item command="0.5">0.5倍速</el-dropdown-item>
  54 + <el-dropdown-item command="1.0">1倍速</el-dropdown-item>
  55 + <el-dropdown-item command="2.0">2倍速</el-dropdown-item>
  56 + <el-dropdown-item command="4.0">4倍速</el-dropdown-item>
  57 + </el-dropdown-menu>
  58 + </el-dropdown>
  59 + <el-button size="mini" class="iconfont icon-xiazai1" title="下载选定录像" @click="downloadRecord()"></el-button>
  60 + <el-button v-if="sliderMIn === 0 && sliderMax === 86400" size="mini" class="iconfont icon-slider" title="放大滑块" @click="setSliderFit()"></el-button>
  61 + <el-button v-if="sliderMIn !== 0 || sliderMax !== 86400" size="mini" class="iconfont icon-slider-right" title="恢复滑块" @click="setSliderFit()"></el-button>
  62 + </el-button-group>
  63 + </div>
  64 + <el-slider
  65 + class="playtime-slider"
  66 + v-model="playTime"
  67 + id="playtimeSlider"
  68 + :disabled="detailFiles.length === 0"
  69 + :min="sliderMIn"
  70 + :max="sliderMax"
  71 + :range="true"
  72 + :format-tooltip="playTimeFormat"
  73 + @change="playTimeChange"
  74 + :marks="playTimeSliderMarks">
  75 + </el-slider>
  76 + <div class="slider-val-box">
  77 + <div class="slider-val" v-for="item of detailFiles" :style="'width:' + getDataWidth(item) + '%; left:' + getDataLeft(item) + '%'"></div>
  78 + </div>
  79 + </div>
  80 +
  81 + </el-main>
  82 + </el-container>
  83 + <recordDownload ref="recordDownload"></recordDownload>
  84 + </div>
  85 +</template>
  86 +
  87 +
  88 +<script>
  89 + import uiHeader from '../layout/UiHeader.vue'
  90 + import player from './common/jessibuca.vue'
  91 + import moment from 'moment'
  92 + import recordDownload from './dialog/recordDownload.vue'
  93 + export default {
  94 + name: 'app',
  95 + components: {
  96 + uiHeader, player,recordDownload
  97 + },
  98 + data() {
  99 + return {
  100 + deviceId: this.$route.params.deviceId,
  101 + channelId: this.$route.params.channelId,
  102 + recordsLoading: false,
  103 + sliderTime: 0,
  104 + seekTime: 0,
  105 + recordStartTime: 0,
  106 + streamId: "",
  107 + hasAudio: false,
  108 + detailFiles: [],
  109 + chooseDate: null,
  110 + videoUrl: null,
  111 + chooseFile: null,
  112 + streamInfo: null,
  113 + app: null,
  114 + mediaServerId: null,
  115 + ssrc: null,
  116 +
  117 + sliderMIn: 0,
  118 + sliderMax: 86400,
  119 + autoPlay: true,
  120 + taskUpdate: null,
  121 + tabVal: "running",
  122 + recordListStyle: {
  123 + height: this.winHeight + "px",
  124 + overflow: "auto",
  125 + margin: "10px auto 10px auto"
  126 + },
  127 + playerStyle: {
  128 + "margin": "0 auto 20px auto",
  129 + "height": this.winHeight + "px",
  130 + },
  131 + winHeight: window.innerHeight - 240,
  132 + playTime: 0,
  133 + playTimeSliderMarks: {
  134 + 0: "00:00",
  135 + 3600: "01:00",
  136 + 7200: "02:00",
  137 + 10800: "03:00",
  138 + 14400: "04:00",
  139 + 18000: "05:00",
  140 + 21600: "06:00",
  141 + 25200: "07:00",
  142 + 28800: "08:00",
  143 + 32400: "09:00",
  144 + 36000: "10:00",
  145 + 39600: "11:00",
  146 + 43200: "12:00",
  147 + 46800: "13:00",
  148 + 50400: "14:00",
  149 + 54000: "15:00",
  150 + 57600: "16:00",
  151 + 61200: "17:00",
  152 + 64800: "18:00",
  153 + 68400: "19:00",
  154 + 72000: "20:00",
  155 + 75600: "21:00",
  156 + 79200: "22:00",
  157 + 82800: "23:00",
  158 + 86400: "24:00",
  159 + },
  160 + };
  161 + },
  162 + computed: {
  163 +
  164 + },
  165 + mounted() {
  166 + this.recordListStyle.height = this.winHeight + "px";
  167 + this.playerStyle["height"] = this.winHeight + "px";
  168 + this.chooseDate = moment().format('YYYY-MM-DD')
  169 + this.dateChange();
  170 + },
  171 + destroyed() {
  172 + this.$destroy('recordVideoPlayer');
  173 + },
  174 + methods: {
  175 + dateChange(){
  176 + if (!this.chooseDate) {
  177 + return;
  178 + }
  179 + this.recordsLoading = true;
  180 + this.detailFiles = [];
  181 + let startTime = this.chooseDate + " 00:00:00";
  182 + let endTime = this.chooseDate + " 23:59:59";
  183 + this.$axios({
  184 + method: 'get',
  185 + url: '/api/gb_record/query/' + this.deviceId + '/' + this.channelId + '?startTime=' + startTime + '&endTime=' + endTime
  186 + }).then((res)=>{
  187 + this.recordsLoading = false;
  188 + if(res.data.code === 0) {
  189 + // 处理时间信息
  190 + this.detailFiles = res.data.data.recordList;
  191 +
  192 + }else {
  193 + this.$message({
  194 + showClose: true,
  195 + message: res.data.msg,
  196 + type: "error",
  197 + });
  198 + }
  199 +
  200 + }).catch((e)=> {
  201 + this.recordsLoading = false;
  202 + // that.videoHistory.searchHistoryResult = falsificationData.recordData;
  203 + });
  204 + },
  205 + moment: function (v) {
  206 + return moment(v)
  207 + },
  208 + videoError: function (e) {
  209 + console.log("播放器错误:" + JSON.stringify(e));
  210 + },
  211 + checkedFile(file){
  212 + this.chooseFile = file;
  213 + // 开始回放
  214 + this.playRecord(file)
  215 +
  216 + },
  217 + playRecord: function (row) {
  218 +
  219 + let startTime = row.startTime
  220 + this.recordStartTime = row.startTime
  221 + this.showTimeText = row.startTime.split(" ")[1]
  222 + let endTime = row.endTime
  223 + this.sliderTime = 0;
  224 + this.seekTime = new Date(endTime).getTime() - new Date(startTime).getTime();
  225 + if (this.streamId !== "") {
  226 + this.stopPlayRecord(()=> {
  227 + this.streamId = "";
  228 + this.playRecord(row);
  229 + })
  230 + } else {
  231 + this.$axios({
  232 + method: 'get',
  233 + url: '/api/playback/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + startTime + '&endTime=' +
  234 + endTime
  235 + }).then((res)=> {
  236 + if (res.data.code === 0) {
  237 + this.streamInfo = res.data.data;
  238 + this.app = this.streamInfo.app;
  239 + this.streamId = this.streamInfo.stream;
  240 + this.mediaServerId = this.streamInfo.mediaServerId;
  241 + this.ssrc = this.streamInfo.ssrc;
  242 + this.videoUrl = this.getUrlByStreamInfo();
  243 + }else {
  244 + this.$message({
  245 + showClose: true,
  246 + message: res.data.msg,
  247 + type: "error",
  248 + });
  249 + }
  250 + });
  251 + }
  252 + },
  253 + gbPlay(){
  254 + console.log('前端控制:播放');
  255 + this.$axios({
  256 + method: 'get',
  257 + url: '/api/playback/resume/' + this.streamId
  258 + }).then((res)=> {
  259 + this.$refs[this.activePlayer].play(this.videoUrl)
  260 + });
  261 + },
  262 + gbPause(){
  263 + console.log('前端控制:暂停');
  264 + this.$axios({
  265 + method: 'get',
  266 + url: '/api/playback/pause/' + this.streamId
  267 + }).then(function (res) {});
  268 + },
  269 + gbScale(command){
  270 + console.log('前端控制:倍速 ' + command);
  271 + this.$axios({
  272 + method: 'get',
  273 + url: `/api/playback/speed/${this.streamId }/${command}`
  274 + }).then(function (res) {});
  275 + },
  276 + downloadRecord: function (row) {
  277 + if (!row) {
  278 + let startTimeStr = moment(new Date(this.chooseDate + " 00:00:00").getTime() + this.playTime[0]*1000).format("YYYY-MM-DD HH:mm:ss");
  279 + let endTimeStr = moment(new Date(this.chooseDate + " 00:00:00").getTime() + this.playTime[1]*1000).format("YYYY-MM-DD HH:mm:ss");
  280 + console.log(startTimeStr);
  281 + console.log(endTimeStr);
  282 + row = {
  283 + startTime: startTimeStr,
  284 + endTime: endTimeStr
  285 + }
  286 + }
  287 + if (this.streamId !== "") {
  288 + this.stopPlayRecord(()=> {
  289 + this.streamId = "";
  290 + this.downloadRecord(row);
  291 + })
  292 + }else {
  293 + this.$axios({
  294 + method: 'get',
  295 + url: '/api/gb_record/download/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' +
  296 + row.endTime + '&downloadSpeed=4'
  297 + }).then( (res)=> {
  298 + if (res.data.code === 0) {
  299 + let streamInfo = res.data.data;
  300 + this.$refs.recordDownload.openDialog(this.deviceId, this.channelId, streamInfo.app, streamInfo.stream, streamInfo.mediaServerId);
  301 + }else {
  302 + this.$message({
  303 + showClose: true,
  304 + message: res.data.msg,
  305 + type: "error",
  306 + });
  307 + }
  308 + });
  309 + }
  310 + },
  311 + stopDownloadRecord: function (callback) {
  312 + this.$refs["recordVideoPlayer"].pause();
  313 + this.videoUrl = '';
  314 + this.$axios({
  315 + method: 'get',
  316 + url: '/api/gb_record/download/stop/' + this.deviceId + "/" + this.channelId+ "/" + this.streamId
  317 + }).then((res)=> {
  318 + if (callback) callback(res)
  319 + });
  320 + },
  321 + stopPlayRecord: function (callback) {
  322 + this.$refs["recordVideoPlayer"].pause();
  323 + this.videoUrl = '';
  324 + this.$axios({
  325 + method: 'get',
  326 + url: '/api/playback/stop/' + this.deviceId + "/" + this.channelId + "/" + this.streamId
  327 + }).then(function (res) {
  328 + if (callback) callback()
  329 + });
  330 + },
  331 + getDataWidth(item){
  332 + let timeForFile = this.getTimeForFile(item);
  333 + let result = (timeForFile[2])/((this.sliderMax - this.sliderMIn)*1000)
  334 + return result*100
  335 + },
  336 + getDataLeft(item){
  337 + let timeForFile = this.getTimeForFile(item);
  338 + let differenceTime = timeForFile[0].getTime() - new Date(this.chooseDate + " 00:00:00").getTime()
  339 + return parseFloat((differenceTime - this.sliderMIn * 1000)/((this.sliderMax - this.sliderMIn)*1000))*100 ;
  340 + },
  341 + getUrlByStreamInfo(){
  342 + if (location.protocol === "https:") {
  343 + this.videoUrl = this.streamInfo["wss_flv"]
  344 + }else {
  345 + this.videoUrl = this.streamInfo["ws_flv"]
  346 + }
  347 + return this.videoUrl;
  348 +
  349 + },
  350 + playTimeChange(val){
  351 + console.log(val)
  352 + let maxTime = this.getTimeForFile(this.detailFiles[this.detailFiles.length - 1])[1];
  353 +
  354 + let startTimeStr = moment(new Date(this.chooseDate + " 00:00:00").getTime() + val[0]*1000).format("YYYY-MM-DD HH:mm:ss");
  355 + let endTimeStr = moment(new Date(this.chooseDate + " 00:00:00").getTime() + val[1]*1000).format("YYYY-MM-DD HH:mm:ss");
  356 + console.log(startTimeStr);
  357 + console.log(endTimeStr);
  358 +
  359 + this.checkedFile({
  360 + startTime: startTimeStr,
  361 + endTime: endTimeStr,
  362 + });
  363 + },
  364 + setSliderFit() {
  365 + if (this.sliderMIn === 0 && this.sliderMax === 86400) {
  366 + if (this.detailFiles.length > 0){
  367 + let timeForFile = this.getTimeForFile(this.detailFiles[0]);
  368 + let lastTimeForFile = this.getTimeForFile(this.detailFiles[this.detailFiles.length - 1]);
  369 + let timeNum = timeForFile[0].getTime() - new Date(this.chooseDate + " " + "00:00:00").getTime()
  370 + let lastTimeNum = lastTimeForFile[1].getTime() - new Date(this.chooseDate + " " + "00:00:00").getTime()
  371 +
  372 + this.playTime = parseInt(timeNum/1000)
  373 + this.sliderMIn = parseInt(timeNum/1000 - timeNum/1000%(60*60))
  374 + this.sliderMax = parseInt(lastTimeNum/1000 - lastTimeNum/1000%(60*60)) + 60*60
  375 +
  376 + this.playTime = [this.sliderMIn, this.sliderMax];
  377 + }
  378 + }else {
  379 + this.sliderMIn = 0;
  380 + this.sliderMax = 86400;
  381 + }
  382 + },
  383 + getTimeForFile(file){
  384 + let startTime = new Date(file.startTime);
  385 + let endTime = new Date(file.endTime);
  386 + return [startTime, endTime, endTime.getTime() - startTime.getTime()];
  387 + },
  388 + playTimeFormat(val){
  389 + let h = parseInt(val/3600);
  390 + let m = parseInt((val - h*3600)/60);
  391 + let s = parseInt(val - h*3600 - m*60);
  392 +
  393 + let hStr = h;
  394 + let mStr = m;
  395 + let sStr = s;
  396 + if (h < 10) {
  397 + hStr = "0" + hStr;
  398 + }
  399 + if (m < 10) {
  400 + mStr = "0" + mStr;s
  401 + }
  402 + if (s < 10) {
  403 + sStr = "0" + sStr;
  404 + }
  405 + return hStr + ":" + mStr + ":" + sStr
  406 + },
  407 + goBack(){
  408 + window.history.go(-1);
  409 + }
  410 + }
  411 + };
  412 +</script>
  413 +
  414 +<style>
  415 + .el-slider__runway {
  416 + background-color:rgba(206, 206, 206, 0.47) !important;
  417 + }
  418 + .el-slider__bar {
  419 + background-color: rgba(153, 153, 153, 0) !important;
  420 + }
  421 + .playtime-slider {
  422 + position: relative;
  423 + z-index: 100;
  424 + }
  425 + .data-picker-true{
  426 +
  427 + }
  428 + .data-picker-true:after{
  429 + content: "";
  430 + position: absolute;
  431 + width: 4px;
  432 + height: 4px;
  433 + background-color: #606060;
  434 + border-radius: 4px;
  435 + left: 45%;
  436 + top: 74%;
  437 +
  438 + }
  439 + .data-picker-false{
  440 +
  441 + }
  442 + .slider-val-box{
  443 + height: 6px;
  444 + position: relative;
  445 + top: -22px;
  446 + }
  447 + .slider-val{
  448 + height: 6px;
  449 + background-color: #007CFF;
  450 + position: absolute;
  451 + }
  452 + .record-list-box-box{
  453 + width: 250px;
  454 + float: left;
  455 + }
  456 + .record-list-box{
  457 + overflow: auto;
  458 + width: 220px;
  459 + list-style: none;
  460 + padding: 0;
  461 + margin: 0;
  462 + margin-top: 0px;
  463 + padding: 1rem 0;
  464 + background-color: #FFF;
  465 + margin-top: 10px;
  466 + }
  467 + .record-list{
  468 + list-style: none;
  469 + padding: 0;
  470 + margin: 0;
  471 + background-color: #FFF;
  472 +
  473 + }
  474 + .record-list-no-val {
  475 + position: absolute;
  476 + color: #9f9f9f;
  477 + top: 50%;
  478 + left: 110px;
  479 + }
  480 + .record-list-item{
  481 + padding: 0;
  482 + margin: 0;
  483 + margin: 0.5rem 0;
  484 + cursor: pointer;
  485 + }
  486 + .record-list-option {
  487 + width: 10px;
  488 + float: left;
  489 + margin-top: 39px;
  490 +
  491 + }
  492 + .player-option-box{
  493 + padding: 0 20px;
  494 + }
  495 +</style>
web_src/src/components/channelList.vue
@@ -269,10 +269,10 @@ export default { @@ -269,10 +269,10 @@ export default {
269 }); 269 });
270 }, 270 },
271 queryRecords: function (itemData) { 271 queryRecords: function (itemData) {
272 - var format = moment().format("yyyy-MM-DD");  
273 let deviceId = this.deviceId; 272 let deviceId = this.deviceId;
274 let channelId = itemData.channelId; 273 let channelId = itemData.channelId;
275 - this.$refs.devicePlayer.openDialog("record", deviceId, channelId, {date: format}) 274 +
  275 + this.$router.push(`/gbRecordDetail/${deviceId}/${channelId}`)
276 }, 276 },
277 stopDevicePush: function (itemData) { 277 stopDevicePush: function (itemData) {
278 var that = this; 278 var that = this;
web_src/src/components/console.vue
@@ -101,11 +101,14 @@ export default { @@ -101,11 +101,14 @@ export default {
101 window.clearTimeout(this.timer); 101 window.clearTimeout(this.timer);
102 } 102 }
103 this.timer = setTimeout(()=>{ 103 this.timer = setTimeout(()=>{
104 - this.getSystemInfo();  
105 - this.getLoad();  
106 - this.timer = null;  
107 - this.loopForSystemInfo()  
108 - this.getResourceInfo() 104 + if (this.$route.path === "/console") {
  105 + this.getSystemInfo();
  106 + this.getLoad();
  107 + this.timer = null;
  108 + this.loopForSystemInfo()
  109 + this.getResourceInfo()
  110 + }
  111 +
109 }, 2000) 112 }, 2000)
110 }, 113 },
111 getSystemInfo: function (){ 114 getSystemInfo: function (){
web_src/src/components/console/ConsoleResource.vue
1 <template > 1 <template >
2 <div id="consoleResource" style="width: 100%; height: 100%; background: #FFFFFF; text-align: center"> 2 <div id="consoleResource" style="width: 100%; height: 100%; background: #FFFFFF; text-align: center">
3 <div style="width: 50%;height: 50%; float:left; "> 3 <div style="width: 50%;height: 50%; float:left; ">
4 - <el-progress :width="100" :stroke-width="8" type="circle" :percentage="Math.floor(deviceInfo.online/deviceInfo.total*100)" style="margin-top: 20px; font-size: 18px"></el-progress> 4 + <el-progress v-if="deviceInfo.total > 0" :width="100" :stroke-width="8" type="circle" :percentage="Math.floor(deviceInfo.online/deviceInfo.total*100)" style="margin-top: 20px; font-size: 18px"></el-progress>
  5 + <el-progress v-if="deviceInfo.total === 0" :width="100" :stroke-width="8" type="circle" :percentage="0" style="margin-top: 20px; font-size: 18px"></el-progress>
5 <div class="resourceInfo"> 6 <div class="resourceInfo">
6 设备总数:{{deviceInfo.total}}<br/> 7 设备总数:{{deviceInfo.total}}<br/>
7 在线数:{{deviceInfo.online}} 8 在线数:{{deviceInfo.online}}
8 </div> 9 </div>
9 </div> 10 </div>
10 <div style="width: 50%;height: 50%; float:left; "> 11 <div style="width: 50%;height: 50%; float:left; ">
11 - <el-progress :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(channelInfo.online/channelInfo.total*100)" style="margin-top: 20px"></el-progress> 12 + <el-progress v-if="channelInfo.total > 0" :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(channelInfo.online/channelInfo.total*100)" style="margin-top: 20px"></el-progress>
  13 + <el-progress v-if="channelInfo.total === 0" :width="100" :stroke-width="10" type="circle" :percentage="0" style="margin-top: 20px"></el-progress>
12 <div class="resourceInfo"> 14 <div class="resourceInfo">
13 通道总数:{{channelInfo.total}}<br/> 15 通道总数:{{channelInfo.total}}<br/>
14 在线数:{{channelInfo.online}} 16 在线数:{{channelInfo.online}}
15 </div> 17 </div>
16 </div> 18 </div>
17 <div style="width: 50%;height: 50%; float:left; "> 19 <div style="width: 50%;height: 50%; float:left; ">
18 - <el-progress :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(pushInfo.online/pushInfo.total*100)" style="margin-top: 20px"></el-progress> 20 + <el-progress v-if="pushInfo.total > 0" :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(pushInfo.online/pushInfo.total*100)" style="margin-top: 20px"></el-progress>
  21 + <el-progress v-if="pushInfo.total === 0" :width="100" :stroke-width="10" type="circle" :percentage="0" style="margin-top: 20px"></el-progress>
19 <div class="resourceInfo"> 22 <div class="resourceInfo">
20 推流总数:{{pushInfo.total}}<br/> 23 推流总数:{{pushInfo.total}}<br/>
21 在线数:{{pushInfo.online}} 24 在线数:{{pushInfo.online}}
22 </div> 25 </div>
23 </div> 26 </div>
24 <div style="width: 50%;height: 50%; float:left; "> 27 <div style="width: 50%;height: 50%; float:left; ">
25 - <el-progress :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(proxyInfo.online/proxyInfo.total*100)" style="margin-top: 20px"></el-progress> 28 + <el-progress v-if="proxyInfo.total > 0" :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(proxyInfo.online/proxyInfo.total*100)" style="margin-top: 20px"></el-progress>
  29 + <el-progress v-if="proxyInfo.total === 0" :width="100" :stroke-width="10" type="circle" :percentage="0" style="margin-top: 20px"></el-progress>
26 <div class="resourceInfo"> 30 <div class="resourceInfo">
27 拉流代理总数:{{proxyInfo.total}}<br/> 31 拉流代理总数:{{proxyInfo.total}}<br/>
28 在线数:{{proxyInfo.online}} 32 在线数:{{proxyInfo.online}}
web_src/src/components/dialog/devicePlayer.vue
@@ -23,11 +23,6 @@ @@ -23,11 +23,6 @@
23 <div id="shared" style="text-align: right; margin-top: 1rem;"> 23 <div id="shared" style="text-align: right; margin-top: 1rem;">
24 <el-tabs v-model="tabActiveName" @tab-click="tabHandleClick" > 24 <el-tabs v-model="tabActiveName" @tab-click="tabHandleClick" >
25 <el-tab-pane label="实时视频" name="media"> 25 <el-tab-pane label="实时视频" name="media">
26 - <div style="margin-bottom: 0.5rem;">  
27 - <!-- <el-button type="primary" size="small" @click="playRecord(true, '')">播放</el-button>-->  
28 - <!-- <el-button type="primary" size="small" @click="startRecord()">录制</el-button>-->  
29 - <!-- <el-button type="primary" size="small" @click="stopRecord()">停止录制</el-button>-->  
30 - </div>  
31 <div style="display: flex; margin-bottom: 0.5rem; height: 2.5rem;"> 26 <div style="display: flex; margin-bottom: 0.5rem; height: 2.5rem;">
32 <span style="width: 5rem; line-height: 2.5rem; text-align: right;">播放地址:</span> 27 <span style="width: 5rem; line-height: 2.5rem; text-align: right;">播放地址:</span>
33 <el-input v-model="getPlayerShared.sharedUrl" :disabled="true" > 28 <el-input v-model="getPlayerShared.sharedUrl" :disabled="true" >
@@ -148,51 +143,6 @@ @@ -148,51 +143,6 @@
148 </div> 143 </div>
149 </el-tab-pane> 144 </el-tab-pane>
150 <!--{"code":0,"data":{"paths":["22-29-30.mp4"],"rootPath":"/home/kkkkk/Documents/ZLMediaKit/release/linux/Debug/www/record/hls/kkkkk/2020-05-11/"}}--> 145 <!--{"code":0,"data":{"paths":["22-29-30.mp4"],"rootPath":"/home/kkkkk/Documents/ZLMediaKit/release/linux/Debug/www/record/hls/kkkkk/2020-05-11/"}}-->
151 - <el-tab-pane label="录像查询" name="record" v-if="showRrecord">  
152 - <div style="width: 100%;">  
153 - <div style="width: 100%; text-align: left">  
154 - <span>录像控制</span>  
155 - <el-button-group style="margin-left: 1rem;">  
156 - <el-button size="mini" class="iconfont icon-zanting" title="开始" @click="gbPause()"></el-button>  
157 - <el-button size="mini" class="iconfont icon-kaishi" title="暂停" @click="gbPlay()"></el-button>  
158 - <el-dropdown size="mini" title="播放倍速" style="margin-left: 1px;" @command="gbScale">  
159 - <el-button size="mini">  
160 - 倍速 <i class="el-icon-arrow-down el-icon--right"></i>  
161 - </el-button>  
162 - <el-dropdown-menu slot="dropdown">  
163 - <el-dropdown-item command="0.25">0.25倍速</el-dropdown-item>  
164 - <el-dropdown-item command="0.5">0.5倍速</el-dropdown-item>  
165 - <el-dropdown-item command="1.0">1倍速</el-dropdown-item>  
166 - <el-dropdown-item command="2.0">2倍速</el-dropdown-item>  
167 - <el-dropdown-item command="4.0">4倍速</el-dropdown-item>  
168 - </el-dropdown-menu>  
169 - </el-dropdown>  
170 - </el-button-group>  
171 - <el-date-picker style="float: right;" size="mini" v-model="videoHistory.date" type="date" value-format="yyyy-MM-dd" placeholder="日期" @change="queryRecords()"></el-date-picker>  
172 - </div>  
173 - <div style="width: 100%; text-align: left">  
174 - <span class="demonstration" style="padding: 12px 36px 12px 0;float: left;">{{showTimeText}}</span>  
175 - <el-slider style="width: 80%; float:left;" v-model="sliderTime" @change="gbSeek" :show-tooltip="false"></el-slider>  
176 - </div>  
177 - </div>  
178 -  
179 -  
180 - <el-table :data="videoHistory.searchHistoryResult" height="150" v-loading="recordsLoading">  
181 - <el-table-column label="名称" prop="name"></el-table-column>  
182 - <el-table-column label="文件" prop="filePath"></el-table-column>  
183 - <el-table-column label="开始时间" prop="startTime" :formatter="timeFormatter"></el-table-column>  
184 - <el-table-column label="结束时间" prop="endTime" :formatter="timeFormatter"></el-table-column>  
185 -  
186 - <el-table-column label="操作">  
187 - <template slot-scope="scope">  
188 - <el-button-group>  
189 - <el-button icon="el-icon-video-play" size="mini" @click="playRecord(scope.row)">播放</el-button>  
190 - <el-button icon="el-icon-download" size="mini" @click="downloadRecord(scope.row)">下载</el-button>  
191 - </el-button-group>  
192 - </template>  
193 - </el-table-column>  
194 - </el-table>  
195 - </el-tab-pane>  
196 <!--遥控界面--> 146 <!--遥控界面-->
197 <el-tab-pane label="云台控制" name="control" v-if="showPtz"> 147 <el-tab-pane label="云台控制" name="control" v-if="showPtz">
198 <div style="display: flex; justify-content: left;"> 148 <div style="display: flex; justify-content: left;">
@@ -286,21 +236,18 @@ @@ -286,21 +236,18 @@
286 </el-tabs> 236 </el-tabs>
287 </div> 237 </div>
288 </el-dialog> 238 </el-dialog>
289 - <recordDownload ref="recordDownload"></recordDownload>  
290 </div> 239 </div>
291 </template> 240 </template>
292 241
293 <script> 242 <script>
294 import rtcPlayer from '../dialog/rtcPlayer.vue' 243 import rtcPlayer from '../dialog/rtcPlayer.vue'
295 import LivePlayer from '@liveqing/liveplayer' 244 import LivePlayer from '@liveqing/liveplayer'
296 -// import player from '../dialog/easyPlayer.vue'  
297 import jessibucaPlayer from '../common/jessibuca.vue' 245 import jessibucaPlayer from '../common/jessibuca.vue'
298 -import recordDownload from '../dialog/recordDownload.vue'  
299 export default { 246 export default {
300 name: 'devicePlayer', 247 name: 'devicePlayer',
301 props: {}, 248 props: {},
302 components: { 249 components: {
303 - LivePlayer, jessibucaPlayer, rtcPlayer, recordDownload, 250 + LivePlayer, jessibucaPlayer, rtcPlayer,
304 }, 251 },
305 computed: { 252 computed: {
306 getPlayerShared: function () { 253 getPlayerShared: function () {
@@ -328,10 +275,6 @@ export default { @@ -328,10 +275,6 @@ export default {
328 livePlayer : ["ws_flv", "wss_flv"], 275 livePlayer : ["ws_flv", "wss_flv"],
329 webRTC: ["rtc", "rtcs"], 276 webRTC: ["rtc", "rtcs"],
330 }, 277 },
331 - videoHistory: {  
332 - date: '',  
333 - searchHistoryResult: [] //媒体流历史记录搜索结果  
334 - },  
335 showVideoDialog: false, 278 showVideoDialog: false,
336 streamId: '', 279 streamId: '',
337 app : '', 280 app : '',
@@ -357,7 +300,6 @@ export default { @@ -357,7 +300,6 @@ export default {
357 tracks: [], 300 tracks: [],
358 coverPlaying:false, 301 coverPlaying:false,
359 tracksLoading: false, 302 tracksLoading: false,
360 - recordPlay: "",  
361 showPtz: true, 303 showPtz: true,
362 showRrecord: true, 304 showRrecord: true,
363 tracksNotLoaded: false, 305 tracksNotLoaded: false,
@@ -418,11 +360,6 @@ export default { @@ -418,11 +360,6 @@ export default {
418 case "media": 360 case "media":
419 this.play(param.streamInfo, param.hasAudio) 361 this.play(param.streamInfo, param.hasAudio)
420 break; 362 break;
421 - case "record":  
422 - this.showVideoDialog = true;  
423 - this.videoHistory.date = param.date;  
424 - this.queryRecords()  
425 - break;  
426 case "streamPlay": 363 case "streamPlay":
427 this.tabActiveName = "media"; 364 this.tabActiveName = "media";
428 this.showRrecord = false; 365 this.showRrecord = false;
@@ -433,9 +370,6 @@ export default { @@ -433,9 +370,6 @@ export default {
433 break; 370 break;
434 } 371 }
435 }, 372 },
436 - timeAxisSelTime: function (val) {  
437 - console.log(val)  
438 - },  
439 play: function (streamInfo, hasAudio) { 373 play: function (streamInfo, hasAudio) {
440 this.streamInfo = streamInfo; 374 this.streamInfo = streamInfo;
441 this.hasAudio = hasAudio; 375 this.hasAudio = hasAudio;
@@ -531,10 +465,6 @@ export default { @@ -531,10 +465,6 @@ export default {
531 this.convertStop(); 465 this.convertStop();
532 } 466 }
533 this.convertKey = '' 467 this.convertKey = ''
534 - if (this.recordPlay != '') {  
535 - this.stopPlayRecord();  
536 - }  
537 - this.recordPlay = ''  
538 }, 468 },
539 469
540 copySharedInfo: function (data) { 470 copySharedInfo: function (data) {
@@ -559,137 +489,6 @@ export default { @@ -559,137 +489,6 @@ export default {
559 } 489 }
560 ); 490 );
561 }, 491 },
562 -  
563 - queryRecords: function () {  
564 - if (!this.videoHistory.date) {  
565 - return;  
566 - }  
567 - this.recordsLoading = true;  
568 - this.videoHistory.searchHistoryResult = [];  
569 - let that = this;  
570 - var startTime = this.videoHistory.date + " 00:00:00";  
571 - var endTime = this.videoHistory.date + " 23:59:59";  
572 - this.$axios({  
573 - method: 'get',  
574 - url: '/api/gb_record/query/' + this.deviceId + '/' + this.channelId + '?startTime=' + startTime + '&endTime=' + endTime  
575 - }).then(function (res) {  
576 - console.log(res)  
577 - that.recordsLoading = false;  
578 - if(res.data.code === 0) {  
579 - // 处理时间信息  
580 - that.videoHistory.searchHistoryResult = res.data.data.recordList;  
581 - }else {  
582 - this.$message({  
583 - showClose: true,  
584 - message: res.data.msg,  
585 - type: "error",  
586 - });  
587 - }  
588 -  
589 - }).catch(function (e) {  
590 - console.log(e.message);  
591 - // that.videoHistory.searchHistoryResult = falsificationData.recordData;  
592 - });  
593 -  
594 - },  
595 - onTimeChange: function (video) {  
596 - // this.queryRecords()  
597 - },  
598 - playRecord: function (row) {  
599 - let that = this;  
600 -  
601 - let startTime = row.startTime  
602 - this.recordStartTime = row.startTime  
603 - this.showTimeText = row.startTime.split(" ")[1]  
604 - let endtime = row.endTime  
605 - this.sliderTime = 0;  
606 - this.seekTime = new Date(endtime).getTime() - new Date(startTime).getTime();  
607 - console.log(this.seekTime)  
608 - if (that.streamId != "") {  
609 - that.stopPlayRecord(function () {  
610 - that.streamId = "";  
611 - that.playRecord(row);  
612 - })  
613 - } else {  
614 - this.$axios({  
615 - method: 'get',  
616 - url: '/api/playback/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' +  
617 - row.endTime  
618 - }).then(function (res) {  
619 - if (res.data.code === 0) {  
620 - that.streamInfo = res.data.data;  
621 - that.app = that.streamInfo.app;  
622 - that.streamId = that.streamInfo.stream;  
623 - that.mediaServerId = that.streamInfo.mediaServerId;  
624 - that.ssrc = that.streamInfo.ssrc;  
625 - that.videoUrl = that.getUrlByStreamInfo();  
626 - }else {  
627 - that.$message({  
628 - showClose: true,  
629 - message: res.data.msg,  
630 - type: "error",  
631 - });  
632 - }  
633 - that.recordPlay = true;  
634 - });  
635 - }  
636 - },  
637 - stopPlayRecord: function (callback) {  
638 - this.$refs[this.activePlayer].pause();  
639 - this.videoUrl = '';  
640 - this.$axios({  
641 - method: 'get',  
642 - url: '/api/playback/stop/' + this.deviceId + "/" + this.channelId + "/" + this.streamId  
643 - }).then(function (res) {  
644 - if (callback) callback()  
645 - });  
646 - },  
647 - downloadRecord: function (row) {  
648 - let that = this;  
649 - if (that.streamId != "") {  
650 - that.stopDownloadRecord(function (res) {  
651 - if (res.code == 0) {  
652 - that.streamId = "";  
653 - that.downloadRecord(row);  
654 - }else {  
655 - this.$message({  
656 - showClose: true,  
657 - message: res.data.msg,  
658 - type: "error",  
659 - });  
660 - }  
661 -  
662 - })  
663 - } else {  
664 - this.$axios({  
665 - method: 'get',  
666 - url: '/api/gb_record/download/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' +  
667 - row.endTime + '&downloadSpeed=4'  
668 - }).then(function (res) {  
669 - if (res.data.code == 0) {  
670 - let streamInfo = res.data.data;  
671 - that.recordPlay = false;  
672 - that.$refs.recordDownload.openDialog(that.deviceId, that.channelId, streamInfo.app, streamInfo.stream, streamInfo.mediaServerId);  
673 - }else {  
674 - that.$message({  
675 - showClose: true,  
676 - message: res.data.msg,  
677 - type: "error",  
678 - });  
679 - }  
680 - });  
681 - }  
682 - },  
683 - stopDownloadRecord: function (callback) {  
684 - this.$refs[this.activePlayer].pause();  
685 - this.videoUrl = '';  
686 - this.$axios({  
687 - method: 'get',  
688 - url: '/api/gb_record/download/stop/' + this.deviceId + "/" + this.channelId+ "/" + this.streamId  
689 - }).then((res)=> {  
690 - if (callback) callback(res)  
691 - });  
692 - },  
693 ptzCamera: function (command) { 492 ptzCamera: function (command) {
694 console.log('云台控制:' + command); 493 console.log('云台控制:' + command);
695 let that = this; 494 let that = this;
@@ -728,52 +527,6 @@ export default { @@ -728,52 +527,6 @@ export default {
728 url: '/api/ptz/front_end_command/' + this.deviceId + '/' + this.channelId + '?cmdCode=' + cmdCode + '&parameter1=' + groupNum + '&parameter2=' + parameter + '&combindCode2=0' 527 url: '/api/ptz/front_end_command/' + this.deviceId + '/' + this.channelId + '?cmdCode=' + cmdCode + '&parameter1=' + groupNum + '&parameter2=' + parameter + '&combindCode2=0'
729 }).then(function (res) {}); 528 }).then(function (res) {});
730 }, 529 },
731 - formatTooltip: function (val) {  
732 - var h = parseInt(val / 60);  
733 - var hStr = h < 10 ? ("0" + h) : h;  
734 - var s = val % 60;  
735 - var sStr = s < 10 ? ("0" + s) : s;  
736 - return h + ":" + sStr;  
737 - },  
738 - timeFormatter: function (row, column, cellValue, index) {  
739 - return cellValue.split(" ")[1];  
740 - },  
741 - mergeTime: function (timeArray) {  
742 - var resultArray = [];  
743 - for (let i = 0; i < timeArray.length; i++) {  
744 - var startTime = new Date(timeArray[i].startTime);  
745 - var endTime = new Date(timeArray[i].endTime);  
746 - if (i == 0) {  
747 - resultArray[0] = {  
748 - startTime: startTime,  
749 - endTime: endTime  
750 - }  
751 - }  
752 - for (let j = 0; j < resultArray.length; j++) {  
753 - if (startTime > resultArray[j].endTime) { // 合并  
754 - if (startTime - resultArray[j].endTime <= 1000) {  
755 - resultArray[j].endTime = endTime;  
756 - } else {  
757 - resultArray[resultArray.length] = {  
758 - startTime: startTime,  
759 - endTime: endTime  
760 - }  
761 - }  
762 - } else if (resultArray[j].startTime > endTime) { // 合并  
763 - if (resultArray[j].startTime - endTime <= 1000) {  
764 - resultArray[j].startTime = startTime;  
765 - } else {  
766 - resultArray[resultArray.length] = {  
767 - startTime: startTime,  
768 - endTime: endTime  
769 - }  
770 - }  
771 - }  
772 - }  
773 - }  
774 - console.log(resultArray)  
775 - return resultArray;  
776 - },  
777 copyUrl: function (dropdownItem){ 530 copyUrl: function (dropdownItem){
778 console.log(dropdownItem) 531 console.log(dropdownItem)
779 this.$copyText(dropdownItem).then((e)=> { 532 this.$copyText(dropdownItem).then((e)=> {
@@ -782,47 +535,7 @@ export default { @@ -782,47 +535,7 @@ export default {
782 535
783 }) 536 })
784 }, 537 },
785 - gbPlay(){  
786 - console.log('前端控制:播放');  
787 - this.$axios({  
788 - method: 'get',  
789 - url: '/api/playback/resume/' + this.streamId  
790 - }).then((res)=> {  
791 - this.$refs[this.activePlayer].play(this.videoUrl)  
792 - });  
793 - },  
794 - gbPause(){  
795 - console.log('前端控制:暂停');  
796 - this.$axios({  
797 - method: 'get',  
798 - url: '/api/playback/pause/' + this.streamId  
799 - }).then(function (res) {});  
800 - },  
801 - gbScale(command){  
802 - console.log('前端控制:倍速 ' + command);  
803 - this.$axios({  
804 - method: 'get',  
805 - url: `/api/playback/speed/${this.streamId }/${command}`  
806 - }).then(function (res) {});  
807 - },  
808 - gbSeek(val){  
809 - console.log('前端控制:seek ');  
810 - console.log(this.seekTime);  
811 - console.log(this.sliderTime);  
812 - let showTime = new Date(new Date(this.recordStartTime).getTime() + this.seekTime * val / 100)  
813 - let hour = showTime.getHours();  
814 - let minutes = showTime.getMinutes();  
815 - let seconds = showTime.getSeconds();  
816 - this.showTimeText = (hour < 10?("0" + hour):hour) + ":" + (minutes<10?("0" + minutes):minutes) + ":" + (seconds<10?("0" + seconds):seconds)  
817 - this.$axios({  
818 - method: 'get',  
819 - url: `/api/playback/seek/${this.streamId }/` + Math.floor(this.seekTime * val / 100000)  
820 - }).then( (res)=> {  
821 - setTimeout(()=>{  
822 - this.$refs[this.activePlayer].play(this.videoUrl)  
823 - }, 600)  
824 - });  
825 - }, 538 +
826 539
827 540
828 } 541 }
web_src/src/router/index.js
@@ -5,6 +5,7 @@ import Layout from &quot;../layout/index.vue&quot; @@ -5,6 +5,7 @@ import Layout from &quot;../layout/index.vue&quot;
5 import console from '../components/console.vue' 5 import console from '../components/console.vue'
6 import deviceList from '../components/DeviceList.vue' 6 import deviceList from '../components/DeviceList.vue'
7 import channelList from '../components/channelList.vue' 7 import channelList from '../components/channelList.vue'
  8 +import gbRecordDetail from '../components/GBRecordDetail.vue'
8 import pushVideoList from '../components/PushVideoList.vue' 9 import pushVideoList from '../components/PushVideoList.vue'
9 import streamProxyList from '../components/StreamProxyList.vue' 10 import streamProxyList from '../components/StreamProxyList.vue'
10 import map from '../components/map.vue' 11 import map from '../components/map.vue'
@@ -65,6 +66,11 @@ export default new VueRouter({ @@ -65,6 +66,11 @@ export default new VueRouter({
65 component: channelList, 66 component: channelList,
66 }, 67 },
67 { 68 {
  69 + path: '/gbRecordDetail/:deviceId/:channelId/',
  70 + name: 'gbRecordDetail',
  71 + component: gbRecordDetail,
  72 + },
  73 + {
68 path: '/parentPlatformList/:count/:page', 74 path: '/parentPlatformList/:count/:page',
69 name: 'parentPlatformList', 75 name: 'parentPlatformList',
70 component: parentPlatformList, 76 component: parentPlatformList,
web_src/static/css/iconfont.css
1 @font-face { 1 @font-face {
2 font-family: "iconfont"; /* Project id 1291092 */ 2 font-family: "iconfont"; /* Project id 1291092 */
3 - src: url('iconfont.woff2?t=1655453611360') format('woff2'),  
4 - url('iconfont.woff?t=1655453611360') format('woff'),  
5 - url('iconfont.ttf?t=1655453611360') format('truetype'); 3 + src: url('iconfont.woff2?t=1673251105600') format('woff2'),
  4 + url('iconfont.woff?t=1673251105600') format('woff'),
  5 + url('iconfont.ttf?t=1673251105600') format('truetype');
6 } 6 }
7 7
8 .iconfont { 8 .iconfont {
@@ -13,6 +13,14 @@ @@ -13,6 +13,14 @@
13 -moz-osx-font-smoothing: grayscale; 13 -moz-osx-font-smoothing: grayscale;
14 } 14 }
15 15
  16 +.icon-slider:before {
  17 + content: "\e7e0";
  18 +}
  19 +
  20 +.icon-slider-right:before {
  21 + content: "\ea19";
  22 +}
  23 +
16 .icon-list:before { 24 .icon-list:before {
17 content: "\e7de"; 25 content: "\e7de";
18 } 26 }
web_src/static/css/iconfont.woff2
No preview for this file type