Commit 908145ceed661028410ad68caa6ddd07cf22b2fc

Authored by Lawrence
1 parent 50c19f47

突出返回按钮

web_src/src/components/channelList.vue
1 1 <template>
2   - <div id="channelList">
3   - <el-container>
  2 +<div id="channelList">
  3 + <el-container>
4 4  
5   - <el-header>
6   - <uiHeader></uiHeader>
7   - </el-header>
8   - <el-main>
9   - <div style="background-color: #FFFFFF; position: relative; padding: 1rem 0.5rem 0.5rem 0.5rem; text-align: center;">
10   - <span style="font-size: 1rem; font-weight: 500; ">通道列表({{parentChannelId ==0 ? deviceId:parentChannelId}})</span>
  5 + <el-header>
  6 + <uiHeader></uiHeader>
  7 + </el-header>
  8 + <el-main>
  9 + <div style="background-color: #FFFFFF; position: relative; padding: 1rem 0.5rem 0.5rem 0.5rem; text-align: center;">
  10 + <span style="font-size: 1rem; font-weight: 500; ">通道列表({{parentChannelId ==0 ? deviceId:parentChannelId}})</span>
11 11  
12   - </div>
13   - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;">
14   - <el-button icon="el-icon-arrow-left" size="mini" style="margin-right: 1rem;" @click="showDevice">返回</el-button>
15   - 搜索: <el-input @input="search" style="margin-right: 1rem; width: auto;" size="mini" placeholder="关键字" prefix-icon="el-icon-search" v-model="searchSrt" clearable> </el-input>
  12 + </div>
  13 + <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;">
  14 + <el-button icon="el-icon-arrow-left" size="mini" style="margin-right: 1rem;" type="primary" @click="showDevice">返回</el-button>
  15 + 搜索: <el-input @input="search" style="margin-right: 1rem; width: auto;" size="mini" placeholder="关键字" prefix-icon="el-icon-search" v-model="searchSrt" clearable> </el-input>
16 16  
17   - 通道类型: <el-select size="mini" @change="search" style="margin-right: 1rem;" v-model="channelType" placeholder="请选择" default-first-option>
18   - <el-option label="全部" value="" ></el-option>
19   - <el-option label="设备" value="false"></el-option>
20   - <el-option label="子目录" value="true" ></el-option>
21   - </el-select>
22   - 在线状态: <el-select size="mini" @change="search" v-model="online" placeholder="请选择" default-first-option>
23   - <el-option label="全部" value=""></el-option>
24   - <el-option label="在线" value="on"></el-option>
25   - <el-option label="离线" value="off"></el-option>
26   - </el-select>
  17 + 通道类型: <el-select size="mini" @change="search" style="margin-right: 1rem;" v-model="channelType" placeholder="请选择" default-first-option>
  18 + <el-option label="全部" value=""></el-option>
  19 + <el-option label="设备" value="false"></el-option>
  20 + <el-option label="子目录" value="true"></el-option>
  21 + </el-select>
  22 + 在线状态: <el-select size="mini" @change="search" v-model="online" placeholder="请选择" default-first-option>
  23 + <el-option label="全部" value=""></el-option>
  24 + <el-option label="在线" value="on"></el-option>
  25 + <el-option label="离线" value="off"></el-option>
  26 + </el-select>
