Compare commits
2 Commits
32868dd4ca
...
ec9651b9ce
| Author | SHA1 | Date |
|---|---|---|
|
|
ec9651b9ce | |
|
|
e4d22794ef |
Binary file not shown.
|
After Width: | Height: | Size: 9.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
|
|
@ -3,6 +3,7 @@ import { GetClockOnListParams } from './model/patrol';
|
|||
|
||||
enum Api {
|
||||
GetPatrolInfoByUserId = '/api/FirePatrol/GetPatrolInfoByUserId',
|
||||
GetPatrolPointByTimeSubsection = '/api/FirePatrol/GetPatrolPointByTimeSubsection',
|
||||
}
|
||||
/**
|
||||
* @description: 获取人员巡查轨迹
|
||||
|
|
@ -10,3 +11,9 @@ enum Api {
|
|||
export function getPatrolInfoByUserId(params: GetClockOnListParams) {
|
||||
return defHttp.get({ url: Api.GetPatrolInfoByUserId, params });
|
||||
}
|
||||
/**
|
||||
* @description: 获取巡查信息
|
||||
*/
|
||||
export function getPatrolPointByTimeSubsection(params: GetClockOnListParams) {
|
||||
return defHttp.get({ url: Api.GetPatrolPointByTimeSubsection, params });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,535 @@
|
|||
<template>
|
||||
<div
|
||||
style="position: relative; height: 100%"
|
||||
ref="vChartRef"
|
||||
:id="'mars3d-container-' + name"
|
||||
></div>
|
||||
<EditModal @register="editModal" @success="editSuccess" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, watch } from 'vue';
|
||||
import { isArray } from '@/utils';
|
||||
import * as mars3d from 'mars3d';
|
||||
import { EditModal } from './index';
|
||||
import { useModal } from '@/components/Modal';
|
||||
import { EventBus } from '@/utils/eventBus';
|
||||
import { getPointUserOnLine } from '@/api/firegrid/firemanagement';
|
||||
import axios from 'axios';
|
||||
|
||||
const [editModal, { openModal: openEidtModal }] = useModal();
|
||||
|
||||
let map: mars3d.Map; // 地图对象
|
||||
const trajectoryTimePointGeoJson = ref({
|
||||
type: 'FeatureCollection',
|
||||
features: [],
|
||||
});
|
||||
const vChartRef = ref<HTMLElement>();
|
||||
const trajectoryLayerGeoJson = ref<any>(null);
|
||||
const props = defineProps({
|
||||
name: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
mapData: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
routerLine: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
});
|
||||
onMounted(() => {
|
||||
let options = {
|
||||
scene: {
|
||||
center: {
|
||||
lat: 35.362625,
|
||||
lng: 118.033886,
|
||||
alt: 8306.3,
|
||||
heading: 360,
|
||||
pitch: -45,
|
||||
},
|
||||
scene3DOnly: false,
|
||||
shadows: false,
|
||||
removeDblClick: true,
|
||||
sceneMode: 3,
|
||||
showSun: true,
|
||||
showMoon: true,
|
||||
showSkyBox: true,
|
||||
showSkyAtmosphere: true,
|
||||
fog: true,
|
||||
fxaa: true,
|
||||
requestRenderMode: true,
|
||||
contextOptions: {
|
||||
requestWebgl1: false,
|
||||
webgl: {
|
||||
preserveDrawingBuffer: true,
|
||||
alpha: false,
|
||||
stencil: true,
|
||||
powerPreference: 'high-performance',
|
||||
},
|
||||
},
|
||||
globe: {
|
||||
depthTestAgainstTerrain: false,
|
||||
baseColor: '#546a53',
|
||||
showGroundAtmosphere: true,
|
||||
enableLighting: false,
|
||||
},
|
||||
cameraController: {
|
||||
zoomFactor: 3,
|
||||
minimumZoomDistance: 1,
|
||||
maximumZoomDistance: 50000000,
|
||||
enableRotate: true,
|
||||
enableTranslate: true,
|
||||
enableTilt: true,
|
||||
enableZoom: true,
|
||||
enableCollisionDetection: true,
|
||||
minimumCollisionTerrainHeight: 15000,
|
||||
},
|
||||
},
|
||||
control: {
|
||||
homeButton: false,
|
||||
baseLayerPicker: false,
|
||||
sceneModePicker: false,
|
||||
vrButton: false,
|
||||
fullscreenButton: false,
|
||||
navigationHelpButton: false,
|
||||
animation: false,
|
||||
timeline: false,
|
||||
infoBox: false,
|
||||
geocoder: false,
|
||||
selectionIndicator: false,
|
||||
showRenderLoopErrors: true,
|
||||
contextmenu: {
|
||||
hasDefault: true,
|
||||
},
|
||||
mouseDownView: true,
|
||||
zoom: {
|
||||
insertIndex: 1,
|
||||
},
|
||||
},
|
||||
method: {
|
||||
templateValues: {
|
||||
dataServer: '//data.mars3d.cn',
|
||||
gltfServerUrl: '//data.mars3d.cn/gltf',
|
||||
},
|
||||
},
|
||||
terrain: {
|
||||
url: '//data.mars3d.cn/terrain',
|
||||
show: true,
|
||||
clip: true,
|
||||
},
|
||||
basemaps: [
|
||||
{
|
||||
id: 10,
|
||||
name: '地图底图',
|
||||
type: 'group',
|
||||
opacity: 1,
|
||||
},
|
||||
{
|
||||
id: 2021,
|
||||
pid: 10,
|
||||
name: '天地图影像',
|
||||
icon: 'https://data.mars3d.cn/img/thumbnail/basemap/tdt_img.png',
|
||||
type: 'group',
|
||||
layers: [
|
||||
{
|
||||
name: '底图',
|
||||
type: 'tdt',
|
||||
layer: 'img_d',
|
||||
eventParent: {
|
||||
id: 2021,
|
||||
pid: 10,
|
||||
name: '天地图影像',
|
||||
icon: 'https://data.mars3d.cn/img/thumbnail/basemap/tdt_img.png',
|
||||
type: 'group',
|
||||
layers: [
|
||||
{
|
||||
name: '底图',
|
||||
type: 'tdt',
|
||||
layer: 'img_d',
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
name: '注记',
|
||||
type: 'tdt',
|
||||
layer: 'img_z',
|
||||
show: true,
|
||||
},
|
||||
],
|
||||
show: true,
|
||||
},
|
||||
private: false,
|
||||
id: 'm-a57ecb7d-ba05-47a3-b1be-2e28411a5954',
|
||||
opacity: 1,
|
||||
pid: 2021,
|
||||
parent: {
|
||||
id: 2021,
|
||||
pid: 10,
|
||||
name: '天地图影像',
|
||||
icon: 'https://data.mars3d.cn/img/thumbnail/basemap/tdt_img.png',
|
||||
type: 'group',
|
||||
layers: [
|
||||
{
|
||||
name: '底图',
|
||||
type: 'tdt',
|
||||
layer: 'img_d',
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
name: '注记',
|
||||
type: 'tdt',
|
||||
layer: 'img_z',
|
||||
show: true,
|
||||
},
|
||||
],
|
||||
show: true,
|
||||
},
|
||||
zIndex: 1,
|
||||
},
|
||||
{
|
||||
name: '注记',
|
||||
type: 'tdt',
|
||||
layer: 'img_z',
|
||||
eventParent: {
|
||||
id: 2021,
|
||||
pid: 10,
|
||||
name: '天地图影像',
|
||||
icon: 'https://data.mars3d.cn/img/thumbnail/basemap/tdt_img.png',
|
||||
type: 'group',
|
||||
layers: [
|
||||
{
|
||||
name: '底图',
|
||||
type: 'tdt',
|
||||
layer: 'img_d',
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
name: '注记',
|
||||
type: 'tdt',
|
||||
layer: 'img_z',
|
||||
show: true,
|
||||
},
|
||||
],
|
||||
show: true,
|
||||
},
|
||||
private: false,
|
||||
id: 'm-671f9d42-dda7-45ec-9d0f-4259c915b2cb',
|
||||
opacity: 1,
|
||||
pid: 2021,
|
||||
parent: {
|
||||
id: 2021,
|
||||
pid: 10,
|
||||
name: '天地图影像',
|
||||
icon: 'https://data.mars3d.cn/img/thumbnail/basemap/tdt_img.png',
|
||||
type: 'group',
|
||||
layers: [
|
||||
{
|
||||
name: '底图',
|
||||
type: 'tdt',
|
||||
layer: 'img_d',
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
name: '注记',
|
||||
type: 'tdt',
|
||||
layer: 'img_z',
|
||||
show: true,
|
||||
},
|
||||
],
|
||||
show: true,
|
||||
},
|
||||
zIndex: 2,
|
||||
},
|
||||
],
|
||||
show: true,
|
||||
opacity: 1,
|
||||
},
|
||||
],
|
||||
layers: [],
|
||||
};
|
||||
initMap(options);
|
||||
getPointInfo(props.mapData);
|
||||
loadAllRangeLayer('费县');
|
||||
// 定位到某个经纬度
|
||||
EventBus.on('inspectionMoldeMap', (data: any) => {
|
||||
map.flyToPoint(data, {
|
||||
radius: 5000, // 距离目标点的距离
|
||||
duration: 4,
|
||||
});
|
||||
});
|
||||
});
|
||||
watch(
|
||||
() => props.mapData,
|
||||
(newData) => {
|
||||
getPointInfo(newData);
|
||||
loadAllRangeLayer(newData.townname);
|
||||
},
|
||||
);
|
||||
watch(
|
||||
() => props.routerLine,
|
||||
(e) => {
|
||||
if (e.length > 0) {
|
||||
handlerTimePoint(e);
|
||||
map.flyToPoint([parseFloat(e[0].points[0].lng), parseFloat(e[0].points[0].lat)], {
|
||||
radius: 5000, // 距离目标点的距离
|
||||
duration: 4,
|
||||
});
|
||||
let data = e;
|
||||
trajectoryLayerGeoJson.value = handleRouterTeamData(e);
|
||||
console.log('trajectoryLayerGeoJson', trajectoryLayerGeoJson.value);
|
||||
}
|
||||
},
|
||||
);
|
||||
const handleRouterTeamData = (pointsArray) => {
|
||||
let geojson = {
|
||||
type: 'FeatureCollection',
|
||||
features: [],
|
||||
crs: {
|
||||
type: 'name',
|
||||
properties: {},
|
||||
},
|
||||
};
|
||||
|
||||
pointsArray.forEach((points, idx) => {
|
||||
let der = 0;
|
||||
let feature = {
|
||||
type: 'Feature',
|
||||
geometry: {
|
||||
type: 'MultiLineString',
|
||||
coordinates: [[]],
|
||||
},
|
||||
properties: {
|
||||
id: 1,
|
||||
creater_id: 1,
|
||||
},
|
||||
};
|
||||
let data = points.points;
|
||||
data.forEach((item, index) => {
|
||||
// 如果是第一条数据
|
||||
if (index == 0) {
|
||||
der = item.intype;
|
||||
feature = {
|
||||
type: 'Feature',
|
||||
geometry: {
|
||||
type: 'MultiLineString',
|
||||
coordinates: [[]],
|
||||
},
|
||||
properties: {
|
||||
intype: item.intype,
|
||||
},
|
||||
};
|
||||
}
|
||||
if (der == item.intype) {
|
||||
feature.geometry.coordinates[0].push([parseFloat(item.lng), parseFloat(item.lat)]);
|
||||
} else {
|
||||
geojson.features.push(feature);
|
||||
feature = {
|
||||
type: 'Feature',
|
||||
geometry: {
|
||||
type: 'MultiLineString',
|
||||
coordinates: [[[parseFloat(data[index - 1].lng), parseFloat(data[index - 1].lat)]]],
|
||||
},
|
||||
properties: {
|
||||
intype: item.intype,
|
||||
},
|
||||
};
|
||||
|
||||
der = item.intype;
|
||||
}
|
||||
|
||||
if (feature.geometry.coordinates[0].length > 0) {
|
||||
geojson.features.push(feature);
|
||||
}
|
||||
});
|
||||
});
|
||||
return geojson;
|
||||
};
|
||||
const handlerTimePoint = (data) => {
|
||||
trajectoryTimePointGeoJson.value.features = [];
|
||||
data.forEach((item, index) => {
|
||||
if (item.points.length > 2) {
|
||||
let featureStart = {
|
||||
type: 'Feature',
|
||||
geometry: {
|
||||
type: 'Point',
|
||||
coordinates: [item.points[0].lng, item.points[0].lat],
|
||||
},
|
||||
properties: item.points[0],
|
||||
};
|
||||
let featureEnd = {
|
||||
type: 'Feature',
|
||||
geometry: {
|
||||
type: 'Point',
|
||||
coordinates: [
|
||||
item.points[item.points.length - 1].lng,
|
||||
item.points[item.points.length - 1].lat,
|
||||
],
|
||||
},
|
||||
properties: item.points[item.points.length - 1],
|
||||
};
|
||||
trajectoryTimePointGeoJson.value.features.push(featureStart);
|
||||
trajectoryTimePointGeoJson.value.features.push(featureEnd);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const isFirstLoad = ref(true);
|
||||
const initMap = (newData: any) => {
|
||||
// 第一次加载
|
||||
if (isFirstLoad.value) {
|
||||
map = new mars3d.Map(vChartRef.value, newData);
|
||||
} else {
|
||||
// 之后更新
|
||||
// map.setOptions(newData);
|
||||
map.setSceneOptions(newData.scene);
|
||||
}
|
||||
isFirstLoad.value = false;
|
||||
// 初始化矢量图层
|
||||
handlerInitEntityLayer();
|
||||
const mapContextmenuItems = [
|
||||
{
|
||||
text: '在此处添加打卡点',
|
||||
callback: (e) => {
|
||||
const mpt = mars3d.LngLatPoint.fromCartesian(e.cartesian);
|
||||
openEidtModal(true, {
|
||||
isUpdate: false,
|
||||
lat: mpt.lat,
|
||||
lng: mpt.lng,
|
||||
});
|
||||
},
|
||||
},
|
||||
];
|
||||
map.bindContextMenu(mapContextmenuItems);
|
||||
};
|
||||
const loadAllRangeLayer = (currentStreet) => {
|
||||
// 获取所有管护范围
|
||||
let filter_options =
|
||||
currentStreet != '费县' ? '&cql_filter=xzq%20like%20%27%25' + currentStreet + '%25%27' : '';
|
||||
let url = '';
|
||||
if (currentStreet != '费县') {
|
||||
url =
|
||||
'http://221.2.83.254:9007/geoserver/ksp/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=ksp%3Ahulinyuanguanhufanwei' +
|
||||
filter_options +
|
||||
'&maxFeatures=5000&outputFormat=application%2Fjson';
|
||||
} else {
|
||||
url =
|
||||
'http://221.2.83.254:9007/geoserver/ksp/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=ksp%3Ahulinyuanguanhufanwei&maxFeatures=50000&outputFormat=application%2Fjson';
|
||||
}
|
||||
axios({
|
||||
method: 'get',
|
||||
url: url,
|
||||
}).then((res) => {
|
||||
let geojson = res.data;
|
||||
const graphicLayer = new mars3d.layer.GeoJsonLayer({
|
||||
data: geojson,
|
||||
symbol: {
|
||||
styleOptions: {
|
||||
fill: true,
|
||||
opacity: 0.3,
|
||||
outline: true,
|
||||
color: '#7CD00F',
|
||||
outlineStyle: {
|
||||
color: '#F4CC39',
|
||||
width: 3,
|
||||
opacity: 1,
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
// 面中心点,显示文字的配置
|
||||
text: '{hulinyuan}', // 对应的属性名称
|
||||
opacity: 1,
|
||||
font_size: 16,
|
||||
color: '#ffffff',
|
||||
|
||||
font_family: '楷体',
|
||||
outline: true,
|
||||
outlineColor: '#000000',
|
||||
outlineWidth: 3,
|
||||
|
||||
background: false,
|
||||
backgroundColor: '#000000',
|
||||
backgroundOpacity: 0.1,
|
||||
|
||||
font_weight: 'normal',
|
||||
font_style: 'normal',
|
||||
|
||||
scaleByDistance: true,
|
||||
scaleByDistance_far: 20000000,
|
||||
scaleByDistance_farValue: 0.1,
|
||||
scaleByDistance_near: 1000,
|
||||
scaleByDistance_nearValue: 1,
|
||||
|
||||
distanceDisplayCondition: false,
|
||||
distanceDisplayCondition_far: 10000,
|
||||
distanceDisplayCondition_near: 0,
|
||||
visibleDepth: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
popup: '{hulinyuan}',
|
||||
flyTo: true,
|
||||
});
|
||||
map.addLayer(graphicLayer);
|
||||
});
|
||||
};
|
||||
const getPointInfo = (data: any) => {
|
||||
getPointUserOnLine(data).then((res) => {
|
||||
mapKindergarten(res.items.userinfo);
|
||||
});
|
||||
};
|
||||
const mapKindergarten = (arr) => {
|
||||
// 初始化地图
|
||||
// 创建一个用于存放所有点位的图层
|
||||
const pointLayer = new mars3d.layer.GraphicLayer({
|
||||
name: 'PointLayer',
|
||||
hasEdit: false,
|
||||
isAutoEditing: false,
|
||||
});
|
||||
|
||||
// 将图层添加到地图
|
||||
map.addLayer(pointLayer);
|
||||
// 遍历数组,为每个点位数据创建图形点
|
||||
arr.forEach((pointData: any) => {
|
||||
// 解析点位的坐标
|
||||
const coordinates = [pointData.lng, pointData.lat];
|
||||
// 创建自定义图标点
|
||||
// 创建 Mars3D 中的点对象(默认点位样式)
|
||||
const pointGraphic = new mars3d.graphic.BillboardEntity({
|
||||
position: coordinates,
|
||||
attr: pointData,
|
||||
style: {
|
||||
label: {
|
||||
text: pointData.name,
|
||||
scale: 1,
|
||||
color: '#ffffff',
|
||||
pixelOffsetX: 0,
|
||||
pixelOffsetY: -20,
|
||||
font_size: 20,
|
||||
},
|
||||
pixelSize: 100,
|
||||
scale: 0.5,
|
||||
image: '/user.png',
|
||||
},
|
||||
});
|
||||
|
||||
// 添加点位点击事件
|
||||
pointGraphic.on(mars3d.EventType.click, function (event: any) {
|
||||
var data = event.graphic.options.attr;
|
||||
console.log('点击了点位', data);
|
||||
});
|
||||
// 将点对象添加到图层
|
||||
pointLayer.addGraphic(pointGraphic);
|
||||
});
|
||||
};
|
||||
|
||||
let graphicLayer = null;
|
||||
// 地球创建完成后默认加载矢量数据图层
|
||||
const handlerInitEntityLayer = () => {
|
||||
if (graphicLayer == null) {
|
||||
graphicLayer = new mars3d.layer.GraphicLayer({ id: 999 });
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="less" scoped></style>
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
item.label
|
||||
}}</a-select-option>
|
||||
</a-select>
|
||||
<div class="form-button">
|
||||
<div class="form-button" @click="getLine">
|
||||
<a-button type="primary">查询</a-button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -66,7 +66,9 @@
|
|||
</BasicTable>
|
||||
</div>
|
||||
</div>
|
||||
<Map :name="'InspectionModel'" class="w-1/2 xl:w-1/2" />
|
||||
<div class="w-1/2 xl:w-1/2" style="height: 90vh">
|
||||
<InspectionMap :routerLine="routerLine" :name="'InspectionModel'" :mapData="formState" />
|
||||
</div>
|
||||
<a-modal
|
||||
v-model:visible="patrolTrackModelVisible"
|
||||
title="巡查"
|
||||
|
|
@ -83,19 +85,24 @@
|
|||
import { BasicTable, useTable, TableAction } from '@/components/Table';
|
||||
import { getPointUserOnLine } from '@/api/firegrid/firemanagement';
|
||||
import { InspectionColumns } from './data';
|
||||
import { PatrolTrackModel, Map } from './index';
|
||||
import { PatrolTrackModel, InspectionMap } from './index';
|
||||
import { EventBus } from '@/utils/eventBus';
|
||||
import { useMessage } from '@/hooks/web/useMessage';
|
||||
import { getPatrolPointByTimeSubsection } from '@/api/firegrid/patrol';
|
||||
|
||||
const { createMessage } = useMessage();
|
||||
defineOptions({ name: 'DeptModal' });
|
||||
const patrolTrackModelVisible = ref(false);
|
||||
const onlineInfo = ref({
|
||||
const onlineInfo = reactive({
|
||||
online: 0,
|
||||
offline: 0,
|
||||
});
|
||||
const [registerTable, { reload, getSelectRows, clearSelectedRowKeys }] = useTable({
|
||||
const routerLine = ref([]);
|
||||
const [registerTable, { reload, getSelectRows, clearSelectedRowKeys, setTableData }] = useTable({
|
||||
// 表格名称
|
||||
title: '角色列表',
|
||||
title: '巡检列表',
|
||||
// 获取数据的接口
|
||||
api: getPointUserOnLine,
|
||||
dataSource: [],
|
||||
// 表单列信息 BasicColumn[]
|
||||
columns: InspectionColumns,
|
||||
rowKey: 'id',
|
||||
|
|
@ -107,12 +114,6 @@
|
|||
bordered: true,
|
||||
// 序号列
|
||||
showIndexColumn: false,
|
||||
// 勾选列
|
||||
rowSelection: {
|
||||
//多选框
|
||||
// type: 'checkbox',
|
||||
type: 'radio',
|
||||
},
|
||||
// 搜索
|
||||
handleSearchInfoFn(info) {
|
||||
return info;
|
||||
|
|
@ -125,11 +126,54 @@
|
|||
fixed: undefined,
|
||||
},
|
||||
});
|
||||
const toPosition = () => {
|
||||
console.log('位置');
|
||||
const toPosition = (row) => {
|
||||
const lnglat = [row.lng, row.lat];
|
||||
EventBus.emit('inspectionMoldeMap', lnglat);
|
||||
};
|
||||
const toTrajectory = () => {
|
||||
const toTrajectory = (row) => {
|
||||
console.log('轨迹');
|
||||
console.log(row);
|
||||
getRouteList(row);
|
||||
};
|
||||
const getRouteList = (item) => {
|
||||
let start = new Date();
|
||||
let end = new Date(start.getTime());
|
||||
|
||||
let SAETime = [
|
||||
end.getFullYear() +
|
||||
'-' +
|
||||
(end.getMonth() + 1) +
|
||||
'-' +
|
||||
end.getDate() +
|
||||
' ' +
|
||||
(end.getHours() - 2) +
|
||||
':00:00',
|
||||
start.getFullYear() +
|
||||
'-' +
|
||||
(start.getMonth() + 1) +
|
||||
'-' +
|
||||
start.getDate() +
|
||||
' ' +
|
||||
start.getHours() +
|
||||
':' +
|
||||
start.getMinutes() +
|
||||
':' +
|
||||
start.getSeconds(),
|
||||
];
|
||||
|
||||
let query = {
|
||||
id: item.createId,
|
||||
beginTime: SAETime[0],
|
||||
endTime: SAETime[1],
|
||||
};
|
||||
// LoadPatrolPointByTimeSubsection
|
||||
getPatrolPointByTimeSubsection(query).then((res) => {
|
||||
console.log(res);
|
||||
routerLine.value = res;
|
||||
if (res.length == 0) {
|
||||
return createMessage.warning('暂无1小时内轨迹');
|
||||
}
|
||||
});
|
||||
};
|
||||
const stateOptions = ref([
|
||||
{
|
||||
|
|
@ -158,9 +202,21 @@
|
|||
});
|
||||
const getLine = () => {
|
||||
getPointUserOnLine(formState).then((res) => {
|
||||
console.log(res);
|
||||
res.items.userinfo.forEach((item) => {
|
||||
item.onLineTime = friendlyDate(item.onLineTime);
|
||||
});
|
||||
onlineInfo.online = res.items.online;
|
||||
onlineInfo.offline = res.items.offline;
|
||||
setTableData(res.items.userinfo);
|
||||
});
|
||||
};
|
||||
const friendlyDate = (time) => {
|
||||
if (time > 60) {
|
||||
return Math.ceil(time / 60) + '小时前';
|
||||
} else {
|
||||
return time + '分钟前';
|
||||
}
|
||||
};
|
||||
onMounted(() => {
|
||||
getLine();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@
|
|||
wrap-class-name="full-modal"
|
||||
width="100%"
|
||||
:footer="null"
|
||||
destroyOnClose
|
||||
>
|
||||
<InspectionModel />
|
||||
</a-modal>
|
||||
|
|
@ -142,6 +143,7 @@
|
|||
limit: pageData.pageSize,
|
||||
pointName: formState.orgId,
|
||||
};
|
||||
EventBus.emit('getPatrolMap', params);
|
||||
getCheckPointList(params).then((res) => {
|
||||
tasklist.value = res.items;
|
||||
pageData.total = res.total;
|
||||
|
|
@ -240,14 +242,14 @@
|
|||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="less">
|
||||
<style lang="less" scoped>
|
||||
.full-modal {
|
||||
.ant-modal {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.ant-modal-content {
|
||||
height: calc(80vh);
|
||||
height: calc(100vh);
|
||||
}
|
||||
|
||||
.ant-modal-body {
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@
|
|||
} from '@ant-design/icons-vue';
|
||||
import { getCheckInfoByPointId } from '@/api/firegrid/index';
|
||||
import { getPatrolInfoByUserId } from '@/api/firegrid/patrol';
|
||||
import { EventBus } from '@/utils/eventBus';
|
||||
|
||||
const props = defineProps({
|
||||
itemData: Object,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
<template>
|
||||
<div style="position: relative" ref="vChartRef" :id="'mars3d-container-' + name"></div>
|
||||
<div
|
||||
style="position: relative; height: 100%"
|
||||
ref="vChartRef"
|
||||
:id="'mars3d-container-' + name"
|
||||
></div>
|
||||
<EditModal @register="editModal" @success="editSuccess" />
|
||||
</template>
|
||||
|
||||
|
|
@ -10,6 +14,8 @@
|
|||
import { EditModal } from './index';
|
||||
import { useModal } from '@/components/Modal';
|
||||
import { EventBus } from '@/utils/eventBus';
|
||||
import { getCheckPointList } from '@/api/firegrid/index';
|
||||
import axios from 'axios';
|
||||
|
||||
const [editModal, { openModal: openEidtModal }] = useModal();
|
||||
|
||||
|
|
@ -239,11 +245,19 @@
|
|||
// 定位到某个经纬度
|
||||
EventBus.on('inspectionMap', (data: any) => {
|
||||
map.flyToPoint(data, {
|
||||
alt: 4269.7,
|
||||
heading: 359.2,
|
||||
pitch: -51.9,
|
||||
radius: 5000, // 距离目标点的距离
|
||||
duration: 4,
|
||||
});
|
||||
});
|
||||
getPointInfo({
|
||||
page: 1,
|
||||
limit: 10,
|
||||
});
|
||||
loadAllRangeLayer('费县');
|
||||
EventBus.on('getPatrolMap', (data: any) => {
|
||||
getPointInfo(data);
|
||||
loadAllRangeLayer(data.pointName);
|
||||
});
|
||||
});
|
||||
|
||||
const isFirstLoad = ref(true);
|
||||
|
|
@ -274,6 +288,164 @@
|
|||
];
|
||||
map.bindContextMenu(mapContextmenuItems);
|
||||
};
|
||||
const loadAllRangeLayer = (currentStreet) => {
|
||||
// 获取所有管护范围
|
||||
let filter_options =
|
||||
currentStreet != '费县' ? '&cql_filter=xzq%20like%20%27%25' + currentStreet + '%25%27' : '';
|
||||
let url = '';
|
||||
if (currentStreet != '费县') {
|
||||
url =
|
||||
'http://221.2.83.254:9007/geoserver/ksp/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=ksp%3Ahulinyuanguanhufanwei' +
|
||||
filter_options +
|
||||
'&maxFeatures=5000&outputFormat=application%2Fjson';
|
||||
} else {
|
||||
url =
|
||||
'http://221.2.83.254:9007/geoserver/ksp/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=ksp%3Ahulinyuanguanhufanwei&maxFeatures=50000&outputFormat=application%2Fjson';
|
||||
}
|
||||
axios({
|
||||
method: 'get',
|
||||
url: url,
|
||||
}).then((res) => {
|
||||
let geojson = res.data;
|
||||
const graphicLayer = new mars3d.layer.GeoJsonLayer({
|
||||
data: geojson,
|
||||
symbol: {
|
||||
styleOptions: {
|
||||
fill: true,
|
||||
opacity: 0.3,
|
||||
outline: true,
|
||||
color: '#7CD00F',
|
||||
outlineStyle: {
|
||||
color: '#F4CC39',
|
||||
width: 3,
|
||||
opacity: 1,
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
// 面中心点,显示文字的配置
|
||||
text: '{hulinyuan}', // 对应的属性名称
|
||||
opacity: 1,
|
||||
font_size: 16,
|
||||
color: '#ffffff',
|
||||
|
||||
font_family: '楷体',
|
||||
outline: true,
|
||||
outlineColor: '#000000',
|
||||
outlineWidth: 3,
|
||||
|
||||
background: false,
|
||||
backgroundColor: '#000000',
|
||||
backgroundOpacity: 0.1,
|
||||
|
||||
font_weight: 'normal',
|
||||
font_style: 'normal',
|
||||
|
||||
scaleByDistance: true,
|
||||
scaleByDistance_far: 20000000,
|
||||
scaleByDistance_farValue: 0.1,
|
||||
scaleByDistance_near: 1000,
|
||||
scaleByDistance_nearValue: 1,
|
||||
|
||||
distanceDisplayCondition: false,
|
||||
distanceDisplayCondition_far: 10000,
|
||||
distanceDisplayCondition_near: 0,
|
||||
visibleDepth: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
popup: '{hulinyuan}',
|
||||
flyTo: true,
|
||||
});
|
||||
map.addLayer(graphicLayer);
|
||||
// if (map.getSource('allRangeSource')) {
|
||||
// } else {
|
||||
// map.addSource('allRangeSource', {
|
||||
// type: 'geojson',
|
||||
// data: geojson,
|
||||
// });
|
||||
|
||||
// map.addLayer({
|
||||
// id: 'allRangeLayerFill',
|
||||
// type: 'fill',
|
||||
// source: 'allRangeSource',
|
||||
// layout: {},
|
||||
// paint: {
|
||||
// 'fill-color': '#7CD00F',
|
||||
// 'fill-opacity': 0.3,
|
||||
// },
|
||||
// });
|
||||
|
||||
// map.addLayer({
|
||||
// id: 'allRangeLayerLine',
|
||||
// type: 'line',
|
||||
// source: 'allRangeSource',
|
||||
// layout: {},
|
||||
// paint: {
|
||||
// 'line-color': '#F4CC39',
|
||||
// 'line-width': 1,
|
||||
// },
|
||||
// });
|
||||
|
||||
// map.addLayer({
|
||||
// id: 'allRangeLayerName',
|
||||
// type: 'symbol',
|
||||
// source: 'allRangeSource',
|
||||
// layout: {
|
||||
// 'text-field': '{hulinyuan}',
|
||||
// 'text-size': 12,
|
||||
// 'text-font': ['Microsoft YaHei Regular'],
|
||||
// },
|
||||
// paint: {
|
||||
// 'text-color': '#000000', // 文本的颜色(可选,默认值为 #000000)
|
||||
// 'text-halo-color': '#FFFFFF',
|
||||
// 'text-halo-width': 1,
|
||||
// },
|
||||
// });
|
||||
// }
|
||||
});
|
||||
};
|
||||
|
||||
const getPointInfo = (data: any) => {
|
||||
getCheckPointList(data).then((res) => {
|
||||
mapKindergarten(res.items);
|
||||
});
|
||||
};
|
||||
const mapKindergarten = (arr) => {
|
||||
// 初始化地图
|
||||
// 创建一个用于存放所有点位的图层
|
||||
const pointLayer = new mars3d.layer.GraphicLayer({
|
||||
name: 'PointLayer',
|
||||
hasEdit: false,
|
||||
isAutoEditing: false,
|
||||
});
|
||||
|
||||
// 将图层添加到地图
|
||||
map.addLayer(pointLayer);
|
||||
// 遍历数组,为每个点位数据创建图形点
|
||||
arr.forEach((pointData: any) => {
|
||||
// 解析点位的坐标
|
||||
const coordinates = [pointData.Lng, pointData.Lat];
|
||||
// 创建自定义图标点
|
||||
// 创建 Mars3D 中的点对象(默认点位样式)
|
||||
const pointGraphic = new mars3d.graphic.BillboardEntity({
|
||||
position: coordinates,
|
||||
attr: pointData,
|
||||
style: {
|
||||
pixelSize: 100,
|
||||
scale: 0.5,
|
||||
image: '/dakadian.png',
|
||||
},
|
||||
});
|
||||
|
||||
// 添加点位点击事件
|
||||
pointGraphic.on(mars3d.EventType.click, function (event: any) {
|
||||
var data = event.graphic.options.attr;
|
||||
console.log('点击了点位', data);
|
||||
});
|
||||
// 将点对象添加到图层
|
||||
pointLayer.addGraphic(pointGraphic);
|
||||
});
|
||||
};
|
||||
|
||||
const dataHandle = (newData: any) => {
|
||||
if (!mapIns && !AMapIns) {
|
||||
|
|
@ -340,13 +512,13 @@
|
|||
const handlerAddEntity = (data) => {
|
||||
let graphicOptions = {
|
||||
id: data.id,
|
||||
position: [parseFloat(data.position.lng), parseFloat(data.position.lat)],
|
||||
position: [parseFloat(data.Lng), parseFloat(data.Lat)],
|
||||
style: {
|
||||
image: data.image.generalIcon,
|
||||
image: '@/assets/images/chart/xunchaguiji/locationicon.png',
|
||||
clampToGround: true,
|
||||
scale: 0.5,
|
||||
label: {
|
||||
text: data.attribute.label,
|
||||
text: data.PointName,
|
||||
font_size: 14,
|
||||
color: '#ffffff',
|
||||
pixelOffsetY: 10,
|
||||
|
|
@ -368,7 +540,7 @@
|
|||
<div class="title">火点信息</div>
|
||||
<div class="label-content">
|
||||
<div class="data-li">
|
||||
<div class="data-label">火点地址:${data.attribute.address}</div>
|
||||
<div class="data-label">火点地址:${data.PointName}</div>
|
||||
</div>
|
||||
<div class="data-li">
|
||||
<div class="data-label">上报时间:</div>
|
||||
|
|
@ -377,8 +549,8 @@
|
|||
</div>
|
||||
<div class="data-li">
|
||||
<div class="data-value">
|
||||
<span id="lablCSFM3" onclick="aroundYuAn([${data.position.lng},${data.position.lat}])" class="label-tag data-value-status-2" >防灭火资源</span>
|
||||
<span id="lablCSFM2" onclick="delFirePoint(${data.id})" class="label-tag data-value-status-3" title="删除火点">删除火点</span>
|
||||
<span id="lablCSFM3" onclick="aroundYuAn([${data.Lng},${data.Lat}])" class="label-tag data-value-status-2" >防灭火资源</span>
|
||||
<span id="lablCSFM2" onclick="delFirePoint(${data.Id})" class="label-tag data-value-status-3" title="删除火点">删除火点</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,17 @@
|
|||
</div>
|
||||
<a-tabs v-model:activeKey="activeKey">
|
||||
<a-tab-pane key="1" tab="巡查轨迹">
|
||||
<div class="users-container">
|
||||
<div
|
||||
style="width: 100%; text-align: center; padding: 100px 0px"
|
||||
v-if="list.length <= 0 && activeKey == 1"
|
||||
>
|
||||
<img
|
||||
src="@/assets/images/canvas/noData.png"
|
||||
style="width: 140px; margin-bottom: 20px"
|
||||
/>
|
||||
<p style="color: #cfcfcf">暂无巡查轨迹</p>
|
||||
</div>
|
||||
<div class="users-container" v-else>
|
||||
<div class="history-line" v-for="(it, idx) in list" :key="idx">
|
||||
<div class="user-item">
|
||||
<div class="user-photo">
|
||||
|
|
@ -37,7 +47,17 @@
|
|||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="2" tab="打卡记录" force-render>
|
||||
<div class="users-container">
|
||||
<div
|
||||
style="width: 100%; text-align: center; padding: 100px 0px"
|
||||
v-if="clockInList.length <= 0 && activeKey == 2"
|
||||
>
|
||||
<img
|
||||
src="@/assets/images/canvas/noData.png"
|
||||
style="width: 140px; margin-bottom: 20px"
|
||||
/>
|
||||
<p style="color: #cfcfcf">暂无打卡记录</p>
|
||||
</div>
|
||||
<div class="users-container" v-else>
|
||||
<div class="clockIn-box" v-for="(item, idx) in clockInList" :key="idx">
|
||||
<p>
|
||||
<span><UserOutlined /> 打卡人员:</span>{{ item.Name }}
|
||||
|
|
@ -55,11 +75,13 @@
|
|||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</div>
|
||||
<Map :name="'patrolTrackModel'" class="w-1/2 xl:w-1/2" />
|
||||
<div class="w-1/2 xl:w-1/2" style="height: 90vh">
|
||||
<Map :name="'patrolTrackModel'" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { Map } from './index';
|
||||
import {
|
||||
SwapRightOutlined,
|
||||
|
|
@ -67,57 +89,61 @@
|
|||
HistoryOutlined,
|
||||
EnvironmentOutlined,
|
||||
} from '@ant-design/icons-vue';
|
||||
import { getCheckInfoByUserId } from '@/api/firegrid/index';
|
||||
import { getPatrolInfoByUserId } from '@/api/firegrid/patrol';
|
||||
|
||||
defineOptions({ name: 'DeptModal' });
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {};
|
||||
},
|
||||
},
|
||||
});
|
||||
const activeKey = ref('1');
|
||||
const list = ref([
|
||||
{
|
||||
name: '张三',
|
||||
phone: '',
|
||||
startAddress: '',
|
||||
endAddress: '',
|
||||
startTime: '2022-01-01 10:00:00',
|
||||
endTime: '2022-01-01 12:00:00',
|
||||
},
|
||||
{
|
||||
name: '张三',
|
||||
phone: '',
|
||||
startAddress: '',
|
||||
endAddress: '',
|
||||
startTime: '2022-01-01 10:00:00',
|
||||
endTime: '2022-01-01 12:00:00',
|
||||
},
|
||||
]);
|
||||
const clockInList = ref([
|
||||
{
|
||||
Name: '张三',
|
||||
clockontime: '2022-01-01 10:00:00',
|
||||
lng: '116.404',
|
||||
lat: '39.915',
|
||||
},
|
||||
{
|
||||
Name: '张三',
|
||||
clockontime: '2022-01-01 10:00:00',
|
||||
lng: '116.404',
|
||||
lat: '39.915',
|
||||
},
|
||||
]);
|
||||
const list = ref([]);
|
||||
const clockInList = ref([]);
|
||||
const getTrajectoryData = (item) => {
|
||||
console.log(item);
|
||||
};
|
||||
// 查询
|
||||
interface FormState {
|
||||
begintime: string;
|
||||
endtime: string;
|
||||
begintime: string | null;
|
||||
endtime: string | null;
|
||||
}
|
||||
const formState: FormState = reactive({
|
||||
begintime: '',
|
||||
endtime: '',
|
||||
begintime: null,
|
||||
endtime: null,
|
||||
});
|
||||
const timeChange = (value: any, dateString: string) => {
|
||||
formState.begintime = dateString[0];
|
||||
formState.endtime = dateString[1];
|
||||
getCheckList();
|
||||
getPatrolList();
|
||||
};
|
||||
const getCheckList = () => {
|
||||
const params = {
|
||||
...formState,
|
||||
id: props.data.id,
|
||||
};
|
||||
getCheckInfoByUserId(params).then((res) => {
|
||||
clockInList.value = res.items;
|
||||
});
|
||||
};
|
||||
const getPatrolList = () => {
|
||||
const params = {
|
||||
...formState,
|
||||
id: props.data.id,
|
||||
};
|
||||
getPatrolInfoByUserId(params).then((res) => {
|
||||
list.value = res;
|
||||
});
|
||||
};
|
||||
onMounted(() => {
|
||||
getCheckList();
|
||||
getPatrolList();
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.users-container {
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@
|
|||
{
|
||||
// icon: 'ant-design:ellipsis-outlined',
|
||||
label: '巡查轨迹',
|
||||
onClick: getGuiji.bind(null, record),
|
||||
onClick: getGuiji.bind(null,record),
|
||||
},
|
||||
]"
|
||||
/>
|
||||
|
|
@ -89,7 +89,7 @@
|
|||
width="100%"
|
||||
:footer="null"
|
||||
>
|
||||
<PatrolTrackModel />
|
||||
<PatrolTrackModel :data="patrolTrackData" />
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -136,9 +136,10 @@
|
|||
fixed: undefined,
|
||||
},
|
||||
});
|
||||
const getGuiji = () => {
|
||||
console.log('查看轨迹');
|
||||
const patrolTrackData = ref({});
|
||||
const getGuiji = (item: any) => {
|
||||
patrolTrackModelVisible.value = true;
|
||||
patrolTrackData.value = item;
|
||||
};
|
||||
const allData: any = ref({});
|
||||
// 查询
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
import { BasicColumn, FormSchema } from '@/components/Table';
|
||||
import { Tag } from 'ant-design-vue';
|
||||
import { h } from 'vue';
|
||||
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
|
|
@ -40,6 +42,13 @@ export const InspectionColumns: BasicColumn[] = [
|
|||
{
|
||||
title: '在线状态',
|
||||
dataIndex: 'state',
|
||||
customRender: ({ record }) => {
|
||||
const state = record.state;
|
||||
const enable = ~~state === '在线';
|
||||
const color = enable ? 'green' : 'red';
|
||||
const text = state;
|
||||
return h(Tag, { color: color }, () => text);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '离线时长',
|
||||
|
|
|
|||
|
|
@ -5,3 +5,4 @@ export { default as Map } from './Map.vue';
|
|||
export { default as PatrolTrackModel } from './PatrolTrackModel.vue';
|
||||
export { default as LeftView } from './LeftView.vue';
|
||||
export { default as InspectionModel } from './InspectionModel.vue';
|
||||
export { default as InspectionMap } from './InspectionMap.vue';
|
||||
|
|
|
|||
Loading…
Reference in New Issue