数据地图
This commit is contained in:
parent
745efa50f3
commit
4d019f3396
|
|
@ -10,5 +10,6 @@
|
|||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
<script type="text/javascript" src="https://api.map.baidu.com/api?v=3.0&ak=cClgLBaLgGUdQDilX9dGvieL"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ watch(
|
|||
navMenuList.value = [
|
||||
{ name: '首页', routerName: 'home', permissions: 'home' },
|
||||
// { name: '数据大屏', routerName: 'big-screen', permissions: 'home' },
|
||||
{ name: '数据地图', routerName: '', permissions: 'home' },
|
||||
{ name: '数据地图', routerName: 'map', permissions: 'home' },
|
||||
{ name: '装备共享大厅', routerName: 'equipList', permissions: 'share' },
|
||||
{ name: '租赁需求大厅', routerName: 'parity', permissions: 'demand' },
|
||||
// { name: '专区设备', routerName: 'zoneEquipment' },
|
||||
|
|
@ -45,7 +45,7 @@ watch(
|
|||
navMenuList.value = [
|
||||
{ name: '首页', routerName: 'home', permissions: 'home' },
|
||||
// { name: '数据大屏', routerName: 'big-screen', permissions: 'home' },
|
||||
{ name: '数据地图', routerName: '', permissions: 'home' },
|
||||
{ name: '数据地图', routerName: 'map', permissions: 'home' },
|
||||
{ name: '装备共享大厅', routerName: 'equipList', permissions: 'home' },
|
||||
{ name: '租赁需求大厅', routerName: 'parity', permissions: 'home' },
|
||||
// { name: '专区设备', routerName: 'zoneEquipment' },
|
||||
|
|
@ -57,7 +57,7 @@ watch(
|
|||
navMenuList.value = [
|
||||
{ name: '首页', routerName: 'home', permissions: 'home' },
|
||||
// { name: '数据大屏', routerName: 'big-screen', permissions: 'home' },
|
||||
{ name: '数据地图', routerName: '', permissions: 'home' },
|
||||
{ name: '数据地图', routerName: 'map', permissions: 'home' },
|
||||
{ name: '装备共享大厅', routerName: 'equipList', permissions: 'home' },
|
||||
// { name: '专区设备', routerName: 'zoneEquipment' },
|
||||
{ name: '租赁需求大厅', routerName: 'parity', permissions: 'home' },
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
import { get, post } from '../../index'
|
||||
|
||||
// 获取坐标点数据
|
||||
export const getMapData = () => {
|
||||
return get('/material-mall/api/mqtt/latest-data', {})
|
||||
}
|
||||
|
|
@ -93,6 +93,17 @@ const routes: Array<RouteRecordRaw> = [
|
|||
activeName: 'home',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'map',
|
||||
name: 'map',
|
||||
component: () => import('views/home/map.vue'),
|
||||
meta: {
|
||||
title: '数据地图',
|
||||
keepAlive: true,
|
||||
AuthFlag: false,
|
||||
activeName: 'map',
|
||||
},
|
||||
},
|
||||
// 自选直租
|
||||
{
|
||||
path: '/equipList',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,91 @@
|
|||
// 坐标转换工具函数
|
||||
const xPI = (Math.PI * 3000.0) / 180.0
|
||||
const PI = Math.PI
|
||||
const a = 6378245.0
|
||||
const ee = 0.00669342162296594323
|
||||
|
||||
function transformlat(lng: number, lat: number): number {
|
||||
let ret =
|
||||
-100.0 +
|
||||
2.0 * lng +
|
||||
3.0 * lat +
|
||||
0.2 * lat * lat +
|
||||
0.1 * lng * lat +
|
||||
0.2 * Math.sqrt(Math.abs(lng))
|
||||
ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0
|
||||
ret += ((20.0 * Math.sin(lat * PI) + 40.0 * Math.sin((lat / 3.0) * PI)) * 2.0) / 3.0
|
||||
ret += ((160.0 * Math.sin((lat / 12.0) * PI) + 320 * Math.sin((lat * PI) / 30.0)) * 2.0) / 3.0
|
||||
return ret
|
||||
}
|
||||
|
||||
function transformlng(lng: number, lat: number): number {
|
||||
let ret =
|
||||
300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng))
|
||||
ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0
|
||||
ret += ((20.0 * Math.sin(lng * PI) + 40.0 * Math.sin((lng / 3.0) * PI)) * 2.0) / 3.0
|
||||
ret += ((150.0 * Math.sin((lng / 12.0) * PI) + 300.0 * Math.sin((lng / 30.0) * PI)) * 2.0) / 3.0
|
||||
return ret
|
||||
}
|
||||
|
||||
function convertDmToDd(dmValue: any) {
|
||||
// 确保是字符串类型
|
||||
const str = dmValue.toString()
|
||||
|
||||
// 经度处理(dddmm.mmmm)
|
||||
if (str.length > 11) {
|
||||
const degrees = parseFloat(str.substring(0, 3))
|
||||
const minutes = parseFloat(str.substring(3))
|
||||
return degrees + minutes / 60
|
||||
}
|
||||
// 纬度处理(ddmm.mmmm)
|
||||
else {
|
||||
const degrees = parseFloat(str.substring(0, 2))
|
||||
const minutes = parseFloat(str.substring(2))
|
||||
return degrees + minutes / 60
|
||||
}
|
||||
}
|
||||
|
||||
interface CoordInfo {
|
||||
[key: string]: any
|
||||
latitude: number
|
||||
longitude: number
|
||||
}
|
||||
|
||||
/**
|
||||
* WGS84 -> GCJ02 -> BD09
|
||||
* @param lng 原始经度
|
||||
* @param lat 原始纬度
|
||||
* @param extra 需要合并返回的额外信息
|
||||
* @returns 返回包含百度坐标系的对象(包含额外字段)
|
||||
*/
|
||||
export function wgs84ToGcj02ToBd09Public(
|
||||
lng: number,
|
||||
lat: number,
|
||||
extra: { [key: string]: any } = {},
|
||||
): CoordInfo {
|
||||
lng = convertDmToDd(lng)
|
||||
lat = convertDmToDd(lat)
|
||||
// Step 1: WGS84 -> GCJ02
|
||||
let dlat = transformlat(lng - 105.0, lat - 35.0)
|
||||
let dlng = transformlng(lng - 105.0, lat - 35.0)
|
||||
let radlat = (lat / 180.0) * PI
|
||||
let magic = Math.sin(radlat)
|
||||
magic = 1 - ee * magic * magic
|
||||
let sqrtmagic = Math.sqrt(magic)
|
||||
dlat = (dlat * 180.0) / (((a * (1 - ee)) / (magic * sqrtmagic)) * PI)
|
||||
dlng = (dlng * 180.0) / ((a / sqrtmagic) * Math.cos(radlat) * PI)
|
||||
let mglat = lat + dlat
|
||||
let mglng = lng + dlng
|
||||
|
||||
// Step 2: GCJ02 -> BD09
|
||||
let z = Math.sqrt(mglng * mglng + mglat * mglat) + 0.00002 * Math.sin(mglat * xPI)
|
||||
let theta = Math.atan2(mglat, mglng) + 0.000003 * Math.cos(mglng * xPI)
|
||||
let bdlng = z * Math.cos(theta) + 0.0065
|
||||
let bdlat = z * Math.sin(theta) + 0.006
|
||||
|
||||
return {
|
||||
...extra,
|
||||
longitude: bdlng,
|
||||
latitude: bdlat,
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,896 @@
|
|||
<script setup lang="ts">
|
||||
import EquipCard from 'components/equipCard.vue'
|
||||
import EquipCardNew from 'components/equipCardNew/index.vue'
|
||||
import NavMenu from 'components/Navmenu/index.vue'
|
||||
import { getGoodsClassListApi, getCompanyListApi, getSwiperListApi } from 'http/api/home'
|
||||
import { useStore } from 'store/user'
|
||||
import { mainStore } from 'store/main'
|
||||
import { getHotList } from 'http/api/equip'
|
||||
import { loginNewApi } from 'http/api/home/index'
|
||||
import { getUserInfoAPI } from 'http/api/login/index'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { wgs84ToGcj02ToBd09Public } from 'utils/map'
|
||||
import { getMapData } from 'http/api/map'
|
||||
|
||||
const router: any = useRouter()
|
||||
const userStore = useStore()
|
||||
const store: any = mainStore()
|
||||
const tokenNew = localStorage.getItem('tokenNew')
|
||||
const companyList: any = ref([])
|
||||
const classList: any = ref([])
|
||||
const selectOptions = ref<boolean>(false) // 分类
|
||||
const selectOptionsValue = ref<string>('分类筛选')
|
||||
const mapContainer = ref(null) // 地图容器
|
||||
const mapDialog = ref(false) // 地图弹框
|
||||
// 标记点
|
||||
const points: any = ref([])
|
||||
const mapData = ref()
|
||||
const tagData: any = ref()
|
||||
const tagIndex: any = ref()
|
||||
|
||||
// 获取地图数据
|
||||
const getMapDataList = async () => {
|
||||
try {
|
||||
const res: any = await getMapData()
|
||||
console.log('🚀 ~ getMapDataList ~ res:', res)
|
||||
mapData.value = res.data
|
||||
console.log('🚀 ~ getMapDataList ~ mapData.value:', mapData.value.longitude)
|
||||
let { longitude, latitude } = wgs84ToGcj02ToBd09Public(
|
||||
Number(mapData.value.longitude),
|
||||
Number(mapData.value.latitude),
|
||||
)
|
||||
mapData.value.longitude = longitude
|
||||
mapData.value.latitude = latitude
|
||||
console.log('🚀 ~ getMapDataList ~ longitude:', longitude, latitude)
|
||||
points.value.push({
|
||||
id: 4,
|
||||
lng: longitude,
|
||||
lat: latitude,
|
||||
})
|
||||
initMap()
|
||||
} catch (error) {
|
||||
console.log('🚀 ~ getMapDataList ~ error:', error)
|
||||
initMap()
|
||||
}
|
||||
}
|
||||
|
||||
// 获取公司名称
|
||||
const getCompanyListData = async () => {
|
||||
const res: any = await getCompanyListApi()
|
||||
const result: any = await getGoodsClassListApi()
|
||||
// 过滤掉 isShow 为 false 的数据
|
||||
companyList.value = res.data.filter((item: any) => item.isShow)
|
||||
// console.log('🚀 ~ getCompanyListData ~ companyList.value:', companyList.value)
|
||||
classList.value = result.data
|
||||
// console.log('res公司名称', res)
|
||||
}
|
||||
|
||||
getCompanyListData()
|
||||
|
||||
// 点击跳转装备共享大厅
|
||||
const onSharedHall = (level: number, typeId: any, name: any) => {
|
||||
router.push({
|
||||
name: 'equipList',
|
||||
query: {
|
||||
level,
|
||||
typeId,
|
||||
name,
|
||||
},
|
||||
})
|
||||
}
|
||||
const onSharedHallByCompany = (companyId: any, name: any) => {
|
||||
router.push({
|
||||
name: 'equipList',
|
||||
query: {
|
||||
companyId,
|
||||
name,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const handlerGoodsDetails = (...arg: any) => {
|
||||
const arr = arg.map((key: any, index: number) => {
|
||||
return {
|
||||
level: index + 1 + '',
|
||||
typeId: key.id,
|
||||
typeName: key.name,
|
||||
}
|
||||
})
|
||||
|
||||
router.push({
|
||||
name: 'equipList',
|
||||
state: { typeTag: arr },
|
||||
})
|
||||
}
|
||||
|
||||
const hotDeviceList: any = ref([])
|
||||
|
||||
/* 获取热搜装备 */
|
||||
const getHotDeviceList = async () => {
|
||||
const res: any = await getHotList({ pageSize: 3 })
|
||||
hotDeviceList.value = res.data
|
||||
}
|
||||
|
||||
/* 热搜卡片点击跳转至详情页 */
|
||||
const onClick = (val: any) => {
|
||||
router.push({
|
||||
name: 'equipDetail',
|
||||
query: {
|
||||
id: val.id,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 分类点击事件
|
||||
const onSelectOptions = () => {
|
||||
selectOptions.value = !selectOptions.value
|
||||
}
|
||||
|
||||
// 分类选择事件
|
||||
const onSelectItem = (type: number) => {
|
||||
if (type === 1) {
|
||||
selectOptionsValue.value = '分类筛选'
|
||||
} else {
|
||||
selectOptionsValue.value = '公司筛选'
|
||||
}
|
||||
selectOptions.value = false
|
||||
}
|
||||
|
||||
const swiperList = ref([])
|
||||
// 获取轮播图
|
||||
const getSwiperListData = async () => {
|
||||
const res: any = await getSwiperListApi()
|
||||
swiperList.value = res.rows
|
||||
// console.log(res, '轮播图信息')
|
||||
}
|
||||
|
||||
const onClickSwiper = (item: any) => {
|
||||
if (item.slideLink) {
|
||||
const link = item.slideLink.startsWith('http')
|
||||
? item.slideLink
|
||||
: `https://${item.slideLink}`
|
||||
window.open(link, '_blank')
|
||||
} else {
|
||||
router.push({ name: 'equipList' })
|
||||
}
|
||||
}
|
||||
|
||||
getSwiperListData()
|
||||
|
||||
const formatUtcTimeV2 = (utcTime: any, date: any) => {
|
||||
if (!utcTime || !date) return '未知时间'
|
||||
|
||||
// 解析UTC时间和日期
|
||||
const hours = parseInt(utcTime.substring(0, 2))
|
||||
const minutes = parseInt(utcTime.substring(2, 4))
|
||||
const seconds = parseInt(utcTime.substring(4, 6))
|
||||
|
||||
const day = parseInt(date.substring(0, 2))
|
||||
const month = parseInt(date.substring(2, 4)) - 1 // 月份是0-11
|
||||
const year = 2000 + parseInt(date.substring(4, 6)) // 假设是20xx年
|
||||
|
||||
// 创建UTC时间对象
|
||||
const utcDate = new Date(Date.UTC(year, month, day, hours, minutes, seconds))
|
||||
|
||||
// 转换为北京时间 (UTC+8)
|
||||
// const beijingOffset = 8 * 60 * 60 * 1000; // 8小时的毫秒数
|
||||
const beijingTime = new Date(utcDate.getTime())
|
||||
|
||||
// 格式化输出
|
||||
return `${beijingTime
|
||||
.toLocaleString('zh-CN', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
hour12: false,
|
||||
})
|
||||
.replace(/\//g, '-')} (北京时间)`
|
||||
}
|
||||
|
||||
const initMap = () => {
|
||||
if (window.BMap) {
|
||||
const map = new BMap.Map(mapContainer.value)
|
||||
const point = new BMap.Point(106.6302, 26.6477) // 默认贵州贵阳
|
||||
// 添加标记点
|
||||
points.value.forEach((item: any) => {
|
||||
const point = new BMap.Point(item.lng, item.lat)
|
||||
const marker = new BMap.Marker(point)
|
||||
map.addOverlay(marker)
|
||||
// const label = new BMap.Label(item.name, { offset: new BMap.Size(20, -10) })
|
||||
// marker.setLabel(label) // 设置标记点名称
|
||||
marker.addEventListener('click', () => {
|
||||
// 点击标记点事件
|
||||
console.log('点击了标记点')
|
||||
// 打开详情弹框 - 目前没有
|
||||
mapDialog.value = true
|
||||
tagData.value = mapData.value.aphase
|
||||
tagIndex.value = 1
|
||||
})
|
||||
})
|
||||
map.centerAndZoom(point, 7) // 设置地图中心点及缩放级别
|
||||
map.enableScrollWheelZoom(true) // 启用滚轮缩放
|
||||
// 将贵阳整个地图放大到级别 7
|
||||
} else {
|
||||
console.error('BMap 未加载')
|
||||
}
|
||||
}
|
||||
|
||||
const handleTag = (tag: number) => {
|
||||
console.log('tag', tag)
|
||||
tagIndex.value = tag
|
||||
if (tag == 1) {
|
||||
tagData.value = mapData.value.aphase
|
||||
} else if (tag == 2) {
|
||||
tagData.value = mapData.value.bphase
|
||||
} else {
|
||||
tagData.value = mapData.value.cphase
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
getMapDataList()
|
||||
if (!tokenNew) {
|
||||
const origin = window.location.href
|
||||
|
||||
console.log(origin.split('ticket=')[1], 'origin')
|
||||
|
||||
if (origin.indexOf('ticket') != -1) {
|
||||
// console.log('origin.split爱玩送ticket')
|
||||
const res: any = await loginNewApi({
|
||||
ticket: origin.split('ticket=')[1].split('#/')[0],
|
||||
sysType: 0,
|
||||
})
|
||||
|
||||
store.setToken(res.data.access_token)
|
||||
localStorage.setItem('tokenNew', res.data.access_token)
|
||||
const result: any = await getUserInfoAPI()
|
||||
store.setUserInfo(result.user)
|
||||
const roles = result.roles
|
||||
const isAdmin = roles.some((e: any) => e == 'admin')
|
||||
|
||||
if (isAdmin) {
|
||||
localStorage.setItem('rolesType', '3')
|
||||
} else {
|
||||
localStorage.setItem('rolesType', '1')
|
||||
}
|
||||
userStore.editcurrentMenuItem('goodsManagement')
|
||||
// 跳转登录页面
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="home-index-banner">
|
||||
<div class="home-index">
|
||||
<!-- 商品菜单导航以及轮播图区域 -->
|
||||
<div class="home-goods">
|
||||
<ul class="left-nav">
|
||||
<!-- 左侧机械名称菜单按钮 -->
|
||||
<li class="left-filter" @click="onSelectOptions">
|
||||
<div>
|
||||
{{ selectOptionsValue }}
|
||||
<el-icon style="margin-left: 10px"><ArrowDownBold /></el-icon>
|
||||
</div>
|
||||
|
||||
<div class="select-options" v-if="selectOptions">
|
||||
<div @click.stop="onSelectItem(1)">分类筛选</div>
|
||||
<div @click.stop="onSelectItem(2)">公司筛选</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<template v-if="selectOptionsValue === '分类筛选'">
|
||||
<div v-for="item in classList" :key="item.name" class="item-container">
|
||||
<li class="item-nav" @click="onSharedHall(1, item.id, item.name)">
|
||||
{{ item.name }}
|
||||
<ul class="sub-goods">
|
||||
<!-- 级联框内 类别名称 -->
|
||||
<li
|
||||
v-for="child in item.children"
|
||||
:key="child.id"
|
||||
@click.stop="onSharedHall(2, child.id, child.name)"
|
||||
>
|
||||
<!-- 第二级 -->
|
||||
<span class="second-name">
|
||||
{{ child.name }}
|
||||
</span>
|
||||
|
||||
<span style="display: flex; flex: 1; flex-wrap: wrap">
|
||||
<a
|
||||
v-for="son in child.children"
|
||||
:key="son.id"
|
||||
style="font-size: 14px; font-weight: normal"
|
||||
@click.stop="onSharedHall(3, son.id, son.name)"
|
||||
>
|
||||
{{ son.name }} ( {{ son.maCount }} )
|
||||
</a>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<div
|
||||
v-for="item in companyList"
|
||||
:key="item.companyId"
|
||||
class="item-container"
|
||||
>
|
||||
<li
|
||||
class="item-nav"
|
||||
@click="onSharedHallByCompany(item.companyId, item.companyName)"
|
||||
>
|
||||
{{ item.companyName }}
|
||||
{{ item.maCount ? `(${item.maCount})` : '(0)' }}
|
||||
</li>
|
||||
</div>
|
||||
</template>
|
||||
</ul>
|
||||
<div class="right-content">
|
||||
<NavMenu />
|
||||
<!-- 地图 -->
|
||||
<div class="swiper-img">
|
||||
<div ref="mapContainer" style="width: 100%; height: 100%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 热搜装备 -->
|
||||
|
||||
<div class="hot-equip-container" v-if="false">
|
||||
<div class="hot-equip">
|
||||
<span>最新装备</span>
|
||||
<a
|
||||
@click="
|
||||
() => {
|
||||
router.push({ name: 'equipList' })
|
||||
}
|
||||
"
|
||||
style="
|
||||
color: #00a288;
|
||||
font-weight: bold;
|
||||
text-decoration: underline;
|
||||
font-size: 16px;
|
||||
letter-spacing: 1px;
|
||||
"
|
||||
>更多产品</a
|
||||
>
|
||||
</div>
|
||||
|
||||
<div v-for="item in hotDeviceList" :key="item.typeName" style="margin-top: 15px">
|
||||
<div class="hot-title">
|
||||
{{ item.typeName }}
|
||||
</div>
|
||||
<ul class="equip-pic">
|
||||
<li v-for="g in item.devInfoList" :key="g.maId" style="cursor: pointer">
|
||||
<EquipCardNew
|
||||
@onClick="onClick"
|
||||
:id="g.maId"
|
||||
:companyId="g.companyId"
|
||||
:company="g.companyName"
|
||||
:operateAddress="g.operateAddress"
|
||||
:name="g.deviceName"
|
||||
:typeName="g.typeName"
|
||||
:price="g.dayLeasePrice"
|
||||
:url="g.picUrl"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-dialog v-model="mapDialog" title="IOT设备信息" width="70%">
|
||||
<div>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12" style="margin-bottom: 20px">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>设备信息</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="card-item">
|
||||
<span class="card-title">设备UUID: </span>{{ mapData.uuid }}
|
||||
</div>
|
||||
<div class="card-item">
|
||||
<span class="card-title">最后更新时间: </span
|
||||
>{{ formatUtcTimeV2(mapData.utcTime, mapData.date) }}
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="12" style="margin-bottom: 20px">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>环境数据</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="card-item">
|
||||
<span class="card-title">温度: </span>{{ mapData.temperature }}℃
|
||||
</div>
|
||||
<div class="card-item">
|
||||
<span class="card-title">湿度: </span>{{ mapData.humidity }}%
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="12" style="margin-bottom: 20px">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>位置信息</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="card-item">
|
||||
<span class="card-title">经度: </span>{{ mapData.longitude }} N
|
||||
</div>
|
||||
<div class="card-item">
|
||||
<span class="card-title">维度: </span>{{ mapData.latitude }} E
|
||||
</div>
|
||||
<div class="card-item">
|
||||
<span class="card-title">速度: </span>{{ mapData.speedOverGround }} 节
|
||||
</div>
|
||||
<div class="card-item">
|
||||
<span class="card-title">航向: </span
|
||||
>{{ mapData.courseOverGround || 0 }}°
|
||||
</div>
|
||||
<div class="card-item">
|
||||
<span class="card-title">海拔: </span>{{ mapData.altitude }} 米
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="12" style="margin-bottom: 20px">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>运动传感器数据</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="card-item">
|
||||
<span class="card-title">X轴加速度: </span>{{ mapData.accX }} m/s²
|
||||
</div>
|
||||
<div class="card-item">
|
||||
<span class="card-title">Y轴加速度: </span>{{ mapData.accY }} m/s²
|
||||
</div>
|
||||
<div class="card-item">
|
||||
<span class="card-title">Z轴加速度: </span>{{ mapData.accZ }} m/s²
|
||||
</div>
|
||||
<div class="card-item">
|
||||
<span class="card-title">X轴角速度: </span>{{ mapData.gyroX }} m/s²
|
||||
</div>
|
||||
<div class="card-item">
|
||||
<span class="card-title">Y轴角速度: </span>{{ mapData.gyroY }} m/s²
|
||||
</div>
|
||||
<div class="card-item">
|
||||
<span class="card-title">Z轴角速度: </span>{{ mapData.gyroZ }} m/s²
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="24" style="margin-bottom: 20px">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>运动传感器数据</span>
|
||||
</div>
|
||||
</template>
|
||||
<div
|
||||
class="card-item"
|
||||
style="display: flex; justify-content: space-between"
|
||||
>
|
||||
<div><span class="card-title">定位质量: </span>{{ 'GPS定位' }}</div>
|
||||
<div>
|
||||
<span class="card-title">使用卫星数: </span
|
||||
>{{ mapData.numSatellitesUsed }}
|
||||
</div>
|
||||
<div><span class="card-title">水平精度: </span>{{ mapData.hdop }}</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="24" style="margin-bottom: 20px">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>电力数据</span>
|
||||
</div>
|
||||
</template>
|
||||
<div style="margin-bottom: 15px">
|
||||
<el-button :type="tagIndex == 1 ? 'primary' : ''" @click="handleTag(1)"
|
||||
>A组</el-button
|
||||
>
|
||||
<el-button :type="tagIndex == 2 ? 'primary' : ''" @click="handleTag(2)"
|
||||
>B组</el-button
|
||||
>
|
||||
<el-button :type="tagIndex == 3 ? 'primary' : ''" @click="handleTag(3)"
|
||||
>C组</el-button
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
class="card-item"
|
||||
style="display: flex; justify-content: space-between"
|
||||
>
|
||||
<div>
|
||||
<div class="item">
|
||||
<span class="card-title">电压: </span>{{ tagData.voltage }} W
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="card-title">电流: </span>{{ tagData.current }} A
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="card-title">有功功率: </span
|
||||
>{{ tagData.activePower }} V
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="item">
|
||||
<span class="card-title">无功功率: </span
|
||||
>{{ tagData.reactivePower }} VAR
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="card-title">功率因素: </span
|
||||
>{{ tagData.powerFactor }}
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="card-title">频率: </span>{{ tagData.frequency }} Hz
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="item">
|
||||
<span class="card-title">正向有功: </span
|
||||
>{{ tagData.forwardActiveEnergy }} kWh
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="card-title">正向无功: </span
|
||||
>{{ tagData.forwardReactiveEnergy }} kvarh
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="card-title">反向有功: </span
|
||||
>{{ tagData.reverseActiveEnergy }} kWh
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="item">
|
||||
<span class="card-title">反向无功: </span
|
||||
>{{ tagData.reverseReactiveEnergy }} kvarh
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="card-title">视在功率: </span
|
||||
>{{ tagData.apparentPower }} VA
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="card-title">谐波有功: </span
|
||||
>{{ tagData.harmonicActivePower }} W
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="card-title">基波有功: </span
|
||||
>{{ tagData.fundamentalActivePower }} W
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="card-title">基波无功: </span
|
||||
>{{ tagData.fundamentalReactivePower }} VAR
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="mapDialog = false">关闭</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card-item {
|
||||
margin-bottom: 15px;
|
||||
text-align: left;
|
||||
.item {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
}
|
||||
.card-title {
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
:deep(.el-carousel__container) {
|
||||
.el-carousel__item {
|
||||
.el-image {
|
||||
height: 100%;
|
||||
img {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.home-index-banner {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.home-index {
|
||||
.home-goods {
|
||||
height: 700px;
|
||||
display: flex;
|
||||
position: relative;
|
||||
|
||||
.left-nav {
|
||||
width: 270px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
background-color: #f7f9fa;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
border-radius: 16px;
|
||||
|
||||
.left-filter {
|
||||
margin-top: 10px;
|
||||
padding: 16px 0;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-content: center;
|
||||
justify-content: center;
|
||||
color: #38b2a4;
|
||||
font-size: 22px;
|
||||
// height: 46px;
|
||||
// line-height: 46px;
|
||||
// text-align: center;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
|
||||
width: 100%;
|
||||
|
||||
.select-options {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
|
||||
transform: translate(50%, 100%);
|
||||
// left: 50%;
|
||||
// bottom: -65px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
|
||||
// transform: translateX(-50%);
|
||||
background-color: #fff;
|
||||
|
||||
div {
|
||||
padding: 10px 30px;
|
||||
text-align: left;
|
||||
// font-size: 14px;
|
||||
font-size: 16px;
|
||||
font-weight: normal;
|
||||
cursor: pointer;
|
||||
color: #333;
|
||||
}
|
||||
div:hover {
|
||||
color: #fff;
|
||||
background-color: #00a288;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.item-container {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
.item-nav {
|
||||
// text-align: left;
|
||||
// padding-left: 50px;
|
||||
display: inline-block;
|
||||
margin-top: 10px;
|
||||
// padding: 0 10px;
|
||||
color: #000;
|
||||
min-height: 32px;
|
||||
line-height: 32px;
|
||||
text-align: center;
|
||||
padding: 2px 20px;
|
||||
// font-size: 16px !important;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
// color: #2282ff;
|
||||
// font-weight: bold;
|
||||
background-color: #1abc9c;
|
||||
border-radius: 18px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.sub-goods {
|
||||
position: absolute;
|
||||
display: none;
|
||||
top: 0;
|
||||
left: 270px;
|
||||
width: 1242px;
|
||||
min-height: 100%;
|
||||
max-height: 100%;
|
||||
background-color: #fff;
|
||||
z-index: 999;
|
||||
// opacity: 0.9;
|
||||
border: 1px solid #eee;
|
||||
overflow-y: auto;
|
||||
box-sizing: border-box;
|
||||
|
||||
li {
|
||||
// margin: 10px 0;
|
||||
padding: 10px 80px;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
// background: orange;
|
||||
|
||||
.second-name {
|
||||
// width: 160px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
span a {
|
||||
margin: 0 30px;
|
||||
font-size: 16px;
|
||||
font-weight: normal;
|
||||
color: #333;
|
||||
&:hover {
|
||||
color: #1abc9c;
|
||||
border-bottom: 1px solid #1abc9c !important;
|
||||
}
|
||||
}
|
||||
|
||||
.last-level {
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
.last-level:hover {
|
||||
color: #1abc9c;
|
||||
border-bottom: 1px solid #1abc9c !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.item-container:hover {
|
||||
.sub-goods {
|
||||
display: block !important;
|
||||
z-index: 9999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right-content {
|
||||
box-sizing: border-box;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
margin-left: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.swiper-img {
|
||||
margin-top: 20px;
|
||||
flex: 1;
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.hot-equip {
|
||||
margin-top: 30px;
|
||||
height: 37px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
span {
|
||||
background-color: #1abc9c;
|
||||
padding: 10px 18px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
a {
|
||||
color: rgba(24, 103, 221, 0.8);
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.hot-title {
|
||||
padding: 15px 0 10px 20px;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
.equip-pic {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
li {
|
||||
width: calc((100% - 100px) / 4);
|
||||
margin: 8px 0 8px 20px;
|
||||
&:nth-child(4n) {
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.consult-nav {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
display: flex;
|
||||
|
||||
li {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
margin: 0 15px;
|
||||
|
||||
&:hover {
|
||||
border-bottom: 1px solid #3cb4a6;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.consult-content {
|
||||
margin-top: 20px;
|
||||
height: 210px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.left-bg {
|
||||
background: url(../../assets/img/home/2023_12_01_beijing2/left_bg.png) no-repeat;
|
||||
background-size: cover;
|
||||
width: 340px;
|
||||
height: 210px;
|
||||
}
|
||||
|
||||
.right-consult {
|
||||
height: 210px;
|
||||
flex: 1;
|
||||
width: calc(100% - 340px);
|
||||
// padding-left: 35px;
|
||||
overflow-y: auto;
|
||||
.consult-box {
|
||||
margin-bottom: 10px;
|
||||
//height: 70px;
|
||||
padding-left: 15px;
|
||||
cursor: pointer;
|
||||
.consult-title {
|
||||
height: 30px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
h2 {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
span {
|
||||
color: #827d7d;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.consult-info {
|
||||
width: calc(100% - 100px);
|
||||
height: 10px;
|
||||
line-height: 40px;
|
||||
border-bottom: 1px dashed #979797;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-carousel__container) {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.el-carousel--horizontal {
|
||||
border-radius: 14px;
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue