<template>
|
<div>
|
<HeaderBox />
|
<div
|
id="container"
|
style="width: 1920px; height: 995px; background-color: #001635"
|
></div>
|
<!-- 类型切换tab -->
|
<div
|
class="flex a-center absolute postion-center top--109 br--16 c-fff fs--14 bgcolor4 SSHR"
|
>
|
<div @click="changeTab(1)" class="lh--32 px--20 cursor-pointer z-10">
|
在建工程
|
</div>
|
<div @click="changeTab(2)" class="lh--32 px--20 cursor-pointer z-10">
|
固定资产
|
</div>
|
<div class="activeBox" :class="activeTab == 2 && 'activeBox2'">
|
占位盒子
|
</div>
|
</div>
|
<!-- 左下角隐患 -->
|
<div
|
v-if="
|
(activeTab == 1 && permissionClient.includes('4')) ||
|
(activeTab == 1 && permissionClient.includes('6'))
|
"
|
class="flex a-center absolute left--14 bottom--14"
|
>
|
<img
|
src="../../assets/img/home/Group@2x (4).png"
|
class="w--110 h--110 mr--9 shrink0"
|
/>
|
<div @click="toHiddenDanger" class="bgimg4 pt--10 c-fff cursor-pointer">
|
<div class="flex a-center ml--14">
|
<div class="ripple">
|
<div class="ripple-wave wave-1"></div>
|
<div class="ripple-wave wave-2"></div>
|
<div class="ripple-wave wave-3"></div>
|
</div>
|
<div class="fs--15 lh--15 ml--25">重大隐患数</div>
|
<div class="color5 ml--13 fs--30 lh--30 zh_tr">
|
{{ screenData.majorHazardTotal }}
|
</div>
|
</div>
|
<div class="flex a-center j-center gap--52 mt--11">
|
<div class="flex a-center">
|
<div class="fs--14 lh--14 ml--10">未整改</div>
|
<div class="color6 ml--13 fs--20 lh--24 zh_tr">
|
{{ screenData.unrectifiedHazardCount }}
|
</div>
|
</div>
|
<div class="flex a-center">
|
<div class="fs--14 lh--14 ml--10">已整改</div>
|
<div class="color7 ml--13 fs--20 lh--24 zh_tr">
|
{{ screenData.rectifiedHazardCount }}
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
<!-- 地图legend -->
|
<div
|
class="fixed bottom--30 h--120 w--250 py--29 px--37 bgimg5"
|
style="right: 505px"
|
>
|
<div
|
v-if="activeTab == 1"
|
class="flex a-center j-between fs--12 SHSR c-fff"
|
>
|
<div
|
class="flex a-center gap--14 cursor-pointer"
|
@click="toggleCategory('municipal')"
|
>
|
<img
|
v-if="categoryFilter.municipal"
|
src="../../assets/img/home/Combined Shape@2x.png"
|
class="w--16 h--16 shrink0"
|
/>
|
<img
|
v-else
|
src="../../assets/img/home/11Combined Shape@2x.png"
|
class="w--16 h--16 shrink0"
|
/>
|
<div :class="!categoryFilter.municipal && 'gray-text'">市政</div>
|
</div>
|
<div
|
class="flex a-center gap--14 cursor-pointer"
|
@click="toggleCategory('house')"
|
>
|
<img
|
v-if="categoryFilter.house"
|
src="../../assets/img/home/Shape@2x (4).png"
|
class="w--18 h--16 shrink0"
|
/>
|
<img
|
v-else
|
src="../../assets/img/home/11Shape@2x.png"
|
class="w--18 h--16 shrink0"
|
/>
|
<div :class="!categoryFilter.house && 'gray-text'">房建</div>
|
</div>
|
</div>
|
<div v-else class="flex a-center j-center fs--12 SHSR c-fff">
|
<div
|
class="flex a-center gap--14 cursor-pointer"
|
@click="toggleCategory('assets')"
|
>
|
<img
|
v-if="categoryFilter.assets"
|
src="../../assets/img/home/assets.png"
|
class="w--18 h--16 shrink0"
|
/>
|
<img
|
v-else
|
src="../../assets/img/home/znull.png"
|
class="w--18 h--16 shrink0"
|
/>
|
<div :class="!categoryFilter.assets && 'gray-text'">资产</div>
|
</div>
|
</div>
|
<div class="flex a-center j-between gap--23 px--13 fs--12 SHSR mt--26">
|
<div
|
class="flex a-center flex-column cursor-pointer"
|
@click="toggleLevel('A')"
|
>
|
<div
|
class="w--8 h--8 mb--5 br50"
|
:class="levelFilter.A ? 'bgcolor8' : 'gray-bg'"
|
></div>
|
<div :class="levelFilter.A ? 'color8' : 'gray-text'">A类</div>
|
</div>
|
<div
|
class="flex a-center flex-column cursor-pointer"
|
@click="toggleLevel('C')"
|
>
|
<div
|
class="w--8 h--8 mb--5 br50"
|
:class="levelFilter.C ? 'bgcolor10' : 'gray-bg'"
|
></div>
|
<div :class="levelFilter.C ? 'color10' : 'gray-text'">B类</div>
|
</div>
|
<div
|
class="flex a-center flex-column cursor-pointer"
|
@click="toggleLevel('B')"
|
>
|
<div
|
class="w--8 h--8 mb--5 br50"
|
:class="levelFilter.B ? 'bgcolor9' : 'gray-bg'"
|
></div>
|
<div :class="levelFilter.B ? 'color9' : 'gray-text'">C类</div>
|
</div>
|
</div>
|
</div>
|
<div class="leftBox">
|
<div
|
@click="handleClick"
|
class="flex a-center j-between w100 h--40 relative bgcolor1 picker"
|
>
|
<el-date-picker
|
v-model="dateRange"
|
ref="datePicker"
|
type="daterange"
|
range-separator=""
|
start-placeholder=""
|
end-placeholder=""
|
>
|
</el-date-picker>
|
<div class="absolute w100 h100 flex a-center px--20">
|
<div
|
class="flex a-center c-fff fs--14 SHS"
|
style="width: calc(100% - 20px)"
|
>
|
{{ dateTxt }}
|
</div>
|
<div class="flex a-center gap--5">
|
<i
|
@click.stop="dateRange = []"
|
class="el-icon-circle-close c-fff cursor-pointer"
|
v-show="dateTxt"
|
/>
|
<img
|
src="../../assets/img/home/Shape@2x (6).png"
|
class="w--13 h--13 shrink0"
|
/>
|
</div>
|
</div>
|
</div>
|
<div
|
class="flex a-center j-between w100 pl--20 mt--13 h--40 relative bgcolor1 searchBox"
|
>
|
<el-select filterable v-model="projectId" placeholder="请输入项目名称">
|
<el-option
|
v-for="item in projectList"
|
:key="item.id"
|
:label="item.name"
|
:value="item.id"
|
>
|
</el-option>
|
</el-select>
|
<div
|
class="flex a-center gap--5 absolute"
|
style="top: -2px; right: -2px"
|
>
|
<i
|
@click.stop="projectId = null"
|
class="el-icon-circle-close c-fff cursor-pointer"
|
v-show="projectId"
|
/>
|
<div class="btn" @click="handleSearch">搜索</div>
|
</div>
|
</div>
|
<div
|
v-if="
|
(activeTab == 1 && permissionClient.includes('2')) ||
|
(activeTab == 1 && permissionClient.includes('5'))
|
"
|
class="mt--33 relative"
|
>
|
<TitleBox>
|
<template #title> 项目数据总览 </template>
|
<template #content>
|
<div class="flex j-center px--20 mt--17 pb--16">
|
<div
|
@click="toPorjectList"
|
class="flex flex-column a-center mt--17 cursor-pointer"
|
>
|
<div class="bgImg1 flex a-center flex-column j-end">
|
<div class="mb--23 c-fff SHSBold lh--18 fs--18 txts1">
|
项目总数
|
</div>
|
</div>
|
<div
|
class="color1 fs--34 lh--39 txts2 ff54-"
|
style="margin-top: -20px"
|
>
|
{{ screenData.projectTotal }}
|
</div>
|
</div>
|
<div class="ml--18" v-if="activeTab == 1">
|
<div
|
@click="toPorjectList"
|
class="flex a-center pl--11 pr--13 py--6 bgimg2 cursor-pointer thisBox relative"
|
>
|
<div class="c-fff fs--14 SHSR mr--29 lh--14 shrink0">
|
本月检查情况
|
</div>
|
<img
|
src="../../assets/img/home/Shape@2x.png"
|
class="w--14 h--14 shrink0"
|
/>
|
<div
|
@click="toPorjectList"
|
class="hoverBox pt--20 px--20 pb--26"
|
>
|
<div class="c-fff SHSBold fs--15 lh--15">本月检查情况</div>
|
<div class="flex a-center j-between mt--20">
|
<div class="px--13 py--13 bsh1" style="min-width: 150px">
|
<div class="c-fff fs---14 lh--14 SHSH">已检查数:</div>
|
<div class="fs--45 lh--45 ff54- color8">
|
{{ screenData.inspectedCount }}
|
</div>
|
<div class="mt--20 c-fff SHSR fs--13 lh--25">
|
<div>
|
房建:{{ screenData.inspectedHousingCount }}
|
</div>
|
<div>
|
市政:{{ screenData.inspectedMunicipalCount }}
|
</div>
|
</div>
|
</div>
|
<div class="px--13 py--13 bsh2" style="min-width: 150px">
|
<div class="c-fff fs---14 lh--14 SHSH">未检查数:</div>
|
<div class="fs--45 lh--45 ff54- color6">
|
{{ screenData.uninspectedCount }}
|
</div>
|
<div class="mt--20 c-fff SHSR fs--13 lh--25">
|
<div>
|
房建:{{ screenData.uninspectedHousingCount }}
|
</div>
|
<div>
|
市政:{{ screenData.uninspectedMunicipalCount }}
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
<div class="mt--13 flex bgcolor2 pl--9 pb--5 pt--4 pr--10">
|
<div class="flex flex1 mt--7 shrink0">
|
<img
|
src="../../assets/img/home/Shape@2x (5).png"
|
class="w--31 h--30 shrink0"
|
/>
|
<div class="ml--7 SHSR shrink0">
|
<div class="color2 fs--14 lh--14">房建</div>
|
<div
|
v-if="!dateRange.length"
|
class="mt--9 fs--8 lh--8 color3"
|
>
|
本月检查覆盖率
|
</div>
|
</div>
|
</div>
|
<div class="ml--11 txt-center">
|
<div class="c-fff fs--22 lh--22 SHSBold">
|
{{ screenData.housingProjectCount }}
|
</div>
|
<div
|
v-if="!dateRange.length"
|
class="mt--9 fs--10 lh--12 color4 SHSM"
|
>
|
{{ screenData.housingInspectionCoverage }}%
|
</div>
|
</div>
|
</div>
|
<div class="mt--10 flex bgcolor2 pl--9 pb--5 pt--4 pr--10">
|
<div class="flex flex1 mt--7 shrink0">
|
<img
|
src="../../assets/img/home/Combined Shape@2x (4).png"
|
class="w--30 h--30 shrink0"
|
/>
|
<div class="ml--7 SHSR shrink0">
|
<div class="color2 fs--14 lh--14">市政</div>
|
<div
|
v-if="!dateRange.length"
|
class="mt--9 fs--8 lh--8 color3"
|
>
|
本月检查覆盖率
|
</div>
|
</div>
|
</div>
|
<div class="ml--11 txt-center">
|
<div class="c-fff fs--22 lh--22 SHSBold">
|
{{ screenData.municipalInspectionCoverage }}
|
</div>
|
<div
|
v-if="!dateRange.length"
|
class="mt--9 fs--10 lh--12 color4 SHSM"
|
>
|
{{ screenData.municipalInspectionCoverage }}%
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</template>
|
</TitleBox>
|
</div>
|
<div
|
class="mt--25"
|
v-if="activeTab == 1 && permissionClient.includes('3')"
|
>
|
<TitleBox>
|
<template #title> 设备数据总览 </template>
|
<template #content>
|
<div class="flex j-end mt--8 mr--18">
|
<div
|
@click="toEquipmentList"
|
class="flex a-center pl--11 pr--13 py--6 bgimg2 cursor-pointer thisBox relative"
|
>
|
<div class="c-fff fs--14 SHSR mr--29 lh--14 shrink0">
|
本月检查情况
|
</div>
|
<img
|
src="../../assets/img/home/Shape@2x.png"
|
class="w--14 h--14 shrink0"
|
/>
|
<div
|
@click="toEquipmentList"
|
class="hoverBox pt--20 px--20 pb--26"
|
>
|
<div class="c-fff SHSBold fs--15 lh--15">本月检查情况</div>
|
<div class="flex a-center j-between mt--20">
|
<div class="px--13 py--13 bsh1" style="min-width: 150px">
|
<div class="c-fff fs---14 lh--14 SHSH">已检查数:</div>
|
<div class="fs--45 lh--45 ff54- color8">
|
{{ screenData.inspectedMachineryTotal }}
|
</div>
|
<div class="mt--20 h--50 oa">
|
<div
|
v-for="(
|
item, index
|
) in screenData.machineryStatistics"
|
:key="index"
|
class="c-fff SHSR fs--13 lh--25"
|
>
|
<div>{{ item.name }}:{{ item.inspectedCount }}</div>
|
</div>
|
</div>
|
</div>
|
<div class="px--13 py--13 bsh2" style="min-width: 150px">
|
<div class="c-fff fs---14 lh--14 SHSH">未检查数:</div>
|
<div class="fs--45 lh--45 ff54- color6">
|
{{ screenData.uninspectedMachineryTotal }}
|
</div>
|
<div class="mt--20 h--50 oa">
|
<div
|
v-for="(
|
item, index
|
) in screenData.machineryStatistics"
|
:key="index"
|
class="c-fff SHSR fs--13 lh--25"
|
>
|
<div>
|
{{ item.name }}:{{ item.uninspectedCount }}
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
<div
|
@click="toEquipmentList"
|
class="flex a-center j-center gap--40 mt--14 mx--20 br--10 py--14 bgcolor3 cursor-pointer"
|
>
|
<img
|
src="../../assets/img/home/15@2x.png"
|
class="w--72 h--77 shrink0"
|
/>
|
<div>
|
<div class="fs--34 lh--39 color1 txts2 ff54-">
|
{{ screenData.machineryTotal }}
|
</div>
|
<div class="c-fff fs--16 lh--16 SHSBold mt--10">
|
大型机械设备数
|
</div>
|
</div>
|
</div>
|
<div class="mt--14 mx--20 pb--10 rowItem h--250 oa">
|
<div
|
@click="toEquipmentList"
|
v-for="(item, index) in screenData.machineryStatistics"
|
:key="index"
|
class="cursor-pointer"
|
>
|
<div class="bgimg3">
|
<div class="c-fff fs--22 lh--33 SHSBold txt-center">
|
{{ item.total }}
|
</div>
|
</div>
|
<div class="fs--12 lh--12 color5 nameTxt">{{ item.name }}</div>
|
</div>
|
</div>
|
</template>
|
</TitleBox>
|
</div>
|
</div>
|
<div class="rightBox">
|
<div class="mt--33" v-if="permissionClient.includes('7')">
|
<TitleBox>
|
<template #title> 事故简讯 </template>
|
<template #right>
|
<div class="flex a-center gap--10">
|
<div class="flex a-center searchTabs">
|
<div
|
@click="handleTabClick(item)"
|
v-for="item in searchTabs"
|
:key="item"
|
:class="{ activeTabs: item === activeTabs }"
|
>
|
{{ item }}
|
</div>
|
</div>
|
<div
|
@click="toAccidentCaseList"
|
class="flex a-center py--6 pl--10 pr--8 br--4 bgcolor5 cursor-pointer"
|
>
|
<div class="fs--12 lh--12 c-fff mr--4 SHSR">详情</div>
|
<img
|
src="../../assets/img/home/13@2x.png"
|
class="w--14 h--14 shrink0"
|
/>
|
</div>
|
</div>
|
</template>
|
<template #content>
|
<div
|
ref="scrollContainer"
|
class="scroll-container"
|
style="height: 408px"
|
@mouseenter="handleMouseEnter"
|
@mouseleave="handleMouseLeave"
|
@wheel="handleWheel"
|
>
|
<div>
|
<div
|
@click="toAccidentCaseDetail(item)"
|
v-for="(item, index) in scrollData"
|
:key="`${item.id}-${index}`"
|
:class="(index + 1) % 2 === 0 ? 'bgcolor7' : ''"
|
class="relative py--20 pl--20 pr--32 c-fff"
|
>
|
<div
|
class="absolute lh--20 fs--12 SHSBold bgcolor6 px--6 top0 right0"
|
>
|
{{ item.classifyName }}
|
</div>
|
<div class="fs--16 lh--16 SHSBold">
|
{{ item.title }}
|
</div>
|
<div class="flex a-center mt--14">
|
<img
|
src="../../assets/img/home/Shape@2x (2).png"
|
class="w--8 h--10 shrink0 mr--7"
|
/>
|
<div class="SHSN fs--12 lh--12">
|
{{ item.province + item.city + item.area }}
|
</div>
|
</div>
|
<div class="flex a-center j-between mt--8 pr--76">
|
<div class="flex a-center">
|
<img
|
src="../../assets/img/home/Shape@2x (3).png"
|
class="w--10 h--9 shrink0 mr--7"
|
/>
|
<div class="SHSN fs--12 lh--12">{{ item.time }}</div>
|
</div>
|
<div class="flex a-center">
|
<img
|
src="../../assets/img/home/Shape@2x (1).png"
|
class="w--9 h--10 shrink0 mr--7"
|
/>
|
<div class="SHSN fs--12 lh--12">
|
伤亡:造成
|
<span class="SHSBold fs--12">{{
|
item.casualties
|
}}</span>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</template>
|
</TitleBox>
|
</div>
|
<div class="mt--33" v-if="permissionClient.includes('8')">
|
<TitleBox>
|
<template #title> 工作展示 </template>
|
<template #right>
|
<div
|
@click="toWorkList"
|
class="flex a-center py--6 pl--10 pr--8 br--4 bgcolor5 cursor-pointer"
|
>
|
<div class="fs--12 lh--12 c-fff mr--4 SHSR">详情</div>
|
<img
|
src="../../assets/img/home/13@2x.png"
|
class="w--14 h--14 shrink0"
|
/>
|
</div>
|
</template>
|
<template #content>
|
<div class="px--19 pt--5 pb--9">
|
<el-carousel
|
height="366px"
|
indicator-position="none"
|
:interval="5000"
|
arrow="never"
|
ref="carousel"
|
@change="handleChangeCarousel"
|
>
|
<el-carousel-item v-for="item in workListData" :key="item.id">
|
<div @click="toWorkDetail(item)" class="cursor-pointer">
|
<img :src="item.img.split(',')[0]" class="w100 h--290" />
|
<div
|
class="fs--18 lh--24 SHSBold py--10 pl--20 pr--14 c-fff"
|
>
|
{{ item.title }}
|
</div>
|
</div>
|
</el-carousel-item>
|
</el-carousel>
|
<div class="flex a-center justify-center mt--9">
|
<div class="flex a-center gap--3">
|
<img
|
v-for="(item, index) in workListData"
|
:key="item.id"
|
:src="
|
activeIndex === index
|
? require('../../assets/img/home/Rectangle@2x.png')
|
: require('../../assets/img/home/Rectangle@2x (1).png')
|
"
|
class="w--18 h--4 shrink0 cursor-pointer"
|
@click="changeActiveIndex(index)"
|
/>
|
</div>
|
</div>
|
</div>
|
</template>
|
</TitleBox>
|
</div>
|
</div>
|
<!-- 自定义悬浮窗 -->
|
<div
|
v-if="tooltipVisible"
|
class="map-tooltip-wrapper"
|
:style="{ left: tooltipPos.left + 'px', top: tooltipPos.top + 'px' }"
|
>
|
<div class="custom-tooltip">
|
<div v-if="tooltipLoading" class="loading">
|
<i class="el-icon-loading"></i> 数据加载中...
|
</div>
|
<div v-else-if="tooltipError" class="error">数据加载失败</div>
|
<div v-else>
|
<div class="title">{{ tooltipData.name || "-" }}</div>
|
<div class="row">
|
<span class="label">项目地址:</span>
|
<span class="value">{{ tooltipData.address || "-" }}</span>
|
</div>
|
<div class="flex gap--20">
|
<div class="row">
|
<span class="label">施工单位:</span>
|
<span class="value">
|
{{ tooltipData.constructionCompanyInfo.name || "-" }}
|
</span>
|
</div>
|
<div class="row">
|
<span class="label">项目经理:</span>
|
<span class="value">
|
{{ tooltipData.constructionCompanyInfo.leader || "-" }}
|
</span>
|
</div>
|
</div>
|
<div class="flex gap--20">
|
<div class="row">
|
<span class="label">监理单位:</span>
|
<span class="value">
|
{{ tooltipData.supervisorCompanyInfo.name || "-" }}
|
</span>
|
</div>
|
<div class="row">
|
<span class="label">总监:</span>
|
<span class="value">
|
{{ tooltipData.supervisorCompanyInfo.leader || "-" }}
|
</span>
|
</div>
|
</div>
|
<div class="flex gap--20">
|
<div class="row">
|
<span class="label">建设单位:</span>
|
<span class="value">
|
{{ tooltipData.developmentCompanyInfo.name || "-" }}
|
</span>
|
</div>
|
<div class="row">
|
<span class="label">项目负责人:</span>
|
<span class="value">
|
{{ tooltipData.developmentCompanyInfo.leader || "-" }}
|
</span>
|
</div>
|
</div>
|
<div class="flex gap--20">
|
<div class="row">
|
<span class="label">建设单位:</span>
|
<span class="value">
|
{{ tooltipData.developmentCompanyInfo.name || "-" }}
|
</span>
|
</div>
|
<div class="row">
|
<span class="label">项目负责人:</span>
|
<span class="value">
|
{{ tooltipData.developmentCompanyInfo.leader || "-" }}
|
</span>
|
</div>
|
</div>
|
<div
|
class="flex gap--20"
|
v-for="(item, index) in tooltipData.properties"
|
:key="index"
|
>
|
<div class="row">
|
<span class="label">设备租赁单位:</span>
|
<span class="value">
|
{{ JSON.parse(item)["工程起重机械租赁单位"] || "-" }}
|
</span>
|
</div>
|
<div class="row">
|
<span class="label">联系人:</span>
|
<span class="value">
|
{{ JSON.parse(item)["联系电话"] || "-" }}
|
</span>
|
</div>
|
</div>
|
<div
|
class="flex flex-warp gap--20"
|
v-for="(item, index) in tooltipData.deviceCountVos"
|
:key="index"
|
>
|
<div class="row">
|
<span class="label">{{ item.name }}:</span>
|
<span class="value">
|
{{ item.count || 0 }}
|
</span>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
import HeaderBox from "../header/index.vue";
|
import moment from "moment";
|
import s1 from "../../assets/img/home/s1.png";
|
import s2 from "../../assets/img/home/s2.png";
|
import s3 from "../../assets/img/home/s3.png";
|
import f1 from "../../assets/img/home/f1.png";
|
import f2 from "../../assets/img/home/f2.png";
|
import f3 from "../../assets/img/home/f3.png";
|
import z1 from "../../assets/img/home/assets1.png";
|
import z2 from "../../assets/img/home/assets2.png";
|
import z3 from "../../assets/img/home/assets3.png";
|
import s4 from "../../assets/img/home/s4.png";
|
import f4 from "../../assets/img/home/f4.png";
|
import z4 from "../../assets/img/home/z4.png";
|
import {
|
getStatistics,
|
getStoryList,
|
getProjectSelect,
|
getWorkPresentationList,
|
getprojectTooltip,
|
} from "./service";
|
|
export default {
|
components: {
|
HeaderBox,
|
},
|
data() {
|
return {
|
mapView: null,
|
mapPromise: null,
|
dateRange: [moment().startOf("month"), moment().endOf("month")], //默认本月
|
dateTxt: "",
|
activeTab: 1,
|
scrollData: [], // 存储滚动数据
|
scrollTimer: null, // 滚动定时器
|
scrollContainer: null, // 滚动容器引用
|
activeIndex: 0, // 当前活动索引
|
projectId: null,
|
categoryFilter: {
|
municipal: true,
|
house: true,
|
assets: true,
|
},
|
levelFilter: {
|
A: true,
|
B: true,
|
C: true,
|
},
|
markers: [],
|
// 2项目总数(在建工程) 3大型机械设备数(在建工程) 4重大隐患数(在建工程) 5项目总数(固定资产) 6重大隐患数(固定资产) 7事故简讯 8工作展示
|
permissionClient: JSON.parse(localStorage.getItem("permissionClient")),
|
// 9各分项隐患趋势 10隐患数量 11设备数量 12查看报告入口 13人员在岗率 14重大风险源 15 项目风险趋势
|
permissionProject: JSON.parse(localStorage.getItem("permissionProject")),
|
screenData: {},
|
searchTabs: ["本周", "本月", "本季度", "本年"],
|
activeTabs: "本周",
|
workListData: [],
|
VUE_APP_IMAGE_BASE_URL: process.env.VUE_APP_IMAGE_BASE_URL,
|
projectList: [],
|
tooltipVisible: false,
|
tooltipPos: { left: 0, top: 0 },
|
tooltipData: {},
|
tooltipLoading: false,
|
tooltipError: false,
|
};
|
},
|
watch: {
|
dateRange: {
|
handler(newVal, oldVal) {
|
if (newVal.length > 0) {
|
this.dateTxt =
|
moment(newVal[0]).format("YYYY年MM月DD日") +
|
" ~ " +
|
moment(newVal[1]).format("YYYY年MM月DD日");
|
} else {
|
this.dateTxt = "";
|
}
|
this.getScreenData();
|
let params = {
|
startDate: "",
|
endDate: "",
|
clientId: localStorage.getItem("clientId"),
|
};
|
if (newVal.length > 0) {
|
params.startDate = moment(this.dateRange[0]).format("YYYY-MM-DD");
|
params.endDate = moment(this.dateRange[1]).format("YYYY-MM-DD");
|
}
|
getProjectSelect(params).then((res) => {
|
this.projectList = res;
|
});
|
},
|
immediate: true,
|
},
|
},
|
created() {
|
this.mapPromise = AMapLoader.load({
|
key: "232929db1cb31f26d42b3645a7456154",
|
version: "2.0",
|
});
|
this.getStoryData();
|
getWorkPresentationList({
|
clientId: localStorage.getItem("clientId"),
|
state: 1,
|
pageNum: 1,
|
pageSize: 9999,
|
}).then((res) => {
|
this.workListData = res.records;
|
});
|
},
|
mounted() {
|
this.$nextTick(() => {
|
this.scrollContainer = this.$refs.scrollContainer;
|
});
|
},
|
beforeDestroy() {
|
this.stopAutoScroll();
|
},
|
methods: {
|
handleTabClick(tab) {
|
this.activeTabs = tab;
|
this.getStoryData();
|
},
|
changeTab(type) {
|
if (this.activeTab == type) return;
|
this.activeTab = type;
|
this.getScreenData();
|
},
|
getStoryData() {
|
let startTime = moment();
|
let endTime = moment();
|
if (this.activeTabs == "本周") {
|
startTime = moment().startOf("isoWeek");
|
endTime = moment().endOf("isoWeek");
|
} else if (this.activeTabs == "本月") {
|
startTime = moment().startOf("month");
|
endTime = moment().endOf("month");
|
} else if (this.activeTabs == "本季度") {
|
startTime = moment().startOf("quarter");
|
endTime = moment().endOf("quarter");
|
} else if (this.activeTabs == "本年") {
|
startTime = moment().startOf("year");
|
endTime = moment().endOf("year");
|
}
|
let time =
|
startTime.format("YYYY-MM-DD") + " - " + endTime.format("YYYY-MM-DD");
|
getStoryList({
|
time: time,
|
}).then((res) => {
|
this.scrollData = res;
|
if (this.screenData.length > 4) {
|
this.initScrollData();
|
}
|
});
|
},
|
getScreenData() {
|
let params = {
|
projectCategory: ["ongoing", "fixed"][this.activeTab - 1],
|
startDate: "",
|
endDate: "",
|
clientId: localStorage.getItem("clientId"),
|
};
|
if (this.dateRange.length) {
|
params.startDate = moment(this.dateRange[0]).format("YYYY-MM-DD");
|
params.endDate = moment(this.dateRange[1]).format("YYYY-MM-DD");
|
}
|
getStatistics(params).then((res) => {
|
this.screenData = res.ongoingProject || res.fixedAsset;
|
this.setMapload();
|
});
|
},
|
toAccidentCaseDetail(item) {
|
this.$router.push({
|
path: "/accidentCase/detail",
|
query: {
|
id: item.id,
|
},
|
});
|
},
|
toAccidentCaseList() {
|
this.$router.push("/accidentCase");
|
},
|
toWorkDetail(item) {
|
this.$router.push({
|
path: "/workList/detail",
|
query: {
|
id: item.id,
|
},
|
});
|
},
|
toWorkList() {
|
this.$router.push("/workList");
|
},
|
toPorjectList() {
|
this.$router.push("/projectList");
|
},
|
toEquipmentList() {
|
this.$router.push("/equipmentList");
|
},
|
toHiddenDanger() {
|
this.$router.push("/hiddenDanger");
|
},
|
// 切换活动索引
|
changeActiveIndex(index) {
|
this.activeIndex = index;
|
this.$refs.carousel.setActiveItem(index);
|
},
|
// 切换活动索引
|
handleChangeCarousel(index) {
|
this.activeIndex = index;
|
},
|
handleClick() {
|
this.$refs.datePicker.focus();
|
},
|
handleSearch() {
|
if (!this.projectId) {
|
return;
|
}
|
|
const target = this.screenData.projectMapPoints.find(
|
(item) => item.projectId === this.projectId
|
);
|
|
if (Object.keys(target).length == 0) {
|
this.$message.warning("无此项目地图点位");
|
return;
|
}
|
|
if (target.longitude && target.latitude) {
|
// 定位地图
|
this.mapView.setZoomAndCenter(15, [
|
Number(target.longitude),
|
Number(target.latitude),
|
]);
|
|
// 显示悬浮窗
|
this.showTooltip(null, {
|
projectId: target.projectId,
|
position: [Number(target.longitude), Number(target.latitude)],
|
});
|
} else {
|
this.$message.warning("该项目暂无位置信息");
|
}
|
},
|
// 初始化滚动数据
|
initScrollData() {
|
this.stopAutoScroll();
|
if (!this.scrollData || this.scrollData.length === 0) return;
|
|
// 为了实现无缝滚动,复制2份数据
|
this.scrollData = [...this.scrollData, ...this.scrollData];
|
|
// 开始滚动
|
this.$nextTick(() => {
|
this.startAutoScroll();
|
});
|
},
|
|
// 开始自动滚动
|
startAutoScroll() {
|
this.stopAutoScroll();
|
|
if (!this.scrollContainer || !this.scrollData.length) return;
|
|
const originalDataLength = this.scrollData.length / 2;
|
|
// 动态计算高度
|
let firstHalfHeight = 0;
|
const wrapper = this.scrollContainer.children[0];
|
if (wrapper && wrapper.children.length) {
|
for (let i = 0; i < originalDataLength; i++) {
|
if (wrapper.children[i]) {
|
firstHalfHeight += wrapper.children[i].offsetHeight;
|
}
|
}
|
}
|
|
// 兜底
|
if (firstHalfHeight === 0) firstHalfHeight = originalDataLength * 102;
|
|
// 判断是否需要跳转的标志
|
let shouldJump = false;
|
|
const scroll = () => {
|
let currentScrollTop = this.scrollContainer.scrollTop;
|
|
// 当滚动到第二份的末尾时
|
if (currentScrollTop >= firstHalfHeight) {
|
// 计算当前滚动位置相对于第二份数据开始的偏移量
|
const offset = currentScrollTop - firstHalfHeight;
|
// 直接跳到第一份数据相同偏移量的位置
|
this.scrollContainer.scrollTop = offset;
|
// 设置标志表示刚刚进行过跳转
|
shouldJump = true;
|
} else {
|
// 如果在跳转后,并且位置重置到了0附近,重置标志
|
if (shouldJump && currentScrollTop < 2) {
|
shouldJump = false;
|
}
|
}
|
|
// 只有在不处于跳转状态时才继续滚动
|
if (!shouldJump) {
|
this.scrollContainer.scrollTop += 1;
|
}
|
|
this.scrollTimer = requestAnimationFrame(scroll);
|
};
|
|
// 开始滚动
|
this.scrollTimer = requestAnimationFrame(scroll);
|
},
|
|
// 停止自动滚动
|
stopAutoScroll() {
|
if (this.scrollTimer) {
|
cancelAnimationFrame(this.scrollTimer);
|
this.scrollTimer = null;
|
}
|
},
|
|
// 鼠标进入容器时暂停滚动
|
handleMouseEnter() {
|
this.stopAutoScroll();
|
},
|
|
// 鼠标离开容器时恢复滚动
|
handleMouseLeave() {
|
this.startAutoScroll();
|
},
|
|
// 处理滚轮事件
|
handleWheel(event) {
|
event.preventDefault();
|
this.scrollContainer.scrollTop += event.deltaY;
|
},
|
|
setMapload() {
|
if (!this.mapPromise) {
|
this.mapPromise = AMapLoader.load({
|
key: "232929db1cb31f26d42b3645a7456154",
|
version: "2.0",
|
});
|
}
|
this.mapPromise
|
.then((AMap) => {
|
this.mapView = new AMap.Map("container", {
|
zoom: 13,
|
center: [104.065617, 30.656952], // 初始化地图中心点
|
mapStyle: "amap://styles/darkblue",
|
});
|
// this.infoWindow = new AMap.InfoWindow({
|
// isCustom: true,
|
// offset: new AMap.Pixel(0, -30),
|
// });
|
this.initCategoryMarkers(AMap);
|
})
|
.catch((e) => {
|
console.error(e); //加载错误提示
|
});
|
},
|
initCategoryMarkers(AMap) {
|
if (!this.mapView) {
|
return;
|
}
|
const points = this.screenData.projectMapPoints.map((item) => {
|
let category;
|
if (this.activeTab === 2) {
|
category = "assets";
|
} else {
|
category = ["house", "municipal", "assets"][item.projectType];
|
}
|
return {
|
...item,
|
position: [Number(item.longitude), Number(item.latitude)],
|
category: category,
|
level: item.category,
|
};
|
});
|
const markers = [];
|
points.forEach((item) => {
|
const marker = this.createCategoryMarker(AMap, item);
|
if (marker) {
|
this.mapView.add(marker);
|
markers.push(marker);
|
}
|
});
|
this.markers = markers;
|
this.updateMarkerVisibility();
|
},
|
createCategoryMarker(AMap, item) {
|
if (!item || !item.position) {
|
return null;
|
}
|
let image = null;
|
let level = item.level;
|
if (item.category === "municipal") {
|
if (item.level === "A") {
|
image = s1;
|
} else if (item.level === "B") {
|
image = s2;
|
} else if (item.level === "C") {
|
image = s3;
|
} else {
|
image = s4;
|
}
|
} else if (item.category === "house") {
|
if (item.level === "A") {
|
image = f1;
|
} else if (item.level === "B") {
|
image = f2;
|
} else if (item.level === "C") {
|
image = f3;
|
} else {
|
image = f4;
|
}
|
} else if (item.category === "assets") {
|
if (item.level === "A") {
|
image = z1;
|
} else if (item.level === "B") {
|
image = z2;
|
} else if (item.level === "C") {
|
image = z3;
|
} else {
|
image = z4;
|
}
|
}
|
if (!image) {
|
return null;
|
}
|
const icon = new AMap.Icon({
|
image,
|
size: new AMap.Size(30, 30),
|
imageSize: new AMap.Size(30, 30),
|
});
|
const marker = new AMap.Marker({
|
position: item.position,
|
icon,
|
offset: new AMap.Pixel(-12, -12),
|
extData: {
|
category: item.category,
|
level: level,
|
},
|
});
|
marker.on("mouseover", (e) => {
|
this.showTooltip(e, item);
|
});
|
marker.on("mouseout", () => {
|
this.hideTooltip();
|
});
|
return marker;
|
},
|
updateMarkerVisibility() {
|
if (!this.markers || !this.markers.length) {
|
return;
|
}
|
this.markers.forEach((marker) => {
|
if (!marker) {
|
return;
|
}
|
const data = marker.getExtData ? marker.getExtData() : null;
|
if (!data) {
|
return;
|
}
|
const categoryVisible = this.categoryFilter[data.category];
|
const levelVisible = !data.level || this.levelFilter[data.level];
|
if (categoryVisible && levelVisible) {
|
marker.show();
|
} else {
|
marker.hide();
|
}
|
});
|
},
|
toggleCategory(type) {
|
if (!this.categoryFilter.hasOwnProperty(type)) {
|
return;
|
}
|
this.categoryFilter[type] = !this.categoryFilter[type];
|
this.updateMarkerVisibility();
|
},
|
toggleLevel(level) {
|
if (!this.levelFilter.hasOwnProperty(level)) {
|
return;
|
}
|
this.levelFilter[level] = !this.levelFilter[level];
|
this.updateMarkerVisibility();
|
},
|
showTooltip(e, item) {
|
if (!this.mapView) return;
|
|
const pixel = this.mapView.lngLatToContainer(item.position);
|
this.tooltipPos = { left: pixel.x, top: pixel.y };
|
this.tooltipVisible = true;
|
this.tooltipLoading = true;
|
this.tooltipError = false;
|
this.tooltipData = {};
|
|
getprojectTooltip(item.projectId)
|
.then((res) => {
|
let address = "-";
|
let constructionCompanyInfo = "-";
|
let supervisorCompanyInfo = "-";
|
let developmentCompanyInfo = "-";
|
|
try {
|
if (res.addressInfo) {
|
const addressInfo = JSON.parse(res.addressInfo);
|
address =
|
(addressInfo.province || "") +
|
(addressInfo.city || "") +
|
(addressInfo.district || "") +
|
(addressInfo.detail || "");
|
}
|
if (res.constructionCompanyInfo) {
|
constructionCompanyInfo = JSON.parse(res.constructionCompanyInfo);
|
}
|
if (res.supervisorCompanyInfo) {
|
supervisorCompanyInfo = JSON.parse(res.supervisorCompanyInfo);
|
}
|
if (res.developmentCompanyInfo) {
|
developmentCompanyInfo = JSON.parse(res.developmentCompanyInfo);
|
}
|
} catch (error) {
|
console.error("Parse error", error);
|
}
|
|
this.tooltipData = {
|
...res,
|
address,
|
constructionCompanyInfo,
|
supervisorCompanyInfo,
|
developmentCompanyInfo,
|
};
|
this.tooltipLoading = false;
|
})
|
.catch((err) => {
|
this.tooltipLoading = false;
|
this.tooltipError = true;
|
});
|
},
|
hideTooltip() {
|
this.tooltipVisible = false;
|
},
|
},
|
};
|
</script>
|
|
<style lang="less" scoped>
|
.bsh1 {
|
box-shadow: inset 0px 0px 22px 0px rgba(11, 220, 140, 0.35);
|
}
|
|
.bsh2 {
|
box-shadow: inset 0px 0px 22px 0px rgba(254, 219, 101, 0.3);
|
}
|
|
.bgimg4 {
|
background-image: url("../../assets/img/home/Group 24 Copy@2x.png");
|
background-size: 100% 100%;
|
width: 300px;
|
height: 94px;
|
}
|
|
.bgimg5 {
|
background-image: url("../../assets/img/home/25@2x.png");
|
background-size: 100% 100%;
|
}
|
|
.gray-text {
|
color: rgba(255, 255, 255, 0.5) !important;
|
}
|
|
.gray-bg {
|
background: rgba(255, 255, 255, 0.5) !important;
|
}
|
|
.color5 {
|
color: #ff4d04;
|
}
|
|
.color6 {
|
color: #fedb65;
|
}
|
|
.color7 {
|
color: #47a1ff;
|
}
|
|
.color8 {
|
color: #00ffd2;
|
}
|
|
.color9 {
|
color: #ff4d4f;
|
}
|
|
.color10 {
|
color: #ffc53d;
|
}
|
|
.bgcolor4 {
|
background: #06175b;
|
border-radius: 16px;
|
border: 1px solid #204fb3;
|
}
|
|
.bgcolor5 {
|
background: rgba(14, 93, 251, 0.5);
|
}
|
|
.bgcolor6 {
|
background: linear-gradient(180deg, #ff4d4f 0%, #e5484d 100%);
|
border-radius: 2px 0px 0px 10px;
|
border: 1px solid #e5484d;
|
}
|
|
.bgcolor7 {
|
background: rgba(14, 95, 255, 0.2);
|
}
|
|
.bgcolor8 {
|
background: #00ffd2;
|
}
|
|
.bgcolor9 {
|
background: #ff4d4f;
|
}
|
|
.bgcolor10 {
|
background: #ffc53d;
|
}
|
|
.activeBox {
|
position: absolute;
|
top: 0;
|
left: 0;
|
padding: 0 20px;
|
height: 32px;
|
background: #0600e4;
|
color: transparent;
|
box-shadow: inset 0px 0px 20px 0px rgba(102, 255, 255, 0.52);
|
border-radius: 20px;
|
border: 1px solid rgba(50, 197, 255, 0.22);
|
transition: all 0.3s ease-in-out;
|
}
|
|
.activeBox2 {
|
left: 95px;
|
}
|
|
.leftBox {
|
width: 380px;
|
position: fixed;
|
top: 109px;
|
left: 23px;
|
|
.bgImg1 {
|
background-image: url("../../assets/img/home/Group@2x (3).png");
|
background-size: 100% 100%;
|
width: 171px;
|
height: 120px;
|
}
|
|
.bgimg2 {
|
background-image: url("../../assets/img/home/Group@2x (2).png");
|
background-size: 100% 100%;
|
}
|
|
.bgimg3 {
|
background-image: url("../../assets/img/home/@3x@2x.png");
|
background-size: 100% 100%;
|
width: 45px;
|
height: 49px;
|
}
|
|
.txts1 {
|
text-shadow: 0px 0px 7px #132c5a;
|
}
|
|
.txts2 {
|
text-shadow: 0px 0px 12px #1068f7;
|
}
|
|
.bgcolor1 {
|
background: rgba(2, 0, 77, 0.8);
|
box-shadow: inset 0px 0px 34px 0px rgba(17, 40, 255, 0.66);
|
border: 2px solid #0d53b7;
|
}
|
|
.bgcolor2 {
|
background: rgba(0, 113, 251, 0.1);
|
}
|
|
.bgcolor3 {
|
box-shadow: inset 0px 0px 22px 0px #2548b1;
|
border: 1px solid #3341b6;
|
}
|
|
.color1 {
|
color: #66ffff;
|
}
|
|
.color2 {
|
color: #cce0f8;
|
}
|
|
.color3 {
|
color: #7cc1ff;
|
}
|
|
.color4 {
|
color: #fedb65;
|
}
|
|
.color5 {
|
color: rgba(204, 224, 248, 0.7);
|
}
|
|
.hoverBox {
|
background-image: url("../../assets/img/home/444Group 24 Copy@2x.png");
|
background-size: 100% 100%;
|
width: 358px;
|
}
|
|
.picker {
|
::v-deep .el-input__icon {
|
display: none;
|
}
|
|
::v-deep .el-range-separator {
|
display: none;
|
}
|
|
::v-deep .el-input__inner {
|
background: transparent;
|
border: none;
|
color: transparent;
|
}
|
|
::v-deep .el-range-input {
|
background: transparent;
|
border: none;
|
color: transparent;
|
}
|
}
|
|
.searchBox {
|
::v-deep .el-input__inner {
|
background: transparent;
|
border: none;
|
color: #fff;
|
padding: 0;
|
}
|
|
::v-deep .el-input__suffix {
|
display: none;
|
}
|
|
.btn {
|
background: linear-gradient(
|
90deg,
|
#3467d0 0%,
|
#0d226a 50.35%,
|
#376fe0 100%
|
);
|
line-height: 38px;
|
font-size: 14px;
|
color: #ffffff;
|
font-family: "Source Han Sans CN Heavy";
|
padding: 0 26px;
|
border: 1px solid #307ad9;
|
box-sizing: border-box;
|
cursor: pointer;
|
}
|
}
|
|
.rowItem {
|
display: grid;
|
grid-template-columns: repeat(4, 1fr);
|
gap: 14px 33px;
|
|
.nameTxt {
|
width: 5em;
|
overflow: hidden;
|
max-height: 2em;
|
text-align: center;
|
}
|
}
|
}
|
|
.ripple {
|
position: fixed;
|
width: 14px;
|
height: 14px;
|
margin-right: 14px;
|
}
|
|
.ripple-wave {
|
position: absolute;
|
border-radius: 50%;
|
left: 50%;
|
top: 50%;
|
transform: translate(-50%, -50%);
|
}
|
|
.wave-1 {
|
width: 14px;
|
height: 14px;
|
background-color: rgba(255, 77, 4, 1);
|
}
|
|
.wave-2 {
|
width: 20px;
|
height: 20px;
|
background-color: rgba(255, 77, 4, 0.6);
|
animation: ripple-effect 2s ease-out infinite;
|
}
|
|
.wave-3 {
|
width: 24px;
|
height: 24px;
|
background-color: rgba(255, 77, 4, 0.4);
|
animation: ripple-effect 2s ease-out infinite 1s;
|
}
|
|
@keyframes ripple-effect {
|
0% {
|
transform: translate(-50%, -50%) scale(0.7);
|
opacity: 0;
|
}
|
20% {
|
opacity: 1;
|
opacity: 1;
|
}
|
100% {
|
-webkit-transform: translate(-50%, -50%) scale(1.4);
|
opacity: 0;
|
}
|
}
|
|
.rightBox {
|
width: 462px;
|
position: fixed;
|
top: 85px;
|
right: 20px;
|
}
|
|
/* 无缝滚动容器 */
|
.scroll-container {
|
overflow-y: auto;
|
overflow-x: hidden;
|
scrollbar-width: thin;
|
scrollbar-color: rgba(255, 255, 255, 0.3) transparent;
|
-ms-overflow-style: none;
|
scrollbar-width: none;
|
|
&::-webkit-scrollbar {
|
width: 6px;
|
}
|
|
&::-webkit-scrollbar-track {
|
background: transparent;
|
}
|
|
&::-webkit-scrollbar-thumb {
|
background-color: rgba(255, 255, 255, 0.3);
|
border-radius: 3px;
|
}
|
|
&::-webkit-scrollbar-thumb:hover {
|
background-color: rgba(255, 255, 255, 0.5);
|
}
|
}
|
|
.thisBox .hoverBox {
|
position: absolute;
|
left: 100%;
|
margin-left: 40px;
|
top: -60px;
|
display: none;
|
z-index: 100;
|
|
&::before {
|
content: "";
|
position: absolute;
|
top: 0;
|
left: -40px;
|
width: 40px;
|
height: 100%;
|
background: transparent;
|
}
|
}
|
|
.thisBox:hover .hoverBox {
|
display: block;
|
}
|
|
.searchTabs {
|
background: rgba(2, 0, 77, 0.8);
|
box-shadow: inset 0px 0px 34px 0px rgba(17, 40, 255, 0.66);
|
font-size: 12px;
|
color: rgba(255, 255, 255, 0.8);
|
font-family: "Source Han Sans CN Normal";
|
text-align: center;
|
flex-shrink: 0;
|
|
div {
|
padding: 2px;
|
width: 50px;
|
cursor: pointer;
|
line-height: 24px;
|
border: 1px solid #0d53b7;
|
|
&:hover {
|
background: #017be7;
|
color: #ffffff;
|
}
|
}
|
|
.activeTabs {
|
background: #017be7;
|
color: #ffffff;
|
}
|
}
|
</style>
|
|
<style lang="less">
|
.map-tooltip-wrapper {
|
position: absolute;
|
z-index: 9999;
|
pointer-events: none;
|
transform: translate(-50%, -50%);
|
margin-top: -40px;
|
}
|
|
.custom-tooltip {
|
position: relative;
|
background: rgba(0, 22, 53, 0.9);
|
border: 1px solid #204fb3;
|
border-radius: 4px;
|
padding: 10px;
|
color: #fff;
|
min-width: 250px;
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
|
|
&::after {
|
content: "";
|
position: absolute;
|
bottom: -6px;
|
left: 50%;
|
transform: translateX(-50%);
|
border-left: 6px solid transparent;
|
border-right: 6px solid transparent;
|
border-top: 6px solid #204fb3;
|
}
|
|
&::before {
|
content: "";
|
position: absolute;
|
bottom: -5px;
|
left: 50%;
|
transform: translateX(-50%);
|
border-left: 6px solid transparent;
|
border-right: 6px solid transparent;
|
border-top: 6px solid rgba(0, 22, 53, 0.9);
|
z-index: 1;
|
}
|
|
.title {
|
font-size: 16px;
|
font-weight: bold;
|
margin-bottom: 8px;
|
color: #fff;
|
}
|
|
.row {
|
display: flex;
|
font-size: 12px;
|
line-height: 1.5;
|
margin-bottom: 4px;
|
flex-shrink: 0;
|
|
.label {
|
color: rgba(255, 255, 255, 0.7);
|
min-width: 70px;
|
flex-shrink: 0;
|
}
|
|
.value {
|
color: #fff;
|
flex: 1;
|
}
|
}
|
|
.loading {
|
text-align: center;
|
padding: 10px;
|
color: #00ffd2;
|
}
|
|
.error {
|
color: #ff4d4f;
|
text-align: center;
|
padding: 10px;
|
}
|
}
|
</style>
|