LsS4S?Xdp9=kJDl$x
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
Eg4|-?Z2$lO
literal 0
HcmV?d00001
diff --git a/static/tabbar/history.png b/static/tabbar/history.png
new file mode 100644
index 0000000000000000000000000000000000000000..b1a30e50782af995b708fd773371b79de72a27fd
GIT binary patch
literal 1065
zcmV+^1lIeBP)Px&<4Ht8RA@u(n%iy@Nf3tr8iNfXfjbTtAV6?IW->kycmRZuKmsH}E*2!jE++|A
zt7UnCyZ{Ok2MNWw;0m4qB!qYXNSxTrSO|$MU=bh-3m6CDY{mthjUkvByJu{VP2|3`
zs;ld(zq+QU$AkqoXo2yd1=Q?{R;>^-Q^H6eX0{4jySlCu5xarz>+4hY_Vga|I=^(S
zs(}(o;|K`XgkuHeX6mL;J6pVJd3&{r6@>N=@db;$|G4%v=Jb@gOv`3c*7J-q{9{;e34tg14l
zSQDTkRB6`1JQ&rr6GbS|Kt>)Iae(RqGgtC5+;TQ{*)Ku~4OX&RPfQ#UFw0Sks^Ol!Gb@
zG@LRn67aj1#p^eRF2;2A57%w`-sq?rpg^)wW#$yHC_js>@b*Z=w6k$kXgHbbCsO{b
zU#7i#CZIp6Yk#={N+b;f1l9Ypb)3mCV_{8m1vH#8vJ$Pij!`?i7A<|Nt}S;3lt>w_
zUIY9li|Lx}c5&Q8EueW4t>|dSn$@ci3I_3MY6{~oUm-X7v8E#WrqHssHf-Lw9z@^7
zXXaU`iPvvx2IU*j=8YTBzO2nQ@HhXyMP~d31YotpH=wY(1&X3L#+#d*#MsjeEX%5j
z$v2>ASLH`netH^XPo7~apZ5&aR6v4aX2!y!$72w1UPjXa35a*uEdG9)@xp_q1QPow
zm44U)5*cVph2CegvmMXNXgZ)7YpyBe7eG_^soHi#>-_H6Q(8{q!74hNP^g;WTgjC@
z`n-LI%=7V|>*yoSaho>S98O8iU+l980r&p@+YV_k^q+F4hZB=?g^EkKJ#0dB~B
zwzF1bSv(Wj77iP(fQ0c#%DBY98QDVc!;XN0XYU|#0M{>K=E+6({|64E+7q5I#GNt^&G9lMA`p3)C@=>riPf*HOq}4Y5_GO
j>u%O;DdZ+wjj;U;VrbYzmTLG700000NkvXXu0mjfh`Q>$
literal 0
HcmV?d00001
diff --git a/static/tabbar/history_active.png b/static/tabbar/history_active.png
new file mode 100644
index 0000000000000000000000000000000000000000..caed26c2e2ccca8f85476ccb9c96ee0b0d2e200d
GIT binary patch
literal 1784
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
literal 0
HcmV?d00001
diff --git a/static/tabbar/home_active.png b/static/tabbar/home_active.png
new file mode 100644
index 0000000000000000000000000000000000000000..6466d916d89fcbdc28e839f10204e5112d23a6b0
GIT binary patch
literal 2056
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
DIn3cX
literal 0
HcmV?d00001
diff --git a/static/tabbar/message_active.png b/static/tabbar/message_active.png
new file mode 100644
index 0000000000000000000000000000000000000000..bb7b6347fbdf1456706bf95118a348308a1b7e76
GIT binary patch
literal 2057
zcmV+k2=@1hP)Px+!%0LzRA@u(n175MWf{l6@65Zmw^xb;0ilIz+xszBs`ZizBnWCMD2b%4#Wtoi
z&CRtOTFy!XQhRN=t5gb+wgO5n?JdTHifGl;e?$>c{{ZVHwL*@&>!sLMTPeN%$Q_;8
znc4Tzncdl)*`2+8_qx|Kg!yZC=6Rp@`ONdY&-{^|8_E<
zCI#r*rxrIe&JNgu$8F-UNremL{TAN;F-wiLynM}$;c7!o4$#>pzjlPWs02&~jMU%!
zar#q>FL|JjGmGaD#SYlSnVT6mcrQDd%w%D_@}m^cvj6%g4ptMY>KR&dX6Y{-p)Sc}
zfx{{Q@ypL$Q#SbCz8kvlxnzOvKfP=&pdPe@s`x-2fCuGgD3;5VMO@gnGVksB&bO)s
zRn-i&k1YSWP0G@I@P3B!<>taUaPRx&r@k~i>yc%b98l}X@;M5WH!Z=H+}a6c#?Mj^
z#=9p{LVWVS4G;BK1FC8nYCW~$cMkC{g-a~l2;9by-HQSx=-IsdUc&=lzGQ$}M^4T;{{z$51Ty`ym%gu$!GzJeQe+d8w2w;w3cL7Z4cp1_}>?lA(0RC$7)GpM2
z<7DB0BB1TYZJ!fDdC`V?ZKfOw7jndU2$WQ)WqS%CpyP6SE;2LaUVh>8(*%6Y)bv+_
z4?;jYjaz5@f0uvL2ERNYBt!DWEgNr_&qp~DXa0+DH`Z#vpO(4Lq
zg3f2n65Me}*=#`l5h?L2Y=?KIiQQM}LMdlYpg~h>(;|U3jo$SOTkv~=drDq&70Cah
zOoSy(8vOBNv)67222?lLyM~DU5P(`PQ2FPy*U;K>iak_v8^*q}Amzkf$?e{yRC3hX
z$tnbYY^p|`eriU?@xs7r29gUEU=IW8QTwlQzX3b`^1^
z2v;C%Ck1fp(G8nys9Oq8Z+v0uWhMaQPACJE7)&k$;YArB0^4kA
zt=}tWD+S~_X*trp&mw+zl-wzVkpYSi@2*!I<<9`7l?xKUK10(NO4!MtZO=Wn^;4Fu
z9t?fRWjmcinKBDrMpLT-#waR?ME|Z^ps4#~+jbi2JWE^oD5s&SoBd>WD2A_uD9U
zU>F7C+7i;UOl|c$MH_4X?nR2Cyimc$deqSLkITTgHqs^M8c#p8^G^===l!l%3dRFs
z^nJ6btuq+NM5GT9UNf8ZFH8#1$A+KXZ>81GxGG{i7;kd-3lrF6D%f4?uqj~F$$(X|
zfd%aTZfN>Vvg0bs(3OMFjo9EUCwUA(DbY1Oe-k4y8fQ)R8={Ckzq2)7WTCB
zbJ|bHKuKq4%FwPmgiwB8!8?$dU&=-Zc4ul%>mOu{rGXNI$p=B$F5|T7HVo^GCVhvD
zUumG)f#-KKP@9a?YTFQ4uc@_4H56%}#M{X?z;JW5gO&0}_?ywJ-y&lx4OBajJjZ~`
zWt>*qhJbUXre7iBR}P545`(=Cz(QxXG7}JB0Q9enE&Bum5;EfoY|@6NbD42+Kmck7
zk^>BAl5y(V5bzd2+sr9be}x;C8s4~LFC}WdU5mj+4lw^%KQA+BkxgGuUE;Eu4v<(2mH~6mtqJH!#n~pzY&B*5
zRtDsI?dyrv#FcsmVWsw-cn4i2N=r5h-;RjI`+H{-lp4#h4@qY_Fwew*Dh>1^+J6Xi
n5nuL%rur~L6MAhIanSz&a&$+4a5#5$00000NkvXXu0mjfuAc%~
literal 0
HcmV?d00001
diff --git a/static/tabbar/my.png b/static/tabbar/my.png
new file mode 100644
index 0000000000000000000000000000000000000000..8a649a89e70f8b0814e3e38172beb611d7add37b
GIT binary patch
literal 826
zcmV-A1I7G_P)Px%^hrcPRA@u(m_29{VHn5%PcEi*5SL7`OQE9SE_d{rLFyn5g0|qt?jm9btLWsQ
zOTo!S3RMIP3gXm3si5MZQ#a|Q_Yri`B^Cuch=qQb+#@GsGRb|tNzQm#^L+iD|MNb1
z-w+1uLj%Tx6e#J6rV9O+3N0-yNn?lPX(F6u@DVT
zEtku`5(nfJ6ykwb1LKyiDNjUzG-JeG+pUWE>j@4j0GtJ3otV}DEN^Z8cs4mXxg`=t
z_{fPaE=s(vC={g-Q9dbo%nZJWF7K2}A
zxv{KiS}knMP(X%Z6eydUW8eaSY}jNW?dt?Q=KAiOuIuYTeFFm-rg@r4dP=~)put7h
zG4PYPabDN77eV3$0y6CCRWQ%T`2#UXF&%7N5M9?x@`7I+Um#Bzko3HdFii#*+&Jf_
zR7W81%y2gMvDahPPK7_?SKmF{=}dJ5s#wlL1}^!@+{^C?SR7ZCnRYqb0(q;sLDJ_Q
zY_qWas7u@!ZMV|f0Dvy(lnz4tlMt@>Dn=
z)2@N&K=@=m@L>L;Yo(D;Ko!f`j(eTy7MgcW8dsIQp@0m_;cgWqBCf6~EsslwGn4{}
zXnf!psX~EUl`uo!%W1;u^(`j_@@-L{4N`^rEP!wN-$p(hM4IbQQvd(}07*qoM6N<$
Ef>HHzApigX
literal 0
HcmV?d00001
diff --git a/static/tabbar/my_active.png b/static/tabbar/my_active.png
new file mode 100644
index 0000000000000000000000000000000000000000..e2fc74fa76eb2b9c323ba367ce4b507c2555a734
GIT binary patch
literal 1276
zcmVPx(wn;=mRA@u(nNMgORUF5EZ{FMd0jnPNVhl(inn@cJsfS<>C5LFuLal}NP=uOY
z8o@@RJyb|hYFmYXmY^2VUYXLkR-q$0TL5nfB*yS*M-lVKNOJTeaYp)`L$*zF7lLnC-=-Gk~pg)A9DcgpuK>d
z_le?r7p4d*Ko_EOfKL58Id3v?+CZUrFpeS)Py!6(Anj*gsiHcbQj~zs06LR<_P9aH
zLWv@dIxfHlr2@)1s&NNe>*-J48k~(csOM(xbHK$4
zF6Y%wsX^EiAT29ipf}g|E=uBaPOX$E5CRkUU9jFfHFMOHgwezC)zGo^{Z|Z2?DDO-
ztoWTZ$0>Ms{qfXuEj_5F1q$Rz#0xb0&%qUmVyK!G7c9GUJ@V7eH3b{Se&mVA3p8{0
zPywiHkt_hXX$TuTf}o-Z+-nRd&vX6o=xcgxox)3Nhp$MB?<$%?VG#{W!IHYc1bE80
z0BdG_zD((gKnDn@&Np(sp&nj0`32MW&*9mWvB36
z%dXn?xM1ZlHUt8^qO0joVg&*MHudM+RRhJ&(ly340SBNo1uMY-gTM0TeZ#QhU@l%D
z0GRyajok+JT+;2<$6GXgSE~aC0ElQt8_g`W0uxCMc>#?7e&V=9vEbKIV4d+GD=K5d
z0G!v)Q7+NKS6WaF7mr;OtW3+7B6@$5OfIs-;L`qt{`z&DN05AXq0vOz806!7XMeXkT
z*YNbQe3USer(D#*H8Wm&6lx}th_2}ZMKqCZ8>T6RhOaLSN-mx^F_AKmKQ2Ke4dlI4
z)|)jFH38@h;0^)&OpLx$G`yI9;>cE0EBfl*S5W-1miD`ql2yPi#fe8uPB*wl_
z2v6QqGq>vnt6QNREAQ=Px_R!KxbRCr$PU3+*`)wTbvnas?YydVh=1M&zF2}%$|sn1$b>Z`tcDOliE9+oSh
zA_c*#QcxZ$f+%Re0@|XzVn40Lx2+;xtG#L!i%0_DkqCrGOhQO9bIwfWto!YgM<>s7
z&dfP8Q=R=!zAv-(T5Ip$*{`+NUW<_6rM9-VSBfMRaxgRu4&(te5R6r00vsD
zV<`w*p{nnzlC(9AsN7=yQL#%1KxA1S!bFpZaWex$8b9`!6eeId6J93f=Ojtm9TTZt
z2#Hn0+o^E!&@noR|Z`%%>_!a2^QL
zm^n2bjn;#M3Vuyt!#viyaHg}M1&QRB<-_N
zP77<>0b%A0MF}ou@N57nv1pVHG8zcQ+%CoA$(KOyvd1;mOZ1J^dRPvKEH_-oq&^GgY^#+`
zD1Jm$#Ex4fDdklw^|A~QW_J0N;KKyID*?8!R`yX>yqH0cdp)juh$v`vf(JfNp-^F@Fs0pa*
zwV7V;hmo`|B0$8*NMYWV1f%0F7oao{{V0-=Vj7UfH3J_dr>U;Le=&VI2p5`NQ%nJ(
z?WR&(e@ialh9{%Fp@!f^W_DkO0TJg6Sq^;oz1`Xx#-I%$;}c18Uu^W8Vi*vg99Tu*
zIg#r1eXhr#)v1#EZXm$u#1M(5N=FM^K8)*pbLoK?;ik%
z^NV=crYeIc@OIS)*joKDzN+7iAUEi>r^DY}l!C&vAsCZ&0j|ux1Uatm5%Gzt5>XY@
z(Ai$Ex2!8Zx`4=X;IFZ^+J0X96*e7x1s|RK93c)x)emheJIRR)Ge=?aDK}zNMxmv=
z^_U4Ou_U?2MhuA0r;H~DUeFU{)$jkP-GOz7pU0PVyR2f_C7%)LXJBUEi8v=?cueF8
zA*^CTYN}^*X97DNA>yV_RszKUY`VuedOt_${vM<4$epAuY6_Xo-
za>?T^=`_tNLrz->{_YNz{ev;{ryr&~#@S9vCniW3w-^T@M1SmO9yW
zbqI*&kN^^+!?ru{fEvVO2RGo46>r$y0cHe@>v;|4_L~N`!)2zLS=t5y7j)z}(IFsy
zzq}qq)67aSN?#xHVb0!%@LBB+qg7%`cW%aTtUm2Nq&aQ$QexiV^-9y*Hmn^W!f#4e
z0>b6R7FV6B;0equS%hL=OuT9$2C^VEAL|A$Mz(!htSQ1nGN8!)!`)U}0V2zRnG9ZQ$LLsI_H@E6;6~di7W#z){>v!2DLMkp
zk|g)K=1Q#q@%xoeKp1U`qXA;EwVl6zg#pUMC3$4f0(-W^j8DB@Pm6O%3n1E)08o+D
z21Ie_yJ_bP)P;Oe^)`Vt1EG@~8ZY6h9?K%mDSsOFv>k^>Ch*Yarw}cG_!Z?LF#g->
zM&7&s(TGmqZgSzgZXEVkE3zpC+u4_4Yk+#$t7>A7zrHFw7E2RnB)b!o=nqryZOvAWd*I+`g>r7c?#Wwo+
zV_WcM<@>gdp7lePS#J9xpjeVTLt6mRo{=d5@eV@Q`fH|lZ!Mm0%20TI=Gj=BcUM%?
z!j8IPEG=7$J^oTNsv4#h2FYg&9x+UBkdRf6`&99~P6NR2S0;k+oWaV5$b<=9oH>k^
z8GUZSZMhRb6#X~h56QT{bQRvK{@AE^Q*`2NV!7#_)k$8j_xVOZ6lEhAQ%q^4Lwsk+
z68vw?r-oQg&mE83`%W}OYm|tYao>T*@MhIEqg4#k{jl3;tQq`(VR}P^glD`S&(uah
zWaWUBuU*AW-xWLl)6nJ8nC=(gvC}$UXJl1@Slk`t=(0^>M0lO;uV}?#bo%av*ikR+
zq}CO2$@R|g-Vd`O=x|knbJPj&5n$I=oczmaaZ#2+mGF
z6B`R2Hd95P*6FyMd_MV3a?s=Y)W#@;cgQ8%#~X4;czgKo(A(Xk9b@51GVbeHC=WCa
z+?DzF;0zN1P74hN3nc(4j$fq$rMEyTxSWqE4wgE+t2NXu9uGOJ|0lB2bAJj=zR&C;ktL8pMe7q3G$(*480^NI_M@
z3GHpqgRbA?>WblQA`ST-1D;88EPgtTre(Ut^
z5WA_T%m08^zkL_i_P7i;_qY=Mq})!c)`sfwUiC-#-I143rW`gRqC=W%b1uV@JPVyU
z8K070R)i5KKVq%gRGeHiS95C9D>w8Qi$w#YpDB+8zQw$K%hAu1i+lRdKxRt1p6Hg}
z#cuB9inp=q&_;+Yw%H<_?=}s6%xtx;==X^!tBQautGHghV+xK0^dlhsAmc3jX2{a0
z#0mrBt;O>&srOB|vFDE?<|Veq;#%2=-r+)W-M#SU@Mj{H+qNPD)g;SGJp-2A=KpB>
z1k{A|gB=J5g7-)KkG5Nhq=<$3wmtXaitHcar#-KVghi`5hm<3jTD$0-(YCVD@3e1?LJ)E{k({zyNoH2MXul0d2{7T@3p=(f()_OlvRKFLu6p7de`o*3p
zO9@n3`PAT=9aB(lU{P;wuDF)nIAjHerWt?czUI)gI3w+JjLo{RU9Tx>0L#jr(%y{R
zaq2I$-B)-K*8=OyU&J|?h1waSqtSWe&KcVK6TQ;M-3xD6xTr&f>xkF3H@vaJ?D4c_
zKr|L!@s5(kxVzs}?NN>$W#RruwRb6c#hz`iU-^VA^fWOu2ZuLUT-`3qn}>_KpQG0g
z5YvwE0uiThJBm@4C94mHEDnb8GM#kPkzy;nZNv*mX=6ffOFMJVBFyVQ-L?^8)G=dr
z-^rL_wdo{Y#>I{R8Jl$x9?4(O@{`z2b#ytktZW@dXO6(-9jqZ%jF=mC{t{)fzDdO%
z<6<1m?`=D8#i04xK~J2(#gn!dD_+Mb?j9&iD?q-tzvldqLMfW@P`o!3^i~()y)t2!
zzDdV6^LsomsKPtbMJ~Kr_*=YE@fV02$9lDE$2!U3!5f7eE%#3U)xKqhoFiU%q((cWGrH`QZn&lQb-1a=
zmB?~+9#>76?wdU%tAi(T`9CLWjuJ*nOk7EYBC?zq&eldcMUO^o4hm8SVPyK5+G##3
zr8~r#=4h}2!gwgADDhlvPQNMI-(M8Z)Bb0q#KhUUX&p(Z=LkkRCt4Z-oUjOsfHj+s
zzpl$J#?KKF`@xQGZ`n)`^9MWHC`mqP>lD_QKWS@RN0N^|J3=IGk3O}mHy$bZEIJI8
zxIT++8YRiV0Zo9!J#c`~BNpIy{pVznI?bAJSa+pY9&G}^@PTp(q)YouOgH{B7^
zxWG4D#|Q~GZ$tD(JKPLibExrMz7owvN4R=^8?1(}O{j74=uF3E&0rV+6(p-ZzW$&^P%LE)nW
zn^PV&tCCC#)-@op~r
zdKEzYQ?Is+lw@+^#7R!v3`#P6cLJsF4xdG}jBY9POgwB~MmMCE&=FOs4Lrq2<~1|&
z44Y2OFcq2Ih@2Z@olMM(j?vHxt1WYAnqJ1WNMzUoNV6hMNyS9C9NY6)Mbh{P>XfsJ
zxm_joihyUUDz*aBWCP1kl;C0p&$cs#QnVeRQ@?>gPkKDAMV%${vP!<~fP`(2^O>;#
zL?W7{E!lgl>Xa}(0WfbO!itXaMcE)P_V*jY?@LjF^FWwpN8%VOI!Pp20b_&5<9f7h
zN+K)xcf})SBc!bon%k;d8qds=K{z*_mtRe~i3}K@5z(eVK;9gl^~P=x!uiJykZ>im
z+$BVlh;cImLt+RH6R?{JFB9`~%{e?`2|!y}2?0o}bBxH;AP2_4flI*{V`T{RCOM@b
zY=w&VRmr_oWF&|u00|FBTLrau^paG_!O$=`kO$B}V&sC5!$7tJ@G#&J^$1W@Kp~(C
yj7laP0k{+@4v@>avq6@>%E-vj4+t4Yg#I5L9cAM^b&@v#0000Px)8c9S!RA@u(nn7^$?ERX^#
ziYl={Vne026c$u%p-QX9o;UL@+&6EWvEz_9QX&Up$$EO8J7edZd(OEYM>s_fy}vbv
z@f*M}_9jk0L?~Bk7NsG|k8=Iyqm|A(;o`L>Kp*^Y4Qbyyxa;>rO%*MEma8A%KVe)C
z{dQ|hKQ0sd%E|yDslSFx~U)$psK>}-;aTFG}DS$R(R)$uA&f6-E^zA6;3>^^fa-;;Zdy+
zJV>{;dG893#tQOY-Jn)0R6Ig=PP7{Fsa9nJ;UY)@Y4RySyH#xV$6nw6A+%`vPSE^A
zR*RE>O+;u5Y=gc4sZkAx)IdP!_UU!3J|J4-275auu{+0(qum-cP`Vm%HL(fZN}$z1
zRo1lAfGcZ447gEE+1PvT@a88I5z&r-yLU&lk1BLhF}~=D(@a295yewf8GHlWfG_ik
zr!nvf4{@G=o{&UN23#}XiIhwTJ&8sD74TYW1S7yk&!|RJ0dgMn{NbEIUV^@y5fHUS
zj0ARozaRs?NI(MCfbNgyeGj-8F?KwItZkr_nm|W_0WUGHMNL}=obD2EVN~;UJ0Rnl
zcQ?**3*PI2z3^0&q3K&>WPr#xDwV90GlC0xnwxpQ?%z`ojdo1V(1egLW3)0gvzzB$s
zXBp6Y{9*>Iq5!j?M8JXtEz1D2pdkTw9*2V!P>ej9v!GXib+!S$EQAeA>vk7A1uTZ}
zY@b7TsDRFO+p6bPyyNVhZ$g9pOi5S;k=)-pyd7YAw097BZP3D
z0mBd$`7`rp&^{q-$BKn1XfXq3N-ztuX=peFH8qpABjDL)EjMmVmyDrh
zH4EWVJgxaZo}#S?c??Zp%D<1HdqX&fah{5X7L+>Qz)w@q25>PcKr93LDd-4e=v)Zf
zc&ghtdA^4L#e9Bu3^fAg_GT|_mkBchT#ZdZa|#%Yp*Hr&wi9Y
i22hW3$^YWNrTh(YBM+#2u1-k+0000IP)Px&F-b&0R9Hvln9GV3Nfd^^6O~%!!qp7ZF1)mY<6>|Yf~YGMTnPFczJ)87`Xau8
z3qf3nir_++%`9v$ptjnerO?$8nQ`<)Ub?C>`{s?pDky>^BP!2V|9}3BOktCcF5MZx
zU>~r6V=o%}X}Y*IBA6h=SQ3U&Mcght|Ag(w&!nRJP6V`XMLS2&b=UC{ePB$
zTM+v6!2(WCAY?mILdl8pSdN@t-qE^WGby?FB5A?s_ZQn*L6rfdRDJt>3pJGSeF!jhw-JG0cYCFsis{}T03XWdRSqFzKf
zi*PW_QC=Y2#mOzAG~HsEi3U4l&ipz4eEG`a1C`U?enU{
zwcE3zs_4@FMI6Ulg_cU**aWg#qIm*!1T1;c0&Fz<@)2~1hzA0KM>T+WG|dl)dfeEt
zos$^S8at1cW7I(AJmNet59LUp(7^7@Q>+DC<_R(2`kpMeYp$~Y%t%DkKu_WLtF1`9
z3|!fkqm&^|hD0rp3bF)U1%2NFO#lW|flGBTE(KXTM_b&i@T0k1FBOKcnXj$~zMp08X0h=muxm3prsm5B-tw6^W
zP2dJtDQXIfL7Jk`)5|=$hDOm{8t4bl=MY#t=S830yM#E`q3F%dKcJIb;#c)wp)Ezt
z%C8$6x+&|X;$vyy^k=E57>FI#wYf>j3NVHe)V|J_7B=fg>Q47)qpVri(sw*{bI+(KK|d^bIcj0_
zy|))p+sv=vq`JLOpjwB~2Q+?aQdhA)oCKXXHd_{D&o-dWW2rl#=-BPW(l(ENB6YiO
zFLSbCn42x&Ty5$T>^wZCHBXZB@ZjCR&cmye26i4^j*V|+f2Y@-UjRw!44D~Tt8)MV
N002ovPDHLkV1kT*txx~}
literal 0
HcmV?d00001
diff --git a/static/wechat/static/tag_tab1.png b/static/wechat/static/tag_tab1.png
new file mode 100644
index 0000000000000000000000000000000000000000..a5a867c1113545b3b0f31801a99dd1d15d62a043
GIT binary patch
literal 919
zcmV;I18Dq-P)Px&QAtEWR9Hvln7xi1MG%0$>Y46ao8ttsEtA+_2P7Z|mMokhOAh=7eh~a^Bw(we*4yZ-8{s-79)E&Axw
z-4TpF04@`F7tLF~eF+mX{{s6k{!^~q885?vJEI^Hq=&_N+<>FK7;aUj)AP
zz`FPNGC^-5)Tff8G-UZnuHW7tes8UT_1O>Ckm)BUTV0k4RkZq5KKkrw7qPa$Znny|
z{y%JosLC|_*qL5SVDDKO-8pp`FBMILj(4r6*Aw`U$2Z9O;llj~t;u>1<#U9q9;3WK
z_>Lft$kHtSo;;T;w|`zcV7D8#?k+54$rn(*0N40pf|OLT+BfaS=n
z|BYgpaM2Ug0c&sgy<+@iX5}{|e7PX-;0Sm-M*fb8k!@tga2;CHUc#N>0_}zeC2ghZ
zF&10O+@Y70^qgV21Zv5t2~zpmmh=U?i9DIsBMu&g
zu%z9r!TOZm26o)ASPyqodWFZ*8xDdq2|JS;k24`T#Xr$ay0!Ec+q8!Vhu);e!~RKj
tlU@My(3|v%r-$C8mw3bBzKYkh{{cLM>S!1~Q04#t002ovPDHLkV1lB%z9|3z
literal 0
HcmV?d00001
diff --git a/uni.scss b/uni.scss
new file mode 100644
index 0000000..b9249e9
--- /dev/null
+++ b/uni.scss
@@ -0,0 +1,76 @@
+/**
+ * 这里是uni-app内置的常用样式变量
+ *
+ * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
+ * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
+ *
+ */
+
+/**
+ * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
+ *
+ * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
+ */
+
+/* 颜色变量 */
+
+/* 行为相关颜色 */
+$uni-color-primary: #007aff;
+$uni-color-success: #4cd964;
+$uni-color-warning: #f0ad4e;
+$uni-color-error: #dd524d;
+
+/* 文字基本颜色 */
+$uni-text-color:#333;//基本色
+$uni-text-color-inverse:#fff;//反色
+$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
+$uni-text-color-placeholder: #808080;
+$uni-text-color-disable:#c0c0c0;
+
+/* 背景颜色 */
+$uni-bg-color:#ffffff;
+$uni-bg-color-grey:#f8f8f8;
+$uni-bg-color-hover:#f1f1f1;//点击状态颜色
+$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
+
+/* 边框颜色 */
+$uni-border-color:#c8c7cc;
+
+/* 尺寸变量 */
+
+/* 文字尺寸 */
+$uni-font-size-sm:12px;
+$uni-font-size-base:14px;
+$uni-font-size-lg:16px;
+
+/* 图片尺寸 */
+$uni-img-size-sm:20px;
+$uni-img-size-base:26px;
+$uni-img-size-lg:40px;
+
+/* Border Radius */
+$uni-border-radius-sm: 2px;
+$uni-border-radius-base: 3px;
+$uni-border-radius-lg: 6px;
+$uni-border-radius-circle: 50%;
+
+/* 水平间距 */
+$uni-spacing-row-sm: 5px;
+$uni-spacing-row-base: 10px;
+$uni-spacing-row-lg: 15px;
+
+/* 垂直间距 */
+$uni-spacing-col-sm: 4px;
+$uni-spacing-col-base: 8px;
+$uni-spacing-col-lg: 12px;
+
+/* 透明度 */
+$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
+
+/* 文章场景相关 */
+$uni-color-title: #2C405A; // 文章标题颜色
+$uni-font-size-title:20px;
+$uni-color-subtitle: #555555; // 二级标题颜色
+$uni-font-size-subtitle:26px;
+$uni-color-paragraph: #3F536E; // 文章段落颜色
+$uni-font-size-paragraph:15px;
diff --git a/uni_modules/uni-data-picker/changelog.md b/uni_modules/uni-data-picker/changelog.md
new file mode 100644
index 0000000..e095788
--- /dev/null
+++ b/uni_modules/uni-data-picker/changelog.md
@@ -0,0 +1,79 @@
+## 2.0.1(2024-08-22)
+- 修复 uni-app-x v-model 没有更新传入值的 bug
+## 2.0.0(2023-12-11)
+- 新增 支持 uni-app-x
+## 1.1.2(2023-04-11)
+- 修复 更改 modelValue 报错的 bug
+- 修复 v-for 未使用 key 值控制台 warning
+## 1.1.1(2023-02-21)
+- 修复代码合并时引发 value 属性为空时不渲染数据的问题
+## 1.1.0(2023-02-15)
+- 修复 localdata 不支持动态更新的bug
+## 1.0.9(2023-02-15)
+- 修复 localdata 不支持动态更新的bug
+## 1.0.8(2022-09-16)
+- 可以使用 uni-scss 控制主题色
+## 1.0.7(2022-07-06)
+- 优化 pc端图标位置不正确的问题
+## 1.0.6(2022-07-05)
+- 优化 显示样式
+## 1.0.5(2022-07-04)
+- 修复 uni-data-picker 在 uni-forms-item 中宽度不正确的bug
+## 1.0.4(2022-04-19)
+- 修复 字节小程序 本地数据无法选择下一级的Bug
+## 1.0.3(2022-02-25)
+- 修复 nvue 不支持的 v-show 的 bug
+## 1.0.2(2022-02-25)
+- 修复 条件编译 nvue 不支持的 css 样式
+## 1.0.1(2021-11-23)
+- 修复 由上个版本引发的map、v-model等属性不生效的bug
+## 1.0.0(2021-11-19)
+- 优化 组件 UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-data-picker](https://uniapp.dcloud.io/component/uniui/uni-data-picker)
+## 0.4.9(2021-10-28)
+- 修复 VUE2 v-model 概率无效的 bug
+## 0.4.8(2021-10-27)
+- 修复 v-model 概率无效的 bug
+## 0.4.7(2021-10-25)
+- 新增 属性 spaceInfo 服务空间配置 HBuilderX 3.2.11+
+- 修复 树型 uniCloud 数据类型为 int 时报错的 bug
+## 0.4.6(2021-10-19)
+- 修复 非 VUE3 v-model 为 0 时无法选中的 bug
+## 0.4.5(2021-09-26)
+- 新增 清除已选项的功能(通过 clearIcon 属性配置是否显示按钮),同时提供 clear 方法以供调用,二者等效
+- 修复 readonly 为 true 时报错的 bug
+## 0.4.4(2021-09-26)
+- 修复 上一版本造成的 map 属性失效的 bug
+- 新增 ellipsis 属性,支持配置 tab 选项长度过长时是否自动省略
+## 0.4.3(2021-09-24)
+- 修复 某些情况下级联未触发的 bug
+## 0.4.2(2021-09-23)
+- 新增 提供 show 和 hide 方法,开发者可以通过 ref 调用
+- 新增 选项内容过长自动添加省略号
+## 0.4.1(2021-09-15)
+- 新增 map 属性 字段映射,将 text/value 映射到数据中的其他字段
+## 0.4.0(2021-07-13)
+- 组件兼容 vue3,如何创建 vue3 项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 0.3.5(2021-06-04)
+- 修复 无法加载云端数据的问题
+## 0.3.4(2021-05-28)
+- 修复 v-model 无效问题
+- 修复 loaddata 为空数据组时加载时间过长问题
+- 修复 上个版本引出的本地数据无法选择带有 children 的 2 级节点
+## 0.3.3(2021-05-12)
+- 新增 组件示例地址
+## 0.3.2(2021-04-22)
+- 修复 非树形数据有 where 属性查询报错的问题
+## 0.3.1(2021-04-15)
+- 修复 本地数据概率无法回显时问题
+## 0.3.0(2021-04-07)
+- 新增 支持云端非树形表结构数据
+- 修复 根节点 parent_field 字段等于 null 时选择界面错乱问题
+## 0.2.0(2021-03-15)
+- 修复 nodeclick、popupopened、popupclosed 事件无法触发的问题
+## 0.1.9(2021-03-09)
+- 修复 微信小程序某些情况下无法选择的问题
+## 0.1.8(2021-02-05)
+- 优化 部分样式在 nvue 上的兼容表现
+## 0.1.7(2021-02-05)
+- 调整为 uni_modules 目录规范
diff --git a/uni_modules/uni-data-picker/components/uni-data-picker/keypress.js b/uni_modules/uni-data-picker/components/uni-data-picker/keypress.js
new file mode 100644
index 0000000..6ef26a2
--- /dev/null
+++ b/uni_modules/uni-data-picker/components/uni-data-picker/keypress.js
@@ -0,0 +1,45 @@
+// #ifdef H5
+export default {
+ name: 'Keypress',
+ props: {
+ disable: {
+ type: Boolean,
+ default: false
+ }
+ },
+ mounted () {
+ const keyNames = {
+ esc: ['Esc', 'Escape'],
+ tab: 'Tab',
+ enter: 'Enter',
+ space: [' ', 'Spacebar'],
+ up: ['Up', 'ArrowUp'],
+ left: ['Left', 'ArrowLeft'],
+ right: ['Right', 'ArrowRight'],
+ down: ['Down', 'ArrowDown'],
+ delete: ['Backspace', 'Delete', 'Del']
+ }
+ const listener = ($event) => {
+ if (this.disable) {
+ return
+ }
+ const keyName = Object.keys(keyNames).find(key => {
+ const keyName = $event.key
+ const value = keyNames[key]
+ return value === keyName || (Array.isArray(value) && value.includes(keyName))
+ })
+ if (keyName) {
+ // 避免和其他按键事件冲突
+ setTimeout(() => {
+ this.$emit(keyName, {})
+ }, 0)
+ }
+ }
+ document.addEventListener('keyup', listener)
+ this.$once('hook:beforeDestroy', () => {
+ document.removeEventListener('keyup', listener)
+ })
+ },
+ render: () => {}
+}
+// #endif
diff --git a/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.uvue b/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.uvue
new file mode 100644
index 0000000..dcbfd5f
--- /dev/null
+++ b/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.uvue
@@ -0,0 +1,381 @@
+
+
+
+
+
+ {{error!.errMsg}}
+
+
+
+ {{item[mappingTextName]}}
+ {{split}}
+
+
+
+ {{placeholder}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{popupTitle}}
+
+
+
+
+
+
+
+
+ {{error!.errMsg}}
+
+
+
+
+
+ {{item[mappingTextName]}}
+
+
+
+
+
+
+ {{item[mappingTextName]}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue b/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue
new file mode 100644
index 0000000..179a4e0
--- /dev/null
+++ b/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue
@@ -0,0 +1,551 @@
+
+
+
+
+
+ {{errorMessage}}
+
+
+
+
+
+
+ {{item.text}}{{split}}
+
+
+
+ {{placeholder}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{popupTitle}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js
new file mode 100644
index 0000000..cfae22a
--- /dev/null
+++ b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js
@@ -0,0 +1,622 @@
+export default {
+ props: {
+ localdata: {
+ type: [Array, Object],
+ default () {
+ return []
+ }
+ },
+ spaceInfo: {
+ type: Object,
+ default () {
+ return {}
+ }
+ },
+ collection: {
+ type: String,
+ default: ''
+ },
+ action: {
+ type: String,
+ default: ''
+ },
+ field: {
+ type: String,
+ default: ''
+ },
+ orderby: {
+ type: String,
+ default: ''
+ },
+ where: {
+ type: [String, Object],
+ default: ''
+ },
+ pageData: {
+ type: String,
+ default: 'add'
+ },
+ pageCurrent: {
+ type: Number,
+ default: 1
+ },
+ pageSize: {
+ type: Number,
+ default: 500
+ },
+ getcount: {
+ type: [Boolean, String],
+ default: false
+ },
+ getone: {
+ type: [Boolean, String],
+ default: false
+ },
+ gettree: {
+ type: [Boolean, String],
+ default: false
+ },
+ manual: {
+ type: Boolean,
+ default: false
+ },
+ value: {
+ type: [Array, String, Number],
+ default () {
+ return []
+ }
+ },
+ modelValue: {
+ type: [Array, String, Number],
+ default () {
+ return []
+ }
+ },
+ preload: {
+ type: Boolean,
+ default: false
+ },
+ stepSearh: {
+ type: Boolean,
+ default: true
+ },
+ selfField: {
+ type: String,
+ default: ''
+ },
+ parentField: {
+ type: String,
+ default: ''
+ },
+ multiple: {
+ type: Boolean,
+ default: false
+ },
+ map: {
+ type: Object,
+ default () {
+ return {
+ text: "text",
+ value: "value"
+ }
+ }
+ }
+ },
+ data() {
+ return {
+ loading: false,
+ errorMessage: '',
+ loadMore: {
+ contentdown: '',
+ contentrefresh: '',
+ contentnomore: ''
+ },
+ dataList: [],
+ selected: [],
+ selectedIndex: 0,
+ page: {
+ current: this.pageCurrent,
+ size: this.pageSize,
+ count: 0
+ }
+ }
+ },
+ computed: {
+ isLocalData() {
+ return !this.collection.length;
+ },
+ isCloudData() {
+ return this.collection.length > 0;
+ },
+ isCloudDataList() {
+ return (this.isCloudData && (!this.parentField && !this.selfField));
+ },
+ isCloudDataTree() {
+ return (this.isCloudData && this.parentField && this.selfField);
+ },
+ dataValue() {
+ let isModelValue = Array.isArray(this.modelValue) ? (this.modelValue.length > 0) : (this.modelValue !== null ||
+ this.modelValue !== undefined);
+ return isModelValue ? this.modelValue : this.value;
+ },
+ hasValue() {
+ if (typeof this.dataValue === 'number') {
+ return true
+ }
+ return (this.dataValue != null) && (this.dataValue.length > 0)
+ }
+ },
+ created() {
+ this.$watch(() => {
+ var al = [];
+ ['pageCurrent',
+ 'pageSize',
+ 'spaceInfo',
+ 'value',
+ 'modelValue',
+ 'localdata',
+ 'collection',
+ 'action',
+ 'field',
+ 'orderby',
+ 'where',
+ 'getont',
+ 'getcount',
+ 'gettree'
+ ].forEach(key => {
+ al.push(this[key])
+ });
+ return al
+ }, (newValue, oldValue) => {
+ let needReset = false
+ for (let i = 2; i < newValue.length; i++) {
+ if (newValue[i] != oldValue[i]) {
+ needReset = true
+ break
+ }
+ }
+ if (newValue[0] != oldValue[0]) {
+ this.page.current = this.pageCurrent
+ }
+ this.page.size = this.pageSize
+
+ this.onPropsChange()
+ })
+ this._treeData = []
+ },
+ methods: {
+ onPropsChange() {
+ this._treeData = [];
+ },
+
+ // 填充 pickview 数据
+ async loadData() {
+ if (this.isLocalData) {
+ this.loadLocalData();
+ } else if (this.isCloudDataList) {
+ this.loadCloudDataList();
+ } else if (this.isCloudDataTree) {
+ this.loadCloudDataTree();
+ }
+ },
+
+ // 加载本地数据
+ async loadLocalData() {
+ this._treeData = [];
+ this._extractTree(this.localdata, this._treeData);
+
+ let inputValue = this.dataValue;
+ if (inputValue === undefined) {
+ return;
+ }
+
+ if (Array.isArray(inputValue)) {
+ inputValue = inputValue[inputValue.length - 1];
+ if (typeof inputValue === 'object' && inputValue[this.map.value]) {
+ inputValue = inputValue[this.map.value];
+ }
+ }
+
+ this.selected = this._findNodePath(inputValue, this.localdata);
+ },
+
+ // 加载 Cloud 数据 (单列)
+ async loadCloudDataList() {
+ if (this.loading) {
+ return;
+ }
+ this.loading = true;
+
+ try {
+ let response = await this.getCommand();
+ let responseData = response.result.data;
+
+ this._treeData = responseData;
+
+ this._updateBindData();
+ this._updateSelected();
+
+ this.onDataChange();
+ } catch (e) {
+ this.errorMessage = e;
+ } finally {
+ this.loading = false;
+ }
+ },
+
+ // 加载 Cloud 数据 (树形)
+ async loadCloudDataTree() {
+ if (this.loading) {
+ return;
+ }
+ this.loading = true;
+
+ try {
+ let commandOptions = {
+ field: this._cloudDataPostField(),
+ where: this._cloudDataTreeWhere()
+ };
+ if (this.gettree) {
+ commandOptions.startwith = `${this.selfField}=='${this.dataValue}'`;
+ }
+
+ let response = await this.getCommand(commandOptions);
+ let responseData = response.result.data;
+
+ this._treeData = responseData;
+ this._updateBindData();
+ this._updateSelected();
+
+ this.onDataChange();
+ } catch (e) {
+ this.errorMessage = e;
+ } finally {
+ this.loading = false;
+ }
+ },
+
+ // 加载 Cloud 数据 (节点)
+ async loadCloudDataNode(callback) {
+ if (this.loading) {
+ return;
+ }
+ this.loading = true;
+
+ try {
+ let commandOptions = {
+ field: this._cloudDataPostField(),
+ where: this._cloudDataNodeWhere()
+ };
+
+ let response = await this.getCommand(commandOptions);
+ let responseData = response.result.data;
+
+ callback(responseData);
+ } catch (e) {
+ this.errorMessage = e;
+ } finally {
+ this.loading = false;
+ }
+ },
+
+ // 回显 Cloud 数据
+ getCloudDataValue() {
+ if (this.isCloudDataList) {
+ return this.getCloudDataListValue();
+ }
+
+ if (this.isCloudDataTree) {
+ return this.getCloudDataTreeValue();
+ }
+ },
+
+ // 回显 Cloud 数据 (单列)
+ getCloudDataListValue() {
+ // 根据 field's as value标识匹配 where 条件
+ let where = [];
+ let whereField = this._getForeignKeyByField();
+ if (whereField) {
+ where.push(`${whereField} == '${this.dataValue}'`)
+ }
+
+ where = where.join(' || ');
+
+ if (this.where) {
+ where = `(${this.where}) && (${where})`
+ }
+
+ return this.getCommand({
+ field: this._cloudDataPostField(),
+ where
+ }).then((res) => {
+ this.selected = res.result.data;
+ return res.result.data;
+ });
+ },
+
+ // 回显 Cloud 数据 (树形)
+ getCloudDataTreeValue() {
+ return this.getCommand({
+ field: this._cloudDataPostField(),
+ getTreePath: {
+ startWith: `${this.selfField}=='${this.dataValue}'`
+ }
+ }).then((res) => {
+ let treePath = [];
+ this._extractTreePath(res.result.data, treePath);
+ this.selected = treePath;
+ return treePath;
+ });
+ },
+
+ getCommand(options = {}) {
+ /* eslint-disable no-undef */
+ let db = uniCloud.database(this.spaceInfo)
+
+ const action = options.action || this.action
+ if (action) {
+ db = db.action(action)
+ }
+
+ const collection = options.collection || this.collection
+ db = db.collection(collection)
+
+ const where = options.where || this.where
+ if (!(!where || !Object.keys(where).length)) {
+ db = db.where(where)
+ }
+
+ const field = options.field || this.field
+ if (field) {
+ db = db.field(field)
+ }
+
+ const orderby = options.orderby || this.orderby
+ if (orderby) {
+ db = db.orderBy(orderby)
+ }
+
+ const current = options.pageCurrent !== undefined ? options.pageCurrent : this.page.current
+ const size = options.pageSize !== undefined ? options.pageSize : this.page.size
+ const getCount = options.getcount !== undefined ? options.getcount : this.getcount
+ const getTree = options.gettree !== undefined ? options.gettree : this.gettree
+
+ const getOptions = {
+ getCount,
+ getTree
+ }
+ if (options.getTreePath) {
+ getOptions.getTreePath = options.getTreePath
+ }
+
+ db = db.skip(size * (current - 1)).limit(size).get(getOptions)
+
+ return db
+ },
+
+ _cloudDataPostField() {
+ let fields = [this.field];
+ if (this.parentField) {
+ fields.push(`${this.parentField} as parent_value`);
+ }
+ return fields.join(',');
+ },
+
+ _cloudDataTreeWhere() {
+ let result = []
+ let selected = this.selected
+ let parentField = this.parentField
+ if (parentField) {
+ result.push(`${parentField} == null || ${parentField} == ""`)
+ }
+ if (selected.length) {
+ for (var i = 0; i < selected.length - 1; i++) {
+ result.push(`${parentField} == '${selected[i].value}'`)
+ }
+ }
+
+ let where = []
+ if (this.where) {
+ where.push(`(${this.where})`)
+ }
+
+ if (result.length) {
+ where.push(`(${result.join(' || ')})`)
+ }
+
+ return where.join(' && ')
+ },
+
+ _cloudDataNodeWhere() {
+ let where = []
+ let selected = this.selected;
+ if (selected.length) {
+ where.push(`${this.parentField} == '${selected[selected.length - 1].value}'`);
+ }
+
+ where = where.join(' || ');
+
+ if (this.where) {
+ return `(${this.where}) && (${where})`
+ }
+
+ return where
+ },
+
+ _getWhereByForeignKey() {
+ let result = []
+ let whereField = this._getForeignKeyByField();
+ if (whereField) {
+ result.push(`${whereField} == '${this.dataValue}'`)
+ }
+
+ if (this.where) {
+ return `(${this.where}) && (${result.join(' || ')})`
+ }
+
+ return result.join(' || ')
+ },
+
+ _getForeignKeyByField() {
+ let fields = this.field.split(',');
+ let whereField = null;
+ for (let i = 0; i < fields.length; i++) {
+ const items = fields[i].split('as');
+ if (items.length < 2) {
+ continue;
+ }
+ if (items[1].trim() === 'value') {
+ whereField = items[0].trim();
+ break;
+ }
+ }
+ return whereField;
+ },
+
+ _updateBindData(node) {
+ const {
+ dataList,
+ hasNodes
+ } = this._filterData(this._treeData, this.selected)
+
+ let isleaf = this._stepSearh === false && !hasNodes
+
+ if (node) {
+ node.isleaf = isleaf
+ }
+
+ this.dataList = dataList
+ this.selectedIndex = dataList.length - 1
+
+ if (!isleaf && this.selected.length < dataList.length) {
+ this.selected.push({
+ value: null,
+ text: "请选择"
+ })
+ }
+
+ return {
+ isleaf,
+ hasNodes
+ }
+ },
+
+ _updateSelected() {
+ let dl = this.dataList
+ let sl = this.selected
+ let textField = this.map.text
+ let valueField = this.map.value
+ for (let i = 0; i < sl.length; i++) {
+ let value = sl[i].value
+ let dl2 = dl[i]
+ for (let j = 0; j < dl2.length; j++) {
+ let item2 = dl2[j]
+ if (item2[valueField] === value) {
+ sl[i].text = item2[textField]
+ break
+ }
+ }
+ }
+ },
+
+ _filterData(data, paths) {
+ let dataList = []
+ let hasNodes = true
+
+ dataList.push(data.filter((item) => {
+ return (item.parent_value === null || item.parent_value === undefined || item.parent_value === '')
+ }))
+ for (let i = 0; i < paths.length; i++) {
+ let value = paths[i].value
+ let nodes = data.filter((item) => {
+ return item.parent_value === value
+ })
+
+ if (nodes.length) {
+ dataList.push(nodes)
+ } else {
+ hasNodes = false
+ }
+ }
+
+ return {
+ dataList,
+ hasNodes
+ }
+ },
+
+ _extractTree(nodes, result, parent_value) {
+ let list = result || []
+ let valueField = this.map.value
+ for (let i = 0; i < nodes.length; i++) {
+ let node = nodes[i]
+
+ let child = {}
+ for (let key in node) {
+ if (key !== 'children') {
+ child[key] = node[key]
+ }
+ }
+ if (parent_value !== null && parent_value !== undefined && parent_value !== '') {
+ child.parent_value = parent_value
+ }
+ result.push(child)
+
+ let children = node.children
+ if (children) {
+ this._extractTree(children, result, node[valueField])
+ }
+ }
+ },
+
+ _extractTreePath(nodes, result) {
+ let list = result || []
+ for (let i = 0; i < nodes.length; i++) {
+ let node = nodes[i]
+
+ let child = {}
+ for (let key in node) {
+ if (key !== 'children') {
+ child[key] = node[key]
+ }
+ }
+ result.push(child)
+
+ let children = node.children
+ if (children) {
+ this._extractTreePath(children, result)
+ }
+ }
+ },
+
+ _findNodePath(key, nodes, path = []) {
+ let textField = this.map.text
+ let valueField = this.map.value
+ for (let i = 0; i < nodes.length; i++) {
+ let node = nodes[i]
+ let children = node.children
+ let text = node[textField]
+ let value = node[valueField]
+
+ path.push({
+ value,
+ text
+ })
+
+ if (value === key) {
+ return path
+ }
+
+ if (children) {
+ const p = this._findNodePath(key, children, path)
+ if (p.length) {
+ return p
+ }
+ }
+
+ path.pop()
+ }
+ return []
+ }
+ }
+}
diff --git a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.uts b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.uts
new file mode 100644
index 0000000..857408d
--- /dev/null
+++ b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.uts
@@ -0,0 +1,692 @@
+export type PaginationType = {
+ current : number,
+ size : number,
+ count : number
+}
+
+export type LoadMoreType = {
+ contentdown : string,
+ contentrefresh : string,
+ contentnomore : string
+}
+
+export type SelectedItemType = {
+ name : string,
+ value : string,
+}
+
+export type GetCommandOptions = {
+ collection ?: UTSJSONObject,
+ field ?: string,
+ orderby ?: string,
+ where ?: any,
+ pageData ?: string,
+ pageCurrent ?: number,
+ pageSize ?: number,
+ getCount ?: boolean,
+ getTree ?: any,
+ getTreePath ?: UTSJSONObject,
+ startwith ?: string,
+ limitlevel ?: number,
+ groupby ?: string,
+ groupField ?: string,
+ distinct ?: boolean,
+ pageIndistinct ?: boolean,
+ foreignKey ?: string,
+ loadtime ?: string,
+ manual ?: boolean
+}
+
+const DefaultSelectedNode = {
+ text: '请选择',
+ value: ''
+}
+
+export const dataPicker = defineMixin({
+ props: {
+ localdata: {
+ type: Array as PropType>,
+ default: [] as Array
+ },
+ collection: {
+ type: Object,
+ default: ''
+ },
+ field: {
+ type: String,
+ default: ''
+ },
+ orderby: {
+ type: String,
+ default: ''
+ },
+ where: {
+ type: Object,
+ default: ''
+ },
+ pageData: {
+ type: String,
+ default: 'add'
+ },
+ pageCurrent: {
+ type: Number,
+ default: 1
+ },
+ pageSize: {
+ type: Number,
+ default: 20
+ },
+ getcount: {
+ type: Boolean,
+ default: false
+ },
+ gettree: {
+ type: Object,
+ default: ''
+ },
+ gettreepath: {
+ type: Object,
+ default: ''
+ },
+ startwith: {
+ type: String,
+ default: ''
+ },
+ limitlevel: {
+ type: Number,
+ default: 10
+ },
+ groupby: {
+ type: String,
+ default: ''
+ },
+ groupField: {
+ type: String,
+ default: ''
+ },
+ distinct: {
+ type: Boolean,
+ default: false
+ },
+ pageIndistinct: {
+ type: Boolean,
+ default: false
+ },
+ foreignKey: {
+ type: String,
+ default: ''
+ },
+ loadtime: {
+ type: String,
+ default: 'auto'
+ },
+ manual: {
+ type: Boolean,
+ default: false
+ },
+ preload: {
+ type: Boolean,
+ default: false
+ },
+ stepSearh: {
+ type: Boolean,
+ default: true
+ },
+ selfField: {
+ type: String,
+ default: ''
+ },
+ parentField: {
+ type: String,
+ default: ''
+ },
+ multiple: {
+ type: Boolean,
+ default: false
+ },
+ value: {
+ type: Object,
+ default: ''
+ },
+ modelValue: {
+ type: Object,
+ default: ''
+ },
+ defaultProps: {
+ type: Object as PropType,
+ }
+ },
+ data() {
+ return {
+ loading: false,
+ error: null as UniCloudError | null,
+ treeData: [] as Array,
+ selectedIndex: 0,
+ selectedNodes: [] as Array,
+ selectedPages: [] as Array[],
+ selectedValue: '',
+ selectedPaths: [] as Array,
+ pagination: {
+ current: 1,
+ size: 20,
+ count: 0
+ } as PaginationType
+ }
+ },
+ computed: {
+ mappingTextName() : string {
+ // TODO
+ return (this.defaultProps != null) ? this.defaultProps!.getString('text', 'text') : 'text'
+ },
+ mappingValueName() : string {
+ // TODO
+ return (this.defaultProps != null) ? this.defaultProps!.getString('value', 'value') : 'value'
+ },
+ currentDataList() : Array {
+ if (this.selectedIndex > this.selectedPages.length - 1) {
+ return [] as Array
+ }
+ return this.selectedPages[this.selectedIndex]
+ },
+ isLocalData() : boolean {
+ return this.localdata.length > 0
+ },
+ isCloudData() : boolean {
+ return this._checkIsNotNull(this.collection)
+ },
+ isCloudDataList() : boolean {
+ return (this.isCloudData && (this.parentField.length == 0 && this.selfField.length == 0))
+ },
+ isCloudDataTree() : boolean {
+ return (this.isCloudData && this.parentField.length > 0 && this.selfField.length > 0)
+ },
+ dataValue() : any {
+ return this.hasModelValue ? this.modelValue : this.value
+ },
+ hasCloudTreeData() : boolean {
+ return this.treeData.length > 0
+ },
+ hasModelValue() : boolean {
+ if (typeof this.modelValue == 'string') {
+ const valueString = this.modelValue as string
+ return (valueString.length > 0)
+ } else if (Array.isArray(this.modelValue)) {
+ const valueArray = this.modelValue as Array
+ return (valueArray.length > 0)
+ }
+ return false
+ },
+ hasCloudDataValue() : boolean {
+ if (typeof this.dataValue == 'string') {
+ const valueString = this.dataValue as string
+ return (valueString.length > 0)
+ }
+ return false
+ }
+ },
+ created() {
+ this.pagination.current = this.pageCurrent
+ this.pagination.size = this.pageSize
+
+ this.$watch(
+ () : any => [
+ this.pageCurrent,
+ this.pageSize,
+ this.localdata,
+ this.value,
+ this.collection,
+ this.field,
+ this.getcount,
+ this.orderby,
+ this.where,
+ this.groupby,
+ this.groupField,
+ this.distinct
+ ],
+ (newValue : Array, oldValue : Array) => {
+ this.pagination.size = this.pageSize
+ if (newValue[0] !== oldValue[0]) {
+ this.pagination.current = this.pageCurrent
+ }
+
+ this.onPropsChange()
+ }
+ )
+ },
+ methods: {
+ onPropsChange() {
+ this.selectedIndex = 0
+ this.selectedNodes.length = 0
+ this.selectedPages.length = 0
+ this.selectedPaths.length = 0
+
+ // 加载数据
+ this.$nextTick(() => {
+ this.loadData()
+ })
+ },
+
+ onTabSelect(index : number) {
+ this.selectedIndex = index
+ },
+
+ onNodeClick(nodeData : UTSJSONObject) {
+ if (nodeData.getBoolean('disable', false)) {
+ return
+ }
+
+ const isLeaf = this._checkIsLeafNode(nodeData)
+
+ this._trimSelectedNodes(nodeData)
+
+ this.$emit('nodeclick', nodeData)
+
+ if (this.isLocalData) {
+ if (isLeaf || !this._checkHasChildren(nodeData)) {
+ this.onFinish()
+ }
+ } else if (this.isCloudDataList) {
+ this.onFinish()
+ } else if (this.isCloudDataTree) {
+ if (isLeaf) {
+ this.onFinish()
+ } else if (!this._checkHasChildren(nodeData)) {
+ // 尝试请求一次,如果没有返回数据标记为叶子节点
+ this.loadCloudDataNode(nodeData)
+ }
+ }
+ },
+
+ getChangeNodes(): Array {
+ const nodes: Array = []
+ this.selectedNodes.forEach((node : UTSJSONObject) => {
+ const newNode: UTSJSONObject = {}
+ newNode[this.mappingTextName] = node.getString(this.mappingTextName)
+ newNode[this.mappingValueName] = node.getString(this.mappingValueName)
+ nodes.push(newNode)
+ })
+ return nodes
+ },
+
+ onFinish() { },
+
+ // 加载数据(自动判定环境)
+ loadData() {
+ if (this.isLocalData) {
+ this.loadLocalData()
+ } else if (this.isCloudDataList) {
+ this.loadCloudDataList()
+ } else if (this.isCloudDataTree) {
+ this.loadCloudDataTree()
+ }
+ },
+
+ // 加载本地数据
+ loadLocalData() {
+ this.treeData = this.localdata
+ if (Array.isArray(this.dataValue)) {
+ const value = this.dataValue as Array
+ this.selectedPaths = value.slice(0)
+ this._pushSelectedTreeNodes(value, this.localdata)
+ } else {
+ this._pushSelectedNodes(this.localdata)
+ }
+ },
+
+ // 加载 Cloud 数据 (单列)
+ loadCloudDataList() {
+ this._loadCloudData(null, (data : Array) => {
+ this.treeData = data
+ this._pushSelectedNodes(data)
+ })
+ },
+
+ // 加载 Cloud 数据 (树形)
+ loadCloudDataTree() {
+ let commandOptions = {
+ field: this._cloudDataPostField(),
+ where: this._cloudDataTreeWhere(),
+ getTree: true
+ } as GetCommandOptions
+ if (this._checkIsNotNull(this.gettree)) {
+ commandOptions.startwith = `${this.selfField}=='${this.dataValue as string}'`
+ }
+ this._loadCloudData(commandOptions, (data : Array) => {
+ this.treeData = data
+ if (this.selectedPaths.length > 0) {
+ this._pushSelectedTreeNodes(this.selectedPaths, data)
+ } else {
+ this._pushSelectedNodes(data)
+ }
+ })
+ },
+
+ // 加载 Cloud 数据 (节点)
+ loadCloudDataNode(nodeData : UTSJSONObject) {
+ const commandOptions = {
+ field: this._cloudDataPostField(),
+ where: this._cloudDataNodeWhere()
+ } as GetCommandOptions
+ this._loadCloudData(commandOptions, (data : Array) => {
+ nodeData['children'] = data
+ if (data.length == 0) {
+ nodeData['isleaf'] = true
+ this.onFinish()
+ } else {
+ this._pushSelectedNodes(data)
+ }
+ })
+ },
+
+ // 回显 Cloud Tree Path
+ loadCloudDataPath() {
+ if (!this.hasCloudDataValue) {
+ return
+ }
+
+ const command : GetCommandOptions = {}
+
+ // 单列
+ if (this.isCloudDataList) {
+ // 根据 field's as value标识匹配 where 条件
+ let where : Array = [];
+ let whereField = this._getForeignKeyByField();
+ if (whereField.length > 0) {
+ where.push(`${whereField} == '${this.dataValue as string}'`)
+ }
+
+ let whereString = where.join(' || ')
+ if (this._checkIsNotNull(this.where)) {
+ whereString = `(${this.where}) && (${whereString})`
+ }
+
+ command.field = this._cloudDataPostField()
+ command.where = whereString
+ }
+
+ // 树形
+ if (this.isCloudDataTree) {
+ command.field = this._cloudDataPostField()
+ command.getTreePath = {
+ startWith: `${this.selfField}=='${this.dataValue as string}'`
+ }
+ }
+
+ this._loadCloudData(command, (data : Array) => {
+ this._extractTreePath(data, this.selectedPaths)
+ })
+ },
+
+ _loadCloudData(options ?: GetCommandOptions, callback ?: ((data : Array) => void)) {
+ if (this.loading) {
+ return
+ }
+ this.loading = true
+
+ this.error = null
+
+ this._getCommand(options).then((response : UniCloudDBGetResult) => {
+ callback?.(response.data)
+ }).catch((err : any | null) => {
+ this.error = err as UniCloudError
+ }).finally(() => {
+ this.loading = false
+ })
+ },
+
+ _cloudDataPostField() : string {
+ let fields = [this.field];
+ if (this.parentField.length > 0) {
+ fields.push(`${this.parentField} as parent_value`)
+ }
+ return fields.join(',')
+ },
+
+ _cloudDataTreeWhere() : string {
+ let result : Array = []
+ let selectedNodes = this.selectedNodes.length > 0 ? this.selectedNodes : this.selectedPaths
+ let parentField = this.parentField
+ if (parentField.length > 0) {
+ result.push(`${parentField} == null || ${parentField} == ""`)
+ }
+ if (selectedNodes.length > 0) {
+ for (var i = 0; i < selectedNodes.length - 1; i++) {
+ const parentFieldValue = selectedNodes[i].getString('value', '')
+ result.push(`${parentField} == '${parentFieldValue}'`)
+ }
+ }
+
+ let where : Array = []
+ if (this._checkIsNotNull(this.where)) {
+ where.push(`(${this.where as string})`)
+ }
+
+ if (result.length > 0) {
+ where.push(`(${result.join(' || ')})`)
+ }
+
+ return where.join(' && ')
+ },
+
+ _cloudDataNodeWhere() : string {
+ const where : Array = []
+ if (this.selectedNodes.length > 0) {
+ const value = this.selectedNodes[this.selectedNodes.length - 1].getString('value', '')
+ where.push(`${this.parentField} == '${value}'`)
+ }
+
+ let whereString = where.join(' || ')
+ if (this._checkIsNotNull(this.where)) {
+ return `(${this.where as string}) && (${whereString})`
+ }
+
+ return whereString
+ },
+
+ _getWhereByForeignKey() : string {
+ let result : Array = []
+ let whereField = this._getForeignKeyByField();
+ if (whereField.length > 0) {
+ result.push(`${whereField} == '${this.dataValue as string}'`)
+ }
+
+ if (this._checkIsNotNull(this.where)) {
+ return `(${this.where}) && (${result.join(' || ')})`
+ }
+
+ return result.join(' || ')
+ },
+
+ _getForeignKeyByField() : string {
+ const fields = this.field.split(',')
+ let whereField = ''
+ for (let i = 0; i < fields.length; i++) {
+ const items = fields[i].split('as')
+ if (items.length < 2) {
+ continue
+ }
+ if (items[1].trim() === 'value') {
+ whereField = items[0].trim()
+ break
+ }
+ }
+ return whereField
+ },
+
+ _getCommand(options ?: GetCommandOptions) : Promise {
+ let db = uniCloud.databaseForJQL()
+
+ let collection = Array.isArray(this.collection) ? db.collection(...(this.collection as Array)) : db.collection(this.collection)
+
+ let filter : UniCloudDBFilter | null = null
+ if (this.foreignKey.length > 0) {
+ filter = collection.foreignKey(this.foreignKey)
+ }
+
+ const where : any = options?.where ?? this.where
+ if (typeof where == 'string') {
+ const whereString = where as string
+ if (whereString.length > 0) {
+ filter = (filter != null) ? filter.where(where) : collection.where(where)
+ }
+ } else {
+ filter = (filter != null) ? filter.where(where) : collection.where(where)
+ }
+
+ let query : UniCloudDBQuery | null = null
+ if (this.field.length > 0) {
+ query = (filter != null) ? filter.field(this.field) : collection.field(this.field)
+ }
+ if (this.groupby.length > 0) {
+ if (query != null) {
+ query = query.groupBy(this.groupby)
+ } else if (filter != null) {
+ query = filter.groupBy(this.groupby)
+ }
+ }
+ if (this.groupField.length > 0) {
+ if (query != null) {
+ query = query.groupField(this.groupField)
+ } else if (filter != null) {
+ query = filter.groupField(this.groupField)
+ }
+ }
+ if (this.distinct == true) {
+ if (query != null) {
+ query = query.distinct(this.field)
+ } else if (filter != null) {
+ query = filter.distinct(this.field)
+ }
+ }
+ if (this.orderby.length > 0) {
+ if (query != null) {
+ query = query.orderBy(this.orderby)
+ } else if (filter != null) {
+ query = filter.orderBy(this.orderby)
+ }
+ }
+
+ const size = this.pagination.size
+ const current = this.pagination.current
+ if (query != null) {
+ query = query.skip(size * (current - 1)).limit(size)
+ } else if (filter != null) {
+ query = filter.skip(size * (current - 1)).limit(size)
+ } else {
+ query = collection.skip(size * (current - 1)).limit(size)
+ }
+
+ const getOptions = {}
+ const treeOptions = {
+ limitLevel: this.limitlevel,
+ startWith: this.startwith
+ }
+ if (this.getcount == true) {
+ getOptions['getCount'] = this.getcount
+ }
+
+ const getTree : any = options?.getTree ?? this.gettree
+ if (typeof getTree == 'string') {
+ const getTreeString = getTree as string
+ if (getTreeString.length > 0) {
+ getOptions['getTree'] = treeOptions
+ }
+ } else if (typeof getTree == 'object') {
+ getOptions['getTree'] = treeOptions
+ } else {
+ getOptions['getTree'] = getTree
+ }
+
+ const getTreePath = options?.getTreePath ?? this.gettreepath
+ if (typeof getTreePath == 'string') {
+ const getTreePathString = getTreePath as string
+ if (getTreePathString.length > 0) {
+ getOptions['getTreePath'] = getTreePath
+ }
+ } else {
+ getOptions['getTreePath'] = getTreePath
+ }
+
+ return query.get(getOptions)
+ },
+
+ _checkIsNotNull(value : any) : boolean {
+ if (typeof value == 'string') {
+ const valueString = value as string
+ return (valueString.length > 0)
+ } else if (value instanceof UTSJSONObject) {
+ return true
+ }
+ return false
+ },
+
+ _checkIsLeafNode(nodeData : UTSJSONObject) : boolean {
+ if (this.selectedIndex >= this.limitlevel) {
+ return true
+ }
+
+ if (nodeData.getBoolean('isleaf', false)) {
+ return true
+ }
+
+ return false
+ },
+
+ _checkHasChildren(nodeData : UTSJSONObject) : boolean {
+ const children = nodeData.getArray('children') ?? ([] as Array)
+ return children.length > 0
+ },
+
+ _pushSelectedNodes(nodes : Array) {
+ this.selectedNodes.push(DefaultSelectedNode)
+ this.selectedPages.push(nodes)
+ this.selectedIndex = this.selectedPages.length - 1
+ },
+
+ _trimSelectedNodes(nodeData : UTSJSONObject) {
+ this.selectedNodes.splice(this.selectedIndex)
+ this.selectedNodes.push(nodeData)
+
+ if (this.selectedPages.length > 0) {
+ this.selectedPages.splice(this.selectedIndex + 1)
+ }
+
+ const children = nodeData.getArray('children') ?? ([] as Array)
+ if (children.length > 0) {
+ this.selectedNodes.push(DefaultSelectedNode)
+ this.selectedPages.push(children)
+ }
+
+ this.selectedIndex = this.selectedPages.length - 1
+ },
+
+ _pushSelectedTreeNodes(paths : Array, nodes : Array) {
+ let children : Array = nodes
+ paths.forEach((node : UTSJSONObject) => {
+ const findNode = children.find((item : UTSJSONObject) : boolean => {
+ return (item.getString(this.mappingValueName) == node.getString(this.mappingValueName))
+ })
+ if (findNode != null) {
+ this.selectedPages.push(children)
+ this.selectedNodes.push(node)
+ children = findNode.getArray('children') ?? ([] as Array)
+ }
+ })
+ this.selectedIndex = this.selectedPages.length - 1
+ },
+
+ _extractTreePath(nodes : Array, result : Array) {
+ if (nodes.length == 0) {
+ return
+ }
+
+ const node = nodes[0]
+ result.push(node)
+
+ const children = node.getArray('children')
+ if (Array.isArray(children) && children!.length > 0) {
+ this._extractTreePath(children, result)
+ }
+ }
+ }
+})
diff --git a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.css b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.css
new file mode 100644
index 0000000..39fe1c3
--- /dev/null
+++ b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.css
@@ -0,0 +1,76 @@
+.uni-data-pickerview {
+ position: relative;
+ flex-direction: column;
+ overflow: hidden;
+}
+
+.loading-cover {
+ position: absolute;
+ left: 0;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ align-items: center;
+ justify-content: center;
+ background-color: rgba(150, 150, 150, .1);
+}
+
+.error {
+ background-color: #fff;
+ padding: 15px;
+}
+
+.error-text {
+ color: #DD524D;
+}
+
+.selected-node-list {
+ flex-direction: row;
+ flex-wrap: nowrap;
+}
+
+.selected-node-item {
+ margin-left: 10px;
+ margin-right: 10px;
+ padding: 8px 10px 8px 10px;
+ border-bottom: 2px solid transparent;
+}
+
+.selected-node-item-active {
+ color: #007aff;
+ border-bottom-color: #007aff;
+}
+
+.list-view {
+ flex: 1;
+}
+
+.list-item {
+ flex-direction: row;
+ justify-content: space-between;
+ padding: 12px 15px;
+ border-bottom: 1px solid #f0f0f0;
+}
+
+.item-text {
+ color: #333333;
+}
+
+.item-text-disabled {
+ opacity: .5;
+}
+
+.item-text-overflow {
+ overflow: hidden;
+}
+
+.check {
+ margin-right: 5px;
+ border: 2px solid #007aff;
+ border-left: 0;
+ border-top: 0;
+ height: 12px;
+ width: 6px;
+ transform-origin: center;
+ transform: rotate(45deg);
+}
diff --git a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.uvue b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.uvue
new file mode 100644
index 0000000..f4780f3
--- /dev/null
+++ b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.uvue
@@ -0,0 +1,69 @@
+
+
+
+ {{error!.errMsg}}
+
+
+
+
+
+ {{item[mappingTextName]}}
+
+
+
+
+
+
+ {{item[mappingTextName]}}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue
new file mode 100644
index 0000000..6ebced9
--- /dev/null
+++ b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue
@@ -0,0 +1,323 @@
+
+
+
+
+
+ {{item.text || ''}}
+
+
+
+
+
+
+ {{item[map.text]}}
+
+
+
+
+
+
+
+
+ {{errorMessage}}
+
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-data-picker/package.json b/uni_modules/uni-data-picker/package.json
new file mode 100644
index 0000000..efc60c2
--- /dev/null
+++ b/uni_modules/uni-data-picker/package.json
@@ -0,0 +1,91 @@
+{
+ "id": "uni-data-picker",
+ "displayName": "uni-data-picker 数据驱动的picker选择器",
+ "version": "2.0.1",
+ "description": "单列、多列级联选择器,常用于省市区城市选择、公司部门选择、多级分类等场景",
+ "keywords": [
+ "uni-ui",
+ "uniui",
+ "picker",
+ "级联",
+ "省市区",
+ ""
+],
+ "repository": "https://github.com/dcloudio/uni-ui",
+ "engines": {
+ "HBuilderX": ""
+ },
+ "directories": {
+ "example": "../../temps/example_temps"
+ },
+"dcloudext": {
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "无",
+ "data": "无",
+ "permissions": "无"
+ },
+ "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+ "type": "component-vue"
+ },
+ "uni_modules": {
+ "dependencies": [
+ "uni-load-more",
+ "uni-icons",
+ "uni-scss"
+ ],
+ "encrypt": [],
+ "platforms": {
+ "cloud": {
+ "tcb": "y",
+ "aliyun": "y",
+ "alipay": "n"
+ },
+ "client": {
+ "App": {
+ "app-vue": "y",
+ "app-nvue": "y"
+ },
+ "H5-mobile": {
+ "Safari": "y",
+ "Android Browser": "y",
+ "微信浏览器(Android)": "y",
+ "QQ浏览器(Android)": "y"
+ },
+ "H5-pc": {
+ "Chrome": "y",
+ "IE": "y",
+ "Edge": "y",
+ "Firefox": "y",
+ "Safari": "y"
+ },
+ "小程序": {
+ "微信": "y",
+ "阿里": "y",
+ "百度": "y",
+ "字节跳动": "y",
+ "QQ": "y",
+ "京东": "u"
+ },
+ "快应用": {
+ "华为": "u",
+ "联盟": "u"
+ },
+ "Vue": {
+ "vue2": "y",
+ "vue3": "y"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-data-picker/readme.md b/uni_modules/uni-data-picker/readme.md
new file mode 100644
index 0000000..19dd0e8
--- /dev/null
+++ b/uni_modules/uni-data-picker/readme.md
@@ -0,0 +1,22 @@
+## DataPicker 级联选择
+> **组件名:uni-data-picker**
+> 代码块: `uDataPicker`
+> 关联组件:`uni-data-pickerview`、`uni-load-more`。
+
+
+`` 是一个选择类[datacom组件](https://uniapp.dcloud.net.cn/component/datacom)。
+
+支持单列、和多列级联选择。列数没有限制,如果屏幕显示不全,顶部tab区域会左右滚动。
+
+候选数据支持一次性加载完毕,也支持懒加载,比如示例图中,选择了“北京”后,动态加载北京的区县数据。
+
+`` 组件尤其适用于地址选择、分类选择等选择类。
+
+`` 支持本地数据、云端静态数据(json),uniCloud云数据库数据。
+
+`` 可以通过JQL直连uniCloud云数据库,配套[DB Schema](https://uniapp.dcloud.net.cn/uniCloud/schema),可在schema2code中自动生成前端页面,还支持服务器端校验。
+
+在uniCloud数据表中新建表“uni-id-address”和“opendb-city-china”,这2个表的schema自带foreignKey关联。在“uni-id-address”表的表结构页面使用schema2code生成前端页面,会自动生成地址管理的维护页面,自动从“opendb-city-china”表包含的中国所有省市区信息里选择地址。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-data-picker)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
\ No newline at end of file
diff --git a/uni_modules/uni-icons/changelog.md b/uni_modules/uni-icons/changelog.md
new file mode 100644
index 0000000..0261131
--- /dev/null
+++ b/uni_modules/uni-icons/changelog.md
@@ -0,0 +1,42 @@
+## 2.0.10(2024-06-07)
+- 优化 uni-app x 中,size 属性的类型
+## 2.0.9(2024-01-12)
+fix: 修复图标大小默认值错误的问题
+## 2.0.8(2023-12-14)
+- 修复 项目未使用 ts 情况下,打包报错的bug
+## 2.0.7(2023-12-14)
+- 修复 size 属性为 string 时,不加单位导致尺寸异常的bug
+## 2.0.6(2023-12-11)
+- 优化 兼容老版本icon类型,如 top ,bottom 等
+## 2.0.5(2023-12-11)
+- 优化 兼容老版本icon类型,如 top ,bottom 等
+## 2.0.4(2023-12-06)
+- 优化 uni-app x 下示例项目图标排序
+## 2.0.3(2023-12-06)
+- 修复 nvue下引入组件报错的bug
+## 2.0.2(2023-12-05)
+-优化 size 属性支持单位
+## 2.0.1(2023-12-05)
+- 新增 uni-app x 支持定义图标
+## 1.3.5(2022-01-24)
+- 优化 size 属性可以传入不带单位的字符串数值
+## 1.3.4(2022-01-24)
+- 优化 size 支持其他单位
+## 1.3.3(2022-01-17)
+- 修复 nvue 有些图标不显示的bug,兼容老版本图标
+## 1.3.2(2021-12-01)
+- 优化 示例可复制图标名称
+## 1.3.1(2021-11-23)
+- 优化 兼容旧组件 type 值
+## 1.3.0(2021-11-19)
+- 新增 更多图标
+- 优化 自定义图标使用方式
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-icons](https://uniapp.dcloud.io/component/uniui/uni-icons)
+## 1.1.7(2021-11-08)
+## 1.2.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.1.5(2021-05-12)
+- 新增 组件示例地址
+## 1.1.4(2021-02-05)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-icons/components/uni-icons/uni-icons.uvue b/uni_modules/uni-icons/components/uni-icons/uni-icons.uvue
new file mode 100644
index 0000000..8740559
--- /dev/null
+++ b/uni_modules/uni-icons/components/uni-icons/uni-icons.uvue
@@ -0,0 +1,91 @@
+
+
+ {{unicode}}
+
+
+
+
+
+
diff --git a/uni_modules/uni-icons/components/uni-icons/uni-icons.vue b/uni_modules/uni-icons/components/uni-icons/uni-icons.vue
new file mode 100644
index 0000000..7da5356
--- /dev/null
+++ b/uni_modules/uni-icons/components/uni-icons/uni-icons.vue
@@ -0,0 +1,110 @@
+
+
+ {{unicode}}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-icons/components/uni-icons/uniicons.css b/uni_modules/uni-icons/components/uni-icons/uniicons.css
new file mode 100644
index 0000000..0a6b6fe
--- /dev/null
+++ b/uni_modules/uni-icons/components/uni-icons/uniicons.css
@@ -0,0 +1,664 @@
+
+.uniui-cart-filled:before {
+ content: "\e6d0";
+}
+
+.uniui-gift-filled:before {
+ content: "\e6c4";
+}
+
+.uniui-color:before {
+ content: "\e6cf";
+}
+
+.uniui-wallet:before {
+ content: "\e6b1";
+}
+
+.uniui-settings-filled:before {
+ content: "\e6ce";
+}
+
+.uniui-auth-filled:before {
+ content: "\e6cc";
+}
+
+.uniui-shop-filled:before {
+ content: "\e6cd";
+}
+
+.uniui-staff-filled:before {
+ content: "\e6cb";
+}
+
+.uniui-vip-filled:before {
+ content: "\e6c6";
+}
+
+.uniui-plus-filled:before {
+ content: "\e6c7";
+}
+
+.uniui-folder-add-filled:before {
+ content: "\e6c8";
+}
+
+.uniui-color-filled:before {
+ content: "\e6c9";
+}
+
+.uniui-tune-filled:before {
+ content: "\e6ca";
+}
+
+.uniui-calendar-filled:before {
+ content: "\e6c0";
+}
+
+.uniui-notification-filled:before {
+ content: "\e6c1";
+}
+
+.uniui-wallet-filled:before {
+ content: "\e6c2";
+}
+
+.uniui-medal-filled:before {
+ content: "\e6c3";
+}
+
+.uniui-fire-filled:before {
+ content: "\e6c5";
+}
+
+.uniui-refreshempty:before {
+ content: "\e6bf";
+}
+
+.uniui-location-filled:before {
+ content: "\e6af";
+}
+
+.uniui-person-filled:before {
+ content: "\e69d";
+}
+
+.uniui-personadd-filled:before {
+ content: "\e698";
+}
+
+.uniui-arrowthinleft:before {
+ content: "\e6d2";
+}
+
+.uniui-arrowthinup:before {
+ content: "\e6d3";
+}
+
+.uniui-arrowthindown:before {
+ content: "\e6d4";
+}
+
+.uniui-back:before {
+ content: "\e6b9";
+}
+
+.uniui-forward:before {
+ content: "\e6ba";
+}
+
+.uniui-arrow-right:before {
+ content: "\e6bb";
+}
+
+.uniui-arrow-left:before {
+ content: "\e6bc";
+}
+
+.uniui-arrow-up:before {
+ content: "\e6bd";
+}
+
+.uniui-arrow-down:before {
+ content: "\e6be";
+}
+
+.uniui-arrowthinright:before {
+ content: "\e6d1";
+}
+
+.uniui-down:before {
+ content: "\e6b8";
+}
+
+.uniui-bottom:before {
+ content: "\e6b8";
+}
+
+.uniui-arrowright:before {
+ content: "\e6d5";
+}
+
+.uniui-right:before {
+ content: "\e6b5";
+}
+
+.uniui-up:before {
+ content: "\e6b6";
+}
+
+.uniui-top:before {
+ content: "\e6b6";
+}
+
+.uniui-left:before {
+ content: "\e6b7";
+}
+
+.uniui-arrowup:before {
+ content: "\e6d6";
+}
+
+.uniui-eye:before {
+ content: "\e651";
+}
+
+.uniui-eye-filled:before {
+ content: "\e66a";
+}
+
+.uniui-eye-slash:before {
+ content: "\e6b3";
+}
+
+.uniui-eye-slash-filled:before {
+ content: "\e6b4";
+}
+
+.uniui-info-filled:before {
+ content: "\e649";
+}
+
+.uniui-reload:before {
+ content: "\e6b2";
+}
+
+.uniui-micoff-filled:before {
+ content: "\e6b0";
+}
+
+.uniui-map-pin-ellipse:before {
+ content: "\e6ac";
+}
+
+.uniui-map-pin:before {
+ content: "\e6ad";
+}
+
+.uniui-location:before {
+ content: "\e6ae";
+}
+
+.uniui-starhalf:before {
+ content: "\e683";
+}
+
+.uniui-star:before {
+ content: "\e688";
+}
+
+.uniui-star-filled:before {
+ content: "\e68f";
+}
+
+.uniui-calendar:before {
+ content: "\e6a0";
+}
+
+.uniui-fire:before {
+ content: "\e6a1";
+}
+
+.uniui-medal:before {
+ content: "\e6a2";
+}
+
+.uniui-font:before {
+ content: "\e6a3";
+}
+
+.uniui-gift:before {
+ content: "\e6a4";
+}
+
+.uniui-link:before {
+ content: "\e6a5";
+}
+
+.uniui-notification:before {
+ content: "\e6a6";
+}
+
+.uniui-staff:before {
+ content: "\e6a7";
+}
+
+.uniui-vip:before {
+ content: "\e6a8";
+}
+
+.uniui-folder-add:before {
+ content: "\e6a9";
+}
+
+.uniui-tune:before {
+ content: "\e6aa";
+}
+
+.uniui-auth:before {
+ content: "\e6ab";
+}
+
+.uniui-person:before {
+ content: "\e699";
+}
+
+.uniui-email-filled:before {
+ content: "\e69a";
+}
+
+.uniui-phone-filled:before {
+ content: "\e69b";
+}
+
+.uniui-phone:before {
+ content: "\e69c";
+}
+
+.uniui-email:before {
+ content: "\e69e";
+}
+
+.uniui-personadd:before {
+ content: "\e69f";
+}
+
+.uniui-chatboxes-filled:before {
+ content: "\e692";
+}
+
+.uniui-contact:before {
+ content: "\e693";
+}
+
+.uniui-chatbubble-filled:before {
+ content: "\e694";
+}
+
+.uniui-contact-filled:before {
+ content: "\e695";
+}
+
+.uniui-chatboxes:before {
+ content: "\e696";
+}
+
+.uniui-chatbubble:before {
+ content: "\e697";
+}
+
+.uniui-upload-filled:before {
+ content: "\e68e";
+}
+
+.uniui-upload:before {
+ content: "\e690";
+}
+
+.uniui-weixin:before {
+ content: "\e691";
+}
+
+.uniui-compose:before {
+ content: "\e67f";
+}
+
+.uniui-qq:before {
+ content: "\e680";
+}
+
+.uniui-download-filled:before {
+ content: "\e681";
+}
+
+.uniui-pyq:before {
+ content: "\e682";
+}
+
+.uniui-sound:before {
+ content: "\e684";
+}
+
+.uniui-trash-filled:before {
+ content: "\e685";
+}
+
+.uniui-sound-filled:before {
+ content: "\e686";
+}
+
+.uniui-trash:before {
+ content: "\e687";
+}
+
+.uniui-videocam-filled:before {
+ content: "\e689";
+}
+
+.uniui-spinner-cycle:before {
+ content: "\e68a";
+}
+
+.uniui-weibo:before {
+ content: "\e68b";
+}
+
+.uniui-videocam:before {
+ content: "\e68c";
+}
+
+.uniui-download:before {
+ content: "\e68d";
+}
+
+.uniui-help:before {
+ content: "\e679";
+}
+
+.uniui-navigate-filled:before {
+ content: "\e67a";
+}
+
+.uniui-plusempty:before {
+ content: "\e67b";
+}
+
+.uniui-smallcircle:before {
+ content: "\e67c";
+}
+
+.uniui-minus-filled:before {
+ content: "\e67d";
+}
+
+.uniui-micoff:before {
+ content: "\e67e";
+}
+
+.uniui-closeempty:before {
+ content: "\e66c";
+}
+
+.uniui-clear:before {
+ content: "\e66d";
+}
+
+.uniui-navigate:before {
+ content: "\e66e";
+}
+
+.uniui-minus:before {
+ content: "\e66f";
+}
+
+.uniui-image:before {
+ content: "\e670";
+}
+
+.uniui-mic:before {
+ content: "\e671";
+}
+
+.uniui-paperplane:before {
+ content: "\e672";
+}
+
+.uniui-close:before {
+ content: "\e673";
+}
+
+.uniui-help-filled:before {
+ content: "\e674";
+}
+
+.uniui-paperplane-filled:before {
+ content: "\e675";
+}
+
+.uniui-plus:before {
+ content: "\e676";
+}
+
+.uniui-mic-filled:before {
+ content: "\e677";
+}
+
+.uniui-image-filled:before {
+ content: "\e678";
+}
+
+.uniui-locked-filled:before {
+ content: "\e668";
+}
+
+.uniui-info:before {
+ content: "\e669";
+}
+
+.uniui-locked:before {
+ content: "\e66b";
+}
+
+.uniui-camera-filled:before {
+ content: "\e658";
+}
+
+.uniui-chat-filled:before {
+ content: "\e659";
+}
+
+.uniui-camera:before {
+ content: "\e65a";
+}
+
+.uniui-circle:before {
+ content: "\e65b";
+}
+
+.uniui-checkmarkempty:before {
+ content: "\e65c";
+}
+
+.uniui-chat:before {
+ content: "\e65d";
+}
+
+.uniui-circle-filled:before {
+ content: "\e65e";
+}
+
+.uniui-flag:before {
+ content: "\e65f";
+}
+
+.uniui-flag-filled:before {
+ content: "\e660";
+}
+
+.uniui-gear-filled:before {
+ content: "\e661";
+}
+
+.uniui-home:before {
+ content: "\e662";
+}
+
+.uniui-home-filled:before {
+ content: "\e663";
+}
+
+.uniui-gear:before {
+ content: "\e664";
+}
+
+.uniui-smallcircle-filled:before {
+ content: "\e665";
+}
+
+.uniui-map-filled:before {
+ content: "\e666";
+}
+
+.uniui-map:before {
+ content: "\e667";
+}
+
+.uniui-refresh-filled:before {
+ content: "\e656";
+}
+
+.uniui-refresh:before {
+ content: "\e657";
+}
+
+.uniui-cloud-upload:before {
+ content: "\e645";
+}
+
+.uniui-cloud-download-filled:before {
+ content: "\e646";
+}
+
+.uniui-cloud-download:before {
+ content: "\e647";
+}
+
+.uniui-cloud-upload-filled:before {
+ content: "\e648";
+}
+
+.uniui-redo:before {
+ content: "\e64a";
+}
+
+.uniui-images-filled:before {
+ content: "\e64b";
+}
+
+.uniui-undo-filled:before {
+ content: "\e64c";
+}
+
+.uniui-more:before {
+ content: "\e64d";
+}
+
+.uniui-more-filled:before {
+ content: "\e64e";
+}
+
+.uniui-undo:before {
+ content: "\e64f";
+}
+
+.uniui-images:before {
+ content: "\e650";
+}
+
+.uniui-paperclip:before {
+ content: "\e652";
+}
+
+.uniui-settings:before {
+ content: "\e653";
+}
+
+.uniui-search:before {
+ content: "\e654";
+}
+
+.uniui-redo-filled:before {
+ content: "\e655";
+}
+
+.uniui-list:before {
+ content: "\e644";
+}
+
+.uniui-mail-open-filled:before {
+ content: "\e63a";
+}
+
+.uniui-hand-down-filled:before {
+ content: "\e63c";
+}
+
+.uniui-hand-down:before {
+ content: "\e63d";
+}
+
+.uniui-hand-up-filled:before {
+ content: "\e63e";
+}
+
+.uniui-hand-up:before {
+ content: "\e63f";
+}
+
+.uniui-heart-filled:before {
+ content: "\e641";
+}
+
+.uniui-mail-open:before {
+ content: "\e643";
+}
+
+.uniui-heart:before {
+ content: "\e639";
+}
+
+.uniui-loop:before {
+ content: "\e633";
+}
+
+.uniui-pulldown:before {
+ content: "\e632";
+}
+
+.uniui-scan:before {
+ content: "\e62a";
+}
+
+.uniui-bars:before {
+ content: "\e627";
+}
+
+.uniui-checkbox:before {
+ content: "\e62b";
+}
+
+.uniui-checkbox-filled:before {
+ content: "\e62c";
+}
+
+.uniui-shop:before {
+ content: "\e62f";
+}
+
+.uniui-headphones:before {
+ content: "\e630";
+}
+
+.uniui-cart:before {
+ content: "\e631";
+}
diff --git a/uni_modules/uni-icons/components/uni-icons/uniicons.ttf b/uni_modules/uni-icons/components/uni-icons/uniicons.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..14696d038d828073edac09ea4e5ba1dec2f58115
GIT binary patch
literal 35824
zcmeFacbp`3nLl2is_w3i)m>GcbC?b@J*lUsyC;X8*`1l4%{ea{*j?DXWCS+=x`1Rc
zpd{rG^~9_Q2$&HOFdXOI8BR}IPdz;YC>~S$eLqz_vkNSWzx%yjzdwH8-F~X8D}KWB
zdBXd7KA+(j$8iqs7$m|vZHHYVCsJSej9$Dvt$3ZLw|by
z;14;@w1?yD*X`bS*{-|aee@R`=jrCS!}shtciYZf`HFYq+J6UC_uzo|LsJs_kAj-^
z?7#5RE3kv-{hH(WEA}1SvF%~|_jrzz{)l5E`?pUw>Y24^H?#cMO-kvNd>m;s2%o+Xnw%@Bmm3d<`kX
zajga$@=qE3$-a!E#Hp?L#t6f46MGkad+;CEgR5KX<$7OzxIS8c{uIU^jb>;=
z92uh{ulUFGJH1?#i*rr*&vEbO-o@R)y@z`*cPB>lJGpmow{tggH*q&}w{W*|w{dUh
zZs6X`9p#R3$GI$bg1d^ln!AR33-?y;B$wi@<*wtd=ibI$!ClGidlPpacRrWq_HvuJ&D<7lD|ZgJjoZ%c;C6E7a=W-py8@VZNAvet};)>j2ZV9)PTZT4R&aL29a;v!2+ybtRo8Tt75pI;5$Bl90
z+O{&05{0_AbEzlcCG_5sKj+~Wv-j6a8<6x^>DphfotYkI4_sSfX{Imv_hOq
za7iu(2^B%h1h^m<;#5xJ+-NNsqDA3sXnhCdoeMI_!infF>X+GT>3)upr27B+KV2h;
zPc)k0KH^7%z-L^UOATS1%d_-s9@vdLnQkSMM+g{K(Zi4FYF!^^!s0QLf%)5V)1A
zmkk2na`j$=z`NAdDBTK4}m}4p*Nt2xEw=FEj|FiK|Z=gmJ~y7a4>R
z#?==agt5lep^b?!>bUw+gE0QM`Z9ws61n