From cca998b7f1449a289cf8ea4da6adc764b81a8325 Mon Sep 17 00:00:00 2001 From: chenqiang Date: Thu, 30 Nov 2023 11:02:55 +0800 Subject: [PATCH] =?UTF-8?q?feat():=20=E6=96=B0=E5=A2=9E=E5=88=86=E6=9E=90?= =?UTF-8?q?=E5=A4=A7=E5=B1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/images/equip/home/kx.png | Bin 0 -> 5486 bytes src/assets/images/equip/home/mark_green.png | Bin 0 -> 1726 bytes src/assets/images/equip/home/mark_red.png | Bin 0 -> 1719 bytes src/assets/images/equip/home/mark_yellow.png | Bin 0 -> 1717 bytes src/assets/images/equip/home/poto.png | Bin 0 -> 1229 bytes src/assets/images/equip/home/rerm.png | Bin 0 -> 1156 bytes src/assets/images/equip/home/yc.png | Bin 0 -> 16628 bytes src/components/MapComponets/BaseMap/index.jsx | 215 +-- src/components/MapComponets/MarkCenter/index.jsx | 47 + .../MapComponets/ParkingViewMarkers/index.jsx | 189 +++ .../MapComponets/ParkingViewMarkers/index.scss | 71 + src/components/MapComponets/index.jsx | 16 +- .../MemberStat/ParkingAly/index.scss | 7 +- .../MemberStat/ParkingAly/loadable.jsx | 157 +- .../MemberStat/PayAly/index.scss | 7 +- .../MemberStat/PayAly/loadable.jsx | 405 +++-- .../MemberStat/RegisterAly/loadable.jsx | 302 ++-- .../ParkingOverview/index.scss | 466 +++++- .../ParkingOverview/loadable.jsx | 1553 +++++++++++++++++++- src/services/ElectInvoice/index.js | 35 +- src/services/ParkingOverview/index.js | 100 ++ src/services/index.js | 2 + 22 files changed, 3000 insertions(+), 572 deletions(-) create mode 100644 src/assets/images/equip/home/kx.png create mode 100644 src/assets/images/equip/home/mark_green.png create mode 100644 src/assets/images/equip/home/mark_red.png create mode 100644 src/assets/images/equip/home/mark_yellow.png create mode 100644 src/assets/images/equip/home/poto.png create mode 100644 src/assets/images/equip/home/rerm.png create mode 100644 src/assets/images/equip/home/yc.png create mode 100644 src/components/MapComponets/MarkCenter/index.jsx create mode 100644 src/components/MapComponets/ParkingViewMarkers/index.jsx create mode 100644 src/components/MapComponets/ParkingViewMarkers/index.scss create mode 100644 src/services/ParkingOverview/index.js diff --git a/src/assets/images/equip/home/kx.png b/src/assets/images/equip/home/kx.png new file mode 100644 index 0000000000000000000000000000000000000000..1faea5943c59e4395dc48946d1f8e64f52c5550d GIT binary patch literal 5486 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 Y^oSyJALVVaa|3E&a@@Gu&?EYP04U6>EdT%j literal 0 HcmV?d00001 diff --git a/src/assets/images/equip/home/mark_green.png b/src/assets/images/equip/home/mark_green.png new file mode 100644 index 0000000000000000000000000000000000000000..e85fb681a65c3dc30055fa7e3d003d897e748204 GIT binary patch literal 1726 zcmaJ?eM}Q~7_O^Th66M%1R3hlq7iL-*8+uBsw=dGBCULMqk))F+JhF_Ug;gQu;Q?8 z14T3E2gpz`1;+$sAOb-gNYo&rL0NSIDj+eAAQOT4fgrmg;Qko9R=L^7UmwRDcOFArSHd8B7|3#esY|41Zwm zA>+{u%0x~SUpN;FUvbGQ4AXN!&}cN$jXre5kOVT=Y&HlnK_-)iBWP%b4wIW`I+QZ6 zz=u(VL9NHshz_tT$`g<@j7!FyzE44`Uy#+Ib7jH{2Abr0kU@v+Da`}L;{S(gwF_tz zi-JG+{ZC<3nxTimC>TZ33<~_<5-IjjdQPwbmSc!PiXfW#Dn_Uf3_(?h9$+%)Okh)t zTBk&esP`;EEar%GC??k_U=g27#wF-#wUPrt0m2}LUqApqNXTFa1Z)=Hm+$Kv;0Fb< z{UD~_JeQ9s(zLJ+o98M&aM_D;?Y*GY*y~>cf<0bTjk}EGy2lLd8zJ^@ zQ4w$T*A=5z0sT(Bhdb9*=LZH)ie zVQkPVsg({|SMyefc#p6GoU5A5Q_0mX)WJ5_y=ncW-Q9?-Et@WeKFM!#2z%>PRfEXl zexgr?v%BH|Li25&|9$5$c2+6R)r};)Y?RcU7~5gqncvAW<#^RB;_MMXlrOUB(#hKQ6V)CnsA*ZN_*wY&~jhwEot(h8i80JoF_;ahOYDk`c zvfna5O|4>X!^?^xHe@9hRF^!Zz_ej1b=y*L^5!&Z?a56VCrn%#&D%&Y5|0AMsm+;h~ zJNFW8$DU_%%1N5nO7Dxr1B(8FBK48r5>&YB4L!oT{V=~=>1uE*)D>lndtD{c4A;JU zR4u=B{ie=vi@r5*g{nYkE}PaIR}W1sEB&Fwv$~}1sd~RLvHIB;R+{EMAw4$t-uT(f zn!l-WcPCzsO|~oIUu8-jo;_Ohmyf9oDUPOoMm_O5a6d~m;3IDD^hZ;?WkFwAnsZJtb8^!a50=!vnPHS3O1K?VeSDkkuAAr>``b0A zo~VkU6xm>ESc7G}rzhv3q0CtucHXr92HMyq*i{y z8VwV;CK7*djmjyVkmL=2*`CfmLK`=K9~h2ioL}Bey&q8+=~eNBr`*c2$B7p`?0*!IK*FyIinsg&QFEzH literal 0 HcmV?d00001 diff --git a/src/assets/images/equip/home/mark_red.png b/src/assets/images/equip/home/mark_red.png new file mode 100644 index 0000000000000000000000000000000000000000..8e3a5c2ae05f1a37eadc82378342995f1c557463 GIT binary patch literal 1719 zcmaJ?X;2eq7!HbvT2ML`5X7!Y5vh=D0)}KI*n|*>Bpe}@ONEduWDCiryQ_o<)^ez= zFy4qz6c4C49kfXBDjHEy6o!ga1+>IEctSZ8FKq1w0sEtLXLi41p67X=_x;{)_PdC% zV7uuq(A2?zK`MpBTAWa5m9SXIqmmMI1W`dC--qqP^z-2e1tKOhD2VIF6mSJWT!E0u5r}*R zV_YGsT&;n%#28ogf$KXV*U}3b9T`~&W5^m3H9gi}B8fwPd?vWM6;UWa=ib%jaStU#{=?r7%83&Y#DB=(sV`&zK6*HXh3iM92@ z?j3FG>-Z9nY}cOh{4?g+C%c~wJ~i==Wiv{qve$<{XhuX?zUmtv(GttI?9cBqFX$^! z@2e;%-pi|-TyI`91u}(2nC`hwYdvoZTEF48VONg!b7Rj^?Ao>$zt&cGn5eU+hVq>{ zmB5Xp4Z-KdtziYb+je$rY`(Xvj&t!{dGY@ITlMsY2>%9ylhN9UOKvE=;?KJWdTHCj zbMg|Wam@X)VNS^uW1QWV+{#0_Lw`B)j@*YbZI77JepTK%E*(DV8!GqcZux4R4|iIz zx5UGFD8XEPoxOaxOVTSbxJzba44e)LNS-q^|6oSIygZE)2g z$Dy~$(QZ|F#z5Nj8_{V+i03-jx8@ly2QyA(?p^EelLMb%X%a6iIM!KT^L^^#kTg~M z;SDEBF1N&Jd-%616K3mLv#i3OH{yk`F)w6c8Dgx>vM>2L#RSa!oi)%WaC?yR+&LLC zMJ1GbzInY{V++T+JctU7SZngcHz6JkJaFT?eVCIh^90y*a0BF`T(u`K*R`gn*(cfV z>16xIYjlyrFC5OztqgMAPVC)?t*jbgUj1XutMx6pHQ~Pv-jWdF+O8Z=`{9RK{i0s4 zCYy?!Zu`*3IkiXQ-8+Mt@TQ^Ixrs%a@6bV*mgE literal 0 HcmV?d00001 diff --git a/src/assets/images/equip/home/mark_yellow.png b/src/assets/images/equip/home/mark_yellow.png new file mode 100644 index 0000000000000000000000000000000000000000..501c3f822183d575706e93c7ee67736a29f82e06 GIT binary patch literal 1717 zcmaJ?Yfuws6b+z2Q4nZ{R|j1;*kTIFZW1Di1PUaWSQ0Tt31~GTSxA6nW3qvS!Qm0a zf;to(Ut{GZl`2&M6{#SIiozh`3tCWHTNRK;!HN%NRJuW+{ZYCzyWeBZIrrTA-ETH8 zO1R3=!OMX_AUN`Q91%Wx<1f+P7XKE7#EF=Wg|FD462r7C3MDl)m7Gc=qq+nN%w#et5S2ou`r`v z`N!{n3hTutEkY3?deoqk;|CW{w1m>K!gYuYLv>;lO`fS@loG{Iy%N;|RG3T!e4|ww z1)8c~K1C1+SbU8hlWF7#pTh=m39?G1V8P75@PJSl4&;PIz%Z8^#^unNP#_bE2&0Ft zpoPzHIjG#AMl{$ASMd**Iw#lC3u-MMnSP>SMb9;g2 z!fG4@b zdLGgKa&Kb011XQ3BTnRSZg0;aJD*h{E)ukB<4b9I)P!qHYl`Vi7X=iSoQ)jZ*3;pC-ZZA#}2uWe)ZdnRsvH=5D+sw1Z%RwiH9oLJ?dFz1cG&N^M< zNzeQ_tFYDt5=+{wwf4!8W9h-|BYvkdk3N#sl(ca=v#BTFFQ#WDlpJW}OBYKVz_)>I z%&Plb%)0K{=GFC%!ptG7B~7-&cI^|@CaL!uDZ|NA&vL-b&`?Xs=DHp?ZQf)^*0V>e zYM2+f%@pZ;rQOOet#+V3JUikg!2D9zIy6z_S8R^Bwg-Ok@yl_KKtd3-0J}4}KoL7W zwlYvy{xsWNWNtK{s8A(4mzJCr38H$xYL|I;EGnq}wM~*;O*~QR%D!CVxCzQOMZEKo z*zeEW7QE!#j>;Hl!{JichqPR_?KHQ*t8US#IT1R%vvX7AJ#v(j;q?WxwJex@S4~?}RF{6~uL9S!@autaP<Yv?<0Ra zr{(57G!)y$Sh+t;7~^dTs)*^9%=?I$->rN`)3g*>+XNZguQt&P2Ny*Vg=dQ^8ZR6h z=-*Q7;@d8QimT_zUoR-W=y_MTYo*j_G9=zjlzztfhJ2xcer?ag!u&%e2wF7OUDdsn zcRo8-{pZdO+jzIcu3VoZ{iP2MR9ffM9CR9ee&k!m`jesVGz4u{6u&jOH;4{xKcA(N z9_rkXR`JwO*`DG;+1U4f7i*z@ZJAx(p7i>ZCVtCm&ntYf78aKSlIBz{sqBuEnPk^Y zY9!_oPn;^)=Qct*mo!|({eGW*a@qaEPiwCf_Cc6I>N0RE-Fv+2r^vM2$DoPOmrd(! k>Fo(C>d%{0XUz8?kbO@+{;hEEpyfxx=L$Ke!lc=M1LuUFNB{r; literal 0 HcmV?d00001 diff --git a/src/assets/images/equip/home/poto.png b/src/assets/images/equip/home/poto.png new file mode 100644 index 0000000000000000000000000000000000000000..5ca4063659356f2983a6ecc002915b1d84846ba8 GIT binary patch literal 1229 zcmeAS@N?(olHy`uVBq!ia0vp^LO?9Q!3HFy+4N(8lw^r(L`iUdT1k0gQ7VIDN`6wR zf@f}GdTLN=VoGJ<$y6H#24>~Vkcg59UmvUF{9L_6kQ%*;+ybC(1_m4Zih{)C?9>v4 zq}24xJX@vryZ0+8WTx0Eg`4^s_!c;)W@LI)6{QAO`Gq7`WhYyvDB0U7*i={n4aiL` zNmQuF&B-gas<2f8n`;GRgM{^!6u?SKvTcwn^Gtf;oFfdXux70H< zGchqU&`~flFf!0LFx59S(ls=*GBB|+G*^HEC7^9ZDQQ+gE^bh}fIM5JjFOT9D}DX) z@^Za$W4-*MbbUihOG|wNBYh(yU7!lx;>x^|#0uTKVr7^KE~&-IMVSR9nfZANAQKal z@=Hr>m4GgVcp>!tmQH53(wdYzwXa3?&DhCi|CAY@>9@BrK5Uj*Iua&mmIm+a|Eyneyvh zL1%SOf`8hS@C8D-JiAu3h$OGe2(< zUpC8>Eppnno@|?tU+Npv_%0n=S}9bbR4sJsS)PPnxuD3eX{tYp!e+(FoZI(Dm~+nm v@G13Mv`xwk)c$*1dwP1E&SznEdnO)+$kT}zZwT5R1r;!!u6{1-oD!M|6H_V+Po~;1Ffc1;hD4M^`1)8S=jZArg4F0$^BXQ!4Z zB&DWj=GiK}-@RW+Av48RDcsc8z_-9TH6zobswg$M$}c3jDm&RSMakYy!KT6rXh3di zNuokUZcbjYRfVk**jy_h8zii+qySb@l5ML5aa4qFfP!;=QL2KOo`G(%fq{{Nxuu?= znTd&+fsTTafsui}fvLWsk*=Ycm4S(sp}7JSC;@FNN=dT{a&d#&1?1T(Wt5Z@Sn2DR zmzV368|&p4rRy77T3YHG80i}s=>k>g7FXt#Bv$C=6)VF`a7isrF3Kz@$;{7F0GXJW zlwVq6s|0i@#0$9vaAWg|p}_t}jquF8 zl>G8yO|S-EUn|eN;*!L?w0pQ+GRV1Co5uZ~@<6GZN(9$@*t(1hFLqo_)!j7h6dKzieW>U3;Ujy8aN`e)kPCcW6Ax-DtZQYx%PG*#XwJd#XuZz~N9Ix{s}&75 zPqnBqc5USM_@nD^hx73Q?K<`&iUHsJGprh!#dNN{V|~QwP$Sl1uk6jhBEhgNOwap> Sx$p^4x!~#Q=d#Wzp$P!gI(F3n literal 0 HcmV?d00001 diff --git a/src/assets/images/equip/home/yc.png b/src/assets/images/equip/home/yc.png new file mode 100644 index 0000000000000000000000000000000000000000..c52be4ac0365dbf4283185b91c2f2a3e83182dcb GIT binary patch literal 16628 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 D&`n9h literal 0 HcmV?d00001 diff --git a/src/components/MapComponets/BaseMap/index.jsx b/src/components/MapComponets/BaseMap/index.jsx index 608cd29..f2d3153 100644 --- a/src/components/MapComponets/BaseMap/index.jsx +++ b/src/components/MapComponets/BaseMap/index.jsx @@ -1,21 +1,21 @@ -import React, { useState, useEffect, useRef } from "react" -import L from "leaflet" -import "leaflet/dist/leaflet.css" -import "../js/BoundaryCanvas.js" -import "leaflet.chinatmsproviders" -import "./index.scss" -import { useSelector } from "react-redux" -const isDevelopment = process.env.NODE_ENV === "development" +import React, { useState, useEffect, useRef } from "react"; +import L from "leaflet"; +import "leaflet/dist/leaflet.css"; +import "../js/BoundaryCanvas.js"; +import "leaflet.chinatmsproviders"; +import "./index.scss"; +import { useSelector } from "react-redux"; +const isDevelopment = process.env.NODE_ENV === "development"; function BaseMap(props) { - const skin = useSelector((state) => state.common.skin) + const skin = useSelector((state) => state.common.skin); const { id = "map", scrollZoom = true, zoom, // 地图初始化缩放等级 backgroundImg, // 地图背景图片 - onClick - } = props + onClick = () => {}, + } = props; const mapConfig = { center: sysConfig.map.center, @@ -26,134 +26,151 @@ function BaseMap(props) { mapTileHost: sysConfig.map.mapTileHost, zoomOffset: sysConfig.map.zoomOffset, mapTileType: sysConfig.map.mapTileType, - } - console.log( sysConfig.map); - let mapTileType = mapConfig.mapTileType - let mapLayer = {} - if (mapTileType === 'pgis') { - mapLayer = new L.TileLayer('{mapTileHost}/Maps/{mapName}/EzMap?Service=getImage&Type=RGB&ZoomOffset=0&Col={x}&Row={y}&Zoom={z}&V=1.0.0', { - minZoom: mapConfig.zooms[0], - maxZoom: mapConfig.zooms[1], - subdomains: [0, 1, 2], - tileSize: 256, - zoomOffset: mapConfig.zoomOffset, - dragging: true, - mapTileHost:mapConfig.mapTileHost, - mapName: mapConfig.mapName - }) - } else if (mapTileType === 'custom') { - mapLayer = new L.TileLayer('{mapTileHost}/tmap-tile/{z}/{x}/{y}.png', { - maxZoom: mapConfig.zooms[1], - minZoom: mapConfig.zooms[0], - mapTileHost:mapConfig.mapTileHost, - }) - } else if (mapTileType === 'test') { - mapLayer = new L.TileLayer('http://www.sdmap.gov.cn/tileservice/SDPubMap?layer=sdvec&style=default&tilematrixset=c&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image%2Fpng&TileMatrix={z}&TileCol={x}&TileRow={y}', { - minZoom: mapConfig.zooms[0], - maxZoom: mapConfig.zooms[1], - subdomains: [0, 1, 2], - tileSize: 256, - zoomOffset: mapConfig.zoomOffset, - dragging: true, - mapTileHost:mapConfig.mapTileHost, - mapName: mapConfig.mapName - }) - - } else if (mapTileType === 'tianditu') { - mapLayer = new L.TileLayer('{mapTileHost}&layer=vec&style=default&tilematrixset=c&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&TileMatrix={z}&TileCol={x}&TileRow={y}', { - minZoom: mapConfig.zooms[0], + }; + console.log(sysConfig.map); + let mapTileType = mapConfig.mapTileType; + let mapLayer = {}; + if (mapTileType === "pgis") { + mapLayer = new L.TileLayer( + "{mapTileHost}/Maps/{mapName}/EzMap?Service=getImage&Type=RGB&ZoomOffset=0&Col={x}&Row={y}&Zoom={z}&V=1.0.0", + { + minZoom: mapConfig.zooms[0], + maxZoom: mapConfig.zooms[1], + subdomains: [0, 1, 2], + tileSize: 256, + zoomOffset: mapConfig.zoomOffset, + dragging: true, + mapTileHost: mapConfig.mapTileHost, + mapName: mapConfig.mapName, + } + ); + } else if (mapTileType === "custom") { + mapLayer = new L.TileLayer("{mapTileHost}/tmap-tile/{z}/{x}/{y}.png", { maxZoom: mapConfig.zooms[1], - subdomains: [0, 1, 2], - tileSize: 256, - zoomOffset: mapConfig.zoomOffset, - dragging: true, - mapTileHost:mapConfig.mapTileHost, - mapName: mapConfig.mapName - }) - textLayer = new L.TileLayer('http://t0.tianditu.gov.cn/cva_w/wmts?layer=cva&style=default&tilematrixset=c&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&TileMatrix={z}&TileCol={x}&TileRow={y}&tk=e5e59e67c525c4879d9af763ac00aace', { minZoom: mapConfig.zooms[0], - maxZoom: mapConfig.zooms[1], - subdomains: [0, 1, 2], - tileSize: 256, - zoomOffset: mapConfig.zoomOffset, - dragging: true, - mapTileHost: 'http://t0.tianditu.gov.cn/cva_w/wmts?tk=e5e59e67c525c4879d9af763ac00aace', - mapName: mapConfig.mapName - }) + mapTileHost: mapConfig.mapTileHost, + }); + } else if (mapTileType === "test") { + mapLayer = new L.TileLayer( + "http://www.sdmap.gov.cn/tileservice/SDPubMap?layer=sdvec&style=default&tilematrixset=c&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image%2Fpng&TileMatrix={z}&TileCol={x}&TileRow={y}", + { + minZoom: mapConfig.zooms[0], + maxZoom: mapConfig.zooms[1], + subdomains: [0, 1, 2], + tileSize: 256, + zoomOffset: mapConfig.zoomOffset, + dragging: true, + mapTileHost: mapConfig.mapTileHost, + mapName: mapConfig.mapName, + } + ); + } else if (mapTileType === "tianditu") { + mapLayer = new L.TileLayer( + "{mapTileHost}&layer=vec&style=default&tilematrixset=c&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&TileMatrix={z}&TileCol={x}&TileRow={y}", + { + minZoom: mapConfig.zooms[0], + maxZoom: mapConfig.zooms[1], + subdomains: [0, 1, 2], + tileSize: 256, + zoomOffset: mapConfig.zoomOffset, + dragging: true, + mapTileHost: mapConfig.mapTileHost, + mapName: mapConfig.mapName, + } + ); + textLayer = new L.TileLayer( + "http://t0.tianditu.gov.cn/cva_w/wmts?layer=cva&style=default&tilematrixset=c&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&TileMatrix={z}&TileCol={x}&TileRow={y}&tk=e5e59e67c525c4879d9af763ac00aace", + { + minZoom: mapConfig.zooms[0], + maxZoom: mapConfig.zooms[1], + subdomains: [0, 1, 2], + tileSize: 256, + zoomOffset: mapConfig.zoomOffset, + dragging: true, + mapTileHost: + "http://t0.tianditu.gov.cn/cva_w/wmts?tk=e5e59e67c525c4879d9af763ac00aace", + mapName: mapConfig.mapName, + } + ); } else { - mapLayer = L.tileLayer('{mapTileHost}/v3/tile?z={z}&x={x}&y={y}', { + mapLayer = L.tileLayer("{mapTileHost}/v3/tile?z={z}&x={x}&y={y}", { maxZoom: mapConfig.zooms[1], minZoom: mapConfig.zooms[0], - zoomOffset: mapConfig.zoomOffset || 0, - mapTileHost: mapConfig.mapTileHost - }) + zoomOffset: mapConfig.zoomOffset || 0, + mapTileHost: mapConfig.mapTileHost, + }); } - const [map, setMap] = useState(null) - const mapRef = useRef(map) - mapRef.current = map - const [hasInit, setHasInit] = useState(false) // 地图是否已经创建 + const [map, setMap] = useState(null); + const mapRef = useRef(map); + mapRef.current = map; + const [hasInit, setHasInit] = useState(false); // 地图是否已经创建 // const [mapLayer, setMapLayer] = useState(null) const initMap = () => { let _map = L.map(id, { attributionControl: false, zoomControl: false, - crs:L.CRS.EPSG3857, - }).setView([mapConfig.center[0], mapConfig.center[1]], zoom ? zoom : mapConfig.zoom) - setMap(_map) - _map.on('click', function(info) { - onClick(info) - }) - mapLayer.addTo(_map) + crs: L.CRS.EPSG3857, + }).setView( + [mapConfig.center[0], mapConfig.center[1]], + zoom ? zoom : mapConfig.zoom + ); + setMap(_map); + if (onClick) { + _map.on("click", function (info) { + onClick(info); + }); + } + + mapLayer.addTo(_map); // setMapLayer(mapLayer) - mapRef.current = map - setHasInit(true) - } + mapRef.current = map; + setHasInit(true); + }; const renderChildren = (map) => { return React.Children.map(props.children, (child) => { if (child) { - const cType = child.type + const cType = child.type; /* 针对下面两种组件不注入地图相关属性 * 1. 明确声明不需要注入的 * 2. DOM 元素 */ if (cType.preventAmap || typeof cType === "string") { - return child + return child; } return React.cloneElement(child, { __map__: map, - }) + }); } - return child - }) - } + return child; + }); + }; useEffect(() => { - initMap() - + initMap(); return () => { - mapRef.current.remove() - } - }, []) + mapRef.current.remove(); + }; + }, []); useEffect(() => { - if(hasInit) { + if (hasInit) { // changeMap(skin) } - }, [skin]) + }, [skin]); useEffect(() => { if (map) { if (scrollZoom) { - map.scrollWheelZoom.enable() + map.scrollWheelZoom.enable(); } else { - map.scrollWheelZoom.disable() + map.scrollWheelZoom.disable(); } } - }, [scrollZoom]) + }, [scrollZoom]); return (

{hasInit ? renderChildren(map) : null}
- ) + ); } -export default BaseMap +export default BaseMap; diff --git a/src/components/MapComponets/MarkCenter/index.jsx b/src/components/MapComponets/MarkCenter/index.jsx new file mode 100644 index 0000000..c734569 --- /dev/null +++ b/src/components/MapComponets/MarkCenter/index.jsx @@ -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(`${data.name}`, { + offset: [20, -5], + direction: "right", + }); + setMarker(marker); + setTimeout(() => { + map.setView([data.lat, data.lng]); + }, 800); + }; + + return null; +} + +export default Markers; diff --git a/src/components/MapComponets/ParkingViewMarkers/index.jsx b/src/components/MapComponets/ParkingViewMarkers/index.jsx new file mode 100644 index 0000000..b41489c --- /dev/null +++ b/src/components/MapComponets/ParkingViewMarkers/index.jsx @@ -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(`${elem[tooltipKey]}`, { + 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 = `
+
请选择点位
+
+ `; + data.forEach((elem) => { + let _data = elem.data.data; + if (_data.name && _data.locationId) { + template += `
${_data.name}
`; + } + }); + template += `
`; + return template; + }; + + return null; +} + +export default Markers; diff --git a/src/components/MapComponets/ParkingViewMarkers/index.scss b/src/components/MapComponets/ParkingViewMarkers/index.scss new file mode 100644 index 0000000..44b8500 --- /dev/null +++ b/src/components/MapComponets/ParkingViewMarkers/index.scss @@ -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; +} diff --git a/src/components/MapComponets/index.jsx b/src/components/MapComponets/index.jsx index 5b5f195..0b42135 100644 --- a/src/components/MapComponets/index.jsx +++ b/src/components/MapComponets/index.jsx @@ -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, +}; diff --git a/src/pages/DataAnalysisPrediction/MemberStat/ParkingAly/index.scss b/src/pages/DataAnalysisPrediction/MemberStat/ParkingAly/index.scss index 8d3ecb8..6af9af0 100644 --- a/src/pages/DataAnalysisPrediction/MemberStat/ParkingAly/index.scss +++ b/src/pages/DataAnalysisPrediction/MemberStat/ParkingAly/index.scss @@ -404,6 +404,9 @@ $color-primary : var(--color-primary); background: var(--color-user-list-bg); box-shadow: 0px 3px 8px 0px rgba(0, 0, 0, 0.12); border-radius: 28px 0 0 0; + overflow-y: scroll; + // position: relative; + @include scrollBar(var(--color-user-list-bg), #3B97FF); .result-box { color: #ffffff; @@ -475,9 +478,7 @@ $color-primary : var(--color-primary); .scrplltab { width: 100%; - overflow-x: scroll; - // position: relative; - @include scrollBar(var(--color-user-list-bg), #3B97FF); + .poxi { cursor: pointer; diff --git a/src/pages/DataAnalysisPrediction/MemberStat/ParkingAly/loadable.jsx b/src/pages/DataAnalysisPrediction/MemberStat/ParkingAly/loadable.jsx index 188a192..841b72f 100644 --- a/src/pages/DataAnalysisPrediction/MemberStat/ParkingAly/loadable.jsx +++ b/src/pages/DataAnalysisPrediction/MemberStat/ParkingAly/loadable.jsx @@ -26,13 +26,10 @@ function ParkingAly() { //页面检索-重复 const formdata = { operator_id: "0", //商户 - park_type: "", //车场类型 1=路内 2=路外 + data_source: "", //车场类型 1=路内 2=路外 date_type: "1", - is_excel: 0, - start_time: moment().startOf("day").format("YYYY-MM-DD"), - end_time: moment().endOf("day").format("YYYY-MM-DD"), - pn: 1, - page_size: dictionary?.pageSizeOptions1[0], + start_date: moment().startOf("day").format("YYYY-MM-DD"), + end_date: moment().endOf("day").format("YYYY-MM-DD"), }; const col = [ { @@ -43,20 +40,20 @@ function ParkingAly() { }, { title: "会员停车次数(次)", - dataIndex: "date", - key: "date", + dataIndex: "member_count", + key: "member_count", align: "center", }, { title: "非会员停车次数(次)", - dataIndex: "date", - key: "date", + dataIndex: "un_member_count", + key: "un_member_count", align: "center", }, { title: "会员停车占比", - dataIndex: "date", - key: "date", + dataIndex: "ratio", + key: "ratio", align: "center", }, ]; @@ -159,11 +156,29 @@ function ParkingAly() { setFormData({ ...FormData, date_type: e, - start_time: start, - end_time: end, + start_date: start, + end_date: end, }); }; - + //数据上传 + const DateFormt = (e) => { + let start = ""; + let end = ""; + if (e == 4) { + start = moment(FormData.start_date).startOf("year").format("YYYY-MM-DD"); + end = moment(FormData.end_date).endOf("year").format("YYYY-MM-DD"); + } else if (e == 3) { + start = moment(FormData.start_date).startOf("month").format("YYYY-MM-DD"); + end = moment(FormData.end_date).endOf("month").format("YYYY-MM-DD"); + } else { + start = FormData.start_date; + end = FormData.end_date; + } + return { + start_date: start, + end_date: end, + }; + }; //页码 function onShowSizeChange(pn, page_size) { let temFormData = {}; @@ -228,54 +243,17 @@ function ParkingAly() { } ); }; - const filterad = (dates, data, name) => { - const areaData = data.filter((item) => item.type === name); - const arr = dates.map((item) => { - for (const { pay_date, income } of areaData) { - console.log(pay_date, income); - if (pay_date === item) return income; - } - return 0; - }); - return arr; - }; const getRevenueOption = ( data = [ { - income: 4, - // area: "1", - pay_date: "2023-08-21", - type: "非会员停车次数", - }, - { - income: 14, - // area: "1", - pay_date: "2023-08-21", - type: "会员停车次数", - }, - { - income: 12, - // area: "2", - pay_date: "2023-08-19", - type: "会员停车次数", - }, - { - income: 40, - // area: "1", - pay_date: "2023-08-25", - type: "非会员停车次数", + date: moment().startOf("day").format("YYYY-MM-DD"), + member_count: 0, + un_member_count: 0, }, ] ) => { - // 获取所有地区名称 - data.sort((a, b) => { - return new Date(a.pay_date) - new Date(b.pay_date); - }); - const areaNames = [...new Set(data.map((item) => item.type))]; // 获取所有日期 - const dates = [...new Set(data.map((item) => item.pay_date))].sort( - (a, b) => a.pay_date - b.pay_date - ); + const dates = [...new Set(data.map((item) => item.date))]; // 构建X轴数据 const xAxisData = dates.map((date) => { return { @@ -320,7 +298,7 @@ function ParkingAly() { type: "scroll", top: 0, left: "center", - data: areaNames, + data: ["非会员停车次数", "会员停车次数"], itemWidth: 18, itemHeight: 12, width: "40%", @@ -373,12 +351,12 @@ function ParkingAly() { { name: "非会员停车次数", type: "line", - data: filterad(dates, data, "非会员停车次数"), + data: data.map((ele) => ele.un_member_count), }, { name: "会员停车次数", type: "line", - data: filterad(dates, data, "会员停车次数"), + data: data.map((ele) => ele.member_count), }, ], grid: { @@ -392,16 +370,17 @@ function ParkingAly() { //获取页面显示数据 const getData = (data) => { setLoading(false); - ajax.ElectInvoice.getOperationReport({ + ajax.ElectInvoice.getParking({ ...data, - area: data?.area?.length ? data?.area[data.area.length - 1] : "", + ...DateFormt(data.date_type), }).then( (res) => { if (parseInt(res?.status) === 20000) { setData({ - data: res?.data?.list || [], - total: res?.total || 0, + data: res?.data || [], + total: res?.data.length || 0, }); + getRevenueOption(res?.data); setLoading(true); } else { message.error(res?.message); @@ -416,7 +395,7 @@ function ParkingAly() { }; useEffect(() => { sessionStorage.setItem("FormData_ParkingAly", JSON.stringify(FormDatas)); - // getData(FormDatas); + getData(FormDatas); //调用接口 }, [FormDatas]); useEffect(() => { @@ -453,7 +432,7 @@ function ParkingAly() { 车场类型
setFormData({ ...FormData, - park_type: e, + data_source: e, }) } /> @@ -707,10 +772,6 @@ function PayAly() { value: "3", label: "月", }, - { - value: "4", - label: "年", - }, ]} onChange={(e) => SetTimeNow(e)} /> @@ -723,33 +784,33 @@ function PayAly() { format={TimeChange().mat} picker={TimeChange().str} allowClear={false} - value={FormData.start_time ? moment(FormData.start_time) : null} + value={FormData.start_date ? moment(FormData.start_date) : null} onChange={(date, dateString) => { if (TimeChange().str == "week") { setFormData({ ...FormData, - start_time: date + start_date: date ? moment(date).day(1).format("YYYY-MM-DD") : null, }); } else if (TimeChange().str == "day") { - if (date > moment(FormData.end_time)) { + if (date > moment(FormData.end_date)) { setFormData({ ...FormData, - end_time: dateString, - start_time: FormData.end_time, + end_date: dateString, + start_date: FormData.end_date, }); } else { setFormData({ ...FormData, - start_time: dateString, + start_date: dateString, }); } } else { - setFormData({ ...FormData, start_time: dateString }); + setFormData({ ...FormData, start_date: dateString }); } }} - disabledDate={(current) => current > moment(FormData.end_time)} + disabledDate={(current) => current > moment(FormData.end_date)} />
@@ -762,34 +823,34 @@ function PayAly() { format={TimeChange().mat} picker={TimeChange().str} allowClear={false} - value={FormData.end_time ? moment(FormData.end_time) : null} + value={FormData.end_date ? moment(FormData.end_date) : null} onChange={(date, dateString) => { if (TimeChange().str == "week") { setFormData({ ...FormData, - end_time: date + end_date: date ? moment(date).day(7).format("YYYY-MM-DD") : null, }); } else if (TimeChange().str == "day") { - if (date < moment(FormData.start_time)) { + if (date < moment(FormData.start_date)) { setFormData({ ...FormData, - start_time: dateString, - end_time: FormData.start_time, + start_date: dateString, + end_date: FormData.start_date, }); } else { setFormData({ ...FormData, - end_time: dateString, + end_date: dateString, }); } } else { - setFormData({ ...FormData, end_time: dateString }); + setFormData({ ...FormData, end_date: dateString }); } }} disabledDate={(current) => - current < moment(FormData.start_time) + current < moment(FormData.start_date) } /> @@ -811,11 +872,9 @@ function PayAly() { var fortm = FormData; setFormData({ ...fortm, - pn: 1, }); setFormDatas({ ...fortm, - pn: 1, }); }} > @@ -841,7 +900,25 @@ function PayAly() { -
全部|订单
+
+ { + setVipo("1"); + getRingOption(Data.list, "1", Vipt); + }} + > + 金额 + + | + { + setVipo("2"); + getRingOption(Data.list, "2", Vipt); + }} + > + 订单 + +
-
全部|订单
+
+ { + setVipt("1"); + getRingOption(Data.list, Vipo, "1"); + }} + > + 金额 + + | + { + setVipt("2"); + getRingOption(Data.list, Vipo, "2"); + }} + > + 订单 + +
- + {/*
-
+ */} diff --git a/src/pages/DataAnalysisPrediction/MemberStat/RegisterAly/loadable.jsx b/src/pages/DataAnalysisPrediction/MemberStat/RegisterAly/loadable.jsx index 868aa73..a7641f7 100644 --- a/src/pages/DataAnalysisPrediction/MemberStat/RegisterAly/loadable.jsx +++ b/src/pages/DataAnalysisPrediction/MemberStat/RegisterAly/loadable.jsx @@ -23,11 +23,8 @@ import "./index.scss"; function RegisterAly() { const formdata = { date_type: "1", - is_excel: 0, - start_time: moment().startOf("day").format("YYYY-MM-DD"), - end_time: moment().endOf("day").format("YYYY-MM-DD"), - pn: 1, - page_size: dictionary?.pageSizeOptions1[0], + start_date: moment().startOf("day").format("YYYY-MM-DD"), + end_date: moment().endOf("day").format("YYYY-MM-DD"), }; const col = [ { @@ -38,43 +35,26 @@ function RegisterAly() { }, { title: "会员注册(个)", - children: [ - { - title: "APP", - dataIndex: "date", - key: "date", - align: "center", - }, - { - title: "公众号", - dataIndex: "date", - key: "date", - align: "center", - }, - { - title: "其他", - dataIndex: "date", - key: "date", - align: "center", - }, - ], + dataIndex: "user_count", + key: "user_count", + align: "center", }, { title: "车牌绑定(个)", - dataIndex: "date", - key: "date", + dataIndex: "car_count", + key: "car_count", align: "center", }, { title: "累计会员注册(个)", - dataIndex: "date", - key: "date", + dataIndex: "all_user_count", + key: "all_user_count", align: "center", }, { title: "累计车牌绑定(个)", - dataIndex: "date", - key: "date", + dataIndex: "all_car_count", + key: "all_car_count", align: "center", }, ]; @@ -93,14 +73,19 @@ function RegisterAly() { const [Data, setData] = useState({ data: [], total: 0, + list: { + binding_count: "", + user_count: "", + car_count: "", + unbinding_car_count: "", + unbinding_user_count: "", + }, }); const [ringData, setRingData] = useState({}); const [lingData, setLingData] = useState({}); const [revenueData, setRevenueData] = useState({}); - //获取区域 - const [Area, setArea] = useState([]); //商户 const [Yunying, setYunying] = useState([]); //自动填充 @@ -174,11 +159,29 @@ function RegisterAly() { setFormData({ ...FormData, date_type: e, - start_time: start, - end_time: end, + start_date: start, + end_date: end, }); }; - + //数据上传 + const DateFormt = (e) => { + let start = ""; + let end = ""; + if (e == 4) { + start = moment(FormData.start_date).startOf("year").format("YYYY-MM-DD"); + end = moment(FormData.end_date).endOf("year").format("YYYY-MM-DD"); + } else if (e == 3) { + start = moment(FormData.start_date).startOf("month").format("YYYY-MM-DD"); + end = moment(FormData.end_date).endOf("month").format("YYYY-MM-DD"); + } else { + start = FormData.start_date; + end = FormData.end_date; + } + return { + start_date: start, + end_date: end, + }; + }; //页码 function onShowSizeChange(pn, page_size) { let temFormData = {}; @@ -243,73 +246,58 @@ function RegisterAly() { } ); }; - const filterad = (dates, data, name) => { - const areaData = data.filter((item) => item.type === name); - const arr = dates.map((item) => { - for (const { pay_date, income } of areaData) { - console.log(pay_date, income); - if (pay_date === item) return income; - } - return 0; + const FilterLine = (data, dates, str) => { + let aee = []; + dates.forEach((ele) => { + data.forEach((val) => { + if (ele == val.date) { + aee.push(val[str] || 0); + } + }); }); - return arr; + return aee; }; + const getRingOption = ( - data = [ - { - income: 60, - // area: "1", - qu: 60, - pay_date: "2023-08-21", - type: "绑定车牌数", - }, - { - income: 40, - qu: 40, - // area: "1", - pay_date: "2023-08-25", - type: "未绑定车牌数", - }, - ], - datas = [ - { - income: 60, - // area: "1", - qu: 60, - pay_date: "2023-08-21", - type: "绑定车牌会员数", - }, - { - income: 40, - qu: 40, - // area: "1", - pay_date: "2023-08-25", - type: "非绑定车牌会员数", - }, - ] + data = { + binding_count: "0", + user_count: "0", + car_count: "0", + unbinding_car_count: "0", + unbinding_user_count: "0", + } ) => { // 获取所有地区名称 const arrleft = - data.map((ele) => { - return { - name: ele.type, - value: ele.income, - qu: ele.qu, - }; - }) || []; + [ + { + name: "绑定车牌数", + value: data.binding_count, + }, + { + name: "未绑定车牌数", + value: data.unbinding_car_count, + }, + ] || []; const arrRight = - datas.map((ele) => { - return { - name: ele.type, - value: ele.income, - qu: ele.qu, - }; - }) || []; + [ + { + name: "绑定车牌会员数", + value: data.binding_count, + }, + { + name: "非绑定车牌会员数", + value: data.unbinding_user_count, + }, + ] || []; setLingData({ title: { - text: "", + text: "已知车辆数量:" + data.car_count + "辆", + x: "center", + y: "bottom", textStyle: { color: "#fff", + fontSize: 14, }, }, tooltip: { @@ -328,8 +316,9 @@ function RegisterAly() { legend: { type: "scroll", //right: "5%", - top: "bottom", - bottom: "center", + x: "right", + y: "center", + orient: "vertical", //data: areaNames, data: ["绑定车牌数", "未绑定车牌数"], itemWidth: 18, @@ -377,9 +366,12 @@ function RegisterAly() { }); setRingData({ title: { - text: "", + text: "注册用户总数:" + data.user_count + "个", + x: "center", + y: "bottom", textStyle: { color: "#fff", + fontSize: 14, }, }, tooltip: { @@ -398,8 +390,9 @@ function RegisterAly() { legend: { type: "scroll", //right: "5%", - top: "bottom", - bottom: "center", + x: "right", + y: "center", + orient: "vertical", //data: areaNames, data: ["绑定车牌会员数", "非绑定车牌会员数"], itemWidth: 18, @@ -448,39 +441,21 @@ function RegisterAly() { const getRevenueOption = ( data = [ { - income: 4, - // area: "1", - pay_date: "2023-08-21", - type: "会员注册", - }, - { - income: 14, - // area: "1", - pay_date: "2023-08-21", - type: "车牌绑定", - }, - { - income: 12, - // area: "2", - pay_date: "2023-08-19", - type: "会员注册", - }, - { - income: 40, - // area: "1", - pay_date: "2023-08-25", - type: "车牌绑定", + date: moment().startOf("day").format("YYYY-MM-DD"), + user_count: "0", + car_count: "0", + all_user_count: 0, + all_car_count: 0, }, ] ) => { // 获取所有地区名称 data.sort((a, b) => { - return new Date(a.pay_date) - new Date(b.pay_date); + return new Date(a.date) - new Date(b.date); }); - const areaNames = [...new Set(data.map((item) => item.type))]; // 获取所有日期 - const dates = [...new Set(data.map((item) => item.pay_date))].sort( - (a, b) => a.pay_date - b.pay_date + const dates = [...new Set(data.map((item) => item.date))].sort( + (a, b) => a.date - b.date ); // 构建X轴数据 const xAxisData = dates.map((date) => { @@ -521,7 +496,7 @@ function RegisterAly() { type: "scroll", top: 0, left: "center", - data: areaNames, + data: ["会员注册", "车牌绑定"], itemWidth: 18, itemHeight: 12, width: "40%", @@ -548,10 +523,9 @@ function RegisterAly() { yAxis: { type: "value", name: "数量(个)", - min: 0, // /max: 50, - interval: 10, - splitNumber: 6, //设置坐标轴的分割段数 + // interval: 10,// min: 0, + axisLabel: { //formatter: "{value}元", textStyle: { @@ -574,12 +548,12 @@ function RegisterAly() { { name: "会员注册", type: "line", - data: filterad(dates, data, "会员注册"), + data: FilterLine(data, dates, "user_count"), }, { name: "车牌绑定", type: "line", - data: filterad(dates, data, "车牌绑定"), + data: FilterLine(data, dates, "car_count"), }, ], grid: { @@ -593,15 +567,30 @@ function RegisterAly() { //获取页面显示数据 const getData = (data) => { setLoading(false); - ajax.ElectInvoice.getOperationReport({ + ajax.ElectInvoice.getRegister({ ...data, - area: data?.area?.length ? data?.area[data.area.length - 1] : "", + ...DateFormt(data.date_type), }).then( (res) => { if (parseInt(res?.status) === 20000) { setData({ - data: res?.data?.list || [], - total: res?.total || 0, + data: res?.data || [], + total: res?.data?.length || 0, + list: { + binding_count: res.binding_count, + user_count: res.user_count, + car_count: res.car_count, + unbinding_car_count: res.unbinding_car_count, + unbinding_user_count: res.unbinding_user_count, + }, + }); + getRevenueOption(res?.data); + getRingOption({ + binding_count: res.binding_count, + user_count: res.user_count, + car_count: res.car_count, + unbinding_car_count: res.unbinding_car_count, + unbinding_user_count: res.unbinding_user_count, }); setLoading(true); } else { @@ -617,13 +606,12 @@ function RegisterAly() { }; useEffect(() => { sessionStorage.setItem("FormData_RegisterAly", JSON.stringify(FormDatas)); - // getData(FormDatas); + getData(FormDatas); //调用接口 }, [FormDatas]); useEffect(() => { getSelectData(); - getRevenueOption(); - getRingOption(); + // getRingOption(); }, []); return (
@@ -653,10 +641,6 @@ function RegisterAly() { value: "3", label: "月", }, - { - value: "4", - label: "年", - }, ]} onChange={(e) => SetTimeNow(e)} /> @@ -669,33 +653,33 @@ function RegisterAly() { format={TimeChange().mat} picker={TimeChange().str} allowClear={false} - value={FormData.start_time ? moment(FormData.start_time) : null} + value={FormData.start_date ? moment(FormData.start_date) : null} onChange={(date, dateString) => { if (TimeChange().str == "week") { setFormData({ ...FormData, - start_time: date + start_date: date ? moment(date).day(1).format("YYYY-MM-DD") : null, }); } else if (TimeChange().str == "day") { - if (date > moment(FormData.end_time)) { + if (date > moment(FormData.end_date)) { setFormData({ ...FormData, - end_time: dateString, - start_time: FormData.end_time, + end_date: dateString, + start_date: FormData.end_date, }); } else { setFormData({ ...FormData, - start_time: dateString, + start_date: dateString, }); } } else { - setFormData({ ...FormData, start_time: dateString }); + setFormData({ ...FormData, start_date: dateString }); } }} - disabledDate={(current) => current > moment(FormData.end_time)} + disabledDate={(current) => current > moment(FormData.end_date)} />
@@ -708,34 +692,34 @@ function RegisterAly() { format={TimeChange().mat} picker={TimeChange().str} allowClear={false} - value={FormData.end_time ? moment(FormData.end_time) : null} + value={FormData.end_date ? moment(FormData.end_date) : null} onChange={(date, dateString) => { if (TimeChange().str == "week") { setFormData({ ...FormData, - end_time: date + end_date: date ? moment(date).day(7).format("YYYY-MM-DD") : null, }); } else if (TimeChange().str == "day") { - if (date < moment(FormData.start_time)) { + if (date < moment(FormData.start_date)) { setFormData({ ...FormData, - start_time: dateString, - end_time: FormData.start_time, + start_date: dateString, + end_date: FormData.start_date, }); } else { setFormData({ ...FormData, - end_time: dateString, + end_date: dateString, }); } } else { - setFormData({ ...FormData, end_time: dateString }); + setFormData({ ...FormData, end_date: dateString }); } }} disabledDate={(current) => - current < moment(FormData.start_time) + current < moment(FormData.start_date) } /> @@ -757,11 +741,9 @@ function RegisterAly() { var fortm = FormData; setFormData({ ...fortm, - pn: 1, }); setFormDatas({ ...fortm, - pn: 1, }); }} > @@ -857,7 +839,7 @@ function RegisterAly() { -
+ {/*
-
+
*/} diff --git a/src/pages/DataAnalysisPrediction/ParkingOverview/index.scss b/src/pages/DataAnalysisPrediction/ParkingOverview/index.scss index 187b8c5..3a6dddc 100644 --- a/src/pages/DataAnalysisPrediction/ParkingOverview/index.scss +++ b/src/pages/DataAnalysisPrediction/ParkingOverview/index.scss @@ -17,6 +17,23 @@ $color-primary : var(--color-primary); width: 100%; height: 50px; background: url("../../../assets/images/equip/home/pvhome_title.png"); + + i { + width: 14px; + height: 14px; + font-size: 12px; + border-radius: 50%; + cursor: pointer; + margin-left: 4px; + border: #ffffff 1px solid; + display: flex; + justify-content: center; + align-items: center; + } + } + + .curpoin { + cursor: pointer; } .pk_header { @@ -46,6 +63,82 @@ $color-primary : var(--color-primary); border-radius: 2px; display: flex; overflow: hidden; + + .serdd { + width: 18px; + height: 100%; + cursor: pointer; + color: #A9C6FF; + display: flex; + z-index: 1001; + align-items: center; + } + } + + .select_modals { + z-index: 1000; + position: absolute; + top: 133px; + left: 392px; + width: 340px; + height: 414px; + background: rgba(30, 38, 53, 0.64); + border: 1px solid #a9c6ff; + border-radius: 2px; + display: flex; + padding: 20px 18px 20px 20px; + overflow: hidden; + flex-direction: column; + + p { + margin-bottom: 0%; + } + + .p { + + margin-left: 6px; + width: 280px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + .address_home { + display: flex; + align-items: center; + } + + .imgd { + width: 300px; + height: 168px; + + } + + .parent { + display: flex; + flex-direction: column; + height: 50px; + border-bottom: 1px #bbb dotted; + justify-content: center; + } + + .a_href { + cursor: pointer; + color: #75bcff; + text-align: right; + } + + .zhanbo { + width: 100%; + display: flex; + justify-content: space-between; + + p { + span { + margin-right: 6px; + } + } + } } .show_c { @@ -82,6 +175,7 @@ $color-primary : var(--color-primary); max-width: 170px; overflow: hidden; text-overflow: ellipsis; + white-space: nowrap; } i { @@ -117,10 +211,19 @@ $color-primary : var(--color-primary); margin-bottom: 0%; } + .dlex_f { + display: flex; + height: calc(100% - 50px); + flex-direction: column; + justify-content: space-between; + } + + + .lf_s { width: 100%; display: flex; - padding: 14px 0 14px 20px; + padding: 0 0 0 20px; img { width: 80px; @@ -145,6 +248,7 @@ $color-primary : var(--color-primary); max-width: 170px; overflow: hidden; text-overflow: ellipsis; + white-space: nowrap; } i { @@ -157,6 +261,127 @@ $color-primary : var(--color-primary); } } + .right_ssdf { + width: 168px; + height: 270px; + z-index: 1000; + + position: absolute; + bottom: 38px; + right: 390px; + + .c_t { + background: rgba(30, 38, 53, 0.64); + height: 100px; + margin-bottom: 10px; + padding: 20px; + display: flex; + flex-direction: column; + justify-content: space-between; + + .ant-checkbox-wrapper { + display: flex; + justify-content: space-between; + flex-direction: row-reverse; + margin-left: 0; + + &::after { + display: none; + } + } + } + + .colcr { + background: rgba(30, 38, 53, 0.64); + height: 160px; + padding: 20px; + display: flex; + flex-direction: column; + justify-content: space-between; + + + .tkr { + font-size: 14px; + font-family: Microsoft YaHei, Microsoft YaHei-Bold; + font-weight: 700; + text-align: left; + color: #ffffff; + } + + .cd_color { + display: flex; + justify-content: space-between; + color: #bbb; + + &:nth-last-child(2) { + span { + &:nth-last-child(1) { + width: 40px; + height: 16px; + background: #FFA200; + } + } + + } + + &:nth-last-child(3) { + span { + &:nth-last-child(1) { + width: 40px; + height: 16px; + background: #12D4B2; + } + } + + } + + &:nth-last-child(1) { + span { + &:nth-last-child(1) { + width: 40px; + height: 16px; + background: #F44465; + } + } + + } + } + } + } + + .right_home { + z-index: 1000; + position: absolute; + top: 96px; + right: 50px; + width: 320px; + height: 87%; + background: rgba(30, 38, 53, 0.64); + display: flex; + flex-direction: column; + justify-content: space-between; + + .day_select { + margin: 10px auto; + width: 280px; + height: 20px; + background: rgba(30, 38, 53, 0.65); + display: flex; + align-items: center; + + .day_item { + display: block; + width: 25%; + text-align: center; + cursor: pointer; + } + + .day_checked { + background: url("../../../assets/images/equip/home/right_checked.png") no-repeat; + } + } + } + .pk_footer { z-index: 1000; position: absolute; @@ -228,6 +453,7 @@ $color-primary : var(--color-primary); text-align: center; overflow: hidden; text-overflow: ellipsis; + white-space: nowrap; } .q { @@ -235,4 +461,242 @@ $color-primary : var(--color-primary); } } } +} + +.modal-boeat { + .ant-modal-header { + font-size: 18px; + font-family: Microsoft YaHei, Microsoft YaHei-Bold; + font-weight: 700; + text-align: center; + background: linear-gradient(0deg, #526991 0%, #47597a 100%); + } + + .ant-modal-body { + padding: 1px 20px 20px; + } + + .ant-modal-footer { + display: flex; + justify-content: center; + + span { + display: flex; + justify-content: center; + align-items: center; + width: 80px; + cursor: pointer; + height: 36px; + background: #4a6184; + border-radius: 2px; + } + } + + .boweizs { + .header_bohome { + display: flex; + padding: 20px 0 30px; + + .form_item { + display: flex; + align-items: center; + padding: 0 10px 16px 0; + + .lab { + text-align: right; + margin-right: 10px; + } + + .inputs { + width: 200px; + // border: 1px solid var(--color-table-border-bottom-color); + border-radius: 4px; + overflow: hidden; + } + } + + .but_on { + display: flex; + // align-items: center; + margin: 0 10px 0 0; + justify-content: space-between; + font-size: 16px; + + span { + width: 80px; + height: 32px; + border-radius: 4px; + color: #ffffff; + margin-right: 10px; + text-align: center; + line-height: 32px; + cursor: pointer; + } + + .sear_ser, + .sear_rep { + background: linear-gradient(180deg, #3aa9ff, #59b7ff); + } + } + } + + .ant-table-thead { + th { + border: rgba(255, 255, 255, .08) 1px solid; + + i { + cursor: pointer; + margin-left: 10px; + display: inline-block; + width: 14px; + height: 14px; + border: solid 1px $color-text; + border-radius: 7px; + line-height: 14px; + text-align: center; + } + + &::before { + display: none; + } + } + + .ant-table-selection-column { + text-align: center; + padding: 0; + } + } + + .ant-table-body { + @include scrollBar(var(--color-user-list-bg), #3B97FF); + + } + + + } + + .Kcar { + display: flex; + flex-wrap: wrap; + height: 600px; + overflow-y: scroll; + @include scrollBar(var(--color-user-list-bg), #3B97FF); + + .casd { + width: 280px; + height: 268px; + background: #39445d; + display: flex; + flex-direction: column; + align-items: center; + margin: 20px 18px 0 0; + padding: 30px 0 0 0; + + img { + width: 192px; + margin-bottom: 23px; + } + + p { + width: 156px; + height: 36px; + background: #6B758C; + border-radius: 4px; + display: flex; + justify-content: center; + align-items: center; + } + + span { + margin-top: 10px; + } + } + + .curoin { + cursor: pointer; + + p { + background: #127bfc; + } + } + } + + .detail_roda { + .shoe { + display: flex; + flex-wrap: wrap; + padding: 30px 0; + + .item_cas { + width: 30%; + display: flex; + + .lanf { + width: 60px; + } + + .imfdg { + margin-left: 4px; + width: 240px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + } + } + + .tu_per { + display: flex; + flex-direction: column; + + .proe { + display: flex; + align-items: center; + + img { + width: 18px; + height: 16px; + } + + span { + font-size: 16px; + font-family: Microsoft YaHei, Microsoft YaHei-Regular; + margin-left: 7px; + } + } + + } + + .zhao_p { + display: flex; + justify-content: space-between; + margin-top: 20px; + + .content { + width: 320px; + height: 218px; + background: #39445d; + display: flex; + flex-direction: column; + + p { + text-align: center; + line-height: 40px; + margin-bottom: 0%; + } + + .imffg { + margin: 0% auto; + width: 300px; + height: 168px; + } + } + } + } +} + +.labds { + span { + margin-right: 10px; + } } \ No newline at end of file diff --git a/src/pages/DataAnalysisPrediction/ParkingOverview/loadable.jsx b/src/pages/DataAnalysisPrediction/ParkingOverview/loadable.jsx index 5b816ea..59d31fb 100644 --- a/src/pages/DataAnalysisPrediction/ParkingOverview/loadable.jsx +++ b/src/pages/DataAnalysisPrediction/ParkingOverview/loadable.jsx @@ -3,17 +3,27 @@ import { message, Pagination, Input, + Tooltip, + Checkbox, AutoComplete, Table, Select, Modal, } from "antd"; -import { UserOutlined } from "@ant-design/icons"; -// import { dictionary, utils } from "@/config/common"; +import { EnvironmentOutlined, SearchOutlined } from "@ant-design/icons"; +import ReactEcharts from "echarts-for-react"; + +import { + ImgError, + ResultFlow, + ParkingViewMarkers, + BaseMap, + MarkCenter, +} from "@/components"; +import { dictionary, utils } from "@/config/common"; // import moment from 'moment' // import { useSessionStorageState, useUpdateEffect, useSize, useUpdate } from 'ahooks'; import ajax from "@/services"; -import { BaseMap } from "@/components"; import "./index.scss"; import Btckd from "@/assets/images/equip/home/bottom_checked.png"; import Pkhl from "@/assets/images/equip/home/pkhome_left.png"; @@ -25,89 +35,747 @@ import Lf4 from "@/assets/images/equip/home/left_4.png"; import Lf5 from "@/assets/images/equip/home/left_5.png"; import Lf6 from "@/assets/images/equip/home/left_6.png"; import Lf7 from "@/assets/images/equip/home/left_7.png"; +import Kx from "@/assets/images/equip/home/kx.png"; +import Yc from "@/assets/images/equip/home/yc.png"; +import Poto from "@/assets/images/equip/home/poto.png"; + // import errorImg from "@/assets/images/layout/error.png" // import { useLocation } from "react-router-dom"; function ParkingOverview() { + let timer = null; + //地图数据展示is + const MapS = [ + { + text: "热力图", + value: "1", + }, + { + text: "停车场", + value: "2", + }, + ]; + //右侧时间选择 + const Dayfour = [ + { + text: "今日", + value: "1", + }, + + { + text: "近7日", + value: "2", + }, + { + text: "近30日", + value: "3", + }, + { + text: "近12月", + value: "4", + }, + ]; + //底部车场类型切换 + const Road = [ + { + text: "全部车场", + value: "1", + }, + + { + text: "路内车场", + value: "2", + }, + { + text: "路外车场", + value: "3", + }, + ]; + //默认泊位列表检索 + const defaultform = { + berthCode: "", //编号 + parkingName: "", //停车场 + operatorId: "", //商户 + berthType: "", //泊位类型 + plate: "", //车牌 + pn: 1, + size: dictionary?.pageSizeOptions1[0], + }; + //默认泊位列表 + const column = [ + { + title: "泊位号", + dataIndex: "berthCode", + key: "berthCode", + align: "center", + }, + { + title: "所属路段", + dataIndex: "parkingName", + key: "parkingName", + align: "center", + }, + { + title: "区域", + dataIndex: "areaName", + key: "areaName", + align: "center", + }, + { + title: "商户", + dataIndex: "operatorName", + key: "operatorName", + align: "center", + }, + { + title: "泊位类型", + dataIndex: "berthTypeName", + key: "berthTypeName", + align: "center", + }, + { + title: "当前泊车", + dataIndex: "plate", + key: "plate", + align: "center", + }, + { + title: "更新时间", + dataIndex: "updateTime", + key: "updateTime", + align: "center", + }, + ]; + //泊位详情展示 + const DataDetail = [ + { + text: "商户:", + value: "operatorName", + }, + { + text: "泊位号:", + value: "berthCode", + }, + { + text: "入场时间:", + value: "inTime", + }, + { + text: "停车时长:", + value: "parkTime", + }, + { + text: "车牌号:", + value: "plate", + }, + { + text: "计费金额:", + value: "receivable_amount", + }, + { + text: "实收金额:", + value: "actual_amount", + }, + { + text: "停车场:", + value: "parkingName", + }, + ]; + //左侧数据储存 + const [LeftDataTop, setLeftDataTop] = useState({ + parkTotal: 0, + berthTotal: 0, + orderTotal: 0, + income: 0, + memberTotal: 0, + }); + const [LeftDataOther, setLeftDataOther] = useState({ + usage: 0, + turnoverRate: 0, + }); //左侧展示栏 const [LeftShow, setLeftShow] = useState([ { text: "车场总数", - value: "233", + value: "parkTotal", img: Lf1, status: "", }, { text: "泊位总数", - value: "42,176", + value: "berthTotal", img: Lf2, status: "", }, { text: "近7日交易订单数", - value: "60,637", + value: "orderTotal", img: Lf3, status: "单", }, { text: "近7日收入", - value: "264,578.000", + value: "income", img: Lf4, status: "元", }, { text: "近7日泊位利用率", - value: "228.80", + value: "usage", img: Lf5, status: "%", + other: true, + url: "/dataAlyPrediction/parkUsageAly", }, { text: "近7日泊位周转率", - value: "1.00", + value: "turnoverRate", img: Lf6, status: "次", + other: true, + url: "/dataAlyPrediction/parkTurnoverAly", }, { text: "注册会员", - value: "466,188", + value: "memberTotal", img: Lf7, status: "", }, ]); - //底部车场类型切换 - const Road = [ - { - text: "全部车场", - value: "0", - }, - { - text: "路内车场", - value: "1", - }, - { - text: "路外车场", - value: "2", - }, - ]; + //左侧车场信息是否展示 + const [LeftCar, setLeftCar] = useState(false); + //停车场和位置切换 + const [Selectq, setSelectq] = useState("1"); + //左侧泊位总数弹框展开类型等 + const [BoOpenClass, setBoOpenClass] = useState({ + width: 1632, + title: "泊位列表", + type: 1, + }); + //左侧泊位总数弹框展开 + const [BoOpen, setBoOpen] = useState(false); + //泊位详情 + const [BoOpenDetail, setBoOpenDetail] = useState(false); + + //商户 + const [Yunying, setYunying] = useState([]); + //检索 + const [FormData, setFormData] = useState(defaultform); + //页码状态 + const [loading, setLoading] = useState(false); + //页面数据 + const [Data, setData] = useState({ + data: [], + total: 0, + }); + + //中间 + const [Zata, setZata] = useState({ + income: "0", + parkNumber: "0", + }); + + //地图数据展示选择 + const [MapShow, setMapShow] = useState(["1", "2"]); + //地图点位数据 + const [MapData, setMapData] = useState([]); + //页面显示的车场数据 + const [RoadData, setRoadData] = useState({}); + //储存选择的位置信息 + const [Center, setCenter] = useState({ + lng: "", + lat: "", + name: "", + }); + //检索 + const [Value, setValue] = useState(""); + //检索下拉 + const [Option, setOption] = useState([]); + + //右侧时间切换 + const [DaySel, setDaySel] = useState("1"); + const [DaySet, setDaySet] = useState("1"); + const [DaySes, setDaySes] = useState("1"); + //右侧echarts列表数据 + const [RightOne, setRightOne] = useState({}); + const [RightTwo, setRightTwo] = useState({}); + const [RightThree, setRightThree] = useState({}); + //底部车场类型切换 - const [RoadSelect, setRoadSelect] = useState("0"); + const [RoadSelect, setRoadSelect] = useState("1"); //底部车场切换数据 const [CarRoad, setCarRoad] = useState([ { text: "西海岸新区", value: "1", }, - { - text: "西海岸东区", - value: "2", - }, - { - text: "西海岸南区", - value: "3", - }, ]); //底部车场切换展示 const [CarShow, setCarShow] = useState(0); + + //页码 + function onShowSizeChange(pn, size) { + let temFormData = {}; + if (FormData.size == size) { + temFormData = { + ...FormData, + pn, + }; + } else { + temFormData = { + ...FormData, + pn: 1, + size, + }; + } + setFormData(temFormData); + getData(temFormData); + } + //停车场和位置切换 + const hangChange = (val) => { + setSelectq(val); + if (val == "2") { + setLeftCar(false); + } + setOption([]); + }; + //地图点位点击 + const ClickMap = (val) => { + setRoadData(val); + setLeftCar(true); + }; + //选择 + const onSelect = (data) => { + if (Selectq == "1") { + let add = Option.filter((ele) => ele.parkName == data)[0].road_id || ""; + let arr = MapData.filter((ele) => ele.roadId == add)[0]; + if (arr) { + setRoadData(arr); + setLeftCar(true); + } else { + setLeftCar(false); + message.error("未找到相关车场信息"); + } + } else { + let dasd = Option.filter((ele) => ele.address == data)[0] || {}; + setCenter({ + lng: dasd?.longitude || "", + lat: dasd?.latitude || "", + name: dasd.address || "", + }); + } + }; + //输入 + const AutoChange = (data) => { + setValue(data); + }; + //模糊 + const AutoChangesize = (data) => { + if (data) { + if (Selectq == "1") { + ajax.ParkingOverview.searchPark({ + type: RoadSelect, + keywords: data, + }).then( + (res) => { + if (parseInt(res?.status) === 20000) { + setOption( + res?.data.map((ele) => { + return { + label: ( +
+ + {ele.parkName} +
+ ), + value: ele.parkName, + ...ele, + }; + }) + ); + } else { + message.error(res?.message); + } + setLoading(true); + }, + (err) => { + console.log(err); + setLoading(true); + } + ); + } else { + ajax.ParkingOverview.searchGeocode({ + keywords: data, + }).then( + (res) => { + if (parseInt(res?.status) === 20000) { + setOption( + res?.data.map((ele) => { + return { + label: ( +
+ + {ele.address} +
+ ), + value: ele.address, + ...ele, + }; + }) + ); + } else { + message.error(res?.message); + } + setLoading(true); + }, + (err) => { + console.log(err); + setLoading(true); + } + ); + } + } else { + setOption([]); + } + }; + + //右侧时间切换 + const SelectDay = (str, val) => { + if (str == 1) { + setDaySel(val); + GetComplaintType(RoadSelect, val); + } else if (str == 2) { + setDaySet(val); + GetParkingEvaluate(RoadSelect, val); + } else if (str == 3) { + setDaySes(val); + GetRevenueAnalysis(RoadSelect, val); + } + }; + function sum(arr) { + var len = arr.length; + if (len == 0) { + return 0; + } else if (len == 1) { + return arr[0]; + } else { + return arr[0] + sum(arr.slice(1)); + } + } + //右侧上、中echarts + const getOingOption = ( + datas = [ + { + key: "停车次数", + value: 0, + }, + { + key: "功能异常", + value: 0, + }, + ] + ) => { + // 获取所有地区名称 + const arrleft = + datas.map((ele) => { + return { + name: ele.key, + value: ele.value, + }; + }) || []; + setRightOne({ + title: { + text: "{a|" + sum(datas.map((ele) => ele.value)) + "}{c|次}", + x: "center", + y: "center", + subtext: "客诉总数", + subtextStyle: { + color: "#fff", + fontSize: 14, + }, + textStyle: { + rich: { + a: { + fontSize: 30, + color: "#4DC3FF", + }, + + c: { + fontSize: 14, + color: "#4DC3FF", + // padding: [5,0] + }, + }, + }, + }, + tooltip: { + trigger: "item", + formatter: (params) => { + return `
${params.marker} ${params.name} ${params.value}次 ${params.percent}%
`; + }, + }, + legend: { + type: "scroll", + //right: "5%", + top: "bottom", + bottom: "center", + //data: areaNames, + data: datas.map((ele) => ele.key), + itemWidth: 18, + itemHeight: 12, + textStyle: { + fontSize: 14, + color: "white", + }, + }, + + // color: ["#34F3B6", "#4DC3FF"], + //series: seriesData, + series: [ + { + // name: 'Access From', + type: "pie", + radius: ["60%", "70%"], + avoidLabelOverlap: false, + label: { + show: false, + position: "center", + }, + // emphasis: { + // label: { + // show: true, + // fontSize: 40, + + // fontWeight: "bold", + // }, + // }, + labelLine: { + show: false, + }, + data: arrleft, + }, + ], + grid: { + x: 50, + y: 55, + x2: 70, + y2: 20, + }, + }); + }; + const getRingOption = ( + datas = [ + { + key: "1星", + value: 0, + }, + { + key: "2星", + value: 0, + }, + { + key: "3星", + value: 0, + }, + { + key: "4星", + value: 0, + }, + { + key: "5星", + value: 0, + }, + ] + ) => { + // 获取所有地区名称 + + const arrRight = + datas.map((ele) => { + return { + name: ele.key, + value: ele.value, + }; + }) || []; + setRightTwo({ + title: { + text: "{a|" + sum(datas.map((ele) => ele.value)) + "}{c|次}", + x: "center", + y: "center", + subtext: "评价总数", + subtextStyle: { + color: "#fff", + fontSize: 14, + }, + textStyle: { + rich: { + a: { + fontSize: 30, + color: "#4DC3FF", + }, + + c: { + fontSize: 14, + color: "#4DC3FF", + // padding: [5,0] + }, + }, + }, + }, + tooltip: { + trigger: "item", + formatter: (params) => { + return `
${params.marker} ${params.name} ${params.value}次 ${params.percent}%
`; + }, + }, + legend: { + type: "scroll", + //right: "5%", + top: "bottom", + bottom: "center", + //data: areaNames, + data: ["1星", "2星", "3星", "4星", "5星"], + itemWidth: 18, + itemHeight: 12, + textStyle: { + fontSize: 14, + color: "white", + }, + }, + + // color: ["#34F3B6", "#4DC3FF"], + //series: seriesData, + series: [ + { + // name: 'Access From', + type: "pie", + radius: ["60%", "70%"], + avoidLabelOverlap: false, + label: { + show: false, + position: "center", + }, + // emphasis: { + // label: { + // show: true, + // fontSize: 40, + // fontWeight: "bold", + // }, + // }, + labelLine: { + show: false, + }, + data: arrRight, + }, + ], + grid: { + x: 50, + y: 55, + x2: 70, + y2: 20, + }, + }); + }; + //右下 + const getRevenueOption = ( + data = [ + { + key: "", + value: 0, + }, + ] + ) => { + // 获取所有地区名称 + + setRightThree({ + title: { + text: "", + textStyle: { + color: "#fff", + }, + }, + tooltip: { + trigger: "axis", + formatter: (params) => { + console.log(params); + return `
+ ${params[0].axisValue} ${params[0].seriesName} ${params[0].value} +
`; + }, + }, + legend: { + type: "scroll", + top: 0, + left: "center", + data: "停车收入(元)", + itemWidth: 18, + itemHeight: 12, + width: "40%", + textStyle: { + fontSize: 14, + color: "white", + }, + }, + xAxis: { + data: data.map((ele) => ele.key), + type: "category", + boundaryGap: false, // 不留白,从原点开始 + axisLine: { + lineStyle: { + color: "#bbb", + }, + }, + axisLabel: { + textStyle: { + color: "#bbb", + }, + }, + }, + yAxis: { + type: "value", + name: "停车收入(元)", + min: 0, + // /max: 50, + interval: 10, + // splitNumber: 6, //设置坐标轴的分割段数 + axisLabel: { + //formatter: "{value}元", + textStyle: { + color: "#bbb", + }, + }, + splitLine: { + show: true, // 是否显示分隔线。默认数值轴显示,类目轴不显示 + interval: "0", // 坐标轴刻度标签的显示间隔,在类目轴中有效.0显示所有 + lineStyle: { + color: ["#cccccc42"], // 分隔线颜色,可以设置成单个颜色,也可以设置成颜色数组,分隔线会按数组中颜色的顺序依次循环设置颜色 + width: 1.3, // 分隔线线宽 + type: "dashed", // 坐标轴线线的类型('solid',实线类型;'dashed',虚线类型;'dotted',点状类型) + }, + }, + }, + color: ["#0DE1FA"], + //series: seriesData, + series: [ + { + name: "停车收入", + type: "line", + areaStyle: { + //color: '#94C9EC' + + color: "rgba(13,225,250, .31)", + }, + data: data.map((ele) => ele.value), + }, + ], + grid: { + x: 50, + y: 35, + x2: 20, + y2: 30, + }, + }); + }; + //底部车场切换 const BottomCar = (val) => { let length = CarRoad.length; @@ -130,29 +798,329 @@ function ParkingOverview() { const BottomTab = (val) => { setRoadSelect(val); }; + + //获取左边数据(不包括7日利用率和周转) + const GetOverviewData = (val) => { + ajax.ParkingOverview.GetOverviewData({ type: val }).then( + (res) => { + if (parseInt(res?.status) === 20000) { + setLeftDataTop({ ...res?.data }); + } else { + message.error(res?.message); + } + setLoading(true); + }, + (err) => { + console.log(err); + setLoading(true); + } + ); + }; + //获取左边数据(7日利用率和周转) + const GetUseInfo = (val) => { + ajax.ParkingOverview.GetUseInfo({ type: val }).then( + (res) => { + if (parseInt(res?.status) === 20000) { + setLeftDataOther({ ...res.data }); + } else { + message.error(res?.message); + } + setLoading(true); + }, + (err) => { + console.log(err); + setLoading(true); + } + ); + }; + + //获取泊位页面筛选数据 + const getSelectData = () => { + ajax.getAllOperator().then( + (res) => { + if (parseInt(res?.status) === 20000) { + setYunying(res.data); + } else { + message.error(res?.message); + } + setLoading(true); + }, + (err) => { + console.log(err); + setLoading(true); + } + ); + }; + //获取点位数据 + const getMapData = (val) => { + ajax.ParkingOverview.getMapData({ type: val }).then( + (res) => { + if (parseInt(res?.status) === 20000) { + let arrcopy = res?.data.map((ele, index) => { + if (ele.usageRate) { + let user = ele.usageRate.slice(0, ele.usageRate.length - 1); + if (user >= 50) { + return { + ...ele, + lat: ele.latitude, + lng: ele.longitude, + type: 1, + id: index, + text: ele.parkName, + }; + } else if (user <= 20) { + return { + ...ele, + lat: ele.latitude, + lng: ele.longitude, + type: 3, + id: index, + text: ele.parkName, + }; + } else { + return { + ...ele, + lat: ele.latitude, + lng: ele.longitude, + type: 2, + id: index, + text: ele.parkName, + }; + } + } + }); + setMapData(arrcopy); + } else { + message.error(res?.message); + } + setLoading(true); + }, + (err) => { + console.log(err); + setLoading(true); + } + ); + }; + //获取今日收入和服务车辆- + const GetDataStatic = (val) => { + ajax.ParkingOverview.GetDataStatic({ type: val }).then( + (res) => { + if (parseInt(res?.status) === 20000) { + setZata(res?.data); + } else { + message.error(res?.message); + } + setLoading(true); + }, + (err) => { + console.log(err); + setLoading(true); + } + ); + }; + //获取收入分析 + const GetRevenueAnalysis = (val, item) => { + ajax.ParkingOverview.GetRevenueAnalysis({ type: val, dateType: item }).then( + (res) => { + if (parseInt(res?.status) === 20000) { + // setZata(res?.data); + getRevenueOption(res.data || []); + } else { + message.error(res?.message); + } + setLoading(true); + }, + (err) => { + console.log(err); + setLoading(true); + } + ); + }; //获取车场评价 + const GetParkingEvaluate = (val, item) => { + ajax.ParkingOverview.GetParkingEvaluate({ type: val, dateType: item }).then( + (res) => { + if (parseInt(res?.status) === 20000) { + // setZata(res?.data); + getRingOption(res?.data); + } else { + message.error(res?.message); + } + setLoading(true); + }, + (err) => { + console.log(err); + setLoading(true); + } + ); + }; //获取客诉类型分析 + const GetComplaintType = (val, item) => { + ajax.ParkingOverview.GetComplaintType({ type: val, dateType: item }).then( + (res) => { + if (parseInt(res?.status) === 20000) { + getOingOption(res?.data); + } else { + message.error(res?.message); + } + setLoading(true); + }, + (err) => { + console.log(err); + setLoading(true); + } + ); + }; + + //获取泊位页面显示数据 + const getData = (data) => { + setLoading(false); + ajax.ParkingOverview.getParkingBoW({ + ...data, + }).then( + (res) => { + if (parseInt(res?.status) === 20000) { + setData({ + data: res?.data || [], + total: res.total || 0, + }); + setLoading(true); + } else { + message.error(res?.message); + } + setLoading(true); + }, + (err) => { + console.log(err); + setLoading(true); + } + ); + }; + //获取实时泊位显示数据 + const getSituationData = (data) => { + setLoading(false); + ajax.ParkingOverview.getSituationData({ + roadId: data, + }).then( + (res) => { + if (parseInt(res?.status) === 20000) { + setBoOpenClass({ + width: 1540, + title: RoadData?.text || "--", + type: 2, + }); + setData({ + data: res?.data || [], + }); + setBoOpen(true); + setLoading(true); + } else { + message.error(res?.message); + } + setLoading(true); + }, + (err) => { + console.log(err); + setLoading(true); + } + ); + }; + //获取实时泊位显示详情数据 + const getSituationDetailData = (data) => { + setLoading(false); + ajax.ParkingOverview.getSituationDetailData({ + roadId: data, + }).then( + (res) => { + setBoOpen(false); + if (parseInt(res?.status) === 20000) { + setData({ + data: res?.data, + }); + setBoOpenClass({ + ...BoOpenClass, + width: 1060, + type: 3, + }); + setBoOpenDetail(true); + setLoading(true); + } else { + message.error(res?.message); + } + setLoading(true); + }, + (err) => { + console.log(err); + setLoading(true); + } + ); + }; + useEffect(() => { + setDaySel("1"); + setDaySet("1"); + setDaySes("1"); + getMapData(RoadSelect); + GetDataStatic(RoadSelect); + GetOverviewData(RoadSelect); + GetUseInfo(RoadSelect); + GetRevenueAnalysis(RoadSelect, "1"); + GetParkingEvaluate(RoadSelect, "1"); + GetComplaintType(RoadSelect, "1"); + }, [RoadSelect]); + useEffect(() => { + getSelectData(); + return () => {}; + }, []); return (
西海岸新区停车信息管理平台
停车业务概览
- {LeftShow.map((ele) => { - return ( -
- -
-
-

{ele.value}

- {ele.status} +
+ {LeftShow.map((ele) => { + return ( +
{ + if (ele?.url) { + window.location = `/#${ele.url}`; + } + if (ele.text == "泊位总数") { + getData(FormData); + setBoOpenClass({ + width: 1632, + title: "泊位列表", + type: 1, + }); + setBoOpen(true); + } + }} + key={ele.text} + > + +
+
+

+ {ele.other + ? LeftDataOther[ele.value] + : LeftDataTop[ele.value]} +

+ {ele.status} +
+ {ele.text}
- {ele.text}
-
- ); - })} + ); + })} +
+ setFormData({ + ...FormData, + berthCode: e.target.value, + }) + } + /> +
+
+
+ 停车场名称 +
+ + setFormData({ + ...FormData, + parkingName: e.target.value, + }) + } + /> +
+
+
+ 商户 +
+ + setFormData({ + ...FormData, + berthType: e, + }) + } + /> +
+
+
+ 车牌号 +
+ + setFormData({ + ...FormData, + plate: e.target.value, + }) + } + /> +
+
+
+ { + var fortm = FormData; + setFormData({ + ...fortm, + pn: 1, + }); + getData({ + ...fortm, + pn: 1, + }); + }} + > + 查询 + + { + var reset = defaultform; + setFormData(reset); + getData(reset); + }} + > + 重置 + +
+
+ +
+
+ record.id} + dataSource={Data.data} + pagination={false} + scroll={{ + // x: 1300, + y: "calc(100vh - 520px)", + }} + /> + + + +
+ `共 ${total_records} 条`} + total={Data.total} + current={FormData.pn} + pageSize={FormData.size} + pageSizeOptions={dictionary?.pageSizeOptions} + onChange={onShowSizeChange} + onShowSizeChange={onShowSizeChange} + /> +
+ + + ) : BoOpenClass.type == 2 ? ( +
+ {Data.data.map((ele) => { + return ( +
{ + if (ele.status == 1) { + getSituationDetailData(ele?.berthCode); + } + }} + > + +

{ele?.status == 1 ? ele?.plate : "车位空闲"}

+ {ele?.berthCode} +
+ ); + })} +
+ ) : ( +
+
+ {DataDetail.map((ele) => { + return ( +
+ {ele?.text} +

+ {ele?.value || "--"} +

+
+ ); + })} +
+
+
+ )} + + { + setBoOpenDetail(false); + setData({ + data: [], + total: 0, + }); + }} + > + 返回 + + } + onCancel={() => { + setBoOpenDetail(false); + setData({ + data: [], + total: 0, + }); + }} + width={BoOpenClass.width} + destroyOnClose + className="modal-boeat" + title={BoOpenClass.title} + > +
+
+ {DataDetail.map((ele) => { + return ( +
+ {ele?.text} +

+ {Data.data[ele?.value] || "--"} +

+
+ ); + })} +
+
+
+ + 入场照片 +
+
+
+
+

