-
BINsrc/assets/images/equip/home/kx.png
-
BINsrc/assets/images/equip/home/mark_green.png
-
BINsrc/assets/images/equip/home/mark_red.png
-
BINsrc/assets/images/equip/home/mark_yellow.png
-
BINsrc/assets/images/equip/home/poto.png
-
BINsrc/assets/images/equip/home/rerm.png
-
BINsrc/assets/images/equip/home/yc.png
-
151src/components/MapComponets/BaseMap/index.jsx
-
47src/components/MapComponets/MarkCenter/index.jsx
-
189src/components/MapComponets/ParkingViewMarkers/index.jsx
-
71src/components/MapComponets/ParkingViewMarkers/index.scss
-
16src/components/MapComponets/index.jsx
-
7src/pages/DataAnalysisPrediction/MemberStat/ParkingAly/index.scss
-
157src/pages/DataAnalysisPrediction/MemberStat/ParkingAly/loadable.jsx
-
5src/pages/DataAnalysisPrediction/MemberStat/PayAly/index.scss
-
393src/pages/DataAnalysisPrediction/MemberStat/PayAly/loadable.jsx
-
290src/pages/DataAnalysisPrediction/MemberStat/RegisterAly/loadable.jsx
-
466src/pages/DataAnalysisPrediction/ParkingOverview/index.scss
-
1527src/pages/DataAnalysisPrediction/ParkingOverview/loadable.jsx
-
35src/services/ElectInvoice/index.js
-
100src/services/ParkingOverview/index.js
-
2src/services/index.js
After Width: 194 | Height: 122 | Size: 5.4 KiB |
After Width: 29 | Height: 35 | Size: 1.7 KiB |
After Width: 29 | Height: 35 | Size: 1.7 KiB |
After Width: 29 | Height: 35 | Size: 1.7 KiB |
After Width: 18 | Height: 16 | Size: 1.2 KiB |
After Width: 11 | Height: 14 | Size: 1.1 KiB |
After Width: 194 | Height: 122 | Size: 16 KiB |
@ -0,0 +1,47 @@ |
|||
import React, { useState, useEffect, useRef } from "react"; |
|||
import L from "leaflet"; |
|||
import "leaflet/dist/leaflet.css"; |
|||
// import "leaflet-canvas-marker" |
|||
import "../js/leaflet.canvas-markers"; |
|||
// import "./index.scss"; |
|||
import Rerm from "../Marker/default-marker2.png"; |
|||
|
|||
function Markers(props) { |
|||
const map = props.__map__; |
|||
const { |
|||
data = {}, |
|||
iconSize = [30, 40], // 点位图片大小 |
|||
iconAnchor = [11, 11], // 图片偏移量 |
|||
} = props; |
|||
const [Marker, setMarker] = useState(null); |
|||
useEffect(() => { |
|||
if (data.lng) { |
|||
addMarker(data); |
|||
} |
|||
}, [data]); |
|||
const addMarker = (data) => { |
|||
if (Marker) { |
|||
map.removeLayer(Marker); |
|||
} |
|||
let marker = L.marker([data.lat, data.lng], { |
|||
icon: L.icon({ |
|||
iconUrl: Rerm, |
|||
iconSize, |
|||
iconAnchor, |
|||
}), |
|||
}) |
|||
.addTo(map) |
|||
.bindTooltip(`<span>${data.name}</span>`, { |
|||
offset: [20, -5], |
|||
direction: "right", |
|||
}); |
|||
setMarker(marker); |
|||
setTimeout(() => { |
|||
map.setView([data.lat, data.lng]); |
|||
}, 800); |
|||
}; |
|||
|
|||
return null; |
|||
} |
|||
|
|||
export default Markers; |
@ -0,0 +1,189 @@ |
|||
import React, { useState, useEffect, useRef } from "react"; |
|||
import L from "leaflet"; |
|||
import "leaflet/dist/leaflet.css"; |
|||
// import "leaflet-canvas-marker" |
|||
import "../js/leaflet.canvas-markers"; |
|||
import "./index.scss"; |
|||
import mgreen from "@/assets/images/equip/home/mark_green.png"; |
|||
import mgred from "@/assets/images/equip/home/mark_red.png"; |
|||
import mgyellow from "@/assets/images/equip/home/mark_yellow.png"; |
|||
|
|||
function Markers(props) { |
|||
const map = props.__map__; |
|||
const { |
|||
data = [], |
|||
iconSize = [30, 40], // 点位图片大小 |
|||
iconAnchor = [15, 20], // 图片偏移量 |
|||
tooltipKey = "name", // 提示信息的key |
|||
// contentCb, // 生成弹窗显示内容方法事件 |
|||
clickCb, // 点击事件 |
|||
} = props; |
|||
const [massLayer, setMassLayer] = useState(null); // 海量点图层 |
|||
const massLayerRef = useRef(massLayer); |
|||
massLayerRef.current = massLayer; |
|||
const [massObj, setMassObj] = useState({}); // 海量点对象 |
|||
const massObjRef = useRef(); |
|||
massObjRef.current = massObj; |
|||
// const imgurls = (val) => { |
|||
|
|||
// } |
|||
useEffect(() => { |
|||
return () => { |
|||
if (map && massLayerRef.current) { |
|||
if (massLayerRef.current._latlngMarkers) { |
|||
// 判断是否有点位存在 |
|||
massLayerRef.current.clearLayers(); // 清除点位图层 |
|||
} |
|||
} |
|||
}; |
|||
}, []); |
|||
|
|||
useEffect(() => { |
|||
if (map && !massLayer) { |
|||
let _massLayer = L.canvasIconLayer({}); // 创建海量点图层 |
|||
setMassLayer(_massLayer); |
|||
_massLayer.addTo(map); |
|||
if (data.length) { |
|||
let _mass = handleLocation(data); // 处理点位数据 |
|||
addMarker(_mass, _massLayer); // 添加点位 |
|||
} |
|||
} |
|||
}, [map]); |
|||
|
|||
useEffect(() => { |
|||
if (massLayerRef.current) { |
|||
if (massLayerRef.current._latlngMarkers) { |
|||
// 判断是否有点位存在 |
|||
massLayerRef.current.clearLayers(); // 清除点位图层 |
|||
massLayerRef.current._onClickListeners = []; // 清除监听事件 |
|||
} |
|||
if (data.length) { |
|||
let _mass = handleLocation(data); // 处理点位数据 |
|||
addMarker(_mass, massLayerRef.current); // 添加点位 |
|||
} |
|||
} |
|||
}, [data]); |
|||
|
|||
const handleLocation = (arr = []) => { |
|||
if (!Array.isArray(arr)) { |
|||
console.log("传值必须为数组"); |
|||
return false; |
|||
} |
|||
let object = {}; |
|||
for (let i = 0; i < arr.length; i++) { |
|||
let elem = arr[i]; |
|||
if (!parseFloat(elem.latitude) || !parseFloat(elem.longitude)) { |
|||
// 经纬度必须有 |
|||
continue; |
|||
} |
|||
let typeKey = "type_" + elem.type; |
|||
if (object.hasOwnProperty(typeKey)) { |
|||
object[typeKey].nodes.push({ |
|||
lnglat: [parseFloat(elem.lat), parseFloat(elem.lng)], |
|||
name: elem.text, |
|||
style: 0, |
|||
locationId: elem.id, |
|||
type: elem.type, |
|||
action: elem.action, |
|||
data: elem, |
|||
}); |
|||
} else { |
|||
object[typeKey] = { |
|||
type: elem.type, |
|||
iconStyle: [ |
|||
L.icon({ |
|||
iconUrl: |
|||
elem.type == 1 ? mgred : elem.type == 3 ? mgreen : mgyellow, |
|||
iconSize: iconSize, |
|||
iconAnchor: iconAnchor, |
|||
}), |
|||
], |
|||
nodes: [ |
|||
{ |
|||
lnglat: [parseFloat(elem.lat), parseFloat(elem.lng)], |
|||
name: elem.text, |
|||
style: 0, |
|||
locationId: elem.id, |
|||
type: elem.type, |
|||
action: elem.action, |
|||
data: elem, |
|||
}, |
|||
], |
|||
}; |
|||
} |
|||
} |
|||
setMassObj(object); |
|||
return object; |
|||
}; |
|||
|
|||
const addMarker = (markerArr, _massLayer) => { |
|||
for (let [key, value] of Object.entries(markerArr)) { |
|||
if (!value.hasOwnProperty("massMarkers")) { |
|||
value.massMarkers = []; |
|||
value.nodes.forEach((elem) => { |
|||
let marker = L.marker([elem.lnglat[0], elem.lnglat[1]], { |
|||
icon: value.iconStyle[0], |
|||
}); |
|||
marker.data = elem; |
|||
value.massMarkers.push(marker); |
|||
marker.bindTooltip(`<span>${elem[tooltipKey]}</span>`, { |
|||
offset: [20, -5], |
|||
direction: "right", |
|||
}); |
|||
}); |
|||
_massLayer.addLayers(value.massMarkers); |
|||
} else { |
|||
_massLayer.addLayers(value.massMarkers); |
|||
} |
|||
} |
|||
_massLayer._onClickListeners = []; |
|||
if (clickCb) { |
|||
_massLayer.addOnClickListener(function (e, data) { |
|||
if (data.length == "1") { |
|||
let elem = data[0].data.data.data; |
|||
clickCb(elem); |
|||
} else { |
|||
map.openPopup(renderMarkerList(data), e.latlng, { |
|||
className: "markers-list-box", |
|||
}); |
|||
let dom = document.querySelectorAll(".marker-list-item"); |
|||
dom.forEach((elem) => { |
|||
elem.addEventListener("click", function (e) { |
|||
map.closePopup(); |
|||
let type = e.target.dataset.type, |
|||
id = e.target.dataset.id; |
|||
let marker = massObjRef.current["type_" + type].nodes.filter( |
|||
(i) => i.locationId == id |
|||
)[0]; |
|||
let elem = marker.data; |
|||
clickCb(elem); |
|||
}); |
|||
}); |
|||
} |
|||
}); |
|||
} |
|||
let markers = []; |
|||
for (let [key, value] of Object.entries(markerArr)) { |
|||
markers = [...markers, ...value.massMarkers]; |
|||
} |
|||
}; |
|||
|
|||
const renderMarkerList = (data) => { |
|||
let template = `<div class="marker-list-content"> |
|||
<div class="marker-list-header">请选择点位</div> |
|||
<div class="marker-list"> |
|||
`; |
|||
data.forEach((elem) => { |
|||
let _data = elem.data.data; |
|||
if (_data.name && _data.locationId) { |
|||
template += `<div class="marker-list-item" data-type="${_data.type}" data-id="${_data.locationId}" title="${_data.name}">${_data.name}</div>`; |
|||
} |
|||
}); |
|||
template += `</div></div>`; |
|||
return template; |
|||
}; |
|||
|
|||
return null; |
|||
} |
|||
|
|||
export default Markers; |
@ -0,0 +1,71 @@ |
|||
.markers-list-box { |
|||
width: 300px !important; |
|||
.leaflet-popup-content-wrapper { |
|||
padding: 0; |
|||
border-radius: 0; |
|||
color: #ccddff; |
|||
background: #172c4d !important; |
|||
} |
|||
.leaflet-popup-content { |
|||
margin: 0; |
|||
width: 100% !important; |
|||
} |
|||
.leaflet-popup-tip-container { |
|||
.leaflet-popup-tip { |
|||
background: #172c4d; |
|||
} |
|||
} |
|||
.leaflet-popup-close-button { |
|||
display: none; |
|||
} |
|||
.marker-list-content { |
|||
.marker-list-header { |
|||
height: 32px; |
|||
line-height: 32px; |
|||
vertical-align: middle; |
|||
padding: 0 10px; |
|||
font-size: 14px; |
|||
font-weight: bold; |
|||
letter-spacing: 1px; |
|||
width: 100%; |
|||
overflow: hidden; |
|||
white-space: nowrap; |
|||
text-overflow: ellipsis; |
|||
} |
|||
.marker-list { |
|||
padding: 10px; |
|||
color: var(--color-text); |
|||
max-height: 200px; |
|||
overflow-y: auto; |
|||
overflow-x: hidden; |
|||
&::-webkit-scrollbar-track-piece { |
|||
background-color: transparent; |
|||
border-radius: 8px; |
|||
} |
|||
&::-webkit-scrollbar { |
|||
width: 8px; |
|||
height: 8px; |
|||
} |
|||
&::-webkit-scrollbar-thumb { |
|||
background-clip: padding-box; |
|||
border-radius: 8px; |
|||
min-height: 28px; |
|||
} |
|||
.marker-list-item { |
|||
width: 100%; |
|||
height: 24px; |
|||
line-height: 24px; |
|||
white-space: nowrap; |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; |
|||
cursor: pointer; |
|||
&:hover { |
|||
text-decoration: underline; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.construction-polygon { |
|||
font-size: 14px; |
|||
} |
@ -1,11 +1,15 @@ |
|||
import BaseMap from "./BaseMap" |
|||
import BaseGaodeMap from "./BaseGaodeMap" |
|||
import Markers from "./Markers" |
|||
import Marker from "./Marker" |
|||
import BaseMap from "./BaseMap"; |
|||
import BaseGaodeMap from "./BaseGaodeMap"; |
|||
import Markers from "./Markers"; |
|||
import Marker from "./Marker"; |
|||
import ParkingViewMarkers from "./ParkingViewMarkers"; |
|||
import MarkCenter from "./MarkCenter"; |
|||
|
|||
export { |
|||
BaseMap, |
|||
BaseGaodeMap, |
|||
Markers, |
|||
Marker |
|||
} |
|||
Marker, |
|||
MarkCenter, |
|||
ParkingViewMarkers, |
|||
}; |
1527
src/pages/DataAnalysisPrediction/ParkingOverview/loadable.jsx
File diff suppressed because it is too large
View File
@ -0,0 +1,100 @@ |
|||
import ajax from "../../config/ajax"; |
|||
//-----------------------------停车业务概括数据----------------------------------
|
|||
export default { |
|||
//获取泊位总数弹框数据列表
|
|||
getParkingBoW: (params) => { |
|||
return ajax({ |
|||
url: "/api/ana/overview/berthList", |
|||
type: "post", |
|||
data: params, |
|||
}); |
|||
}, |
|||
//获取实时泊位显示数据
|
|||
getSituationData: (params) => { |
|||
return ajax({ |
|||
url: "/api/ana/overview/berthSituation", |
|||
type: "get", |
|||
data: params, |
|||
}); |
|||
}, |
|||
//获取实时泊位显示数据详情
|
|||
getSituationDetailData: (params) => { |
|||
return ajax({ |
|||
url: "/api/ana/overview/getBerthDetail", |
|||
type: "get", |
|||
data: params, |
|||
}); |
|||
}, |
|||
//获取地图车场数据
|
|||
getMapData: (params) => { |
|||
return ajax({ |
|||
url: "/api/ana/overview/getParks", |
|||
type: "get", |
|||
data: params, |
|||
}); |
|||
}, |
|||
//获取停车场模糊检索
|
|||
searchPark: (params) => { |
|||
return ajax({ |
|||
url: "/api/ana/overview/searchPaking", |
|||
type: "get", |
|||
data: params, |
|||
}); |
|||
}, |
|||
//获取位置模糊检索
|
|||
searchGeocode: (params) => { |
|||
return ajax({ |
|||
url: "/api/ana/overview/geocode", |
|||
type: "get", |
|||
data: params, |
|||
}); |
|||
}, |
|||
//获取今日收入和服务车辆
|
|||
GetDataStatic: (params) => { |
|||
return ajax({ |
|||
url: "/api/ana/overview/dataStatic", |
|||
type: "get", |
|||
data: params, |
|||
}); |
|||
}, |
|||
//获取收入分析
|
|||
GetRevenueAnalysis: (params) => { |
|||
return ajax({ |
|||
url: "/api/ana/overview/revenueAnalysis", |
|||
type: "get", |
|||
data: params, |
|||
}); |
|||
}, |
|||
//获取车场评价
|
|||
GetParkingEvaluate: (params) => { |
|||
return ajax({ |
|||
url: "/api/ana/overview/parkingEvaluate", |
|||
type: "get", |
|||
data: params, |
|||
}); |
|||
}, |
|||
//获取客诉类型分析
|
|||
GetComplaintType: (params) => { |
|||
return ajax({ |
|||
url: "/api/ana/overview/complaintType", |
|||
type: "get", |
|||
data: params, |
|||
}); |
|||
}, |
|||
//获取左边数据(不包括7日利用率和周转)
|
|||
GetOverviewData: (params) => { |
|||
return ajax({ |
|||
url: "/api/ana/overview/overviewData", |
|||
type: "get", |
|||
data: params, |
|||
}); |
|||
}, |
|||
//获取左边数据(7日利用率和周转)
|
|||
GetUseInfo: (params) => { |
|||
return ajax({ |
|||
url: "/api/ana/overview/berthUseInfo", |
|||
type: "get", |
|||
data: params, |
|||
}); |
|||
}, |
|||
}; |