From a9c66a376af1572de0f052dcf1c417bc75bb7d30 Mon Sep 17 00:00:00 2001 From: renna <576157508@qq.com> Date: Tue, 8 Jul 2025 10:50:41 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B9=B3=E5=8F=B0=E6=A6=82=E8=A7=88=E8=BD=A6?= =?UTF-8?q?=E8=BE=86=E7=A7=BB=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 +- package.json | 6 +- src/assets/images/Aircraft1.png | Bin 0 -> 1462 bytes src/assets/images/airport_bg.png | Bin 0 -> 609 bytes src/assets/images/airport_out.png | Bin 0 -> 612 bytes src/assets/images/layerActive.png | Bin 2204 -> 2197 bytes src/assets/images/left_arrow.png | Bin 0 -> 4329 bytes src/assets/images/left_arrow_active.png | Bin 0 -> 3068 bytes src/assets/images/right_arrow.png | Bin 0 -> 4333 bytes src/assets/images/right_arrow_active.png | Bin 0 -> 3068 bytes src/assets/images/znz.png | Bin 2246 -> 1112 bytes src/assets/images/znzBg.png | Bin 0 -> 1768 bytes src/assets/images/按钮-一宫格悬停.png | Bin 434 -> 0 bytes src/assets/images/按钮-一宫格选中.png | Bin 448 -> 0 bytes src/assets/images/按钮-二宫格悬停.png | Bin 452 -> 0 bytes src/assets/images/按钮-二宫格选中.png | Bin 476 -> 0 bytes src/assets/images/按钮-六宫格悬停.png | Bin 681 -> 0 bytes src/assets/images/按钮-六宫格选中.png | Bin 682 -> 0 bytes src/assets/images/选项icon-充放电统计选中.png | Bin 464 -> 0 bytes src/assets/images/选项icon-故障报警选中.png | Bin 446 -> 0 bytes src/assets/images/选项icon-电池概况选中.png | Bin 312 -> 0 bytes src/assets/images/选项icon-视频监控选中.png | Bin 402 -> 0 bytes src/assets/images/选项icon-轨迹回放选中.png | Bin 590 -> 0 bytes src/components/map/OpenLayersMap.vue | 3 +- src/components/map/controls/LayerSwitcher.vue | 58 +- .../map/controls/OpenLayersMapInfo.vue | 4 +- .../map/controls/OpenLayersZoomControl.vue | 263 ++++++++- .../map/controls/VehicleMovementControl.vue | 454 +++++++++++++++ src/utils/test_websocket.html | 534 ++++++++---------- src/utils/websocket使用说明.md | 65 --- src/views/platform/index.vue | 61 +- src/views/system/role/index.vue | 2 +- 32 files changed, 1044 insertions(+), 411 deletions(-) create mode 100644 src/assets/images/Aircraft1.png create mode 100644 src/assets/images/airport_bg.png create mode 100644 src/assets/images/airport_out.png create mode 100644 src/assets/images/left_arrow.png create mode 100644 src/assets/images/left_arrow_active.png create mode 100644 src/assets/images/right_arrow.png create mode 100644 src/assets/images/right_arrow_active.png create mode 100644 src/assets/images/znzBg.png delete mode 100644 src/assets/images/按钮-一宫格悬停.png delete mode 100644 src/assets/images/按钮-一宫格选中.png delete mode 100644 src/assets/images/按钮-二宫格悬停.png delete mode 100644 src/assets/images/按钮-二宫格选中.png delete mode 100644 src/assets/images/按钮-六宫格悬停.png delete mode 100644 src/assets/images/按钮-六宫格选中.png delete mode 100644 src/assets/images/选项icon-充放电统计选中.png delete mode 100644 src/assets/images/选项icon-故障报警选中.png delete mode 100644 src/assets/images/选项icon-电池概况选中.png delete mode 100644 src/assets/images/选项icon-视频监控选中.png delete mode 100644 src/assets/images/选项icon-轨迹回放选中.png create mode 100644 src/components/map/controls/VehicleMovementControl.vue delete mode 100644 src/utils/websocket使用说明.md diff --git a/README.md b/README.md index 9305d3b..f3e5f5b 100644 --- a/README.md +++ b/README.md @@ -121,4 +121,7 @@ function getUserOptions() { userOptions.value = res.rows; }); -} \ No newline at end of file +} + +使用SockJS + STOMP协议 +滑出蓝色 滑入黄色 \ No newline at end of file diff --git a/package.json b/package.json index bf3b1d1..ede8c60 100644 --- a/package.json +++ b/package.json @@ -15,11 +15,10 @@ }, "dependencies": { "@element-plus/icons-vue": "2.0.10", + "@stomp/stompjs": "^7.1.1", "@supermap/iclient-ol": "^11.1.1", "@vueuse/core": "9.5.0", "axios": "0.27.2", - "ol": "6.15.1", - "proj4": "^2.17.0", "echarts": "5.4.0", "element-plus": "2.2.21", "file-saver": "2.0.5", @@ -28,7 +27,10 @@ "jsencrypt": "3.3.1", "leaflet-minimap": "^3.6.1", "nprogress": "0.2.0", + "ol": "6.15.1", "pinia": "2.0.22", + "proj4": "^2.17.0", + "sockjs-client": "^1.6.1", "vue": "3.2.45", "vue-cropper": "1.0.3", "vue-router": "4.1.4" diff --git a/src/assets/images/Aircraft1.png b/src/assets/images/Aircraft1.png new file mode 100644 index 0000000000000000000000000000000000000000..6c179139cbe4671ccdb1d7fb51b3ba610660367f GIT binary patch literal 1462 zcmV;n1xfmeP)YJI|k8sBOMHt#r9u*KkUVnhbGD z!T?aNHebFE4HxGii{Z6NrP3mtOM^JGnh*f3R?D2saaCkXTp$wpKwV-zk)NNh!B^t0 zuCB)qfY0YEvn9@*XBwxarO9xZ-re1u6314F0l>mzqMs=XI7fT&;r}>-LxdOBxb}RM z07#Ot7$1EGu;`Q!oA8#Gmy^P4m{`^w3xN6^iDn#stH{2yvy;K|*6y`q80O`oq9Q4c zTU%QTX-!g6Qa6O^;!r=w5{Fu?e(l1!#Rj)KrA;P3ouA5ge$~`CTigD|U)T*H;!~Hb zgY;>y!s9LOKpO>4eS##Vd@wJXLK(tmFRK5b{bOnwYP0(H<}!a7lD$vlBNFZ3>-@O| z&{VE~?nl*|>DU$Wf(^JmAQ9oKEK~=o8$3T*3}pxUSTpl@SNHvUS3f( z70AjIGMVgNM@NT!aBy%}7WTCa6`eTUf4%wIjMNKeE{fsRhL+5-+5~si030>Sr@?wIx$RT!~N-OU|DWf zn(I4t{n|kA{TE+X!cT*_vl%D2T%~+NT!pnjM-~mpViCf3H%sB}P=U$mbY9ZwbTc@; zof73-OV=woCx^NL6__y6QN0vwwtyaMVRmh8?boHH>1iI1xBa?Sql>I{I{9ESnLgL+ z^&=XM=K0@8t|-}jyW8T4L=Hm+R2TZyPYonPIOxc0J(wE%1%yB-ooz#9TuPv=LF^D-H71KA~+vLO_iyL zWB|ebLw4xgOlu_)2_IQeU@#b#x3;!^fY7%>+OsGKavs72wW|&L`};@4V)0XCC_<=s z?Ydc(C8z!{pq=8u=xlgY3gQThRRl((aV5&mht3JS6P;71MKlfVDEicJFuuJ!5ZK(@ zq{`u8p>WX-_X-}_gwd2yArkt6M@Du+p)i0M*lQmMD~T%%h!@^>doKVk%J@jZ49uIc zSVaqd2m}HY{WgM%Wa%i`wSPj_F)<|mXnEl#&dP*Sg@uJDF>91|4j!kFb8Ol9zMc}! zY2^piFpkv50L4;#7uawE{;5s zn7?3=32S{mKCh?mnLn^o{0! z3L)}3RN^|ToSYo7*=)|oVFvt1QuIs3Opy|~2*QDFqAo$`Ti{TM>#tN^ULMcq^ZAix zH!vd>oU$VK+XMoE1DTL5C@5g@wsRm;Zs9vpy3vko>qM$GdJT7s&9N={FQ$c54t7&N QM*si-07*qoM6N<$g50^fi~s-t literal 0 HcmV?d00001 diff --git a/src/assets/images/airport_bg.png b/src/assets/images/airport_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..862bb7014fd8f1dcab85f2856d9f3949a28ca94e GIT binary patch literal 609 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 M07*qoM6N<$g4Am!ivR!s delta 2141 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 GqW%fj+g5P^ literal 0 HcmV?d00001 diff --git a/src/assets/images/left_arrow_active.png b/src/assets/images/left_arrow_active.png new file mode 100644 index 0000000000000000000000000000000000000000..34f83b9b26a4b471e459f10bbad0b787387a7469 GIT binary patch literal 3068 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 KMNUMnLSTY)5X-Fq literal 0 HcmV?d00001 diff --git a/src/assets/images/right_arrow.png b/src/assets/images/right_arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..f86115b7a02d90afb1799fa7b493d4ad4da0a4d8 GIT binary patch literal 4333 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 literal 0 HcmV?d00001 diff --git a/src/assets/images/right_arrow_active.png b/src/assets/images/right_arrow_active.png new file mode 100644 index 0000000000000000000000000000000000000000..ec1650094afb64e4748bda34bdb917051cb480c2 GIT binary patch literal 3068 zcmVStO&>uS)ve<0AYj>5AR{$W90N^4L=L-RlQUJ&DC0@ZjPh;=*jPLSYvv5M~MFBAl0-BNIsH z15C~g000{K(ZT*WKal6<?_01!^k@7iDG<<3=fuAC~28EsPoqkpK{9G%|Vj005J}`Hw&=0RYXHq~ibpyyzHQsFW8>#s~laM4*8xut5h5 z!4#~(4xGUqyucR%VFpA%3?#rj5JCpzfE)^;7?wd9RKPme1hudO8lVxH;SjXJF*pt9 z;1XPc>u?taU>Kgl7`%oF1VP9M6Ja4bh!J9r*dopd7nzO(B4J20l7OTj>4+3jBE`sZ zqynizYLQ(?Bl0bB6giDtK>Co|$RIL`{EECsF_eL_Q3KQhbwIhO9~z3rpmWi5G!I>X zmZEFX8nhlgfVQHi(M#xcbO3#dj$?q)F%D*o*1Pf{>6$SWH+$s3q(pv=X`qR|$iJF~TPzlc-O$C3+J1 z#CT#lv5;6stS0Uu9wDA3UMCI{Uz12A4#|?_P6{CkNG+sOq(0IRX`DyT~9-sA|ffUF>wk++Z!kWZ5P$;0Hg6gtI-;!FvmBvPc55=u2?Kjj3apE5$3psG>L zsh-pbs)#zDT1jo7c2F-(3)vyY4>O^>2$gY-Gd%Qm(Z8e zYv>2*=jns=cMJ`N4THx>VkjAF8G9M07`GWOnM|ey)0dgZR4~^v8<}UA514ONSSt1^ zd=-((5|uiYR+WC0=c-gyb5%dpd8!Lkt5pxHURHgkMpd&=fR^vEcAI*_=wwAG2sV%zY%w@v@XU~7=xdm1xY6*0;iwVIXu6TaXrs|dqbIl~ z?uTdNHFy_3W~^@g_pF#!K2~{F^;XxcN!DEJEbDF7 zS8PxlSDOr*I-AS3sI8l=#CDr)-xT5$k15hA^;2%zG3@;83hbKf2JJcaVfH2VZT8O{ z%p4LO);n}Nd~$Sk%yw*Wyz8XlG{dRHsl(}4XB%gsbDi@w7p6;)%MzD%mlsoQr;4X; zpL)xc%+^yMd)ZNTI#eJ*$O)i@o$z8)e??LqN_gLa_%;TM>o2SC_ zkmoO6c3xRt`@J4dvz#WL)-Y|z+r(Soy~}%GIzByR`p)SCKE^%*pL(B%zNWq+-#xw~ ze%5}Oeh2)X`#bu}{g3#+;d$~F@lFL`0l@*~0lk45fwKc^10MvL1f>Tx1&sx}1}_Xg z6+#RN4Ot&@lW)Km@*DYMGu&q^n$Z=?2%QyL8~QNJCQKgI5srq>2;UHXZ>IT7>CCnW zh~P(Th`1kV8JQRPeH1AwGO8}>QM6NZadh`A)~w`N`)9q5@sFvDxjWlxwsLl7tZHmh zY-8-3xPZ8-xPf?w_(k!T5_A(J3GIpG#Ms0=iQ{tu=WLoYoaCBRmULsT<=mpV7v|~C z%bs^USv6UZd^m-e5|^?+<%1wXP%juy<)>~<9TW0|n}ttBzM_qyQL(qUN<5P0omQ3h zINdvaL;7fjPeygdGYL;pD|wL_lDQ-EO;$wK-mK5raoH_7l$?~Dqf!lNmb5F^Ft;eT zPi8AClMUo~=55LwlZVRpxOiFd;3B_8yA~shQx|tGF!j;$toK>JuS&gYLDkTP@C~gS@r~shUu{a>bfJ1` z^^VQ7&C1OKHDNXFTgC{M|V%fo{xK_dk6MK@9S!GZ*1JJzrV5xZBjOk z9!NTH<(q(S+MDf~ceQX@Dh|Ry<-sT4rhI$jQ0Sq~!`#Eo-%($2E^vo}is5J@NVEf|KK?WT&2;PCq@=ncR8z zO#GQ^T~S@VXG71PKNocFOt)Y6$@AXlk6rM*aP%VgV%sIRORYVwJx6|U{ozQjTW{-S z_si{9Jg#)~P3t?+@6&(!YQWWV*Z9{iU7vZq@5byKw{9lg9JnRA_4s!7?H6|n?o8ZW zdXIRo{Jz@#>IeD{>VLHUv1Pz*;P_y`V9&!@5AO~Mho1hF|I>%z(nrik)gwkDjgOrl z9~%uCz4Bzvli{bbrxVZ0epdf^>vOB;-~HnIOV3#R*zgPai_gEVd8zYq@2jb=I>#f& zAH2?aJ@Kaet@DE*sA9s;~l0q_A6uUv`E(SIOe~6MY zC@Z7MEW)C6M-x{@%Vl68LLsHNhI^Ex>s-C(S-!pRd7k&v`z)uSQmLp_qsv;chFu)s z_4|2gzUH{b+Q;Ap1?=DsTbM(8#B3A*$01uVjScL@%*O&JzkmgNWCfIdJa?$B?$4^{ z4=Pwf8NC?G61c$x7O@`QO=Sr{G30j0@vMQbD&q=6XiEXWX~@A;z-7qJRKRn{d@7(h z9D<{%t}40000< KMNUMnLSTYs5Y2%A literal 0 HcmV?d00001 diff --git a/src/assets/images/znz.png b/src/assets/images/znz.png index 82f36d728b460631599f0612abf1e32bb7948d2e..388670cf6e31fd2f556e45e1df2833206b3e7425 100644 GIT binary patch delta 1077 zcmV-51j_ry5!eVJiBL{Q4GJ0x0000DNk~Le0000F0000W2nGNE0L?5SsgWTxe*^7F zL_t(|0ku_IOJi3Q-uomcCeBIDnVdL@lcZ!)b*$n;MbM{?LZMLF7s0>aL;DN*r2dIM z_*^Jxp|oJ}(TBdNBL#&jUIu5zOD^VeaxpoVJ>NQ-A<@VT46`wqz4!Xo`qsDB+F|T- zE+GVe=+66qF<)I><%L2)qW?Ive>msPU0dD_ys@$2DV0hAfOT1xEuYVq-`m@3EG;c{ zIFQ)=#Sab+e9dMvTCdl?1#kvus;=wu-4yQ8-rnB!#N+Xvd_JGTc4l&NathI%tE;QO zus4ZZ*T@SC3zA_N9>;Nlwrvk0(sNDI5}{D&`_t3Y0NJ-k?*NaEj&kHGe_vl;hvDFP zDwT?6vpFBc`q8p11>(u=I!Wz9k-Esy55pw(>7k(^tynCwOg0xBA0L0AC`xzm;^HD7 z8yoXd1bm($+7rUS{fL3B@xdIwmNBpGyde7;O15_+Xlfg$6~Mw2y~ z%^zyDTCiHJN@V*UOrD^!e*{H)P@<YHdZ>I1lg zHa|W-hK)yo%1Kbxke}K>#G6~j-=3eda5y|m)R&i+J*-`N5(Bit*ncrHGLk5kN^Wjc zR5)Xf?XX(CK7({(5Y@etT8)7N8Ihl08-+onTs8smkOxVj{PytQBi86$uiu{T?JH)gDOb0tVI~JavIviwjx!e{i zKw(KVhBS83!bi}@xi^xu=H})E8pH&+aB*?*-=p5ZD+tFlRb@Rs-|v}B#>OMq{TU+a z`}_MAM5>@Hf9L49|AUIc`av0^_%{T#TOD@~Ow?nsn1vy!o2GerczF0nIQ*DJ^vC~# z@-b0v<=ZVXqs~F2G+>lP`a5WfEu`@qu1w6aU>{nbCatWj1lHHr!x)fX(6R&cvfj0O v@OOxer>CbSG>jlNw?ch5^2Y}Fr1cIs@j6VeKBtBN3jhEBNkvXXu0mjflj#S1 delta 2220 zcmV;d2vhgi2*wd1iBL{Q4GJ0x0000DNk~Le0000e0000e2nGNE0F3^)ZIK}~e+XMi zL_t(|0j*hWY#V1Cf1bPZ*=PG~=f!E0uFgxF_jySZ%GesZ78MD`P^Ik)8G;E3f`oYa zz>okT0Uyx5bP^v15}Ab90JWg)!!#r+rfD6?R*jM-ZI&f*+ca&KwP*uJyRch9r` zbB+@`@yj{ePr5{T?z#W-yZ`(Be}mBh(b0FdA5qeV2<|7CwquOk2vIq67sn_?%N)f^ z2$2xt`LUVn?~I`X09UfPz5SGoUHl-WcyO1D<)fA`rDK?So7@(?11Ye*$vIUTPo4 z99($!LKInm45~ciuWyvsSMFUcD!b64X;MkJKr!t{Wx#Qa9EZ1sVM4PY$SPoS2&?4# zv$OBT_Q@~!fF%6M3b~BtI4s(DuDVLLdp$0jjpuO&9I^`7+(sq-LZN&6Ow7y*syKtn z3C&1G0?%_Ek1Pi2>)ds9f3;#{E3WCfK|zzS!IG)BNuq{A=FTJ7(f7pHLF5mSMKEpI z?RNf59#q1q(_R1N#VK$`4^o>vK0Ze>Dc|#R>9=7dY&a z?1InZwjXb45yRmP{OHMkuia+jcn()o1a<{eGw0?JWZI(`J(XSbdA-7~e)glLFP!Xg z7n8$6L9p4dEW2!Om*faO66B)MD2hZP{J>);Wu7s#z_Is{Zf8^D(L6=4f{@iBmm$5& zm}%|8?|#vFtm#P2e@tjjDJ0a4UO3+l;p_8w?7&Z`sjlKQO+zcItLTfT9`)En5nEvx zjmGpBe*JuBcUPM;cbz!+!5xAGVKb%t;Cs&<`oo3ac2YwZfrc@0b4o2p5H4QevC}E> zUXNRBX=xJTiG;}~t))>TZMJ}Vn@_wkN)BMkWGSvCZfBCQ0WY^%)3_;eFWPR_C zFTb+-(#x;T+iaq)CN-s)K+Lh+XTx4FuTye}4|jJ9TU%R9C=~>rYN-@|$}}@yR)cpT z;srrKx~`+gKi}``4R&WV3BK6TH_*=^!^lg>-R-UJ>D%++;a4v$6eI^n3J@G3q!+I& z+a*a9>gwvae^fHXDgv`ST3lL2UpaTSO0hk$ zTkhtT=795qYvYlL8%4~EdGk=&CGj5FCHD39+9J^?&SX5Z3S-?cQ0ws~cWq4-)R^+& zJoMvVhOSLag{wSrz8@0W&k+tcf6gR`kqyl2c1kv<%OSM39us1* z7+a^=%FZak8XxTHbh65a%J^X<8Zqw9FR0DU0V(f14!1G==jFbY)wNV9VeA2xLL>+f zkK4`rYik7-y=E}%b~NEul6{pihe?jXgl}f_JerrfgrLf&5qUq3`I5n(w z3_hQ4fAdUnjDyE_0s_jE;dZ$MpVwEi(>91sRW(VrVsUMHc2@PsGTMn^5J(`31A&L| z-!8qjW)P1UsF@1hK=I2~%2{M7I(eq$9=a zfAM78laT{L&<~V@=m zi6m6TxG_1Ekep7Fhv|Pn(ChV}iOG+mL?@P8|Gu6s-+DNbM-cok1XbS%Az>*JG&>gsAn+B9!87FXxy@25tl%%m4jiu-AEhJ^xjT##2(dGZV6NNxRR`89dpRAW82YvmGe}{9| zd6+zyzuAxQ!h%)t8xE;M?4Y#Q*%) ze>^Y@Yx()y*#X~QF2241C05UQ`8Q|BN6d-CP9?!kV;CvIQ;Uw>2ss*fX!V9gb@Fqr5De}M*q6aH*n2;A|#z(L3p0NjQ@ZpXtm||r<;Ms(MvdKp#Ekk-a2tA0Zi=i8% zFYc4S7ahH)Vf2B@jz0DZ`ZP@eo6m$MMxNcfUU)X+GM)$Hg-|62po4>@6gE66bgyKh zuhiTJK_Ro|qGZ<+hCz@n<~1q%rW+mu^jr4wu?xZ3N6F59VlOclz*Y zz_f;wbhywwa4#wwqHhz0Bj8&a*Q1I68iSI`CFw;g#12F-7ahTYei(1Th1$SW4VjOx utQ%1FZ-_X2-9fKO#*mIetni});1lOP*_2QB2@n7P002ovPDHLk0$_r@g;^*7 diff --git a/src/assets/images/znzBg.png b/src/assets/images/znzBg.png new file mode 100644 index 0000000000000000000000000000000000000000..31f6cf030d3cceb81005af973e8d23ba3ef81614 GIT binary patch literal 1768 zcmVP)eDRM5kB|pQyG&Ff`K*64F06CrJ3&PZ|ke7?k))UM0f9* zJ`g+!ob+)bx(I;?fH0h|Br62WQbA?_cp4Z>O^#hjfe#QbgS)!=4H9MpLXd$qGOm}J zAwr}G6N7hB!?Uhuxfx^=3$b$oU;thNh=7Z3iEc}<`~6b`!h&<&J+|%AGlY}D$?I2t z+iDcs>SOoeliy%0Avw^u8b=7lhpasyzy%C+<>`3qTgLpe$A7=lcD2nyS#In4!m_VO3QbaX`T> zaBxxt+4*|kHc2dHMOU1L?Tk8>L1BzWqlVg+XfayiyY!{yT)Apm(krO5E2&pVLZY7B z>j-xDp85n$ehn_6GDdV=XK%zCgY9jJhA+SPtSOhvS06o|E?bV);1NCX*7hutyjgp( zszcY|{siZCLb!sAI*dOO2xzpiA*#oWP@t`CuXg(6v8bl&o@K5X2rxrM1V)?8WtUO=Atws2&Oi zlwD1Yv{I?Sv**v@gZ`sYRnv%Xh6o;D1FHl%kZnuKI)eBxg^^Gw$gs3%9dEZQxqRN{ zQ>|3ty@UH>0ZpTh6TQcwO^gtSpgfg$i#_Q*S^HEHGs0>p7}O3PIG`*qFH56BQJAQd z%dG#Hl$rVVpp3=t-V=QkEX$Mkq`wtR4$M^ao}nW@rKP2XmP=(>`=s*lbY>Pl`tVGn zrfWoII{1ZPN$LNjmpPcd_M%2O$f8DA>pgTxUCLyLQ}OIwn3$FYo%`A&&AS>^Myc;W zE6ksS`&Uy9;MNqp? zS(Yi1ot;ejbat)AruOW zQn?J}atR;#e+7!=GSO8H?xgSMgeCm*6C_J-q6niVUYbO~S=2lZy)KoXO-W<2P;TqW9#ggeaJ=wVh3rLT`%*kperx(}Vi)(3dLr|d*m*`G;|51-xmzJ6~e zY<-L3c`D#LBL^wjJgWC?%R=u}Za=6e>&w`(Ke&L6oOojIEdE05L6g_qz!X`G)bH+& zj|^@#%3TXsb{_23h_~*;t028bN@B2HKX4L51A^!}K!`mI6HF*k5NXv~MeBgh0q#~h_K{}}b0000< KMNUMnLSTX+1yAY# literal 0 HcmV?d00001 diff --git a/src/assets/images/按钮-一宫格悬停.png b/src/assets/images/按钮-一宫格悬停.png deleted file mode 100644 index 2d27e9b2de68730a79e8aff75ce1dfa95b642245..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 434 zcmV;j0ZsmiP)5T2M@@;c#;Y@~O~>4pqk3PFB4*KZB-C zqX@n56`ReiPl3Qz`OC;I66XE>01uB($b-)J>DtV9ISm-Yy}iTX(J}IHu)l}(wXpzD z{4r%f8BhlNhkze@(PGWO=}Ep`G(R`{Yk-T)hz!G*v@7ZbT6T}`{Q`rp@}BMT!X9ZG z&27kn53&}GC*n3Q0!T)9-gmD%)OX#tgd}yDA;L>|ikf79)XWu!QYuEMfntd3cH^nI cEek diff --git a/src/assets/images/按钮-一宫格选中.png b/src/assets/images/按钮-一宫格选中.png deleted file mode 100644 index 6863d5532e33f3b4d89c598f35ee7a280bb234f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 448 zcmV;x0YCnUP)pV`TKQ zdDzSaLfjLOLj*98D*{=1xXinQf{o)=Gpg|MlKzKW6Dqu{!pn#pmgEW1Gl;Q@`sX8k zcVHru6qp6C6JYn+`w{9c4Yd@;59#o?p2UmSM;OesfSEETC4*&5J8VCH;_UVnVK~`K zW4rh}j^m$+3*v&fU>*vl&Z6~|McnK!BMhsVg+B@iww`)J(eC<#sc5Fck8H2wPYNQ( z0Ase=SwpvT)kajPSEk1OgkM+hjf;pOBKPSc+u+V=z8lD(6lIAH52P&VJsbZ}JZhCW qr;5@A%!0m8BHQoDx>L({wfX`MCU-@Q)Nt+q0000&@SRya2K3J5Hp5CC9aB?snJbH zhC&j~`-;J6u1h$VlHZVA-j}?WWOzs58^bWl!B{;72HSWE`EV$q-GP1APXvMoUEi(7 zEPi0XsvrRZ#8rsWvh7=U5}<9h-(;DmL&EuRL(%lM$<0lWPnm{vtTM(<((29i6;vuq zkcW}?0sEbUAAx|O@>3&y6Po*e0M9S48H0Ll6-uQ=7(PA;XDitkn*?M)^P}UljE-OD z2Z3;Qd2tS#&Gn2<;h!l2ihv?u76OD_gvEv3@|UCtMYDQs4WEXJj&Ih5Nm(}C& zFW~6NskZ>bu`>_K8wuYRk_q~&XOEokfOAs?Asw+REZD)-5MfE&GIi?2oQAk>EQBo1 zxz)W$x2Sn$j9umy!z_{EE@MTxC#%NJ$)H3juLzt&5Xtl8yyHw+!>k))i9P@kRfH*^ Spb!cG0000VZ%qna)x09D+xetjdkB<2aX;^1iU>``7u4(r1_FuU*mlJO!LH8wF%DX|1oX+qir+@A6oz2jgQGyy4sgO;{~` z!ph3WRvBxR@1%cld4GH#qS0NA1h%bp0Y42UJxvV5 zFkroT>+(I(-FW`&(O(mYfx!_+J+vN0#xiXn2k|CjtX00DRQiIULkE3p=FJ7oJGRKS zf40@hsff^6TYq)?2(!2$+l~#hN2iqj$9{_#}NY^lk2v=e6-S+mIMM1Gn%}S;%m=t4ZG~*zhyI-J(-mo- z;ietT+&L$|*ulWowVE>Kf9!IvDP_>K}keE&p-PwVK;^ zpG)xi<6mh%yxHy6hx+68d|ukrAFZ8z(g$tv)S%xu<<1m3?+#RO%CTdE*k9x5mvOB( zfPgejJx7=ti-I3CLDeZrsG^BdU`A+p-F>CG9mQg8$aA(E^ft}o*MCI0WbcEP)|Mlgaat<-T+IeGIMVrHxN!BMwVa|Y`_*|-at43-aukO3Qqv67a%cmd)l6n ztwQheX6&ITo$HEC-sLgU&0Z-5ZD_t445BnKdyj`>;-zQ@N z`#<*Q9kRyrUy!EkHZ4d(F2DK_3hZxgiAT`x5HrAG2#RSOeki(xW*shP_d{q-g?(#2ICUIUK zqLVEJ>sFX~{?a*)HaSdZ0&n0A)D!5^L=y1?Sn2`Tmzn24 zBq9OZre89Fy!ZIc$2S>(4TV*WqjAs_8aIIexDeK>-TEw>)2aZ1^JkJ25nzoN(^YA& zY>t%`jf>fp1gOPQo(L&=z_6)mqm=-Ob@jmzCAq$`oh%@90nyY)L2W5OSvM2w-fhEb zPr||Bbk_H-cP%1_wsyGlFW}%ZJXV0m}kS0r}waJ8u81Kfh84l(i>c zdLg)9%NifX$oj>4K2S8Kp#u_h@21{^HDpZZ??~ipQosjeiZ+=)AX2m{fQWQS``W z$lZxy-8q?;Kn_c~qpu?a!^VE@KZ&eB{#j2K$B+ufyFt5o4>|B`)nB+Mk)dT0Zxe@5 zs#$|z0@I5L9IU((6S!t5Br?7Dso^t0L&xF#-I?4PTRQu==B4~p{(W;3?}yI^?wM?4 zF+O%+LEuscyCd)RY+HON{f>z<)2D_h;YuzS94>Rr_575XwrYj*8Hst*&gM?#yc6l> zw)a~2Gwt~Y#S8w9Dl`Ckf0zI zYybHa7w3gj`6nG?x+NY5^>i4l`o!)rMQNe<`Zpr~*!@#kLmqCdtPTfyjKR~@&t;uc GLK6T#jCXSY diff --git a/src/assets/images/选项icon-视频监控选中.png b/src/assets/images/选项icon-视频监控选中.png deleted file mode 100644 index 7923a7917e101aa04e2fc2ff13be258dcce7a128..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 402 zcmV;D0d4+?P)%SFQ9g|P956N{t12{@WM&&IGn812Y34)M&+Z~1jA z`wE`=(%!T|)pd~Hw!i%b(2_Y}ut&HLL(gZXGm6{gBHmpl5M|oTnjFr$VbN3sa4GWD w?zS4pHCRc|%mm3yVBw<(HtU19O8RU21S4sCuUEhhzW@LL07*qoM6N<$f@{R6=>Px# diff --git a/src/assets/images/选项icon-轨迹回放选中.png b/src/assets/images/选项icon-轨迹回放选中.png deleted file mode 100644 index 43c3eddeb704ae7ecdaedb44f6bf679f1c539621..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 590 zcmV-U0P&}0#_XrqcvI05AZ6(@+;pbAGyZeS-u ztc`?J)V}wI88@wLCs9Z8!t?We^YcA~9dO2R}ni*`d=zSV$rKen!&Bps(@u}P5RgVCpa&dd`E2;xX%z4-4s;G4=qpkti zMg(wPW+w1+?kYWG);b6fP5^mN0w7FW9I6}lxz0!gxz##lwz%v!&dMT#m&4x;MM%ZA zlTXc!Gm+90@8Knuty!f!{@uL~>7nc13t{lb5S)-yCgdHXi2*^AkMZq4J#gCJx c%WZl80o#7`_8eCd^Z)<=07*qoM6N<$f|hRyng9R* diff --git a/src/components/map/OpenLayersMap.vue b/src/components/map/OpenLayersMap.vue index 2794d1b..49b8837 100644 --- a/src/components/map/OpenLayersMap.vue +++ b/src/components/map/OpenLayersMap.vue @@ -344,7 +344,8 @@ defineExpose({ zoomOut, compass, resetView, - getCurrentMapState // 暴露获取当前地图状态的方法 + getCurrentMapState, // 暴露获取当前地图状态的方法 + map // 暴露地图实例 }); diff --git a/src/components/map/controls/LayerSwitcher.vue b/src/components/map/controls/LayerSwitcher.vue index 0209a21..af5748e 100644 --- a/src/components/map/controls/LayerSwitcher.vue +++ b/src/components/map/controls/LayerSwitcher.vue @@ -161,9 +161,12 @@ import Overlay from 'ol/Overlay'; import labelBg from '../../../assets/images/label_bg.png'; // 导入车辆图标 -import car1Icon from '../../../assets/images/Aircraft.png'; +import car1Icon from '../../../assets/images/Aircraft.png'; //滑入航空器 +import car1Icon1 from '../../../assets/images/Aircraft1.png'; //滑出航空器 import car2Icon from '../../../assets/images/noPeopleCar.png'; import noPeopleCarIcon from '../../../assets/images/noPeopleCar.png'; +import airportBg from '../../../assets/images/airport_bg.png'; // 蓝色背景 +import airportOutBg from '../../../assets/images/airport_out.png'; // 黄色背景 // 定义props接收地图实例 const props = defineProps({ @@ -191,7 +194,7 @@ const exampleVehicleLayers = ref([ name: '滑入航空器', visible: true, showLabel: true, - icon: car1Icon, + icon: car1Icon1, type: 'aircraft-in', layer: null, features: [ @@ -356,7 +359,18 @@ function initExampleLayers() { // 创建标签内容 const labelDiv = document.createElement('div'); labelDiv.className = `custom-label label-${layerConfig.type}`; - labelDiv.style.backgroundImage = `url(${labelBg})`; + + // 根据类型选择背景图片 - 滑入使用黄色背景(airport_out.png),滑出使用蓝色背景(airport_bg.png) + let backgroundImage; + if (layerConfig.type === 'aircraft-in') { + backgroundImage = airportOutBg; // 滑入航空器背景 - 黄色 + } else if (layerConfig.type === 'aircraft-out') { + backgroundImage = airportBg; // 滑出航空器背景 - 蓝色 + } else { + backgroundImage = labelBg; // 普通车辆背景 + } + + labelDiv.style.backgroundImage = `url(${backgroundImage})`; labelDiv.style.backgroundRepeat = 'no-repeat'; labelDiv.style.backgroundSize = '100% 100%'; labelDiv.style.padding = '3px 10px'; @@ -436,7 +450,7 @@ function selectTextStyle(style) { const allLabels = document.querySelectorAll('.custom-label'); allLabels.forEach(label => { // 确保背景图片始终存在 - label.style.backgroundImage = "url('../../../assets/images/label_bg.png')"; + label.style.backgroundImage = labelBg; label.style.backgroundRepeat = "no-repeat"; label.style.backgroundSize = "100% 100%"; @@ -457,13 +471,13 @@ function selectTextStyle(style) { default: // 默认样式,恢复原始样式 if (label.classList.contains('label-aircraft-in')) { - // label.style.backgroundColor = 'rgba(52, 122, 226, 0.7)'; - // label.style.borderColor = '#347AE2'; - label.style.color = '#fff'; - } else if (label.classList.contains('label-aircraft-out')) { // label.style.backgroundColor = 'rgba(245, 231, 79, 0.7)'; // label.style.borderColor = '#E4CB0D'; - label.style.color = '#333'; + label.style.color = '#333'; // 滑入航空器 - 黄色背景,黑色文字 + } else if (label.classList.contains('label-aircraft-out')) { + // label.style.backgroundColor = 'rgba(52, 122, 226, 0.7)'; + // label.style.borderColor = '#347AE2'; + label.style.color = '#fff'; // 滑出航空器 - 蓝色背景,白色文字 } else if (label.classList.contains('label-car')) { // label.style.backgroundColor = 'rgba(37, 37, 37, 0.7)'; // label.style.borderColor = '#484848'; @@ -513,13 +527,13 @@ function updateAllLabelsStyle(styleName) { default: // 默认样式,恢复原始样式 if (isAircraftIn) { - // label.style.backgroundColor = 'rgba(52, 122, 226, 0.7)'; - // label.style.borderColor = '#347AE2'; - label.style.color = '#fff'; - } else if (isAircraftOut) { // label.style.backgroundColor = 'rgba(245, 231, 79, 0.7)'; // label.style.borderColor = '#E4CB0D'; - label.style.color = '#333'; + label.style.color = '#333'; // 滑入航空器 - 黄色背景,黑色文字 + } else if (isAircraftOut) { + // label.style.backgroundColor = 'rgba(52, 122, 226, 0.7)'; + // label.style.borderColor = '#347AE2'; + label.style.color = '#fff'; // 滑出航空器 - 蓝色背景,白色文字 } else if (isCar) { // label.style.backgroundColor = 'rgba(37, 37, 37, 0.7)'; // label.style.borderColor = '#484848'; @@ -1126,20 +1140,20 @@ function toggleExampleLabel(layer) { transform: translateX(-50%); } -/* 滑入航空器 */ +/* 滑入航空器 - 黄色背景,黑色文字 */ .label-aircraft-in { - background-color: rgba(52, 122, 226, 0.7); - border-color: #347AE2; - color: #fff; -} - -/* 滑出航空器 */ -.label-aircraft-out { background-color: rgba(245, 231, 79, 0.7); border-color: #E4CB0D; color: #333; } +/* 滑出航空器 - 蓝色背景,白色文字 */ +.label-aircraft-out { + background-color: rgba(52, 122, 226, 0.7); + border-color: #347AE2; + color: #fff; +} + /* 无人车 */ .label-car { background-color: rgba(37, 37, 37, 0.7); diff --git a/src/components/map/controls/OpenLayersMapInfo.vue b/src/components/map/controls/OpenLayersMapInfo.vue index 3cf1616..503ab9b 100644 --- a/src/components/map/controls/OpenLayersMapInfo.vue +++ b/src/components/map/controls/OpenLayersMapInfo.vue @@ -1,7 +1,7 @@ diff --git a/src/components/map/controls/OpenLayersZoomControl.vue b/src/components/map/controls/OpenLayersZoomControl.vue index f73e124..e8ae335 100644 --- a/src/components/map/controls/OpenLayersZoomControl.vue +++ b/src/components/map/controls/OpenLayersZoomControl.vue @@ -1,35 +1,108 @@ @@ -83,15 +217,64 @@ defineExpose({ gap: 25px; } -.compass { +.compass-container { + position: relative; width: 40px; height: 40px; - background: url("../../../assets/images/znz.png") no-repeat; - background-size: 100% 100%; cursor: pointer; - z-index: 3000; + background: url("../../../assets/images/znzBg.png") no-repeat; + background-size: 100% 100%; } -.layer-switcher{ + +.rotation-controls { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: flex; + justify-content: space-between; + align-items: center; + z-index: 3002; +} + +.rotate-left, +.rotate-right { + width: 24px; + height: 24px; + position: absolute; + top: 50%; + transform: translateY(-50%); + cursor: pointer; +} + +.rotate-left { + left: -3px; + background: url("../../../assets/images/left_arrow.png") no-repeat; + background-size: 100% 100%; + z-index: 5000; +} + +.rotate-right { + right: -3px; + background: url("../../../assets/images/right_arrow.png") no-repeat; + background-size: 100% 100%; +} + +.rotate-left:hover, +.rotate-left:active { + left: -3px; + background: url("../../../assets/images/left_arrow_active.png") no-repeat; + background-size: 100% 100%; +} +.rotate-right:hover, +.rotate-right:active { + right: -3px; + background: url("../../../assets/images/right_arrow_active.png") no-repeat; + background-size: 100% 100%; +} + +.layer-switcher { z-index: 3000; width: 40px; height: 40px; @@ -99,6 +282,11 @@ defineExpose({ background-size: 100% 100%; cursor: pointer; } +.layer-switcher:hover, +.layer-switcher:active { + background: url("../../../assets/images/layerActive.png") no-repeat; + background-size: 100% 100%; +} .zoom-in { background: url("../../../assets/images/zoomOut.png") no-repeat; @@ -108,6 +296,11 @@ defineExpose({ height: 40px; cursor: pointer; } +.zoom-in:hover, +.zoom-in:active { + background: url("../../../assets/images/zoomOutActive.png") no-repeat; + background-size: 100% 100%; +} .zoom-out { background: url("../../../assets/images/zoomIn.png") no-repeat; @@ -117,15 +310,43 @@ defineExpose({ height: 40px; cursor: pointer; } +.zoom-out:hover, +.zoom-out:active { + background: url("../../../assets/images/zoomInActive.png") no-repeat; + background-size: 100% 100%; +} + /* 响应式调整 */ @media (max-width: 768px) { - .zoom-in, .zoom-out, .compass { + .zoom-in, + .zoom-out, + .compass-container, + .compass-bg, + .compass-needle { width: 28px; height: 28px; + } + + .zoom-in, + .zoom-out { background-size: 80%; background-position: center center; background-repeat: no-repeat; } + + .rotate-left, + .rotate-right { + width: 18px; + height: 18px; + } + + .rotate-left { + left: -18px; + } + + .rotate-right { + right: -18px; + } } - \ No newline at end of file + diff --git a/src/components/map/controls/VehicleMovementControl.vue b/src/components/map/controls/VehicleMovementControl.vue new file mode 100644 index 0000000..7957a6e --- /dev/null +++ b/src/components/map/controls/VehicleMovementControl.vue @@ -0,0 +1,454 @@ + + + + + \ No newline at end of file diff --git a/src/utils/test_websocket.html b/src/utils/test_websocket.html index 69915bd..363613d 100644 --- a/src/utils/test_websocket.html +++ b/src/utils/test_websocket.html @@ -1,388 +1,332 @@ - WebSocket 测试客户端 - STOMP + SockJS + + 冲突检测WebSocket测试工具 - - -
-

WebSocket 实时消息测试客户端

-

连接地址: http://10.0.0.124:8082/ws

-

订阅主题: /topic/realtime

+

冲突检测WebSocket测试工具

-
未连接
- -
- - - -
- -
-
-
0
-
总消息数
+ +
+

🚗 冲突检测WebSocket (原生协议)

+ +
+ +
-
-
0
-
位置更新
+ +
+ + + +
-
-
0
-
预警消息
-
-
-
0
-
控制指令
+ +
状态:未连接
+ +
+

日志:

+
-
+ +
+

🎛️ 控制面板

+
+ + + +
+
diff --git a/src/utils/websocket使用说明.md b/src/utils/websocket使用说明.md deleted file mode 100644 index 07e13f9..0000000 --- a/src/utils/websocket使用说明.md +++ /dev/null @@ -1,65 +0,0 @@ -# WebSocket 使用说明 - -## 1. 引入 WebSocket 工具 -```js -import { createWebSocket } from '@/utils/websocket'; -``` - -## 2. 创建 WebSocket 实例 -```js -const ws = createWebSocket('ws://你的后端ws地址'); -``` - -## 3. 监听事件 -```js -// 连接成功 -ws.on('open', () => { - console.log('WebSocket 已连接'); -}); - -// 接收消息 -ws.on('message', (data) => { - console.log('收到消息:', data); - // 这里可以处理接收到的数据 -}); - -// 监听错误 -ws.on('error', (err) => { - console.error('WebSocket 错误:', err); -}); - -// 监听关闭 -ws.on('close', () => { - console.log('WebSocket 已关闭'); -}); -``` - -## 4. 发送数据 -```js -// 发送对象(会自动转为 JSON 字符串) -ws.send({ type: 'yourType', payload: '你的数据' }); - -// 发送字符串 -ws.send('hello server'); -``` - -## 5. 关闭连接 -建议在页面销毁时关闭 WebSocket 连接: -```js -import { onUnmounted } from 'vue'; - -onUnmounted(() => { - ws.close(); -}); -``` - -## 6. 其他说明 -- 支持自动重连,默认最大重连 10 次,每次间隔 3 秒。 -- 支持事件解绑: -```js -ws.off('message', callback); -``` -- 支持多页面/组件复用,内部采用单例模式。 - ---- -如需更复杂的用法或有特殊需求,请联系开发维护者。 \ No newline at end of file diff --git a/src/views/platform/index.vue b/src/views/platform/index.vue index 51b0d2a..b52a462 100644 --- a/src/views/platform/index.vue +++ b/src/views/platform/index.vue @@ -20,6 +20,11 @@ + + + + +