合并
This commit is contained in:
		| @ -16,8 +16,8 @@ | ||||
|         <div class="swiper_content" ref="swiperContent"> | ||||
|           <div class="swiper_item" v-for="(item, i) in inspectionList" :key="i"> | ||||
|             <img :src="item.picture" alt="安全巡检" class="swiper_img"> | ||||
|             <!-- <div class="swiper_date">{{ item.createTime.slice(5) }}</div> --> | ||||
|             <div class="swiper_tip">{{ item.label }}</div> | ||||
|             <div class="swiper_date">{{ item.createTime.slice(5, 16) }}</div> | ||||
|             <div class="swiper_tip">{{ item.label || '未佩戴安全帽' }}</div> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="arrow" :class="{ 'canUse': canRight }" @click="swiperClick('right')"> | ||||
| @ -89,19 +89,71 @@ const getInspectionList = async () => { | ||||
|   const res = await getScreenSafetyInspection(props.projectId) | ||||
|   const { code, data } = res | ||||
|   if (code === 200) { | ||||
|     console.log(violation_level_type.value) | ||||
|     data.map(item => { | ||||
|       item.label = violation_level_type.value.find((i) => i.value === item.violationType)?.label | ||||
|     }) | ||||
|     inspectionList.value = data | ||||
|   } | ||||
| } | ||||
| // 创建地球 | ||||
| const createEarth = () => { | ||||
|   window.YJ.on({ | ||||
|     ws: true, | ||||
|     // host: getIP(), //资源所在服务器地址 | ||||
|     // username: this.loginForm.username, //用户名 可以不登录(不填写用户名),不登录时无法加载服务端的数据 | ||||
|     // password: md5pass, //密码  生成方式:md5(用户名_密码) | ||||
|   }).then((res) => { | ||||
|     let earth = new YJ.YJEarth("earth"); | ||||
|     window.Earth1 = earth; | ||||
|     YJ.Global.openRightClick(window.Earth1); | ||||
|     YJ.Global.openLeftClick(window.Earth1); | ||||
|     let view = { | ||||
|       "position": { | ||||
|         "lng": 102.03643298211526, | ||||
|         "lat": 34.393586474501, | ||||
|         "alt": 11298179.51993155 | ||||
|       }, | ||||
|       "orientation": { | ||||
|         "heading": 360, | ||||
|         "pitch": -89.94481747201486, | ||||
|         "roll": 0 | ||||
|       } | ||||
|     } | ||||
|     loadBaseMap(earth.viewer) | ||||
|     YJ.Global.CesiumContainer(window.Earth1, { | ||||
|       compass: false, //罗盘 | ||||
|     }); | ||||
|     // YJ.Global.flyTo(earth, view); | ||||
|     // YJ.Global.setDefaultView(earth.viewer, view) | ||||
|   }) | ||||
| } | ||||
| // 加载底图 | ||||
| const loadBaseMap = (viewer) => { | ||||
|   // 创建瓦片提供器 | ||||
|   const imageryProvider = new Cesium.UrlTemplateImageryProvider({ | ||||
|     url: 'https://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}', | ||||
|     // 可选:设置瓦片的格式 | ||||
|     fileExtension: 'png', | ||||
|     // 可选:设置瓦片的范围和级别 | ||||
|     minimumLevel: 0, | ||||
|     maximumLevel: 18, | ||||
|     // 可选:设置瓦片的投影(默认为Web Mercator) | ||||
|     projection: Cesium.WebMercatorProjection, | ||||
|     // 可选:如果瓦片服务需要跨域请求,设置请求头部 | ||||
|     credit: new Cesium.Credit('卫星图数据来源') | ||||
|   }); | ||||
|  | ||||
|   // 添加图层到视图 | ||||
|   const layer = viewer.imageryLayers.addImageryProvider(imageryProvider); | ||||
| } | ||||
|  | ||||
| onMounted(() => { | ||||
|   getInspectionList() | ||||
|   if (swiperContent.value && swiperContent.value.children.length > 0) { | ||||
|     swiperItemWidth.value = swiperContent.value.children[0].clientWidth + 20 | ||||
|   } | ||||
| }) | ||||
|  | ||||
| </script> | ||||
|  | ||||
| <style scoped lang="scss"> | ||||
| @ -113,10 +165,6 @@ onMounted(() => { | ||||
|  | ||||
| .topPage, | ||||
| .endPage { | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   align-items: center; | ||||
|   justify-content: center; | ||||
|   width: 100%; | ||||
|   padding: 15px 0; | ||||
|   border: 1px solid rgba(230, 247, 255, 0.1); | ||||
| @ -125,12 +173,16 @@ onMounted(() => { | ||||
|  | ||||
| .topPage { | ||||
|   flex: 1; | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   align-items: center; | ||||
|   justify-content: center; | ||||
|   margin-bottom: 23px; | ||||
|   transition: flex 0.5s ease; | ||||
| } | ||||
|  | ||||
| .endPage { | ||||
|   max-height: 300px; | ||||
|   height: 170px; | ||||
|   opacity: 1; | ||||
|   transition: all 0.5s ease; | ||||
| } | ||||
| @ -150,7 +202,7 @@ onMounted(() => { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   gap: 20px; | ||||
|   padding: 20px 20px 10px 20px; | ||||
|   padding: 12px 20px 10px 20px; | ||||
|  | ||||
|   .swiper_content { | ||||
|     width: 100%; | ||||
| @ -182,7 +234,7 @@ onMounted(() => { | ||||
|       position: absolute; | ||||
|       top: 4px; | ||||
|       right: 4px; | ||||
|       font-size: 14px; | ||||
|       font-size: 12px; | ||||
|       font-weight: 400; | ||||
|       color: rgba(230, 247, 255, 1); | ||||
|     } | ||||
|  | ||||
| @ -4,27 +4,23 @@ | ||||
|       <div class="header_left_img"> | ||||
|         <img src="@/assets/large/secure.png" style="width: 100%; height: 100%" /> | ||||
|       </div> | ||||
|       <div style="font-size: 12px; padding-left: 10px">安全生产天数:</div> | ||||
|       <div style="font-size: 0.83vw; padding-left: 10px">安全生产天数:</div> | ||||
|       <div class="header_left_text"> | ||||
|         {{ safetyDay }} | ||||
|         <span style="font-size: 12px">天</span> | ||||
|       </div> | ||||
|     </div> | ||||
|     <div class="title"> | ||||
|       <div>煤科建管-新能源项目级管理平台</div> | ||||
|       <div>Coal Science Construction Management - New Energy Project Level Management Platform</div> | ||||
|       <div>{{ currentProjectName }}</div> | ||||
|       <div>施工现场数智化管理</div> | ||||
|     </div> | ||||
|     <div class="header_right"> | ||||
|       <div class="top-bar"> | ||||
|         <!-- 左侧:天气图标 + 日期文字 --> | ||||
|         <div class="left-section"> | ||||
|           <div class="weather-list" @mouseenter="requestPause" @mouseleave="resumeScroll"> | ||||
|             <div | ||||
|               v-for="(item, i) in weatherList" | ||||
|               :key="i" | ||||
|               class="weather-item" | ||||
|               :style="{ transform: `translateY(-${offsetY}px)`, transition: transition }" | ||||
|             > | ||||
|             <div v-for="(item, i) in weatherList" :key="i" class="weather-item" | ||||
|               :style="{ transform: `translateY(-${offsetY}px)`, transition: transition }"> | ||||
|               <img :src="`/assets/demo/${item.icon}.png`" alt="" /> | ||||
|               <div>{{ item.weather }}{{ item.tempMin }}°/{{ item.tempMax }}°</div> | ||||
|               <div>{{ item.week }}({{ item.date }})</div> | ||||
| @ -63,6 +59,10 @@ | ||||
| <script setup lang="ts"> | ||||
| import { ref, onMounted, onUnmounted } from 'vue'; | ||||
| import { getScreenSafetyDay, getScreenWeather } from '@/api/projectScreen'; | ||||
| import { useUserStoreHook } from '@/store/modules/user'; | ||||
|  | ||||
| const userStore = useUserStoreHook(); | ||||
| const currentProjectName = computed(() => userStore.selectedProject?.name); | ||||
|  | ||||
| interface Weather { | ||||
|   week: string; | ||||
| @ -212,7 +212,8 @@ onUnmounted(() => { | ||||
|   } | ||||
|  | ||||
|   .header_left_text { | ||||
|     font-weight: 500; | ||||
|     font-size: 1.45vw; | ||||
|     font-weight: 700; | ||||
|     text-shadow: 0px 1.24px 6.21px rgba(25, 179, 250, 1); | ||||
|   } | ||||
| } | ||||
| @ -237,7 +238,7 @@ onUnmounted(() => { | ||||
|  | ||||
| .title>div:last-child { | ||||
|   /* 最后一个子元素的样式 */ | ||||
|   font-size: 14px; | ||||
|   font-size: 26px; | ||||
| } | ||||
|  | ||||
| /* 顶部栏容器:Flex 水平布局 + 垂直居中 */ | ||||
|  | ||||
| @ -68,12 +68,15 @@ | ||||
|           <div class="attendance_item_title">出勤率</div> | ||||
|           <div class="attendance_item_title">出勤时间</div> | ||||
|         </div> | ||||
|       </div> | ||||
|  | ||||
|       <div class="attendance_list scroll"> | ||||
|         <div v-for="item in teamAttendanceList" :key="item.id" class="attendance_item"> | ||||
|           <div class="attendance_item_title">{{ item.teamName }}</div> | ||||
|           <div class="attendance_item_number"> | ||||
|             {{ item.attendanceNumber }} <span class="subfont">人/{{ item.allNumber }}</span> | ||||
|           </div> | ||||
|           <div class="attendance_item_rate">{{ item.attendanceRate }} %</div> | ||||
|           <div class="attendance_item_rate">{{ item.attendanceRate != '0' ? item.attendanceRate : `${item.attendanceRate}.00` }} %</div> | ||||
|           <div class="attendance_item_date subfont">{{ item.attendanceTime }}</div> | ||||
|         </div> | ||||
|       </div> | ||||
| @ -107,7 +110,7 @@ const newId = ref(''); | ||||
| const attendanceCount = ref(0); | ||||
| const attendanceRate = ref(0); | ||||
| const peopleCount = ref(0); | ||||
| const teamAttendanceList = ref([{ id: '', teamName: '', attendanceNumber: 0, allNumber: 0, attendanceRate: 0, attendanceTime: '' }]); | ||||
| const teamAttendanceList = ref([]); | ||||
|  | ||||
| /** | ||||
|  * 显示新闻详情 | ||||
| @ -128,6 +131,7 @@ const getPeopleData = async () => { | ||||
|   const res = await getScreenPeople(props.projectId); | ||||
|   const { data, code } = res; | ||||
|   if (code === 200) { | ||||
|     console.log(data); | ||||
|     attendanceCount.value = data.attendanceCount; | ||||
|     attendanceRate.value = data.attendanceRate; | ||||
|     peopleCount.value = data.peopleCount; | ||||
| @ -148,14 +152,8 @@ const getNewsData = async () => { | ||||
| }; | ||||
|  | ||||
| var lastTime = 0; | ||||
| const state = reactive({ | ||||
|   events: [], | ||||
|   outputList: [], | ||||
|   detialInfoShow: false, | ||||
|   notShowPro: [{ id: 37 }, { id: 44 }, { id: 48 }], //模块内容区域不展示的项目(中煤科工 广东户用光伏项目 兴隆光伏) | ||||
|   scrolltimerTable: null, | ||||
|   flagPause: true //滚动继续滚动 | ||||
| }); | ||||
| var scrolltimerTable = null; | ||||
| var rotate = false; | ||||
|  | ||||
| const autoScrollTable = (time: number) => { | ||||
|   const divData = document.getElementById('event_scroll'); | ||||
| @ -165,10 +163,21 @@ const autoScrollTable = (time: number) => { | ||||
|     return; // 如果时间未到,则返回,不执行动画更新 | ||||
|   } | ||||
|   lastTime = time; | ||||
|   if (rotate) { | ||||
|     divData.scrollTop -= 1; | ||||
|   } else { | ||||
|     divData.scrollTop += 1; | ||||
|   if (divData.clientHeight + divData.scrollTop >= divData.scrollHeight - 1) { | ||||
|     divData.scrollTop = 0; | ||||
|   } | ||||
|   if (divData.clientHeight + divData.scrollTop == divData.scrollHeight) { | ||||
|     rotate = true; | ||||
|     setTimeout(() => { | ||||
|       scrolltimerTable = requestAnimationFrame(autoScrollTable); | ||||
|     }, 1000); | ||||
|   } else if (divData.scrollTop == 0) { | ||||
|     rotate = false; | ||||
|     setTimeout(() => { | ||||
|       scrolltimerTable = requestAnimationFrame(autoScrollTable); | ||||
|     }, 1000); | ||||
|   } else { | ||||
|     scrolltimerTable = requestAnimationFrame(autoScrollTable); | ||||
|   } | ||||
| @ -306,7 +315,9 @@ onUnmounted(() => {}); | ||||
| } | ||||
|  | ||||
| .attendance_list { | ||||
|   padding: 0px 30px; | ||||
|   width: calc(100% - 30px); | ||||
|   padding: 0px 15px; | ||||
|   margin: 0 auto; | ||||
|   font-size: 14px; | ||||
|  | ||||
|   .attendance_item { | ||||
| @ -314,6 +325,22 @@ onUnmounted(() => {}); | ||||
|     grid-template-columns: 3fr 2fr 2fr 3fr; | ||||
|     margin-top: 20px; | ||||
|   } | ||||
|  | ||||
|   &.scroll { | ||||
|     margin-top: 10px; | ||||
|     height: 280px; | ||||
|     overflow-y: auto; | ||||
|  | ||||
|     &::-webkit-scrollbar-track { | ||||
|       background: rgba(204, 204, 204, 0.1); | ||||
|       border-radius: 10px; | ||||
|     } | ||||
|  | ||||
|     &::-webkit-scrollbar-thumb { | ||||
|       background: rgba(29, 214, 255, 0.78); | ||||
|       border-radius: 10px; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| .subfont { | ||||
| @ -330,7 +357,9 @@ onUnmounted(() => {}); | ||||
|   overflow-y: auto; | ||||
|   padding: 10px 15px; | ||||
|   box-sizing: border-box; | ||||
|   background: rgba(255, 255, 255, 0.2); | ||||
|   background: rgba(138, 157, 161, 0.5); | ||||
|   border: 2px dashed rgba(29, 214, 255, 0.3); | ||||
|   border-right: none; | ||||
|   border-radius: 4px; | ||||
|   transition: all 0.3s ease; | ||||
|   opacity: 0; | ||||
| @ -349,22 +378,4 @@ onUnmounted(() => {}); | ||||
|     cursor: pointer; | ||||
|   } | ||||
| } | ||||
|  | ||||
| .detailBox::before { | ||||
|   content: ''; | ||||
|   /* 绝对定位相对于父元素 */ | ||||
|   position: absolute; | ||||
|   /* 定位到左侧中间位置 */ | ||||
|   left: -10px; | ||||
|   top: 50%; | ||||
|   /* 垂直居中 */ | ||||
|   transform: translateY(-50%); | ||||
|   /* 利用边框创建三角形 */ | ||||
|   border-width: 10px 10px 10px 0; | ||||
|   border-style: solid; | ||||
|   /* 三角形颜色与背景匹配,左侧边框透明 */ | ||||
|   border-color: transparent rgba(255, 255, 255, 0.2) transparent transparent; | ||||
|   /* 确保三角形在内容下方 */ | ||||
|   z-index: -1; | ||||
| } | ||||
| </style> | ||||
|  | ||||
| @ -4,10 +4,10 @@ export let pieOption = { | ||||
|     { | ||||
|       type: 'text', | ||||
|       left: 'center', | ||||
|       top: '40%', | ||||
|       top: '43%', | ||||
|       style: { | ||||
|         // 需要从接口替换 | ||||
|         text: '70%', | ||||
|         text: '0%', | ||||
|         fontSize: 24, | ||||
|         fontWeight: 'bold', | ||||
|         fill: '#fff' | ||||
| @ -16,7 +16,7 @@ export let pieOption = { | ||||
|     { | ||||
|       type: 'text', | ||||
|       left: 'center', | ||||
|       top: '50%', | ||||
|       top: '55%', | ||||
|       style: { | ||||
|         text: '总进度', | ||||
|         fontSize: 14, | ||||
| @ -27,7 +27,7 @@ export let pieOption = { | ||||
|   legend: { | ||||
|     show: true, | ||||
|     type: 'plain', | ||||
|     bottom: 20, | ||||
|     bottom: 0, | ||||
|     itemWidth: 12, | ||||
|     itemHeight: 12, | ||||
|     textStyle: { | ||||
| @ -38,7 +38,7 @@ export let pieOption = { | ||||
|     type: 'pie', | ||||
|     data: [], | ||||
|     radius: [50, 80], | ||||
|     center: ['50%', '45%'], | ||||
|     center: ['50%', '50%'], | ||||
|     itemStyle: { | ||||
|       borderColor: '#fff', | ||||
|       borderWidth: 1 | ||||
| @ -73,7 +73,7 @@ export let barOption = { | ||||
|     itemHeight: 12, | ||||
|     // 调整文字与图标间距 | ||||
|     data: ['计划流转面积', '已流转面积'], | ||||
|     top: 0, | ||||
|     top: 10, | ||||
|     right: 20, | ||||
|     textStyle: { | ||||
|       color: '#fff', | ||||
|  | ||||
| @ -4,12 +4,13 @@ | ||||
|       <Title title="项目概况" /> | ||||
|       <div class="content" v-html="generalize"></div> | ||||
|     </div> | ||||
|     <div class="endPage"> | ||||
|     <div class="midPage"> | ||||
|       <Title title="形象进度" /> | ||||
|       <div class="chart_container"> | ||||
|       <div ref="pieChartRef" class="echart" /> | ||||
|         <div ref="lineChartRef" class="echart" /> | ||||
|     </div> | ||||
|     <div class="endPage"> | ||||
|       <Title title="土地流转情况" /> | ||||
|       <div ref="lineChartRef" class="echart" /> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
| @ -40,8 +41,8 @@ let lineChart: any = null; | ||||
| const designAreaData = ref([]) | ||||
| const transferAreaData = ref([]) | ||||
| // 饼图数据 | ||||
| const pieData = [ | ||||
|   { label: 'areaPercentage', name: '厂区', value: 0 }, | ||||
| let pieData = [ | ||||
|   { label: 'areaPercentage', name: '场区', value: 0 }, | ||||
|   { label: 'roadPercentage', name: '道路', value: 0 }, | ||||
|   { label: 'collectorLinePercentage', name: '集电线路', value: 0 }, | ||||
|   { label: 'exportLinePercentage', name: '送出线路', value: 0 }, | ||||
| @ -79,12 +80,6 @@ const initLineChart = () => { | ||||
|   lineChart.setOption(barOption); | ||||
| } | ||||
|  | ||||
| // 响应窗口大小变化 | ||||
| const handleResize = () => { | ||||
|   if (pieChart) pieChart.resize(); | ||||
|   if (lineChart) lineChart.resize(); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 获取项目土地统计数据 | ||||
|  */ | ||||
| @ -109,6 +104,8 @@ const getScreenImgProcessData = async () => { | ||||
|     pieData.forEach((item: any) => { | ||||
|       item.value = data[item.label] | ||||
|     }) | ||||
|     pieData = pieData.filter((item: any) => item.value != '0.0') | ||||
|     console.log(pieData) | ||||
|     initPieChart() | ||||
|   } | ||||
| } | ||||
| @ -118,12 +115,18 @@ const getScreenImgProcessData = async () => { | ||||
|  */ | ||||
| const getScreenGeneralizeData = async () => { | ||||
|   const res = await getScreenGeneralize(props.projectId); | ||||
|   const { data, code } = res | ||||
|   const { data, code, msg } = res | ||||
|   if (code === 200) { | ||||
|     generalize.value = data | ||||
|     generalize.value = msg | ||||
|   } | ||||
| } | ||||
|  | ||||
| // 响应窗口大小变化 | ||||
| const handleResize = () => { | ||||
|   if (pieChart) pieChart.resize(); | ||||
|   if (lineChart) lineChart.resize(); | ||||
| }; | ||||
|  | ||||
| // 组件挂载时初始化图表 | ||||
| onMounted(() => { | ||||
|   getScreenLandData() | ||||
| @ -137,7 +140,6 @@ onMounted(() => { | ||||
|  | ||||
| // 组件卸载时清理 | ||||
| onUnmounted(() => { | ||||
|   window.removeEventListener('resize', handleResize); | ||||
|   if (pieChart) { | ||||
|     pieChart.dispose(); | ||||
|     pieChart = null; | ||||
| @ -156,6 +158,7 @@ onUnmounted(() => { | ||||
|   height: 100%; | ||||
|  | ||||
|   .topPage, | ||||
|   .midPage, | ||||
|   .endPage { | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
| @ -166,20 +169,13 @@ onUnmounted(() => { | ||||
|     box-sizing: border-box; | ||||
|   } | ||||
|  | ||||
|   .endPage { | ||||
|   .endPage, | ||||
|   .midPage { | ||||
|     flex: 1; | ||||
|     margin-top: 23px; | ||||
|  | ||||
|     .chart_container { | ||||
|       display: flex; | ||||
|       flex-direction: column; | ||||
|       gap: 5px; | ||||
|       width: 100%; | ||||
|       height: 100%; | ||||
|     } | ||||
|  | ||||
|     .echart { | ||||
|       height: 48%; | ||||
|       height: 100%; | ||||
|       width: 100%; | ||||
|     } | ||||
|   } | ||||
| @ -189,7 +185,6 @@ onUnmounted(() => { | ||||
|   height: 100px; | ||||
|   margin: 0 15px; | ||||
|   padding: 0 10px; | ||||
|   margin-top: 15px; | ||||
|   box-sizing: border-box; | ||||
|   overflow-y: auto; | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user