feat:导览页搭建完成

wuyanfu
guangyin 2023-05-17 15:07:29 +08:00
parent f13a95d92d
commit e83e914347
13 changed files with 449 additions and 376 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

View File

@ -2780,6 +2780,7 @@ svg.loading-icon {
.tree-box{
width: 330px;
height: 300px;
padding: 14px;
background: rgba(0,0,0,0.5);
box-shadow: 0 10px 20px -10px #000000;
border-radius: 6px;
@ -2788,15 +2789,123 @@ svg.loading-icon {
}
.tree-line{
&.el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content{
background: rgba(125, 174, 255, 0.7);
}
&::before{
content: "";
height: 79%;
width: 1px;
position: absolute;
left: 23px;
top: 14px;
border-width: 1px;
border-left: 1px solid #ffffff;
}
& > div[role="treeitem"] {
padding-bottom: 10px;
}
.white{
color: #FFFFFF;
font-size: 14px;
}
.custom-tree-node{
position: relative;
left: 8px;
width: 100%;
.doc-style{
width: 5px;
height: 5px;
border-radius: 50%;
background-color: #FFFFFF;
position: absolute;
left: -11px;
}
}
.right-icon{
transition: all .3s linear;
position: relative;
left: -10px;
}
.sub-item{
padding-left: 16px;
&::before{
content: '';
width: 12px;
height: 20px;
position: absolute;
left: -3px;
top: 9px;
border-width: 1px;
//border-top: 1px solid #ffffff;
}
&::after{
content: "";
height: 130%;
width: 1px;
position: absolute;
left: -1px;
top: 0px;
border: none;
}
}
.is-expanded{
.sub-item{
padding-left: 8px;
&::before{
content: '';
width: 3px;
height: 20px;
position: absolute;
left: -3px;
top: 9px;
border-width: 1px;
//border-top: 1px solid #ffffff;
}
&::after{
content: "";
height: 100%;
width: 1px;
position: absolute;
left: -1px;
top: 10px;
border-width: 1px;
border-left: 1px solid #ffffff;
}
}
.sub-item-border-none{
&::after{
content: "";
height: 130%;
width: 1px;
position: absolute;
left: -1px;
top: 0px;
border: none;
}
}
}
div[role="treeitem"].is-expanded > div.el-tree-node__content > div > span:nth-child(2),
div[role="group"] div[role="treeitem"].is-expanded,
{
.right-icon{
transform: rotate(90deg);
transition: all .3s linear;
}
}
&.el-tree,.el-tree-node__content, .el-upload-list__item{
background: transparent;
&:hover,&:focus,&:active,&:visited{
background: transparent;
}
}
.el-tree-node:focus>.el-tree-node__content{
background: transparent;
}
.tree-level-1-icon{
width: 24px;
@ -2804,11 +2913,16 @@ svg.loading-icon {
background: #FFFFFF;
border-radius: 2px;
position: relative;
left: -4px;
left: -12px;
}
margin-top:10px;
.el-tree-node {
position: relative;
padding-left: 16px; //
color: black;
padding: 0;
padding-left: 10px; //
}
.el-tree-node__children {
padding-left: 16px; //
@ -2821,27 +2935,29 @@ svg.loading-icon {
width: 1px;
position: absolute;
left: -3px;
top: 0;
top: -13px;
border-width: 1px;
border-left: 1px solid #ffffff;
}
// 线
.el-tree-node:last-child::before {
height: 38px; //
height: 34px; //
}
// 线
.el-tree-node::after {
content: "";
width: 24px;
width: 27px;
//width: 16px;
height: 20px;
position: absolute;
left: -3px;
top: 12px;
top: 20px;
border-width: 1px;
border-top: 1px solid #ffffff;
}
border-top: 1px solid #ffffff;
content: "";
}
// 线
& > .el-tree-node::after {
border-top: none;
@ -2850,6 +2966,66 @@ svg.loading-icon {
border-left: none;
}
.el-tree-node__content{
padding-left:0 !important;
color:#444;
height: 40px;
//
.el-icon-caret-right::before{
content: "";
width:14px;
height:14px;
background-size: 100% 100%;
border-radius: 3px;
display: inline-block;
}
.el-tree-node__expand-icon.expanded{
transform: rotate(0);
}
//
.el-tree-node__expand-icon.expanded::before{
content: "";
width:0;
height:0;
background-size: 100% 100%;
border-radius: 3px;
display: inline-block;
}
.el-tree-node__expand-icon.is-leaf::before{
content: "";
}
.el-icon-caret-right.is-leaf::before{
content: "";
display: none;
}
.custom-tree-node .file_class{
color: #ffb400;
}
.custom-tree-node .label{
margin-left:5px;
}
.custom-tree-node .no_children{
color: #aaa;
}
}
// 使flexcustom-tree-node_body
.custom-tree-node_body{
width:100%;
display: flex;
justify-content: space-between;
// margin-top:-3px;
}
.tree_form_left_tree_icon{
padding:0 3px;
font-size:16px;
color:#666;
i{
margin:0 4px;
}
}
.tree_form_left_tree_icon:hover{
cursor: pointer;
}
// icon
.el-tree-node__expand-icon{
font-size: 16px;
@ -2862,3 +3038,89 @@ svg.loading-icon {
}
}
.view-list{
&-item{
width: 330px;
height: 186px;
border-radius: 8px;
background-color: #1B6BEB;
position: relative;
margin-bottom: 20px;
&:last-child{
margin-bottom: 0;
}
&-title{
position: absolute;
bottom: 0;
border-radius: 0 0 8px 8px;
background: rgba(0,0,0,0.7);
height: 34px;
line-height: 34px;
width: 100%;
}
.cover {
top: 0;
width: 100%;
height: 100%;
text-align: center;
position: absolute;
background-color: rgba(0, 0, 0, 0.5);
opacity: 0;
cursor: pointer;
}
/* 鼠标hover,显示遮罩,设置过渡时间 */
.cover:hover {
transition: all .4s;
opacity: 1;
}
}
}
.view-right-title{
font-size: 20px;
color: #FFFFFF;
padding: 20px 0;
border-bottom: 1px solid rgba(216,216,216,0.4);;
}
.sub-title{
font-size: 16px;
margin-bottom: 16px;
margin-top: 16px;
}
.text-con{
color: rgba(255, 255, 255, 0.6);
font-size: 14px;
}
.right-view-list{
height: 1px;
flex: 1;
overflow-y: auto;
@include scrollStyle(2px);
}
.right-view-item{
width: 350px;
height: 98px;
background: rgba(0,0,0,0.3);
border-radius: 8px;
border: 1px solid rgba(255,255,255,0.15);
padding-left: 3px;
margin-bottom: 10px;
cursor: pointer;
&:last-child{
margin-bottom: 0;
}
img{
margin-right: 12px;
}
p{
font-size: 16px;
padding: 0 0 10px 0;
}
.right-sub-text{
font-size: 12px;
}
.el-rate__icon{
margin-right: 0;
}
}

View File

@ -8,18 +8,14 @@
<span>查看更多</span>
<i class="el-icon-caret-right"></i>
</div>
<div class="manual" v-if="showManual" @click="addManual">
<div class="manual" v-if="showViewFlag" @click="showView">
<i class="el-icon-plus"></i>
<span>人工接警</span>
<span>自由导览</span>
</div>
<div class="close" v-if="showClose" @click="changeClose">
<!-- <span>关闭</span>-->
<i class="el-icon-close" title="关闭"></i>
</div>
<div class="close" v-if="showList" @click="showListData">
<span>缺失物资清单</span>
<i class="el-icon-caret-right" title="缺失物资清单"></i>
</div>
</div>
</div>
@ -36,9 +32,7 @@ export default class TitleComponent extends Vue {
//
@Prop({default: false}) showClose!: boolean;
//
@Prop({default: false}) showManual!: boolean;
//
@Prop({default: false}) showList!: boolean;
@Prop({default: false}) showViewFlag!: boolean;
@Emit()
changeMore(){
@ -48,13 +42,9 @@ export default class TitleComponent extends Vue {
changeClose(){
return this.showClose
}
@Emit('addManual')
addManual(){
return this.showManual
}
@Emit('showListData')
showListData(){
return this.showManual
@Emit('showView')
showView(){
return this.showView
}
}

View File

@ -9,43 +9,55 @@
class="tree-line"
:indent="0"
icon-class="none"
highlight-current
@node-click="nodeClick"
:data="treeData"
>
<div class="custom-tree-node" slot-scope="{ node, data }">
<span class="d-flex align-items-center">
<!-- 判断是否存在子级数据 -->
<div v-if="node.level === 1" class="tree-level-1-icon d-flex align-items-center is-justify-space-center">
<img src="~@/assets/img/home/training-devices-B.png" alt="">
</div>
<!-- 节点展开样式 -->
<i v-else-if="node.expanded" class="file_class font_family icon-file_open"></i>
<!-- 节点收缩样式 -->
<i v-else class="file_class font_family icon-file_close"></i>
<span class="white">{{ node.label }}</span>
</span>
<span>
<!-- <el-button
type="text"
v-if="!data.childSubjects || !data.childSubjects.length"
size="mini"
@click.stop="() => removeData(data)">
<i class="el-icon-delete"></i>
</el-button>
<el-button
type="text"
size="mini"
@click.stop="() => editData(data)">
<i class="el-icon-edit-outline"></i>
</el-button>-->
</span>
<div class="custom-tree-node d-flex is-justify-space-between align-items-center"
:class="getNodeClass(node)" slot-scope="{ node, data }">
<span class="d-flex align-items-center">
<!-- 判断是否存在子级数据 -->
<div v-if="node.level === 1"
class="tree-level-1-icon d-flex align-items-center is-justify-space-center">
<img src="~@/assets/img/home/training-devices-B.png" alt="">
</div>
<i class="doc-style" v-if="node.level > 1"></i>
<span class="white">{{ node.label }}</span>
</span>
<span class="d-flex align-items-center">
<img class="right-icon" v-show="node.level<3 " src="~@/assets/img/view/tree-icon.png" alt="">
</span>
</div>
</el-tree>
</div>
</div>
<div class="box-content margin-top-47">
<title-component :imgSrc="imgSrc">
告警列表
<div class="box-content margin-top-23">
<title-component :showViewFlag="true" @showView="showView" :imgSrc="imgSrc">
基地导览路线
</title-component>
<div class="view-list margin-top-23">
<div class="view-list-item">
<div @click="playView" class="cover d-flex align-items-center is-justify-space-center">
<img src="~@/assets/img/view/play.png" alt="">
</div>
<div class="view-list-item-title d-flex align-items-center is-justify-space-center">
<span>北大门东区</span>
<i class="el-icon-right"></i>
<span>南大门西区</span>
</div>
<img src="~@/assets/img/view/view.png" alt="">
</div>
<div class="view-list-item">
<div @click="playView" class="cover d-flex align-items-center is-justify-space-center">
<img src="~@/assets/img/view/play.png" alt="">
</div>
<div class="view-list-item-title d-flex align-items-center is-justify-space-center">
<span>北大门东区</span>
<i class="el-icon-right"></i>
<span>南大门西区</span>
</div>
<img src="~@/assets/img/view/view.png" alt="">
</div>
</div>
</div>
</div>

View File

@ -22,45 +22,63 @@ export default class ViewLeftComponent extends Vue {
//标题左侧图标
imgSrc = require("@/assets/icons/png/env/env-title-icon.png");
treeData = [{
label: '一级 1',
treeData = [
{
label: '技能训练设施',
children: []
}, {
label: '灾害事故处置训练设施',
children: [{
label: '二级 1-1',
children: []
label: '火灾扑救训练设',
children: [
{
label: '综合训练楼',
children: []
},{
label: '化工装置火灾事故处置训练设施',
children: []
}
]
}]
}, {
label: '一级 2',
children: [{
label: '二级 2-1',
children: []
}, {
label: '二级 2-2',
children: [{
label: '三级 2-2-1'
}]
}]
}, {
label: '一级 3',
children: [{
label: '二级 3-1',
children: [{
label: '三级 3-1-1'
}]
}, {
label: '二级 3-2',
children: [{
label: '三级 3-2-1'
}]
}]
label: '战勤保障训练设施',
children: []
}]
//获取class类
getNodeClass(node){
const arr:string[] = []
if (node.level>1){
arr.push('sub-item')
}
if (node.childNodes.length === 0 || !node.expanded){
arr.push('sub-item-border-none')
}
return arr
}
@Emit('showView')
showView(){
//todo 展开自由导览
}
//点击告警信息
@Emit()
getItem(item) {
// console.log('item', item)
}
//点击节点
nodeClick(data,node,self){
if (node.isLeaf){
this.showViewRight(node.data)
}
}
//显示右侧
@Emit('showViewRight')
showViewRight(item){
//
}
playView(){
console.log('导览')
}
count = 1

View File

@ -1,43 +1,32 @@
<div class="env-right emergency-part">
<div class="box-content">
<title-component :imgSrc="imgSrc">
能耗统计
</title-component>
<hbt-echarts className="line-chart-emergency" :options="option"
@onChartInit="getEcharts($event,'lineChart')"></hbt-echarts>
</div>
<div class="box-content flex-15 margin-top-20 device-box">
<title-component :imgSrc="imgSrc">
设备在线统计
</title-component>
<div class="energyRightTitle d-flex is-justify-space-between margin-top-23">
<div class="d-flex align-items-center">
<img src="~@/assets/img/home/security-equipment.png" alt="">
<span>安防设备</span>
</div>
<span>100<span class="grayColor">/300</span></span>
<div class="view-right-title flex-0">
化工装置火灾事故装置训练设施
</div>
<div class="energyRightTitle d-flex is-justify-space-between margin-top-10">
<div class="d-flex align-items-center">
<img src="~@/assets/img/home/training-devices.png" alt="">
<span>训练设备</span>
</div>
<span>100<span class="grayColor">/300</span></span>
<h3 class="sub-title flex-0">训练内容</h3>
<div class="text-con flex-0">
模拟在密闭建筑物内发生火灾,消防员在高温、浓烟、高噪音的情况下进行火情侦察,寻找被困人员,救出被困人员,灭火抢险等战斗
</div>
<div class="energyRightTitle d-flex is-justify-space-between margin-top-10">
<div class="d-flex align-items-center">
<img src="~@/assets/img/home/logistics.png" alt="">
<span>配套设备</span>
<h3 class="sub-title flex-0">训练内容</h3>
<div class="right-view-list">
<div class="right-view-item d-flex align-items-center" @click="showDetail(item)" v-for="(item,i) in tableData">
<img v-if="1%2 === 0" src="~@/assets/img/view/fire.png" alt="">
<img v-else src="~@/assets/img/view/fire2.png" alt="">
<div>
<p>{{item.title}}</p>
<div class="d-flex align-items-center right-sub-text">
<span>难度:</span>
<el-rate disabled v-model="item.rate" :max="5"></el-rate>
</div>
<div class="d-flex align-items-center right-sub-text">
<span>火点:</span>
<span>{{item.point}}个</span>
</div>
</div>
</div>
<span>100<span class="grayColor">/300</span></span>
</div>
</div>
<div class="box-content margin-top-20 emergency-part">
<title-component :imgSrc="imgSrc">
物资盘点
</title-component>
<hbt-echarts className="line-chart-emergency" :options="radarData"
@onChartInit="getEcharts($event,'radar')"></hbt-echarts>
</div>
</div>

View File

@ -17,274 +17,56 @@ Component.registerHooks([
},
})
export default class ViewRightComponent extends Vue {
//标题图片
imgSrc = require("@/assets/icons/png/env/env-title-icon.png");
//定时器
timer: any = null;
//折线图数据
option: any = {}
//折线图实例
lineChart: any = {}
//雷达图数据
radarData: any = {}
//折线图实例
radar: any = {}
showPop = false
showLogPop = false
popTitle = '开启演练'
popObj:any = {
popTitle:'报警记录',
type:'',
title: '风险点异常',
info: '',
time: '',
address:'',
level: '',
typeName:"",
reporter:"",
tel:"",
position:[],
content:"",
typeId:"",
plan:"",
linkPlan:"化工园区氢气泄露处理预案",
id:''
}
typeList =[
{
label:'气体泄露',
value:'normal',
level:2,
id:1
},{
label:'火灾爆炸',
value:'fire',
level:1,
id:2
},{
label:'气液泄露',
value:'normal',
level:1,
id:3
},{
label:'安全事故',
value:'normal',
level:2,
id:4
},{
label:'自然灾害',
value:'normal',
level:3,
id:5
},
]
levelList =[
{
label:'一级',
value:'1',
id:1
},{
label:'二级',
value:'2',
id:2
},{
label:'三级',
value:'3',
id:3
},{
label:'四级',
value:'4',
id:4
}
]
planList =[
{
label:'氢气泄露演练',
value:'氢气泄露演练',
id:1
},{
label:'氯气泄露演练',
value:'氯气泄露演练',
id:2
},{
label:'氯化氢泄露演练',
value:'氯化氢泄露演练',
id:3
},{
label:'二氧化硫泄露演练',
value:'二氧化硫泄露演练',
id:5
}
]
linkPlanList =[
{
label:'化工园区氢气泄露处理预案',
value:'化工园区氢气泄露处理预案',
id:1
}
]
tableData = [
{
type:'火灾爆炸',
content:'发生火灾',
alarm:'发生火灾',
reporter:'罗马',
address:'A号点位',
suggestion:'立即救援',
}, {
type:'火灾爆炸',
content:'发生火灾',
alarm:'发生火灾',
reporter:'罗马',
address:'A号点位',
suggestion:'立即救援',
}, {
type:'火灾爆炸',
content:'发生火灾',
alarm:'发生火灾',
reporter:'罗马',
address:'A号点位',
suggestion:'立即救援',
}, {
type:'火灾爆炸',
content:'发生火灾',
alarm:'发生火灾',
reporter:'罗马',
address:'A号点位',
suggestion:'立即救援',
}, {
type:'火灾爆炸',
content:'发生火灾',
alarm:'发生火灾',
reporter:'罗马',
address:'A号点位',
suggestion:'立即救援',
}, {
type:'火灾爆炸',
content:'发生火灾',
alarm:'发生火灾',
reporter:'罗马',
address:'A号点位',
suggestion:'立即救援',
rate:3,
title:'顶层沸溢火',
point:'5',
},{
type:'火灾爆炸',
content:'发生火灾',
alarm:'发生火灾',
reporter:'罗马',
address:'A号点位',
suggestion:'立即救援',
}, {
type:'火灾爆炸',
content:'发生火灾',
alarm:'发生火灾',
reporter:'罗马',
address:'A号点位',
suggestion:'立即救援',
}, {
type:'火灾爆炸',
content:'发生火灾',
alarm:'发生火灾',
reporter:'罗马',
address:'A号点位',
suggestion:'立即救援',
}, {
type:'火灾爆炸',
content:'发生火灾',
alarm:'发生火灾',
reporter:'罗马',
address:'A号点位',
suggestion:'立即救援',
}, {
type:'火灾爆炸',
content:'发生火灾',
alarm:'发生火灾',
reporter:'罗马',
address:'A号点位',
suggestion:'立即救援',
}, {
type:'火灾爆炸',
content:'发生火灾',
alarm:'发生火灾',
reporter:'罗马',
address:'A号点位',
suggestion:'立即救援',
rate:4,
title:'顶层沸溢火',
point:'5',
},{
rate:2,
title:'顶层沸溢火',
point:'5',
},{
rate:3,
title:'顶层沸溢火',
point:'5',
},{
rate:4,
title:'顶层沸溢火',
point:'5',
},{
rate:2,
title:'顶层沸溢火',
point:'5',
},
]
//获取图表实例
getEcharts(e, type) {
this[type] = e
if (type === 'lineChart'){
this.initLineData()
}else{
this.radarData = radarChartData()
}
}
setData(val,type){
if (type === 'typeName'){
const find = this.typeList.find(item=>item.id == val) as any
this.popObj.title = find.label
this.popObj.type = find.value
}
this.popObj[type] = val
}
//图表自适应
resize() {
setTimeout(() => {
this.lineChart.resize();
}, 300)
}
timerForLineData: any = null;
//自动切换line图表数据
autoChangeLineData() {
this.timerForLineData = setInterval(() => {
this.lineChart.clear()
this.lineChart.setOption(this.option)
}, 5000)
}
//获取范围内随机数
getRandomInt(min: number, max: number) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min; //不含最大值,含最小值
//训练内容详情
@Emit('showDetail')
showDetail(item){
//
}
mounted() {
this.autoChangeLineData()
window.addEventListener("resize", this.resize);
}
//初始化line图表
initLineData() {
this.option = lineChartData()
}
beforeDestroy() {
clearInterval(this.timer)
clearInterval(this.timerForLineData)
}
destroyed() {
window.removeEventListener("resize", this.resize)
}
//改变污染物监测颜色
changeColor(val) {
if (Number(val) <= 30) {
return '#ffffff'
} else if (Number(val) > 30 && Number(val) <= 50) {
return '#F2A183'
} else {
return '#DD7171'
}
}
}

View File

@ -7,16 +7,16 @@
<!-- 首页-->
<HomeLeftComponent v-if="currentNav === 'home'" class="animate__animated animate__fadeInLeft"></HomeLeftComponent>
<!-- 导览-->
<ViewLeftComponent v-if="currentNav === 'view'" class="animate__animated animate__fadeInLeft"></ViewLeftComponent>
<ViewLeftComponent @showView="showView" @showViewRight="showViewRight" v-if="currentNav === 'view'" class="animate__animated animate__fadeInLeft"></ViewLeftComponent>
</div>
</div>
<div class="bg-box right main animate__animated">
<div class="bg-box right main animate__animated" :class="showBackGround">
<div class="panel-container">
<!-- 首页-->
<HomeRightComponent v-if="currentNav === 'home'"
class="animate__animated animate__fadeInRight"></HomeRightComponent>
<!-- 导览-->
<ViewRightComponent v-if="currentNav === 'view' && viewRightShow" class="animate__animated animate__fadeInLeft"></ViewRightComponent>
<ViewRightComponent @showDetail="showDetail" v-if="currentNav === 'view' && viewRightShow" class="animate__animated animate__fadeInLeft"></ViewRightComponent>
</div>
</div>

View File

@ -137,12 +137,32 @@ export default class OverViewComponent extends BaseComponent {
}
layer.selected = !layer.selected;
}
//进入自由导览
showView(){
//todo 进入自由导览
}
//展开导览右侧
showViewRight(){
if (this.viewRightShow){
this.viewRightShow = false
setTimeout(()=>{
this.viewRightShow = true
})
}else{
this.viewRightShow = true
}
}
//右侧详情点击事件
showDetail(item){
console.log('右侧详情点击事件')
}
mounted() {
console.log(2)
}
get showBackGround(){
let flag = this.currentNav === 'view' && !this.viewRightShow
return flag?'none':''
}
public getCurrentLayers(){