Merge remote-tracking branch 'origin/重构/1078' into 重构/1078
This commit is contained in:
@@ -2,266 +2,51 @@
|
||||
<div id="channelList" style="width: 100%">
|
||||
<div class="page-header">
|
||||
<div class="page-title">
|
||||
<el-button icon="el-icon-back" size="mini" style="font-size: 20px; color: #000;" type="text" @click="showDevice" ></el-button>
|
||||
<el-button icon="el-icon-back" size="mini" style="font-size: 20px; color: #000;" type="text" @click="close" ></el-button>
|
||||
<el-divider direction="vertical"></el-divider>
|
||||
通道编辑
|
||||
编辑推流信息
|
||||
</div>
|
||||
<div class="page-header-btn">
|
||||
<div style="display: inline;">
|
||||
<el-button icon="el-icon-close" circle size="mini" @click="showDevice()"></el-button>
|
||||
<el-button icon="el-icon-close" size="mini" style="font-size: 20px; color: #000;" type="text" @click="close" ></el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-container v-loading="isLoading" style="height: 82vh; overflow: auto">
|
||||
<el-main style="padding: 5px; background-color: #ffffff;">
|
||||
<el-divider content-position="center">部标通道参数</el-divider>
|
||||
<el-form ref="form" :rules="rules" :model="form" label-width="240px" style="display: grid; grid-template-columns: 1fr 1fr 1fr ">
|
||||
<el-tabs tab-position="left">
|
||||
<el-tab-pane label="推流信息编辑" style="background-color: #FFFFFF; padding: 1rem">
|
||||
<el-form ref="form" :rules="rules" :model="jtChannel" label-width="240px" style="display: grid; grid-template-columns: 1fr 1fr 1fr ">
|
||||
<el-form-item label="编号" prop="channelId">
|
||||
<el-input v-model="form.channelId" clearable></el-input>
|
||||
<el-input v-model="jtChannel.channelId" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input v-model="form.name" clearable></el-input>
|
||||
<el-input v-model="jtChannel.name" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-divider content-position="center">国标通道参数</el-divider>
|
||||
<el-form size="mini" ref="form" :rules="rules" :model="form" label-width="240px" style="display: grid; grid-template-columns: 1fr 1fr 1fr ">
|
||||
<el-form-item label="国标编码" prop="gbDeviceId">
|
||||
<el-input v-model="form.gbDeviceId" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="通道名称" prop="gbName">
|
||||
<el-input v-model="form.gbName" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="设备厂商" prop="gbManufacturer">
|
||||
<el-input v-model="form.gbManufacturer" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="设备型号" prop="gbModel">
|
||||
<el-input v-model="form.gbModel" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="行政区域" prop="gbCivilCode">
|
||||
<el-input v-model="form.gbCivilCode" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="警区" prop="gbBlock">
|
||||
<el-input v-model="form.gbBlock" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="安装地址" prop="gbAddress">
|
||||
<el-input v-model="form.gbAddress" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否有子设备" prop="gbParental">
|
||||
<el-checkbox v-model="form.gbParental" ></el-checkbox>
|
||||
</el-form-item>
|
||||
<el-form-item label="父节点ID" prop="gbParentId">
|
||||
<el-input v-model="form.gbParentId" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="注册方式" prop="gbRegisterWay">
|
||||
<el-input v-model="form.gbRegisterWay" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="摄像机安全能力等级代码" prop="gbSecurityLevelCode">
|
||||
<el-input v-model="form.gbSecurityLevelCode" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="保密属性" prop="gbSecrecy">
|
||||
<el-select v-model="form.gbSecrecy" style="float: left; width: 100%" >
|
||||
<el-option label="不涉密" :value="0"></el-option>
|
||||
<el-option label="涉密" :value="1"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="IP" prop="gbIpAddress">
|
||||
<el-input v-model="form.gbIpAddress" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="端口" prop="gbPort">
|
||||
<el-input v-model="form.gbPort" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="口令" prop="gbPort">
|
||||
<el-input v-model="form.gbPort" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="gbStatus">
|
||||
<el-switch
|
||||
v-model="form.gbStatus"
|
||||
active-text="在线"
|
||||
inactive-text="离线">
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="经度(WGS-84坐标系)" prop="gbLongitude">
|
||||
<el-input v-model="form.gbLongitude" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="纬度(WGS-84坐标系)" prop="gbLatitude">
|
||||
<el-input v-model="form.gbLatitude" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="虚拟组织所属的业务分组ID" prop="gbBusinessGroupId">
|
||||
<el-input v-model="form.gbBusinessGroupId" clearable></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="摄像机结构类型" prop="gbPtzType">
|
||||
<el-select v-model="form.gbPtzType" style="float: left; width: 100%" >
|
||||
<el-option label="球机" :value="1"></el-option>
|
||||
<el-option label="半球" :value="2"></el-option>
|
||||
<el-option label="固定枪机" :value="3"></el-option>
|
||||
<el-option label="遥控枪机" :value="4"></el-option>
|
||||
<el-option label="遥控半球" :value="5"></el-option>
|
||||
<el-option label="多目设备的全景/拼接通道" :value="6"></el-option>
|
||||
<el-option label="多目设备的分割通道" :value="7"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="摄像机光电成像类型" prop="gbPtzType">
|
||||
<el-select multiple v-model="form.gbPtzType" style="float: left; width: 100%" >
|
||||
<el-option label="可见光成像" :value="1"></el-option>
|
||||
<el-option label="热成像" :value="2"></el-option>
|
||||
<el-option label="雷达成像" :value="3"></el-option>
|
||||
<el-option label="X光成像" :value="4"></el-option>
|
||||
<el-option label="深度光场成像" :value="5"></el-option>
|
||||
<el-option label="其他" :value="6"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="摄像机采集部位类型" prop="gbCapturePositionType">
|
||||
<el-input v-model="form.gbCapturePositionType" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="室外/室内" prop="gbRoomType">
|
||||
<el-select multiple v-model="form.gbRoomType" style="float: left; width: 100%" >
|
||||
<el-option label="室外" :value="1"></el-option>
|
||||
<el-option label="室内" :value="2"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="摄像机补光属性" prop="gbSupplyLightType">
|
||||
<el-select multiple v-model="form.gbSupplyLightType" style="float: left; width: 100%" >
|
||||
<el-option label="无补光" :value="1"></el-option>
|
||||
<el-option label="红外补光" :value="2"></el-option>
|
||||
<el-option label="白光补光" :value="3"></el-option>
|
||||
<el-option label="激光补光" :value="4"></el-option>
|
||||
<el-option label="其他" :value="9"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="摄像机监视方位" prop="udpPortIcMaster">
|
||||
<el-select multiple v-model="form.gbRoomType" style="float: left; width: 100%" >
|
||||
<el-option label="东(西向东)" :value="1"></el-option>
|
||||
<el-option label="西(东向西)" :value="2"></el-option>
|
||||
<el-option label="南(北向南)" :value="3"></el-option>
|
||||
<el-option label="北(南向北)" :value="4"></el-option>
|
||||
<el-option label="东南(西北到东南)" :value="5"></el-option>
|
||||
<el-option label="东北(西南到东北)" :value="6"></el-option>
|
||||
<el-option label="西南(东北到西南)" :value="7"></el-option>
|
||||
<el-option label="西北(东南到西北)" :value="8"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="摄像机支持的分辨率" prop="gbResolution">
|
||||
<el-input v-model="form.gbResolution" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="摄像机支持的码流编号列表" prop="gbStreamNumberList">
|
||||
<el-input v-model="form.gbStreamNumberList" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="下载倍速" prop="gbDownloadSpeed">
|
||||
<el-input v-model="form.gbDownloadSpeed" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="空域编码能力" prop="gbSvcSpaceSupportMod">
|
||||
<el-select multiple v-model="form.gbSvcSpaceSupportMod" style="float: left; width: 100%" >
|
||||
<el-option label="不支持" :value="0"></el-option>
|
||||
<el-option label="1级增强(1个增强层)" :value="1"></el-option>
|
||||
<el-option label="2级增强(2个增强层)" :value="2"></el-option>
|
||||
<el-option label="3级增强(3个增强层)" :value="3"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="时域编码能力" prop="gbSvcTimeSupportMode">
|
||||
<el-select multiple v-model="form.gbSvcTimeSupportMode" style="float: left; width: 100%" >
|
||||
<el-option label="不支持" :value="0"></el-option>
|
||||
<el-option label="1级增强" :value="1"></el-option>
|
||||
<el-option label="2级增强" :value="2"></el-option>
|
||||
<el-option label="3级增强" :value="3"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="SSVC增强层与基本层比例能力" prop="gbSsvcRatioSupportList">
|
||||
<el-input v-model="form.gbSsvcRatioSupportList" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="移动采集设备类型" prop="gbMobileDeviceType">
|
||||
<el-select multiple v-model="form.gbMobileDeviceType" style="float: left; width: 100%" >
|
||||
<el-option label="移动机器人载摄像机" :value="1"></el-option>
|
||||
<el-option label="执法记录仪" :value="2"></el-option>
|
||||
<el-option label="移动单兵设备" :value="3"></el-option>
|
||||
<el-option label="车载视频记录设备" :value="4"></el-option>
|
||||
<el-option label="无人机载摄像机" :value="5"></el-option>
|
||||
<el-option label="其他" :value="9"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="摄像机水平视场角(0-360)" prop="gbHorizontalFieldAngle">
|
||||
<el-input v-model="form.gbHorizontalFieldAngle" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="摄像机竖直视场角(0-360)" prop="gbVerticalFieldAngle">
|
||||
<el-input v-model="form.gbVerticalFieldAngle" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="摄像机可视距离(米)" prop="gbMaxViewDistance">
|
||||
<el-input v-model="form.gbMaxViewDistance" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="基层组织编码" prop="gbGrassrootsCode">
|
||||
<el-input v-model="form.gbGrassrootsCode" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="监控点位类型" prop="gbPoType">
|
||||
<el-select v-model="form.gbPoType" style="float: left; width: 100%" >
|
||||
<el-option label="一类视频监控点" :value="1"></el-option>
|
||||
<el-option label="二类视频监控点" :value="2"></el-option>
|
||||
<el-option label="三类视频监控点" :value="3"></el-option>
|
||||
<el-option label="其他点位" :value="4"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="MAC地址(XX-XX-XX-XX-XX-XX)" prop="gbMac">
|
||||
<el-input v-model="form.gbMac" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="卡口功能类型" prop="gbFunctionType">
|
||||
<el-select v-model="form.gbFunctionType" style="float: left; width: 100%" >
|
||||
<el-option label="人脸卡口" value="01"></el-option>
|
||||
<el-option label="人员卡口" value="02"></el-option>
|
||||
<el-option label="机动车卡口" value="03"></el-option>
|
||||
<el-option label="非机动车卡口" value="04"></el-option>
|
||||
<el-option label="物品卡口" value="05"></el-option>
|
||||
<el-option label="其他" value="99"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="摄像机视频编码格式" prop="gbEncodeType">
|
||||
<el-input v-model="form.gbEncodeType" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="摄像机安装使用时间" prop="gbInstallTime">
|
||||
<el-input v-model="form.gbInstallTime" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="管理单位名称" prop="gbManagementUnit">
|
||||
<el-input v-model="form.gbManagementUnit" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="管理单位联系人联系方式" prop="gbContactInfo">
|
||||
<el-input v-model="form.gbContactInfo" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="录像保存天数" prop="gbRecordSaveDays">
|
||||
<el-input v-model="form.gbRecordSaveDays" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="国民经济行业分类代码" prop="gbIndustrialClassification">
|
||||
<el-input v-model="form.gbIndustrialClassification" clearable></el-input>
|
||||
<el-form style="text-align: right">
|
||||
<el-form-item >
|
||||
<el-button type="primary" @click="onSubmit">保存</el-button>
|
||||
<el-button @click="close">取消</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div style="float: right;">
|
||||
<el-button type="primary" @click="onSubmit" >确认</el-button>
|
||||
<el-button @click="showDevice">取消</el-button>
|
||||
</div>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="国标通道配置" v-if="jtChannel.id">
|
||||
<CommonChannelEdit ref="commonChannelEdit" :dataForm="jtChannel" :cancel="close"></CommonChannelEdit>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import devicePlayer from './dialog/jtDevicePlayer.vue'
|
||||
import uiHeader from '../layout/UiHeader.vue'
|
||||
import DeviceTree from "./common/DeviceTree";
|
||||
import channelEdit from "./dialog/jtChannelEdit.vue";
|
||||
import JTDeviceService from "./service/JTDeviceService";
|
||||
import CommonChannelEdit from './common/CommonChannelEdit'
|
||||
|
||||
export default {
|
||||
name: 'channelList',
|
||||
props: [ 'jtChannel', 'closeEdit'],
|
||||
components: {
|
||||
channelEdit,
|
||||
devicePlayer,
|
||||
uiHeader,
|
||||
DeviceTree
|
||||
CommonChannelEdit
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
id: this.$route.params.id,
|
||||
terminalDbId: this.$route.params.terminalDbId
|
||||
},
|
||||
version: 3,
|
||||
rules: {
|
||||
deviceId: [{ required: true, message: "请输入设备编号", trigger: "blur" }]
|
||||
@@ -272,39 +57,15 @@ export default {
|
||||
};
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.initData();
|
||||
},
|
||||
mounted() {},
|
||||
methods: {
|
||||
initData: function () {
|
||||
console.log(this.form.id)
|
||||
if (this.form.id) {
|
||||
this.isLoading = true;
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: `/api/jt1078/terminal/channel/one`,
|
||||
params: {
|
||||
id: this.form.id
|
||||
}
|
||||
}).then((res)=> {
|
||||
this.isLoading = false;
|
||||
if (res.data.data) {
|
||||
this.form = res.data.data;
|
||||
}
|
||||
}).cache((e)=>{
|
||||
this.isLoading = false;
|
||||
});
|
||||
}else {
|
||||
isLoading = false;
|
||||
}
|
||||
},
|
||||
onSubmit: function () {
|
||||
console.log("onSubmit");
|
||||
let isEdit = typeof (this.form.id) !== "undefined"
|
||||
console.log(this.jtChannel)
|
||||
let isEdit = typeof (this.jtChannel.id) !== "undefined"
|
||||
this.$axios({
|
||||
method: 'post',
|
||||
url:`/api/jt1078/terminal/channel/${isEdit?'update':'add'}/`,
|
||||
params: this.form
|
||||
params: this.jtChannel
|
||||
}).then((res) => {
|
||||
console.log(res.data)
|
||||
if (res.data.code === 0) {
|
||||
@@ -324,8 +85,8 @@ export default {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
showDevice: function () {
|
||||
window.history.go(-1)
|
||||
close: function () {
|
||||
this.closeEdit()
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,99 +1,101 @@
|
||||
<template>
|
||||
<div id="channelList" style="width: 100%">
|
||||
<div class="page-header">
|
||||
<div class="page-title">
|
||||
<el-button icon="el-icon-back" size="mini" style="font-size: 20px; color: #000;" type="text" @click="showDevice" ></el-button>
|
||||
<el-divider direction="vertical"></el-divider>
|
||||
通道列表
|
||||
</div>
|
||||
<div class="page-header-btn">
|
||||
<div style="display: inline;">
|
||||
搜索:
|
||||
<el-input @input="search" style="margin-right: 1rem; width: auto;" size="mini" placeholder="关键字"
|
||||
prefix-icon="el-icon-search" v-model="searchSrt" clearable></el-input>
|
||||
<el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="add">添加通道</el-button>
|
||||
<el-button icon="el-icon-refresh-right" circle size="mini" @click="refresh()"></el-button>
|
||||
<div v-if="!jtChannel">
|
||||
<div class="page-header" >
|
||||
<div class="page-title">
|
||||
<el-button icon="el-icon-back" size="mini" style="font-size: 20px; color: #000;" type="text" @click="showDevice" ></el-button>
|
||||
<el-divider direction="vertical"></el-divider>
|
||||
通道列表
|
||||
</div>
|
||||
<div class="page-header-btn">
|
||||
<div style="display: inline;">
|
||||
搜索:
|
||||
<el-input @input="search" style="margin-right: 1rem; width: auto;" size="mini" placeholder="关键字"
|
||||
prefix-icon="el-icon-search" v-model="searchSrt" clearable></el-input>
|
||||
<el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="add">添加通道</el-button>
|
||||
<el-button icon="el-icon-refresh-right" circle size="mini" @click="refresh()"></el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-container v-loading="isLoging" style="height: 82vh;">
|
||||
<el-main style="padding: 5px;">
|
||||
<el-table ref="channelListTable" :data="deviceChannelList" :height="winHeight" style="width: 100%"
|
||||
header-row-class-name="table-header">
|
||||
<el-table-column prop="channelId" label="通道编号" min-width="180">
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="名称" min-width="180">
|
||||
</el-table-column>
|
||||
<el-table-column label="快照" min-width="100">
|
||||
<template v-slot:default="scope">
|
||||
<el-image
|
||||
:src="getSnap(scope.row)"
|
||||
:preview-src-list="getBigSnap(scope.row)"
|
||||
@error="getSnapErrorEvent(scope.row.deviceId, scope.row.channelId)"
|
||||
:fit="'contain'"
|
||||
style="width: 60px">
|
||||
<div slot="error" class="image-slot">
|
||||
<i class="el-icon-picture-outline"></i>
|
||||
</div>
|
||||
</el-image>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="开启音频" min-width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-switch @change="updateChannel(scope.row)" v-model="scope.row.hasAudio" active-color="#409EFF">
|
||||
</el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" min-width="340" fixed="right">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="medium" v-bind:disabled="device == null || device.online === 0" icon="el-icon-video-play"
|
||||
type="text" @click="sendDevicePush(scope.row)">播放
|
||||
</el-button>
|
||||
<el-button size="medium" v-bind:disabled="device == null || device.online === 0"
|
||||
icon="el-icon-switch-button"
|
||||
type="text" style="color: #f56c6c" v-if="!!scope.row.stream"
|
||||
@click="stopDevicePush(scope.row)">停止
|
||||
</el-button>
|
||||
<el-divider direction="vertical"></el-divider>
|
||||
<el-button
|
||||
size="medium"
|
||||
type="text"
|
||||
icon="el-icon-edit"
|
||||
@click="handleEdit(scope.row)"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-divider direction="vertical"></el-divider>
|
||||
<el-dropdown @command="(command)=>{moreClick(command, scope.row)}">
|
||||
<el-button size="medium" type="text" >
|
||||
更多功能<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="records" v-bind:disabled="device == null || device.online === 0">
|
||||
设备录像</el-dropdown-item>
|
||||
<el-dropdown-item command="cloudRecords" v-bind:disabled="device == null || device.online === 0" >
|
||||
云端录像</el-dropdown-item>
|
||||
<!-- <el-dropdown-item command="shooting" v-bind:disabled="device == null || device.online === 0" >-->
|
||||
<!-- 立即拍摄</el-dropdown-item>-->
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</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>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</div>
|
||||
<devicePlayer ref="devicePlayer"></devicePlayer>
|
||||
<el-container v-loading="isLoging" style="height: 82vh;">
|
||||
<el-main style="padding: 5px;">
|
||||
<el-table ref="channelListTable" :data="deviceChannelList" :height="winHeight" style="width: 100%"
|
||||
header-row-class-name="table-header">
|
||||
<el-table-column prop="channelId" label="通道编号" min-width="180">
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="名称" min-width="180">
|
||||
</el-table-column>
|
||||
<el-table-column label="快照" min-width="100">
|
||||
<template v-slot:default="scope">
|
||||
<el-image
|
||||
:src="getSnap(scope.row)"
|
||||
:preview-src-list="getBigSnap(scope.row)"
|
||||
@error="getSnapErrorEvent(scope.row.deviceId, scope.row.channelId)"
|
||||
:fit="'contain'"
|
||||
style="width: 60px">
|
||||
<div slot="error" class="image-slot">
|
||||
<i class="el-icon-picture-outline"></i>
|
||||
</div>
|
||||
</el-image>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="开启音频" min-width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-switch @change="updateChannel(scope.row)" v-model="scope.row.hasAudio" active-color="#409EFF">
|
||||
</el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" min-width="340" fixed="right">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="medium" v-bind:disabled="device == null || device.online === 0" icon="el-icon-video-play"
|
||||
type="text" @click="sendDevicePush(scope.row)">播放
|
||||
</el-button>
|
||||
<el-button size="medium" v-bind:disabled="device == null || device.online === 0"
|
||||
icon="el-icon-switch-button"
|
||||
type="text" style="color: #f56c6c" v-if="!!scope.row.stream"
|
||||
@click="stopDevicePush(scope.row)">停止
|
||||
</el-button>
|
||||
<el-divider direction="vertical"></el-divider>
|
||||
<el-button
|
||||
size="medium"
|
||||
type="text"
|
||||
icon="el-icon-edit"
|
||||
@click="handleEdit(scope.row)"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-divider direction="vertical"></el-divider>
|
||||
<el-dropdown @command="(command)=>{moreClick(command, scope.row)}">
|
||||
<el-button size="medium" type="text" >
|
||||
更多功能<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="records" v-bind:disabled="device == null || device.online === 0">
|
||||
设备录像</el-dropdown-item>
|
||||
<el-dropdown-item command="cloudRecords" v-bind:disabled="device == null || device.online === 0" >
|
||||
云端录像</el-dropdown-item>
|
||||
<!-- <el-dropdown-item command="shooting" v-bind:disabled="device == null || device.online === 0" >-->
|
||||
<!-- 立即拍摄</el-dropdown-item>-->
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</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>
|
||||
</el-main>
|
||||
</el-container>
|
||||
<channelEdit ref="channelEdit"></channelEdit>
|
||||
<channelEdit v-if="jtChannel" ref="channelEdit" :jtChannel="jtChannel" :closeEdit="closeEdit"></channelEdit>
|
||||
<!--设备列表-->
|
||||
|
||||
</div>
|
||||
@@ -103,7 +105,7 @@
|
||||
import devicePlayer from './dialog/jtDevicePlayer.vue'
|
||||
import uiHeader from '../layout/UiHeader.vue'
|
||||
import DeviceTree from "./common/DeviceTree";
|
||||
import channelEdit from "./dialog/jtChannelEdit.vue";
|
||||
import channelEdit from "./JTChannelEdit.vue";
|
||||
import JTDeviceService from "./service/JTDeviceService";
|
||||
|
||||
export default {
|
||||
@@ -131,6 +133,7 @@ export default {
|
||||
beforeUrl: "/jtDeviceList",
|
||||
isLoging: false,
|
||||
loadSnap: {},
|
||||
jtChannel: null,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -306,29 +309,15 @@ export default {
|
||||
this.initData();
|
||||
},
|
||||
add: function () {
|
||||
// this.$refs.channelEdit.openDialog(null, this.deviceId, () => {
|
||||
// this.$refs.channelEdit.close();
|
||||
// this.$message({
|
||||
// showClose: true,
|
||||
// message: "添加成功",
|
||||
// type: "success",
|
||||
// });
|
||||
// setTimeout(this.getList, 200)
|
||||
// })
|
||||
this.$router.push(`/jtChannelEdit/${this.device.id}`);
|
||||
this.jtChannel = {};
|
||||
},
|
||||
// 编辑
|
||||
handleEdit(row) {
|
||||
// this.$refs.channelEdit.openDialog(row, this.deviceId, () => {
|
||||
// this.$refs.channelEdit.close();
|
||||
// this.$message({
|
||||
// showClose: true,
|
||||
// message: "修改成功",
|
||||
// type: "success",
|
||||
// });
|
||||
// setTimeout(this.getList, 200)
|
||||
// })
|
||||
this.$router.push(`/jtChannelEdit/${this.device.id}/${row.id}`);
|
||||
this.jtChannel = row;
|
||||
},
|
||||
// 编辑
|
||||
closeEdit(row) {
|
||||
this.jtChannel = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -287,13 +287,11 @@
|
||||
import devicePlayer from './dialog/jtDevicePlayer.vue'
|
||||
import uiHeader from '../layout/UiHeader.vue'
|
||||
import DeviceTree from "./common/DeviceTree";
|
||||
import channelEdit from "./dialog/jtChannelEdit.vue";
|
||||
import JTDeviceService from "./service/JTDeviceService";
|
||||
|
||||
export default {
|
||||
name: 'channelList',
|
||||
components: {
|
||||
channelEdit,
|
||||
devicePlayer,
|
||||
uiHeader,
|
||||
DeviceTree
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
<template>
|
||||
<div id="deviceEdit" v-loading="isLoging">
|
||||
<el-dialog
|
||||
title="通道编辑"
|
||||
width="40%"
|
||||
top="2rem"
|
||||
:close-on-click-modal="false"
|
||||
:visible.sync="showDialog"
|
||||
:destroy-on-close="true"
|
||||
@close="close()"
|
||||
>
|
||||
<div id="shared" style="margin-top: 1rem;margin-right: 100px;">
|
||||
<el-form ref="form" :rules="rules" :model="form" label-width="100px" >
|
||||
<el-form-item label="编号" prop="channelId">
|
||||
<el-input v-model="form.channelId" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input v-model="form.name" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<div style="float: right;">
|
||||
<el-button type="primary" @click="onSubmit" >确认</el-button>
|
||||
<el-button @click="close">取消</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "deviceEdit",
|
||||
props: {},
|
||||
computed: {},
|
||||
created() {},
|
||||
data() {
|
||||
return {
|
||||
listChangeCallback: null,
|
||||
showDialog: false,
|
||||
isLoging: false,
|
||||
form: {},
|
||||
row: "",
|
||||
deviceId: "",
|
||||
isEdit: false,
|
||||
rules: {
|
||||
deviceId: [{ required: true, message: "请输入设备编号", trigger: "blur" }]
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
openDialog: function (row, deviceId, callback) {
|
||||
console.log(row)
|
||||
this.showDialog = true;
|
||||
this.isEdit = false;
|
||||
this.form = {};
|
||||
if (row) {
|
||||
this.isEdit = true;
|
||||
this.form = row;
|
||||
}
|
||||
this.deviceId = deviceId;
|
||||
this.listChangeCallback = callback;
|
||||
},
|
||||
onSubmit: function () {
|
||||
console.log("onSubmit");
|
||||
let params = {
|
||||
channelId: this.form.channelId,
|
||||
name: this.form.name,
|
||||
terminalDbId: this.deviceId,
|
||||
}
|
||||
this.$axios({
|
||||
method: 'post',
|
||||
url:`/api/jt1078/terminal/channel/${this.isEdit?'update':'add'}/`,
|
||||
params: params
|
||||
}).then((res) => {
|
||||
console.log(res.data)
|
||||
if (res.data.code === 0) {
|
||||
this.listChangeCallback()
|
||||
}else {
|
||||
this.$message({
|
||||
showClose: true,
|
||||
message: res.data.msg,
|
||||
type: "error",
|
||||
});
|
||||
}
|
||||
}).catch(function (error) {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
close: function () {
|
||||
this.showDialog = false;
|
||||
this.$refs.form.resetFields();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -154,39 +154,61 @@
|
||||
<!--{"code":0,"data":{"paths":["22-29-30.mp4"],"rootPath":"/home/kkkkk/Documents/ZLMediaKit/release/linux/Debug/www/record/hls/kkkkk/2020-05-11/"}}-->
|
||||
<!--遥控界面-->
|
||||
<el-tab-pane label="云台控制" name="control" v-if="showPtz">
|
||||
<div style="display: flex; justify-content: left;">
|
||||
<div class="control-wrapper">
|
||||
<div class="control-btn control-top" @mousedown="ptzCamera('up')" @mouseup="ptzCamera('stop')">
|
||||
<i class="el-icon-caret-top"></i>
|
||||
<div class="control-inner-btn control-inner"></div>
|
||||
<div style="display: grid; grid-template-columns: 240px auto; height: 180px; overflow: auto">
|
||||
<div style="display: grid; grid-template-columns: 6.25rem auto;">
|
||||
|
||||
<div class="control-wrapper">
|
||||
<div class="control-btn control-top" @mousedown="ptzCamera('up')" @mouseup="ptzCamera('stop')">
|
||||
<i class="el-icon-caret-top"></i>
|
||||
<div class="control-inner-btn control-inner"></div>
|
||||
</div>
|
||||
<div class="control-btn control-left" @mousedown="ptzCamera('left')" @mouseup="ptzCamera('stop')">
|
||||
<i class="el-icon-caret-left"></i>
|
||||
<div class="control-inner-btn control-inner"></div>
|
||||
</div>
|
||||
<div class="control-btn control-bottom" @mousedown="ptzCamera('down')" @mouseup="ptzCamera('stop')">
|
||||
<i class="el-icon-caret-bottom"></i>
|
||||
<div class="control-inner-btn control-inner"></div>
|
||||
</div>
|
||||
<div class="control-btn control-right" @mousedown="ptzCamera('right')" @mouseup="ptzCamera('stop')">
|
||||
<i class="el-icon-caret-right"></i>
|
||||
<div class="control-inner-btn control-inner"></div>
|
||||
</div>
|
||||
<div class="control-round">
|
||||
<div class="control-round-inner"><i class="fa fa-pause-circle"></i></div>
|
||||
</div>
|
||||
<div class="contro-speed" style="position: absolute; left: 4px; top: 7rem; width: 6.25rem;">
|
||||
<el-slider v-model="controSpeed" :max="100"></el-slider>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-btn control-left" @mousedown="ptzCamera('left')" @mouseup="ptzCamera('stop')">
|
||||
<i class="el-icon-caret-left"></i>
|
||||
<div class="control-inner-btn control-inner"></div>
|
||||
</div>
|
||||
<div class="control-btn control-bottom" @mousedown="ptzCamera('down')" @mouseup="ptzCamera('stop')">
|
||||
<i class="el-icon-caret-bottom"></i>
|
||||
<div class="control-inner-btn control-inner"></div>
|
||||
</div>
|
||||
<div class="control-btn control-right" @mousedown="ptzCamera('right')" @mouseup="ptzCamera('stop')">
|
||||
<i class="el-icon-caret-right"></i>
|
||||
<div class="control-inner-btn control-inner"></div>
|
||||
</div>
|
||||
<div class="control-round">
|
||||
<div class="control-round-inner"><i class="fa fa-pause-circle"></i></div>
|
||||
</div>
|
||||
<div style="position: absolute; left: 7.25rem; top: 1.25rem" @mousedown="ptzCamera('zoomin')"
|
||||
@mouseup="ptzCamera('stop')"><i class="el-icon-zoom-in control-zoom-btn"
|
||||
style="font-size: 1.875rem;"></i></div>
|
||||
<div style="position: absolute; left: 7.25rem; top: 3.25rem; font-size: 1.875rem;"
|
||||
@mousedown="ptzCamera('zoomout')" @mouseup="ptzCamera('stop')"><i
|
||||
class="el-icon-zoom-out control-zoom-btn"></i></div>
|
||||
<div class="contro-speed" style="position: absolute; left: 4px; top: 7rem; width: 9rem;">
|
||||
<el-slider v-model="controSpeed" :max="255"></el-slider>
|
||||
<div>
|
||||
<div class="ptz-btn-box">
|
||||
<div style="" @mousedown="ptzCamera('zoomin')" @mouseup="ptzCamera('stop')" title="变倍+">
|
||||
<i class="el-icon-zoom-in control-zoom-btn" style="font-size: 1.5rem;"></i>
|
||||
</div>
|
||||
<div style="" @mousedown="ptzCamera('zoomout')" @mouseup="ptzCamera('stop')" title="变倍-">
|
||||
<i class="el-icon-zoom-out control-zoom-btn" style="font-size: 1.5rem;"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ptz-btn-box">
|
||||
<div @mousedown="ptzCamera('focusnear')" @mouseup="ptzCamera('stop')" title="聚焦+">
|
||||
<i class="iconfont icon-bianjiao-fangda control-zoom-btn" style="font-size: 1.5rem;"></i>
|
||||
</div>
|
||||
<div @mousedown="ptzCamera('focusfar')" @mouseup="ptzCamera('stop')" title="聚焦-">
|
||||
<i class="iconfont icon-bianjiao-suoxiao control-zoom-btn" style="font-size: 1.5rem;"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ptz-btn-box">
|
||||
<div @mousedown="ptzCamera('irisin')" @mouseup="ptzCamera('stop')" title="光圈+">
|
||||
<i class="iconfont icon-guangquan control-zoom-btn" style="font-size: 1.5rem;"></i>
|
||||
</div>
|
||||
<div @mousedown="ptzCamera('irisout')" @mouseup="ptzCamera('stop')" title="光圈-">
|
||||
<i class="iconfont icon-guangquan- control-zoom-btn" style="font-size: 1.5rem;"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-panel">
|
||||
<div style="text-align: left" >
|
||||
<div style="width: 100%; display: grid; grid-template-rows: 1fr 1fr; grid-row-gap: 10px">
|
||||
<el-button-group>
|
||||
<el-button size="mini" @click="wiper('on')">开启雨刷
|
||||
@@ -200,49 +222,13 @@
|
||||
<el-button size="mini" @click="fillLight('off')">关补光灯
|
||||
</el-button>
|
||||
</el-button-group>
|
||||
<el-button-group>
|
||||
<el-button size="mini" @click="ptzCamera('irisin')">光圈调大
|
||||
</el-button>
|
||||
<el-button size="mini" @click="ptzCamera('irisout')">光圈调小
|
||||
</el-button>
|
||||
</el-button-group>
|
||||
<el-button-group>
|
||||
<el-button size="mini" @click="ptzCamera('focusfar')">焦距调大
|
||||
</el-button>
|
||||
<el-button size="mini" @click="ptzCamera('focusnear')">焦距调小
|
||||
</el-button>
|
||||
</el-button-group>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="编码信息" name="codec" v-loading="tracksLoading">
|
||||
<p>
|
||||
无法播放或者没有声音?   试一试 
|
||||
<el-button size="mini" type="primary" v-if="!coverPlaying" @click="coverPlay">转码播放</el-button>
|
||||
<el-button size="mini" type="danger" v-if="coverPlaying" @click="convertStopClick">停止转码</el-button>
|
||||
</p>
|
||||
<div class="trank">
|
||||
<p v-if="tracksNotLoaded" style="text-align: center;padding-top: 3rem;">暂无数据</p>
|
||||
<div v-for="(item, index) in tracks" style="width: 50%; float: left" loading>
|
||||
<span>流 {{ index }}</span>
|
||||
<div class="trankInfo" v-if="item.codec_type == 0">
|
||||
<p>格式: {{ item.codec_id_name }}</p>
|
||||
<p>类型: 视频</p>
|
||||
<p>分辨率: {{ item.width }} x {{ item.height }}</p>
|
||||
<p>帧率: {{ item.fps }}</p>
|
||||
</div>
|
||||
<div class="trankInfo" v-if="item.codec_type == 1">
|
||||
<p>格式: {{ item.codec_id_name }}</p>
|
||||
<p>类型: 音频</p>
|
||||
<p>采样位数: {{ item.sample_bit }}</p>
|
||||
<p>采样率: {{ item.sample_rate }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<mediaInfo :app="app" :stream="streamId" :mediaServerId="mediaServerId"></mediaInfo>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="语音对讲" name="broadcast">
|
||||
<div class="trank" style="text-align: center;">
|
||||
@@ -269,11 +255,13 @@ import rtcPlayer from '../dialog/rtcPlayer.vue'
|
||||
import LivePlayer from '@liveqing/liveplayer'
|
||||
import crypto from 'crypto'
|
||||
import jessibucaPlayer from '../common/jessibuca.vue'
|
||||
import mediaInfo from '../common/mediaInfo.vue'
|
||||
|
||||
export default {
|
||||
name: 'devicePlayer',
|
||||
props: {},
|
||||
components: {
|
||||
mediaInfo,
|
||||
LivePlayer, jessibucaPlayer, rtcPlayer,
|
||||
},
|
||||
computed: {
|
||||
@@ -307,7 +295,6 @@ export default {
|
||||
streamId: '',
|
||||
app: '',
|
||||
mediaServerId: '',
|
||||
convertKey: '',
|
||||
deviceId: '',
|
||||
channelId: '',
|
||||
tabActiveName: 'media',
|
||||
@@ -326,7 +313,6 @@ export default {
|
||||
scanSpeed: 100,
|
||||
scanGroup: 0,
|
||||
tracks: [],
|
||||
coverPlaying: false,
|
||||
tracksLoading: false,
|
||||
showPtz: true,
|
||||
showRrecord: true,
|
||||
@@ -415,70 +401,17 @@ export default {
|
||||
},
|
||||
getUrlByStreamInfo() {
|
||||
console.log(this.streamInfo)
|
||||
let streamInfo = this.streamInfo
|
||||
if (this.streamInfo.transcodeStream) {
|
||||
streamInfo = this.streamInfo.transcodeStream;
|
||||
}
|
||||
if (location.protocol === "https:") {
|
||||
this.videoUrl = this.streamInfo[this.player[this.activePlayer][1]]
|
||||
this.videoUrl = streamInfo[this.player[this.activePlayer][1]]
|
||||
} else {
|
||||
this.videoUrl = this.streamInfo[this.player[this.activePlayer][0]]
|
||||
this.videoUrl = streamInfo[this.player[this.activePlayer][0]]
|
||||
}
|
||||
return this.videoUrl;
|
||||
|
||||
},
|
||||
coverPlay: function () {
|
||||
var that = this;
|
||||
this.coverPlaying = true;
|
||||
this.$refs[this.activePlayer].pause()
|
||||
that.$axios({
|
||||
method: 'post',
|
||||
url: '/api/play/convert/' + that.streamId
|
||||
}).then(function (res) {
|
||||
if (res.data.code === 0) {
|
||||
that.convertKey = res.data.key;
|
||||
setTimeout(() => {
|
||||
that.isLoging = false;
|
||||
that.playFromStreamInfo(false, res.data.data);
|
||||
}, 2000)
|
||||
} else {
|
||||
that.isLoging = false;
|
||||
that.coverPlaying = false;
|
||||
that.$message({
|
||||
showClose: true,
|
||||
message: '转码失败',
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
}).catch(function (e) {
|
||||
console.log(e)
|
||||
that.coverPlaying = false;
|
||||
that.$message({
|
||||
showClose: true,
|
||||
message: '播放错误',
|
||||
type: 'error'
|
||||
});
|
||||
});
|
||||
},
|
||||
convertStopClick: function () {
|
||||
this.convertStop(() => {
|
||||
this.$refs[this.activePlayer].play(this.videoUrl)
|
||||
});
|
||||
},
|
||||
convertStop: function (callback) {
|
||||
var that = this;
|
||||
that.$refs.videoPlayer.pause()
|
||||
this.$axios({
|
||||
method: 'post',
|
||||
url: '/api/play/convertStop/' + this.convertKey
|
||||
}).then(function (res) {
|
||||
if (res.data.code == 0) {
|
||||
console.log(res.data.msg)
|
||||
} else {
|
||||
console.error(res.data.msg)
|
||||
}
|
||||
if (callback) callback();
|
||||
}).catch(function (e) {
|
||||
});
|
||||
that.coverPlaying = false;
|
||||
that.convertKey = "";
|
||||
// if (callback )callback();
|
||||
},
|
||||
|
||||
playFromStreamInfo: function (realHasAudio, streamInfo) {
|
||||
@@ -500,10 +433,6 @@ export default {
|
||||
this.videoUrl = '';
|
||||
this.coverPlaying = false;
|
||||
this.showVideoDialog = false;
|
||||
if (this.convertKey != '') {
|
||||
this.convertStop();
|
||||
}
|
||||
this.convertKey = ''
|
||||
this.stopBroadcast()
|
||||
},
|
||||
|
||||
@@ -606,7 +535,10 @@ export default {
|
||||
copyUrl: function (dropdownItem) {
|
||||
console.log(dropdownItem)
|
||||
this.$copyText(dropdownItem).then((e) => {
|
||||
this.$message.success("成功拷贝到粘贴板");
|
||||
this.$message.success({
|
||||
showClose: true,
|
||||
message: "成功拷贝到粘贴板"
|
||||
})
|
||||
}, (e) => {
|
||||
|
||||
})
|
||||
@@ -968,4 +900,14 @@ export default {
|
||||
width: 80%;
|
||||
padding: 0 10%;
|
||||
}
|
||||
.el-dialog__body{
|
||||
padding: 10px 20px;
|
||||
}
|
||||
.ptz-btn-box {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
padding: 0 2rem;
|
||||
height: 3rem;
|
||||
line-height: 4rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user