From 3edd781bde7ddc0decbe6df443f9aeac7c691042 Mon Sep 17 00:00:00 2001 From: chndfang Date: Mon, 28 Apr 2025 20:04:46 +0800 Subject: [PATCH] feat: draw point --- eslint.config.js | 2 +- public/point/11-dark.png | Bin 1246 -> 1832 bytes public/point/11-light.png | Bin 0 -> 2002 bytes public/point/12-dark.png | Bin 1158 -> 1805 bytes public/point/12-light.png | Bin 0 -> 1919 bytes public/point/13-dark.png | Bin 1464 -> 2006 bytes public/point/13-light.png | Bin 0 -> 2148 bytes public/point/14-dark.png | Bin 1563 -> 2100 bytes public/point/14-light.png | Bin 0 -> 2319 bytes public/point/15-dark.png | Bin 2020 -> 2531 bytes public/point/15-light.png | Bin 0 -> 2755 bytes src/apis/map/constant.ts | 7 +-- src/assets/themes/antd-dark.json | 9 +++ src/assets/themes/editor-dark.json | 6 +- src/components/robot-list.vue | 3 +- src/pages/exception.vue | 10 ++++ src/services/editor.service.ts | 87 +++++++++++++++++++++++------ src/services/router.ts | 7 ++- src/services/theme.service.ts | 2 +- 19 files changed, 105 insertions(+), 28 deletions(-) create mode 100644 public/point/11-light.png create mode 100644 public/point/12-light.png create mode 100644 public/point/13-light.png create mode 100644 public/point/14-light.png create mode 100644 public/point/15-light.png create mode 100644 src/assets/themes/antd-dark.json create mode 100644 src/pages/exception.vue diff --git a/eslint.config.js b/eslint.config.js index e9452df..a492420 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -24,7 +24,7 @@ export default [ files: ['**/*.vue'], languageOptions: { parserOptions: { parser: tseslint.parser } }, rules: { - 'vue/multi-word-component-names': ['warn', { ignores: ['index'] }], + 'vue/multi-word-component-names': ['warn', { ignores: ['index', 'exception'] }], }, }, { diff --git a/public/point/11-dark.png b/public/point/11-dark.png index 9a57193b00ffd632f1f3520d161871d9f7c7e74a..dcb2bcfa3eff7a4a173d0d5248d905b335a17de1 100644 GIT binary patch literal 1832 zcmc&#`#;l*8~<1vpQ&Yt$sBEn$v6>_TeH@g%ORGI6Xp^JtwMMybBWn;olA%ga|@|q z;!wUrX?CHyAuiK$io)s0l5^a3Fr_LHi;) zyAc8;=v54_0>Rf<=N2As_Zwvk=xbsz-A22St^R7d-xs-F?ufgo>;pPhA43yy`*d6k zemdeMTy{s;kp#24(aKChzuhcsRzO^tQHWd#31>Ru6;If%-cfAB9#YHgpWU$4(b2{7 z*W!~daU>EMwdFI?Y@Le7Ed67AG{p`qn%h$xx|@aiQL!4L^>X!6Hv@CQk>09F3*b$` zU6&$AQEU&Ru6hcsTj_GWts#N$y0qA_qy#irKj1(VDu$ENWDv-dZlO=ba1^IIb)66= z_I@gf6*2rDIfYB(DiZq8G^9!EWbq}-*fz^zpk>n`T(`fZykip;JXh&Cwc@$&rHzm^ z9+=(u3Bj0)n1SKzN;Xzd!F&77c!d>X^~G5oC9yb?OS=*^aY7oy4-8PsyvlNUxhu^L z`UCZ=_c(nYGQRs+O0lpH)SbjL5hVAy`ky=ho+yqv@_pPO2-gw?yAxyn8#PSG} zYz9OMEm6=qc~6Oo;me1up5uf|J<*kQ$o-sKw7^?FqmdRDx6EaH{O_YbDj>n-EFSt8 z_$9w??*FCxj&z7bhBt$PI=j1Jcs;$2k&!C{J*7R=S zi4f39hpNLH=y$_t#3E;5ijZ5;?^K=Hy1{Y$lT6%HexfP^>EC|}$zyu$d@GoagINhj z=M)Qt41zUKn%#8!yB-ostf>_ZW*faf7c(|K{>5?~`fpJP=5ep&19lpmPr+_LOx33I zp^!sRQ&dB9Gdf_kp7Q+JfoF=T&KppdAS4Kx3WxfoNQF5qex5113yIgV_6ldG^j%LC zFkYuzJ$i3%!pwJ+IP}8^J)Uj0C>*=*6F_UC`jO#&WYI=~`S8M{-P?od0j{QJ&kCMP zh9OxVcNTNHV`GC9T9)?8j*2BP7b10>Jry49ACA)&3Q{|w%LP~JZCr?kC( zX#whc7BN$XMT%O**#!kOe$QE&>f2t#6ZpC0s@jZCG*G0kEoUhH3i zgChn3bIjjlPqHn*>D_&61VcbSB>Vo)T5^n?v+c@pAJyRtN+i;Tq|I^dk{o6Io`=fJ z(}X+@Cf9&-ftyh$6&*tV@FKnx;YAwUDFz2_bwtU^`EXZz-LM3L9M zr;WMZ+9y?$zCLl+Gmb*xa|cj0TJ5#hI}f wHHrQKVg>}C9CH*n?^4{$M*HBtnpS=X>aK77Yz9B!d+_=In~M%4F42qeKX?jNw*UYD literal 1246 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 BF|hyu literal 1158 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 Dd=_rh literal 0 HcmV?d00001 diff --git a/public/point/13-dark.png b/public/point/13-dark.png index adf76330c9947c9e2da608c0373b641234dd1aec..25fed6069da0cd444262fe6d7f1a42144dd09d80 100644 GIT binary patch delta 1980 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 b-?Yq*i2~dTpEp-CVBhBK;7)2J26Fxa-2Ii! diff --git a/public/point/13-light.png b/public/point/13-light.png new file mode 100644 index 0000000000000000000000000000000000000000..5384a2e134a1b56524aa20d4a920508e9151531b GIT binary patch literal 2148 zcmV-q2%GnbP)Px-9!W$&RCr$Polj^KR~*ORdx)~Lnh=SfswWwH1Qw3>HMui-D$=cc3jZ1f5_cz_y&QA8v`}3RK zWcT-AA!Oh0H#6VQ`@P?9-n`xA%%bITxuHU#FerrBBc&XaQucAq`z&0p8dE7{nsYu6 zFDd2kLWtQ!A~9=n0bJJzgkD-&I$0KgwZ*S8C=K2z$8pB$ zd8rGbJpJ61QV!Xj0$G<8n9Jw$!~OmJ>8K)gA$Xqm8)IycB*asIb3W@h&ae^$nu73z zUnY2sscBgxWHOnfw_ZedYBvq^mr1Saw<{&>* zLGU~eBH(bWhbQO00^y3O0-+oQFG-`;DUi?S`ym=C5HO=)=C424*YiKKzyEpHx+`kI zkv6RBVP9?7!A9Qy5bJ1@$z*aO3<075B^PY}^+)#Ror`s%E6Pvrnsw~Y9baOdQ#zSU z_WKZA*BvUYghE0_X&*fOzT=`G5C)>*mrp)N(FvRgA%=Yjp65+4#>TNc!*ulRo2MNY z4eza4$G#c(6mvR)1U=?M$Y!&!JaGUE0{PKW;8qX`v_zq$8*1nI0Ky_;tSg>~p~{Ej z?7tG#^E`>;kGz;DKoCq+L$)CZ$by=Db*@hq>3u@wyAeg9zY(o%` z1vPO;5KL4;*efu`%pfdKgYu7Gz@7_IQdmF>H zLMUy9wK;cGTZo2*g#}cfs?G>PNU73xP*vSf`w;|!P$>%-j?`0CXw zcK-Z%cJ11=nj@JaAtcL-7cbbRO`A|dK5+K-?OV2f{d$5BC{Qmk$2}t3b=-QRYDMM* zf)L9jP}^y{Mr6B=OOX&#fFP^@F?1nB`(sa+loJ&06S@)tEFZu!LL3bi4YzFBqE(`H zB?P!xJA3vl`l=?}Bb+*QO8aK5D(a)m)Yc=qg>znjmd5d;JE z_V3@%Zrr%xTRwdFknP>O*TBpFCIrDizVNP$>({UQ8;flkLC{nWrXZM#f(HAE&Ye4_ z>7}|mLC}y7lJVWUcdPa$9Xocc@|*zPhYh~lwr%rYBO@b9RTDwbfDk0(ut~714#W>{ z9E1M@AeBZCR8(Tj7dR+Mo0-5p15`|^OBn>AnWE+Qp&Ej!NTuoK34)-YYBU))GHLWc zzn&dIP=KJbQ8=8a6r< zSc1?1LbN1>Y6q4nph2F9ma3{HY4nh_AVi}I?mHeoeykg04g0UiZIIzJhMjmbGc*1I z9lSvNpyZ4uYDmVgexzEGHiJ;B#MLPdR7tIP2#qcTo*_W42%1SUt~DKj_y8RIMSQ2ndwL@Z}@0L;{O~akfeZ{L-x5O*REJHuA50Z6N7wswzNS0BJ3-J?&34OUt-}!nO$c#x zCkSz)(>SpYY7C~ zJ)&5Gn)-=*nj#1aWI6(Z?Ur=~onq^vv&F{rBw7*)keFe4!SrE^>BZUF!Ob9i4O~Yg zW?L~j-M%G}(CH%DULQfQRS?0RARvfn>w+NIDu`eoK%k$8M-bD{Mdjz=Uoyr944sgf zodR=yBxJMMn^MXHcD~5kP=Q-MgiIzg$~nJm=!DGd6qxiOxUM@Sgt%|#i>yr)5JC+5 z5TJRUN6FblMGG6w`Ml#en=24p*PReTj9d65Q+)-dlgZ?f3WUYQ#lE#`*FrQrzU&7^>q4NZ36DapDM)EL3U|t6GKb+tPD)8D zt$J+IQp(9xDmB%}tZ5_!#<^T>pin4GaL&KbJCE+{4Wqxb=?(O1`uoPp5TYSszt{Dvi}>ewx>zCs1{QTd?|Ojq4vKd a_xl%crn&O)!f*Ki0000e0#1Jw=5eFcF8)@&`zTw(~Tj~&w`tR>jB%DF`33taYduUV3S zpO#raDQ*)36^3n6s}|+lH*)jqohW1X~Hmhuqa`slV9;+u!&9RgfJ>q*iM-L z`GW&?wLkq%+=}}_P4k_7NnwSN?=^e-NX5ZC3Jy#kZMuXJG-CMN;@W2a!Xp)-eX{za zxKSxb9X2g`h(nn~G(2OOhA~#-l$0^jeuM08UNZhox{I@<^bN+&?ms$U-^9d2`ov!3 z*q6SaPRX0~je@?5e2y07k?>=nQ}!$n9@o`ToKSLjm|)iAwO-Lu4%Li$(&p5Xcxc~t zz$?~Z7;?3C_75uUj}Ph+x)jkhKdn8sx4-^8vhk+X_FMPB;mHf(Q94@YTSAe+9Q&5LSx>9ti+vB(s~QCK1$eY*b7UGHRmp=vv^Nk zUxw?E!V_V@+cUwAw0ROH`i*)CtDOh*OIgNpUNIX{-QLgb-!VdN#xtK*c@#8_xGv(N z`Jj-NipUg5a^1;zL~^H=8m9zX62vB$W9omiGf+h?KWdmn!dCJ|5O8So^%ed9KmOq? z^2hodQ{4=vI#D6}!L`YyCV{{d-UDIC%sH zgXv4}1`I#3uMuo5n_jKq4i~G07|dN-Mdn@!<219B2I%-oL4vb7bT9&h(fb;aOj5y^ zjO*vuARyOG+?j->kw5x|QiXmAw4GvMi2^e%cXBMxg(|$xK|8LU7yvK=AS?%{f}wEY z*b17VQYz>Z7}GJbgnH+?3I<^-9_cHkhHozPEsnl-!W6a>nj(}Mjj9P}VA2P*wY3#P zC&hn+8c%f#Gzo}<64E3F3+s<0S`<@2pfMc@IG`=#wosViJS_ksrhDaKVUM#T%!ujz z*08i?p~{Mldy2?hia8FV0@XHQX{)sYM$Bzf42?l(pB0-#ClrGZ5n@zO;EIC0D& z#mUNoLU@*VpXgIder}J7r%Rl|+2HEnU6b0L2l(3(6G8$aawQdFBP?gYMbPrqeJ95a zxJ2L9nOUm4?w4pQ7uY#;Cq=Q*C6yShOM1#k5bRJfT``pkh5e>$=K^ze@0UYLNlDSa z@SldtWylZrsyYKs;y#D`hM4eJ$dC*&?<%zlS)=HmO(T9hVFGyLB3%E_6!|aZ^<-K+ zQ{-mVi*k<_`pG)x$sV`&d6P`h;()ROY4wFHUDPW&9$Eql5^-jCr?gwO=NYpFlz;Skuwd^4Fa8w4kpu{}k$e$>~f1<)F^P z6WLX2$g9dr%RH!_lfO9gcnO_VN+ybH1TUsi>Dcs>nR!^OLTO92JrQ|(XH0ak>V?9b zO_hNj7?-KS%E!XK-)jbX9r|t0gR@d&%sI$Rhb7#%>1Rd*Ccrhiiwe0=ebFSh0$G*A zp5*hjz95rx0;8P~jJRlfzRSQn$~eVXIcNHQn{wgAjwhx>p_JRI3$7^4J`0B!DKOu+ zTj7gTex3ld^9?`{pKw}2Dp_sUBUP=Y@*7;vb-_Rr-<7U~IGNu`0tP7s!}Usp76ktn5F|_zs@+t&C<%2aILoPHq8XvF z@6yVR?W)BY1!eT2Nzb`cI32cz5w~u9EXU2Dmesxj$lV$`e}g5X&uN|5TSh|c3jFhE zqbc=mgs?efa#lb>0qyp~k)853%|OOO1}lIK9RG@W1YS(7gf$z$U=<;)1e;sH3s=fa z8=FtA^C1CI@GMck=Sr<)X400F;7LL~AL*j|=h_PrUc6r?ru^ro$SOaN^w>6+GJAUr zcf300ihp_}S0k-Zo1KPt6!G3ufzgaf-d$?Pt_Ly~T~9Rr;MR9;{c=!S8Fg>a(^wT@ zh7(7VZUQ%E;!0I0-q$FG=RNxe9MrSkf#S_4rq-SXR$?d-P>_%7ff56~+A34tG5S@* zUg*MNIF;!`=;(n;r!5IzeGBU8KMM7GJg%v5IH(r*u_1`kwIWz73hp%&z=n7%16{an n{mLq0QtUyHdgE?&$&#ms{|(8y634%@#sTrF+jX=B2q{) zAo_TwoCt2-LaWC|9RTU|_+(OAf-5p}*?c_U_s-0=&f>N`sY|c9`EXrQmu)*DR~Zq-3ttxbS?J4N4f0>sDzVI5 z^rRSGQQ;XHWqWLSu>{uZV?VkMUu$$d&V(d^)L{q6VNCCy4#+gV9;5^2hf4aC zMfuXUN6I2+v-Ut-gR`TbJI-oHre7uMU0Cq21kG0MeCYNc=Yt3!v5H~SpE$LfI5uMT z!F(T2fS{>8i|Glqgu0)9cC7HHl+{HE$l`EJ*>cj9x*=wA8`1JIURxX0`tkPj1Q+!> zrcerO=#hIGF1JCx;mGO(R_HSVr*-6`4hVi-I-qoGH9mzjsGFoRqN4l;o%H$ zV9fM{J3V(Vx_cdf%7-X@Zivh^e4yl{?41Z?($) zUATG;>GzVt9#E7(#wZYrl1Sjmiex(%O4BCe78#+0>}^o`QCW|o$5y*C%Htq}6WT*Xw8XYxv zRA@BmVmv63R}Ina{ZjK6tKMkoe#*9%*(v{%nirpC&AEwB z_QmCnRH9{J!Mn8X$IJQf1LrL%sx1zR0kY%|>sg~EZRe?X?o6XYx{Fx0IS!Y_#M*d9;J}6wS|B#(vDI})0=8l2x#}pYhriv$ zi`T;U_XR`PQ@e34K_84sQlzVz0)YLPszMb!I`e=6pwB(_GS!SUR3z2;Md{A|P%v%6 zu$dz}@|)c88jY2*D#dZ(*e%c9^bUtYo_#VwT@&k=&l_+$dGjIloY0`y$m)+U7%B7)rMEd2%uN zu+Edj&l7wPLoSjmB>zNPH1{>c)g8_9ikVt*f)t}C-}k>uI4_-v+pNM;0bX+%5Mn{m zMgcqsQErN1>~@%p@)!xg|YI2=WY#W3u3|G$7CuL3pfnS^fzy8GAO9yn;rvMFVF Gi~a>Ub*>)( diff --git a/public/point/14-light.png b/public/point/14-light.png new file mode 100644 index 0000000000000000000000000000000000000000..d2d973981c4fb16013755914687f04857e8915b3 GIT binary patch literal 2319 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 delta 1994 zcmaKtdpy$%AIG=((T@`rii2v~^9Z#vhq+|`(Uf)07Qq4E&Yz$*d@li(yQv9if zBCl+HEIciIGUchViwEQ{=ru%Nr}Fheh&N8g?V;MAv4(akC;Oy3M%YKNo1vL&kSB6? zI!U^)EC0~UuEpDaSG~D)FNc4;jn1nS8k(+0(G*{|?x!g*@j8JTRsai=3{xnWDxQKX zc?Lo>Uuf!!Au3w~8O+4Zfc<5t8;xM)4aQB%*UbSNb;lA_TGoX2Iy$~-tD~V$jz@sHdh4Jl=XBM9u7M6j;SAOWaAjciI-Sq7;MQ3^HQJr2RAFoI@Ng^Ewlz)|L*|Em`(=?s`Bm3c{)Gew7tRkW#dEZ)NnAs z6v(=7*P-)h$Q=EzC{T#BO*d^Z$#}5%MeX!1u@g8QS9$Xk^9_6!*_3H|7@ZNa+Ke}{ zN1%W(dwQrr!r^TE81%B7(K&+$p^V+_IuAHiTHejXUH4K*e_}2R~RC_ zni8BSkpk7L>>4EE979WLw-;pmS!t zIU2A;Xj}Iyo`O!E&l?;pwVf9Rz4d*-!SgwTbZP)ap_Y_05uB`*uLoX3I5{Ds{MjM5 z+hH{b6gn~>4eo(%E;|UIm;;P;mb6T8ps{z)%0J2i@LOG^G{4>?58u9%TAx?W=gPsNGw9yMvLpzVL1Gh2}4i zvDxxj=JSu&oAK3s^uuaM>>~hz1bAnLq&Tw4MoRTD+?9d&`z&2=k#0?Qekrt#_b8JCZ%h*?fxc3~lRvuIV z^H7QAk@M)pq1Dy2{@+NYxmchozhL7S1r=sG_YH9mEd0IkEpO`OvNq zb{A>y)o^AZm?ZO!@o8vjEKbh%imxG)CnTEJYoo_6haeb5Z6QnSx%R)(l{GQ)s@YJM z!A?tQUMhv))Wi%oT3T?+k8}-mzU4kXP^LrH6?XPzfP6#Z*u|U%f1bmdXS&I5^7x19 ze2*5={N$+bF~ZdN?>{~6?l4`@B=T|Hw%zgiCqmICN4OVZfLjnc6ti#d1g5dih=WQu z^5;n=80N{{NKCo_y-;6Df8W;yOTBT#@7FgT-X9$xmL=cc<;-kz^;+IQP4k^<2GUC; zv6n@N!CtG9x)YOLLFf4UP0ZqLP}xXyYO5de-v%?(n?n4REm)#5yKK`Pj4A@~F2;R(0}OC1 z5jLbD?@}JE70Lu=EClnjc2cY5ypjo`G!r@g>1uUTDXwOy(X=D0mrstmo1-X2d)>X}_;WPvspdFw4pEF?FvhVgzF? z-^JN}y1r&o!4HiCZByO^8R~ww2v&6udT$W}uTStke)A+Xpm8Q0`Si}Hz=F?FTL{E1 z>_FU>jrcb~*3Mr+Fk>YSRP&qBGOnH(*8v+I4c2?NWu$ziT$@d*L?1!L5gh!eCmP9( zUCD|Bk($0t?{n4JaB#na#5|ZW+`oAI*1jU4Ec%~Kr4}x{iYfzS{M?OPMOXDbxO@W_ zNyDC04kAnJ7xnhuHs2x2tOuf4i_A!4MIV-E5|hNfuijbMA7ue>y(D|p^wm?|l% z8^(4LcU4ttiV$CGv98k*11fl)2h~nP6qPWo zhgy+aZ;2p#9vE7sLbY^6z?c6fA^zVe{0|b+Km{XAvhqje|7rQQ<;Bphimxh>p^!}- Mb@Fhm#sxC}2IG6CEdT%j diff --git a/public/point/15-light.png b/public/point/15-light.png new file mode 100644 index 0000000000000000000000000000000000000000..f8ba60f9803a3884d6dd6ec206d5c9600cd4aa01 GIT binary patch literal 2755 zcmcJR`#%$o_s2KpGUYb+6l*0+E!5M?F>C~^Mgz>TU`Gx zo6AvO&y**XmV+Zo^Q)^>h)85lA3bZGNQkFWA?YBV3#nA9DFTXtpzL^@JY@u1;*Rxx zxm|{i4SGYaEn^KX*S3z9N1Bd!XjhDQlshL*ZC6LHW>9WwtLOCl)p(wh0d?%4(sNMh z7K8B@`IJIFxG8qQ=dfHCQRzF@A{jxt`8s57_Ol0oje$I^t_mly|Ypc&B=hgBQo(nilN&(etDWDt4(w@Ve%?)vL*b&g!LWVqDsV)={l)!X6~ z;)$g{G_VmCI~=A<#f>NLe_r2H1gE0>uU3iO$Dh%i+?^RPp5uW?$8|nh#X8``@E~h# zapK`JcVz3h98`8(E;`Pyxpx?ZgmKaV#AL;Zr;(X z2AQ!liANFH6rC|KmoA5y64A}rdp_zppoeB!-Ml~-oM32Im>IY$c_Mus&Y;@SdPr7B zD;^sCKLaY@@5a1)QzX-5^GBbU=KC}uxl3un3S)zM`O|1u*Ve?H7zbP*qcKd%G=A+_ zA7)wB1$7LvGTAoZ`P{3Br+x%nh?j;)YWco52xnLY&zlg4I|SX{9d@w4cQi+6cAK7hq_N0mQmoi>b>bLH1I#BZA6V}4R49c{G~{F9 zXwMC=y(*9D;Oz3Xoff_GZ?N8{gNMPCokF4P|7&)2;3Vh18i6qSWsYTU#F7QK z?mw#h2j0kXW_?6L0vQBBBd-(m-tGrdomw{;aozcPA&fhG!gTU0bf%6r>kbC!cR>UMN|3X_rW+>OOHvNuSdCMeOpF+pS zuhg$xDeLe35bcCQv^M&jcBC(iR*&!PY<2eYy@svi*BrIf?X%VaQxGZ1m%Qzxn5{Vl zrm-iU`vh9b&x)22^k=}jDb;9a)i=(V_|2t!kM5vW1YHfK9(0cUSqxqm$^h2!oBxrg zow6{>Gq#5CiV$hbp9J(h3WdCu(n5GXE$?ox`>X}qUh?cjn`(d7^{n|AyTs7>u2jmc zyAsVbwPw2}YmqbpE1DNQZ#9M9{Q9e+R*?hZ@9DVe-qUUlNPgFg8(w3VKiB?DR;Std zwok|%g%<-Z8#+^rI$~BQ%>x8BdB=yOXrBTmTCN40%U=se(>~x~*CBP4eGk23t0T(I z09~n0a%-%b&CJiH4irv+IbC@zuW!e8*xiZN1Hu~jg25u0WF2*CMR)%>eHuOiaG55j zcupF|nrypO6kEikHW}14Kc79rA*AwgPTdZHzq?Z;m~!M8z}iE!EuY>!GihM{%!pmQ z9F7Sb`b6sbJ8BN&i&Y5aRzd(_FgU=AN${^GeG+fxYezjooOlawOk&EYSs)PBsv#{F zLKpa1Ig zn11?IN8D~aKIUx~@-Mf%YT6jH`0UthfpXQcntRR#@2}aRhFwSc6lce9{4}kFh8=Y2 zOFhUByhn zb4^qAAjMj&R$eo8g;L~`Bvnf&xhZmJkCFv54CPFe4BYvi1s~;>%1dw@A4EHR7kQZ| z>_R`@PDRW}D0Licv6;#x+f$tfJ<`X170R2pt;b1c_WxWnM5PNSK<}@}?SCcUFV(l? zMeo~gZTy-qutz}zQt5soAj4bG`zPcq_;E!9P=;IO4^ni$&DB9f!}t(hX-yoPVZTfg{6Q50S$M_Yij9$VwI{u!xc2_ zvUoaGegBb4(Tu2}@!Xxv8}sOT%KGncgPoWSwkG=W55Du$o}2JXU1^27zv|DZu15`S zZybD9eDe7FCa0(}+F%w%IBVpFka*A?(ee(gh%G-UgCL>Ov#=JH6OrBnSH&-2Dlxo= z0Y!Umw(Mode.常规); watch(editor.value.mouseClick, (v) => { if (mode.value !== Mode.添加点位) return; if (isEmpty(v)) return; + editor.value.addPoint(v, 1); editor.value.addPoint(v, 11); }); watch(editor.value.mouseBrush, (v) => { @@ -44,4 +45,4 @@ watch(editor.value.mouseBrush, (v) => { - + diff --git a/src/pages/exception.vue b/src/pages/exception.vue new file mode 100644 index 0000000..64d6904 --- /dev/null +++ b/src/pages/exception.vue @@ -0,0 +1,10 @@ + + + + + diff --git a/src/services/editor.service.ts b/src/services/editor.service.ts index 06efffe..d7bfe58 100644 --- a/src/services/editor.service.ts +++ b/src/services/editor.service.ts @@ -1,6 +1,6 @@ import { EDITOR_CONFIG, MapAreaType, type MapPen, MapPointType } from '@api/map'; import sTheme from '@core/theme.service'; -import { EditType, LockState, Meta2d } from '@meta2d/core'; +import { CanvasLayer, EditType, LockState, Meta2d } from '@meta2d/core'; import { useObservable } from '@vueuse/rxjs'; import { cloneDeep, get, pick } from 'lodash-es'; import { debounceTime, filter, map, Subject, switchMap } from 'rxjs'; @@ -44,13 +44,19 @@ export class EditorService extends Meta2d { ), ); + public override find(target: string): MapPen[] { + return super.find(target); + } + //#region 点位 public async addPoint(p: Point, type = MapPointType.普通点): Promise { const pen: MapPen = { ...p, ...this.#mapPoint(type), + ...this.#mapPointImage(type), name: 'point', - text: 'POINT', + tags: ['point', `point-${type}`], + label: 'POINT', point: { type }, }; const { x, y, width, height } = this.getPenRect(pen); @@ -60,13 +66,17 @@ export class EditorService extends Meta2d { this.pushHistory({ type: EditType.Add, pens: [cloneDeep(pen)] }); } - #mapPoint(type: MapPointType): Required> { - const theme = this.data().theme; + #mapPoint(type: MapPointType): Required> { const width = type < 10 ? 24 : 48; const height = type < 10 ? 24 : 60; const lineWidth = type < 10 ? 2 : 3; + const iconSize = type < 10 ? 4 : 10; + return { width, height, lineWidth, iconSize }; + } + #mapPointImage(type: MapPointType): Required> { + const theme = this.data().theme; const image = type < 10 ? '' : `/point/${type}-${theme}.png`; - return { width, height, lineWidth, image }; + return { image, canvasLayer: CanvasLayer.CanvasMain }; } //#endregion @@ -81,6 +91,7 @@ export class EditorService extends Meta2d { if (w * scale < 50 || h * scale < 60) return; const pen: MapPen = { name: 'area', + tags: ['area', `area-${type}`], x: Math.min(p1.x, p2.x), y: Math.min(p1.y, p2.y), width: w, @@ -103,14 +114,31 @@ export class EditorService extends Meta2d { watch( () => sTheme.theme, - (v) => this.setTheme(v), + (v) => this.#load(v), { immediate: true }, ); } + #load(theme?: string): void { + if (theme) { + this.setTheme(theme); + } + + this.find('point').forEach((pen) => { + if (!pen.point?.type) return; + if (pen.point.type < 10) return; + this.canvas.updateValue(pen, this.#mapPointImage(pen.point.type)); + }); + this.render(); + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any #listen(e: unknown, v: any) { switch (e) { + case 'opened': + this.#load(); + break; + case 'click': case 'mousedown': case 'mouseup': @@ -132,8 +160,8 @@ export class EditorService extends Meta2d { //#region 绘制函数 function drawPoint(ctx: CanvasRenderingContext2D, pen: MapPen): void { const theme = sTheme.editor; - const active = pen.calculative?.active; - const { x = 0, y = 0, width = 0, height = 0 } = pen.calculative?.worldRect ?? {}; + const { active, iconSize: r = 0, fontSize = 14, lineHeight = 1.5, fontFamily } = pen.calculative ?? {}; + const { x = 0, y = 0, width: w = 0, height: h = 0 } = pen.calculative?.worldRect ?? {}; const { type } = pen.point ?? {}; const { label = '' } = pen ?? {}; @@ -143,28 +171,55 @@ function drawPoint(ctx: CanvasRenderingContext2D, pen: MapPen): void { case MapPointType.等待点: case MapPointType.避让点: case MapPointType.临时避让点: - ctx.lineWidth = 2; + ctx.beginPath(); + ctx.moveTo(x + w / 2 - r, y + r); + ctx.arcTo(x + w / 2, y, x + w - r, y + h / 2 - r, r); + ctx.arcTo(x + w, y + h / 2, x + w / 2 + r, y + h - r, r); + ctx.arcTo(x + w / 2, y + h, x + r, y + h / 2 + r, r); + ctx.arcTo(x, y + h / 2, x + r, y + h / 2 - r, r); + ctx.closePath(); + ctx.fillStyle = get(theme, `point-s.fill-${type}`) ?? ''; + ctx.fill(); + ctx.strokeStyle = get(theme, active ? 'point-s.strokeActive' : 'point-s.stroke') ?? ''; + if (type === MapPointType.临时避让点) { + ctx.lineCap = 'round'; + ctx.beginPath(); + ctx.moveTo(x + 0.66 * r, y + h / 2 - 0.66 * r); + ctx.lineTo(x + r, y + h / 2 - r); + ctx.moveTo(x + w / 2 - 0.66 * r, y + 0.66 * r); + ctx.lineTo(x + w / 2 - r, y + r); + ctx.moveTo(x + w / 2 + 0.66 * r, y + 0.66 * r); + ctx.lineTo(x + w / 2 + r, y + r); + ctx.moveTo(x + w - 0.66 * r, y + h / 2 - 0.66 * r); + ctx.lineTo(x + w - r, y + h / 2 - r); + ctx.moveTo(x + w - 0.66 * r, y + h / 2 + 0.66 * r); + ctx.lineTo(x + w - r, y + h / 2 + r); + ctx.moveTo(x + w / 2 + 0.66 * r, y + h - 0.66 * r); + ctx.lineTo(x + w / 2 + r, y + h - r); + ctx.moveTo(x + w / 2 - 0.66 * r, y + h - 0.66 * r); + ctx.lineTo(x + w / 2 - r, y + h - r); + ctx.moveTo(x + 0.66 * r, y + h / 2 + 0.66 * r); + ctx.lineTo(x + r, y + h / 2 + r); + } + ctx.stroke(); break; case MapPointType.电梯点: case MapPointType.自动门点: case MapPointType.充电点: case MapPointType.停靠点: case MapPointType.动作点: - ctx.rect(x, y, width, height); - // ctx.fillStyle = get(theme, 'point-l.fill') ?? ''; - // ctx.fill(); + ctx.roundRect(x, y, w, h, r); ctx.strokeStyle = get(theme, active ? 'point-l.strokeActive' : 'point-l.stroke') ?? ''; ctx.stroke(); break; - default: break; } ctx.fillStyle = get(theme, 'color') ?? ''; - ctx.font = '14px/20px system-ui'; + ctx.font = `${fontSize}px/${lineHeight} ${fontFamily}`; ctx.textAlign = 'center'; - ctx.textBaseline = 'middle'; - ctx.fillText(label, x + width / 2, y - 10); + ctx.textBaseline = 'top'; + ctx.fillText(label, x + w / 2, y - fontSize * lineHeight); ctx.restore(); } function anchorPoint(pen: MapPen): void { diff --git a/src/services/router.ts b/src/services/router.ts index b776985..151a226 100644 --- a/src/services/router.ts +++ b/src/services/router.ts @@ -1,7 +1,12 @@ import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router'; export const ROUTES = Object.freeze([ - { path: '/:pathMatch(.*)*', redirect: '/' }, + { path: '/:pathMatch(.*)*', redirect: '/exception/404' }, + { + path: '/exception/:code', + props: true, + component: () => import('@/exception.vue'), + }, { path: '/scene-editor/:id', props: true, diff --git a/src/services/theme.service.ts b/src/services/theme.service.ts index 6382936..557125b 100644 --- a/src/services/theme.service.ts +++ b/src/services/theme.service.ts @@ -29,7 +29,7 @@ class ThemeService { public get ant(): AntdTheme { switch (this.#theme.value) { case Theme.Dark: - return { algorithm: theme.darkAlgorithm }; + return THEME_MAP[`antd-${this.#theme.value}`] ?? {}; case Theme.Light: default: return { algorithm: theme.defaultAlgorithm };