Files
td_official/src/views/enterpriseLarge/digitalizationScreen/components/centerPage.vue
2025-09-09 15:37:59 +08:00

276 lines
6.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="centerPage">
<div class="topPage">
<div id="earth" style="width: 100%;height: 100%;"></div>
</div>
<div class="endPage" :class="{ 'slide-out-down': isHide }">
<Title title="AI安全巡检">
<img src="@/assets/projectLarge/robot.svg" alt="" height="20px" width="20px">
</Title>
<div class="swiper" v-if="inspectionList.length">
<div class="arrow" :class="{ 'canUse': canLeft }" @click="swiperClick('left')">
<el-icon size="16" :color="canLeft ? 'rgba(29, 214, 255, 1)' : 'rgba(29, 214, 255, 0.3)'">
<ArrowLeft />
</el-icon>
</div>
<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>
</div>
<div class="arrow" :class="{ 'canUse': canRight }" @click="swiperClick('right')">
<el-icon size="16" :color="canRight ? 'rgba(29, 214, 255, 1)' : 'rgba(29, 214, 255, 0.3)'">
<ArrowRight />
</el-icon>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, toRefs, getCurrentInstance } from "vue"
import Title from './title.vue'
import { ArrowLeft, ArrowRight } from '@element-plus/icons-vue'
import { getScreenSafetyInspection } from '@/api/projectScreen'
const { proxy } = getCurrentInstance();
const { violation_level_type } = toRefs(proxy?.useDict('violation_level_type'));
const props = defineProps({
isHide: {
type: Boolean,
default: false
},
projectId: {
type: String,
default: ""
}
})
const inspectionList = ref([{
id: "",
label: "",
picture: "",
createTime: ""
}])
const swiperContent = ref()
const swiperItemWidth = ref(100)
const canLeft = ref(false)
const canRight = ref(true)
const swiperClick = (direction) => {
if (!swiperContent.value) return
if (direction === 'right') {
if (swiperContent.value.scrollLeft >= swiperContent.value.scrollWidth - swiperContent.value.clientWidth) {
canRight.value = false
canLeft.value = true
return
}
swiperContent.value.scrollLeft += swiperItemWidth.value
} else {
if (swiperContent.value.scrollLeft <= 0) {
canLeft.value = false
canRight.value = true
return
}
swiperContent.value.scrollLeft -= swiperItemWidth.value
}
// 更新箭头状态
canLeft.value = swiperContent.value.scrollLeft > 0
canRight.value = swiperContent.value.scrollLeft < swiperContent.value.scrollWidth - swiperContent.value.clientWidth
}
const getInspectionList = async () => {
const res = await getScreenSafetyInspection(props.projectId)
const { code, data } = res
if (code === 200) {
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()
createEarth()
if (swiperContent.value && swiperContent.value.children.length > 0) {
swiperItemWidth.value = swiperContent.value.children[0].clientWidth + 20
}
})
</script>
<style scoped lang="scss">
.centerPage {
display: flex;
flex-direction: column;
height: 100%;
}
.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);
box-sizing: border-box;
}
.topPage {
flex: 1;
margin-bottom: 23px;
transition: flex 0.5s ease;
}
.endPage {
max-height: 300px;
opacity: 1;
transition: all 0.5s ease;
}
/* 向下滑出动画 */
.slide-out-down {
transform: translateY(100%);
opacity: 0;
max-height: 0;
padding: 0;
margin: 0;
border: none;
}
.swiper {
width: 100%;
display: flex;
align-items: center;
gap: 20px;
padding: 20px 20px 10px 20px;
.swiper_content {
width: 100%;
display: flex;
gap: 20px;
transition: all 0.3s ease-in-out;
overflow-x: auto;
&::-webkit-scrollbar {
display: none;
}
}
.swiper_item {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
width: 133px;
height: 84px;
.swiper_img {
width: 133px;
height: 84px;
object-fit: cover;
}
.swiper_date {
position: absolute;
top: 4px;
right: 4px;
font-size: 14px;
font-weight: 400;
color: rgba(230, 247, 255, 1);
}
.swiper_tip {
position: absolute;
bottom: 0;
width: 100%;
padding: 5px 0;
text-align: center;
font-size: 12px;
font-weight: 400;
color: rgba(230, 247, 255, 1);
background-color: rgba(0, 0, 0, 0.5);
}
}
}
.arrow {
display: grid;
place-items: center;
width: 24px;
height: 24px;
border-radius: 50%;
border: 1px solid rgba(29, 214, 255, 0.3);
color: skyblue;
cursor: pointer;
transition: all 0.3s ease;
&.canUse {
border: 1px solid rgba(29, 214, 255, 1);
}
&:hover:not(.canUse) {
opacity: 0.7;
}
}
</style>