27 27  
28   - </div>
29   - <devicePlayer ref="devicePlayer"></devicePlayer>
30   - <!--设备列表-->
31   - <el-table ref="channelListTable" :data="deviceChannelList" :height="winHeight" border style="width: 100%">
32   - <el-table-column prop="channelId" label="通道编号" width="210">
33   - </el-table-column>
34   - <el-table-column prop="name" label="通道名称">
35   - </el-table-column>
36   - <el-table-column prop="subCount" label="子节点数">
37   - </el-table-column>
38   - <el-table-column label="开启音频" align="center">
39   - <template slot-scope="scope">
40   - <el-switch
41   - @change="updateChannel(scope.row)"
42   - v-model="scope.row.hasAudio"
43   - active-color="#409EFF">
44   - </el-switch>
45   - </template>
46   - </el-table-column>
47   - <el-table-column label="状态" width="180" align="center">
48   - <template slot-scope="scope">
49   - <div slot="reference" class="name-wrapper">
50   - <el-tag size="medium" v-if="scope.row.status == 1">在线</el-tag>
51   - <el-tag size="medium" type="info" v-if="scope.row.status == 0">离线</el-tag>
52   - </div>
53   - </template>
54   - </el-table-column>
55   - <el-table-column prop="ptztypeText" label="云台类型">
56   - </el-table-column>
57   - <el-table-column label="操作" width="280" align="center" fixed="right">
58   - <template slot-scope="scope">
59   - <el-button-group>
60   - <el-button size="mini" icon="el-icon-video-play" v-if="scope.row.parental == 0" @click="sendDevicePush(scope.row)">播放</el-button>
61   - <el-button size="mini" icon="el-icon-switch-button" type="danger" v-if="scope.row.play" @click="stopDevicePush(scope.row)">停止</el-button>
62   - <el-button size="mini" icon="el-icon-s-open" type="primary" v-if="scope.row.parental == 1" @click="changeSubchannel(scope.row)">查看</el-button>
63   -<!-- <el-button size="mini" icon="el-icon-video-camera" type="primary" >设备录象</el-button>-->
64   - <!-- <el-button size="mini" @click="sendDevicePush(scope.row)">录像查询</el-button> -->
65   - </el-button-group>
66   - </template>
67   - </el-table-column>
68   - </el-table>
69   - <el-pagination
70   - style="float: right"
71   - @size-change="handleSizeChange"
72   - @current-change="currentChange"
73   - :current-page="currentPage"
74   - :page-size="count"
75   - :page-sizes="[15, 20, 30, 50]"
76   - layout="total, sizes, prev, pager, next"
77   - :total="total">
78   - </el-pagination>
  28 + </div>
  29 + <devicePlayer ref="devicePlayer"></devicePlayer>
  30 + <!--设备列表-->
  31 + <el-table ref="channelListTable" :data="deviceChannelList" :height="winHeight" border style="width: 100%">
  32 + <el-table-column prop="channelId" label="通道编号" width="210">
  33 + </el-table-column>
  34 + <el-table-column prop="name" label="通道名称">
  35 + </el-table-column>
  36 + <el-table-column prop="subCount" label="子节点数">
  37 + </el-table-column>
  38 + <el-table-column label="开启音频" align="center">
  39 + <template slot-scope="scope">
  40 + <el-switch @change="updateChannel(scope.row)" v-model="scope.row.hasAudio" active-color="#409EFF">
  41 + </el-switch>
  42 + </template>
  43 + </el-table-column>
  44 + <el-table-column label="状态" width="180" align="center">
  45 + <template slot-scope="scope">
  46 + <div slot="reference" class="name-wrapper">
  47 + <el-tag size="medium" v-if="scope.row.status == 1">在线</el-tag>
  48 + <el-tag size="medium" type="info" v-if="scope.row.status == 0">离线</el-tag>
  49 + </div>
  50 + </template>
  51 + </el-table-column>
  52 + <el-table-column prop="ptztypeText" label="云台类型">
  53 + </el-table-column>
  54 + <el-table-column label="操作" width="280" align="center" fixed="right">
  55 + <template slot-scope="scope">
  56 + <el-button-group>
  57 + <el-button size="mini" icon="el-icon-video-play" v-if="scope.row.parental == 0" @click="sendDevicePush(scope.row)">播放</el-button>
  58 + <el-button size="mini" icon="el-icon-switch-button" type="danger" v-if="scope.row.play" @click="stopDevicePush(scope.row)">停止</el-button>
  59 + <el-button size="mini" icon="el-icon-s-open" type="primary" v-if="scope.row.parental == 1" @click="changeSubchannel(scope.row)">查看</el-button>
  60 + <!-- <el-button size="mini" icon="el-icon-video-camera" type="primary" >设备录象</el-button>-->
  61 + <!-- <el-button size="mini" @click="sendDevicePush(scope.row)">录像查询</el-button> -->
  62 + </el-button-group>
  63 + </template>
  64 + </el-table-column>
  65 + </el-table>
  66 + <el-pagination style="float: right" @size-change="handleSizeChange" @current-change="currentChange" :current-page="currentPage" :page-size="count" :page-sizes="[15, 20, 30, 50]" layout="total, sizes, prev, pager, next" :total="total">
  67 + </el-pagination>
79 68  
80   - </el-main>
81   - </el-container>
  69 + </el-main>
  70 + </el-container>
82 71 <Loading v-if="isLoging" marginTop="-50%"></Loading>
83   - </div>
  72 +</div>
