巡检记录画面,巡查统计画面,防火巡检对接接口并显示打卡点
parent
23aab9f636
commit
ce76d5afa5
|
|
@ -44,7 +44,7 @@ export function getCheckPointList(params: GetCheckPointListParams) {
|
|||
*/
|
||||
export function deleteCheckPoint(params: DeleteCheckPointParams) {
|
||||
return defHttp.post({
|
||||
url: Api.DeleteCheckPoint,
|
||||
url: `${Api.DeleteCheckPoint}?id=${params.id}`,
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,15 +14,14 @@
|
|||
/>
|
||||
</template>
|
||||
<template #userId="{ model, field }">
|
||||
<a-tree-select
|
||||
<a-select
|
||||
show-search
|
||||
style="width: 100%"
|
||||
v-model:value="model[field]"
|
||||
:tree-data="treeData"
|
||||
:field-names="{ label: 'name', value: 'id' }"
|
||||
:options="userData"
|
||||
placeholder="请选择"
|
||||
allow-clear
|
||||
multiple
|
||||
:filter-option="filterOption"
|
||||
/>
|
||||
</template>
|
||||
</BasicForm>
|
||||
|
|
@ -33,7 +32,7 @@
|
|||
import { BasicModal, useModalInner } from '@/components/Modal';
|
||||
import { BasicForm, useForm } from '@/components/Form';
|
||||
import { formSchema } from './data';
|
||||
import { getDeptList } from '@/api/demo/system';
|
||||
import { getDeptList, getAccountList } from '@/api/demo/system';
|
||||
import { useMessage } from '@/hooks/web/useMessage';
|
||||
import { addCheckPoint, editCheckPoint, getSingleCheckPoint } from '@/api/firegrid/index';
|
||||
import { EventBus } from '@/utils/eventBus';
|
||||
|
|
@ -45,6 +44,7 @@
|
|||
|
||||
const isUpdate = ref(true);
|
||||
const treeData: any = ref([]);
|
||||
const userData: any = ref([])
|
||||
onMounted(() => {
|
||||
getTreeList();
|
||||
});
|
||||
|
|
@ -74,12 +74,22 @@
|
|||
setFieldsValue({
|
||||
...res,
|
||||
});
|
||||
position.lat = res.lat;
|
||||
position.lng = res.lng;
|
||||
});
|
||||
};
|
||||
const getTreeList = async () => {
|
||||
getDeptList().then((res) => {
|
||||
treeData.value = res;
|
||||
});
|
||||
getAccountList({page:1,limit:9999}).then(res => {
|
||||
userData.value = res.items.map(item => {
|
||||
return {
|
||||
label: item.name,
|
||||
value: item.id
|
||||
}
|
||||
})
|
||||
})
|
||||
};
|
||||
|
||||
const getTitle = computed(() => (!unref(isUpdate) ? '新增打卡点' : '编辑打卡点'));
|
||||
|
|
@ -87,10 +97,13 @@
|
|||
try {
|
||||
const values = await validate();
|
||||
let query: any = values;
|
||||
if(!(query.userId instanceof Array)){
|
||||
query.userId = [query.userId]
|
||||
}
|
||||
query.lat = position.lat;
|
||||
query.lng = position.lng;
|
||||
// 调用接口
|
||||
if (!unref(isUpdate)) {
|
||||
query.lat = position.lat;
|
||||
query.lng = position.lng;
|
||||
const data = await addCheckPoint(query);
|
||||
if (data) {
|
||||
setModalProps({ confirmLoading: true });
|
||||
|
|
@ -115,4 +128,7 @@
|
|||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
const filterOption = (input: string, option: any) => {
|
||||
return option.label.indexOf(input) >= 0;
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -188,8 +188,7 @@
|
|||
// 查看
|
||||
const lookClockInfo = (row) => {
|
||||
emits('viewHandle', row);
|
||||
const lnglat = [row.lng, row.lat];
|
||||
EventBus.emit('inspectionMap', lnglat);
|
||||
EventBus.emit('inspectionMap', row);
|
||||
};
|
||||
// 巡检
|
||||
const toInspection = () => {
|
||||
|
|
|
|||
|
|
@ -33,6 +33,11 @@
|
|||
default: '',
|
||||
},
|
||||
});
|
||||
const dakaPointLayer = new mars3d.layer.GraphicLayer({
|
||||
name: 'dakaPointLayer',
|
||||
hasEdit: false,
|
||||
isAutoEditing: false,
|
||||
});
|
||||
onMounted(() => {
|
||||
let options = {
|
||||
scene: {
|
||||
|
|
@ -245,10 +250,25 @@
|
|||
initMap(options);
|
||||
// 定位到某个经纬度
|
||||
EventBus.on('inspectionMap', (data: any) => {
|
||||
map.flyToPoint(data, {
|
||||
const lnglat = [data.lng, data.lat];
|
||||
map.flyToPoint(lnglat, {
|
||||
radius: 5000, // 距离目标点的距离
|
||||
duration: 4,
|
||||
});
|
||||
dakaPointLayer.clear()
|
||||
const coordinates = [data.lng, data.lat];
|
||||
const pointGraphic = new mars3d.graphic.BillboardEntity({
|
||||
position: coordinates,
|
||||
style: {
|
||||
pixelSize: 100,
|
||||
scale: 0.5,
|
||||
image: '/dakadian.png',
|
||||
clampToGround: true,
|
||||
verticalOrigin: mars3d.Cesium.VerticalOrigin.BOTTOM,
|
||||
horizontalOrigin: mars3d.Cesium.HorizontalOrigin.CENTER,
|
||||
},
|
||||
});
|
||||
dakaPointLayer.addGraphic(pointGraphic);
|
||||
});
|
||||
getPointInfo({
|
||||
page: 1,
|
||||
|
|
@ -273,6 +293,7 @@
|
|||
}
|
||||
map.on(mars3d.EventType.load, function (event) {
|
||||
emits('onLoad', map);
|
||||
map.addLayer(dakaPointLayer);
|
||||
})
|
||||
isFirstLoad.value = false;
|
||||
// 初始化矢量图层
|
||||
|
|
|
|||
|
|
@ -0,0 +1,520 @@
|
|||
<template>
|
||||
<div
|
||||
style="position: relative; height: 100%"
|
||||
ref="vChartRef"
|
||||
:id="'mars3d-container-' + name"
|
||||
></div>
|
||||
</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 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>
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
import { BasicColumn, FormSchema } from '@/components/Table';
|
||||
import { Tag } from 'ant-design-vue';
|
||||
import { h } from 'vue';
|
||||
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '所属班组',
|
||||
dataIndex: 'areaName',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: '护林员',
|
||||
dataIndex: 'name',
|
||||
},
|
||||
{
|
||||
title: '手机号码',
|
||||
dataIndex: 'account',
|
||||
},
|
||||
{
|
||||
title: '打卡次数',
|
||||
dataIndex: 'dakacishu',
|
||||
},
|
||||
{
|
||||
title: '巡检次数',
|
||||
dataIndex: 'xunjian',
|
||||
},
|
||||
{
|
||||
title: '打卡点数量',
|
||||
dataIndex: 'dakadian',
|
||||
},
|
||||
];
|
||||
|
||||
export const InspectionColumns: BasicColumn[] = [
|
||||
{
|
||||
title: '乡镇/村庄',
|
||||
dataIndex: 'townName',
|
||||
},
|
||||
{
|
||||
title: '护林员姓名',
|
||||
dataIndex: 'name',
|
||||
},
|
||||
{
|
||||
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: '离线时长',
|
||||
dataIndex: 'onLineTime',
|
||||
},
|
||||
];
|
||||
|
||||
export const formSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'id',
|
||||
label: 'id',
|
||||
component: 'Input',
|
||||
ifShow: false,
|
||||
},
|
||||
{
|
||||
field: 'pointName',
|
||||
label: '打卡点名称',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
field: 'areaId',
|
||||
label: '行政区划',
|
||||
required: true,
|
||||
slot: 'areaId',
|
||||
},
|
||||
{
|
||||
field: 'userId',
|
||||
label: '责任人',
|
||||
slot: 'userId',
|
||||
required: true,
|
||||
},
|
||||
];
|
||||
|
|
@ -0,0 +1 @@
|
|||
export { default as InspectionMap } from './InspectionRecordMap.vue';
|
||||
|
|
@ -0,0 +1,239 @@
|
|||
<template>
|
||||
<div class="flex">
|
||||
<div class="w-1/2 xl:w-1/2">
|
||||
<div class="search-container flex justify-end items-center form-data m-4">
|
||||
<a-tree-select
|
||||
v-model:value="formState.townname"
|
||||
style="width: 30%; margin-right: 10px"
|
||||
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
|
||||
:tree-data="treeData"
|
||||
placeholder="选择行政区划"
|
||||
:field-names="{ label: 'name', value: 'id' }"
|
||||
/>
|
||||
<a-select ref="select" v-model:value="formState.isonline" style="width: 120px">
|
||||
<a-select-option :value="item.value" v-for="item in stateOptions" :key="item.value">{{
|
||||
item.label
|
||||
}}</a-select-option>
|
||||
</a-select>
|
||||
<div class="form-button" @click="getLine">
|
||||
<a-button type="primary">查询</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="all-count">
|
||||
<div class="online-user-count">
|
||||
在线人数
|
||||
<span style="font-size: 24px; color: #108eff; margin-left: 12px">{{
|
||||
onlineInfo.online
|
||||
}}</span>
|
||||
</div>
|
||||
<div class="online-user-count">
|
||||
离线人数
|
||||
<span style="font-size: 24px; color: #108eff; margin-left: 12px">{{
|
||||
onlineInfo.offline
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-container">
|
||||
<BasicTable @register="registerTable">
|
||||
<template #toolbar>
|
||||
<PermissionBtn @btn-event="onBtnClicked" />
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'action'">
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
// icon: 'ant-design:ellipsis-outlined',
|
||||
label: '位置',
|
||||
onClick: toPosition.bind(null, record),
|
||||
},
|
||||
{
|
||||
// icon: 'ant-design:ellipsis-outlined',
|
||||
label: '轨迹',
|
||||
onClick: toTrajectory.bind(null, record),
|
||||
},
|
||||
]"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
</BasicTable>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-1/2 xl:w-1/2" style="height: 90vh">
|
||||
<InspectionMap :routerLine="routerLine" :name="'InspectionModel'" :mapData="formState" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { BasicTable, useTable, TableAction } from '@/components/Table';
|
||||
import { getPointUserOnLine } from '@/api/firegrid/firemanagement';
|
||||
import { InspectionColumns } from './data';
|
||||
import { InspectionMap } from './index';
|
||||
import { EventBus } from '@/utils/eventBus';
|
||||
import { useMessage } from '@/hooks/web/useMessage';
|
||||
import { getPatrolPointByTimeSubsection } from '@/api/firegrid/patrol';
|
||||
import { getDeptList } from '@/api/demo/system';
|
||||
|
||||
const { createMessage } = useMessage();
|
||||
defineOptions({ name: 'DeptModal' });
|
||||
const onlineInfo = reactive({
|
||||
online: 0,
|
||||
offline: 0,
|
||||
});
|
||||
const treeData: any = ref([]);
|
||||
const getTree = () => {
|
||||
getDeptList().then((res) => {
|
||||
treeData.value = res;
|
||||
});
|
||||
};
|
||||
const routerLine = ref([]);
|
||||
const [registerTable, { reload, getSelectRows, clearSelectedRowKeys, setTableData }] = useTable({
|
||||
// 表格名称
|
||||
title: '巡检列表',
|
||||
// 获取数据的接口
|
||||
dataSource: [],
|
||||
// 表单列信息 BasicColumn[]
|
||||
columns: InspectionColumns,
|
||||
rowKey: 'id',
|
||||
// 使用搜索表单
|
||||
useSearchForm: false,
|
||||
// 显示表格设置工具
|
||||
showTableSetting: true,
|
||||
// 是否显示表格边框
|
||||
bordered: true,
|
||||
// 序号列
|
||||
showIndexColumn: false,
|
||||
// 搜索
|
||||
handleSearchInfoFn(info) {
|
||||
return info;
|
||||
},
|
||||
actionColumn: {
|
||||
width: 120,
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
// slots: { customRender: 'action' },
|
||||
fixed: undefined,
|
||||
},
|
||||
});
|
||||
const toPosition = (row) => {
|
||||
const lnglat = [row.lng, row.lat];
|
||||
EventBus.emit('inspectionMoldeMap', lnglat);
|
||||
};
|
||||
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],
|
||||
};
|
||||
getPatrolPointByTimeSubsection(query).then((res) => {
|
||||
console.log(res);
|
||||
routerLine.value = res;
|
||||
if (res.length == 0) {
|
||||
return createMessage.warning('暂无1小时内轨迹');
|
||||
}
|
||||
});
|
||||
};
|
||||
const stateOptions = ref([
|
||||
{
|
||||
label: '全部',
|
||||
value: '全部',
|
||||
},
|
||||
{
|
||||
label: '在线',
|
||||
value: '在线',
|
||||
},
|
||||
{
|
||||
label: '离线',
|
||||
value: '离线',
|
||||
},
|
||||
]);
|
||||
// 查询
|
||||
interface FormState {
|
||||
isonline: string;
|
||||
townname: string;
|
||||
}
|
||||
const formState: FormState = reactive({
|
||||
isonline: '全部',
|
||||
page: 1,
|
||||
limit: 10,
|
||||
});
|
||||
const getLine = () => {
|
||||
getPointUserOnLine(formState).then((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();
|
||||
getTree();
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.form-button {
|
||||
button {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
::v-deep .ant-modal {
|
||||
top: 20px;
|
||||
}
|
||||
.all-count {
|
||||
width: 100%;
|
||||
padding: 20px 20px;
|
||||
padding-bottom: 60px;
|
||||
border-bottom: 1px solid @border-color-light;
|
||||
border-top: 1px solid @border-color-light;
|
||||
}
|
||||
|
||||
.all-count div {
|
||||
width: 40%;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border-left: 3px solid #409eff;
|
||||
float: left;
|
||||
margin-left: 20px;
|
||||
text-indent: 20px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,609 @@
|
|||
<template>
|
||||
<div
|
||||
style="position: relative; height: 100%"
|
||||
ref="vChartRef"
|
||||
:id="'mars3d-container-' + name"
|
||||
></div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { isArray } from '@/utils';
|
||||
import * as mars3d from 'mars3d';
|
||||
import { useModal } from '@/components/Modal';
|
||||
import { EventBus } from '@/utils/eventBus';
|
||||
import { getCheckPointList } from '@/api/firegrid/index';
|
||||
import axios from 'axios';
|
||||
|
||||
const emits = defineEmits(['onLoad'])
|
||||
|
||||
let map: mars3d.Map; // 地图对象
|
||||
|
||||
let mapIns: any = null;
|
||||
let markers: any = [];
|
||||
let AMapIns: any = null;
|
||||
|
||||
const vChartRef = ref<HTMLElement>();
|
||||
const props = defineProps({
|
||||
name: {
|
||||
type: String,
|
||||
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);
|
||||
// 定位到某个经纬度
|
||||
EventBus.on('inspectionMap', (data: any) => {
|
||||
map.flyToPoint(data, {
|
||||
radius: 5000, // 距离目标点的距离
|
||||
duration: 4,
|
||||
});
|
||||
});
|
||||
getPointInfo({
|
||||
page: 1,
|
||||
limit: 10,
|
||||
});
|
||||
loadAllRangeLayer('费县');
|
||||
EventBus.on('getPatrolMap', (data: any) => {
|
||||
getPointInfo(data);
|
||||
loadAllRangeLayer(data.pointName);
|
||||
});
|
||||
});
|
||||
|
||||
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);
|
||||
}
|
||||
map.on(mars3d.EventType.load, function (event) {
|
||||
emits('onLoad', map);
|
||||
})
|
||||
isFirstLoad.value = false;
|
||||
// 初始化矢量图层
|
||||
handlerInitEntityLayer();
|
||||
};
|
||||
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) {
|
||||
// initMap(props.chartConfig.option)
|
||||
return;
|
||||
}
|
||||
if (isArray(newData.markers)) {
|
||||
// 先清除旧标记
|
||||
mapIns.remove(markers);
|
||||
markers = [];
|
||||
// 记录新标记
|
||||
if (mapMarkerType.value === 'Marker') {
|
||||
newData.markers.forEach((markerItem: any) => {
|
||||
const markerInstance = new AMapIns.Marker({
|
||||
position: [markerItem.position[0], markerItem.position[1]],
|
||||
offset: new AMapIns.Pixel(-13, -30),
|
||||
});
|
||||
markers.push(markerInstance);
|
||||
markerInstance.setMap(mapIns);
|
||||
});
|
||||
} else if (mapMarkerType.value === 'CircleMarker') {
|
||||
newData.markers.forEach((markerItem: any) => {
|
||||
const markerInstance = new AMapIns.CircleMarker({
|
||||
center: [markerItem.position[0], markerItem.position[1]],
|
||||
radius: markerItem.value,
|
||||
...marker.value,
|
||||
});
|
||||
markers.push(markerInstance);
|
||||
markerInstance.setMap(mapIns);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let graphicLayer = null;
|
||||
// 地球创建完成后默认加载矢量数据图层
|
||||
const handlerInitEntityLayer = () => {
|
||||
if (graphicLayer == null) {
|
||||
graphicLayer = new mars3d.layer.GraphicLayer({ id: 999 });
|
||||
}
|
||||
};
|
||||
|
||||
// 点击获取点击位置点位信息 用于常见的下发火点、下发任务点等使用
|
||||
|
||||
const handlerDrawPoint = async () => {
|
||||
const graphic = await graphicLayer.startDraw({
|
||||
type: 'point',
|
||||
});
|
||||
|
||||
let position = graphic.toJSON().position;
|
||||
|
||||
let res = {
|
||||
lng: position[0],
|
||||
lat: position[1],
|
||||
alt: position[0],
|
||||
};
|
||||
|
||||
graphicLayer.removeGraphic(graphic);
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
// 添加Entity
|
||||
const handlerAddEntity = (data) => {
|
||||
let graphicOptions = {
|
||||
id: data.id,
|
||||
position: [parseFloat(data.Lng), parseFloat(data.Lat)],
|
||||
style: {
|
||||
image: '@/assets/images/chart/xunchaguiji/locationicon.png',
|
||||
clampToGround: true,
|
||||
scale: 0.5,
|
||||
label: {
|
||||
text: data.PointName,
|
||||
font_size: 14,
|
||||
color: '#ffffff',
|
||||
pixelOffsetY: 10,
|
||||
distanceDisplayCondition: true,
|
||||
distanceDisplayCondition_far: 500000,
|
||||
distanceDisplayCondition_near: 0,
|
||||
},
|
||||
},
|
||||
popup: `<div class="marsTiltPanel marsTiltPanel-theme-red" style="font-size:12px;">
|
||||
<div class="marsTiltPanel-wrap">
|
||||
<div class="area">
|
||||
<div class="arrow-lt"></div>
|
||||
<div class="b-t"></div>
|
||||
<div class="b-r"></div>
|
||||
<div class="b-b"></div>
|
||||
<div class="b-l"></div>
|
||||
<div class="arrow-rb"></div>
|
||||
<div class="label-wrap">
|
||||
<div class="title">火点信息</div>
|
||||
<div class="label-content">
|
||||
<div class="data-li">
|
||||
<div class="data-label">火点地址:${data.PointName}</div>
|
||||
</div>
|
||||
<div class="data-li">
|
||||
<div class="data-label">上报时间:</div>
|
||||
<div class="data-value"><span id="lablYeWei" class="label-num">2025-2-11 12:00:00</span><span class="label-unit"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="data-li">
|
||||
<div class="data-value">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
<div class="b-t-l"></div>
|
||||
<div class="b-b-r"></div>
|
||||
</div>
|
||||
<div class="arrow" ></div>
|
||||
</div>`,
|
||||
popupOptions: {
|
||||
offsetY: -30,
|
||||
template: '{content}',
|
||||
horizontalOrigin: 'Cesium.HorizontalOrigin.LEFT',
|
||||
verticalOrigin: 'Cesium.VerticalOrigin.CENTER',
|
||||
},
|
||||
};
|
||||
|
||||
let graphic = graphicLayer.getGraphicById(data.id);
|
||||
|
||||
if (graphic) {
|
||||
graphic.setStyleOptions(graphicOptions);
|
||||
} else {
|
||||
graphic = new mars3d.graphic.BillboardEntity(graphicOptions);
|
||||
graphicLayer.addGraphic(graphic);
|
||||
}
|
||||
};
|
||||
|
||||
const handlerHiddenEntity = (data) => {
|
||||
let graphic = graphicLayer.getGraphicById(data.id);
|
||||
if (graphic) {
|
||||
graphic.show = false;
|
||||
}
|
||||
};
|
||||
|
||||
const handlerRemoveEntity = (data) => {
|
||||
let graphic = graphicLayer.getGraphicById(data.id);
|
||||
if (graphic) {
|
||||
graphicLayer.removeGraphic(graphic);
|
||||
}
|
||||
};
|
||||
|
||||
const handlerFlyToEntity = (data) => {
|
||||
let graphic = graphicLayer.getGraphicById(data.id);
|
||||
|
||||
if (graphic) {
|
||||
if (data.image.activeIcon) {
|
||||
grasphic.setStyle({
|
||||
image: data.image.activeIcon,
|
||||
});
|
||||
}
|
||||
|
||||
window.globalMap.flyToGraphic(graphic);
|
||||
}
|
||||
};
|
||||
|
||||
// 清空所有适量图标
|
||||
const handlerClearEntityLayer = () => {
|
||||
graphicLayer.clear();
|
||||
};
|
||||
|
||||
// 隐藏所有矢量图标
|
||||
const handlerHiddenEntityLayer = () => {
|
||||
graphicLayer.show = false;
|
||||
};
|
||||
|
||||
// yi
|
||||
</script>
|
||||
<style lang="less" scoped></style>
|
||||
|
|
@ -0,0 +1,220 @@
|
|||
<template>
|
||||
<div class="m-4 flex">
|
||||
<div class="w-1/2 xl:w-1/2">
|
||||
<div class="search-container flex justify-end items-center form-data m-4">
|
||||
<a-range-picker
|
||||
:show-time="{ format: 'HH:mm' }"
|
||||
format="YYYY-MM-DD HH:mm"
|
||||
:placeholder="['开始时间', '结束时间']"
|
||||
@change="timeChange"
|
||||
v-model:value="value1"
|
||||
/>
|
||||
</div>
|
||||
<a-tabs v-model:activeKey="activeKey">
|
||||
<a-tab-pane key="1" tab="巡查轨迹">
|
||||
<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">
|
||||
<img src="@/assets/images/meshing/rangers-number.png" alt="" />
|
||||
</div>
|
||||
<div class="user-name">{{ it.name }}</div>
|
||||
<div class="user-phone">{{ it.phone }}</div>
|
||||
<a-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
round
|
||||
@click="getTrajectoryData(it)"
|
||||
style="float: right"
|
||||
>轨迹</a-button
|
||||
>
|
||||
</div>
|
||||
{{ it.startAddress }}
|
||||
<span style="font-size: 12px">({{ it.startTime }})</span>
|
||||
<SwapRightOutlined style="font-size: 20px" />
|
||||
{{ it.endAddress }}
|
||||
<span style="font-size: 12px">({{ it.endTime }})</span>
|
||||
</div>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="2" tab="打卡记录" force-render>
|
||||
<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 }}
|
||||
<span
|
||||
> <HistoryOutlined />打卡时间:</span
|
||||
>
|
||||
{{ item.ClockonTime }}
|
||||
</p>
|
||||
<p>
|
||||
<span><EnvironmentOutlined /> 打卡位置:</span>
|
||||
{{ parseFloat(item.Lng).toFixed(6) }},{{ parseFloat(item.Lat).toFixed(6) }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</div>
|
||||
<div class="w-1/2 xl:w-1/2" style="height: 90vh">
|
||||
<Map :name="'patrolTrackModel'" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { Map } from './index';
|
||||
import {
|
||||
SwapRightOutlined,
|
||||
UserOutlined,
|
||||
HistoryOutlined,
|
||||
EnvironmentOutlined,
|
||||
} from '@ant-design/icons-vue';
|
||||
import { getCheckInfoByUserId } from '@/api/firegrid/index';
|
||||
import { getPatrolInfoByUserId } from '@/api/firegrid/patrol';
|
||||
import moment from 'moment';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
defineOptions({ name: 'DeptModal' });
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {};
|
||||
},
|
||||
},
|
||||
});
|
||||
const activeKey = ref('1');
|
||||
const list = ref([]);
|
||||
const clockInList = ref([]);
|
||||
const value1: any = ref([dayjs().subtract(1, 'month'), dayjs()]);
|
||||
const getTrajectoryData = (item) => {
|
||||
console.log(item);
|
||||
};
|
||||
// 查询
|
||||
interface FormState {
|
||||
begintime: string | null;
|
||||
endtime: string | null;
|
||||
}
|
||||
const formState: FormState = reactive({
|
||||
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(() => {
|
||||
formState.begintime = dayjs().subtract(1, 'month').format('YYYY-MM-DD HH:mm')
|
||||
formState.endtime = dayjs().format('YYYY-MM-DD HH:mm')
|
||||
getCheckList();
|
||||
getPatrolList();
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.users-container {
|
||||
width: 100%;
|
||||
padding-right: 15px;
|
||||
height: calc(100vh - 280px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
.item-container-right div {
|
||||
float: left;
|
||||
}
|
||||
.user-item {
|
||||
width: 100%;
|
||||
padding: 0px 0px;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
}
|
||||
.history-line {
|
||||
width: 100%;
|
||||
line-height: 20px;
|
||||
margin-bottom: 20px;
|
||||
text-indent: 0px;
|
||||
border-bottom: 1px solid @border-color-light;
|
||||
cursor: pointer;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
.user-item::after {
|
||||
content: '';
|
||||
clear: both;
|
||||
display: block;
|
||||
visibility: hidden;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.user-photo {
|
||||
float: left;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
margin-top: 6px;
|
||||
background-color: rgb(255, 255, 255);
|
||||
border-radius: 50%;
|
||||
line-height: 36px;
|
||||
text-align: center;
|
||||
}
|
||||
.user-photo img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin: 0px;
|
||||
}
|
||||
.user-name {
|
||||
width: 120px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.user-phone {
|
||||
width: 100px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.user-operation {
|
||||
float: right;
|
||||
}
|
||||
.clockIn-box {
|
||||
border-bottom: 1px solid @border-color-light;
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
import { BasicColumn, FormSchema } from '@/components/Table';
|
||||
import { Tag } from 'ant-design-vue';
|
||||
import { h } from 'vue';
|
||||
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '所属班组',
|
||||
dataIndex: 'areaName',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: '护林员',
|
||||
dataIndex: 'name',
|
||||
},
|
||||
{
|
||||
title: '手机号码',
|
||||
dataIndex: 'account',
|
||||
},
|
||||
{
|
||||
title: '打卡次数',
|
||||
dataIndex: 'dakacishu',
|
||||
},
|
||||
{
|
||||
title: '巡检次数',
|
||||
dataIndex: 'xunjian',
|
||||
},
|
||||
{
|
||||
title: '打卡点数量',
|
||||
dataIndex: 'dakadian',
|
||||
},
|
||||
];
|
||||
|
||||
export const InspectionColumns: BasicColumn[] = [
|
||||
{
|
||||
title: '乡镇/村庄',
|
||||
dataIndex: 'townName',
|
||||
},
|
||||
{
|
||||
title: '护林员姓名',
|
||||
dataIndex: 'name',
|
||||
},
|
||||
{
|
||||
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: '离线时长',
|
||||
dataIndex: 'onLineTime',
|
||||
},
|
||||
];
|
||||
|
||||
export const formSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'id',
|
||||
label: 'id',
|
||||
component: 'Input',
|
||||
ifShow: false,
|
||||
},
|
||||
{
|
||||
field: 'pointName',
|
||||
label: '打卡点名称',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
field: 'areaId',
|
||||
label: '行政区划',
|
||||
required: true,
|
||||
slot: 'areaId',
|
||||
},
|
||||
{
|
||||
field: 'userId',
|
||||
label: '责任人',
|
||||
slot: 'userId',
|
||||
required: true,
|
||||
},
|
||||
];
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
export { default as Map } from './Map.vue';
|
||||
export { default as PatrolTrackModel } from './PatrolTrackModel.vue';
|
||||
|
|
@ -0,0 +1,244 @@
|
|||
<template>
|
||||
<div class="m-4">
|
||||
<div class="search-container flex justify-end items-center form-data m-4">
|
||||
<a-tree-select
|
||||
v-model:value="formState.areaid"
|
||||
style="width: 30%; margin-right: 10px"
|
||||
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
|
||||
:tree-data="treeData"
|
||||
placeholder="选择行政区划"
|
||||
:field-names="{ label: 'name', value: 'id' }"
|
||||
/>
|
||||
<a-range-picker
|
||||
:show-time="{ format: 'HH:mm' }"
|
||||
format="YYYY-MM-DD HH:mm"
|
||||
:placeholder="['开始时间', '结束时间']"
|
||||
@change="timeChange"
|
||||
v-model:value="value1"
|
||||
/>
|
||||
<div class="form-button">
|
||||
<a-button type="primary" @click="inquire">查询</a-button>
|
||||
<a-button type="primary">导出</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cate-title">数据总览</div>
|
||||
<div class="count-item-container">
|
||||
<div class="count-item">
|
||||
<div class="count-item-icon">
|
||||
<img src="@/assets/images/meshing/rangers-number.png" />
|
||||
</div>
|
||||
<div class="count-item-title"> 护林员数量 </div>
|
||||
<div class="count-item-value"> {{ allData.hulinyuan }} <span class="unit">人</span> </div>
|
||||
</div>
|
||||
|
||||
<div class="count-item">
|
||||
<div class="count-item-icon">
|
||||
<img src="@/assets/images/meshing/punch-track.png" />
|
||||
</div>
|
||||
<div class="count-item-title"> 全部巡查总数 </div>
|
||||
<div class="count-item-value">
|
||||
{{ allData.xunchazongshu }} <span class="unit">次</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="count-item">
|
||||
<div class="count-item-icon">
|
||||
<img src="@/assets/images/meshing/punch-times.png" />
|
||||
</div>
|
||||
<div class="count-item-title"> 全部打卡总数 </div>
|
||||
<div class="count-item-value"> {{ allData.dakacishu }} <span class="unit">次</span> </div>
|
||||
</div>
|
||||
|
||||
<div class="count-item">
|
||||
<div class="count-item-icon">
|
||||
<img src="@/assets/images/meshing/significant-frequency.png" />
|
||||
</div>
|
||||
<div class="count-item-title"> 全部打卡点数 </div>
|
||||
<div class="count-item-value"> {{ allData.dakadian }} <span class="unit">个</span> </div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-container">
|
||||
<BasicTable @register="registerTable">
|
||||
<template #toolbar>
|
||||
<!-- <a-button type="primary" @click="handleCreate"> 新增角色 </a-button> -->
|
||||
<!-- <a-button type="primary" @click="handleItem"> 获取选中行 </a-button> -->
|
||||
<PermissionBtn @btn-event="onBtnClicked" />
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'action'">
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
// icon: 'ant-design:ellipsis-outlined',
|
||||
label: '巡查轨迹',
|
||||
onClick: getGuiji.bind(null, record),
|
||||
},
|
||||
]"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
</BasicTable>
|
||||
</div>
|
||||
<a-modal
|
||||
v-model:visible="patrolTrackModelVisible"
|
||||
title="巡查"
|
||||
wrap-class-name="full-modal"
|
||||
width="100%"
|
||||
:footer="null"
|
||||
:destroyOnClose="true"
|
||||
>
|
||||
<PatrolTrackModel :data="patrolTrackData" />
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref, onMounted } from 'vue';
|
||||
import { BasicTable, useTable, TableAction } from '@/components/Table';
|
||||
import { getStatistics, getStatisticsCount } from '@/api/firegrid/index';
|
||||
import { columns } from './data';
|
||||
import { PatrolTrackModel } from './index';
|
||||
import { getDeptList } from '@/api/demo/system';
|
||||
import moment from 'moment';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
defineOptions({ name: 'DeptModal' });
|
||||
const patrolTrackModelVisible = ref(false);
|
||||
const treeData: any = ref([]);
|
||||
const value1: any = ref([dayjs().subtract(1, 'month'), dayjs()]);
|
||||
const getTree = () => {
|
||||
getDeptList().then((res) => {
|
||||
treeData.value = res;
|
||||
});
|
||||
};
|
||||
const [registerTable, { reload, getSelectRows, clearSelectedRowKeys }] = useTable({
|
||||
// 表格名称
|
||||
title: '角色列表',
|
||||
// 获取数据的接口
|
||||
api: getStatistics,
|
||||
// 表单列信息 BasicColumn[]
|
||||
columns,
|
||||
rowKey: 'id',
|
||||
// 使用搜索表单
|
||||
useSearchForm: false,
|
||||
// 显示表格设置工具
|
||||
showTableSetting: true,
|
||||
// 是否显示表格边框
|
||||
bordered: true,
|
||||
// 序号列
|
||||
showIndexColumn: false,
|
||||
// 勾选列
|
||||
rowSelection: {
|
||||
//多选框
|
||||
// type: 'checkbox',
|
||||
type: 'radio',
|
||||
},
|
||||
// 搜索
|
||||
handleSearchInfoFn(info) {
|
||||
return info;
|
||||
},
|
||||
actionColumn: {
|
||||
width: 80,
|
||||
title: '查看账号',
|
||||
dataIndex: 'action',
|
||||
// slots: { customRender: 'action' },
|
||||
fixed: undefined,
|
||||
},
|
||||
});
|
||||
const patrolTrackData = ref({});
|
||||
const getGuiji = (item: any) => {
|
||||
patrolTrackModelVisible.value = true;
|
||||
patrolTrackData.value = item;
|
||||
};
|
||||
const allData: any = ref({});
|
||||
// 查询
|
||||
interface FormState {
|
||||
begintime: string | null;
|
||||
endtime: string | null;
|
||||
areaid: string | null;
|
||||
}
|
||||
const formState: FormState = reactive({
|
||||
begintime: null,
|
||||
endtime: null,
|
||||
areaid: null,
|
||||
});
|
||||
const timeChange = (value: any, dateString: string) => {
|
||||
console.log(dateString);
|
||||
formState.begintime = dateString[0];
|
||||
formState.endtime = dateString[1];
|
||||
};
|
||||
const getCount = () => {
|
||||
getStatisticsCount(formState).then((res) => {
|
||||
allData.value = res;
|
||||
});
|
||||
};
|
||||
const inquire = () => {
|
||||
getCount();
|
||||
reload();
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
formState.begintime = dayjs().subtract(1, 'month').format('YYYY-MM-DD HH:mm')
|
||||
formState.endtime = dayjs().format('YYYY-MM-DD HH:mm')
|
||||
getCount();
|
||||
getTree();
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.form-button {
|
||||
button {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
::v-deep .ant-modal {
|
||||
top: 20px;
|
||||
}
|
||||
.cate-title {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.count-item-container {
|
||||
width: 100%;
|
||||
min-height: 100px;
|
||||
padding: 15px 0px;
|
||||
}
|
||||
|
||||
.count-item {
|
||||
width: calc(25% - 20px);
|
||||
padding: 5px 15px;
|
||||
float: left;
|
||||
margin-right: 20px;
|
||||
border-radius: 0px;
|
||||
box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.count-item .count-item-icon {
|
||||
float: left;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.count-item-icon img {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin-top: 4px;
|
||||
opacity: 0.9;
|
||||
}
|
||||
.count-item-title {
|
||||
line-height: 50px;
|
||||
margin-left: 15px;
|
||||
font-size: 14px;
|
||||
float: left;
|
||||
color: #9da1bd;
|
||||
}
|
||||
.count-item-value {
|
||||
font-size: 20px;
|
||||
line-height: 50px;
|
||||
margin-left: 30px;
|
||||
float: right;
|
||||
}
|
||||
.count-item .unit {
|
||||
font-size: 14px;
|
||||
color: #ccc;
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue