| | |
| | | <div class="relative"> |
| | | <HeaderBox /> |
| | | <div id="mapcontainer" style="width: 1920px; height: 995px"></div> |
| | | <div |
| | | class="flex a-center absolute postion-center top--109 br--16 c-fff fs--14 bgcolor4 SSHR" |
| | | > |
| | | <div @click="activeTab = 1" class="lh--32 px--20 cursor-pointer z-10"> |
| | | 在建工程 |
| | | </div> |
| | | <div @click="activeTab = 2" class="lh--32 px--20 cursor-pointer z-10"> |
| | | 固定资产 |
| | | </div> |
| | | <div class="activeBox" :class="activeTab == 2 && 'activeBox2'"> |
| | | 在建工程 |
| | | </div> |
| | | </div> |
| | | <div 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 class="bgimg4 pt--10 c-fff"> |
| | | <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--10">重大隐患数</div> |
| | | <div class="color5 ml--13 fs--30 lh--30 zh_tr">16</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">14</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">2</div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="leftBox"> |
| | | <div |
| | | @click="handleClick" |
| | | class="flex a-center j-between w100 px--20 h--40 relative bgcolor1" |
| | | class="flex a-center j-between w100 px--20 h--40 relative bgcolor1 picker" |
| | | > |
| | | <el-date-picker |
| | | v-model="dateRange" |
| | |
| | | <div |
| | | class="flex a-center j-between w100 pl--20 mt--13 h--40 relative bgcolor1 searchBox" |
| | | > |
| | | <input placeholder="请输入项目名称" /> |
| | | <el-select filterable placeholder="请输入项目名称" /> |
| | | <div class="btn">搜索</div> |
| | | </div> |
| | | <div class="mt--33"> |
| | |
| | | </TitleBox> |
| | | </div> |
| | | </div> |
| | | <div 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 class="bgimg4 pt--10 c-fff"> |
| | | <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--10">重大隐患数</div> |
| | | <div class="color5 ml--13 fs--30 lh--30">16</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">14</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">2</div> |
| | | </div> |
| | | </div> |
| | | <div class="rightBox"> |
| | | <div class="mt--33"> |
| | | <TitleBox> |
| | | <template #title> 事故简讯 </template> |
| | | <template #right> |
| | | <div |
| | | 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 |
| | | ref="scrollContainer" |
| | | class="scroll-container" |
| | | style="height: 408px" |
| | | @mouseenter="handleMouseEnter" |
| | | @mouseleave="handleMouseLeave" |
| | | @wheel="handleWheel" |
| | | > |
| | | <div> |
| | | <div |
| | | 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.type }} |
| | | </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.location }}</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.date }}</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> |
| | | </div> |
| | |
| | | mapView: null, |
| | | dateRange: [moment().startOf("month"), moment().endOf("month")], //默认本月 |
| | | dateTxt: "", |
| | | activeTab: 1, |
| | | scrollData: [], // 存储滚动数据 |
| | | scrollTimer: null, // 滚动定时器 |
| | | scrollContainer: null, // 滚动容器引用 |
| | | }; |
| | | }, |
| | | watch: { |
| | |
| | | created() {}, |
| | | mounted() { |
| | | this.setMapload(); |
| | | this.$nextTick(() => { |
| | | this.scrollContainer = this.$refs.scrollContainer; |
| | | this.initScrollData(); |
| | | }); |
| | | }, |
| | | beforeDestroy() {}, |
| | | beforeDestroy() { |
| | | this.stopAutoScroll(); |
| | | }, |
| | | methods: { |
| | | handleClick() { |
| | | this.$refs.datePicker.focus(); |
| | | }, |
| | | // 初始化滚动数据 |
| | | initScrollData() { |
| | | // 创建示例数据,模拟真实的事故简讯数据 |
| | | const sampleData = [ |
| | | { |
| | | id: 1, |
| | | type: "塔吊倒塌", |
| | | title: "秦皇岛市钢铁厂发生塔吊倒塌事故", |
| | | location: "河北省秦皇岛市昌黎县", |
| | | date: "2025年11月10日", |
| | | casualties: "造成 1 人死亡", |
| | | }, |
| | | { |
| | | id: 2, |
| | | type: "脚手架坍塌", |
| | | title: "广州市某工地脚手架坍塌事故", |
| | | location: "广东省广州市白云区", |
| | | date: "2025年11月9日", |
| | | casualties: "造成 2 人受伤", |
| | | }, |
| | | { |
| | | id: 3, |
| | | type: "高处坠落", |
| | | title: "深圳市某建筑工地工人高处坠落", |
| | | location: "广东省深圳市南山区", |
| | | date: "2025年11月8日", |
| | | casualties: "造成 1 人死亡,1 人重伤", |
| | | }, |
| | | { |
| | | id: 4, |
| | | type: "物体打击", |
| | | title: "成都市某工地发生物体打击事故", |
| | | location: "四川省成都市武侯区", |
| | | date: "2025年11月7日", |
| | | casualties: "造成 1 人轻伤", |
| | | }, |
| | | { |
| | | id: 5, |
| | | type: "触电事故", |
| | | title: "杭州市某工地发生触电事故", |
| | | location: "浙江省杭州市西湖区", |
| | | date: "2025年11月6日", |
| | | casualties: "造成 1 人死亡", |
| | | }, |
| | | { |
| | | id: 6, |
| | | type: "机械伤害", |
| | | title: "南京市某工地发生机械伤害事故", |
| | | location: "江苏省南京市江宁区", |
| | | date: "2025年11月5日", |
| | | casualties: "造成 1 人重伤", |
| | | }, |
| | | { |
| | | id: 7, |
| | | type: "坍塌事故", |
| | | title: "武汉市某工地发生局部坍塌事故", |
| | | location: "湖北省武汉市汉阳区", |
| | | date: "2025年11月4日", |
| | | casualties: "造成 1 人死亡,2 人受伤", |
| | | }, |
| | | ]; |
| | | |
| | | // 为了实现无缝滚动,复制2份数据 |
| | | this.scrollData = [...sampleData, ...sampleData]; |
| | | |
| | | // 开始滚动 |
| | | this.startAutoScroll(); |
| | | }, |
| | | |
| | | // 开始自动滚动 |
| | | startAutoScroll() { |
| | | this.stopAutoScroll(); |
| | | |
| | | if (!this.scrollContainer) return; |
| | | |
| | | const originalDataLength = this.scrollData.length / 2; |
| | | const itemHeight = 80; // 每个项目高度 |
| | | |
| | | const scroll = () => { |
| | | // 获取当前滚动位置 |
| | | let currentScrollTop = this.scrollContainer.scrollTop; |
| | | |
| | | // 如果滚动到第二份数据的末尾,跳回第一份数据的开头 |
| | | if (currentScrollTop >= originalDataLength * itemHeight) { |
| | | // 瞬间跳回第一份数据的位置,实现无缝滚动 |
| | | this.scrollContainer.scrollTop = 0; |
| | | } else { |
| | | // 正常向下滚动 |
| | | 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() { |
| | | AMapLoader.load({ |
| | |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | | .bgimg4 { |
| | | background-image: url("../../assets/img/home/Group 24 Copy@2x.png"); |
| | | background-size: 100% 100%; |
| | | width: 300px; |
| | | height: 94px; |
| | | } |
| | | |
| | | .color5 { |
| | | color: #ff4d04; |
| | | } |
| | | |
| | | .color6 { |
| | | color: #fedb65; |
| | | } |
| | | |
| | | .color7 { |
| | | color: #47a1ff; |
| | | } |
| | | |
| | | .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); |
| | | } |
| | | |
| | | .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: 100px; |
| | | } |
| | | |
| | | .leftBox { |
| | | width: 380px; |
| | | position: absolute; |
| | |
| | | .color5 { |
| | | color: rgba(204, 224, 248, 0.7); |
| | | } |
| | | .picker { |
| | | ::v-deep .el-input__icon { |
| | | display: none; |
| | | } |
| | | |
| | | ::v-deep .el-input__icon { |
| | | display: none; |
| | | } |
| | | ::v-deep .el-input__inner { |
| | | background: transparent; |
| | | border: none; |
| | | color: transparent; |
| | | } |
| | | |
| | | ::v-deep .el-input__inner { |
| | | background: transparent; |
| | | border: none; |
| | | color: transparent; |
| | | } |
| | | |
| | | ::v-deep .el-range-input { |
| | | background: transparent; |
| | | border: none; |
| | | color: transparent; |
| | | ::v-deep .el-range-input { |
| | | background: transparent; |
| | | border: none; |
| | | color: transparent; |
| | | } |
| | | } |
| | | |
| | | .searchBox { |
| | | input { |
| | | background-color: transparent; |
| | | ::v-deep .el-input__inner { |
| | | background: transparent; |
| | | border: none; |
| | | color: #fff; |
| | | padding: 0; |
| | | } |
| | | |
| | | input::placeholder { |
| | | color: rgba(255, 255, 255, 0.6); |
| | | } |
| | | |
| | | input:focus { |
| | | outline: none; |
| | | ::v-deep .el-input__suffix { |
| | | display: none; |
| | | } |
| | | |
| | | .btn { |
| | |
| | | text-align: center; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .bgimg4 { |
| | | background-image: url("../../assets/img/home/Group 24 Copy@2x.png"); |
| | | background-size: 100% 100%; |
| | | width: 300px; |
| | | height: 94px; |
| | | } |
| | | |
| | | .color5 { |
| | | color: #ff4d04; |
| | | } |
| | | |
| | | .color6 { |
| | | color: #fedb65; |
| | | } |
| | | |
| | | .color7 { |
| | | color: #47a1ff; |
| | | } |
| | | |
| | | .ripple { |
| | |
| | | } |
| | | 20% { |
| | | opacity: 1; |
| | | } |
| | | 100% { |
| | | transform: translate(-50%, -50%) scale(1.4); |
| | | opacity: 0; |
| | | } |
| | | } |
| | | |
| | | /* 兼容性前缀 */ |
| | | .wave-2, .wave-3 { |
| | | -webkit-animation-name: ripple-effect; |
| | | -moz-animation-name: ripple-effect; |
| | | -o-animation-name: ripple-effect; |
| | | animation-name: ripple-effect; |
| | | } |
| | | |
| | | @-webkit-keyframes ripple-effect { |
| | | 0% { |
| | | -webkit-transform: translate(-50%, -50%) scale(0.7); |
| | | opacity: 0; |
| | | } |
| | | 20% { |
| | | opacity: 1; |
| | | } |
| | | 100% { |
| | |
| | | } |
| | | } |
| | | |
| | | @-moz-keyframes ripple-effect { |
| | | 0% { |
| | | -moz-transform: translate(-50%, -50%) scale(0.7); |
| | | opacity: 0; |
| | | .rightBox { |
| | | width: 462px; |
| | | position: absolute; |
| | | 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; |
| | | } |
| | | 20% { |
| | | opacity: 1; |
| | | |
| | | &::-webkit-scrollbar-track { |
| | | background: transparent; |
| | | } |
| | | 100% { |
| | | -moz-transform: translate(-50%, -50%) scale(1.4); |
| | | opacity: 0; |
| | | |
| | | &::-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); |
| | | } |
| | | } |
| | | </style> |