84 73 </template>
85 74  
86 75 <script>
87   - import devicePlayer from './gb28181/devicePlayer.vue'
88   - import uiHeader from './UiHeader.vue'
89   - import Loading from './Loading.vue'
90   - export default {
91   - name: 'channelList',
92   - components: {
93   - devicePlayer,
94   - uiHeader,
95   - Loading
96   - },
97   - data() {
98   - return {
99   - deviceId: this.$route.params.deviceId,
100   - parentChannelId: this.$route.params.parentChannelId,
101   - deviceChannelList: [],
102   - videoComponentList: [],
103   - currentPlayerInfo: {}, //当前播放对象
104   - updateLooper: 0, //数据刷新轮训标志
105   - searchSrt: "",
106   - channelType: "",
107   - online: "",
108   - winHeight: window.innerHeight - 250,
109   - currentPage: parseInt(this.$route.params.page),
110   - count: parseInt(this.$route.params.count),
111   - total:0,
112   - beforeUrl:"/videoList",
113   - isLoging: false
114   - };
115   - },
  76 +import devicePlayer from './gb28181/devicePlayer.vue'
  77 +import uiHeader from './UiHeader.vue'
  78 +import Loading from './Loading.vue'
  79 +export default {
  80 + name: 'channelList',
  81 + components: {
  82 + devicePlayer,
  83 + uiHeader,
  84 + Loading
  85 + },
  86 + data() {
  87 + return {
  88 + deviceId: this.$route.params.deviceId,
  89 + parentChannelId: this.$route.params.parentChannelId,
  90 + deviceChannelList: [],
  91 + videoComponentList: [],
  92 + currentPlayerInfo: {}, //当前播放对象
  93 + updateLooper: 0, //数据刷新轮训标志
  94 + searchSrt: "",
  95 + channelType: "",
  96 + online: "",
  97 + winHeight: window.innerHeight - 250,
  98 + currentPage: parseInt(this.$route.params.page),
  99 + count: parseInt(this.$route.params.count),
  100 + total: 0,
  101 + beforeUrl: "/videoList",
  102 + isLoging: false
  103 + };
  104 + },
116 105  
117   - mounted() {
118   - this.initData();
119   - // this.updateLooper = setInterval(this.initData, 10000);
120   - },
121   - destroyed() {
122   - this.$destroy('videojs');
123   - clearTimeout(this.updateLooper);
124   - },
125   - methods: {
126   - initData: function() {
127   - if (this.parentChannelId == "" || this.parentChannelId == 0 ) {
128   - this.getDeviceChannelList();
129   - }else{
130   - this.showSubchannels();
131   - }
  106 + mounted() {
  107 + this.initData();
  108 + // this.updateLooper = setInterval(this.initData, 10000);
  109 + },
  110 + destroyed() {
  111 + this.$destroy('videojs');
  112 + clearTimeout(this.updateLooper);
  113 + },
  114 + methods: {
  115 + initData: function () {
  116 + if (this.parentChannelId == "" || this.parentChannelId == 0) {
  117 + this.getDeviceChannelList();
  118 + } else {
  119 + this.showSubchannels();
  120 + }
132 121  
133   - },
134   - initParam: function(){
135   - this.deviceId= this.$route.params.deviceId;
136   - this.parentChannelId= this.$route.params.parentChannelId;
137   - this.currentPage= parseInt(this.$route.params.page);
138   - this.count= parseInt(this.$route.params.count);
139   - if (this.parentChannelId == "" || this.parentChannelId == 0 ) {
140   - this.beforeUrl = "/videoList"
141   - }
  122 + },
  123 + initParam: function () {
  124 + this.deviceId = this.$route.params.deviceId;
  125 + this.parentChannelId = this.$route.params.parentChannelId;
  126 + this.currentPage = parseInt(this.$route.params.page);
  127 + this.count = parseInt(this.$route.params.count);
  128 + if (this.parentChannelId == "" || this.parentChannelId == 0) {
  129 + this.beforeUrl = "/videoList"
  130 + }
142 131  
143   - },
144   - currentChange: function(val){
145   - var url = `/${this.$router.currentRoute.name}/${this.deviceId}/${this.parentChannelId}/${this.count}/${val}`
146   - console.log(url)
147   - this.$router.push(url).then(()=>{
148   - this.initParam();
149   - this.initData();
150   - })
151   - },
152   - handleSizeChange: function(val){
153   - var url = `/${this.$router.currentRoute.name}/${this.$router.params.deviceId}/${this.$router.params.parentChannelId}/${val}/1`
154   - this.$router.push(url).then(()=>{
155   - this.initParam();
156   - this.initData();
157   - })
  132 + },
  133 + currentChange: function (val) {
  134 + var url = `/${this.$router.currentRoute.name}/${this.deviceId}/${this.parentChannelId}/${this.count}/${val}`
  135 + console.log(url)
  136 + this.$router.push(url).then(() => {
  137 + this.initParam();
  138 + this.initData();
  139 + })
  140 + },
  141 + handleSizeChange: function (val) {
  142 + var url = `/${this.$router.currentRoute.name}/${this.$router.params.deviceId}/${this.$router.params.parentChannelId}/${val}/1`
  143 + this.$router.push(url).then(() => {
  144 + this.initParam();
  145 + this.initData();
  146 + })
158 147  
159   - },
160   - getDeviceChannelList: function() {
161   - let that = this;
162   - console.log(this.currentPage - 1)
  148 + },
  149 + getDeviceChannelList: function () {
  150 + let that = this;
  151 + console.log(this.currentPage - 1)
163 152  
164   - this.$axios.get(`/api/devices/${this.$route.params.deviceId}/channels`,{
165   - params: {
166   - page: that.currentPage - 1,
167   - count: that.count,
168   - query: that.searchSrt,
169   - online: that.online,
170   - channelType: that.channelType
171   - }
172   - } )
173   - .then(function (res) {
174   - console.log(res);
175   - that.total = res.data.total;
176   - that.deviceChannelList = res.data.data;
177   - // 防止出现表格错位
178   - that.$nextTick(()=>{
179   - that.$refs.channelListTable.doLayout();
180   - })
181   - })
182   - .catch(function (error) {
183   - console.log(error);
184   - });
  153 + this.$axios.get(`/api/devices/${this.$route.params.deviceId}/channels`, {
  154 + params: {
  155 + page: that.currentPage - 1,
  156 + count: that.count,
  157 + query: that.searchSrt,
  158 + online: that.online,
  159 + channelType: that.channelType
  160 + }
  161 + })
  162 + .then(function (res) {
  163 + console.log(res);
  164 + that.total = res.data.total;
  165 + that.deviceChannelList = res.data.data;
  166 + // 防止出现表格错位
  167 + that.$nextTick(() => {
  168 + that.$refs.channelListTable.doLayout();
  169 + })
  170 + })
  171 + .catch(function (error) {
  172 + console.log(error);
  173 + });
185 174  
186   - },
  175 + },
187 176  
  177 + //gb28181平台对接
  178 + //刷新设备信息
  179 + refDevice: function (itemData) {
  180 + ///api/devices/{deviceId}/sync
  181 + console.log("刷新对应设备:" + itemData.deviceId);
  182 + this.$axios({
  183 + method: 'post',
  184 + url: '/api/devices/' + itemData.deviceId + '/sync'
  185 + }).then(function (res) {
  186 + // console.log("刷新设备结果:"+JSON.stringify(res));
  187 + }).catch(function (e) {
  188 + that.$message({
  189 + showClose: true,
  190 + message: '请求成功',
  191 + type: 'success'
  192 + });
  193 + });
  194 + },
  195 + //通知设备上传媒体流
  196 + sendDevicePush: function (itemData) {
  197 + console.log(itemData)
  198 + let deviceId = this.deviceId;
  199 + this.isLoging = true;
  200 + let channelId = itemData.channelId;
  201 + console.log("通知设备推流1:" + deviceId + " : " + channelId);
  202 + let that = this;
  203 + this.$axios({
  204 + method: 'get',
  205 + url: '/api/play/' + deviceId + '/' + channelId
  206 + }).then(function (res) {
  207 + console.log(res.data)
  208 + let ssrc = res.data.ssrc;
  209 + that.isLoging = false;
  210 + if (!!ssrc) {
  211 + that.$refs.devicePlayer.play(res.data, deviceId, channelId, itemData.hasAudio);
  212 + that.initData();
  213 + } else {
  214 + that.$message.error(res.data);
  215 + }
  216 + }).catch(function (e) {});
  217 + },
  218 + stopDevicePush: function (itemData) {
  219 + console.log(itemData)
  220 + var that = this;
  221 + this.$axios({
  222 + method: 'post',
  223 + url: '/api/play/' + itemData.ssrc + '/stop'
  224 + }).then(function (res) {
  225 + console.log(JSON.stringify(res));
  226 + that.initData();
  227 + });
  228 + },
188 229  
189   - //gb28181平台对接
190   - //刷新设备信息
191   - refDevice: function(itemData) {
192   - ///api/devices/{deviceId}/sync
193   - console.log("刷新对应设备:" + itemData.deviceId);
194   - this.$axios({
195   - method: 'post',
196   - url: '/api/devices/' + itemData.deviceId + '/sync'
197   - }).then(function(res) {
198   - // console.log("刷新设备结果:"+JSON.stringify(res));
199   - }).catch(function(e) {
200   - that.$message({
201   - showClose: true,
202   - message: '请求成功',
203   - type: 'success'
204   - });
205   - });
206   - },
207   - //通知设备上传媒体流
208   - sendDevicePush: function(itemData) {
209   - console.log(itemData)
210   - let deviceId = this.deviceId;
211   - this.isLoging = true;
212   - let channelId = itemData.channelId;
213   - console.log("通知设备推流1:" + deviceId + " : " + channelId);
214   - let that = this;
215   - this.$axios({
216   - method: 'get',
217   - url: '/api/play/' + deviceId + '/' + channelId
218   - }).then(function(res) {
219   - console.log(res.data)
220   - let ssrc = res.data.ssrc;
221   - that.isLoging = false
222   - if (!!ssrc) {
223   - that.$refs.devicePlayer.play(res.data,deviceId,channelId,itemData.hasAudio);
224   - that.initData();
225   - }else {
226   - that.$message.error(res.data);
227   - }
228   - }).catch(function(e) {
229   - });
230   - },
231   - stopDevicePush: function(itemData) {
232   - console.log(itemData)
233   - var that = this;
234   - this.$axios({
235   - method: 'post',
236   - url: '/api/play/' + itemData.ssrc + '/stop'
237   - }).then(function(res) {
238   - console.log(JSON.stringify(res));
239   - that.initData();
240   - });
241   - },
  230 + showDevice: function () {
  231 + this.$router.push(this.beforeUrl).then(() => {
  232 + this.initParam();
  233 + this.initData();
  234 + })
  235 + },
  236 + changeSubchannel(itemData) {
  237 + console.log(this.$router.currentRoute)
  238 + this.beforeUrl = this.$router.currentRoute.path;
242 239  
243   - showDevice: function(){
244   - this.$router.push(this.beforeUrl).then(()=>{
245   - this.initParam();
246   - this.initData();
247   - })
248   - },
249   - changeSubchannel(itemData) {
250   - console.log(this.$router.currentRoute)
251   - this.beforeUrl = this.$router.currentRoute.path;
  240 + var url = `/${this.$router.currentRoute.name}/${this.$router.currentRoute.params.deviceId}/${itemData.channelId}/${this.$router.currentRoute.params.count}/1`
  241 + this.$router.push(url).then(() => {
  242 + this.searchSrt = "";
  243 + this.channelType = "";
  244 + this.online = "";
  245 + this.initParam();
  246 + this.initData();
  247 + })
  248 + },
  249 + showSubchannels: function (channelId) {
  250 + let that = this;
252 251  
253   - var url = `/${this.$router.currentRoute.name}/${this.$router.currentRoute.params.deviceId}/${itemData.channelId}/${this.$router.currentRoute.params.count}/1`
254   - this.$router.push(url).then(()=>{
255   - this.searchSrt= "";
256   - this.channelType= "";
257   - this.online= "";
258   - this.initParam();
259   - this.initData();
260   - })
261   - },
262   - showSubchannels: function(channelId){
263   - let that = this;
  252 + this.$axios.get(`/api/subChannels/${this.deviceId}/${this.parentChannelId}/channels`, {
  253 + params: {
  254 + page: that.currentPage - 1,
  255 + count: that.count,
  256 + query: that.searchSrt,
  257 + online: that.online,
  258 + channelType: that.channelType
  259 + }
  260 + })
  261 + .then(function (res) {
  262 + that.total = res.data.total;
  263 + that.deviceChannelList = res.data.data;
  264 + // 防止出现表格错位
  265 + that.$nextTick(() => {
  266 + that.$refs.channelListTable.doLayout();
  267 + })
  268 + })
  269 + .catch(function (error) {
  270 + console.log(error);
  271 + });
  272 + },
  273 + search: function () {
  274 + console.log(this.searchSrt)
  275 + this.currentPage = 1;
  276 + this.total = 0;
  277 + this.initData();
  278 + },
  279 + updateChannel: function (row) {
  280 + console.log(row)
  281 + this.$axios({
  282 + method: 'post',
  283 + url: `/api/channel/update/${this.deviceId}`,
  284 + params: row
  285 + }).then(function (res) {
  286 + console.log(JSON.stringify(res));
  287 + });
  288 + }
264 289  
265   - this.$axios.get(`/api/subChannels/${this.deviceId}/${this.parentChannelId}/channels`,{
266   - params: {
267   - page: that.currentPage - 1,
268   - count: that.count,
269   - query: that.searchSrt,
270   - online: that.online,
271   - channelType: that.channelType
272   - }
273   - } )
274   - .then(function (res) {
275   - that.total = res.data.total;
276   - that.deviceChannelList = res.data.data;
277   - // 防止出现表格错位
278   - that.$nextTick(()=>{
279   - that.$refs.channelListTable.doLayout();
280   - })
281   - })
282   - .catch(function (error) {
283   - console.log(error);
284   - });
285   - },
286   - search: function() {
287   - console.log(this.searchSrt)
288   - this.currentPage = 1;
289   - this.total = 0;
290   - this.initData();
291   - },
292   - updateChannel: function(row) {
293   - console.log(row)
294   - this.$axios({
295   - method: 'post',
296   - url: `/api/channel/update/${this.deviceId}`,
297   - params: row
298   - }).then(function(res) {
299   - console.log(JSON.stringify(res));
300   - });
301   - }
302   -
303   - }
304   - };
  290 + }
  291 +};
305 292 </script>
306 293  
307 294 <style>
308   - .videoList {
309   - display: flex;
310   - flex-wrap: wrap;
311   - align-content: flex-start;
312   - }
  295 +.videoList {
  296 + display: flex;
  297 + flex-wrap: wrap;
  298 + align-content: flex-start;
  299 +}
313 300  
314   - .video-item {
315   - position: relative;
316   - width: 15rem;
317   - height: 10rem;
318   - margin-right: 1rem;
319   - background-color: #000000;
320   - }
  301 +.video-item {
  302 + position: relative;
  303 + width: 15rem;
  304 + height: 10rem;
  305 + margin-right: 1rem;
  306 + background-color: #000000;
  307 +}
321 308  
322   - .video-item-img {
323   - position: absolute;
324   - top: 0;
325   - bottom: 0;
326   - left: 0;
327   - right: 0;
328   - margin: auto;
329   - width: 100%;
330   - height: 100%;
331   - }
  309 +.video-item-img {
  310 + position: absolute;
  311 + top: 0;
  312 + bottom: 0;
  313 + left: 0;
  314 + right: 0;
  315 + margin: auto;
  316 + width: 100%;
  317 + height: 100%;
  318 +}
332 319  
333   - .video-item-img:after {
334   - content: "";
335   - display: inline-block;
336   - position: absolute;
337   - z-index: 2;
338   - top: 0;
339   - bottom: 0;
340   - left: 0;
341   - right: 0;
342   - margin: auto;
343   - width: 3rem;
344   - height: 3rem;
345   - background-image: url("../assets/loading.png");
346   - background-size: cover;
347   - background-color: #000000;
348   - }
  320 +.video-item-img:after {
  321 + content: "";
  322 + display: inline-block;
  323 + position: absolute;
  324 + z-index: 2;
  325 + top: 0;
  326 + bottom: 0;
  327 + left: 0;
  328 + right: 0;
  329 + margin: auto;
  330 + width: 3rem;
  331 + height: 3rem;
  332 + background-image: url("../assets/loading.png");
  333 + background-size: cover;
  334 + background-color: #000000;
  335 +}
349 336  
350   - .video-item-title {
351   - position: absolute;
352   - bottom: 0;
353   - color: #000000;
354   - background-color: #ffffff;
355   - line-height: 1.5rem;
356   - padding: 0.3rem;
357   - width: 14.4rem;
358   - }
  337 +.video-item-title {
  338 + position: absolute;
  339 + bottom: 0;
  340 + color: #000000;
  341 + background-color: #ffffff;
  342 + line-height: 1.5rem;
  343 + padding: 0.3rem;
  344 + width: 14.4rem;
  345 +}
359 346 </style>
... ...