From 45e45d81602e3b337afc686405110a0dee6f9c1a Mon Sep 17 00:00:00 2001 From: userGyl Date: Mon, 9 Feb 2026 15:10:00 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=AF=E5=88=86=E5=85=91=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../assets/images/mall_pay_success@2x.png | Bin 0 -> 19280 bytes .../pages/c_page/mall/detail/controller.dart | 117 ++++++++ .../lib/pages/c_page/mall/detail/view.dart | 283 ++++++++++++++++++ .../c_page/mall/exchange_success/view.dart | 68 +++++ .../pages/c_page/mall/mall_controller.dart | 10 +- 5 files changed, 472 insertions(+), 6 deletions(-) create mode 100644 ln_jq_app/assets/images/mall_pay_success@2x.png create mode 100644 ln_jq_app/lib/pages/c_page/mall/detail/controller.dart create mode 100644 ln_jq_app/lib/pages/c_page/mall/detail/view.dart create mode 100644 ln_jq_app/lib/pages/c_page/mall/exchange_success/view.dart diff --git a/ln_jq_app/assets/images/mall_pay_success@2x.png b/ln_jq_app/assets/images/mall_pay_success@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..5398a167093b5dc75c48be7a4e9ea8ae46eb23e2 GIT binary patch literal 19280 zcmV))K#ISKP)diB_4v;}F!{wdJ~;iQw>>!Z_-_ZA_`)ANIJM&s zQ2#$a*e#d!Q(u0|gHw;a<$G+M&^0b1j->?oQtNcOPDF>);sk&$9YtUV`%-ZVae(;zhi1O`vky-0_&ouLy?3v% z-oKatZfO^QR{%1}6P2e;lce(|P3OR8T`Q@XMluDO&RfZ0*KAFubAeMXX)0|bGpL)+ zY1>MsO)Ftr_QAfIrkOU;cLShr_&g`rGjS#rXE_!|bceA$JhS7@ho-*p^AGIXasDZ^ z1bv%|j( zjk;iyO*apM#?kf=`kBb*S`z^LR9;I6`WgUFu-911+CPM?cS_?T?z1&F9TjV`tH4gPigW=8JxUcEj?YLOx8B{t9N1hP-lX`~TTrk;!gNC%Ud79;OoQ)}!>X8^idbC;QF z?lE%!?rdwfol16@nbux2lkBlm>F#tk-DhXhJ?V6Iz)olTvzdHPTFXcW+MGJp?Mdgd zU9jI}Yp|b6_sUFyzLV$eM6%P&wsxAC=8w&6^Z9hTx!X)P_S#y57t{e;YfidmYsxf| znXH*MOq$jm0Iu>p!(4LZ&&pEsKQMYfF!8199+>*{8H4p|@4erAkG}x41LQ$ZgD&X3 z_3|tMYCpTYCd;*7Uhn<3?tuC5$eq@@*W}K|EitBHlbpA9DI1vf)`J7HzGPgzR%1x z#_fD_+%;MO;3i4yrkOQtf(*);+}cf6%uS+4-u%G$jvLnrxId1yE${NzLjI4Sf$Ul- z{rGZv_DYszFDGg12D9_-`b6b1D6g9=W3D=#*ON&%-x_zb&HdRdz&q1KI?>vl9WFp@ z4k!B%Nf8~hgV}sO3D8csIsjV_U~S}yYdGT)pLvooM)~hY@h-Ga^2|3};&>4d z^gI_Yn1k6&&M`2m??Oc1olPa6)^6N2_NFsUUWDVW27otPv$)gD;f+hfBzfu$j`=1R zyX&nlz}@TE24qJdcXwR^yj#~7SzG7-dO1BsTHn7M`;%e&!Pzfde(&Kr+CuvKWjB~eQ zM+xo+4)3`0B<9@52E%6tUVG*fR#wHJ&IlLK}-n`{G_X+bToI|7QpTJ4zn)t-@^W8&E6 zkk(AvW`0PL>;M4HGzDo%g8aR;Cz}m(M1*fm;BGYIlC=(Jd2!jIt?jC*374~Im?GU*!%T1pVf|sbE@G1b~h&_H6ODs!HtwJJ;?Jgt&Y8-i79NQB zM&mFd(KsSAZo94BSV%7D0Xvt?;LQaWy5SPXTlb0j-{|$6Bj?IF6WsgkY7iC^wD8FFweOZ@4A!RcpK4|4@`gIXEyrWIsOd?YNi|Z@X(vB_OC=_%IkQmF>M;@ zxSLP*WwWilb{hHQY%-qCWRtd)Gcq%JaiKZk7ZP#KDRS?*EVGBCmhDI6-fwEj0b6Sw z#Kk}1>a8i?O6E-quK;tCJ9*V#&Fr{iqo*Sq3e!E+co0m+ zu}J%}IlQKuMkK1GhwOYlt&ub5^%q2BUg|<6uyOHwUf9zvF%v1kZRb*arA!WFwctBO z?V4>O9Z8MDhnw0|{$~1mseVsVT~DXoFrdEg@aM0nr|M0aWO!9)vKgPGlZeg-aXa0g z%^>>BqzBSEA~V69I6ge}tIm;j?_+w2(i~Cx`4@g6I;`jVV{; z&L=B6pC=<@H|H<8>6fz$ZofUh_?>S}Fa7i1N-z8HZzY#MdPj1_r|xWBvE$Cx<$>-1 z|Ch<-pZXtLuXyw~TbJHPx-GrnoxhO0?DiY7bFV#Hs$6@^>o&xAlV}mv=e`Q;s|I)=mye_dU62i#&|lL z&Dv(pr+R*TSPMt-9GAK?xBYT*;qAYfz2fdWk}Dp4LvqolE_7S}{5&`M&M{lPeb~o0 zX|FC(-f#2Xjo}U>BqL6&cjBBI!-uVHv6pK}W43bpi`>vVFELy1`=#aupL!bre|vKA zpWl+c^wx{q8QXZywIKR%P8aFOAv>QPG>rtDUt*IQfXy$oCXQasHCc=Cto9swwH*wi zJ)P$O=%z^wqs25H2*>k!GHz$naW$9WfyVIGnfS~z+6-b0WuHG~wq1K$e$kzGrdK}t zGxHy<|XBLWB>xj;*X>wH8bhvGeqocBA-iVkdD+`l5#B^ z)`V*_fFbm?ORP;_`&)Hq{|-;wxtQzeL;yFPR*hsooI7r3(s6u9VgB6k$v|J#F|D{Q zzxd8OvMWD)r9Jz;v)srX$_t{e7w152Fj{Z}FdFA1b5C8 za+rWl>jMQe!Ti?z6?gv&^U_DRAU6hz$2>s{z!J zffJy)q!t8S3Q9n!%K-MHb<`Jx3n8>+y^)-tZugzz0?2VL)8<1~ZoR&F&ZBQ=y?h|x z?f^S)+9?DRt^tD!gG`Z%q%qg(USIt9>IMJtwyozs`WyGW+JVyny9V=uZZ)*9E9Q(9Y_@000mGNklK&$(0OK4pZS$uwTrcTLw4cqZ$z50MTXwOXzaWPm|gL<0ud35 z+5vKoh@AmQc?VpKrnw{mjCm&_Cy1`4E&-Se@aEEL+a(sjCAe7zPfJc2l&}m+*_K3r zqfC8@bCYuLtfVkbE5iWyPo`(xcT;lSt&7cfC3^V4)A!Se*weO^Pue^P+*0QOr zX=-gi)45%9Tb0OEo89>bdECMM7CnbSr zA(Ey5U&=B7%SfG)qnrSwK@T~l3_be^I+TM9&N|xSK2%&BunRJPTiUXocA-tzcyice zp=?E*L(V;X_pdcxcHhhMP1{!Gq^`!MJIBuIA!1LtM#{CSW6frowKsH`A1``!=kdzH zYECMsANbLy&oFs&mkZvA=#0Gi!&R@ZWvUUN z3?N$oI!DyAAcN=o9C>p_u#f%d{3-~vh5rcI@s zp)P~2;CYeGlwe0)0%CpQd5*jQey}%?k^bPkImZdgaSmx- zZELY}o-|P3d+;-_O}!hbnN~iHJbJ>m(#dQtpXU!Hc`OT}!(xM8j-KhpFXtECSLDtf zF&TvD?2vm{fZ8xRw|NeLWh8(l1+Y>A34jS;LOJOo)@J}vMtg8x3^T3uDPeDcq^gyV~VZ*+1*w8k^xe7Avi_0MT=aQk{6m?;2~3j59+&B+iL_ zY%s={O=mp5( zPY4`D+>{);40bv61WgWmQUDS31{CT7w*V~&ZKz`%?F=48NqHCGsi#d2Q0DA2w0DxX z%N$pzhd#r(vo_})BgKWsF{jiA*#P`Ta@dd@a_yf?&bqI^z&36cz&@NM`FStD`0wLN zWx;6dMV@Ik&0h}yw@Y?;Qb6r={im@|`J8WMGe|k$pu7er&AH4bd4Jw?Tw~6?g!!`; zwGC*-?gO9=!9+j<%mh;gFmUn1tsI~rI8p#HA&5I<0ThcUnFB0F@&G(=0LQ>K2hRyW zaQ0b{6LO35S)7YxU}Jf1*x5i15C^foZHH(W+L>?;D>>`~p>5tCYmPej4|PT|=s4z# zW2GK*pe{ipv#W0$45d0EZ3@)<$M^qN48|Xf8!*P;u zj=US#7;gqW$IS7isLODHQO7cEGmM#Kj@x)U22kGz>I<-qG172NTg#fJUUjusUH$6+ zeA`WL{-bxi{*HItb@Oli+=1Wx=%1YoKob|5hqa{KCD%87hREE?@MzLnMTCSD1p`E1s*4R0Ksw9-kG?f6jm8h2hNLK6%Gg#{1_ zvXWz=bAXaOMYKz?_!yIG!XFmWI`*M&Sfd{f3@Zqii*#pod zj*EakBC`Z7-g9|?KM?IpLOaxkqoWRz16dHu4#0K*C&A3In8j*1|+b}b(WooXOF{Ok*N9ML({7TN{WYC&{ zIy@YTy|ivx`K-&bNjDGPG!2hD8c}++lP92m*1YsS-~}m%2h^N66db^Zg$#LW4glmR zb8$09HY|F|TQqpaMF%Gk3}pbpbdg0n_Jv-hAe;jj1@^+wJ%C3Fh2@=2PB|hkE}h9jJh!2!p0(Ezp8n5e}IiNq=q%D zIebdbn@A&*ypB6D)K{OZXuW2j&ZTx)-L^*N0qB{$o=?LGW!i!DTJ?^H!uujT6nY@Q z5n$v1q5)Zu!Q$tnt_9}eXDFvwaDt$$r)&ra5V=Kr*M_n~-^dOE&^Tz1GKuo4s021H zl+aI`mwj_yR0Uu|a2!tla8!x)->J@gos%C2fYDQ@%{*tCMc@3}ekW1%v z*T1ymH}Xq=UlY&(Snvh_jaY`r%q8dgsEO3a>h-4WF<(!KTIS;ZCEE33q9AM)? zC5H?!p=+GQcPN~%PlwPA!Hx3-nHz(BfLznT`X$%i}{7OZuP@&;lg9RvCLi!j$CYqNXEq@WGdE;@|X2XSK)WYKBcql9v zxZqgyZa~A%VzF(AdLBm)%=iG7vTqN~@uL`^rUZ6zWgT~-LahL7-yW|(c4FaH&ISH0 zE>_HqAkOIzP>y*UJaiiPg*IFA_>S}Q)jc?(AD`l(v7WUo*LXJ1^Cs3jciC0%TH`k% z0|)h=PyYR7O_Pl@kakQXO4l474s+w^gyU9enTprh7vGHuga<|%lsXAPtw4VRi)UN>_HVyVlcb4M>- z(;sRACYC++Wi@b0U)l6I-gIR7yl$Vb-}(TWku1IDhsm=@du z&^9a}7cs{oW?00qz=%{i7So_?K?VRQz)VP>F94+k^s**9Xk$)xk#n$$z}{RLl|Q=d z*W_zIcdzXIl@G}iKleWQw^zJHM<d@IjbA=ML(~@PT%6?Tz!RPeW4U{2cDYb2>Bg zj?o$+TW70&FTTjM7gP@v)b||t)H#jZZfy|MdBe=Q#5R2503xozf&=PB$+Y8qzd1bM za3MWG2_RY^k+8HV=ZH*U5!;KGl|V+>fGif$1{)_1w`&}6QF!zM!su}9WhiTJgRxve&e8=Y1 zz70V}kLMK^qP4G^x@nr0v**2U@-r_E16qT_KtXMlzbf&Wnai7I&Lp-G*oJM1#{A?88M^uW>*QnwnPAW z92~%Hu_%@gKUgFSVtUb8G?oF}0@wx%3QK@HTnNwu%jkhe06R#9yqa+iv@OBSA(GlB zddEe-AisOj&$mkpv){Sk=fpZMg?|cQ8~BE0aswZZn)vorKQxADEw1hpJD)ZzUJ@9i z(ltv#1_o;0ZW1xWEseYiS8UU#j``NY?(SX7D9tZ$1alxXwO9-Sl$>NbQQ3;YqLFM{ zXJJcn;64Dj4dgC>pv(2Y6WHxhzHIay`HQQ!w@ZsNrY8m$G3Rd?0D?~(d<23_y@9_j zX^!7^~)i0Vnx&YGrc@Qnwq;Kf~j;+ir_ z6MqGHERhozqP0T=a#$b>a*|__@^&6=y%hr80>}kp^1XB!rQ5NUa4Z1LMGAoR1+W2VoJ&X+dcy?-cOaG-;azAA z7;j)e^N#fwuiP#_fk@p8F8=f0CjeO=d_-Rq{;{EK+CHOyNEfum-qK5-i`k%W-;m6= zd~WefWt-j@C-&mS?E9%72&n%APr9l0!wqLl19?@7E0&X7&A>yH_LWYS`#oSNkSJy!K7J?P>r64J4n5$>TrS^|67!1sMpa z#kbB&Y-a0-((`%dQf&b5)qN7b$ewX+i9OE{g{5==stb$ZKVmn_000mGNkl5n2H_~0`Kh=(); z{xa~FZIc%_c6DR(s-kt`GoRuFE$uAwYTMG@Bo)8vA9+2|oCgBxmhsz~3Q^kNQNbIR z8a#5JXe1}7Ki`kt;bFrC;p#YmGY}TRfw&k3k(di(us{}Ir`|wzl(BdoZ92rx(BDSf z`C$0I9v%$KxxMS@zZC+TQ}%ekBzJ9}Ir@e&d}HCi0^kmScQRttO=TY|<*7{s`Lt^y z4M~uWdZo`>XpQ6L@&Bc2Ty}2VWH!M>Qh?g5@&WND-MN=UUWY5(!}$bu0canf zYPm3w$O&o-Ad?LBAd5xg;;|hUl+N+&2Sj1Q1QuI{aM%AR}Av;U>qOWT#&^c~cV z$xUY^7<}qeJRDf09^yE$l@5^YE_GXfk-Q`hluviug#BL=cO2O5k`jJ1i~ zV4!x9Ka;na1XpJ25v9%Q9uO~eXKst6EAu&8y^q27UL zS43*T#Q=hC6>GGTrmJqlJo=A&d@$t6ZhP|HkVjK42`(z;4>V(k4DUcm|2S|)?%+fC zj@*F*|Jz=itp3MRn~}r&Y6Lo+*+|s6<(LM+b-z2!ts2d6o5?-CA^FTBg3^C0KFuX~ z>%k64p%XYi02B_VmBS$qD|SJa_DCR9kx_P!v_|A5$t8y|MoloN%po5 zcbSF|Ek&f}Ma`+@LUfASsbF6c+=7AgW=!&_;d21=Rd#rY!G@`3HQJ!1h~h2%|nLgpu`bn2Vgtg^E}AOkkPC9 zxebH6HL;L+3ryrL6E{k%a2$i6zJi($0GY{Mf_yraJUphYcFYdBAbvAdNSLjOmDchVUBV&A(N5_Yl0tXihQ5+o{?*f=z@qh@Kw!Xa>9`(iIp*1VY zjyDK@<(8L8uOCUqd~)6vPJ>99px7M1i7iDtn^^c8$fnUR{D zJ}&+E@>X?Kul9HzW1P1(_r!=+@h0j9L45@^UKMXLK69z@KE;)3r0dPc3P!)x4_^#l z1Cnq*cdW+|XCwNC8s7#qIhFtoTqjcFq-clZhT93~Uh`;vVEG5UlkQA%p*gp8aG^*z zNZ9y=kpj7g?|j>*9l5O=_LcDQi?%Bv13cKs`ON3|XM9#MqbupBmo|L`wG6A#+&h;= zxfe{JmjNtgvq{BWj^wJq<-y4kBDA9%s3;?3x0gh~L9Bx`5>@4*F(fnKOPz1M)G?2~ z8mUJw<9YJ%_vJ5tc;o|1XwwDSQ0Afi>H{u;W2gY5OW_~x)Py<|sD`HtAEQh^$9DBU zvypg!Iue(Nb-BwcJm(;&ub{?5qR-(9n>)PJTV0gqWQTox33=he~t24)qy>uU<9k%`B1o=Jo;Tv|Lwvjq>GNK zDHLsN7c~Gsfm}vu`ixctF^O^!u|=Zxk0}%lS9r7nbU3``wGQam80m)Ck)42FZxMUBA6S@2FA8W*_1H-Vudt$vx`7Y5XyStFYQHL9h5$&Zfky^&+)N<-a$?yqwEI_F(mVvg^TzSU%6c?rS25jchy*?Q7 z1IuxF^szGqNRL$=SEkF_O8N|80sbr$tSX7=9J*T&)P;5LM@H++d%Oj)Ma1d7Y0sAZ z2DLYMyD7NI^gMzk47FEpB3Q7g>C^8)JIi!$jxe%=vU=z^4dxGBt zFUQaK(I4pg$-7d26z8-_-O6LjtOHWX7#uoihJyYjK@2;a;%#5C7D2PJg8?oKf*$YW zj#tXcx;bI1zJl6Xi*&%@qYGe-PopP1d#?s?J{=p(AqS2_(1imE-8*c4+&I*&SyVpR zz-AuZ>w{q}Z^~^?-Yavax#)aC1?C@kF9-Us%bvyVW+k|f)py(UEc5P-Cq#T+1Wv-G z)N|A281@y^&U-urXw07@U(PU2V9UpIm;?tOp)5=nmRt*%op9$HF~t<*gqEu_=qsq5){XF- zxVkZQS|i}fKijou?l-RLKMG?o(9{QGiE&v;a9`@w}yN6DXFdcm>y10?D%Q{I{>wC8672sxR^anXfHySVl5!_V@IfV-ZlEs)k1yr71ZGb zQ8@PHV8tKhNW~@K0+fWa6ko_t0|7^9L?E^g1^e7O0ygvL<$PcvpqG3fEj?_sjdPwUB$A>h#O~BzsN=l4XQuA_Z8ImJdSIyKLcYgx$?(3GB_Crr4+!cV5UTc zV|f5?M;A!gSu4Vb{n>G*B2e|P4=Q5w!LZl&(I5E!C*;|=Jw1%J%Y+wvG36u5c9~Vd zSrh^l6-VIZLp2++hE&K(bXky;B$Sa%IOkW8jypL-g-a z1OtWTI6{IFNl9n(B8=E46WH%t#&3c@y61`I<I+ivSxHjJ z9lwg?+CL|K*t~U$-Qep>;FSAKeFb%-T!xEKBBlE>;FbW?Tm%w(L`Z?3gTo6)s33Pg z&=h)sUc#or@yOw10s9>nt>8Doj|{ta>DUQ}mThInk0>h?z(RHRA?U)P@L>=YK&?W6 z={8-q+y-=L7s&};wg;;f9r_AtRjo85rGgtex0)3Vt7z1etoVWwdK6KL0tvDx`~z1c zB}%Dqi&RWKlwecBe-H#!WZ`Lt!de5HdGufO_=8G4e_-K6dLn?gv@0E<3Y`ji9E)94 z=bylrs#9XK`PlR&QpXZYgxePKzqHZPocPmpx5{!;jR|j-5 z%StIx3WPcyNm^?mCqcljP%8zeh`t2dS^=AYW*&`G_OvsPUiE|FQD@?$+t+iLI}W_? z!HOCwe8VFY*da;S6r|Fd6T``mgL1V8fFnX5M&enpf$X}Uy^ge`Cb$m8^e6o|B(1tp zN1nQs@SlXEQc83oiBi-Tq(!8VJh%uCERzd2#X~_W0rnrh;*Ii>k>3Bn5F>Q24~G0f zr4Q{~;y1yIVK0323#+LOQ%34`#0NAES}ApKVc}1xl~STX3YAJJaY~KPNA{>UQL=)K zQ93qGMN(1Ks^lx^qNgUrKu?Cf7@c{MG$Xhp?!~xAo0hgkv~JrgI=W37JP;huMIb2! zi;_^UlnN~a<64q}rZ_AY*dtLj{5*Cqz~%=QzLPG_wDghhqu;aWZ-Ot~Rye0(n#UNj zqEx|vMPG3GL(xCb1x~q5TG6WtD=9(=fu%30hhU2ssg+X)4hRAu6a(0GKl}WUdPg3K zN+P8dugdPeH`|f1>zbF|c|-Hc`);bgY6t138drVzisZs2|EyI*id;?!{wcvx!ltn* zN-0rFNk8hghpZcSSh z>L^N~YjUN?C=FY<1O6!O1hNuMeUKmvd?_LtN_ug!l6(urRqqiV5@VxO#Y=0|oh{LU zUZQSARo1$xNWm+Sbhb;fm)@t_zs1r~b_uMb4WoINI*32gGvh{zk1$LNsZ={ty3~SF`Tddbso+aBRkg>t+a~gP#oB<``vTw z-CWgHRBW|k-&Y~MAZRHsMYOpnd+CCIxqenh z0||f~${LTU(4!nFEpQ*S5{T`jdsAJ7E`Y2S*vzA^-qPFu*YoLv-(1-Tmag%3&7u%l zhq+-d;0zE42T%{N!)3uvL8(}Wk|v=-DJ8*gsMC;1S>*bXdhiu5DdMVB`U%}Q>h{M$b5XP?0dxhY6CD--rNF6I zSRf_PzzWvT<0#xpPC2Z+3R35=QegiP-i-A61OMT{5NSu}q`e9RCvA@zGgSrApsa*U z5n#r{g(#&&6-I%h2>+Hjv(#of(a*Bvr>43mt7RJfT`HtR4~9AVPRCUC|bc?3bGCqGh$02M*y*gtYIB#9+fDipdpta%TimrZYf}2 zv-N`T2Xfk`OETusA2`u(f-lvBTCB442r`aNh^DTvSL#T^AfZfeXmX_`(jan>21U@P zk^4;F-g+plBIT6!lKkTpf3h(_O;@VO>>pB9wR7kIBJ7b*-K<-PoVf9S9@(|zL&-CG z@?&hvg;7dL@vm4A4X8#cl1OV1xN38jRU{hr5p-tMphFI(h>P!9e zmAUb{g}0dzU9m$_RTGt&@vn?MyL~2_d%x|< zn{#EJnODt6zBBUUx6`JVaeO11_=v)yVSNN^BN_{)MF|`yT%;HaRZ!H4J`o~yq!GDM zSJ*1FP@<*S*w0ZPDX3OFfN(A;3B_(;Gg3o!!ks^P_jk+rO>my?guT*8VIBZ92gpe% zGzw}Q;1{Zb0UV|vD9l)c(@z?ew6(a>lvLP_hy$$ur?Bj z!g48zG)P4fftXvzI+6-yrBM$8k3brYxS%R%1*q`oK?OqT=v|>m0xS0t*qJk>YEk~= zLVs#^A!`pM2@C^~K(fHb6oVj!0f!a-(f|M)EJJ%9l;}_?VbieHn6qkgmLvEf5HEHT z{KRq=OJAcjQxCqM#z(oCFqkzs=s})i^T=6;HmPA@*fup^Z}PgJ2+uh?3(s>R3%eErI=i?fe3y z#dkg!zH6~RwOcl0eXg#s&yO@dB7NM@uiB(yot-hXtB>6-*_B?hR%BJxyxmlEb!I3U7C2C? zsF23Yk;W#XV;hHFMsd}mX0Gn7#{VT;IQu)b<6CJ)TvxZU;~oEC=0xHtP~_x zF?u6nV+ukN=oJo}qZa%Fcr_{_@CX-r3|$O4hEJ%AA=ie?BmH{gfl&!Ri{m_MNPPVV zFS>i4y0suZ_><@ZL-1+8&-3ZZ?vJI)KEs@vi>I(Cnu~_Tim*^|n<^>}pssKs17R?* zWyB_!BiJhpjEUePfcKU*t)>ziO^%5lr%?=5~4oPZ<2w$oL& z+)*whupx;J6h;R?GyN!47$z+1qzD5Zp3I1)f4Di)!? z+xvvv@}>96i$3|=a>+luQ*Qgpy+?kOl%0?kX}hqRCnT|<64f>$o`t1S5o8ZcE8&ny zq6G6$f@wk25@C)Jq`)C_&au|PCoy~y6WmJGf3&G_uk?9~Vyz-?(;r^;zWsgfddcqe zlC^!P{KoYk$}7IIhflz~9rdBhP8WP=oMak;)l^tG4T>N~T1(6Y6dj^;jK!;f$YXsZ zaz{a@vG7VFv{kUzA~-5h>IeZf&|)u81z`X?`zD31ac&`nLI}p;pim}(b@nplXe%_^ z!A4;g5qwbkgEHse@dN71^7N2-sGn(vV2hPj!yrWK;uZ$oTJ3r*PPC=Ach6>iVRZ0h zpHIj%q=vU4z#w{7H~~ou7ZZ*JxT6Bth)9(#K*sfoA%z+qcnb24vaNuQDhwI+DiB64N-2yMbHO|!QSgIq zQ`F^$C`4+`KaKrI`<-?OwpeL+R;Bso<^+msy6d$#8>4kBvNwuw9KZ>`93T8huKaW5 z0+VZ{1EAsD&H@s=6@pvEczYg6AxG^+hrJZC1{ibzhYCSjAyHK#(2^9m62VbA8xTgY zGt!bMlPHrYcZiK>PhRv>93}L~n()q?0xN_Y3fPOmKtOcXsN*sp&$Kq_rbRzPetQ@YQ>K$r9|UjghkbmW32&h9Tu^Ig$>af3tNebg)M;{ zqb|}qfFP0xJ!nx%3H#7U+##YYolQYHLT#yIv`AT~7aSFcT*5{W2LfIL_F1b?#S4Nu z$|UF&NGrh+2NA(2MdQ2#vXWx_F@cOZMwnAE=SX6d!`$0Ct@Zd1HqGB91K4nW6-80v z4yOkP(ESO!)F-s)lL4c(ie+ykTJ@>Rqq<>!{grt9E`Xx0l)_n*L|9xc8la9OEUJnM zaBFhp)=Wo0)liN)c5yej*@sr>MFB|cO@pgW_Q8)I1SB-jOQ8o4%Q88%N9~~vY=~Km z7j0mL=o>n~U7^si3G^r{R45cRh+LKBFi(z2VXg{u)ZiNP0LPq)=p3UQg?Y#A`NvAv ze+WPy?9;DlN!NzHLzEuY{@}jXt$mc{Q0OP}HKB76tv5*}9Uj1&5Ke%={$_RRF6(_= zW8pOxJpw36aCRr%sHh4SIhG0m&4ngMYSbOIV}K&k00-J@K$?-T=u-sUiqcBLKNYkA zm;t0p!bZ8IBOpZ;z$|FV{V0-hLk9pdOOSA8B{-F65tyq$S}7s1q@jtl25?J?B*NIM z7+07N5m&Kv!l2Ge zV1KnT{`TVGQ6vT=a6XB&M(Uv@R#@;r5#EHvG6Yapkb+dnbtUMkDuOL34i^E-F?8%J zLVu(HH2^Gtn;Za)Kw3nUQXqjPNr8i)(>z^K2?;dS4utigH40Wp{2bIVJ#!8 zcXDmpsueNj$f`&;R?_~xGswa9N?P`#&4Ekaw->Rx7AuW8^rOdx`yjCY)98=3*CPJ7 zssJt;z)&C!utgx00f1^73_}3KkgCW~RFR;g9`zM+)KM1$P_ablqo4}P721GD3jL9A zrWl;%0<4h~yg08`3T2W8*XT_P`-GL0AZB~^8>8PC{gZPXDn7?P000WrNklCiOABY<7N7{=#8z2JUDkTvxBmxDz z0;&QOLjVb>TBai?6EIcqDr{reRS>bs3AkA6kgk+6%cKhQG0sJq6j28F;y`G_en70N zfLEX=k0Hmj1ut~5P*30e z`gEE*R?`nIh?`F;sClazMH)iKtY#v;wtZ~qz-OPT9C&-G-7^a5h!!mo0EF`cjJhCz zwE#!diPS>?%MkQ|Lk{(A&{x2Va)kDg!~h^EfGhMJOAJm>k~10y8FrO6#TZ8n@D_R< zfXhCrDu!H8HJmq+A?T{O$k=~1=(<3S^GGDmd~dY=_OEZLh2Q6t0dGU9s_H;{a0vh~P$QG7L_ep`eF-C|8Ph1YV~P^a~qC^eRAHMPv^gayU=hu0k776>TdZ z@@nWa3P9$0NIYj1Z42H8H2R3~L8Vr;5AE1GHSlyp+8fu*X}53sm4CIjt?C0)OTO(m z!3j{UwrW`i+uRkKc4~OjlxRH(kSOMGsb^sg7)j+WfwSiS3C%D0f z0Iq7_MSZ7?Xx`CN2H>ltwk_)l!bO7mp`eExcpM`BP+MQvQCAW6LE8$(ltunC-yWUY z{^S{l2cA23`;LIFV6CRd&iH1xzCW_+`Hvqhd_MKe`T(_HLrykqw|=MM6dr(4Uc-Gi zQj$-O?!Na)fV-&}xdCpZBmvw?OAG*25D^KaY8!Mz0O$~9a!@q@kf5ss@P|6oS4+_2 zBB+weGI+2-+oO2UvyTei`Vz>o@Lbij0Z zH9s}?tYFO+s9u#yi99Z=+a6gzpvFWdufC@~JR1Lqxf+UVz8B!$bMIHG4!{7w&aFAme<^@17lS4Oz zdiD_r`YQUUmi?o?g0e)>bB)M6^5mwO?O#4);^C74X2HgvvaF7(@5xR7_dtHR2kEDgg^n4gtW7=2e0==;L4;0L^+(l|U{zY$C14 z>lORR?&0RUKfh)C?N6LB^^rlpqT~D*qF8A~K*!$gpxpzU-z7O z-BY{t3L6i!S?%(Fw=)8;>BxbesE5wKSDF6tr$_fb{L!&p+rKtEvHeioe19I-p~yiVSWepl7eRf8c-WVC=fD-mgUNk!5VOAG_|U@aG-YC8#+U z0(&T~?phDP=6Fa&1fTfqCpYc=)BiTMd;8}{54`dDYV+OGQTk95(cCKkj8XE8LWGS( z)hkMe=uJ-Wg4ZL_<6f)ha^;_BM)spKarV&uYVw}{Z}a3EKfU$9_AhRkxc4h#hd;Kj z+BzibWaAnPM|$V%8UVVS@}}#a`ZFi;+bA!25qYF4TKv0d58JToa9pQ{0@!X{0lV8( zvr$%mdT8=nJ4VMp_SsDb9{$wky?6b;pigYxv;E^+_P+7Iow4VZj|bWdzW0_-Y}xn5 zPj20}{lA~F|LvdMa_~M*MdA4$xs9{#FVQ6GPZCiMJ*KP1ZRZC>@grv*OV z$j;b!pl*9Rz3RT_%&>Y6(Z#e?r`bw9fc)7w^_*Pw!RJIhzTy43VL=_%@6reNC6jYs zSCL9W`SfAg9#G27n(6s}l4~B^x9rC2w86#(HJy6PBT0VcgHIVJYx?J6dFl;KRvUxp zoL~LHX9Pan&~rIv@Eaf0<%F(zXs0<`e@aJsp#Sf6dAg0vLv)^*`})R;&b@p5)B!c; zjEIw6`M|SAx$i4?Iwhe?x`{q9)$G|*F*Nv8hUaRi=fb%$hLBotOdQ)nV?M3xc;GasJFZwn z;A=1fiGaH1foDT54v+<~rP;H10ldq28OH+}AJS$EKra4nysYQN5rE6KykJ`O@1u{e z^CA*F%nHwSf?QKVhuq?uwDP5!$PpX>Y?uoqI#eJNW5Wr zobI{;4hzIZ?f=>DK3yod$KE9l9R6QzDPZ5}Wd}WW8+g z?KG%2_yR68{4C+$cvjCWR3~0NlVz-5u=bQto(A 'mall_detail'; + + late final int goodsId; + final Rx goodsDetail = Rx(null); + final RxBool isLoading = true.obs; + + final addressController = TextEditingController(); + final nameController = TextEditingController(); + final phoneController = TextEditingController(); + + final formKey = GlobalKey(); + + @override + void onInit() { + super.onInit(); + goodsId = Get.arguments['goodsId'] as int; + getGoodsDetail(); + } + + @override + bool get listenLifecycleEvent => true; + + Future getGoodsDetail() async { + isLoading.value = true; + updateUi(); + try { + var response = await HttpService.to.post( + 'appointment/score/getScoreGoodsDetail', + data: {'goodsId': goodsId}, + ); + if (response != null && response.data != null) { + var result = BaseModel.fromJson( + response.data, + dataBuilder: (dataJson) => GoodsModel.fromJson(dataJson), + ); + if (result.code == 0 && result.data != null) { + goodsDetail.value = result.data; + } else { + showErrorToast('加载失败: ${result.message}'); + Get.back(); + } + } + } catch (e) { + log('获取商品详情失败: $e'); + showErrorToast('网络异常,请稍后重试'); + Get.back(); + } finally { + isLoading.value = false; + updateUi(); + } + } + + /// 兑换商品 + void exchange() async { + if (!formKey.currentState!.validate()) { + return; + } + + /* + final mallController = Get.find(); + if (mallController.userScore.value < (goodsDetail.value?.score ?? 0)) { + showWarningToast('积分不足'); + return; + }*/ + + // 接口调用预留 + showLoading('兑换中...'); + + final goods = goodsDetail.value; + if (goods == null) { + showErrorToast('兑换失败,请稍后重试'); + return; + } + try { + var response = await HttpService.to.post( + 'appointment/score/scoreExchange', + data: { + "goodsId": goods.id, + "address": addressController.text, + "name": nameController.text, + "phone": phoneController.text, + }, + ); + if (response != null && response.data != null) { + var result = BaseModel.fromJson(response.data); + if (result.code == 0) { + Get.off(() => MallExchangeSuccessPage()); + } + } + } catch (e) { + log('兑换失败: $e'); + showErrorToast('兑换失败,请稍后重试'); + } finally { + dismissLoading(); + } + } + + @override + void onClose() { + addressController.dispose(); + nameController.dispose(); + phoneController.dispose(); + super.onClose(); + } +} diff --git a/ln_jq_app/lib/pages/c_page/mall/detail/view.dart b/ln_jq_app/lib/pages/c_page/mall/detail/view.dart new file mode 100644 index 0000000..70eb3fc --- /dev/null +++ b/ln_jq_app/lib/pages/c_page/mall/detail/view.dart @@ -0,0 +1,283 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:getx_scaffold/getx_scaffold.dart'; +import 'controller.dart'; + +class MallDetailPage extends GetView { + const MallDetailPage({super.key}); + + @override + Widget build(BuildContext context) { + return GetBuilder( + init: MallDetailController(), + id: 'mall_detail', + builder: (_) { + return Scaffold( + backgroundColor: const Color(0xFFF7F8FA), + appBar: AppBar( + title: const Text('商品兑换'), + backgroundColor: Colors.white, + foregroundColor: Colors.black, + elevation: 0, + leading: IconButton( + icon: const Icon(Icons.arrow_back_ios, size: 20), + onPressed: () => Get.back(), + ), + ), + body: controller.isLoading.value + ? const Center(child: CircularProgressIndicator()) + : GestureDetector( + onTap: () { + hideKeyboard(); + }, + child: _buildBody(), + ), + bottomNavigationBar: _buildBottomButton(), + ); + }, + ); + } + + Widget _buildBody() { + final goods = controller.goodsDetail.value; + if (goods == null) return const Center(child: Text('商品信息不存在')); + + return SingleChildScrollView( + padding: const EdgeInsets.all(16), + child: Form( + key: controller.formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildGoodsInfoCard(goods), + const SizedBox(height: 24), + _buildSectionTitle('填写收货信息'), + const SizedBox(height: 16), + _buildInputLabel('详细地址'), + _buildTextField( + controller: controller.addressController, + hint: '请输入完整的收货地址', + icon: Icons.location_on_outlined, + ), + const SizedBox(height: 16), + _buildInputLabel('收货人姓名'), + _buildTextField( + controller: controller.nameController, + hint: '请输入收货人姓名', + icon: Icons.person_outline, + ), + const SizedBox(height: 16), + _buildInputLabel('联系电话'), + _buildTextField( + controller: controller.phoneController, + hint: '请输入手机号码', + icon: Icons.phone_android_outlined, + keyboardType: TextInputType.phone, + ), + const SizedBox(height: 40), + Center( + child: Text( + '兑换成功后,商品会在3个工作日内邮寄\n请注意查收', + textAlign: TextAlign.center, + style: TextStyle( + color: Color(0xFF999999), + fontSize: 12.sp, + fontWeight: FontWeight.w500, + ), + ), + ), + ], + ), + ), + ); + } + + Widget _buildGoodsInfoCard(goods) { + return Container( + padding: const EdgeInsets.all(17), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(16), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.03), + blurRadius: 10, + offset: const Offset(0, 4), + ), + ], + ), + child: Row( + children: [ + ClipRRect( + borderRadius: BorderRadius.circular(12), + child: goods.goodsImage != null + ? Image.network( + goods.goodsImage!, + width: 94.w, + height: 94.h, + fit: BoxFit.cover, + ) + : Container( + width: 80, + height: 80, + color: Colors.grey[200], + child: const Icon(Icons.image, color: Colors.grey), + ), + ), + const SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + goods.goodsName, + style: TextStyle( + fontSize: 16.sp, + fontWeight: FontWeight.w600, + color: Color(0xFF333333), + ), + ), + SizedBox(height: 8.h), + Row( + children: [ + Text( + '${goods.score}', + style: TextStyle( + fontSize: 20.sp, + color: Color(0xFF4CAF50), + fontWeight: FontWeight.w600, + ), + ), + const SizedBox(width: 4), + Text( + '积分', + style: TextStyle( + fontSize: 10.sp, + fontWeight: FontWeight.w600, + color: Color(0xFF999999), + ), + ), + ], + ), + SizedBox(height: 10.h), + Container( + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), + decoration: BoxDecoration( + color: const Color(0xFFF2F3F5), + borderRadius: BorderRadius.circular(4), + ), + child: Text( + '数量: 1', + style: TextStyle( + fontSize: 10.sp, + fontWeight: FontWeight.w500, + color: Color(0xFF666666), + ), + ), + ), + ], + ), + ), + ], + ), + ); + } + + Widget _buildSectionTitle(String title) { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: 6.w, + height: 16.h, + decoration: BoxDecoration( + color: const Color(0xFF4CAF50), + borderRadius: BorderRadius.circular(2), + ), + ), + const SizedBox(width: 8), + Text( + title, + style: TextStyle( + fontSize: 14.sp, + fontWeight: FontWeight.w600, + color: Color.fromRGBO(148, 163, 184, 1), + ), + ), + ], + ); + } + + Widget _buildInputLabel(String label) { + return Padding( + padding: const EdgeInsets.only(bottom: 8), + child: Text( + label, + style: TextStyle( + fontSize: 12.sp, + fontWeight: FontWeight.w600, + color: Color.fromRGBO(100, 116, 139, 1), + ), + ), + ); + } + + Widget _buildTextField({ + required TextEditingController controller, + required String hint, + required IconData icon, + TextInputType? keyboardType, + }) { + return Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: TextFormField( + controller: controller, + keyboardType: keyboardType, + textAlign: TextAlign.start, + decoration: InputDecoration( + hintText: hint, + hintStyle: TextStyle( + color: Color.fromRGBO(134, 144, 156, 1), + fontSize: 14.sp, + fontWeight: FontWeight.w500, + ), + prefixIcon: Icon(icon, color: const Color(0xFF999999), size: 20), + border: InputBorder.none, + contentPadding: const EdgeInsets.symmetric(vertical: 12), + ), + validator: (value) { + if (value == null || value.isEmpty) { + return '内容不能为空'; + } + return null; + }, + ), + ); + } + + Widget _buildBottomButton() { + return Container( + padding: const EdgeInsets.fromLTRB(16, 10, 16, 30), + child: ElevatedButton( + onPressed: controller.exchange, + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFF007A45), + minimumSize: const Size(double.infinity, 50), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(25)), + elevation: 0, + ), + child: const Text( + '兑换商品', + style: TextStyle( + color: Colors.white, + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ), + ); + } +} diff --git a/ln_jq_app/lib/pages/c_page/mall/exchange_success/view.dart b/ln_jq_app/lib/pages/c_page/mall/exchange_success/view.dart new file mode 100644 index 0000000..bcf0464 --- /dev/null +++ b/ln_jq_app/lib/pages/c_page/mall/exchange_success/view.dart @@ -0,0 +1,68 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:getx_scaffold/common/index.dart'; +import 'package:ln_jq_app/common/login_util.dart'; + +class MallExchangeSuccessPage extends StatelessWidget { + const MallExchangeSuccessPage({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + appBar: AppBar( + backgroundColor: Colors.white, + elevation: 0, + leading: IconButton( + icon: const Icon(Icons.arrow_back_ios, size: 20, color: Colors.black), + onPressed: () => Get.back(), // 返回首页 + ), + title: const Text('商品兑换', style: TextStyle(color: Colors.black, fontSize: 18)), + ), + body: Center( + child: Column( + children: [ + SizedBox(height: 114.h), + _buildSuccessIcon(), + const SizedBox(height: 24), + Text( + '兑换成功', + style: TextStyle( + fontSize: 24.sp, + fontWeight: FontWeight.w600, + color: Color(0xFF333333), + ), + ), + const SizedBox(height: 8), + Text( + '预计 3 日内发货\n请留意查收', + textAlign: TextAlign.center, + style: TextStyle(fontSize: 14.sp, color: Color(0xFF999999)), + ), + const SizedBox(height: 60), + ElevatedButton( + onPressed: () => Get.back(), + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFF007A45), + minimumSize: const Size(140, 50), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(25)), + ), + child: Text( + '返回首页', + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.w400, + fontSize: 16.sp, + ), + ), + ), + ], + ), + ), + ); + } + + Widget _buildSuccessIcon() { + return Container(child: LoginUtil.getAssImg("mall_pay_success@2x")); + } +} diff --git a/ln_jq_app/lib/pages/c_page/mall/mall_controller.dart b/ln_jq_app/lib/pages/c_page/mall/mall_controller.dart index f431385..9a16b16 100644 --- a/ln_jq_app/lib/pages/c_page/mall/mall_controller.dart +++ b/ln_jq_app/lib/pages/c_page/mall/mall_controller.dart @@ -1,5 +1,6 @@ import 'package:getx_scaffold/getx_scaffold.dart'; import 'package:ln_jq_app/common/model/base_model.dart'; +import 'package:ln_jq_app/pages/c_page/mall/detail/view.dart'; class GoodsModel { final int id; @@ -140,11 +141,8 @@ class MallController extends GetxController with BaseControllerMixin { /// 兑换商品 (预留) void exchangeGoods(GoodsModel goods) { - if (userScore.value < goods.score) { - showWarningToast('积分不足'); - return; - } - - //todo 跳转 + Get.to(() => MallDetailPage(), arguments: {'goodsId': goods.id})?.then((val) { + refreshData(); + }); } }