<!-- Description: h5-信息查询详情 Author: 李亚光 Date: 2025-01-02 --> <script lang="ts" setup name="H5InfoSearchDetail"> import { showToast } from 'vant' import showPosition from './components/showPosition.vue' import { getDeviceData } from '@/api/mobile/info' import { toHumpObject } from '@/utils/String' const $route = useRoute() // 基本信息 const deviceInfo = ref<any>({}) deviceInfo.value = JSON.parse($route.query.row as string) // 近期数据 const loading = ref(false) const data = ref([]) // 查看位置 const locationRef = ref() const viewLocation = (e) => { if (e.target.innerHTML === ('收起') || e.target.innerHTML === ('展开')) { return } if (!deviceInfo.value.lng || !deviceInfo.value.lat) { showToast('该位置缺少坐标信息'); return } locationRef.value.initDialog([deviceInfo.value.lng, deviceInfo.value.lat]) } // 计算滚动区域高度 const scrollHeight = ref(0) const calcHeight = () => { // 公共头部高度40 // 边距安全 30 // total区域 const totalAreaHeight = document.getElementById('base-info')?.offsetHeight // 查询结果头部 const searchHeaderHeight = document.getElementById('title')?.offsetHeight scrollHeight.value = window.innerHeight - 40 - 30 - (totalAreaHeight || 0) - (searchHeaderHeight || 0) - 14 } const fetchData = () => { getDeviceData({ devcode: deviceInfo.value.devcode, typeName: deviceInfo.value.typeName }).then(res => { data.value = res.data.map((item: any) => toHumpObject(item)) // 上报时间 if (res.data.length) { deviceInfo.value.reportDate = res.data[0].uptime } else { deviceInfo.value.reportDate = '' } loading.value = false }) } onMounted(() => { calcHeight() loading.value = true fetchData() }) window.addEventListener('resize', () => { calcHeight() }) onBeforeUnmount(() => { window.addEventListener('resize', () => { }) }) // 计算电池图标 const calcCellIcon = (cell: string) => { if (!cell) { return '' } if (Number(cell) <= 20) { return 'cell-20' } else if (Number(cell) > 20 && Number(cell) < 70) { return 'cell-40' } else if (Number(cell) >= 70) { return 'cell-70' } } // 计算电池电量进度 const calcCellWidth = (cell: string) => { if (!cell) { return '0' } else { return Number(cell) >= 85 ? `${89}%` : `${cell}%` } } // 计算电池颜色 const calcCellColor = (cell: string) => { if (!cell) { return '' } if (Number(cell) <= 20) { return 'cell-20-color' } else if (Number(cell) > 20 && Number(cell) < 70) { return 'cell-40-color' } else if (Number(cell) >= 70) { return 'cell-70-color' } } </script> <template> <div class="info-container"> <!-- 位置弹窗 --> <show-position ref="locationRef" /> <!-- 基本信息 --> <div id="base-info" class="search-info"> <div class="cell"> <div class="title">设备编号</div> <div class="value">{{ deviceInfo.devcode }}</div> </div> <div class="cell"> <div class="title">设备类型</div> <div class="value">{{ deviceInfo.typeName }}</div> </div> <div class="cell"> <div class="title">位置名称</div> <div class="value">{{ deviceInfo.tagName }}</div> </div> <div class="cell"> <div class="title">安装位置</div> <div class="value">{{ deviceInfo.tagNumber }}</div> </div> <div class="cell"> <div class="title">详细位置</div> <div class="value" @click="(event) => viewLocation(event)"> <!-- {{ deviceInfo.position }} --> <van-text-ellipsis :rows="1" :content="deviceInfo.position" expand-text="展开" collapse-text="收起" /> <span class="location"></span> </div> </div> <div class="cell"> <div class="title">安装日期</div> <div class="value">{{ deviceInfo.installDate }}</div> </div> <div class="cell"> <div class="title">最近上报时间</div> <div class="value">{{ deviceInfo.reportDate }}</div> </div> </div> <!-- 近期数据 --> <div class="search-result"> <div id="title" class="title"> <div class="symbol"></div> 近期数据 </div> <!-- 结果 --> <el-scrollbar ref="scrollbarRef" v-loading="loading" :max-height="`${scrollHeight}px`" style="margin-top: 14px;"> <lazy-component v-if="data.length"> <!-- 燃气智能终端 --> <template v-if="deviceInfo.typeName.includes('燃气智能')"> <div v-for="(item, index) in data" :key="index" :class="index !== 0 ? 'top-border' : ''" class="result-item"> <div class="cell"> <div class="title">{{ item.uptime }}</div> <div class="value"> <!-- 电池图标 --> <div class="cell-icon" :class="calcCellIcon(item.cell)"> <!-- 电池电量 --> <div style="height: 14px;" :style="{ width: `${calcCellWidth(item.cell)}` }" :class="calcCellColor(item.cell)"></div> <!-- 数字 --> <div class="cell-count">{{ item.cell }}</div> </div> </div> </div> <div class="cell"> <div class="title">燃气浓度</div> <div class="value">{{ item.strength }}%LEL</div> </div> </div> </template> <!-- 管网哨兵 --> <template v-if="deviceInfo.typeName.includes('管网哨兵')"> <div v-for="(item, index) in data" :key="index" :class="index !== 0 ? 'top-border' : ''" class="result-item"> <div class="cell"> <div class="title">{{ item.uptime }}</div> <div class="value"> <!-- 电池图标 --> <!-- <div class="cell-icon" :class="calcCellIcon(item.cell)"> --> <!-- 电池电量 --> <!-- <div style="height: 14px;" :style="{ width: `${calcCellWidth(item.cell)}` }" :class="calcCellColor(item.cell)"></div> --> <!-- 数字 --> <!-- <div class="cell-count">{{ item.cell }}</div> --> <!-- </div> --> </div> </div> <div class="cell"> <div class="title">燃气浓度</div> <div class="value">{{ item.gasval }}%LEL</div> </div> </div> </template> </lazy-component> <van-empty v-if="!data.length" description="暂无数据" /> <div v-if="data.length" class="to-top"> <van-back-top /> </div> </el-scrollbar> </div> </div> </template> <style lang="scss" scoped> .cell-icon { position: relative; width: 30px; height: 18px; display: flex; align-items: center; padding-left: 2px; .cell-count { position: absolute; color: #000; text-align: center; left: 50%; top: 50%; transform: translate(-50%, -50%); font-size: 0.8rem; align-items: center; } } .cell-70 { background: url('@/assets/icons/icon-cell-70.svg') no-repeat center center / cover; } .cell-70-color { background-color: rgb(37, 202, 37); } .cell-40 { background: url('@/assets/icons/icon-cell-40.svg') no-repeat center center / cover; } .cell-40-color { background-color: orange; } .cell-20 { background: url('@/assets/icons/icon-cell-20.svg') no-repeat center center / cover; } .cell-20-color { background-color: red; } .info-container { width: 100%; height: calc(100vh - 40px); overflow: hidden; color: #444; .search-info { background-color: #fff; width: 96%; margin: 0 auto; margin-top: 1vh; border-radius: 6px; padding: 4px; padding-top: 0.8rem; padding-bottom: 0.8rem; padding-left: 0.8rem; font-size: 1.1rem; .cell { display: flex; justify-content: space-between; padding-top: 6px; padding-bottom: 6px; padding-right: 14px; align-items: center; .value { color: #888; width: 80%; text-align: right; font-size: 1rem; vertical-align: middle; // display: flex; // flex-direction: column; // justify-content: center; display: flex; align-items: center; justify-content: flex-end; .location { display: inline-block; width: 22px; height: 22px; background: url('@/assets/icons/icon-location.svg') no-repeat center center / cover; vertical-align: middle; margin-left: 8px; } } .title { width: 20%; white-space: nowrap; font-weight: 500; } // .title, // .value { // white-space: nowrap; // overflow: hidden; // text-overflow: ellipsis; // } } } .search-result { background-color: #fff; width: 96%; margin: 0 auto; margin-top: 1vh; border-radius: 6px; padding: 4px; padding-left: 0.6rem; .title { display: flex; font-size: 1.1rem; .symbol { width: 4px; height: 22px; background-color: #0d76d4; border-radius: 4px; margin-right: 8px; } } .top-border { border-top: 1px solid #e4e7ed; // margin-top: 8px; } .result-item { .cell { display: flex; justify-content: space-between; padding-top: 6px; padding-bottom: 6px; padding-right: 18px; align-items: center; .value { color: #888; width: 80%; text-align: right; font-size: 1rem; vertical-align: middle; // display: flex; // flex-direction: column; // justify-content: center; display: flex; align-items: center; justify-content: flex-end; } .title { width: 20%; white-space: nowrap; } } } } } </style>