增加大屏地图
This commit is contained in:
@@ -1,23 +1,24 @@
|
||||
<!doctype html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta name="renderer" content="webkit" />
|
||||
<meta name="description" content="A Modern Back-end Management System" />
|
||||
<meta name="keywords" content="Vben Admin Vue3 Vite" />
|
||||
<meta name="author" content="Vben" />
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
|
||||
<meta name="renderer" content="webkit"/>
|
||||
<meta name="description" content="A Modern Back-end Management System"/>
|
||||
<meta name="keywords" content="Vben Admin Vue3 Vite"/>
|
||||
<meta name="author" content="Vben"/>
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=0"
|
||||
/>
|
||||
<!-- 由 vite 注入 VITE_APP_TITLE 变量,在 .env 文件内配置 -->
|
||||
<title><%= VITE_APP_TITLE %></title>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<script type="text/javascript" src="/EasyPlayer-element.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
<link rel="icon" href="/favicon.ico"/>
|
||||
<script type="text/javascript"
|
||||
src="https://api.map.baidu.com/api?v=3.0&ak=5GUquqE2yrgMo3BPIGcn89dU8uMhnbxG"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -1,182 +1,194 @@
|
||||
import type { BaseEntity, PageQuery } from '#/api/common'
|
||||
import type { BaseEntity, PageQuery } from '#/api/common';
|
||||
|
||||
export interface DeviceManageVO {
|
||||
/**
|
||||
* 主键id
|
||||
*/
|
||||
id: string | number
|
||||
id: string | number;
|
||||
|
||||
/**
|
||||
* 设备编码
|
||||
*/
|
||||
deviceNo: string
|
||||
deviceNo: string;
|
||||
|
||||
/**
|
||||
* 设备名称
|
||||
*/
|
||||
deviceName: string
|
||||
deviceName: string;
|
||||
|
||||
/**
|
||||
* 设备ip
|
||||
*/
|
||||
deviceIp: string
|
||||
deviceIp: string;
|
||||
|
||||
/**
|
||||
* 设备端口
|
||||
*/
|
||||
devicePort: number
|
||||
devicePort: number;
|
||||
|
||||
/**
|
||||
* 设备账号
|
||||
*/
|
||||
deviceAccount: string
|
||||
deviceAccount: string;
|
||||
|
||||
/**
|
||||
* 设备密码
|
||||
*/
|
||||
devicePwd: string
|
||||
devicePwd: string;
|
||||
|
||||
/**
|
||||
* 设备
|
||||
*/
|
||||
deviceMac: string
|
||||
deviceMac: string;
|
||||
|
||||
/**
|
||||
* 设备在线状态 0:离线 1:在线 2:未知
|
||||
*/
|
||||
deviceStatus: number
|
||||
deviceStatus: number;
|
||||
|
||||
/**
|
||||
* 父级设备id
|
||||
*/
|
||||
parentId: string | number
|
||||
parentId: string | number;
|
||||
|
||||
/**
|
||||
* 设备通道编号
|
||||
*/
|
||||
channelNo: string
|
||||
channelNo: string;
|
||||
|
||||
/**
|
||||
* 录像机ip
|
||||
*/
|
||||
vcrIp: string
|
||||
vcrIp: string;
|
||||
|
||||
/**
|
||||
* 录像机端口
|
||||
*/
|
||||
vcrPort: number
|
||||
vcrPort: number;
|
||||
|
||||
/**
|
||||
* 录像机账号
|
||||
*/
|
||||
vcrAccount: string
|
||||
vcrAccount: string;
|
||||
|
||||
/**
|
||||
* 录像机密码
|
||||
*/
|
||||
vcrPwd: string
|
||||
vcrPwd: string;
|
||||
|
||||
/**
|
||||
* 门禁id
|
||||
*/
|
||||
accessControlId: string | number
|
||||
accessControlId: string | number;
|
||||
|
||||
/**
|
||||
* 楼层id
|
||||
*/
|
||||
floorId: string | number
|
||||
floorId: string | number;
|
||||
|
||||
lon: number;
|
||||
|
||||
lat: number;
|
||||
}
|
||||
|
||||
export interface DeviceManageForm extends BaseEntity {
|
||||
/**
|
||||
* 主键id
|
||||
*/
|
||||
id?: string | number
|
||||
id?: string | number;
|
||||
|
||||
/**
|
||||
* 设备编码
|
||||
*/
|
||||
deviceNo?: string
|
||||
deviceNo?: string;
|
||||
|
||||
/**
|
||||
* 设备名称
|
||||
*/
|
||||
deviceName?: string
|
||||
deviceName?: string;
|
||||
|
||||
/**
|
||||
* 设备ip
|
||||
*/
|
||||
deviceIp?: string
|
||||
deviceIp?: string;
|
||||
|
||||
/**
|
||||
* 设备端口
|
||||
*/
|
||||
devicePort?: number
|
||||
devicePort?: number;
|
||||
|
||||
/**
|
||||
* 设备账号
|
||||
*/
|
||||
deviceAccount?: string
|
||||
deviceAccount?: string;
|
||||
|
||||
/**
|
||||
* 设备密码
|
||||
*/
|
||||
devicePwd?: string
|
||||
devicePwd?: string;
|
||||
|
||||
/**
|
||||
* 设备
|
||||
*/
|
||||
deviceMac?: string
|
||||
deviceMac?: string;
|
||||
|
||||
lon: number;
|
||||
|
||||
lat: number;
|
||||
|
||||
/**
|
||||
* 设备在线状态 0:离线 1:在线 2:未知
|
||||
*/
|
||||
deviceStatus?: number
|
||||
deviceStatus?: number;
|
||||
}
|
||||
|
||||
export interface DeviceManageQuery extends PageQuery {
|
||||
/**
|
||||
* 设备编码
|
||||
*/
|
||||
deviceNo?: string
|
||||
deviceNo?: string;
|
||||
|
||||
/**
|
||||
* 设备名称
|
||||
*/
|
||||
deviceName?: string
|
||||
deviceName?: string;
|
||||
|
||||
/**
|
||||
* 设备ip
|
||||
*/
|
||||
deviceIp?: string
|
||||
deviceIp?: string;
|
||||
|
||||
/**
|
||||
* 设备端口
|
||||
*/
|
||||
devicePort?: number
|
||||
devicePort?: number;
|
||||
|
||||
/**
|
||||
* 设备账号
|
||||
*/
|
||||
deviceAccount?: string
|
||||
deviceAccount?: string;
|
||||
|
||||
/**
|
||||
* 设备密码
|
||||
*/
|
||||
devicePwd?: string
|
||||
devicePwd?: string;
|
||||
|
||||
/**
|
||||
* 设备
|
||||
*/
|
||||
deviceMac?: string
|
||||
deviceMac?: string;
|
||||
|
||||
lon: number;
|
||||
|
||||
lat: number;
|
||||
|
||||
/**
|
||||
* 设备在线状态 0:离线 1:在线 2:未知
|
||||
*/
|
||||
deviceStatus?: number
|
||||
deviceStatus?: number;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any
|
||||
params?: any;
|
||||
}
|
||||
|
BIN
apps/web-antd/src/assets/map/alarm1.png
Normal file
BIN
apps/web-antd/src/assets/map/alarm1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.1 KiB |
BIN
apps/web-antd/src/assets/map/alarm2.png
Normal file
BIN
apps/web-antd/src/assets/map/alarm2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.3 KiB |
BIN
apps/web-antd/src/assets/map/camear.png
Normal file
BIN
apps/web-antd/src/assets/map/camear.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.4 KiB |
BIN
apps/web-antd/src/assets/map/video-bg.png
Normal file
BIN
apps/web-antd/src/assets/map/video-bg.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
File diff suppressed because it is too large
Load Diff
131
apps/web-antd/src/views/screen/monitor/map/Map.vue
Normal file
131
apps/web-antd/src/views/screen/monitor/map/Map.vue
Normal file
@@ -0,0 +1,131 @@
|
||||
<template>
|
||||
<div class="vmap">
|
||||
<div id="map" class="map-animation"></div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="js">
|
||||
import './map.scss';
|
||||
import { icons, MapDefaultData } from './constants.js';
|
||||
import { onMounted } from 'vue';
|
||||
import { deviceManageList } from '#/api/sis/deviceManage/index.js';
|
||||
|
||||
// 地图全局对象
|
||||
let map = null;
|
||||
|
||||
onMounted(() => {
|
||||
mapFn.intiMap();
|
||||
// 加载设备信息
|
||||
deviceManageList({ deviceType: 1 }).then(({ rows = [], total = 0 }) => {
|
||||
if (total > 0) {
|
||||
// 渲染设备点位信息
|
||||
let items = rows.map((item) => {
|
||||
return {
|
||||
icon: 'camera',
|
||||
data: item,
|
||||
lon: item.lon,
|
||||
lat: item.lat,
|
||||
};
|
||||
});
|
||||
mapFn.renderOverLayersData(items, function (marker, data) {
|
||||
// 渲染设备点击事件
|
||||
marker.addEventListener('click', () => {
|
||||
console.log(data);
|
||||
// 查询当前设备的通道信息
|
||||
|
||||
//渲染设备播放列表
|
||||
const html = [
|
||||
'<div class="video-wrap" style="width: 530px;height: 350px;padding-top:50px">',
|
||||
`<div class="wrap-title" style="margin-top: -35px;">${data.deviceName}</div>`,
|
||||
`<div class="close" onclick="pageEvent.closeInfoWindow()">X</div>`,
|
||||
`<div class="wrap-content">`,
|
||||
`<div onclick="pageEvent.playClick()" class="content-left" style="height: 270px">`,
|
||||
'<video id="video-player" ref="player1" muted autoplay></video>',
|
||||
`</div>`,
|
||||
`</div>`,
|
||||
`</div>`,
|
||||
];
|
||||
const infoWindow = new BMap.InfoWindow(html.join(''), {
|
||||
width: 530,
|
||||
height: 350,
|
||||
enableCloseOnClick: false,
|
||||
});
|
||||
map.openInfoWindow(infoWindow, marker.point);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
// 当前页面播放的对象
|
||||
let currentPlayer = undefined;
|
||||
|
||||
window.pageEvent = {
|
||||
closeInfoWindow() {
|
||||
map.closeInfoWindow();
|
||||
closeVideo(currentPlayer);
|
||||
},
|
||||
};
|
||||
|
||||
function closeVideo(player) {
|
||||
if (player) {
|
||||
try {
|
||||
player.pause();
|
||||
player.unload();
|
||||
player.destroy();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 地图相关方法 */
|
||||
const mapFn = {
|
||||
renderOverLayersData(data, cb, clear = true) {
|
||||
// 清楚地图上的图层
|
||||
if (clear) {
|
||||
mapFn.clearLayers();
|
||||
}
|
||||
data.forEach((v) => {
|
||||
const { lon, lat, data, icon } = v;
|
||||
const marker = new BMap.Marker(new BMap.Point(lon, lat), {
|
||||
icon: icons[icon],
|
||||
});
|
||||
// 将数据放入marker
|
||||
marker.data = data;
|
||||
marker.setTop(true, 100);
|
||||
// 保存自定义信息到marker对象中
|
||||
map.addOverlay(marker);
|
||||
if (cb) {
|
||||
cb(marker, data);
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 清除地图上的所有图层
|
||||
*/
|
||||
clearLayers: () => map.clearOverlays(),
|
||||
|
||||
/**
|
||||
* 初始化地图
|
||||
* @param cb 地图初始化的回调函数
|
||||
*/
|
||||
intiMap: function (cb) {
|
||||
// 创建地图实例
|
||||
map = new BMap.Map('map', { enableMapClick: false });
|
||||
// 设置地图中心和初始层级
|
||||
map.centerAndZoom(
|
||||
new BMap.Point(MapDefaultData.center[0], MapDefaultData.center[1]),
|
||||
MapDefaultData.zoom,
|
||||
);
|
||||
// 设置地图样式
|
||||
map.setMapStyleV2({
|
||||
styleId: 'bbb822feddbffbb4dc419fc6c37f2e4e',
|
||||
});
|
||||
// 开启滚轮缩放
|
||||
map.enableScrollWheelZoom(true);
|
||||
map.clearOverlays();
|
||||
if (cb) {
|
||||
cb();
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
16
apps/web-antd/src/views/screen/monitor/map/constants.js
Normal file
16
apps/web-antd/src/views/screen/monitor/map/constants.js
Normal file
@@ -0,0 +1,16 @@
|
||||
import camera from "#/assets/map/camear.png";
|
||||
|
||||
export const MapDefaultData = {
|
||||
center: [107.089,29.1714],
|
||||
zoom: 21,
|
||||
icons: {camera}
|
||||
};
|
||||
|
||||
|
||||
export const icons = {
|
||||
camera: new BMap.Icon(MapDefaultData.icons.camera, new BMap.Size(23, 34), {
|
||||
offset: new BMap.Size(12, 30),
|
||||
textColor: '#fff',
|
||||
zIndex: "100"
|
||||
})
|
||||
}
|
89
apps/web-antd/src/views/screen/monitor/map/map.scss
Normal file
89
apps/web-antd/src/views/screen/monitor/map/map.scss
Normal file
@@ -0,0 +1,89 @@
|
||||
.vmap {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.BMap_pop > div {
|
||||
background: transparent !important;
|
||||
border: 0 !important;
|
||||
}
|
||||
|
||||
.BMap_pop > div:nth-child(n) {
|
||||
display: none
|
||||
}
|
||||
|
||||
.BMap_pop > div:nth-child(9) {
|
||||
display: block
|
||||
}
|
||||
|
||||
.BMap_pop > img {
|
||||
width: 0 !important;
|
||||
height: 0 !important;
|
||||
}
|
||||
|
||||
#map {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.anchorBL {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.close {
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
top: 5px;
|
||||
font-size: 18px;
|
||||
cursor: pointer;
|
||||
border: 1px solid #409eff;
|
||||
color: #409eff;
|
||||
padding: 2px 5px;
|
||||
text-align: center;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.wrap-title {
|
||||
margin-top: 16px;
|
||||
font-size: 16px;
|
||||
color: white;
|
||||
position: absolute;
|
||||
height: 30px;
|
||||
width: 100%;
|
||||
line-height: 30px;
|
||||
left: 20px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.video-wrap {
|
||||
width: 530px !important;
|
||||
height: 360px;
|
||||
background: url("/src/assets/map/video-bg.png") no-repeat;
|
||||
background-size: 100% 100%;
|
||||
|
||||
.wrap-content {
|
||||
padding: 15px 10px 10px 10px;
|
||||
height: 75%;
|
||||
display: flex;
|
||||
|
||||
.content-left {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 111%;
|
||||
}
|
||||
|
||||
.content-right {
|
||||
margin-left: 15px;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -4,9 +4,20 @@
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"#/*": ["./src/*"]
|
||||
"#/*": [
|
||||
"./src/*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"references": [{ "path": "./tsconfig.node.json" }],
|
||||
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "types/**/*.d.ts"]
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.node.json"
|
||||
}
|
||||
],
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"src/**/*.tsx",
|
||||
"src/**/*.vue",
|
||||
"types/**/*.d.ts"
|
||||
]
|
||||
}
|
||||
|
Reference in New Issue
Block a user