云台联调
This commit is contained in:
parent
117aa3c224
commit
6f2f047ede
|
|
@ -44,6 +44,7 @@
|
|||
"echarts": "5.4.0",
|
||||
"element-ui": "2.15.14",
|
||||
"file-saver": "2.0.5",
|
||||
"flv.js": "^1.6.2",
|
||||
"fuse.js": "6.4.3",
|
||||
"highlight.js": "9.18.5",
|
||||
"js-beautify": "1.13.0",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
module.exports = {
|
||||
printWidth: 120,
|
||||
tabWidth: 4,
|
||||
tabWidth: 2,
|
||||
semi: false,
|
||||
vueIndentScriptAndStyle: false,
|
||||
singleQuote: true,
|
||||
|
|
|
|||
|
|
@ -64,3 +64,18 @@ export const delPlatformConfiguration = (id) => {
|
|||
export const changeStatus = (data) => {
|
||||
return request.post('/smart-site/platform_configuration/changeStatus', data);
|
||||
};
|
||||
|
||||
// 获取清新token
|
||||
export const getQxToken = (params) => {
|
||||
return request.get('/smart-site/video_equipment/getQxToken', { params });
|
||||
};
|
||||
|
||||
// 获取清新视频设备列表
|
||||
export const getVideoEquipment = (params) => {
|
||||
return request.get('/smart-site/video_equipment/getVideoEquipment', { params });
|
||||
};
|
||||
|
||||
// 更新水印
|
||||
export const updateWaterMark = (data) => {
|
||||
return request.post('/smart-site/video_equipment/updateWaterMark', data);
|
||||
};
|
||||
|
|
@ -230,7 +230,7 @@ export default {
|
|||
wsUrl: [{ required: true, message: '请输入视频连接地址-公网', trigger: 'blur' }],
|
||||
epid: [
|
||||
{ required: true, message: '请输入epid', trigger: 'blur' },
|
||||
{ pattern: /^[0-9]*$/, message: '只能输入正整数', trigger: 'blur' },
|
||||
{ pattern: /^[A-Za-z0-9]+$/, message: '只能输入数字和字母', trigger: 'blur' },
|
||||
],
|
||||
bfix: [{ required: true, message: '请输入bfix', trigger: 'blur' }],
|
||||
},
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@
|
|||
</el-dialog>
|
||||
|
||||
<el-dialog title="调试" :visible.sync="videoDebug" width="70%" height="80%">
|
||||
<MonitoringAndDebug />
|
||||
<MonitoringAndDebug v-if="videoDebug" :row="this.row"/>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -249,6 +249,7 @@ export default {
|
|||
qrData: {
|
||||
devName: '',
|
||||
},
|
||||
row: {}, // 当前行
|
||||
dialogTitle: '新增',
|
||||
isAdd: true,
|
||||
dialogVisible: false,
|
||||
|
|
@ -418,6 +419,7 @@ export default {
|
|||
// 监控调试
|
||||
handleMonitoringAndDebug(row) {
|
||||
console.log('监控调试', row)
|
||||
this.row = row
|
||||
this.videoDebug = true
|
||||
},
|
||||
// 查看配置
|
||||
|
|
|
|||
|
|
@ -2,16 +2,18 @@
|
|||
<div class="monitor-page">
|
||||
<!-- 左侧视频监控区 -->
|
||||
<div class="video-section">
|
||||
<div class="video-title">视频播放</div>
|
||||
<div class="video-title">
|
||||
视频播放
|
||||
<el-select v-model="ballIndex" placeholder="请选择" style="width: 80px">
|
||||
<el-option v-for="item in ballIndexOpts" :key="item.value" :label="item.label" :value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="video-container">
|
||||
<div class="video-overlay">
|
||||
<div class="timestamp">{{ currentTime }}</div>
|
||||
<div class="coordinates">
|
||||
<div>{{ coordinates.line1 }}</div>
|
||||
<div>{{ coordinates.line2 }}</div>
|
||||
</div>
|
||||
<div class="signal-info">电池: {{ batteryInfo }}</div>
|
||||
</div>
|
||||
<video class="cell-player-1" ref="videosmallone" preload="auto" muted type="rtmp/flv" :id="videoId">
|
||||
<source src="" />
|
||||
</video>
|
||||
<canvas ref="canvas" style="display: none"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -23,34 +25,30 @@
|
|||
<!-- 方向控制 -->
|
||||
<div class="direction-control">
|
||||
<div class="direction-pad">
|
||||
<el-button icon="el-icon-arrow-up" circle @click="control('up')">
|
||||
</el-button>
|
||||
<el-button icon="el-icon-arrow-up" circle @click="control('up')"> </el-button>
|
||||
<div class="horizontal-buttons">
|
||||
<el-button icon="el-icon-arrow-left" circle @click="control('left')">
|
||||
</el-button>
|
||||
<el-button icon="el-icon-arrow-right" circle @click="control('right')">
|
||||
</el-button>
|
||||
<el-button icon="el-icon-arrow-left" circle @click="control('left')"> </el-button>
|
||||
<el-button icon="el-icon-arrow-right" circle @click="control('right')"> </el-button>
|
||||
</div>
|
||||
<el-button icon="el-icon-arrow-down" circle @click="control('down')">
|
||||
</el-button>
|
||||
<el-button icon="el-icon-arrow-down" circle @click="control('down')"> </el-button>
|
||||
</div>
|
||||
|
||||
<!-- 缩放控制 -->
|
||||
<div class="zoom-controls">
|
||||
<div class="zoom-column">
|
||||
<el-button size="small" @click="control('zoomIn')">
|
||||
<el-button size="small" @click="control('focusIn')">
|
||||
<i class="el-icon-plus"></i>
|
||||
</el-button>
|
||||
<el-button size="small" @click="control('zoomOut')">
|
||||
<el-button size="small" @click="control('focusOut')">
|
||||
<i class="el-icon-minus"></i>
|
||||
</el-button>
|
||||
<div class="column-label">聚焦</div>
|
||||
</div>
|
||||
<div class="zoom-column">
|
||||
<el-button size="small" @click="control('focusIn')">
|
||||
<el-button size="small" @click="control('zoomIn')">
|
||||
<i class="el-icon-plus"></i>
|
||||
</el-button>
|
||||
<el-button size="small" @click="control('focusOut')">
|
||||
<el-button size="small" @click="control('zoomOut')">
|
||||
<i class="el-icon-minus"></i>
|
||||
</el-button>
|
||||
<div class="column-label">缩放</div>
|
||||
|
|
@ -72,9 +70,10 @@
|
|||
<div class="view-row">
|
||||
<div class="view-item">
|
||||
<i class="el-icon-video-camera"></i>
|
||||
<span>本地录像</span>
|
||||
<span v-if="!isRecording" @click="startRecording">本地录像</span>
|
||||
<span v-else @click="stopRecording">停止录像</span>
|
||||
</div>
|
||||
<div class="view-item">
|
||||
<div class="view-item" @click="takeSnapshot">
|
||||
<i class="el-icon-picture"></i>
|
||||
<span>本地抓拍</span>
|
||||
</div>
|
||||
|
|
@ -104,15 +103,9 @@
|
|||
|
||||
<!-- 水印设置 -->
|
||||
<div class="watermark-section">
|
||||
<div class="watermark-title">应用水印<i class="el-icon-s-operation"></i></div>
|
||||
<el-input
|
||||
v-model="watermark.line1"
|
||||
placeholder="设置第一行视频水印文字"
|
||||
></el-input>
|
||||
<el-input
|
||||
v-model="watermark.line2"
|
||||
placeholder="设置第二行视频水印文字"
|
||||
></el-input>
|
||||
<div class="watermark-title" @click="updateWaterMark">应用水印<i class="el-icon-s-operation"></i></div>
|
||||
<el-input v-model="watermark.oneText" placeholder="设置第一行视频水印文字"></el-input>
|
||||
<el-input v-model="watermark.twoText" placeholder="设置第二行视频水印文字"></el-input>
|
||||
</div>
|
||||
|
||||
<div class="control-title">快捷键设置</div>
|
||||
|
|
@ -122,13 +115,13 @@
|
|||
<div class="shortcut-grid">
|
||||
<div class="shortcut-row" v-for="(row, rowIndex) in shortcutSettings" :key="rowIndex">
|
||||
<div class="shortcut-item" v-for="(item, colIndex) in row" :key="colIndex">
|
||||
<span>{{item.label}}</span>
|
||||
<span>{{ item.label }}</span>
|
||||
<input
|
||||
v-model="item.key"
|
||||
@keydown="handleKeyPress($event, rowIndex, colIndex)"
|
||||
:maxlength="1"
|
||||
class="key"
|
||||
></input>
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -138,66 +131,123 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import flvjs from 'flv.js'
|
||||
import axios from 'axios'
|
||||
import { getQxToken, getVideoEquipment, updateWaterMark } from '@/api/deviceManagement'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
row: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
name: 'VideoMonitor',
|
||||
data() {
|
||||
return {
|
||||
currentTime: '2023-01-07 13:19:38',
|
||||
coordinates: {
|
||||
line1: '116.13263L 000KPH',
|
||||
line2: '033.50462N 000D/G'
|
||||
},
|
||||
batteryInfo: '64% 4G1:96% 4G2:96%',
|
||||
qxToken: '',
|
||||
qxInfo: {},
|
||||
videoId: '',
|
||||
player: null,
|
||||
ballIndex: 0,
|
||||
ballIndexOpts: [],
|
||||
isDown: false,
|
||||
watermark: {
|
||||
line1: '',
|
||||
line2: ''
|
||||
oneText: '',
|
||||
twoText: '',
|
||||
},
|
||||
// 合并后的快捷键设置数据结构
|
||||
shortcutSettings: [
|
||||
[
|
||||
{ label: '上', key: 'W', action: 'up' },
|
||||
{ label: '放大', key: 'Q', action: 'zoomIn' }
|
||||
{ label: '放大', key: 'Q', action: 'zoomIn' },
|
||||
],
|
||||
[
|
||||
{ label: '下', key: 'S', action: 'down' },
|
||||
{ label: '缩小', key: 'E', action: 'zoomOut' }
|
||||
{ label: '缩小', key: 'E', action: 'zoomOut' },
|
||||
],
|
||||
[
|
||||
{ label: '左', key: 'A', action: 'left' },
|
||||
{ label: '远焦', key: 'R', action: 'focusIn' }
|
||||
{ label: '远焦', key: 'R', action: 'focusIn' },
|
||||
],
|
||||
[
|
||||
{ label: '右', key: 'D', action: 'right' },
|
||||
{ label: '近焦', key: 'T', action: 'focusOut' }
|
||||
{ label: '近焦', key: 'T', action: 'focusOut' },
|
||||
],
|
||||
[
|
||||
{ label: '抓拍', key: 'F', action: 'capture' },
|
||||
{ label: '录像', key: 'G', action: 'record' }
|
||||
]
|
||||
]
|
||||
{ label: '录像', key: 'G', action: 'record' },
|
||||
],
|
||||
],
|
||||
mediaRecorder: null,
|
||||
recordedChunks: [],
|
||||
isRecording: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
control(action) {
|
||||
console.log('Control action:', action)
|
||||
this.isDown = true
|
||||
switch (action) {
|
||||
case 'up':
|
||||
console.log('Up')
|
||||
this.requestPost(
|
||||
'PTZ/C_PTZ_Turn?token=' + this.qxToken,
|
||||
{
|
||||
puid: this.row.puId,
|
||||
idx: this.ballIndex,
|
||||
motion: 'up',
|
||||
},
|
||||
async (rv) => {},
|
||||
)
|
||||
this.handleStop()
|
||||
break
|
||||
case 'down':
|
||||
console.log('Down')
|
||||
this.requestPost(
|
||||
'PTZ/C_PTZ_Turn?token=' + this.qxToken,
|
||||
{
|
||||
puid: this.row.puId,
|
||||
idx: this.ballIndex,
|
||||
motion: 'down',
|
||||
},
|
||||
async (rv) => {},
|
||||
)
|
||||
this.handleStop()
|
||||
break
|
||||
case 'left':
|
||||
console.log('Left')
|
||||
this.requestPost(
|
||||
'PTZ/C_PTZ_Turn?token=' + this.qxToken,
|
||||
{
|
||||
puid: this.row.puId,
|
||||
idx: this.ballIndex,
|
||||
motion: 'left',
|
||||
},
|
||||
async (rv) => {},
|
||||
)
|
||||
this.handleStop()
|
||||
break
|
||||
case 'right':
|
||||
console.log('Right')
|
||||
this.requestPost(
|
||||
'PTZ/C_PTZ_Turn?token=' + this.qxToken,
|
||||
{
|
||||
puid: this.row.puId,
|
||||
idx: this.ballIndex,
|
||||
motion: 'right',
|
||||
},
|
||||
async (rv) => {},
|
||||
)
|
||||
this.handleStop()
|
||||
break
|
||||
case 'zoomIn':
|
||||
console.log('Zoom In')
|
||||
this.handleZoomIn()
|
||||
break
|
||||
case 'zoomOut':
|
||||
console.log('Zoom Out')
|
||||
this.handleZoomOut()
|
||||
break
|
||||
case 'focusIn':
|
||||
console.log('Focus In')
|
||||
|
|
@ -219,7 +269,6 @@ export default {
|
|||
break
|
||||
default:
|
||||
console.log('Unknown action:', action)
|
||||
|
||||
}
|
||||
},
|
||||
toggleCloud() {
|
||||
|
|
@ -231,51 +280,250 @@ export default {
|
|||
|
||||
// 处理键盘按键事件
|
||||
handleKeyPress(event, rowIndex, colIndex) {
|
||||
event.preventDefault();
|
||||
const key = event.key.toUpperCase();
|
||||
event.preventDefault()
|
||||
const key = event.key.toUpperCase()
|
||||
// 只允许字母键
|
||||
if (/^[A-Z]$/.test(key)) {
|
||||
// 检查是否已经存在相同的键位
|
||||
const isDuplicate = this.shortcutSettings.some(row =>
|
||||
row.some(item => item.key === key && !(item.key === this.shortcutSettings[rowIndex][colIndex].key))
|
||||
);
|
||||
const isDuplicate = this.shortcutSettings.some((row) =>
|
||||
row.some((item) => item.key === key && !(item.key === this.shortcutSettings[rowIndex][colIndex].key)),
|
||||
)
|
||||
|
||||
if (isDuplicate) {
|
||||
this.$message.error('该键位已被使用,请选择其他键位');
|
||||
return;
|
||||
this.$message.error('该键位已被使用,请选择其他键位')
|
||||
return
|
||||
}
|
||||
|
||||
// 获取当前的键位
|
||||
const oldKey = this.shortcutSettings[rowIndex][colIndex].key;
|
||||
const oldKey = this.shortcutSettings[rowIndex][colIndex].key
|
||||
|
||||
// 更新快捷键设置
|
||||
this.shortcutSettings[rowIndex][colIndex].key = key;
|
||||
this.shortcutSettings[rowIndex][colIndex].key = key
|
||||
}
|
||||
}
|
||||
},
|
||||
// 获取清新token
|
||||
async getQxToken() {
|
||||
try {
|
||||
const res = await getQxToken()
|
||||
console.log('qxToken:', res)
|
||||
this.qxToken = res.msg
|
||||
} catch (error) {
|
||||
console.log('getQxToken error:', error)
|
||||
}
|
||||
},
|
||||
// 获取清新设备信息
|
||||
async getQxInfo() {
|
||||
try {
|
||||
const res = await getVideoEquipment()
|
||||
console.log('qxInfo:', res)
|
||||
this.qxInfo = res.data
|
||||
} catch (error) {
|
||||
console.log('getQxInfo error:', error)
|
||||
}
|
||||
},
|
||||
init() {
|
||||
setTimeout(() => {
|
||||
//使用定时器是因为,在mounted声明周期里调用,可能会出现DOM没加载出来的原因
|
||||
var videoElement = this.$refs.videosmallone // 获取到html中的video标签
|
||||
if (videoElement && flvjs.isSupported()) {
|
||||
//因为我这个是复用组件,进来先判断 player是否存在,如果存在,销毁掉它,不然会占用TCP名额
|
||||
if (this.player !== null) {
|
||||
this.player.pause()
|
||||
this.player.unload()
|
||||
this.player.detachMediaElement()
|
||||
this.player.destroy()
|
||||
this.player = null
|
||||
}
|
||||
this.player = flvjs.createPlayer(
|
||||
//创建直播流,加载到DOM中去
|
||||
{
|
||||
type: 'flv',
|
||||
url:
|
||||
this.qxInfo.videoUrl +
|
||||
'stream.flv?puid=' +
|
||||
this.row.puId +
|
||||
'&idx=' +
|
||||
this.ballIndex +
|
||||
'&stream=0&token=' +
|
||||
this.qxToken, //你的url地址
|
||||
isLive: true, //数据源是否为直播流
|
||||
hasAudio: false, //数据源是否包含有音频
|
||||
hasVideo: true, //数据源是否包含有视频
|
||||
enableStashBuffer: true, //是否启用缓存区
|
||||
},
|
||||
{
|
||||
enableWorker: false, //不启用分离线程
|
||||
enableStashBuffer: false, //关闭IO隐藏缓冲区
|
||||
autoCleanupSourceBuffer: true, //自动清除缓存
|
||||
lazyLoad: false,
|
||||
},
|
||||
)
|
||||
this.player.attachMediaElement(videoElement) //放到dom中去
|
||||
this.player.load() //准备完成
|
||||
//!!!!!!这里需要注意,有的时候load加载完成不一定可以播放,要是播放不成功,用settimeout 给下面的this.player.play() 延时几百毫秒再播放
|
||||
setTimeout(() => {
|
||||
this.player.play()
|
||||
}, 500) // Delay to ensure the player is ready
|
||||
}
|
||||
}, 1000)
|
||||
},
|
||||
requestPost(url, data, callback) {
|
||||
console.log('requestPost----------------', JSON.stringify(data))
|
||||
url = this.qxInfo.videoUrl + url
|
||||
axios.post(url, data).then((rv) => {
|
||||
// console.log(rv)
|
||||
// console.log(JSON.stringify(rv))
|
||||
callback(rv)
|
||||
})
|
||||
},
|
||||
handleStop() {
|
||||
console.log('handleStop')
|
||||
setTimeout(() => {
|
||||
this.requestPost(
|
||||
'PTZ/C_PTZ_Turn?token=' + this.qxToken,
|
||||
{
|
||||
puid: this.row.puId,
|
||||
idx: this.ballIndex,
|
||||
motion: 'stop',
|
||||
},
|
||||
async (rv) => {},
|
||||
)
|
||||
this.isDown = false
|
||||
}, 700)
|
||||
},
|
||||
// 停止缩放
|
||||
handleStopZoom() {
|
||||
const params = {
|
||||
puid: this.row.puId,
|
||||
idx: this.ballIndex,
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.requestPost('PTZ/C_PTZ_StopPictureZoom?token=' + this.qxToken, params, (rv) => {})
|
||||
}, 700)
|
||||
},
|
||||
// 放大
|
||||
handleZoomIn() {
|
||||
const params = {
|
||||
puid: this.row.puId,
|
||||
idx: this.ballIndex,
|
||||
}
|
||||
this.requestPost('PTZ/C_PTZ_ZoomInPicture?token=' + this.qxToken, params, (rv) => {})
|
||||
this.handleStopZoom()
|
||||
},
|
||||
// 缩小
|
||||
handleZoomOut() {
|
||||
const params = {
|
||||
puid: this.row.puId,
|
||||
idx: this.ballIndex,
|
||||
}
|
||||
this.requestPost('PTZ/C_PTZ_ZoomOutPicture?token=' + this.qxToken, params, (rv) => {})
|
||||
this.handleStopZoom()
|
||||
},
|
||||
// 更新水印
|
||||
async updateWaterMark() {
|
||||
try {
|
||||
const params = {
|
||||
puId: this.row.puId,
|
||||
oneText: this.watermark.oneText,
|
||||
twoText: this.watermark.twoText,
|
||||
videoPath: this.qxInfo.videoUrl,
|
||||
}
|
||||
console.log('更新水印 params:', params)
|
||||
const res = await updateWaterMark(params)
|
||||
console.log('updateWaterMark:', res)
|
||||
// 提示
|
||||
this.$message.success('操作成功')
|
||||
} catch (error) {
|
||||
console.log('updateWaterMark error:', error)
|
||||
}
|
||||
},
|
||||
// 开始录像
|
||||
startRecording() {
|
||||
this.isRecording = true;
|
||||
const video = this.$refs.videosmallone;
|
||||
const stream = video.captureStream();
|
||||
this.mediaRecorder = new MediaRecorder(stream);
|
||||
this.mediaRecorder.ondataavailable = (event) => {
|
||||
if (event.data.size > 0) {
|
||||
this.recordedChunks.push(event.data);
|
||||
}
|
||||
};
|
||||
this.mediaRecorder.start();
|
||||
},
|
||||
// 停止录像
|
||||
stopRecording() {
|
||||
this.isRecording = false
|
||||
this.mediaRecorder.stop()
|
||||
this.mediaRecorder.onstop = () => {
|
||||
const blob = new Blob(this.recordedChunks, { type: 'video/webm' })
|
||||
const url = URL.createObjectURL(blob)
|
||||
const a = document.createElement('a')
|
||||
a.href = url
|
||||
a.download = `本地录像_${new Date().getTime()}.mp4`
|
||||
a.click()
|
||||
URL.revokeObjectURL(url)
|
||||
this.recordedChunks = []
|
||||
}
|
||||
},
|
||||
// 抓拍
|
||||
takeSnapshot() {
|
||||
console.log('Take snapshot')
|
||||
const video = this.$refs.videosmallone
|
||||
const canvas = this.$refs.canvas
|
||||
canvas.width = video.videoWidth
|
||||
canvas.height = video.videoHeight
|
||||
const context = canvas.getContext('2d')
|
||||
context.drawImage(video, 0, 0, canvas.width, canvas.height)
|
||||
const dataURL = canvas.toDataURL('image/png')
|
||||
const a = document.createElement('a')
|
||||
a.href = dataURL
|
||||
a.download = 'snapshot.png'
|
||||
a.click()
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
keyMap() {
|
||||
return this.shortcutSettings.reduce((map, row) => {
|
||||
row.forEach(item => {
|
||||
map[item.key] = item.action;
|
||||
});
|
||||
return map;
|
||||
}, {});
|
||||
}
|
||||
row.forEach((item) => {
|
||||
map[item.key] = item.action
|
||||
})
|
||||
return map
|
||||
}, {})
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
// 键盘事件监听
|
||||
window.addEventListener('keydown', (e) => {
|
||||
const key = e.key.toUpperCase();
|
||||
// 检查事件目标是否是输入框
|
||||
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') {
|
||||
console.log('Input focused')
|
||||
return
|
||||
}
|
||||
if (this.isDown) return
|
||||
const key = e.key.toUpperCase()
|
||||
if (this.keyMap[key]) {
|
||||
this.control(this.keyMap[key])
|
||||
}
|
||||
})
|
||||
}
|
||||
this.ballIndexOpts = this.row.videoIndex.split(',').map((item) => {
|
||||
return {
|
||||
value: item,
|
||||
label: item,
|
||||
}
|
||||
})
|
||||
this.getQxToken()
|
||||
this.getQxInfo()
|
||||
this.init()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style lang="scss" scoped>
|
||||
.cell-player-1 {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.monitor-page {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
|
|
@ -386,7 +634,7 @@ export default {
|
|||
margin: 12px 0;
|
||||
}
|
||||
|
||||
.watermark-title{
|
||||
.watermark-title {
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
display: flex;
|
||||
|
|
@ -427,7 +675,7 @@ export default {
|
|||
.key {
|
||||
width: 21px;
|
||||
height: 21px;
|
||||
border: 0px solid #DCDFE6;
|
||||
border: 0px solid #dcdfe6;
|
||||
background: #f5f7fa;
|
||||
color: rgb(25, 190, 107);
|
||||
font-weight: bold;
|
||||
|
|
@ -436,7 +684,7 @@ export default {
|
|||
|
||||
.control-title {
|
||||
font-size: 14px;
|
||||
font-family: "微软雅黑 Bold", "微软雅黑 Regular", 微软雅黑, sans-serif;
|
||||
font-family: '微软雅黑 Bold', '微软雅黑 Regular', 微软雅黑, sans-serif;
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
color: rgb(102, 177, 255);
|
||||
|
|
@ -446,11 +694,11 @@ export default {
|
|||
padding: 8px 9px;
|
||||
}
|
||||
|
||||
.el-button [class^="el-icon-"] {
|
||||
.el-button [class^='el-icon-'] {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.column-label{
|
||||
.column-label {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
|
|
|||
Loading…
Reference in New Issue