全景照片

+
+ +
+
+
+

车辆照片

+
+ +
+
+
+

车牌照片

+
+ +
+
+
+
+
); } diff --git a/src/services/ElectInvoice/index.js b/src/services/ElectInvoice/index.js index f47f557..e6cdec8 100644 --- a/src/services/ElectInvoice/index.js +++ b/src/services/ElectInvoice/index.js @@ -1,5 +1,5 @@ import ajax from "../../config/ajax"; -//为电子发票和财务报表,以及清分结算接口数据 +//为电子发票和财务报表,以及清分结算接口数据 会员统计 设备分析 //-------------------------------------------------电子发票--------------- //************************发票记录 @@ -143,6 +143,35 @@ const downLoadRefund = (params) => { data: params, }); }; +//-------------------------------------------------会员统计--------------- +//************************停车分析 +//获取列表数据 +const getParking = (params) => { + return ajax({ + url: "/api/ana/member/member_parking", + type: "post", + data: params, + }); +}; +//************************注册分析 +//获取列表数据 +const getRegister= (params) => { + return ajax({ + url: "/api/ana/member/member_register", + type: "post", + data: params, + }); +}; +//************************支付分析 +//获取列表数据 +const getPayFx= (params) => { + return ajax({ + url: "/api/ana/member/member_order", + type: "post", + data: params, + }); +}; +//-------------------------------------------------设备分析--------------- export default { getInvoiceMess, FlushRed, @@ -162,4 +191,8 @@ export default { getRepeatDetail, getPayRepeatRefund, downLoadRefund, + + getParking, + getRegister, + getPayFx, }; diff --git a/src/services/ParkingOverview/index.js b/src/services/ParkingOverview/index.js new file mode 100644 index 0000000..9d51308 --- /dev/null +++ b/src/services/ParkingOverview/index.js @@ -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, + }); + }, +}; diff --git a/src/services/index.js b/src/services/index.js index 7141565..0b96648 100644 --- a/src/services/index.js +++ b/src/services/index.js @@ -21,6 +21,7 @@ import BusinessConf from "./SystemMgm"; import ElectInvoice from "./ElectInvoice"; import FinancialMgm from "./FinancialMgm"; import DataAnalysisPrediction from "./DataAnalysisPrediction"; +import ParkingOverview from "./ParkingOverview"; const api = {}; export default { ...api, @@ -47,4 +48,5 @@ export default { ElectInvoice, ...FinancialMgm, ...DataAnalysisPrediction, + ParkingOverview, };