nxdt-web/src/views/screen/components/video/TerminalInspection.vue

1011 lines
28 KiB
Vue

<!--
* @Author: zhangtq 2452618307@qq.com
* @Date: 2024-11-15 14:26:52
* @LastEditors: zhangtq 2452618307@qq.com
* @LastEditTime: 2025-01-20 18:30:16
* @FilePath: src/views/screen/components/video/TerminalInspection.vue
* @Description: 这是默认设置,可以在设置工具File Description中进行配置
-->
<template>
<div class="container">
<div class="left">
<div class="module_title"><span>云台控制</span></div>
<div class="controls">
<VideoControls :item="clickItem" v-on:capture="capture" />
</div>
<div class="list">
<div style="display: flex; flex-direction: row; padding: 10px 15px 0 15px">
<div style="width: 30%; color: white; font-weight: bold; font-size: 24px">设备列表</div>
<div style="display: flex; flex-direction: row; width: 70%">
<el-button :class="buttonClass(1)" type="text" @click="changeData(1)">智能布控球</el-button>
<el-button :class="buttonClass(2)" type="text" @click="changeData(2)">作业记录仪</el-button>
<el-button :class="buttonClass(3)" type="text" @click="changeData(3)">智能安全帽</el-button>
</div>
</div>
<div style="padding: 10px 15px 0 20px; display: flex; flex-direction: row">
<el-input placeholder="请输入内容" v-model="keyWord" clearable @clear="resetBtn" v-no-whitespace></el-input>
<el-button icon="el-icon-search" @click="searchBtn" class="searchButton"></el-button>
</div>
<VideoList
:data="data"
:get-image-src="getImageSrc(listType)"
:list-type="listType"
v-on:playVideo="playVideo"
@updataDeviceList="updataDeviceList"
/>
</div>
</div>
<div class="center">
<VideoPlay
ref="videoPlay"
:item="playItem"
v-on:playerClick="playerClick"
:video-num="numObj"
:log-btn-show="true"
/>
</div>
<div class="right">
<div class="module_title" @click="jumpToPhoto()" style="cursor: pointer"><span>抓拍照片</span></div>
<div class="photo-section">
<div class="photo-list">
<ul class="ul_list_photo">
<li v-for="(item, index) in photoList.slice(0, 20)" :key="index">
<div class="photo-item">
<!-- //TODO 上线修改成真实图片-->
<img :src="`${item.filePath ? lookFaceFile + item.filePath : ''}`" alt="" class="photo-img" />
<div class="photo-details">
<div class="photo-proName">
<el-tooltip
class="item"
effect="dark"
v-if="item.proName.length > 10"
:content="item.proName"
placement="bottom"
>
<div style="flex: 3; font-size: 17px; color: white">
{{ item.proName.length > 10 ? item.proName.substring(0, 10) + '...' : item.proName }}
</div>
</el-tooltip>
<div style="flex: 3; font-size: 17px; color: white" v-if="item.proName.length <= 10">
{{ item.proName }}
</div>
</div>
<div class="photo-time">{{ item.createTime }}</div>
<div class="photo-device">
<el-tooltip
class="item"
effect="dark"
v-if="item.deviceCode.length > 10"
:content="item.deviceCode"
placement="bottom"
>
<div style="flex: 3; font-size: 17px; color: white">
{{ item.deviceCode.length > 10 ? item.deviceCode.substring(0, 10) + '...' : item.deviceCode }}
</div>
</el-tooltip>
<div style="flex: 3; ont-size: 17px; color: white" v-if="item.deviceCode.length <= 10">
{{ item.deviceCode }}
</div>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
<el-dialog title="抓拍照片" :visible.sync="open" :destroy-on-close="true">
<div class="dialog_container">
<div style="width: 100%; background-color: rgb(5, 32, 75); display: flex; flex-direction: row">
<el-select
v-model="proId"
placeholder="请选择工程名称"
class="custom-select"
:popper-append-to-body="false"
clearable
>
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<div class="sift-main">
<el-date-picker
v-model="snapDate"
clearable
type="date"
:append-to-body="false"
popper-class="sift-data"
placeholder="选择日期"
></el-date-picker>
</div>
<el-button type="primary" @click="searchDialogBtn" style="background: #195875; border: 1px solid #195875">
查询
</el-button>
<el-button type="primary" @click="resetDialogBtn" style="background: #195875; border: 1px solid #195875">
重置
</el-button>
</div>
<div class="content_dialog">
<div style="display: flex; flex-wrap: wrap">
<div
style="width: 24%; height: 31vh; margin-left: 1vh; margin-top: 1vh; border-radius: 5px"
v-for="(item, index) in snapPhotoList"
:key="index"
>
<div
class="dialog_item"
:style="{ backgroundImage: `url(${item.filePath ? lookFaceFile + item.filePath : ''})` }"
@click="openPhoto(index)"
>
<!-- <div class="dialog_item" @click="openPhoto(index)">-->
<!-- // TODO 上线修改成真实图片-->
<img
:src="`${item.filePath ? lookFaceFile + item.filePath : ''}`"
alt=""
style="width: 100%; height: 18vh; visibility: hidden"
/>
<div style="display: flex; flex-direction: column; background: rgba(63, 167, 204, 0.26)">
<span style="font-size: 18px; margin-top: 5px; margin-left: 5px">
<el-tooltip
class="item"
effect="dark"
v-if="item.proName.length > 20"
:content="item.proName"
placement="bottom"
>
<div style="flex: 3; font-size: 17px; color: white">
{{ item.proName.length > 20 ? item.proName.substring(0, 20) + '...' : item.proName }}
</div>
</el-tooltip>
<div style="flex: 3; font-size: 17px; color: white" v-if="item.proName.length <= 20">
{{ item.proName }}
</div>
</span>
<span style="font-size: 16px; margin-top: 5px; margin-left: 5px">
<el-tooltip
class="item"
effect="dark"
v-if="item.reason.length > 20"
:content="item.reason"
placement="bottom"
>
<div style="flex: 3; font-size: 17px; color: white">
{{ item.reason.length > 20 ? item.reason.substring(0, 20) + '...' : item.reason }}
</div>
</el-tooltip>
<div style="flex: 3; ont-size: 17px; color: white" v-if="item.reason.length <= 20">
{{ item.reason }}
</div>
</span>
<div
style="
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
margin-top: 5px;
margin-left: 5px;
"
>
<span>{{ item.createTime }}</span>
<div style="height: 40px">
<el-button
v-if="item.isViolation == '0'"
type="text"
style="color: white; background: #054d80; padding: 10px"
@click.stop="changeViolationStatus(1, item.id)"
>
属于违章
</el-button>
<el-button
v-if="item.isViolation == '0'"
type="text"
style="color: white; background: #054d80; padding: 10px"
@click.stop="changeViolationStatus(2, item.id)"
>
不属于违章
</el-button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="page_dialog">
<el-pagination
background
:page-size="8"
:current-page="currentPage"
@current-change="handlePageChange"
:total="total"
layout="total, prev, pager, next"
:data="snapPhotoList"
></el-pagination>
</div>
</div>
</el-dialog>
<el-dialog :visible.sync="photoOpen" width="60%" style="height: 90%" :destroy-on-close="true">
<el-carousel :interval="5000" arrow="always" ref="carousel" :initial-index="initialIndex">
<el-carousel-item v-for="(item, index) in snapPhotoList" :key="index">
<!-- :src="`${item.filePath ? lookFaceFile+item.filePath : ''}`"-->
<img :src="`${item.filePath ? lookFaceFile + item.filePath : ''}`" style="height: 60vh; width: 100%" />
</el-carousel-item>
</el-carousel>
</el-dialog>
<el-dialog title="新增违章" :visible.sync="violationOpen" width="60%" style="height: 90%" :destroy-on-close="true">
<violationForm
:chang-cons="changCons"
:change-person="changePerson"
:change-pro="changePro"
:change-violation-type="changeViolationType"
:dialog-form="dialogForm"
:dialog-rules="dialogRules"
:leader-opts="leaderOpts"
:responsibility-contractor-opts="responsibilityContractorOpts"
:violation-pro-opts="violationProOpts"
:violation-type-opts="violationTypeOpts"
v-on:submitViolationForm="submitViolationForm"
/>
</el-dialog>
</div>
</template>
<script>
import { lookFaceFile as fetchLookFaceFile, parseTime } from '@/utils/bonus'
import VideoPlay from '@/views/screen/components/video/components/VideoPlay.vue'
import VideoControls from '@/views/screen/components/video/components/VideoControls.vue'
// import VideoList from '@/views/screen/components/video/components/VideoList.vue'
import VideoList from '@/views/screen/components/video/components/videoListNew.vue'
import {
getProData,
getProSelect,
getVideoList,
selectSnapPhoto,
selectSnapPhotoList,
updateViolationStatus,
} from '@/api/screen/screen'
import { revocationHiddenDanger } from '@/api/hiddenDangerManagement'
import {
addViolationInfo,
getConsByProIdSelect,
getPersonByConsIdSelect,
getTypeOfViolationSelect,
getUnderConstructionProSelect,
} from '@/api/violation/violation'
import ViolationForm from '@/views/screen/components/video/ViolationForm.vue'
export default {
components: { ViolationForm, VideoList, VideoControls, VideoPlay },
data() {
return {
keyWord: '',
localCapture: false,
photoOpen: false,
type: 1,
listType: '终端设备',
type_select: 'type_select',
type_normal: 'type_normal',
data: [],
playItem: {},
proId: '',
snapDate: '',
options: [],
currentPage: 1,
pageSize: 8,
snapPhotoList: [],
photoList: [],
total: 0,
open: false,
//点击的屏幕的数据
clickItem: {},
numObj: {
totalNum: 0,
onlineNum: 0,
offlineNum: 0,
},
lookFaceFile: '',
initialIndex: 0,
violationOpen: false,
dialogForm: {
proId: '',
consId: '',
personName: '',
violationType: '',
directorId: '',
violationTime: '',
violationContent: '',
violationPhoto: [],
},
dialogRules: {
proId: [{ required: true, message: '请选择违章工程', trigger: 'change' }],
consId: [{ required: true, message: '请选择责任承包商', trigger: 'change' }],
personName: [{ required: true, message: '请选择承包商负责人', trigger: 'blur' }],
violationType: [{ required: true, message: '请选择违章类型', trigger: 'change' }],
directorId: [{ required: true, message: '请选择负责人', trigger: 'change' }],
violationTime: [{ required: true, message: '请选择违章时间', trigger: 'blur' }],
violationContent: [{ required: true, message: '请填写违章依据', trigger: 'blur' }],
},
// 违章工程-下拉框
violationProOpts: [],
// 责任承包商-下拉框
responsibilityContractorOpts: [],
// 承包商负责人-下拉框
contractorLeaderOpts: [],
// 违章类型-下拉框
violationTypeOpts: [],
// 负责人-下拉框
leaderOpts: [],
}
},
updataDeviceList() {
this.fetchData()
},
mounted() {
this.lookFaceFile = fetchLookFaceFile()
this.fetchDatas()
setInterval(this.fetchDatas, 5 * 60 * 1000) // Fetch data every 20 seconds
},
methods: {
fetchLookFaceFile,
fetchDatas() {
this.getTerminalData({ deviceType: '终端设备', type: this.type })
this.getSnapPhotoList()
},
//获取终端设备数据
getTerminalData(params) {
getVideoList(params).then(res => {
this.data = res.data
if (res.data.length > 0) {
this.numObj.totalNum = res.data[0].totalNum
this.numObj.onlineNum = res.data[0].onlineNum
this.numObj.offlineNum = res.data[0].offlineNum
}
})
},
//设置图标样式
getImageSrc(type) {
switch (type) {
case '固定摄像头':
return require('../../../../assets/screen/video/video.png')
case '无人机':
return require('../../../../assets/screen/video/drone.png')
case '终端设备':
return require('../../../../assets/screen/video/device.png')
default:
return ''
}
},
//列表搜索
searchBtn() {
const param = {
keyWord: this.keyWord,
type: this.type,
}
this.getTerminalData({ deviceType: '终端设备', type: this.type, keyWord: this.keyWord })
},
//列表重置
resetBtn() {
this.keyWord = ''
this.getTerminalData({ deviceType: '终端设备', type: this.type, keyWord: this.keyWord })
},
searchDialogBtn() {
this.getSnapPhotoListDialog()
},
resetDialogBtn() {
this.proId = ''
this.snapDate = ''
this.getSnapPhotoListDialog()
},
buttonClass(index) {
return this.type === index ? 'type_select' : 'type_normal'
},
changeData(index) {
this.type = index
this.keyWord = ''
this.getTerminalData({ deviceType: '终端设备', type: this.type, keyWord: this.keyWord })
},
jumpToPhoto() {
this.open = true
this.getSnapPhotoListDialog()
this.getProjectSelect()
},
getProjectSelect() {
getProSelect().then(res => {
this.options = res.data
})
},
//获取违章数据
getSnapPhotoList() {
selectSnapPhoto({ type: 1 }).then(res => {
this.photoList = res.data
})
},
//获取违章数据
getSnapPhotoListDialog() {
const param = {
type: 2,
pageSize: this.pageSize,
pageNum: this.currentPage,
proId: this.proId,
snapDate: parseTime(this.snapDate, '{y}-{m}-{d}'),
}
console.log('param', param)
selectSnapPhotoList(param).then(res => {
console.log('res', res)
this.snapPhotoList = res.rows
this.total = res.total
})
},
handlePageChange(page) {
this.currentPage = page
this.getSnapPhotoListDialog()
},
//播放视频
playVideo(e) {
this.playItem = e
this.$refs.videoPlay.play(e)
},
playerClick(e) {
this.clickItem = e
},
capture(e) {
//调用组件内的方法
this.$refs.videoPlay.captureScreen(e)
},
openPhoto(index) {
try {
this.initialIndex = index
this.photoOpen = true
this.$refs.carousel.setActiveItem(index)
} catch (e) {}
},
changeViolationStatus(type, id) {
if (type === 1) {
//打开违章页面
this.$confirm('确认此张抓拍照片属于违章吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
// 撤回操作
this.getTypeOfViolationSelect()
this.getUnderConstructionProSelect()
this.dialogForm.violationPhoto = [
{
id: id,
name: '大屏抓拍照片_' + new Date().getTime() + '.jpg',
url: this.snapPhotoList.find(item => item.id === id).filePath,
fileName: '大屏抓拍照片_' + new Date().getTime() + '.jpg',
filePath: this.snapPhotoList.find(item => item.id === id).filePath,
},
]
this.violationOpen = true
})
} else {
//更新违章状态,不属于违章
this.$confirm('确认此张抓拍照片不属于违章吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
// 撤回操作
updateViolationStatus({ id: id, isViolation: 2 }).then(res => {
this.$message.success('更新成功')
this.getSnapPhotoListDialog()
})
})
}
},
getTypeOfViolationSelect() {
getTypeOfViolationSelect({ type: 2 }).then(response => {
this.violationTypeOpts = response.data
})
},
getUnderConstructionProSelect() {
getUnderConstructionProSelect({ type: 2 }).then(response => {
this.violationProOpts = response.data
})
},
getConsByProIdSelect(params) {
getConsByProIdSelect(params).then(response => {
this.responsibilityContractorOpts = response.data
})
},
getPersonByConsIdSelect(params) {
getPersonByConsIdSelect(params).then(response => {
this.leaderOpts = response.data
})
},
changePro(val) {
this.dialogForm.proName = this.violationProOpts.find(item => item.value === val).label
this.dialogForm.consId = ''
this.dialogForm.consName = ''
this.dialogForm.directorId = ''
this.dialogForm.directorName = ''
this.getConsByProIdSelect({ proId: val })
},
changCons(val) {
const selectedContractor = this.responsibilityContractorOpts.find(item => item.valueUuid === val)
this.dialogForm.consName = selectedContractor.label
this.dialogForm.personName = selectedContractor.name
this.dialogForm.personId = selectedContractor.userId
this.dialogForm.directorId = ''
this.dialogForm.directorName = ''
this.getPersonByConsIdSelect({ consUuid: val })
},
changePerson(val) {
this.dialogForm.directorName = this.leaderOpts.find(item => item.value === val).label
this.dialogForm.directorId = val
},
changeViolationType(val) {
this.dialogForm.violationTypeName = this.violationTypeOpts.find(item => item.value === val).label
this.dialogForm.violationType = val
},
submitViolationForm(e) {
this.$confirm('确认提交违章信息吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(() => {
this.addViolation(e)
this.violationOpen = false
})
.catch(() => {
this.$message({
type: 'info',
message: '已取消提交',
})
})
},
addViolation(e) {
const params = {
...e,
}
console.log('params', params)
addViolationInfo(params).then(res => {
this.getSnapPhotoListDialog()
this.$message.success('转违章成功')
})
},
},
}
</script>
<style scoped lang="scss">
.container {
width: 100%;
height: 99%;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
.left {
width: 20%;
height: 100%;
margin-top: 4vh;
display: flex;
flex-direction: column;
.controls {
width: 100%;
height: 35%;
}
.list {
width: 100%;
height: 65%;
display: flex;
flex-direction: column;
}
}
.center {
width: 60%;
height: 100%;
}
.right {
width: 20%;
height: 99%;
}
}
.controls {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.type_normal {
color: white;
font-size: 0.9rem;
}
.type_select {
color: rgb(75, 201, 234);
font-size: 0.9rem;
//下划线
text-decoration: underline;
}
// 改变input里的字体颜色
::v-deep input::-webkit-input-placeholder {
color: #8a8a8a;
font-size: 15px;
}
// 改变input框背景颜色
::v-deep .el-input__inner {
background-color: transparent !important;
border: 1px solid rgba(41, 78, 136, 0.8);
color: #ababab;
width: 97%;
}
// 改变input框背景颜色
::v-deep .el-textarea__inner {
background-color: transparent !important;
border: 1px solid rgba(41, 78, 136, 0.8);
color: #8d8c8c;
width: 97%;
}
::v-deep .searchButton {
background-color: transparent !important;
width: 70px;
border: 1px solid rgba(41, 78, 136, 0.8);
}
.photo-section {
display: flex;
flex-direction: column;
padding: 1vh 2vh 0 1.5vh;
.photo-header {
display: flex;
flex-direction: row;
height: 5%;
.photo-title {
width: 30%;
color: white;
font-weight: bold;
font-size: 24px;
}
.photo-actions {
display: flex;
flex-direction: row;
width: 70%;
justify-content: flex-end;
.photo-button {
color: rgb(75, 201, 234);
font-size: 1rem;
text-decoration: underline;
margin-right: 5%;
}
}
}
.photo-list {
height: 75vh;
margin-top: 4vh;
overflow: auto;
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* Internet Explorer 10+ */
.ul_list_photo {
padding: 0;
list-style: none;
.photo-item {
display: flex;
flex-direction: row;
padding: 3px;
.photo-img {
width: 12vh;
height: 9vh;
}
.photo-details {
display: flex;
flex-direction: column;
background: linear-gradient(to left, #1e3451, #24617c);
width: 22vh;
margin-left: 5px;
border-radius: 5px;
.photo-proName,
.photo-time,
.photo-device {
color: white;
margin-left: 10px;
margin-top: 0.8vh;
}
.photo-proName,
.photo-device {
font-size: 1rem;
}
.photo-time {
font-size: 0.8rem;
}
}
}
}
}
}
.photo-list::-webkit-scrollbar {
display: none; /* Safari and Chrome */
}
::v-deep .el-dialog {
background: rgb(5, 32, 75);
width: 90%;
height: 90%;
}
//rgb(5, 32, 75)
//弹框头部
::v-deep .el-dialog__header {
--el-text-color-primary: #1effff;
--el-text-color-regular: #fff;
padding: 0 !important;
width: 100%;
height: 64px;
}
//弹框标题
::v-deep .el-dialog__title {
margin-left: 24px;
line-height: 64px;
color: whitesmoke;
}
//弹框内容部分
::v-deep .el-dialog__body {
--el-bg-color: #000741 !important;
--el-text-color-regular: #fff;
color: whitesmoke;
}
::v-deep .el-select,
::v-deep .el-input,
::v-deep .el-input__inner {
background: rgb(5, 32, 75);
color: #fff;
border-radius: 5px;
}
//el-input聚焦的时候 外层的border会有一个样式
::v-deep .el-select .el-input.is-focus .el-input__inner {
border: 0;
}
//修改的是el-input上下的小图标的颜色
::v-deep .el-select .el-input .el-select__caret {
color: rgba(174, 197, 234, 0.8);
}
//修改总体选项的样式 最外层
::v-deep .el-select-dropdown {
background: rgba(21, 43, 94, 0.3);
margin: 0px;
border: 0px;
border-radius: 0px;
left: 0px !important;
}
::v-deep .el-select-dropdown.el-popper {
min-width: 215px;
transform-origin: center top;
z-index: 2009;
position: absolute !important;
}
//修改单个的选项的样式
::v-deep .el-select-dropdown__item {
background-color: rgb(5, 32, 75, 0.8);
color: #fff;
}
//item选项的hover样式
::v-deep .el-select-dropdown__item.hover,
::v-deep .el-select-dropdown__item:hover {
color: rgb(212, 215, 220);
background-color: #146193;
}
//修改的是下拉框选项内容上方的尖角
::v-deep .el-popper .popper__arrow,
.el-popper .popper__arrow::after {
display: none;
}
/**
* 分页样式
*/
.el-pagination {
float: right;
margin-top: 2vh;
::v-deep .btn-prev,
::v-deep .btn-next {
border: 1px solid #278996;
background-color: transparent;
width: 40px;
height: 40px;
margin-right: 15px;
}
::v-deep .el-icon-arrow-left:before,
::v-deep .el-icon-arrow-right:before {
color: whitesmoke;
font-size: 20px;
}
}
::v-deep .el-pagination.is-background .el-pager li {
border: 1px solid #278996;
background-color: transparent;
color: whitesmoke;
width: 50px;
height: 40px;
line-height: 37px;
font-size: 20px;
margin-right: 15px;
}
::v-deep .el-pagination__total {
font-size: 20px !important;
color: white;
line-height: 28px;
margin-top: 5px;
}
.content_dialog {
height: 66vh;
margin-top: 1vh;
}
.module_title {
position: absolute;
top: 0.5vh;
background: url('../../../../assets/screen/video/title.png') no-repeat;
background-size: 100% 100%;
color: white;
font-size: 1.1rem;
font-weight: bold;
width: 19.5%;
min-height: 35px;
span {
margin-left: 4rem;
}
}
.dialog_item {
display: flex;
flex-direction: column;
background-size: 100% 100%;
border-radius: 5px;
}
::v-deep .el-carousel__container {
position: relative;
height: 65vh !important;
}
/**
* 日历样式
*/
.sift-main {
//年、月、日的日历面板样式
::v-deep.sift-data {
background: rgb(5, 32, 75, 0.9);
//日历面板头部区域的样式
.el-date-picker__header {
background: unset;
}
// 头部lanble的样式,如(2024年3月)
.el-date-picker__header-label {
color: #fff;
}
// 切换日历的按钮样式
.el-picker-panel__icon-btn {
color: #fff;
}
// 周一二三四五的样式
.el-date-table th {
color: #fff;
}
/* 切换到年时 */
//除头部的日历模块区域样式 当type=date点击label的年或者月时的样式
.el-year-table,
.el-month-table {
background: unset;
//头部显示范围内的年的模块的样式
.available {
background: unset;
// 里面的文字的样式
a {
color: #1890ff;
}
}
//今年
.today {
a {
color: #fff;
}
}
//选中的年
.current {
background: unset;
border-radius: unset;
a {
color: yellow;
}
}
}
/* 当type=date点击label 日 的样式 */
// 非本月的区域样式
.prev-month,
.next-month {
background: unset;
color: #8c8c8c;
}
//当月的显示区域样式
.available {
// background: blue;
color: whitesmoke;
}
.current {
// color: green;
// background: yellow;
div {
span {
background: yellow;
color: #000;
}
}
}
.today {
div {
span {
background: #1890ff;
color: #fff;
}
}
}
}
}
::v-deep .el-badge__content.is-dot {
height: 15px !important;
width: 15px !important;
padding: 0;
right: 0;
border-radius: 50%;
}
</style>